#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/ADT/VectorExtras.h"
+#include "llvm/Support/ErrorHandling.h"
using namespace llvm;
DebugLoc dl = Op.getDebugLoc();
// CCState - Info about the registers and stack slot.
- CCState CCInfo(CC, isVarArg, DAG.getTarget(), RVLocs, DAG.getContext());
+ CCState CCInfo(CC, isVarArg, DAG.getTarget(), RVLocs, *DAG.getContext());
// Analize return values of ISD::RET
CCInfo.AnalyzeReturn(Op.getNode(), RetCC_Sparc32);
/// LowerArguments - V8 uses a very simple ABI, where all values are passed in
/// either one or two GPRs, including FP values. TODO: we should pass FP values
/// in FP registers for fastcc functions.
-void
-SparcTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG,
- SmallVectorImpl<SDValue> &ArgValues,
- DebugLoc dl) {
+SDValue
+SparcTargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op,
+ SelectionDAG &DAG) {
MachineFunction &MF = DAG.getMachineFunction();
MachineRegisterInfo &RegInfo = MF.getRegInfo();
+ SDValue Root = Op.getOperand(0);
+ bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0;
+ unsigned CC = MF.getFunction()->getCallingConv();
+ DebugLoc dl = Op.getDebugLoc();
+
+ // Assign locations to all of the incoming arguments.
+ SmallVector<CCValAssign, 16> ArgLocs;
+ CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs, *DAG.getContext());
+ CCInfo.AnalyzeFormalArguments(Op.getNode(), CC_Sparc32);
static const unsigned ArgRegs[] = {
SP::I0, SP::I1, SP::I2, SP::I3, SP::I4, SP::I5
};
-
const unsigned *CurArgReg = ArgRegs, *ArgRegEnd = ArgRegs+6;
unsigned ArgOffset = 68;
- SDValue Root = DAG.getRoot();
- std::vector<SDValue> OutChains;
-
- for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) {
- MVT ObjectVT = getValueType(I->getType());
-
+ SmallVector<SDValue, 16> ArgValues;
+ for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
+ SDValue ArgValue;
+ CCValAssign &VA = ArgLocs[i];
+ // FIXME: We ignore the register assignments of AnalyzeFormalArguments
+ // because it doesn't know how to split a double into two i32 registers.
+ MVT ObjectVT = VA.getValVT();
switch (ObjectVT.getSimpleVT()) {
- default: assert(0 && "Unhandled argument type!");
+ default: llvm_unreachable("Unhandled argument type!");
case MVT::i1:
case MVT::i8:
case MVT::i16:
case MVT::i32:
- if (I->use_empty()) { // Argument is dead.
- if (CurArgReg < ArgRegEnd) ++CurArgReg;
- ArgValues.push_back(DAG.getUNDEF(ObjectVT));
- } else if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR
+ if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR
unsigned VReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
MF.getRegInfo().addLiveIn(*CurArgReg++, VReg);
SDValue Arg = DAG.getCopyFromReg(Root, dl, VReg, MVT::i32);
ArgOffset += 4;
break;
case MVT::f32:
- if (I->use_empty()) { // Argument is dead.
- if (CurArgReg < ArgRegEnd) ++CurArgReg;
- ArgValues.push_back(DAG.getUNDEF(ObjectVT));
- } else if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR
+ if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR
// FP value is passed in an integer register.
unsigned VReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
MF.getRegInfo().addLiveIn(*CurArgReg++, VReg);
case MVT::i64:
case MVT::f64:
- if (I->use_empty()) { // Argument is dead.
- if (CurArgReg < ArgRegEnd) ++CurArgReg;
- if (CurArgReg < ArgRegEnd) ++CurArgReg;
- ArgValues.push_back(DAG.getUNDEF(ObjectVT));
- } else {
+ {
SDValue HiVal;
if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR
unsigned VRegHi = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
}
// Store remaining ArgRegs to the stack if this is a varargs function.
- if (F.isVarArg()) {
+ if (isVarArg) {
// Remember the vararg offset for the va_start implementation.
VarArgsFrameOffset = ArgOffset;
+ std::vector<SDValue> OutChains;
+
for (; CurArgReg != ArgRegEnd; ++CurArgReg) {
unsigned VReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
MF.getRegInfo().addLiveIn(*CurArgReg, VReg);
OutChains.push_back(DAG.getStore(DAG.getRoot(), dl, Arg, FIPtr, NULL, 0));
ArgOffset += 4;
}
+
+ if (!OutChains.empty()) {
+ OutChains.push_back(Root);
+ Root = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
+ &OutChains[0], OutChains.size());
+ }
}
- if (!OutChains.empty())
- DAG.setRoot(DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
- &OutChains[0], OutChains.size()));
+ ArgValues.push_back(Root);
+
+ // Return the new list of results.
+ return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getNode()->getVTList(),
+ &ArgValues[0], ArgValues.size()).getValue(Op.getResNo());
}
static SDValue LowerCALL(SDValue Op, SelectionDAG &DAG) {
unsigned ArgsSize = 0;
for (unsigned i = 0, e = TheCall->getNumArgs(); i != e; ++i) {
switch (TheCall->getArg(i).getValueType().getSimpleVT()) {
- default: assert(0 && "Unknown value type!");
+ default: llvm_unreachable("Unknown value type!");
case MVT::i1:
case MVT::i8:
case MVT::i16:
// Promote the value if needed.
switch (VA.getLocInfo()) {
- default: assert(0 && "Unknown loc info!");
+ default: llvm_unreachable("Unknown loc info!");
case CCValAssign::Full: break;
case CCValAssign::SExt:
Arg = DAG.getNode(ISD::SIGN_EXTEND, VA.getLocVT(), Arg);
SDValue ValToStore(0, 0);
unsigned ObjSize;
switch (ObjectVT.getSimpleVT()) {
- default: assert(0 && "Unhandled argument type!");
+ default: llvm_unreachable("Unhandled argument type!");
case MVT::i32:
ObjSize = 4;
// Assign locations to each value returned by this call.
SmallVector<CCValAssign, 16> RVLocs;
CCState RVInfo(CallingConv, isVarArg, DAG.getTarget(),
- RVLocs, DAG.getContext());
+ RVLocs, *DAG.getContext());
RVInfo.AnalyzeCallResult(TheCall, RetCC_Sparc32);
SmallVector<SDValue, 8> ResultVals;
/// condition.
static SPCC::CondCodes IntCondCCodeToICC(ISD::CondCode CC) {
switch (CC) {
- default: assert(0 && "Unknown integer condition code!");
+ default: llvm_unreachable("Unknown integer condition code!");
case ISD::SETEQ: return SPCC::ICC_E;
case ISD::SETNE: return SPCC::ICC_NE;
case ISD::SETLT: return SPCC::ICC_L;
/// FCC condition.
static SPCC::CondCodes FPCondCCodeToFCC(ISD::CondCode CC) {
switch (CC) {
- default: assert(0 && "Unknown fp condition code!");
+ default: llvm_unreachable("Unknown fp condition code!");
case ISD::SETEQ:
case ISD::SETOEQ: return SPCC::FCC_E;
case ISD::SETNE:
SDValue SparcTargetLowering::
LowerOperation(SDValue Op, SelectionDAG &DAG) {
switch (Op.getOpcode()) {
- default: assert(0 && "Should not custom lower this!");
+ default: llvm_unreachable("Should not custom lower this!");
// Frame & Return address. Currently unimplemented
case ISD::RETURNADDR: return SDValue();
case ISD::FRAMEADDR: return SDValue();
case ISD::GlobalTLSAddress:
- assert(0 && "TLS not implemented for Sparc.");
+ llvm_unreachable("TLS not implemented for Sparc.");
case ISD::GlobalAddress: return LowerGLOBALADDRESS(Op, DAG);
case ISD::ConstantPool: return LowerCONSTANTPOOL(Op, DAG);
case ISD::FP_TO_SINT: return LowerFP_TO_SINT(Op, DAG);
case ISD::VAARG: return LowerVAARG(Op, DAG);
case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG);
case ISD::CALL: return LowerCALL(Op, DAG);
+ case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG);
case ISD::RET: return LowerRET(Op, DAG);
}
}
DebugLoc dl = MI->getDebugLoc();
// Figure out the conditional branch opcode to use for this select_cc.
switch (MI->getOpcode()) {
- default: assert(0 && "Unknown SELECT_CC!");
+ default: llvm_unreachable("Unknown SELECT_CC!");
case SP::SELECT_CC_Int_ICC:
case SP::SELECT_CC_FP_ICC:
case SP::SELECT_CC_DFP_ICC: