Skip to content

Commit ffbc387

Browse files
committed
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.
1 parent d03f331 commit ffbc387

File tree

1 file changed

+10
-6
lines changed

1 file changed

+10
-6
lines changed

src/include/storage/s_lock.h

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,12 @@ typedef unsigned int slock_t;
443443
* NOTE: per the Enhanced PowerPC Architecture manual, v1.0 dated 7-May-2002,
444444
* an isync is a sufficient synchronization barrier after a lwarx/stwcx loop.
445445
* On newer machines, we can use lwsync instead for better performance.
446+
*
447+
* Ordinarily, we'd code the branches here using GNU-style local symbols, that
448+
* is "1f" referencing "1:" and so on. But some people run gcc on AIX with
449+
* IBM's assembler as backend, and IBM's assembler doesn't do local symbols.
450+
* So hand-code the branch offsets; fortunately, all PPC instructions are
451+
* exactly 4 bytes each, so it's not too hard to count.
446452
*/
447453
static __inline__ int
448454
tas(volatile slock_t *lock)
@@ -457,20 +463,18 @@ tas(volatile slock_t *lock)
457463
" lwarx %0,0,%3 \n"
458464
#endif
459465
" cmpwi %0,0 \n"
460-
" bne 1f \n"
466+
" bne $+16 \n" /* branch to li %1,1 */
461467
" addi %0,%0,1 \n"
462468
" stwcx. %0,0,%3 \n"
463-
" beq 2f \n"
464-
"1: li %1,1 \n"
465-
" b 3f \n"
466-
"2: \n"
469+
" beq $+12 \n" /* branch to lwsync/isync */
470+
" li %1,1 \n"
471+
" b $+12 \n" /* branch to end of asm sequence */
467472
#ifdef USE_PPC_LWSYNC
468473
" lwsync \n"
469474
#else
470475
" isync \n"
471476
#endif
472477
" li %1,0 \n"
473-
"3: \n"
474478

475479
: "=&r"(_t), "=r"(_res), "+m"(*lock)
476480
: "r"(lock)

0 commit comments

Comments
 (0)