diff options
author | Jim Grosbach <grosbach@apple.com> | 2011-09-07 20:58:57 +0000 |
---|---|---|
committer | Jim Grosbach <grosbach@apple.com> | 2011-09-07 20:58:57 +0000 |
commit | a8307dd1c9279cbde1f3497e530d2ed9d014a0c5 (patch) | |
tree | 5151b4b3e69d16dda98df393fa6a95b11dbbbe48 /lib/Target/ARM/AsmParser/ARMAsmParser.cpp | |
parent | 94f914e3fd4b040edd81abb5f455ed2b99e2572a (diff) |
Thumb2 parsing and encoding for LDR(immediate).
The immediate offset of the non-writeback i8 form (encoding T4) allows
negative offsets only. The positive offset form of the encoding is the
LDRT instruction. Immediate offsets in the range [0,255] use encoding T3
instead.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@139254 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/AsmParser/ARMAsmParser.cpp')
-rw-r--r-- | lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index b00bb0cdae..9efdd421f0 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -732,6 +732,28 @@ public: int64_t Val = Mem.OffsetImm->getValue(); return Val > -256 && Val < 256; } + bool isMemNegImm8Offset() const { + if (Kind != Memory || Mem.OffsetRegNum != 0) + return false; + // Immediate offset in range [-255, -1]. + if (!Mem.OffsetImm) return true; + int64_t Val = Mem.OffsetImm->getValue(); + return Val > -256 && Val < 0; + } + bool isMemUImm12Offset() const { + // If we have an immediate that's not a constant, treat it as a label + // reference needing a fixup. If it is a constant, it's something else + // and we reject it. + if (Kind == Immediate && !isa<MCConstantExpr>(getImm())) + return true; + + if (Kind != Memory || Mem.OffsetRegNum != 0) + return false; + // Immediate offset in range [0, 4095]. + if (!Mem.OffsetImm) return true; + int64_t Val = Mem.OffsetImm->getValue(); + return (Val >= 0 && Val < 4096); + } bool isMemImm12Offset() const { // If we have an immediate that's not a constant, treat it as a label // reference needing a fixup. If it is a constant, it's something else @@ -1077,6 +1099,28 @@ public: Inst.addOperand(MCOperand::CreateImm(Val)); } + 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)); + } + + void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const { + assert(N == 2 && "Invalid number of operands!"); + // If this is an immediate, it's a label reference. + if (Kind == Immediate) { + addExpr(Inst, getImm()); + Inst.addOperand(MCOperand::CreateImm(0)); + return; + } + + // Otherwise, it's a normal memory reg+offset. + int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; + Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); + Inst.addOperand(MCOperand::CreateImm(Val)); + } + void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const { assert(N == 2 && "Invalid number of operands!"); // If this is an immediate, it's a label reference. |