diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index 08864a7b6de..48d918c1d6c 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -781,6 +781,8 @@ public: virtual void InstructionSelectBasicBlock(SelectionDAG &DAG); bool SelectAddrMode1(SDOperand Op, SDOperand N, SDOperand &Arg, SDOperand &Shift, SDOperand &ShiftType); + bool SelectAddrMode1a(SDOperand Op, SDOperand N, SDOperand &Arg, + SDOperand &Shift, SDOperand &ShiftType); bool SelectAddrMode2(SDOperand Op, SDOperand N, SDOperand &Arg, SDOperand &Offset); bool SelectAddrMode5(SDOperand Op, SDOperand N, SDOperand &Arg, @@ -883,6 +885,25 @@ bool ARMDAGToDAGISel::SelectAddrMode1(SDOperand Op, return true; } +bool ARMDAGToDAGISel::SelectAddrMode1a(SDOperand Op, + SDOperand N, + SDOperand &Arg, + SDOperand &Shift, + SDOperand &ShiftType) { + if (N.getOpcode() != ISD::Constant) + return false; + + uint32_t val = ~cast(N)->getValue(); + if(!isRotInt8Immediate(val)) + return false; + + Arg = CurDAG->getTargetConstant(val, MVT::i32); + Shift = CurDAG->getTargetConstant(0, MVT::i32); + ShiftType = CurDAG->getTargetConstant(ARMShift::LSL, MVT::i32); + + return true; +} + bool ARMDAGToDAGISel::SelectAddrMode2(SDOperand Op, SDOperand N, SDOperand &Arg, SDOperand &Offset) { //TODO: complete and cleanup! diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 4be2b74a5eb..2d1bfc0e554 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -18,6 +18,11 @@ def op_addr_mode1 : Operand { let MIOperandInfo = (ops ptr_rc, ptr_rc, i32imm); } +def op_addr_mode1a : Operand { + let PrintMethod = "printAddrMode1"; + let MIOperandInfo = (ops ptr_rc, ptr_rc, i32imm); +} + def op_addr_mode2 : Operand { let PrintMethod = "printAddrMode2"; let MIOperandInfo = (ops ptr_rc, i32imm); @@ -33,6 +38,9 @@ def op_addr_mode5 : Operand { def addr_mode1 : ComplexPattern; +//Addressing Mode 1a: MVN hack +def addr_mode1a : ComplexPattern; + //Addressing Mode 2: Load and Store Word or Unsigned Byte def addr_mode2 : ComplexPattern; @@ -193,6 +201,9 @@ def MOV : InstARM<(ops IntRegs:$dst, op_addr_mode1:$src), def MVN : InstARM<(ops IntRegs:$dst, op_addr_mode1:$src), "mvn $dst, $src", [(set IntRegs:$dst, (not addr_mode1:$src))]>; +def MVN2 : InstARM<(ops IntRegs:$dst, op_addr_mode1:$src), + "mvn $dst, $src", [(set IntRegs:$dst, addr_mode1a:$src)]>; + def ADD : Addr1BinOp<"add", add>; def ADCS : Addr1BinOp<"adcs", adde>; def ADDS : Addr1BinOp<"adds", addc>; diff --git a/test/CodeGen/ARM/long.ll b/test/CodeGen/ARM/long.ll index 33e9b31bd0f..f067c517fcd 100644 --- a/test/CodeGen/ARM/long.ll +++ b/test/CodeGen/ARM/long.ll @@ -1,9 +1,9 @@ ; RUN: llvm-upgrade < %s | llvm-as | llc -march=arm && ; RUN: llvm-upgrade < %s | llvm-as | llc -march=arm | grep "mov r1, #0" | wc -l | grep 4 && ; RUN: llvm-upgrade < %s | llvm-as | llc -march=arm | grep "mov r0, #1" | wc -l | grep 1 && -; RUN: llvm-upgrade < %s | llvm-as | llc -march=arm | grep ".word.*2147483647" | wc -l | grep 2 && +; RUN: llvm-upgrade < %s | llvm-as | llc -march=arm | grep "mvn r0, #-2147483648" | wc -l | grep 1 && ; RUN: llvm-upgrade < %s | llvm-as | llc -march=arm | grep "mov r0, #-2147483648" | wc -l | grep 1 && -; RUN: llvm-upgrade < %s | llvm-as | llc -march=arm | grep ".word.*4294967295" | wc -l | grep 1 && +; RUN: llvm-upgrade < %s | llvm-as | llc -march=arm | grep "mvn r1, #-2147483648" | wc -l | grep 1 && ; RUN: llvm-upgrade < %s | llvm-as | llc -march=arm | grep "adds" | wc -l | grep 1 && ; RUN: llvm-upgrade < %s | llvm-as | llc -march=arm | grep "adcs" | wc -l | grep 1 && ; RUN: llvm-upgrade < %s | llvm-as | llc -march=arm | grep "subs" | wc -l | grep 1 && diff --git a/test/CodeGen/ARM/mvn.ll b/test/CodeGen/ARM/mvn.ll index fc788b80fdc..d425498ea7e 100644 --- a/test/CodeGen/ARM/mvn.ll +++ b/test/CodeGen/ARM/mvn.ll @@ -1,10 +1,10 @@ ; RUN: llvm-upgrade < %s | llvm-as | llc -march=arm && -; RUN: llvm-upgrade < %s | llvm-as | llc -march=arm | grep mvn | wc -l | grep 4 +; RUN: llvm-upgrade < %s | llvm-as | llc -march=arm | grep mvn | wc -l | grep 5 -;int %f1() { -;entry: -; ret int -1 -;} +int %f1() { +entry: + ret int -1 +} int %f2(int %a) { entry: