diff options
Diffstat (limited to 'lib/Target')
-rw-r--r-- | lib/Target/ARM/ARMISelLowering.cpp | 16 | ||||
-rw-r--r-- | lib/Target/ARM/ARMISelLowering.h | 1 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 16 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrThumb.td | 19 |
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", |