diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index 7597a316adc..74bfdc3da24 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -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(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(N)->getValue(); - Arg = CurDAG->getTargetConstant(t, MVT::i32); + uint32_t val = cast(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 index 00000000000..9d5fb8e637d --- /dev/null +++ b/test/CodeGen/ARM/constants.ll @@ -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 +} diff --git a/test/CodeGen/ARM/long.ll b/test/CodeGen/ARM/long.ll index f4ede17c03e..772884c8cbe 100644 --- a/test/CodeGen/ARM/long.ll +++ b/test/CodeGen/ARM/long.ll @@ -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 index 765bfca182e..00000000000 --- a/test/CodeGen/ARM/ret0.ll +++ /dev/null @@ -1,4 +0,0 @@ -; RUN: llvm-as < %s | llc -march=arm -int %test() { - ret int 0 -}