postgres.git / summary / log / commit / refs

commit    14b497cfbbbbd7663edb14a0d666ed511b81bfe7
Author:   Tom Lane <tgl@sss.pgh.pa.us>
Date:     Sat Aug 29 20:09:25 2015 +0000
First released in: 9.6.0, 9.0.23, 9.1.19, 9.2.14, 9.3.10, 9.4.5, 9.5.0

    Fix s_lock.h PPC assembly code to be compatible with native AIX assembler.
    
    On recent AIX it's necessary to configure gcc to use the native assembler
    (because the GNU assembler hasn't been updated to handle AIX 6+).  This
    caused PG builds to fail with assembler syntax errors, because we'd try
    to compile s_lock.h's gcc asm fragment for PPC, and that assembly code
    relied on GNU-style local labels.  We can't substitute normal labels
    because it would fail in any file containing more than one inlined use of
    tas().  Fortunately, that code is stable enough, and the PPC ISA is simple
    enough, that it doesn't seem like too much of a maintenance burden to just
    hand-code the branch offsets, removing the need for any labels.
    
    Note that the AIX assembler only accepts "$" for the location counter
    pseudo-symbol.  The usual GNU convention is "."; but it appears that all
    versions of gas for PPC also accept "$", so in theory this patch will not
    break any other PPC platforms.
    
    This has been reported by a few people, but Steve Underwood gets the credit
    for being the first to pursue the problem far enough to understand why it
    was failing.  Thanks also to Noah Misch for additional testing.


src/include/storage/s_lock.h | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h index 5ac3d1b0042..a8aecf9fc0f 100644 --- a/src/include/storage/s_lock.h +++ b/src/include/storage/s_lock.h @@ -410,6 +410,12 @@ typedef unsigned int slock_t; /* * NOTE: per the Enhanced PowerPC Architecture manual, v1.0 dated 7-May-2002, * an isync is a sufficient synchronization barrier after a lwarx/stwcx loop. + * + * Ordinarily, we'd code the branches here using GNU-style local symbols, that + * is "1f" referencing "1:" and so on. But some people run gcc on AIX with + * IBM's assembler as backend, and IBM's assembler doesn't do local symbols. + * So hand-code the branch offsets; fortunately, all PPC instructions are + * exactly 4 bytes each, so it's not too hard to count. */ static __inline__ int tas(volatile slock_t *lock) @@ -420,16 +426,14 @@ tas(volatile slock_t *lock) __asm__ __volatile__( " lwarx %0,0,%3 \n" " cmpwi %0,0 \n" -" bne 1f \n" +" bne $+16 \n" /* branch to li %1,1 */ " addi %0,%0,1 \n" " stwcx. %0,0,%3 \n" -" beq 2f \n" -"1: li %1,1 \n" -" b 3f \n" -"2: \n" +" beq $+12 \n" /* branch to isync */ +" li %1,1 \n" +" b $+12 \n" /* branch to end of asm sequence */ " isync \n" " li %1,0 \n" -"3: \n" : "=&r"(_t), "=r"(_res), "+m"(*lock) : "r"(lock) [parent: 7c1c1c6d4600]