mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-23 20:15:35 +00:00
- 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). llvm-svn: 35573
This commit is contained in:
parent
b59fc9767b
commit
7e21418680
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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),
|
||||
|
@ -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",
|
||||
|
21
test/CodeGen/ARM/tst_teq.ll
Normal file
21
test/CodeGen/ARM/tst_teq.ll
Normal file
@ -0,0 +1,21 @@
|
||||
; RUN: llvm-as < %s | llc -march=arm &&
|
||||
; RUN: llvm-as < %s | llc -march=thumb &&
|
||||
; RUN: llvm-as < %s | llc -march=arm | grep "tst" &&
|
||||
; RUN: llvm-as < %s | llc -march=arm | grep "teq" &&
|
||||
; RUN: llvm-as < %s | llc -march=thumb | grep "tst"
|
||||
|
||||
define i32 @f(i32 %a) {
|
||||
entry:
|
||||
%tmp2 = and i32 %a, 255 ; <i32> [#uses=1]
|
||||
icmp eq i32 %tmp2, 0 ; <i1>:0 [#uses=1]
|
||||
%retval = select i1 %0, i32 20, i32 10 ; <i32> [#uses=1]
|
||||
ret i32 %retval
|
||||
}
|
||||
|
||||
define i32 @g(i32 %a) {
|
||||
entry:
|
||||
%tmp2 = xor i32 %a, 255
|
||||
icmp eq i32 %tmp2, 0 ; <i1>:0 [#uses=1]
|
||||
%retval = select i1 %0, i32 20, i32 10 ; <i32> [#uses=1]
|
||||
ret i32 %retval
|
||||
}
|
Loading…
Reference in New Issue
Block a user