diff options
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 17 | ||||
-rw-r--r-- | lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 18 | ||||
-rw-r--r-- | test/MC/ARM/arm-memory-instructions.s | 11 |
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] + |