Skip to content

Commit d5ab531

Browse files
Cleanup the handling on GNU aliasses and add some more tests
1 parent b886a86 commit d5ab531

File tree

3 files changed

+50
-26
lines changed

3 files changed

+50
-26
lines changed

llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6865,8 +6865,9 @@ static void applyMnemonicAliases(StringRef &Mnemonic,
68656865
const FeatureBitset &Features,
68666866
unsigned VariantID);
68676867

6868-
// The GNU assembler has aliases of ldrd and strd with the second register
6869-
// omitted. We don't have a way to do that in tablegen, so fix it up here.
6868+
// The GNU assembler has aliases of ldrd, strd, ldrexd, strexd, ldaexd, and
6869+
// stlexd with the second register omitted. We don't have a way to do that in
6870+
// tablegen, so fix it up here.
68706871
//
68716872
// We have to be careful to not emit an invalid Rt2 here, because the rest of
68726873
// the assembly parser could then generate confusing diagnostics refering to
@@ -6876,13 +6877,19 @@ static void applyMnemonicAliases(StringRef &Mnemonic,
68766877
void ARMAsmParser::fixupGNULDRDAlias(StringRef Mnemonic,
68776878
OperandVector &Operands,
68786879
unsigned MnemonicOpsEndInd) {
6879-
if (Mnemonic != "ldrd" && Mnemonic != "strd")
6880+
if (Mnemonic != "ldrd" && Mnemonic != "strd" && Mnemonic != "ldrexd" &&
6881+
Mnemonic != "strexd" && Mnemonic != "ldaexd" && Mnemonic != "stlexd")
68806882
return;
6881-
if (Operands.size() < MnemonicOpsEndInd + 2)
6883+
6884+
unsigned IdX = Mnemonic == "strexd" || Mnemonic == "stlexd"
6885+
? MnemonicOpsEndInd + 1
6886+
: MnemonicOpsEndInd;
6887+
6888+
if (Operands.size() < IdX + 2)
68826889
return;
68836890

6884-
ARMOperand &Op2 = static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]);
6885-
ARMOperand &Op3 = static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1]);
6891+
ARMOperand &Op2 = static_cast<ARMOperand &>(*Operands[IdX]);
6892+
ARMOperand &Op3 = static_cast<ARMOperand &>(*Operands[IdX + 1]);
68866893

68876894
if (!Op2.isReg())
68886895
return;
@@ -6907,7 +6914,7 @@ void ARMAsmParser::fixupGNULDRDAlias(StringRef Mnemonic,
69076914
return;
69086915

69096916
Operands.insert(
6910-
Operands.begin() + MnemonicOpsEndInd + 1,
6917+
Operands.begin() + IdX + 1,
69116918
ARMOperand::CreateReg(PairedReg, Op2.getStartLoc(), Op2.getEndLoc()));
69126919
}
69136920

@@ -7336,6 +7343,9 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
73367343
static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]).isImm())
73377344
removeCondCode(Operands, MnemonicOpsEndInd);
73387345

7346+
// GNU Assembler extension (compatibility).
7347+
fixupGNULDRDAlias(Mnemonic, Operands, MnemonicOpsEndInd);
7348+
73397349
// Adjust operands of ldrexd/strexd to MCK_GPRPair.
73407350
// ldrexd/strexd require even/odd GPR pair. To enforce this constraint,
73417351
// a single GPRPair reg operand is used in the .td file to replace the two
@@ -7352,23 +7362,18 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
73527362
ARMOperand &Op2 = static_cast<ARMOperand &>(*Operands[Idx + 1]);
73537363

