parent
d4f440de0f
commit
8ec0a2b13a
|
@ -288,6 +288,9 @@ namespace {
|
||||||
static const unsigned notIn = (unsigned)(-1);
|
static const unsigned notIn = (unsigned)(-1);
|
||||||
std::map<SDOperand, unsigned> ExprMap;
|
std::map<SDOperand, unsigned> ExprMap;
|
||||||
|
|
||||||
|
//CCInvMap sometimes (SetNE) we have the inverse CC code for free
|
||||||
|
std::map<SDOperand, unsigned> CCInvMap;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ISel(TargetMachine &TM) : SelectionDAGISel(AlphaLowering), AlphaLowering(TM) {
|
ISel(TargetMachine &TM) : SelectionDAGISel(AlphaLowering), AlphaLowering(TM) {
|
||||||
}
|
}
|
||||||
|
@ -300,6 +303,7 @@ namespace {
|
||||||
|
|
||||||
// Clear state used for selection.
|
// Clear state used for selection.
|
||||||
ExprMap.clear();
|
ExprMap.clear();
|
||||||
|
CCInvMap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned SelectExpr(SDOperand N);
|
unsigned SelectExpr(SDOperand N);
|
||||||
|
@ -307,6 +311,7 @@ namespace {
|
||||||
void Select(SDOperand N);
|
void Select(SDOperand N);
|
||||||
|
|
||||||
void SelectAddr(SDOperand N, unsigned& Reg, long& offset);
|
void SelectAddr(SDOperand N, unsigned& Reg, long& offset);
|
||||||
|
void SelectBranchCC(SDOperand N);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,6 +359,115 @@ void ISel::SelectAddr(SDOperand N, unsigned& Reg, long& offset)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ISel::SelectBranchCC(SDOperand N)
|
||||||
|
{
|
||||||
|
assert(N.getOpcode() == ISD::BRCOND && "Not a BranchCC???");
|
||||||
|
MachineBasicBlock *Dest = cast<BasicBlockSDNode>(N.getOperand(2))->getBasicBlock();
|
||||||
|
unsigned Opc;
|
||||||
|
|
||||||
|
Select(N.getOperand(0)); //chain
|
||||||
|
SDOperand CC = N.getOperand(1);
|
||||||
|
|
||||||
|
if (CC.getOpcode() == ISD::SETCC)
|
||||||
|
{
|
||||||
|
SetCCSDNode* SetCC = dyn_cast<SetCCSDNode>(CC.Val);
|
||||||
|
if (MVT::isInteger(SetCC->getOperand(0).getValueType())) {
|
||||||
|
//Dropping the CC is only useful if we are comparing to 0
|
||||||
|
bool isZero0 = false;
|
||||||
|
bool isZero1 = false;
|
||||||
|
bool isNE = false;
|
||||||
|
|
||||||
|
if(SetCC->getOperand(0).getOpcode() == ISD::Constant &&
|
||||||
|
cast<ConstantSDNode>(SetCC->getOperand(0))->getValue() == 0)
|
||||||
|
isZero0 = true;
|
||||||
|
if(SetCC->getOperand(1).getOpcode() == ISD::Constant &&
|
||||||
|
cast<ConstantSDNode>(SetCC->getOperand(1))->getValue() == 0)
|
||||||
|
isZero1 = true;
|
||||||
|
if(SetCC->getCondition() == ISD::SETNE)
|
||||||
|
isNE = true;
|
||||||
|
|
||||||
|
if (isZero0)
|
||||||
|
{
|
||||||
|
switch (SetCC->getCondition()) {
|
||||||
|
default: CC.Val->dump(); assert(0 && "Unknown integer comparison!");
|
||||||
|
case ISD::SETEQ: Opc = Alpha::BEQ; break;
|
||||||
|
case ISD::SETLT: Opc = Alpha::BGT; break;
|
||||||
|
case ISD::SETLE: Opc = Alpha::BGE; break;
|
||||||
|
case ISD::SETGT: Opc = Alpha::BLT; break;
|
||||||
|
case ISD::SETGE: Opc = Alpha::BLE; break;
|
||||||
|
case ISD::SETULT: Opc = Alpha::BNE; break;
|
||||||
|
case ISD::SETUGT: assert(0 && "0 > (unsigned) x is never true"); break;
|
||||||
|
case ISD::SETULE: assert(0 && "0 <= (unsigned) x is always true"); break;
|
||||||
|
case ISD::SETUGE: Opc = Alpha::BEQ; break; //Technically you could have this CC
|
||||||
|
case ISD::SETNE: Opc = Alpha::BNE; break;
|
||||||
|
}
|
||||||
|
unsigned Tmp1 = SelectExpr(SetCC->getOperand(1));
|
||||||
|
BuildMI(BB, Opc, 2).addReg(Tmp1).addMBB(Dest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (isZero1)
|
||||||
|
{
|
||||||
|
switch (SetCC->getCondition()) {
|
||||||
|
default: CC.Val->dump(); assert(0 && "Unknown integer comparison!");
|
||||||
|
case ISD::SETEQ: Opc = Alpha::BEQ; break;
|
||||||
|
case ISD::SETLT: Opc = Alpha::BLT; break;
|
||||||
|
case ISD::SETLE: Opc = Alpha::BLE; break;
|
||||||
|
case ISD::SETGT: Opc = Alpha::BGT; break;
|
||||||
|
case ISD::SETGE: Opc = Alpha::BGE; break;
|
||||||
|
case ISD::SETULT: assert(0 && "x (unsigned) < 0 is never true"); break;
|
||||||
|
case ISD::SETUGT: Opc = Alpha::BNE; break;
|
||||||
|
case ISD::SETULE: Opc = Alpha::BEQ; break; //Technically you could have this CC
|
||||||
|
case ISD::SETUGE: assert(0 && "x (unsgined >= 0 is always true"); break;
|
||||||
|
case ISD::SETNE: Opc = Alpha::BNE; break;
|
||||||
|
}
|
||||||
|
unsigned Tmp1 = SelectExpr(SetCC->getOperand(0));
|
||||||
|
BuildMI(BB, Opc, 2).addReg(Tmp1).addMBB(Dest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned Tmp1 = SelectExpr(CC);
|
||||||
|
if (isNE)
|
||||||
|
BuildMI(BB, Alpha::BEQ, 2).addReg(CCInvMap[CC]).addMBB(Dest);
|
||||||
|
else
|
||||||
|
BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else { //FP
|
||||||
|
//Any comparison between 2 values should be codegened as an folded branch, as moving
|
||||||
|
//CC to the integer register is very expensive
|
||||||
|
//for a cmp b: c = a - b;
|
||||||
|
//a = b: c = 0
|
||||||
|
//a < b: c < 0
|
||||||
|
//a > b: c > 0
|
||||||
|
unsigned Tmp1 = SelectExpr(SetCC->getOperand(0));
|
||||||
|
unsigned Tmp2 = SelectExpr(SetCC->getOperand(1));
|
||||||
|
unsigned Tmp3 = MakeReg(MVT::f64);
|
||||||
|
BuildMI(BB, Alpha::SUBT, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
|
||||||
|
|
||||||
|
switch (SetCC->getCondition()) {
|
||||||
|
default: CC.Val->dump(); assert(0 && "Unknown FP comparison!");
|
||||||
|
case ISD::SETEQ: Opc = Alpha::FBEQ; break;
|
||||||
|
case ISD::SETLT: Opc = Alpha::FBLT; break;
|
||||||
|
case ISD::SETLE: Opc = Alpha::FBLE; break;
|
||||||
|
case ISD::SETGT: Opc = Alpha::FBGT; break;
|
||||||
|
case ISD::SETGE: Opc = Alpha::FBGE; break;
|
||||||
|
case ISD::SETNE: Opc = Alpha::FBNE; break;
|
||||||
|
}
|
||||||
|
BuildMI(BB, Opc, 2).addReg(Tmp3).addMBB(Dest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
abort(); //Should never be reached
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ //Giveup and do the stupid thing
|
||||||
|
unsigned Tmp1 = SelectExpr(CC);
|
||||||
|
BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
abort(); //Should never be reached
|
||||||
|
}
|
||||||
|
|
||||||
unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
|
unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
|
||||||
{
|
{
|
||||||
unsigned Tmp1, Tmp2, Tmp3;
|
unsigned Tmp1, Tmp2, Tmp3;
|
||||||
|
@ -886,6 +1000,8 @@ unsigned ISel::SelectExpr(SDOperand N) {
|
||||||
Tmp2 = SelectExpr(N.getOperand(1));
|
Tmp2 = SelectExpr(N.getOperand(1));
|
||||||
Tmp3 = MakeReg(MVT::i64);
|
Tmp3 = MakeReg(MVT::i64);
|
||||||
BuildMI(BB, Alpha::CMPEQ, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
|
BuildMI(BB, Alpha::CMPEQ, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
|
||||||
|
//Remeber we have the Inv for this CC
|
||||||
|
CCInvMap[N] = Tmp3;
|
||||||
//and invert
|
//and invert
|
||||||
BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Alpha::R31).addReg(Tmp3);
|
BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Alpha::R31).addReg(Tmp3);
|
||||||
return Result;
|
return Result;
|
||||||
|
@ -1180,13 +1296,7 @@ void ISel::Select(SDOperand N) {
|
||||||
assert(0 && "Node not handled yet!");
|
assert(0 && "Node not handled yet!");
|
||||||
|
|
||||||
case ISD::BRCOND: {
|
case ISD::BRCOND: {
|
||||||
MachineBasicBlock *Dest =
|
SelectBranchCC(N);
|
||||||
cast<BasicBlockSDNode>(N.getOperand(2))->getBasicBlock();
|
|
||||||
|
|
||||||
Select(N.getOperand(0)); //chain
|
|
||||||
|
|
||||||
Tmp1 = SelectExpr(N.getOperand(1));
|
|
||||||
BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue