Skip to content

Commit ccb33b2

Browse files
[ARM][MC] Add GNU Alias for ldrexd and strexd instructions.
These aliasses were supported previously in llvm-mc but support was lost at some point and for a while it seems to have caused a crash. This adds back the alternate forms and tidies up this section of code a little.
1 parent e6f63a9 commit ccb33b2

File tree

2 files changed

+34
-14
lines changed

2 files changed

+34
-14
lines changed

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

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7343,34 +7343,46 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
73437343
// automatically
73447344
// expressed as a GPRPair, so we have to manually merge them.
73457345
// FIXME: We would really like to be able to tablegen'erate this.
7346-
if (!isThumb() && Operands.size() > MnemonicOpsEndInd + 1 &&
7346+
bool IsLoad = (Mnemonic == "ldrexd" || Mnemonic == "ldaexd");
7347+
if (!isThumb() && Operands.size() > MnemonicOpsEndInd + 1 + (!IsLoad) &&
73477348
(Mnemonic == "ldrexd" || Mnemonic == "strexd" || Mnemonic == "ldaexd" ||
73487349
Mnemonic == "stlexd")) {
7349-
bool isLoad = (Mnemonic == "ldrexd" || Mnemonic == "ldaexd");
7350-
unsigned Idx = isLoad ? MnemonicOpsEndInd : MnemonicOpsEndInd + 1;
7350+
unsigned Idx = IsLoad ? MnemonicOpsEndInd : MnemonicOpsEndInd + 1;
73517351
ARMOperand &Op1 = static_cast<ARMOperand &>(*Operands[Idx]);
73527352
ARMOperand &Op2 = static_cast<ARMOperand &>(*Operands[Idx + 1]);
73537353

73547354
const MCRegisterClass &MRC = MRI->getRegClass(ARM::GPRRegClassID);
7355-
// Adjust only if Op1 and Op2 are GPRs.
7356-
if (Op1.isReg() && Op2.isReg() && MRC.contains(Op1.getReg()) &&
7357-
MRC.contains(Op2.getReg())) {
7355+
bool IsGNUAlias = !(Op2.isReg() && MRC.contains(Op2.getReg()));
7356+
// Adjust only if Op1 is a GPR.
7357+
if (Op1.isReg() && MRC.contains(Op1.getReg())) {
73587358
unsigned Reg1 = Op1.getReg();
7359-
unsigned Reg2 = Op2.getReg();
73607359
unsigned Rt = MRI->getEncodingValue(Reg1);
7361-
unsigned Rt2 = MRI->getEncodingValue(Reg2);
73627360

7363-
// Rt2 must be Rt + 1 and Rt must be even.
7364-
if (Rt + 1 != Rt2 || (Rt & 1)) {
7365-
return Error(Op2.getStartLoc(),
7366-
isLoad ? "destination operands must be sequential"
7367-
: "source operands must be sequential");
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");
73687371
}
7372+
// Rt bust be even
7373+
if (Rt & 1)
7374+
return Error(
7375+
Op1.getStartLoc(),
7376+
IsLoad ? "destination operands must start start at an even register"
7377+
: "source operands must start start at an even register");
7378+
73697379
unsigned NewReg = MRI->getMatchingSuperReg(
73707380
Reg1, ARM::gsub_0, &(MRI->getRegClass(ARM::GPRPairRegClassID)));
73717381
Operands[Idx] =
73727382
ARMOperand::CreateReg(NewReg, Op1.getStartLoc(), Op2.getEndLoc());
7373-
Operands.erase(Operands.begin() + Idx + 1);
7383+
// Only remove redundent operand if not in GNU alias case
7384+
if (!IsGNUAlias)
7385+
Operands.erase(Operands.begin() + Idx + 1);
73747386
}
73757387
}
73767388

llvm/test/MC/ARM/basic-arm-instructions.s

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1202,6 +1202,10 @@ Lforward:
12021202
@ CHECK: ldrex r1, [r7] @ encoding: [0x9f,0x1f,0x97,0xe1]
12031203
@ CHECK: ldrexd r6, r7, [r8] @ encoding: [0x9f,0x6f,0xb8,0xe1]
12041204

1205+
@ GNU alias
1206+
ldrexd r6, [r8]
1207+
@ CHECK: ldrexd r6, r7, [r8] @ encoding: [0x9f,0x6f,0xb8,0xe1]
1208+
12051209
@------------------------------------------------------------------------------
12061210
@ LDRHT
12071211
@------------------------------------------------------------------------------
@@ -2904,6 +2908,10 @@ Lforward:
29042908
@ CHECK: strex r2, r1, [r7] @ encoding: [0x91,0x2f,0x87,0xe1]
29052909
@ CHECK: strexd r6, r2, r3, [r8] @ encoding: [0x92,0x6f,0xa8,0xe1]
29062910

2911+
@ GNU alias
2912+
strexd r6, r2, [r8]
2913+
@ CHECK: strexd r6, r2, r3, [r8] @ encoding: [0x92,0x6f,0xa8,0xe1]
2914+
29072915
@------------------------------------------------------------------------------
29082916
@ STR
29092917
@------------------------------------------------------------------------------

0 commit comments

Comments
 (0)