Skip to content

Commit 9fb79e6

Browse files
nemanjaitstellar
authored andcommitted
[PowerPC] Handle base load with reservation mnemonic
The Power ISA defined l[bhwdq]arx as both base and extended mnemonics. The base mnemonic takes the EH bit as an operand and the extended mnemonic omits it, making it implicitly zero. The existing implementation only handles the base mnemonic when EH is 1 and internally produces a different instruction. There are historical reasons for this. This patch simply removes the limitation introduced by this implementation that disallows the base mnemonic with EH = 0 in the ASM parser. This resolves an issue that prevented some files in the Linux kernel from being built with -fintegrated-as. Also fix a crash if the value is not an integer immediate. (cherry picked from commit d6c0ef7)
1 parent e68f640 commit 9fb79e6

File tree

4 files changed

+67
-1
lines changed

4 files changed

+67
-1
lines changed

llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1576,6 +1576,16 @@ bool PPCAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
15761576
std::swap(Operands[2], Operands[1]);
15771577
}
15781578

1579+
// Handle base mnemonic for atomic loads where the EH bit is zero.
1580+
if (Name == "lqarx" || Name == "ldarx" || Name == "lwarx" ||
1581+
Name == "lharx" || Name == "lbarx") {
1582+
if (Operands.size() != 5)
1583+
return false;
1584+
PPCOperand &EHOp = (PPCOperand &)*Operands[4];
1585+
if (EHOp.isU1Imm() && EHOp.getImm() == 0)
1586+
Operands.pop_back();
1587+
}
1588+
15791589
return false;
15801590
}
15811591

@@ -1745,7 +1755,7 @@ unsigned PPCAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
17451755
}
17461756

17471757
PPCOperand &Op = static_cast<PPCOperand &>(AsmOp);
1748-
if (Op.isImm() && Op.getImm() == ImmVal)
1758+
if (Op.isU3Imm() && Op.getImm() == ImmVal)
17491759
return Match_Success;
17501760

17511761
return Match_InvalidOperand;

llvm/test/CodeGen/PowerPC/inline-asm-label.ll

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,39 @@ entry:
4545
ret i32 %4
4646
}
4747

48+
define dso_local signext i32 @NoBarrier_CompareAndSwapExtMne(i32* %ptr, i32 signext %old_value, i32 signext %new_value) #0 {
49+
; CHECK-LABEL: NoBarrier_CompareAndSwapExtMne:
50+
; CHECK: #APP
51+
; CHECK-NEXT: L..tmp2:
52+
; CHECK-NEXT: lwarx 6, 0, 3
53+
; CHECK-NEXT: cmpw 4, 6
54+
; CHECK-NEXT: bne- 0, L..tmp3
55+
; CHECK-NEXT: stwcx. 5, 0, 3
56+
; CHECK-NEXT: bne- 0, L..tmp2
57+
; CHECK-NEXT: L..tmp3:
58+
59+
; NOIS-LABEL: NoBarrier_CompareAndSwapExtMne:
60+
; NOIS: #APP
61+
; NOIS-NEXT: 1: lwarx 6, 0, 3
62+
; NOIS-NEXT: cmpw 4, 6
63+
; NOIS-NEXT: bne- 2f
64+
; NOIS-NEXT: stwcx. 5, 0, 3
65+
; NOIS-NEXT: bne- 1b
66+
; NOIS-NEXT: 2:
67+
68+
entry:
69+
%ptr.addr = alloca i32*, align 8 %old_value.addr = alloca i32, align 4
70+
%new_value.addr = alloca i32, align 4
71+
%result = alloca i32, align 4
72+
store i32* %ptr, i32** %ptr.addr, align 8
73+
store i32 %old_value, i32* %old_value.addr, align 4
74+
store i32 %new_value, i32* %new_value.addr, align 4
75+
%0 = load i32*, i32** %ptr.addr, align 8
76+
%1 = load i32, i32* %old_value.addr, align 4
77+
%2 = load i32, i32* %new_value.addr, align 4
78+
%3 = call i32 asm sideeffect "1: lwarx $0, $4, $1, 0 \0A\09 cmpw $2, $0 \0A\09 bne- 2f \0A\09 stwcx. $3, $4, $1 \0A\09 bne- 1b \0A\092: \0A\09", "=&b,b,b,b,i,~{cr0},~{ctr}"(i32* %0, i32 %1, i32 %2, i32 0)
79+
store i32 %3, i32* %result, align 4
80+
%4 = load i32, i32* %result, align 4
81+
ret i32 %4
82+
}
83+

llvm/test/MC/PowerPC/ppc64-encoding-bookII.s

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,18 +130,34 @@
130130
# CHECK-LE: lbarx 2, 3, 4 # encoding: [0x68,0x20,0x43,0x7c]
131131
lbarx 2, 3, 4
132132

133+
# CHECK-BE: lbarx 2, 3, 4 # encoding: [0x7c,0x43,0x20,0x68]
134+
# CHECK-LE: lbarx 2, 3, 4 # encoding: [0x68,0x20,0x43,0x7c]
135+
lbarx 2, 3, 4, 0
136+
133137
# CHECK-BE: lharx 2, 3, 4 # encoding: [0x7c,0x43,0x20,0xe8]
134138
# CHECK-LE: lharx 2, 3, 4 # encoding: [0xe8,0x20,0x43,0x7c]
135139
lharx 2, 3, 4
136140

141+
# CHECK-BE: lharx 2, 3, 4 # encoding: [0x7c,0x43,0x20,0xe8]
142+
# CHECK-LE: lharx 2, 3, 4 # encoding: [0xe8,0x20,0x43,0x7c]
143+
lharx 2, 3, 4, 0
144+
137145
# CHECK-BE: lwarx 2, 3, 4 # encoding: [0x7c,0x43,0x20,0x28]
138146
# CHECK-LE: lwarx 2, 3, 4 # encoding: [0x28,0x20,0x43,0x7c]
139147
lwarx 2, 3, 4
140148

149+
# CHECK-BE: lwarx 2, 3, 4 # encoding: [0x7c,0x43,0x20,0x28]
150+
# CHECK-LE: lwarx 2, 3, 4 # encoding: [0x28,0x20,0x43,0x7c]
151+
lwarx 2, 3, 4, 0
152+
141153
# CHECK-BE: ldarx 2, 3, 4 # encoding: [0x7c,0x43,0x20,0xa8]
142154
# CHECK-LE: ldarx 2, 3, 4 # encoding: [0xa8,0x20,0x43,0x7c]
143155
ldarx 2, 3, 4
144156

157+
# CHECK-BE: ldarx 2, 3, 4 # encoding: [0x7c,0x43,0x20,0xa8]
158+
# CHECK-LE: ldarx 2, 3, 4 # encoding: [0xa8,0x20,0x43,0x7c]
159+
ldarx 2, 3, 4, 0
160+
145161
# CHECK-BE: lqarx 2, 3, 4 # encoding: [0x7c,0x43,0x22,0x28]
146162
# CHECK-LE: lqarx 2, 3, 4 # encoding: [0x28,0x22,0x43,0x7c]
147163
lqarx 2, 3, 4

llvm/test/MC/PowerPC/ppc64-errors.s

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,7 @@
139139
# CHECK: error: invalid modifier 'got' (no symbols present)
140140
addi 4, 3, 123@got
141141
# CHECK-NEXT: addi 4, 3, 123@got
142+
143+
# CHECK: error: invalid operand for instruction
144+
# CHECK-NEXT: lwarx 1, 2, 3, a
145+
lwarx 1, 2, 3, a

0 commit comments

Comments
 (0)