summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td17
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp18
-rw-r--r--test/MC/ARM/arm-memory-instructions.s11
3 files changed, 45 insertions, 1 deletions
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index b80eefd398..ad134d3f99 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -2280,6 +2280,12 @@ let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
def LDRD : AI3ld<0b1101, 0, (outs GPR:$Rt, GPR:$Rt2), (ins addrmode3:$addr),
LdMiscFrm, IIC_iLoad_d_r, "ldrd", "\t$Rt, $Rt2, $addr", []>,
Requires<[IsARM, HasV5TE]>;
+
+ // GNU Assembler extension (compatibility)
+ let isAsmParserOnly = 1 in
+ def LDRD_PAIR : AI3ld<0b1101, 0, (outs GPRPairOp:$Rt), (ins addrmode3:$addr),
+ LdMiscFrm, IIC_iLoad_d_r, "ldrd", "\t$Rt, $addr", []>,
+ Requires<[IsARM, HasV5TE]>;
}
def LDA : AIldracq<0b00, (outs GPR:$Rt), (ins addr_offset_none:$addr),
@@ -2545,13 +2551,22 @@ def STRH : AI3str<0b1011, (outs), (ins GPR:$Rt, addrmode3:$addr), StMiscFrm,
[(truncstorei16 GPR:$Rt, addrmode3:$addr)]>;
// Store doubleword
-let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in
+let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in {
def STRD : AI3str<0b1111, (outs), (ins GPR:$Rt, GPR:$Rt2, addrmode3:$addr),
StMiscFrm, IIC_iStore_d_r, "strd", "\t$Rt, $Rt2, $addr", []>,
Requires<[IsARM, HasV5TE]> {
let Inst{21} = 0;
}
+ // GNU Assembler extension (compatibility)
+ let isAsmParserOnly = 1 in
+ def STRD_PAIR : AI3str<0b1111, (outs), (ins GPRPairOp:$Rt, addrmode3:$addr),
+ StMiscFrm, IIC_iStore_d_r, "strd", "\t$Rt, $addr", []>,
+ Requires<[IsARM, HasV5TE]> {
+ let Inst{21} = 0;
+ }
+}
+
// Indexed stores
multiclass AI2_stridx<bit isByte, string opc,
InstrItinClass iii, InstrItinClass iir> {
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index c4f7b01352..bebbab5327 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -5445,6 +5445,19 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
}
}
+ // GNU Assembler extension (compatibility)
+ if ((Mnemonic == "ldrd" || Mnemonic == "strd") && !isThumb() &&
+ Operands.size() == 4) {
+ ARMOperand *Op = static_cast<ARMOperand *>(Operands[2]);
+ assert(Op->isReg() && "expected register argument");
+ assert(MRI->getMatchingSuperReg(Op->getReg(), ARM::gsub_0,
+ &MRI->getRegClass(ARM::GPRPairRegClassID))
+ && "expected register pair");
+ Operands.insert(Operands.begin() + 3,
+ ARMOperand::CreateReg(Op->getReg() + 1, Op->getStartLoc(),
+ Op->getEndLoc()));
+ }
+
// FIXME: As said above, this is all a pretty gross hack. This instruction
// does not fit with other "subs" and tblgen.
// Adjust operands of B9.3.19 SUBS PC, LR, #imm (Thumb2) system instruction
@@ -8793,6 +8806,11 @@ unsigned ARMAsmParser::validateTargetOperandClass(MCParsedAsmOperand *AsmOp,
"expression value must be representiable in 32 bits");
}
break;
+ case MCK_GPRPair:
+ if (Op->isReg() &&
+ MRI->getRegClass(ARM::GPRRegClassID).contains(Op->getReg()))
+ return Match_Success;
+ break;
}
return Match_InvalidOperand;
}
diff --git a/test/MC/ARM/arm-memory-instructions.s b/test/MC/ARM/arm-memory-instructions.s
index ad35dd26a0..f41c779b8f 100644
--- a/test/MC/ARM/arm-memory-instructions.s
+++ b/test/MC/ARM/arm-memory-instructions.s
@@ -485,3 +485,14 @@ Lbaz: .quad 0
@ CHECK: strht r8, [r1], #-25 @ encoding: [0xb9,0x81,0x61,0xe0]
@ CHECK: strht r5, [r3], r4 @ encoding: [0xb4,0x50,0xa3,0xe0]
@ CHECK: strht r6, [r8], -r0 @ encoding: [0xb0,0x60,0x28,0xe0]
+
+@------------------------------------------------------------------------------
+@ GNU Assembler Compatibility
+@------------------------------------------------------------------------------
+
+ ldrd r0, [sp]
+ strd r0, [sp]
+
+@ CHECK: ldrd r0, r1, [sp] @ encoding: [0xd0,0x00,0xcd,0xe1]
+@ CHECK: strd r0, r1, [sp] @ encoding: [0xf0,0x00,0xcd,0xe1]
+