aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target
diff options
context:
space:
mode:
authorLauro Ramos Venancio <lauro.venancio@gmail.com>2007-04-02 01:30:03 +0000
committerLauro Ramos Venancio <lauro.venancio@gmail.com>2007-04-02 01:30:03 +0000
commit9996663fc6d50128a4897ff3568d311496e9d944 (patch)
treee3c0545c67db1ab7dbb9c1af9935e84e2ea45f8b /lib/Target
parent086f18626750482318612a10c3027b946b4e36e4 (diff)
downloadexternal_llvm-9996663fc6d50128a4897ff3568d311496e9d944.zip
external_llvm-9996663fc6d50128a4897ff3568d311496e9d944.tar.gz
external_llvm-9996663fc6d50128a4897ff3568d311496e9d944.tar.bz2
- Divides the comparisons in two types: comparisons that only use N and Z
flags (ARMISD::CMPNZ) and comparisons that use all flags (ARMISD::CMP). - Defines the instructions: TST, TEQ (ARM) and TST (Thumb). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35573 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp16
-rw-r--r--lib/Target/ARM/ARMISelLowering.h1
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td16
-rw-r--r--lib/Target/ARM/ARMInstrThumb.td19
4 files changed, 45 insertions, 7 deletions
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index bb715cb..8f3457a 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -266,6 +266,7 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {
case ARMISD::RET_FLAG: return "ARMISD::RET_FLAG";
case ARMISD::PIC_ADD: return "ARMISD::PIC_ADD";
case ARMISD::CMP: return "ARMISD::CMP";
+ case ARMISD::CMPNZ: return "ARMISD::CMPNZ";
case ARMISD::CMPFP: return "ARMISD::CMPFP";
case ARMISD::CMPFPw0: return "ARMISD::CMPFPw0";
case ARMISD::FMSTAT: return "ARMISD::FMSTAT";
@@ -946,8 +947,21 @@ static SDOperand getARMCmp(SDOperand LHS, SDOperand RHS, ISD::CondCode CC,
}
ARMCC::CondCodes CondCode = IntCCToARMCC(CC);
+ ARMISD::NodeType CompareType;
+ switch (CondCode) {
+ default:
+ CompareType = ARMISD::CMP;
+ break;
+ case ARMCC::EQ:
+ case ARMCC::NE:
+ case ARMCC::MI:
+ case ARMCC::PL:
+ // Uses only N and Z Flags
+ CompareType = ARMISD::CMPNZ;
+ break;
+ }
ARMCC = DAG.getConstant(CondCode, MVT::i32);
- return DAG.getNode(ARMISD::CMP, MVT::Flag, LHS, RHS);
+ return DAG.getNode(CompareType, MVT::Flag, LHS, RHS);
}
/// Returns a appropriate VFP CMP (fcmp{s|d}+fmstat) for the given operands.
diff --git a/lib/Target/ARM/ARMISelLowering.h b/lib/Target/ARM/ARMISelLowering.h
index 8846dec..9842b92 100644
--- a/lib/Target/ARM/ARMISelLowering.h
+++ b/lib/Target/ARM/ARMISelLowering.h
@@ -43,6 +43,7 @@ namespace llvm {
PIC_ADD, // Add with a PC operand and a PIC label.
CMP, // ARM compare instructions.
+ CMPNZ, // ARM compare that uses only N or Z flags.
CMPFP, // ARM VFP compare instruction, sets FPSCR.
CMPFPw0, // ARM VFP compare against zero instruction, sets FPSCR.
FMSTAT, // ARM fmstat instruction.
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index 36d2e4a..1c3e34b 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -70,6 +70,9 @@ def ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp,
[SDNPOutFlag]>;
+def ARMcmpNZ : SDNode<"ARMISD::CMPNZ", SDT_ARMCmp,
+ [SDNPOutFlag]>;
+
def ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
def ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
@@ -1023,10 +1026,15 @@ def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
(CMNri GPR:$src, so_imm_neg:$imm)>;
// Note that TST/TEQ don't set all the same flags that CMP does!
-def TSTrr : AI1<(ops GPR:$a, so_reg:$b), "tst $a, $b", []>;
-def TSTri : AI1<(ops GPR:$a, so_imm:$b), "tst $a, $b", []>;
-def TEQrr : AI1<(ops GPR:$a, so_reg:$b), "teq $a, $b", []>;
-def TEQri : AI1<(ops GPR:$a, so_imm:$b), "teq $a, $b", []>;
+defm TST : AI1_bin0_irs<"tst", BinOpFrag<(ARMcmpNZ (and node:$LHS, node:$RHS), 0)>>;
+defm TEQ : AI1_bin0_irs<"teq", BinOpFrag<(ARMcmpNZ (xor node:$LHS, node:$RHS), 0)>>;
+
+defm CMPnz : AI1_bin0_irs<"cmp", BinOpFrag<(ARMcmpNZ node:$LHS, node:$RHS)>>;
+defm CMNnz : AI1_bin0_irs<"cmn", BinOpFrag<(ARMcmpNZ node:$LHS,(ineg node:$RHS))>>;
+
+def : ARMPat<(ARMcmpNZ GPR:$src, so_imm_neg:$imm),
+ (CMNri GPR:$src, so_imm_neg:$imm)>;
+
// Conditional moves
def MOVCCr : AI<(ops GPR:$dst, GPR:$false, GPR:$true, CCOp:$cc),
diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td
index ad8a88f..4819636 100644
--- a/lib/Target/ARM/ARMInstrThumb.td
+++ b/lib/Target/ARM/ARMInstrThumb.td
@@ -356,7 +356,23 @@ def tCMPi8 : TI<(ops GPR:$lhs, i32imm:$rhs),
def tCMPr : TI<(ops GPR:$lhs, GPR:$rhs),
"cmp $lhs, $rhs",
[(ARMcmp GPR:$lhs, GPR:$rhs)]>;
-
+
+def tTST : TI<(ops GPR:$lhs, GPR:$rhs),
+ "tst $lhs, $rhs",
+ [(ARMcmpNZ (and GPR:$lhs, GPR:$rhs), 0)]>;
+
+def tCMNNZ : TI<(ops GPR:$lhs, GPR:$rhs),
+ "cmn $lhs, $rhs",
+ [(ARMcmpNZ GPR:$lhs, (ineg GPR:$rhs))]>;
+
+def tCMPNZi8 : TI<(ops GPR:$lhs, i32imm:$rhs),
+ "cmp $lhs, $rhs",
+ [(ARMcmpNZ GPR:$lhs, imm0_255:$rhs)]>;
+
+def tCMPNZr : TI<(ops GPR:$lhs, GPR:$rhs),
+ "cmp $lhs, $rhs",
+ [(ARMcmpNZ GPR:$lhs, GPR:$rhs)]>;
+
// TODO: A7-37: CMP(3) - cmp hi regs
def tEOR : TIt<(ops GPR:$dst, GPR:$lhs, GPR:$rhs),
@@ -472,7 +488,6 @@ def tSXTH : TI<(ops GPR:$dst, GPR:$src),
[(set GPR:$dst, (sext_inreg GPR:$src, i16))]>,
Requires<[IsThumb, HasV6]>;
-// TODO: A7-122: TST - test.
def tUXTB : TI<(ops GPR:$dst, GPR:$src),
"uxtb $dst, $src",