#include "llvm/Target/TargetLowering.h"
#include "llvm/Support/Debug.h"
#include <iostream>
+#include <queue>
#include <set>
using namespace llvm;
static SPCC::CondCodes FPCondCCodeToFCC(ISD::CondCode CC) {
switch (CC) {
default: assert(0 && "Unknown fp condition code!");
- case ISD::SETEQ: return SPCC::FCC_E;
- case ISD::SETNE: return SPCC::FCC_NE;
- case ISD::SETLT: return SPCC::FCC_L;
- case ISD::SETGT: return SPCC::FCC_G;
- case ISD::SETLE: return SPCC::FCC_LE;
- case ISD::SETGE: return SPCC::FCC_GE;
+ case ISD::SETEQ:
+ case ISD::SETOEQ: return SPCC::FCC_E;
+ case ISD::SETNE:
+ case ISD::SETUNE: return SPCC::FCC_NE;
+ case ISD::SETLT:
+ case ISD::SETOLT: return SPCC::FCC_L;
+ case ISD::SETGT:
+ case ISD::SETOGT: return SPCC::FCC_G;
+ case ISD::SETLE:
+ case ISD::SETOLE: return SPCC::FCC_LE;
+ case ISD::SETGE:
+ case ISD::SETOGE: return SPCC::FCC_GE;
case ISD::SETULT: return SPCC::FCC_UL;
case ISD::SETULE: return SPCC::FCC_ULE;
case ISD::SETUGT: return SPCC::FCC_UG;
}
if (!OutChains.empty())
- DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other, OutChains));
+ DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other,
+ &OutChains[0], OutChains.size()));
// Finally, inform the code generator which regs we return values in.
switch (getValueType(F.getReturnType())) {
}
// Split the value into top and bottom part. Top part goes in a reg.
- SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Val,
+ SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, getPointerTy(), Val,
DAG.getConstant(1, MVT::i32));
- SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Val,
+ SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, getPointerTy(), Val,
DAG.getConstant(0, MVT::i32));
RegValuesToPass.push_back(Hi);
// Emit all stores, make sure the occur before any copies into physregs.
if (!Stores.empty())
- Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Stores);
+ Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0],Stores.size());
static const unsigned ArgRegs[] = {
SP::O0, SP::O1, SP::O2, SP::O3, SP::O4, SP::O5
std::vector<MVT::ValueType> NodeTys;
NodeTys.push_back(MVT::Other); // Returns a chain
NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use.
- std::vector<SDOperand> Ops;
- Ops.push_back(Chain);
- Ops.push_back(Callee);
- if (InFlag.Val)
- Ops.push_back(InFlag);
- Chain = DAG.getNode(SPISD::CALL, NodeTys, Ops);
+ SDOperand Ops[] = { Chain, Callee, InFlag };
+ Chain = DAG.getNode(SPISD::CALL, NodeTys, Ops, InFlag.Val ? 3 : 2);
InFlag = Chain.getValue(1);
MVT::ValueType RetTyVT = getValueType(RetTy);
std::vector<MVT::ValueType> VTs;
VTs.push_back(MVT::i32);
VTs.push_back(MVT::Flag);
- std::vector<SDOperand> Ops;
- Ops.push_back(LHS);
- Ops.push_back(RHS);
- CompareFlag = DAG.getNode(SPISD::CMPICC, VTs, Ops).getValue(1);
+ SDOperand Ops[2] = { LHS, RHS };
+ CompareFlag = DAG.getNode(SPISD::CMPICC, VTs, Ops, 2).getValue(1);
if (SPCC == ~0U) SPCC = IntCondCCodeToICC(CC);
Opc = SPISD::BRICC;
} else {
std::vector<MVT::ValueType> VTs;
VTs.push_back(LHS.getValueType()); // subcc returns a value
VTs.push_back(MVT::Flag);
- std::vector<SDOperand> Ops;
- Ops.push_back(LHS);
- Ops.push_back(RHS);
- CompareFlag = DAG.getNode(SPISD::CMPICC, VTs, Ops).getValue(1);
+ SDOperand Ops[2] = { LHS, RHS };
+ CompareFlag = DAG.getNode(SPISD::CMPICC, VTs, Ops, 2).getValue(1);
Opc = SPISD::SELECT_ICC;
if (SPCC == ~0U) SPCC = IntCondCCodeToICC(CC);
} else {
std::vector<MVT::ValueType> Tys;
Tys.push_back(MVT::f64);
Tys.push_back(MVT::Other);
- std::vector<SDOperand> Ops;
// Bit-Convert the value to f64.
- Ops.push_back(DAG.getNode(ISD::BIT_CONVERT, MVT::f64, V));
- Ops.push_back(V.getValue(1));
- return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops);
+ SDOperand Ops[2] = { DAG.getNode(ISD::BIT_CONVERT, MVT::f64, V),
+ V.getValue(1) };
+ return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops, 2);
}
}
case ISD::DYNAMIC_STACKALLOC: {
std::vector<MVT::ValueType> Tys;
Tys.push_back(MVT::i32);
Tys.push_back(MVT::Other);
- std::vector<SDOperand> Ops;
- Ops.push_back(NewVal);
- Ops.push_back(Chain);
- return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops);
+ SDOperand Ops[2] = { NewVal, Chain };
+ return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops, 2);
}
case ISD::RET: {
SDOperand Copy;
abort();
case 1:
return SDOperand(); // ret void is legal
- case 2: {
+ case 3: {
unsigned ArgReg;
switch(Op.getOperand(1).getValueType()) {
default: assert(0 && "Unknown type to return!");
SDOperand());
break;
}
- case 3:
- Copy = DAG.getCopyToReg(Op.getOperand(0), SP::I0, Op.getOperand(2),
+ case 5:
+ Copy = DAG.getCopyToReg(Op.getOperand(0), SP::I0, Op.getOperand(3),
SDOperand());
Copy = DAG.getCopyToReg(Copy, SP::I1, Op.getOperand(1), Copy.getValue(1));
break;
Subtarget(TM.getSubtarget<SparcSubtarget>()) {
}
- void Select(SDOperand &Result, SDOperand Op);
+ SDNode *Select(SDOperand &Result, SDOperand Op);
// Complex Pattern Selectors.
bool SelectADDRrr(SDOperand N, SDOperand &R1, SDOperand &R2);
// Select target instructions for the DAG.
DAG.setRoot(SelectRoot(DAG.getRoot()));
- CodeGenMap.clear();
DAG.RemoveDeadNodes();
// Emit machine code to BB.
return true;
}
-void SparcDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
+SDNode *SparcDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
SDNode *N = Op.Val;
if (N->getOpcode() >= ISD::BUILTIN_OP_END &&
N->getOpcode() < SPISD::FIRST_NUMBER) {
Result = Op;
- return; // Already selected.
+ return NULL; // Already selected.
}
- // If this has already been converted, use it.
- std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(Op);
- if (CGMI != CodeGenMap.end()) {
- Result = CGMI->second;
- return;
- }
-
switch (N->getOpcode()) {
default: break;
case ISD::SDIV:
case ISD::UDIV: {
// FIXME: should use a custom expander to expose the SRA to the dag.
SDOperand DivLHS, DivRHS;
- Select(DivLHS, N->getOperand(0));
- Select(DivRHS, N->getOperand(1));
+ AddToQueue(DivLHS, N->getOperand(0));
+ AddToQueue(DivRHS, N->getOperand(1));
// Set the Y register to the high-part.
SDOperand TopPart;
// FIXME: Handle div by immediate.
unsigned Opcode = N->getOpcode() == ISD::SDIV ? SP::SDIVrr : SP::UDIVrr;
- Result = CurDAG->SelectNodeTo(N, Opcode, MVT::i32, DivLHS, DivRHS, TopPart);
- return;
+ return CurDAG->SelectNodeTo(N, Opcode, MVT::i32, DivLHS, DivRHS,
+ TopPart).Val;
}
case ISD::MULHU:
case ISD::MULHS: {
// FIXME: Handle mul by immediate.
SDOperand MulLHS, MulRHS;
- Select(MulLHS, N->getOperand(0));
- Select(MulRHS, N->getOperand(1));
+ AddToQueue(MulLHS, N->getOperand(0));
+ AddToQueue(MulRHS, N->getOperand(1));
unsigned Opcode = N->getOpcode() == ISD::MULHU ? SP::UMULrr : SP::SMULrr;
SDNode *Mul = CurDAG->getTargetNode(Opcode, MVT::i32, MVT::Flag,
MulLHS, MulRHS);
// The high part is in the Y register.
- Result = CurDAG->SelectNodeTo(N, SP::RDY, MVT::i32, SDOperand(Mul, 1));
- return;
+ return CurDAG->SelectNodeTo(N, SP::RDY, MVT::i32, SDOperand(Mul, 1)).Val;
+ return NULL;
}
}
- SelectCode(Result, Op);
+ return SelectCode(Result, Op);
}