summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMihai Popa <mihail.popa@gmail.com>2013-08-15 15:43:06 +0000
committerMihai Popa <mihail.popa@gmail.com>2013-08-15 15:43:06 +0000
commitd79f00ba68310dc12b50cc53c9b58a062205f0de (patch)
tree8da51a46357019d3c65e9d4e291dc94f708e18f5
parent16b4ff5c4dba74988d8b72050f988a5e152a32fc (diff)
downloadbcm5719-llvm-d79f00ba68310dc12b50cc53c9b58a062205f0de.tar.gz
bcm5719-llvm-d79f00ba68310dc12b50cc53c9b58a062205f0de.zip
This fixes three issues related to Thumb literal loads:
1. The offset range for Thumb1 PC relative loads is [0..1020] and not [-1024..1020] 2. Thumb2 PC relative loads may define the PC, so the restriction placed on target register is removed 3. Removes unneeded alias between "ldr.n" and t1LDRpci. ".n" is actually stripped by both tablegen and the ASM parser, so this alias rule really does nothing llvm-svn: 188466
-rw-r--r--llvm/lib/Target/ARM/ARMInstrThumb.td3
-rw-r--r--llvm/lib/Target/ARM/ARMInstrThumb2.td6
-rw-r--r--llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp2
-rw-r--r--llvm/test/MC/ARM/basic-thumb2-instructions.s16
-rw-r--r--llvm/test/MC/ARM/thumb-diagnostics.s11
5 files changed, 25 insertions, 13 deletions
diff --git a/llvm/lib/Target/ARM/ARMInstrThumb.td b/llvm/lib/Target/ARM/ARMInstrThumb.td
index d5b65631704..7e383d2b0d1 100644
--- a/llvm/lib/Target/ARM/ARMInstrThumb.td
+++ b/llvm/lib/Target/ARM/ARMInstrThumb.td
@@ -662,9 +662,6 @@ def tLDRpci : T1pIs<(outs tGPR:$Rt), (ins t_addrmode_pc:$addr), IIC_iLoad_i,
let Inst{7-0} = addr;
}
-def : tInstAlias<"ldr${p}.n $Rt, $addr",
- (tLDRpci tGPR:$Rt, t_addrmode_pc:$addr, pred:$p), 0>;
-
// A8.6.194 & A8.6.192
defm tSTR : thumb_st_rr_ri_enc<0b000, 0b0110, t_addrmode_rrs4,
t_addrmode_is4, AddrModeT1_4,
diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td
index 5d04d21424e..77a37596695 100644
--- a/llvm/lib/Target/ARM/ARMInstrThumb2.td
+++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td
@@ -4191,7 +4191,7 @@ def : t2InstAlias<"ldrsh${p} $Rt, $addr",
(t2LDRSHs rGPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>;
def : t2InstAlias<"ldr${p} $Rt, $addr",
- (t2LDRpci GPR:$Rt, t2ldrlabel:$addr, pred:$p)>;
+ (t2LDRpci rGPR:$Rt, t2ldrlabel:$addr, pred:$p)>;
def : t2InstAlias<"ldrb${p} $Rt, $addr",
(t2LDRBpci rGPR:$Rt, t2ldrlabel:$addr, pred:$p)>;
def : t2InstAlias<"ldrh${p} $Rt, $addr",
@@ -4404,7 +4404,7 @@ def : t2InstAlias<"adr${p} $Rd, $addr",
// LDR(literal) w/ alternate [pc, #imm] syntax.
def t2LDRpcrel : t2AsmPseudo<"ldr${p} $Rt, $addr",
- (ins GPRnopc:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>;
+ (ins GPR:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>;
def t2LDRBpcrel : t2AsmPseudo<"ldrb${p} $Rt, $addr",
(ins GPRnopc:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>;
def t2LDRHpcrel : t2AsmPseudo<"ldrh${p} $Rt, $addr",
@@ -4415,7 +4415,7 @@ def t2LDRSHpcrel : t2AsmPseudo<"ldrsh${p} $Rt, $addr",
(ins GPRnopc:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>;
// Version w/ the .w suffix.
def : t2InstAlias<"ldr${p}.w $Rt, $addr",
- (t2LDRpcrel GPRnopc:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p), 0>;
+ (t2LDRpcrel GPR:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p), 0>;
def : t2InstAlias<"ldrb${p}.w $Rt, $addr",
(t2LDRBpcrel GPRnopc:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>;
def : t2InstAlias<"ldrh${p}.w $Rt, $addr",
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 03d3a48f210..3d7baf5b28b 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -647,7 +647,7 @@ public:
Val = Memory.OffsetImm->getValue();
}
else return false;
- return ((Val % 4) == 0) && (Val >= -1020) && (Val <= 1020);
+ return ((Val % 4) == 0) && (Val >= 0) && (Val <= 1020);
}
bool isFPImm() const {
if (!isImm()) return false;
diff --git a/llvm/test/MC/ARM/basic-thumb2-instructions.s b/llvm/test/MC/ARM/basic-thumb2-instructions.s
index c7a3b1b71b2..61eebe69817 100644
--- a/llvm/test/MC/ARM/basic-thumb2-instructions.s
+++ b/llvm/test/MC/ARM/basic-thumb2-instructions.s
@@ -797,23 +797,31 @@ _func:
@ CHECK: ldr.w lr, _strcmp-4 @ encoding: [0x5f'A',0xf8'A',A,0xe0'A']
@ CHECK: @ fixup A - offset: 0, value: _strcmp-4, kind: fixup_t2_ldst_pcrel_12
+ ldr r7, [pc, #8]
+ ldr.n r7, [pc, #8]
+ ldr.w r7, [pc, #8]
ldr r4, [pc, #1020]
ldr r3, [pc, #-1020]
ldr r6, [pc, #1024]
ldr r0, [pc, #-1024]
ldr r2, [pc, #4095]
ldr r1, [pc, #-4095]
- ldr.n r8, [pc, #132]
- ldr.w r8, [pc, #132]
+ ldr r8, [pc, #132]
+ ldr pc, [pc, #256]
+ ldr pc, [pc, #-400]
+@ CHECK: ldr r7, [pc, #8] @ encoding: [0x02,0x4f]
+@ CHECK: ldr r7, [pc, #8] @ encoding: [0x02,0x4f]
+@ CHECK: ldr.w r7, [pc, #8] @ encoding: [0xdf,0xf8,0x08,0x70]
@ CHECK: ldr r4, [pc, #1020] @ encoding: [0xff,0x4c]
-@ CHECK: ldr r3, [pc, #-1020] @ encoding: [0x01,0x4b]
+@ CHECK: ldr.w r3, [pc, #-1020] @ encoding: [0x5f,0xf8,0xfc,0x33]
@ CHECK: ldr.w r6, [pc, #1024] @ encoding: [0xdf,0xf8,0x00,0x64]
@ CHECK: ldr.w r0, [pc, #-1024] @ encoding: [0x5f,0xf8,0x00,0x04]
@ CHECK: ldr.w r2, [pc, #4095] @ encoding: [0xdf,0xf8,0xff,0x2f]
@ CHECK: ldr.w r1, [pc, #-4095] @ encoding: [0x5f,0xf8,0xff,0x1f]
-@ CHECK: ldr r8, [pc, #132] @ encoding: [0x21,0x48]
@ CHECK: ldr.w r8, [pc, #132] @ encoding: [0xdf,0xf8,0x84,0x80]
+@ CHECK: ldr.w pc, [pc, #256] @ encoding: [0xdf,0xf8,0x00,0xf1]
+@ CHECK: ldr.w pc, [pc, #-400] @ encoding: [0x5f,0xf8,0x90,0xf1]
@------------------------------------------------------------------------------
@ LDR(register)
diff --git a/llvm/test/MC/ARM/thumb-diagnostics.s b/llvm/test/MC/ARM/thumb-diagnostics.s
index 3604fc5f1ba..d16f547e729 100644
--- a/llvm/test/MC/ARM/thumb-diagnostics.s
+++ b/llvm/test/MC/ARM/thumb-diagnostics.s
@@ -52,7 +52,6 @@ error: invalid operand for instruction
@ CHECK-ERRORS: ldm r2!, {r2, r3, r4}
@ CHECK-ERRORS: ^
-
@ Invalid writeback and register lists for PUSH/POP
pop {r1, r2, r10}
push {r8, r9}
@@ -141,7 +140,7 @@ error: invalid operand for instruction
@------------------------------------------------------------------------------
-@ WFE/WFI/YIELD - out of range immediates for Thumb1 branches
+@ B/Bcc - out of range immediates for Thumb1 branches
@------------------------------------------------------------------------------
beq #-258
@@ -180,3 +179,11 @@ error: invalid operand for instruction
@------------------------------------------------------------------------------
pldw [r0, #4]
@ CHECK-ERRORS: error: instruction requires: mp-extensions
+
+@------------------------------------------------------------------------------
+@ LDR(lit) - invalid offsets
+@------------------------------------------------------------------------------
+
+ ldr r4, [pc, #-12]
+@ CHECK-ERRORS: error: instruction requires: thumb2
+
OpenPOWER on IntegriCloud