This fixes three issues related to Thumb literal loads:
authorMihai Popa <mihail.popa@gmail.com>
Thu, 15 Aug 2013 15:43:06 +0000 (15:43 +0000)
committerMihai Popa <mihail.popa@gmail.com>
Thu, 15 Aug 2013 15:43:06 +0000 (15:43 +0000)
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

llvm/lib/Target/ARM/ARMInstrThumb.td
llvm/lib/Target/ARM/ARMInstrThumb2.td
llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
llvm/test/MC/ARM/basic-thumb2-instructions.s
llvm/test/MC/ARM/thumb-diagnostics.s

index d5b6563170405fe6f7b86914a5e4785017cfa3a0..7e383d2b0d1ba05f12ce2217d9025e14061e00bc 100644 (file)
@@ -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,
index 5d04d21424ef390be58ef167d1f62fe4a6384356..77a375966953643168eaa34c4a573a7bdbd8b083 100644 (file)
@@ -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",
index 03d3a48f2100db2d2efb7c4e94f52303c6a9511d..3d7baf5b28b21c25924cba44fddb62adbfae3807 100644 (file)
@@ -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;
index c7a3b1b71b2c06c0328995f3de8a4dd22f455525..61eebe698179e2d50ab1d47404ee01e04373c005 100644 (file)
@@ -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)
index 3604fc5f1ba85b56b4a29b80f24b802635e27fc1..d16f547e7293f8b18875e6b4b5033cbb71caf04e 100644 (file)
@@ -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
+