implement missing compares

patch by Lauro
bug fixed by me


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32795 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Rafael Espindola
2006-12-31 18:52:39 +00:00
parent 1fd79b8c42
commit 9985f9f61e
3 changed files with 78 additions and 38 deletions

View File

@@ -151,59 +151,62 @@ namespace llvm {
/// DAGFPCCToARMCC - Convert a DAG fp condition code to an ARM CC /// DAGFPCCToARMCC - Convert a DAG fp condition code to an ARM CC
// Unordered = !N & !Z & C & V = V // Unordered = !N & !Z & C & V = V
// Ordered = N | Z | !C | !V = N | Z | !V // Ordered = N | Z | !C | !V = N | Z | !V
static ARMCC::CondCodes DAGFPCCToARMCC(ISD::CondCode CC) { static std::vector<unsigned> DAGFPCCToARMCC(ISD::CondCode CC) {
switch (CC) { switch (CC) {
default: default:
assert(0 && "Unknown fp condition code!"); assert(0 && "Unknown fp condition code!");
// SETOEQ = (N | Z | !V) & Z = Z = EQ // SETOEQ = (N | Z | !V) & Z = Z = EQ
case ISD::SETEQ: case ISD::SETEQ:
case ISD::SETOEQ: return ARMCC::EQ; case ISD::SETOEQ: return make_vector<unsigned>(ARMCC::EQ, 0);
// SETOGT = (N | Z | !V) & !N & !Z = !V &!N &!Z = (N = V) & !Z = GT // SETOGT = (N | Z | !V) & !N & !Z = !V &!N &!Z = (N = V) & !Z = GT
case ISD::SETGT: case ISD::SETGT:
case ISD::SETOGT: return ARMCC::GT; case ISD::SETOGT: return make_vector<unsigned>(ARMCC::GT, 0);
// SETOGE = (N | Z | !V) & !N = (Z | !V) & !N = !V & !N = GE // SETOGE = (N | Z | !V) & !N = (Z | !V) & !N = !V & !N = GE
case ISD::SETGE: case ISD::SETGE:
case ISD::SETOGE: return ARMCC::GE; case ISD::SETOGE: return make_vector<unsigned>(ARMCC::GE, 0);
// SETOLT = (N | Z | !V) & N = N = MI // SETOLT = (N | Z | !V) & N = N = MI
case ISD::SETLT: case ISD::SETLT:
case ISD::SETOLT: return ARMCC::MI; case ISD::SETOLT: return make_vector<unsigned>(ARMCC::MI, 0);
// SETOLE = (N | Z | !V) & (N | Z) = N | Z = !C | Z = LS // SETOLE = (N | Z | !V) & (N | Z) = N | Z = !C | Z = LS
case ISD::SETLE: case ISD::SETLE:
case ISD::SETOLE: return ARMCC::LS; case ISD::SETOLE: return make_vector<unsigned>(ARMCC::LS, 0);
// SETONE = (N | Z | !V) & !Z = (N | !V) & !Z = !V & !Z = !Z = NE // SETONE = OGT | OLT
case ISD::SETNE: case ISD::SETONE: return make_vector<unsigned>(ARMCC::GT, ARMCC::MI, 0);
case ISD::SETONE: return ARMCC::NE;
// SETO = N | Z | !V = Z | !V = !V = VC // SETO = N | Z | !V = Z | !V = !V = VC
case ISD::SETO: return ARMCC::VC; case ISD::SETO: return make_vector<unsigned>(ARMCC::VC, 0);
// SETUO = V = VS // SETUO = V = VS
case ISD::SETUO: return ARMCC::VS; case ISD::SETUO: return make_vector<unsigned>(ARMCC::VS, 0);
// SETUEQ = V | Z = ?? // SETUEQ = V | Z (need two instructions) = EQ/VS
case ISD::SETUEQ: return make_vector<unsigned>(ARMCC::EQ, ARMCC::VS, 0);
// SETUGT = V | (!Z & !N) = !Z & !N = !Z & C = HI // SETUGT = V | (!Z & !N) = !Z & !N = !Z & C = HI
case ISD::SETUGT: return ARMCC::HI; case ISD::SETUGT: return make_vector<unsigned>(ARMCC::HI, 0);
// SETUGE = V | !N = !N = PL // SETUGE = V | !N = !N = PL
case ISD::SETUGE: return ARMCC::PL; case ISD::SETUGE: return make_vector<unsigned>(ARMCC::PL, 0);
// SETULT = V | N = ?? // SETULT = V | N = LT
// SETULE = V | Z | N = ?? case ISD::SETULT: return make_vector<unsigned>(ARMCC::LT, 0);
// SETULE = V | Z | N = LE
case ISD::SETULE: return make_vector<unsigned>(ARMCC::LE, 0);
// SETUNE = V | !Z = !Z = NE // SETUNE = V | !Z = !Z = NE
case ISD::SETUNE: return ARMCC::NE; case ISD::SETNE:
case ISD::SETUNE: return make_vector<unsigned>(ARMCC::NE, 0);
} }
} }
/// DAGIntCCToARMCC - Convert a DAG integer condition code to an ARM CC /// DAGIntCCToARMCC - Convert a DAG integer condition code to an ARM CC
static ARMCC::CondCodes DAGIntCCToARMCC(ISD::CondCode CC) { static std::vector<unsigned> DAGIntCCToARMCC(ISD::CondCode CC) {
switch (CC) { switch (CC) {
default: default:
assert(0 && "Unknown integer condition code!"); assert(0 && "Unknown integer condition code!");
case ISD::SETEQ: return ARMCC::EQ; case ISD::SETEQ: return make_vector<unsigned>(ARMCC::EQ, 0);
case ISD::SETNE: return ARMCC::NE; case ISD::SETNE: return make_vector<unsigned>(ARMCC::NE, 0);
case ISD::SETLT: return ARMCC::LT; case ISD::SETLT: return make_vector<unsigned>(ARMCC::LT, 0);
case ISD::SETLE: return ARMCC::LE; case ISD::SETLE: return make_vector<unsigned>(ARMCC::LE, 0);
case ISD::SETGT: return ARMCC::GT; case ISD::SETGT: return make_vector<unsigned>(ARMCC::GT, 0);
case ISD::SETGE: return ARMCC::GE; case ISD::SETGE: return make_vector<unsigned>(ARMCC::GE, 0);
case ISD::SETULT: return ARMCC::CC; case ISD::SETULT: return make_vector<unsigned>(ARMCC::CC, 0);
case ISD::SETULE: return ARMCC::LS; case ISD::SETULE: return make_vector<unsigned>(ARMCC::LS, 0);
case ISD::SETUGT: return ARMCC::HI; case ISD::SETUGT: return make_vector<unsigned>(ARMCC::HI, 0);
case ISD::SETUGE: return ARMCC::CS; case ISD::SETUGE: return make_vector<unsigned>(ARMCC::CS, 0);
} }
} }
@@ -653,13 +656,20 @@ static SDOperand GetCMP(ISD::CondCode CC, SDOperand LHS, SDOperand RHS,
return Cmp; return Cmp;
} }
static SDOperand GetARMCC(ISD::CondCode CC, MVT::ValueType vt, static std::vector<SDOperand> GetARMCC(ISD::CondCode CC, MVT::ValueType vt,
SelectionDAG &DAG) { SelectionDAG &DAG) {
assert(vt == MVT::i32 || vt == MVT::f32 || vt == MVT::f64); assert(vt == MVT::i32 || vt == MVT::f32 || vt == MVT::f64);
std::vector<unsigned> vcc;
if (vt == MVT::i32) if (vt == MVT::i32)
return DAG.getConstant(DAGIntCCToARMCC(CC), MVT::i32); vcc = DAGIntCCToARMCC(CC);
else else
return DAG.getConstant(DAGFPCCToARMCC(CC), MVT::i32); vcc = DAGFPCCToARMCC(CC);
std::vector<unsigned>::iterator it;
std::vector<SDOperand> result;
for( it = vcc.begin(); it != vcc.end(); it++ )
result.push_back(DAG.getConstant(*it,MVT::i32));
return result;
} }
static bool isUInt8Immediate(uint32_t x) { static bool isUInt8Immediate(uint32_t x) {
@@ -682,8 +692,9 @@ static bool isRotInt8Immediate(uint32_t x) {
return false; return false;
} }
static void LowerCMP(SDOperand &Cmp, SDOperand &ARMCC, SDOperand LHS, static void LowerCMP(SDOperand &Cmp, std::vector<SDOperand> &ARMCC,
SDOperand RHS, ISD::CondCode CC, SelectionDAG &DAG) { SDOperand LHS, SDOperand RHS, ISD::CondCode CC,
SelectionDAG &DAG) {
MVT::ValueType vt = LHS.getValueType(); MVT::ValueType vt = LHS.getValueType();
if (vt == MVT::i32) { if (vt == MVT::i32) {
assert(!isa<ConstantSDNode>(LHS)); assert(!isa<ConstantSDNode>(LHS));
@@ -745,9 +756,18 @@ static SDOperand LowerSELECT_CC(SDOperand Op, SelectionDAG &DAG) {
SDOperand TrueVal = Op.getOperand(2); SDOperand TrueVal = Op.getOperand(2);
SDOperand FalseVal = Op.getOperand(3); SDOperand FalseVal = Op.getOperand(3);
SDOperand Cmp; SDOperand Cmp;
SDOperand ARMCC; std::vector<SDOperand> ARMCC;
LowerCMP(Cmp, ARMCC, LHS, RHS, CC, DAG); LowerCMP(Cmp, ARMCC, LHS, RHS, CC, DAG);
return DAG.getNode(ARMISD::SELECT, Op.getValueType(), TrueVal, FalseVal, ARMCC, Cmp);
SDOperand Aux = FalseVal;
SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Flag);
std::vector<SDOperand>::iterator it;
for (it = ARMCC.begin(); it != ARMCC.end(); ++it){
SDOperand Flag = it == ARMCC.begin() ? Cmp : Aux.getValue(1);
SDOperand Ops[] = {TrueVal, Aux, *it, Flag};
Aux = DAG.getNode(ARMISD::SELECT, VTs, Ops, 4);
}
return Aux;
} }
static SDOperand LowerBR_CC(SDOperand Op, SelectionDAG &DAG) { static SDOperand LowerBR_CC(SDOperand Op, SelectionDAG &DAG) {
@@ -757,9 +777,18 @@ static SDOperand LowerBR_CC(SDOperand Op, SelectionDAG &DAG) {
SDOperand RHS = Op.getOperand(3); SDOperand RHS = Op.getOperand(3);
SDOperand Dest = Op.getOperand(4); SDOperand Dest = Op.getOperand(4);
SDOperand Cmp; SDOperand Cmp;
SDOperand ARMCC; std::vector<SDOperand> ARMCC;
LowerCMP(Cmp, ARMCC, LHS, RHS, CC, DAG); LowerCMP(Cmp, ARMCC, LHS, RHS, CC, DAG);
return DAG.getNode(ARMISD::BR, MVT::Other, Chain, Dest, ARMCC, Cmp);
SDOperand Aux = Chain;
SDVTList VTs = DAG.getVTList(MVT::Other, MVT::Flag);
std::vector<SDOperand>::iterator it;
for (it = ARMCC.begin(); it != ARMCC.end(); it++){
SDOperand Flag = it == ARMCC.begin() ? Cmp : Aux.getValue(1);
SDOperand Ops[] = {Aux, Dest, *it, Flag};
Aux = DAG.getNode(ARMISD::BR, VTs, Ops, 4);
}
return Aux;
} }
static SDOperand LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) { static SDOperand LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) {

View File

@@ -109,7 +109,7 @@ def SDTarmfmstat : SDTypeProfile<0, 0, []>;
def armfmstat : SDNode<"ARMISD::FMSTAT", SDTarmfmstat, [SDNPInFlag, SDNPOutFlag]>; def armfmstat : SDNode<"ARMISD::FMSTAT", SDTarmfmstat, [SDNPInFlag, SDNPOutFlag]>;
def SDTarmbr : SDTypeProfile<0, 2, [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>; def SDTarmbr : SDTypeProfile<0, 2, [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>;
def armbr : SDNode<"ARMISD::BR", SDTarmbr, [SDNPHasChain, SDNPInFlag]>; def armbr : SDNode<"ARMISD::BR", SDTarmbr, [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
def SDTVoidBinOp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>; def SDTVoidBinOp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
def armcmp : SDNode<"ARMISD::CMP", SDTVoidBinOp, [SDNPOutFlag]>; def armcmp : SDNode<"ARMISD::CMP", SDTVoidBinOp, [SDNPOutFlag]>;

View File

@@ -0,0 +1,11 @@
; RUN: llvm-as < %s | llc -march=arm &&
; RUN: llvm-as < %s | llc -march=arm | grep moveq &&
; RUN: llvm-as < %s | llc -march=arm | grep movvs
define i32 %f7(float %a, float %b) {
entry:
%tmp = fcmp ueq float %a,%b
%retval = select bool %tmp, i32 666, i32 42
ret i32 %retval
}