aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2011-09-07 23:39:14 +0000
committerJim Grosbach <grosbach@apple.com>2011-09-07 23:39:14 +0000
commitf0eee6eca8c39b11b6a41d9b04eba8985655df77 (patch)
tree3a0fdc3f55dfd6d3eddb595a11e8814c7609fe2b
parent489c693f65521649dbee0378dbb465029d71c712 (diff)
Thumb2 assembly parsing and encoding for LDRBT.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@139267 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM/ARMInstrThumb2.td26
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp17
-rw-r--r--test/MC/ARM/basic-thumb2-instructions.s14
-rw-r--r--utils/TableGen/EDEmitter.cpp1
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