From f0eee6eca8c39b11b6a41d9b04eba8985655df77 Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Wed, 7 Sep 2011 23:39:14 +0000 Subject: [PATCH] Thumb2 assembly parsing and encoding for LDRBT. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@139267 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMInstrThumb2.td | 26 +++++++++++++++++--------- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 17 +++++++++++++---- test/MC/ARM/basic-thumb2-instructions.s | 14 ++++++++++++++ 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 bb9debd7696..2857b2d208e 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -123,6 +123,16 @@ def t2adrlabel : Operand { } +// t2addrmode_posimm8 := reg + imm8 +def MemPosImm8OffsetAsmOperand : AsmOperandClass {let Name="MemPosImm8Offset";} +def t2addrmode_posimm8 : Operand { + 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, @@ -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 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 6df2d56ff2c..b66adfc9048 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 4fc9391f88b..1abbd5fa788 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 0a1e4af4180..11de085d9ae 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 -- 2.11.0