diff options
-rw-r--r-- | lib/Target/ARM/ARMInstrThumb2.td | 26 | ||||
-rw-r--r-- | lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 17 | ||||
-rw-r--r-- | test/MC/ARM/basic-thumb2-instructions.s | 14 | ||||
-rw-r--r-- | utils/TableGen/EDEmitter.cpp | 1 |
4 files changed, 45 insertions, 13 deletions
diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index bb9debd769..2857b2d208 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -123,6 +123,16 @@ def t2adrlabel : Operand<i32> { } +// t2addrmode_posimm8 := reg + imm8 +def MemPosImm8OffsetAsmOperand : AsmOperandClass {let Name="MemPosImm8Offset";} +def t2addrmode_posimm8 : Operand<i32> { + let PrintMethod = "printT2AddrModeImm8Operand"; + let EncoderMethod = "getT2AddrModeImm8OpValue"; + let DecoderMethod = "DecodeT2AddrModeImm8"; + let ParserMatchClass = MemPosImm8OffsetAsmOperand; + let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); +} + // t2addrmode_negimm8 := reg - imm8 def MemNegImm8OffsetAsmOperand : AsmOperandClass {let Name="MemNegImm8Offset";} def t2addrmode_negimm8 : Operand<i32>, @@ -1291,26 +1301,24 @@ def t2LDRSH_POST : T2Iidxldst<1, 0b01, 1, 0, (outs GPR:$Rt, GPR:$Rn), []>; } // mayLoad = 1, neverHasSideEffects = 1 -// LDRT, LDRBT, LDRHT, LDRSBT, LDRSHT all have offset mode (PUW=0b110) and are -// for disassembly only. +// LDRT, LDRBT, LDRHT, LDRSBT, LDRSHT all have offset mode (PUW=0b110). // Ref: A8.6.57 LDR (immediate, Thumb) Encoding T4 class T2IldT<bit signed, bits<2> type, string opc, InstrItinClass ii> - : T2Ii8<(outs rGPR:$Rt), (ins t2addrmode_imm8:$addr), ii, opc, + : T2Ii8<(outs rGPR:$Rt), (ins t2addrmode_posimm8:$addr), ii, opc, "\t$Rt, $addr", []> { + bits<4> Rt; + bits<13> addr; let Inst{31-27} = 0b11111; let Inst{26-25} = 0b00; let Inst{24} = signed; let Inst{23} = 0; let Inst{22-21} = type; let Inst{20} = 1; // load + let Inst{19-16} = addr{12-9}; + let Inst{15-12} = Rt; let Inst{11} = 1; let Inst{10-8} = 0b110; // PUW. - - bits<4> Rt; - bits<13> addr; - let Inst{15-12} = Rt; - let Inst{19-16} = addr{12-9}; - let Inst{7-0} = addr{7-0}; + let Inst{7-0} = addr{7-0}; } def t2LDRT : T2IldT<0, 0b10, "ldrt", IIC_iLoad_i>; diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 6df2d56ff2..b66adfc904 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -742,6 +742,14 @@ public: int64_t Val = Mem.OffsetImm->getValue(); return Val > -256 && Val < 256; } + bool isMemPosImm8Offset() const { + if (Kind != Memory || Mem.OffsetRegNum != 0) + return false; + // Immediate offset in range [0, 255]. + if (!Mem.OffsetImm) return true; + int64_t Val = Mem.OffsetImm->getValue(); + return Val >= 0 && Val < 256; + } bool isMemNegImm8Offset() const { if (Kind != Memory || Mem.OffsetRegNum != 0) return false; @@ -1108,11 +1116,12 @@ public: Inst.addOperand(MCOperand::CreateImm(Val)); } + void addMemPosImm8OffsetOperands(MCInst &Inst, unsigned N) const { + addMemImm8OffsetOperands(Inst, N); + } + void addMemNegImm8OffsetOperands(MCInst &Inst, unsigned N) const { - assert(N == 2 && "Invalid number of operands!"); - int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; - Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); - Inst.addOperand(MCOperand::CreateImm(Val)); + addMemImm8OffsetOperands(Inst, N); } void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const { diff --git a/test/MC/ARM/basic-thumb2-instructions.s b/test/MC/ARM/basic-thumb2-instructions.s index 4fc9391f88..1abbd5fa78 100644 --- a/test/MC/ARM/basic-thumb2-instructions.s +++ b/test/MC/ARM/basic-thumb2-instructions.s @@ -592,6 +592,20 @@ _func: @------------------------------------------------------------------------------ +@ LDRBT +@------------------------------------------------------------------------------ + ldrbt r1, [r2] + ldrbt r1, [r8, #0] + ldrbt r1, [r8, #3] + ldrbt r1, [r8, #255] + +@ CHECK: ldrbt r1, [r2] @ encoding: [0x12,0xf8,0x00,0x1e] +@ CHECK: ldrbt r1, [r8] @ encoding: [0x18,0xf8,0x00,0x1e] +@ CHECK: ldrbt r1, [r8, #3] @ encoding: [0x18,0xf8,0x03,0x1e] +@ CHECK: ldrbt r1, [r8, #255] @ encoding: [0x18,0xf8,0xff,0x1e] + + +@------------------------------------------------------------------------------ @ IT @------------------------------------------------------------------------------ @ Test encodings of a few full IT blocks, not just the IT instruction diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp index 0a1e4af418..11de085d9a 100644 --- a/utils/TableGen/EDEmitter.cpp +++ b/utils/TableGen/EDEmitter.cpp @@ -666,6 +666,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type, MISC("spr_reglist", "kOperandTypeARMSPRRegisterList"); // I, R, ... MISC("it_mask", "kOperandTypeThumbITMask"); // I MISC("t2addrmode_reg", "kOperandTypeThumb2AddrModeReg"); // R + MISC("t2addrmode_posimm8", "kOperandTypeThumb2AddrModeImm8"); // R, I MISC("t2addrmode_negimm8", "kOperandTypeThumb2AddrModeImm8"); // R, I MISC("t2addrmode_imm8", "kOperandTypeThumb2AddrModeImm8"); // R, I MISC("t2am_imm8_offset", "kOperandTypeThumb2AddrModeImm8Offset");//I |