diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index 0aacd674d62..cc835df15b3 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -485,6 +485,7 @@ unsigned ARMDAGToDAGISel::ConstantMaterializationCost(unsigned Val) const { if (Subtarget->isThumb()) { if (Val <= 255) return 1; // MOV if (Subtarget->hasV6T2Ops() && Val <= 0xffff) return 1; // MOVW + if (Val <= 511) return 2; // MOV + ADDi8 if (~Val <= 255) return 2; // MOV + MVN if (ARM_AM::isThumbImmShiftedVal(Val)) return 2; // MOV + LSL } else { diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td index 52a376cd8b6..e9b49f90ecb 100644 --- a/lib/Target/ARM/ARMInstrThumb.td +++ b/lib/Target/ARM/ARMInstrThumb.td @@ -66,6 +66,14 @@ def thumb_immshifted_shamt : SDNodeXFormgetTargetConstant(V, SDLoc(N), MVT::i32); }]>; +def imm256_511 : ImmLeaf= 256 && Imm < 512; +}]>; + +def thumb_imm256_511_addend : SDNodeXFormgetTargetConstant(N->getZExtValue() - 255, SDLoc(N), MVT::i32); +}]>; + // Scaled 4 immediate. def t_imm0_1020s4_asmoperand: AsmOperandClass { let Name = "Imm0_1020s4"; } def t_imm0_1020s4 : Operand { @@ -1489,6 +1497,10 @@ def : T1Pat<(i32 thumb_immshifted:$src), def : T1Pat<(i32 imm0_255_comp:$src), (tMVN (tMOVi8 (imm_comp_XFORM imm:$src)))>; +def : T1Pat<(i32 imm256_511:$src), + (tADDi8 (tMOVi8 255), + (thumb_imm256_511_addend imm:$src))>; + // Pseudo instruction that combines ldr from constpool and add pc. This should // be expanded into two instructions late to allow if-conversion and // scheduling. diff --git a/test/CodeGen/Thumb/constants.ll b/test/CodeGen/Thumb/constants.ll new file mode 100644 index 00000000000..34c08139602 --- /dev/null +++ b/test/CodeGen/Thumb/constants.ll @@ -0,0 +1,11 @@ +; RUN: llc < %s -mtriple=thumbv7-linux-gnueabi -mcpu=cortex-m0 -verify-machineinstrs | FileCheck --check-prefix CHECK-T1 %s +; RUN: llc < %s -mtriple=thumbv7-linux-gnueabi -mcpu=cortex-m3 -verify-machineinstrs | FileCheck --check-prefix CHECK-T2 %s + +; CHECK-T1-LABEL: @mov_and_add +; CHECK-T2-LABEL: @mov_and_add +; CHECK-T1: movs r0, #255 +; CHECK-T1: adds r0, #12 +; CHECK-T2: movw r0, #267 +define i32 @mov_and_add() { + ret i32 267 +}