diff options
-rw-r--r-- | lib/Target/ARM/ARMInstrFormats.td | 24 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 94 | ||||
-rw-r--r-- | lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 36 | ||||
-rw-r--r-- | test/MC/ARM/arm_addrmode2.s | 8 | ||||
-rw-r--r-- | test/MC/Disassembler/ARM/addrmode2-reencoding.txt | 8 |
5 files changed, 97 insertions, 73 deletions
diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td index f93504fddb..9ab82ee8a1 100644 --- a/lib/Target/ARM/ARMInstrFormats.td +++ b/lib/Target/ARM/ARMInstrFormats.td @@ -329,10 +329,10 @@ class InstThumb<AddrMode am, int sz, IndexMode im, // Pseudo-instructions for alternate assembly syntax (never used by codegen). // These are aliases that require C++ handling to convert to the target // instruction, while InstAliases can be handled directly by tblgen. -class AsmPseudoInst<string asm, dag iops> +class AsmPseudoInst<string asm, dag iops, dag oops = (outs)> : InstTemplate<AddrModeNone, 0, IndexModeNone, Pseudo, GenericDomain, "", NoItinerary> { - let OutOperandList = (outs); + let OutOperandList = oops; let InOperandList = iops; let Pattern = []; let isCodeGenOnly = 0; // So we get asm matcher for it. @@ -340,16 +340,16 @@ class AsmPseudoInst<string asm, dag iops> let isPseudo = 1; } -class ARMAsmPseudo<string asm, dag iops> : AsmPseudoInst<asm, iops>, - Requires<[IsARM]>; -class tAsmPseudo<string asm, dag iops> : AsmPseudoInst<asm, iops>, - Requires<[IsThumb]>; -class t2AsmPseudo<string asm, dag iops> : AsmPseudoInst<asm, iops>, - Requires<[IsThumb2]>; -class VFP2AsmPseudo<string asm, dag iops> : AsmPseudoInst<asm, iops>, - Requires<[HasVFP2]>; -class NEONAsmPseudo<string asm, dag iops> : AsmPseudoInst<asm, iops>, - Requires<[HasNEON]>; +class ARMAsmPseudo<string asm, dag iops, dag oops = (outs)> + : AsmPseudoInst<asm, iops, oops>, Requires<[IsARM]>; +class tAsmPseudo<string asm, dag iops, dag oops = (outs)> + : AsmPseudoInst<asm, iops, oops>, Requires<[IsThumb]>; +class t2AsmPseudo<string asm, dag iops, dag oops = (outs)> + : AsmPseudoInst<asm, iops, oops>, Requires<[IsThumb2]>; +class VFP2AsmPseudo<string asm, dag iops, dag oops = (outs)> + : AsmPseudoInst<asm, iops, oops>, Requires<[HasVFP2]>; +class NEONAsmPseudo<string asm, dag iops, dag oops = (outs)> + : AsmPseudoInst<asm, iops, oops>, Requires<[HasNEON]>; // Pseudo instructions for the code generator. class PseudoInst<dag oops, dag iops, InstrItinClass itin, list<dag> pattern> diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 2a28122b6c..a6e1d0d018 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -2450,30 +2450,23 @@ def LDRT_POST_REG : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$Rn_wb), let DecoderMethod = "DecodeAddrMode2IdxInstruction"; } -class LDRTImmediate<bit has_offset, string args, dag iops> - : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$Rn_wb), iops, +def LDRT_POST_IMM + : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$Rn_wb), + (ins addr_offset_none:$addr, am2offset_imm:$offset), IndexModePost, LdFrm, IIC_iLoad_ru, - "ldrt", args, "$addr.base = $Rn_wb", []> { + "ldrt", "\t$Rt, $addr, $offset", "$addr.base = $Rn_wb", []> { // {12} isAdd // {11-0} imm12/Rm bits<14> offset; bits<4> addr; let Inst{25} = 0; - let Inst{23} = !if(has_offset, offset{12}, 1); + let Inst{23} = offset{12}; let Inst{21} = 1; // overwrite let Inst{19-16} = addr; - let Inst{11-0} = !if(has_offset, offset{11-0}, 0); -} - -def LDRT_POST_IMM - : LDRTImmediate<1, "\t$Rt, $addr, $offset", - (ins addr_offset_none:$addr, am2offset_imm:$offset)> { + let Inst{11-0} = offset{11-0}; let DecoderMethod = "DecodeAddrMode2IdxInstruction"; } -def LDRT_POST_IMM_0 - : LDRTImmediate<0, "\t$Rt, $addr", (ins addr_offset_none:$addr)>; - def LDRBT_POST_REG : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb), (ins addr_offset_none:$addr, am2offset_reg:$offset), IndexModePost, LdFrm, IIC_iLoad_bh_ru, @@ -2493,30 +2486,23 @@ def LDRBT_POST_REG : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb), let DecoderMethod = "DecodeAddrMode2IdxInstruction"; } -class LDRBTImmediate<bit has_offset, string args, dag iops> - : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb), iops, - IndexModePost, LdFrm, IIC_iLoad_bh_ru, - "ldrbt", args, "$addr.base = $Rn_wb", []> { +def LDRBT_POST_IMM + : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb), + (ins addr_offset_none:$addr, am2offset_imm:$offset), + IndexModePost, LdFrm, IIC_iLoad_bh_ru, + "ldrbt", "\t$Rt, $addr, $offset", "$addr.base = $Rn_wb", []> { // {12} isAdd // {11-0} imm12/Rm bits<14> offset; bits<4> addr; let Inst{25} = 0; - let Inst{23} = !if(has_offset, offset{12}, 1); + let Inst{23} = offset{12}; let Inst{21} = 1; // overwrite let Inst{19-16} = addr; - let Inst{11-0} = !if(has_offset, offset{11-0}, 0); -} - -def LDRBT_POST_IMM - : LDRBTImmediate<1, "\t$Rt, $addr, $offset", - (ins addr_offset_none:$addr, am2offset_imm:$offset)> { + let Inst{11-0} = offset{11-0}; let DecoderMethod = "DecodeAddrMode2IdxInstruction"; } -def LDRBT_POST_IMM_0 - : LDRBTImmediate<0, "\t$Rt, $addr", (ins addr_offset_none:$addr)>; - multiclass AI3ldrT<bits<4> op, string opc> { def i : AI3ldstidxT<op, 1, (outs GPR:$Rt, GPR:$base_wb), (ins addr_offset_none:$addr, postidx_imm8:$offset), @@ -2547,6 +2533,14 @@ defm LDRHT : AI3ldrT<0b1011, "ldrht">; defm LDRSHT : AI3ldrT<0b1111, "ldrsht">; } +def LDRT_POST + : ARMAsmPseudo<"ldrt${q} $Rt, $addr", (ins addr_offset_none:$addr, pred:$q), + (outs GPR:$Rt)>; + +def LDRBT_POST + : ARMAsmPseudo<"ldrbt${q} $Rt, $addr", (ins addr_offset_none:$addr, pred:$q), + (outs GPR:$Rt)>; + // Store // Stores with truncate @@ -2777,29 +2771,26 @@ def STRBT_POST_REG : AI2ldstidx<0, 1, 0, (outs GPR:$Rn_wb), let DecoderMethod = "DecodeAddrMode2IdxInstruction"; } -class STRBTImmediate<bit has_offset, string args, dag iops> - : AI2ldstidx<0, 1, 0, (outs GPR:$Rn_wb), iops, IndexModePost, StFrm, - IIC_iStore_bh_ru, "strbt", args, "$addr.base = $Rn_wb", []> { +def STRBT_POST_IMM + : AI2ldstidx<0, 1, 0, (outs GPR:$Rn_wb), + (ins GPR:$Rt, addr_offset_none:$addr, am2offset_imm:$offset), + IndexModePost, StFrm, IIC_iStore_bh_ru, + "strbt", "\t$Rt, $addr, $offset", "$addr.base = $Rn_wb", []> { // {12} isAdd // {11-0} imm12/Rm bits<14> offset; bits<4> addr; let Inst{25} = 0; - let Inst{23} = !if(has_offset, offset{12}, 1); + let Inst{23} = offset{12}; let Inst{21} = 1; // overwrite let Inst{19-16} = addr; - let Inst{11-0} = !if(has_offset, offset{11-0}, 0); -} - -def STRBT_POST_IMM - : STRBTImmediate<1, "\t$Rt, $addr, $offset", - (ins GPR:$Rt, addr_offset_none:$addr, am2offset_imm:$offset)> { + let Inst{11-0} = offset{11-0}; let DecoderMethod = "DecodeAddrMode2IdxInstruction"; } - -def STRBT_POST_IMM_0 - : STRBTImmediate<0, "\t$Rt, $addr", (ins GPR:$Rt, addr_offset_none:$addr)>; +def STRBT_POST + : ARMAsmPseudo<"strbt${q} $Rt, $addr", + (ins GPR:$Rt, addr_offset_none:$addr, pred:$q)>; let mayStore = 1, neverHasSideEffects = 1 in { def STRT_POST_REG : AI2ldstidx<0, 0, 0, (outs GPR:$Rn_wb), @@ -2821,30 +2812,27 @@ def STRT_POST_REG : AI2ldstidx<0, 0, 0, (outs GPR:$Rn_wb), let DecoderMethod = "DecodeAddrMode2IdxInstruction"; } -class STRTImmediate<bit has_offset, string args, dag iops> - : AI2ldstidx<0, 0, 0, (outs GPR:$Rn_wb), iops, IndexModePost, StFrm, - IIC_iStore_ru, "strt", args, "$addr.base = $Rn_wb", []> { +def STRT_POST_IMM + : AI2ldstidx<0, 0, 0, (outs GPR:$Rn_wb), + (ins GPR:$Rt, addr_offset_none:$addr, am2offset_imm:$offset), + IndexModePost, StFrm, IIC_iStore_ru, + "strt", "\t$Rt, $addr, $offset", "$addr.base = $Rn_wb", []> { // {12} isAdd // {11-0} imm12/Rm bits<14> offset; bits<4> addr; let Inst{25} = 0; - let Inst{23} = !if(has_offset, offset{12}, 1); + let Inst{23} = offset{12}; let Inst{21} = 1; // overwrite let Inst{19-16} = addr; - let Inst{11-0} = !if(has_offset, offset{11-0}, 0); -} - -def STRT_POST_IMM - : STRTImmediate<1, "\t$Rt, $addr, $offset", - (ins GPR:$Rt, addr_offset_none:$addr, am2offset_imm:$offset)> { + let Inst{11-0} = offset{11-0}; let DecoderMethod = "DecodeAddrMode2IdxInstruction"; } - -def STRT_POST_IMM_0 - : STRTImmediate<0, "\t$Rt, $addr", (ins GPR:$Rt, addr_offset_none:$addr)>; } +def STRT_POST + : ARMAsmPseudo<"strt${q} $Rt, $addr", + (ins GPR:$Rt, addr_offset_none:$addr, pred:$q)>; multiclass AI3strT<bits<4> op, string opc> { def i : AI3ldstidxT<op, 0, (outs GPR:$base_wb), diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 77cdb75633..b1ac198c6c 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -6055,6 +6055,42 @@ bool ARMAsmParser:: processInstruction(MCInst &Inst, const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { switch (Inst.getOpcode()) { + // Alias for alternate form of 'ldr{,b}t Rt, [Rn], #imm' instruction. + case ARM::LDRT_POST: + case ARM::LDRBT_POST: { + const unsigned Opcode = + (Inst.getOpcode() == ARM::LDRT_POST) ? ARM::LDRT_POST_IMM + : ARM::LDRBT_POST_IMM; + MCInst TmpInst; + TmpInst.setOpcode(Opcode); + TmpInst.addOperand(Inst.getOperand(0)); + TmpInst.addOperand(Inst.getOperand(1)); + TmpInst.addOperand(Inst.getOperand(1)); + TmpInst.addOperand(MCOperand::CreateReg(0)); + TmpInst.addOperand(MCOperand::CreateImm(0)); + TmpInst.addOperand(Inst.getOperand(2)); + TmpInst.addOperand(Inst.getOperand(3)); + Inst = TmpInst; + return true; + } + // Alias for alternate form of 'str{,b}t Rt, [Rn], #imm' instruction. + case ARM::STRT_POST: + case ARM::STRBT_POST: { + const unsigned Opcode = + (Inst.getOpcode() == ARM::STRT_POST) ? ARM::STRT_POST_IMM + : ARM::STRBT_POST_IMM; + MCInst TmpInst; + TmpInst.setOpcode(Opcode); + TmpInst.addOperand(Inst.getOperand(1)); + TmpInst.addOperand(Inst.getOperand(0)); + TmpInst.addOperand(Inst.getOperand(1)); + TmpInst.addOperand(MCOperand::CreateReg(0)); + TmpInst.addOperand(MCOperand::CreateImm(0)); + TmpInst.addOperand(Inst.getOperand(2)); + TmpInst.addOperand(Inst.getOperand(3)); + Inst = TmpInst; + return true; + } // Alias for alternate form of 'ADR Rd, #imm' instruction. case ARM::ADDri: { if (Inst.getOperand(1).getReg() != ARM::PC || diff --git a/test/MC/ARM/arm_addrmode2.s b/test/MC/ARM/arm_addrmode2.s index a4fb9356db..53290ab0dd 100644 --- a/test/MC/ARM/arm_addrmode2.s +++ b/test/MC/ARM/arm_addrmode2.s @@ -4,19 +4,19 @@ @ CHECK: ldrt r1, [r0], r2 @ encoding: [0x02,0x10,0xb0,0xe6] @ CHECK: ldrt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xb0,0xe6] @ CHECK: ldrt r1, [r0], #4 @ encoding: [0x04,0x10,0xb0,0xe4] -@ CHECK: ldrt r1, [r0] @ encoding: [0x00,0x10,0xb0,0xe4] +@ CHECK: ldrt r1, [r0], #0 @ encoding: [0x00,0x10,0xb0,0xe4] @ CHECK: ldrbt r1, [r0], r2 @ encoding: [0x02,0x10,0xf0,0xe6] @ CHECK: ldrbt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xf0,0xe6] @ CHECK: ldrbt r1, [r0], #4 @ encoding: [0x04,0x10,0xf0,0xe4] -@ CHECK: ldrbt r1, [r0] @ encoding: [0x00,0x10,0xf0,0xe4] +@ CHECK: ldrbt r1, [r0], #0 @ encoding: [0x00,0x10,0xf0,0xe4] @ CHECK: strt r1, [r0], r2 @ encoding: [0x02,0x10,0xa0,0xe6] @ CHECK: strt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xa0,0xe6] @ CHECK: strt r1, [r0], #4 @ encoding: [0x04,0x10,0xa0,0xe4] -@ CHECK: strt r1, [r0] @ encoding: [0x00,0x10,0xa0,0xe4] +@ CHECK: strt r1, [r0], #0 @ encoding: [0x00,0x10,0xa0,0xe4] @ CHECK: strbt r1, [r0], r2 @ encoding: [0x02,0x10,0xe0,0xe6] @ CHECK: strbt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xe0,0xe6] @ CHECK: strbt r1, [r0], #4 @ encoding: [0x04,0x10,0xe0,0xe4] -@ CHECK: strbt r1, [r0] @ encoding: [0x00,0x10,0xe0,0xe4] +@ CHECK: strbt r1, [r0], #0 @ encoding: [0x00,0x10,0xe0,0xe4] ldrt r1, [r0], r2 ldrt r1, [r0], r2, lsr #3 ldrt r1, [r0], #4 diff --git a/test/MC/Disassembler/ARM/addrmode2-reencoding.txt b/test/MC/Disassembler/ARM/addrmode2-reencoding.txt index 128b4b971c..08d2de687a 100644 --- a/test/MC/Disassembler/ARM/addrmode2-reencoding.txt +++ b/test/MC/Disassembler/ARM/addrmode2-reencoding.txt @@ -5,8 +5,8 @@ 0x00 0x10 0xa0 0xe4 0x00 0x10 0xe0 0xe4 -# CHECK: ldrt r1, [r0] @ encoding: [0x00,0x10,0xb0,0xe4] -# CHECK: ldrbt r1, [r0] @ encoding: [0x00,0x10,0xf0,0xe4] -# CHECK: strt r1, [r0] @ encoding: [0x00,0x10,0xa0,0xe4] -# CHECK: strbt r1, [r0] @ encoding: [0x00,0x10,0xe0,0xe4] +# CHECK: ldrt r1, [r0], #0 @ encoding: [0x00,0x10,0xb0,0xe4] +# CHECK: ldrbt r1, [r0], #0 @ encoding: [0x00,0x10,0xf0,0xe4] +# CHECK: strt r1, [r0], #0 @ encoding: [0x00,0x10,0xa0,0xe4] +# CHECK: strbt r1, [r0], #0 @ encoding: [0x00,0x10,0xe0,0xe4] |