73547364
const MCRegisterClass &MRC = MRI->getRegClass(ARM::GPRRegClassID);
7355-
bool IsGNUAlias = !(Op2.isReg() && MRC.contains(Op2.getReg()));
73567365
// Adjust only if Op1 is a GPR.
73577366
if (Op1.isReg() && MRC.contains(Op1.getReg())) {
73587367
unsigned Reg1 = Op1.getReg();
73597368
unsigned Rt = MRI->getEncodingValue(Reg1);
7369+
unsigned Reg2 = Op2.getReg();
7370+
unsigned Rt2 = MRI->getEncodingValue(Reg2);
7371+
// Rt2 must be Rt + 1.
7372+
if (Rt + 1 != Rt2)
7373+
return Error(Op2.getStartLoc(),
7374+
IsLoad ? "destination operands must be sequential"
7375+
: "source operands must be sequential");
73607376

7361-
// Check we are not in the GNU alias case with only one of the register
7362-
// pair specified
7363-
if (!IsGNUAlias) {
7364-
unsigned Reg2 = Op2.getReg();
7365-
unsigned Rt2 = MRI->getEncodingValue(Reg2);
7366-
// Rt2 must be Rt + 1.
7367-
if (Rt + 1 != Rt2)
7368-
return Error(Op2.getStartLoc(),
7369-
IsLoad ? "destination operands must be sequential"
7370-
: "source operands must be sequential");
7371-
}
73727377
// Rt must be even
73737378
if (Rt & 1)
73747379
return Error(
@@ -7378,17 +7383,13 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
73787383

73797384
unsigned NewReg = MRI->getMatchingSuperReg(
73807385
Reg1, ARM::gsub_0, &(MRI->getRegClass(ARM::GPRPairRegClassID)));
7386+
73817387
Operands[Idx] =
73827388
ARMOperand::CreateReg(NewReg, Op1.getStartLoc(), Op2.getEndLoc());
7383-
// redundant operand only exists if not in GNU alias case
7384-
if (!IsGNUAlias)
7385-
Operands.erase(Operands.begin() + Idx + 1);
7389+
Operands.erase(Operands.begin() + Idx + 1);
73867390
}
73877391
}
73887392

7389-
// GNU Assembler extension (compatibility).
7390-
fixupGNULDRDAlias(Mnemonic, Operands, MnemonicOpsEndInd);
7391-
73927393
// FIXME: As said above, this is all a pretty gross hack. This instruction
73937394
// does not fit with other "subs" and tblgen.
73947395
// Adjust operands of B9.3.19 SUBS PC, LR, #imm (Thumb2) system instruction

llvm/test/MC/ARM/load-store-acquire-release-v8-thumb.s

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
@ CHECK-V7: error: instruction requires: acquire/release
1515
@ CHECK-V7: error: instruction requires: acquire/release
1616

17+
@ GNU alias
18+
ldaexd r6, [r8]
19+
@ CHECK: ldaexd r6, r7, [r8] @ encoding: [0xd8,0xe8,0xff,0x67]
20+
1721
stlexb r1, r3, [r4]
1822
stlexh r4, r2, [r5]
1923
stlex r2, r1, [r7]
@@ -27,6 +31,10 @@
2731
@ CHECK-V7: error: instruction requires: acquire/release
2832
@ CHECK-V7: error: instruction requires: acquire/release
2933

34+
@ GNU alias
35+
stlexd r6, r2, [r8]
36+
@ CHECK: stlexd r6, r2, r3, [r8] @ encoding: [0xc8,0xe8,0xf6,0x23]
37+
3038
lda r5, [r6]
3139
ldab r5, [r6]
3240
ldah r12, [r9]

llvm/test/MC/ARM/load-store-acquire-release-v8.s

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
@ RUN: llvm-mc -triple=armv8 -show-encoding < %s | FileCheck %s
1+
@ RUN: not llvm-mc -triple=armv8 -show-encoding < %s 2> %t | FileCheck %s
2+
@ RUN: FileCheck %s < %t --check-prefix=CHECK-ERROR
23
@ RUN: not llvm-mc -triple=armv7 -show-encoding < %s 2>&1 | FileCheck %s --check-prefix=CHECK-V7
34
ldaexb r3, [r4]
45
ldaexh r2, [r5]
@@ -14,6 +15,13 @@
1415
@ CHECK-V7: instruction requires: acquire/release
1516
@ CHECK-V7: instruction requires: acquire/release
1617

18+
ldaexd r2, r4, [r8]
19+
@ CHECK-ERROR: error: destination operands must be sequential
20+
21+
@ GNU alias
22+
ldaexd r6, [r8]
23+
@ CHECK: ldaexd r6, r7, [r8] @ encoding: [0x9f,0x6e,0xb8,0xe1]
24+
1725
stlexb r1, r3, [r4]
1826
stlexh r4, r2, [r5]
1927
stlex r2, r1, [r7]
@@ -27,6 +35,13 @@
2735
@ CHECK-V7: instruction requires: acquire/release
2836
@ CHECK-V7: instruction requires: acquire/release
2937

38+
stlexd r6, r2, r4, [r8]
39+
@ CHECK-ERROR: error: source operands must be sequential
40+
41+
@ GNU alias
42+
stlexd r6, r2, [r8]
43+
@ CHECK: stlexd r6, r2, r3, [r8] @ encoding: [0x92,0x6e,0xa8,0xe1]
44+
3045
lda r5, [r6]
3146
ldab r5, [r6]
3247
ldah r12, [r9]

0 commit comments

Comments
 (0)