Allow large immediates for branch instructions in 32bit mode.
authorJoerg Sonnenberger <joerg@bec.de>
Fri, 8 Aug 2014 20:57:58 +0000 (20:57 +0000)
committerJoerg Sonnenberger <joerg@bec.de>
Fri, 8 Aug 2014 20:57:58 +0000 (20:57 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@215240 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
test/MC/PowerPC/ppc32-ba.s [new file with mode: 0644]

index f99a3aa66340bb49b9cff011e6a282cd9c2bdb57..ae24c8a88e601fd3774d2796aea965b6b62d02ae 100644 (file)
@@ -432,9 +432,23 @@ public:
   bool isS17Imm() const { return Kind == Expression ||
                                  (Kind == Immediate && isInt<17>(getImm())); }
   bool isTLSReg() const { return Kind == TLSRegister; }
-  bool isDirectBr() const { return Kind == Expression ||
-                                   (Kind == Immediate && isInt<26>(getImm()) &&
-                                    (getImm() & 3) == 0); }
+  bool isDirectBr() const {
+    if (Kind == Expression)
+      return true;
+    if (Kind != Immediate)
+      return false;
+    // Operand must be 64-bit aligned, signed 27-bit immediate.
+    if ((getImm() & 3) != 0)
+      return false;
+    if (isInt<26>(getImm()))
+      return true;
+    if (!IsPPC64) {
+      // In 32-bit mode, large 32-bit quantities wrap around.
+      if (isUInt<32>(getImm()) && isInt<26>(static_cast<int32_t>(getImm())))
+        return true;
+    }
+    return false;
+  }
   bool isCondBr() const { return Kind == Expression ||
                                  (Kind == Immediate && isInt<16>(getImm()) &&
                                   (getImm() & 3) == 0); }
diff --git a/test/MC/PowerPC/ppc32-ba.s b/test/MC/PowerPC/ppc32-ba.s
new file mode 100644 (file)
index 0000000..133423b
--- /dev/null
@@ -0,0 +1,6 @@
+# RUN: llvm-mc -triple powerpc-unknown-unknown --show-encoding %s | FileCheck %s
+
+# Check that large immediates in 32bit mode are accepted.
+
+# CHECK: ba -33554432 # encoding: [0x4a,0x00,0x00,0x02]
+         ba 0xfe000000