aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp13
-rw-r--r--lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp4
-rw-r--r--lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp4
-rw-r--r--test/MC/ARM/basic-arm-instructions.s8
-rw-r--r--test/MC/ARM/simple-fp-encoding.s14
5 files changed, 30 insertions, 13 deletions
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 2c7accd61c..443e54481a 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -638,7 +638,8 @@ public:
// Immediate offset in range [-1020, 1020] and a multiple of 4.
if (!Mem.OffsetImm) return true;
int64_t Val = Mem.OffsetImm->getValue();
- return Val >= -1020 && Val <= 1020 && ((Val & 3) == 0);
+ return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
+ Val == INT32_MIN;
}
bool isMemRegOffset() const {
if (Kind != Memory || !Mem.OffsetRegNum)
@@ -709,7 +710,7 @@ public:
// Immediate offset in range [-4095, 4095].
if (!Mem.OffsetImm) return true;
int64_t Val = Mem.OffsetImm->getValue();
- return Val > -4096 && Val < 4096;
+ return (Val > -4096 && Val < 4096) || (Val == INT32_MIN);
}
bool isPostIdxImm8() const {
if (Kind != Immediate)
@@ -2565,8 +2566,7 @@ parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Parser.Lex(); // Eat the '#'.
E = Parser.getTok().getLoc();
- // FIXME: Special case #-0 so we can correctly set the U bit.
-
+ bool isNegative = getParser().getTok().is(AsmToken::Minus);
const MCExpr *Offset;
if (getParser().ParseExpression(Offset))
return true;
@@ -2578,6 +2578,11 @@ parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
if (!CE)
return Error (E, "constant expression expected");
+ // If the constant was #-0, represent it as INT32_MIN.
+ int32_t Val = CE->getValue();
+ if (isNegative && Val == 0)
+ CE = MCConstantExpr::Create(INT32_MIN, getContext());
+
// Now we should have the closing ']'
E = Parser.getTok().getLoc();
if (Parser.getTok().isNot(AsmToken::RBrac))
diff --git a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
index 8b44aa29ff..c421f1cda4 100644
--- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
+++ b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
@@ -446,7 +446,9 @@ void ARMInstPrinter::printAddrMode5Operand(const MCInst *MI, unsigned OpNum,
O << "[" << getRegisterName(MO1.getReg());
- if (unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm())) {
+ unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm());
+ unsigned Op = ARM_AM::getAM5Op(MO2.getImm());
+ if (ImmOffs || Op == ARM_AM::sub) {
O << ", #"
<< ARM_AM::getAddrOpcStr(ARM_AM::getAM5Op(MO2.getImm()))
<< ImmOffs * 4;
diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
index 94aeb59089..11fc0dca79 100644
--- a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
+++ b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
@@ -432,8 +432,10 @@ EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx, unsigned &Reg,
bool isAdd = true;
// Special value for #-0
- if (SImm == INT32_MIN)
+ if (SImm == INT32_MIN) {
SImm = 0;
+ isAdd = false;
+ }
// Immediate is always encoded as positive. The 'U' bit controls add vs sub.
if (SImm < 0) {
diff --git a/test/MC/ARM/basic-arm-instructions.s b/test/MC/ARM/basic-arm-instructions.s
index d466662bd2..861d50faa6 100644
--- a/test/MC/ARM/basic-arm-instructions.s
+++ b/test/MC/ARM/basic-arm-instructions.s
@@ -1884,6 +1884,14 @@ Lforward:
@ CHECK: strex r2, r1, [r7] @ encoding: [0x91,0x2f,0x87,0xe1]
@ CHECK: strexd r6, r2, r3, [r8] @ encoding: [0x92,0x6f,0xa8,0xe1]
+@------------------------------------------------------------------------------
+@ STR
+@------------------------------------------------------------------------------
+ strpl r3, [r10, #-0]!
+ strpl r3, [r10, #0]!
+
+@ CHECK: strpl r3, [r10, #-0]! @ encoding: [0x00,0x30,0x2a,0x55]
+@ CHECK: strpl r3, [r10]! @ encoding: [0x00,0x30,0xaa,0x55]
@------------------------------------------------------------------------------
@ SUB
diff --git a/test/MC/ARM/simple-fp-encoding.s b/test/MC/ARM/simple-fp-encoding.s
index 891738085a..88dd81ac0b 100644
--- a/test/MC/ARM/simple-fp-encoding.s
+++ b/test/MC/ARM/simple-fp-encoding.s
@@ -2,7 +2,7 @@
@ CHECK: vadd.f64 d16, d17, d16 @ encoding: [0xa0,0x0b,0x71,0xee]
vadd.f64 d16, d17, d16
-
+
@ CHECK: vadd.f32 s0, s1, s0 @ encoding: [0x80,0x0a,0x30,0xee]
vadd.f32 s0, s1, s0
@@ -47,7 +47,7 @@
@ CHECK: vabs.f32 s0, s0 @ encoding: [0xc0,0x0a,0xb0,0xee]
vabs.f32 s0, s0
-
+
@ CHECK: vcvt.f32.f64 s0, d16 @ encoding: [0xe0,0x0b,0xb7,0xee]
vcvt.f32.f64 s0, d16
@@ -116,7 +116,7 @@
@ FIXME: vmrs apsr_nzcv, fpscr @ encoding: [0x10,0xfa,0xf1,0xee]
@ vmrs apsr_nzcv, fpscr
-
+
@ CHECK: vnegne.f64 d16, d16 @ encoding: [0x60,0x0b,0xf1,0x1e]
vnegne.f64 d16, d16
@@ -173,13 +173,13 @@
@ CHECK: vldr.64 d1, [r2, #-32] @ encoding: [0x08,0x1b,0x12,0xed]
vldr.64 d1, [r2, #32]
vldr.64 d1, [r2, #-32]
-
+
@ CHECK: vldr.64 d2, [r3] @ encoding: [0x00,0x2b,0x93,0xed]
vldr.64 d2, [r3]
@ CHECK: vldr.64 d3, [pc] @ encoding: [0x00,0x3b,0x9f,0xed]
@ CHECK: vldr.64 d3, [pc] @ encoding: [0x00,0x3b,0x9f,0xed]
-@ CHECK: vldr.64 d3, [pc] @ encoding: [0x00,0x3b,0x9f,0xed]
+@ CHECK: vldr.64 d3, [pc, #-0] @ encoding: [0x00,0x3b,0x1f,0xed]
vldr.64 d3, [pc]
vldr.64 d3, [pc,#0]
vldr.64 d3, [pc,#-0]
@@ -191,13 +191,13 @@
@ CHECK: vldr.32 s1, [r2, #-32] @ encoding: [0x08,0x0a,0x52,0xed]
vldr.32 s1, [r2, #32]
vldr.32 s1, [r2, #-32]
-
+
@ CHECK: vldr.32 s2, [r3] @ encoding: [0x00,0x1a,0x93,0xed]
vldr.32 s2, [r3]
@ CHECK: vldr.32 s5, [pc] @ encoding: [0x00,0x2a,0xdf,0xed]
@ CHECK: vldr.32 s5, [pc] @ encoding: [0x00,0x2a,0xdf,0xed]
-@ CHECK: vldr.32 s5, [pc] @ encoding: [0x00,0x2a,0xdf,0xed]
+@ CHECK: vldr.32 s5, [pc, #-0] @ encoding: [0x00,0x2a,0x5f,0xed]
vldr.32 s5, [pc]
vldr.32 s5, [pc,#0]
vldr.32 s5, [pc,#-0]