if a constant can't be an immediate, add it to the constant pool
authorRafael Espindola <rafael.espindola@gmail.com>
Thu, 21 Sep 2006 11:29:52 +0000 (11:29 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Thu, 21 Sep 2006 11:29:52 +0000 (11:29 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30566 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMISelDAGToDAG.cpp
test/CodeGen/ARM/constants.ll [new file with mode: 0644]
test/CodeGen/ARM/long.ll
test/CodeGen/ARM/ret0.ll [deleted file]

index 7597a316adce0985fa5472b9c28383a088d8aa5d..74bfdc3da249d9b163fc6efb2679b4e3b03e9a58 100644 (file)
@@ -16,6 +16,7 @@
 #include "llvm/CallingConv.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Function.h"
+#include "llvm/Constants.h"
 #include "llvm/Intrinsics.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
@@ -466,7 +467,7 @@ static bool isInt12Immediate(SDNode *N, short &Imm) {
     return false;
 
   int32_t t = cast<ConstantSDNode>(N)->getValue();
-  int max = 2<<12 - 1;
+  int max = 1<<12;
   int min = -max;
   if (t > min && t < max) {
     Imm = t;
@@ -480,15 +481,44 @@ static bool isInt12Immediate(SDOperand Op, short &Imm) {
   return isInt12Immediate(Op.Val, Imm);
 }
 
+static uint32_t rotateL(uint32_t x) {
+  uint32_t bit31 = (x & (1 << 31)) >> 31;
+  uint32_t     t = x << 1;
+  return t | bit31;
+}
+
+static bool isUInt8Immediate(uint32_t x) {
+  return x < (1 << 8);
+}
+
+static bool isRotInt8Immediate(uint32_t x) {
+  int r;
+  for (r = 0; r < 16; r++) {
+    if (isUInt8Immediate(x))
+      return true;
+    x = rotateL(rotateL(x));
+  }
+  return false;
+}
+
 bool ARMDAGToDAGISel::SelectAddrMode1(SDOperand N,
                                      SDOperand &Arg,
                                      SDOperand &Shift,
                                      SDOperand &ShiftType) {
   switch(N.getOpcode()) {
   case ISD::Constant: {
-    //TODO:check that we have a valid constant
-    int32_t t = cast<ConstantSDNode>(N)->getValue();
-    Arg       = CurDAG->getTargetConstant(t,             MVT::i32);
+    uint32_t val = cast<ConstantSDNode>(N)->getValue();
+    if(!isRotInt8Immediate(val)) {
+      const Type  *t =  MVT::getTypeForValueType(MVT::i32);
+      Constant    *C = ConstantUInt::get(t, val);
+      int  alignment = 2;
+      SDOperand Addr = CurDAG->getTargetConstantPool(C, MVT::i32, alignment);
+      SDOperand    Z = CurDAG->getTargetConstant(0,     MVT::i32);
+      SDNode      *n = CurDAG->getTargetNode(ARM::ldr,  MVT::i32, Z, Addr);
+      Arg            = SDOperand(n, 0);
+    } else
+      Arg            = CurDAG->getTargetConstant(val,    MVT::i32);
+
     Shift     = CurDAG->getTargetConstant(0,             MVT::i32);
     ShiftType = CurDAG->getTargetConstant(ARMShift::LSL, MVT::i32);
     return true;
diff --git a/test/CodeGen/ARM/constants.ll b/test/CodeGen/ARM/constants.ll
new file mode 100644 (file)
index 0000000..9d5fb8e
--- /dev/null
@@ -0,0 +1,31 @@
+; RUN: llvm-as < %s | llc -march=arm &&
+; RUN: llvm-as < %s | llc -march=arm | grep "mov r0, #0" | wc -l | grep 1 &&
+; RUN: llvm-as < %s | llc -march=arm | grep "mov r0, #255" | wc -l | grep 1 &&
+; RUN: llvm-as < %s | llc -march=arm | grep "mov r0, #256" | wc -l | grep 1 &&
+; RUN: llvm-as < %s | llc -march=arm | grep ".word.*257" | wc -l | grep 1 &&
+; RUN: llvm-as < %s | llc -march=arm | grep "mov r0, #-1073741761" | wc -l | grep 1 &&
+; RUN: llvm-as < %s | llc -march=arm | grep "mov r0, #1008" | wc -l | grep 1
+
+uint %f1() {
+  ret uint 0
+}
+
+uint %f2() {
+  ret uint 255
+}
+
+uint %f3() {
+  ret uint 256
+}
+
+uint %f4() {
+  ret uint 257
+}
+
+uint %f5() {
+  ret uint 3221225535
+}
+
+uint %f6() {
+  ret uint 1008
+}
index f4ede17c03eeea6b86736f4e6b791973920e4673..772884c8cbece62b29c9862886e99ba353798b08 100644 (file)
@@ -1,10 +1,9 @@
 ; RUN: llvm-as < %s | llc -march=arm &&
 ; RUN: llvm-as < %s | llc -march=arm | grep "mov r1, #0" | wc -l | grep 4 &&
 ; RUN: llvm-as < %s | llc -march=arm | grep "mov r0, #1" | wc -l | grep 1 &&
-; RUN: llvm-as < %s | llc -march=arm | grep "mov r0, #2147483647" | wc -l | grep 1 &&
+; RUN: llvm-as < %s | llc -march=arm | grep ".word.*2147483647" | wc -l | grep 2 &&
 ; RUN: llvm-as < %s | llc -march=arm | grep "mov r0, #-2147483648" | wc -l | grep 1 &&
-; RUN: llvm-as < %s | llc -march=arm | grep "mov r0, #-1" | wc -l | grep 1 &&
-; RUN: llvm-as < %s | llc -march=arm | grep "mov r1, #2147483647" | wc -l | grep 1
+; RUN: llvm-as < %s | llc -march=arm | grep ".word.*4294967295" | wc -l | grep 1
 
 long %f1() {
 entry:
diff --git a/test/CodeGen/ARM/ret0.ll b/test/CodeGen/ARM/ret0.ll
deleted file mode 100644 (file)
index 765bfca..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-; RUN: llvm-as < %s | llc -march=arm
-int %test() {
-  ret int 0
-}