aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2006-12-12 01:03:11 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2006-12-12 01:03:11 +0000
commitf64945d83c61e540a448de0d0d23cda67c92ebe5 (patch)
treecd95462cdaace0fd9db95c1730ef135deb27a189
parent12375467b2da620630cf6bacf90f90aacf8df7e3 (diff)
use MVN to handle small negative constants
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32459 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM/ARMISelDAGToDAG.cpp21
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td11
-rw-r--r--test/CodeGen/ARM/long.ll4
-rw-r--r--test/CodeGen/ARM/mvn.ll10
4 files changed, 39 insertions, 7 deletions
diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp
index 08864a7b6d..48d918c1d6 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<ConstantSDNode>(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 4be2b74a5e..2d1bfc0e55 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -18,6 +18,11 @@ def op_addr_mode1 : Operand<iPTR> {
let MIOperandInfo = (ops ptr_rc, ptr_rc, i32imm);
}
+def op_addr_mode1a : Operand<iPTR> {
+ let PrintMethod = "printAddrMode1";
+ let MIOperandInfo = (ops ptr_rc, ptr_rc, i32imm);
+}
+
def op_addr_mode2 : Operand<iPTR> {
let PrintMethod = "printAddrMode2";
let MIOperandInfo = (ops ptr_rc, i32imm);
@@ -33,6 +38,9 @@ def op_addr_mode5 : Operand<iPTR> {
def addr_mode1 : ComplexPattern<iPTR, 3, "SelectAddrMode1", [imm, sra, shl, srl],
[]>;
+//Addressing Mode 1a: MVN hack
+def addr_mode1a : ComplexPattern<iPTR, 3, "SelectAddrMode1a", [imm], []>;
+
//Addressing Mode 2: Load and Store Word or Unsigned Byte
def addr_mode2 : ComplexPattern<iPTR, 2, "SelectAddrMode2", [], []>;
@@ -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 33e9b31bd0..f067c517fc 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 fc788b80fd..d425498ea7 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: