From a2fce1169d8696f9950a17b1f85126b08c863154 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Sun, 12 Jan 2014 04:36:01 +0000 Subject: ARM: change implicit immediate forms of {ld,st}r{,b}t to psuedo-instructions The implicit immediate 0 forms are assembly aliases, not distinct instruction encodings. Fix the initial implementation introduced in r198914 to an alias to avoid two separate instruction definitions for the same encoding. An InstAlias is insufficient in this case as the necessary due to the need to add a new additional operand for the implicit zero. By using the AsmPsuedoInst, fall back to the C++ code to transform the instruction to the equivalent _POST_IMM form, inserting the additional implicit immediate 0. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199032 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMInstrFormats.td | 24 +++--- lib/Target/ARM/ARMInstrInfo.td | 94 ++++++++++------------- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 36 +++++++++ test/MC/ARM/arm_addrmode2.s | 8 +- 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 +class AsmPseudoInst : InstTemplate { - 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 let isPseudo = 1; } -class ARMAsmPseudo : AsmPseudoInst, - Requires<[IsARM]>; -class tAsmPseudo : AsmPseudoInst, - Requires<[IsThumb]>; -class t2AsmPseudo : AsmPseudoInst, - Requires<[IsThumb2]>; -class VFP2AsmPseudo : AsmPseudoInst, - Requires<[HasVFP2]>; -class NEONAsmPseudo : AsmPseudoInst, - Requires<[HasNEON]>; +class ARMAsmPseudo + : AsmPseudoInst, Requires<[IsARM]>; +class tAsmPseudo + : AsmPseudoInst, Requires<[IsThumb]>; +class t2AsmPseudo + : AsmPseudoInst, Requires<[IsThumb2]>; +class VFP2AsmPseudo + : AsmPseudoInst, Requires<[HasVFP2]>; +class NEONAsmPseudo + : AsmPseudoInst, Requires<[HasNEON]>; // Pseudo instructions for the code generator. class PseudoInst 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 - : 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 - : 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 op, string opc> { def i : AI3ldstidxT; 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 - : 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 - : 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 op, string opc> { def i : AI3ldstidxT &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] -- cgit v1.2.3