-SDOperand AlphaDAGToDAGISel::Select(SDOperand Op) {
- SDNode *N = Op.Val;
- if (N->getOpcode() >= ISD::BUILTIN_OP_END &&
- N->getOpcode() < AlphaISD::FIRST_NUMBER)
- return Op; // Already selected.
-
- // If this has already been converted, use it.
- std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(Op);
- if (CGMI != CodeGenMap.end()) return CGMI->second;
-
- switch (N->getOpcode()) {
- default: break;
- case ISD::TAILCALL:
- case ISD::CALL: return SelectCALL(Op);
-
- case ISD::DYNAMIC_STACKALLOC: {
- if (!isa<ConstantSDNode>(N->getOperand(2)) ||
- cast<ConstantSDNode>(N->getOperand(2))->getValue() != 0) {
- std::cerr << "Cannot allocate stack object with greater alignment than"
- << " the stack alignment yet!";
- abort();
- }
-
- SDOperand Chain = Select(N->getOperand(0));
- SDOperand Amt = Select(N->getOperand(1));
- SDOperand Reg = CurDAG->getRegister(Alpha::R30, MVT::i64);
- SDOperand Val = CurDAG->getCopyFromReg(Chain, Alpha::R30, MVT::i64);
- Chain = Val.getValue(1);
-
- // Subtract the amount (guaranteed to be a multiple of the stack alignment)
- // from the stack pointer, giving us the result pointer.
- SDOperand Result = CurDAG->getTargetNode(Alpha::SUBQ, MVT::i64, Val, Amt);
-
- // Copy this result back into R30.
- Chain = CurDAG->getNode(ISD::CopyToReg, MVT::Other, Chain, Reg, Result);
-
- // Copy this result back out of R30 to make sure we're not using the stack
- // space without decrementing the stack pointer.
- Result = CurDAG->getCopyFromReg(Chain, Alpha::R30, MVT::i64);
-
- // Finally, replace the DYNAMIC_STACKALLOC with the copyfromreg.
- CodeGenMap[Op.getValue(0)] = Result;
- CodeGenMap[Op.getValue(1)] = Result.getValue(1);
- return SDOperand(Result.Val, Op.ResNo);
- }
- case ISD::BRCOND: {
- if (N->getOperand(1).getOpcode() == ISD::SETCC &&
- MVT::isFloatingPoint(N->getOperand(1).getOperand(0).getValueType())) {
- SDOperand Chain = Select(N->getOperand(0));
- SDOperand CC1 = Select(N->getOperand(1).getOperand(0));
- SDOperand CC2 = Select(N->getOperand(1).getOperand(1));
- ISD::CondCode cCode= cast<CondCodeSDNode>(N->getOperand(1).getOperand(2))->get();
-
- bool rev = false;
- bool isNE = false;
- unsigned Opc = Alpha::WTF;
- switch(cCode) {
- default: N->dump(); assert(0 && "Unknown FP comparison!");
- case ISD::SETEQ: Opc = Alpha::CMPTEQ; break;
- case ISD::SETLT: Opc = Alpha::CMPTLT; break;
- case ISD::SETLE: Opc = Alpha::CMPTLE; break;
- case ISD::SETGT: Opc = Alpha::CMPTLT; rev = true; break;
- case ISD::SETGE: Opc = Alpha::CMPTLE; rev = true; break;
- case ISD::SETNE: Opc = Alpha::CMPTEQ; isNE = true; break;
- };
- SDOperand cmp = CurDAG->getTargetNode(Opc, MVT::f64,
- rev?CC2:CC1,
- rev?CC1:CC2);
-
- MachineBasicBlock *Dest =
- cast<BasicBlockSDNode>(N->getOperand(2))->getBasicBlock();
- if(isNE)
- return CurDAG->SelectNodeTo(N, Alpha::FBEQ, MVT::Other, cmp,
- CurDAG->getBasicBlock(Dest), Chain);
- else
- return CurDAG->SelectNodeTo(N, Alpha::FBNE, MVT::Other, cmp,
- CurDAG->getBasicBlock(Dest), Chain);
- }
- SDOperand Chain = Select(N->getOperand(0));
- SDOperand CC = Select(N->getOperand(1));
- MachineBasicBlock *Dest =
- cast<BasicBlockSDNode>(N->getOperand(2))->getBasicBlock();
- return CurDAG->SelectNodeTo(N, Alpha::BNE, MVT::Other, CC,
- CurDAG->getBasicBlock(Dest), Chain);