Correct Thumb2 encodings for a much wider range of loads and stores.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120364 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/ARM/ARMMCCodeEmitter.cpp b/lib/Target/ARM/ARMMCCodeEmitter.cpp
index 2e9d804..a9f8133 100644
--- a/lib/Target/ARM/ARMMCCodeEmitter.cpp
+++ b/lib/Target/ARM/ARMMCCodeEmitter.cpp
@@ -177,6 +177,8 @@
SmallVectorImpl<MCFixup> &Fixups) const;
unsigned getT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum,
SmallVectorImpl<MCFixup> &Fixups) const;
+ unsigned getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum,
+ SmallVectorImpl<MCFixup> &Fixups) const;
unsigned getT2AddrModeImm12OpValue(const MCInst &MI, unsigned OpNum,
SmallVectorImpl<MCFixup> &Fixups) const;
@@ -671,8 +673,28 @@
// Even though the immediate is 8 bits long, we need 9 bits in order
// to represent the (inverse of the) sign bit.
Value <<= 9;
- Value |= ((int32_t)MO2.getImm()) & 511;
- Value ^= 256; // Invert the sign bit.
+ int32_t tmp = (int32_t)MO2.getImm();
+ if (tmp < 0)
+ tmp = abs(tmp);
+ else
+ Value |= 256; // Set the ADD bit
+ Value |= tmp & 255;
+ return Value;
+}
+
+unsigned ARMMCCodeEmitter::
+getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum,
+ SmallVectorImpl<MCFixup> &Fixups) const {
+ const MCOperand &MO1 = MI.getOperand(OpNum);
+
+ // FIXME: Needs fixup support.
+ unsigned Value = 0;
+ int32_t tmp = (int32_t)MO1.getImm();
+ if (tmp < 0)
+ tmp = abs(tmp);
+ else
+ Value |= 256; // Set the ADD bit
+ Value |= tmp & 255;
return Value;
}