mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-04 22:07:27 +00:00
implement passing/returning vector regs to calls, at least non-varargs calls.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28341 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
da098e7d10
commit
c04ba7a97d
@ -137,8 +137,8 @@ namespace {
|
||||
return "PowerPC DAG->DAG Pattern Instruction Selection";
|
||||
}
|
||||
|
||||
/// CreateTargetHazardRecognizer - Return the hazard recognizer to use for this
|
||||
/// target when scheduling the DAG.
|
||||
/// CreateTargetHazardRecognizer - Return the hazard recognizer to use for
|
||||
/// this target when scheduling the DAG.
|
||||
virtual HazardRecognizer *CreateTargetHazardRecognizer() {
|
||||
// Should use subtarget info to pick the right hazard recognizer. For
|
||||
// now, always return a PPC970 recognizer.
|
||||
@ -813,8 +813,8 @@ SDOperand PPCDAGToDAGISel::SelectSETCC(SDOperand Op) {
|
||||
Op = SDOperand(CurDAG->getTargetNode(PPC::NOR, MVT::i32, Op, Op), 0);
|
||||
SDNode *AD = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag,
|
||||
Op, getI32Imm(~0U));
|
||||
return CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, SDOperand(AD, 0), Op,
|
||||
SDOperand(AD, 1));
|
||||
return CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, SDOperand(AD, 0),
|
||||
Op, SDOperand(AD, 1));
|
||||
}
|
||||
case ISD::SETLT: {
|
||||
SDOperand AD = SDOperand(CurDAG->getTargetNode(PPC::ADDI, MVT::i32, Op,
|
||||
@ -908,7 +908,7 @@ SDOperand PPCDAGToDAGISel::SelectCALL(SDOperand Op) {
|
||||
CallOpcode = PPC::BCTRL;
|
||||
}
|
||||
|
||||
unsigned GPR_idx = 0, FPR_idx = 0;
|
||||
unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
|
||||
static const unsigned GPR[] = {
|
||||
PPC::R3, PPC::R4, PPC::R5, PPC::R6,
|
||||
PPC::R7, PPC::R8, PPC::R9, PPC::R10,
|
||||
@ -917,6 +917,10 @@ SDOperand PPCDAGToDAGISel::SelectCALL(SDOperand Op) {
|
||||
PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
|
||||
PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13
|
||||
};
|
||||
static const unsigned VR[] = {
|
||||
PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
|
||||
PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
|
||||
};
|
||||
|
||||
SDOperand InFlag; // Null incoming flag value.
|
||||
|
||||
@ -926,11 +930,13 @@ SDOperand PPCDAGToDAGISel::SelectCALL(SDOperand Op) {
|
||||
if (RegTy == MVT::i32) {
|
||||
assert(GPR_idx < 8 && "Too many int args");
|
||||
DestReg = GPR[GPR_idx++];
|
||||
} else {
|
||||
assert(MVT::isFloatingPoint(N->getOperand(i).getValueType()) &&
|
||||
"Unpromoted integer arg?");
|
||||
} else if (MVT::isFloatingPoint(N->getOperand(i).getValueType())) {
|
||||
assert(FPR_idx < 13 && "Too many fp args");
|
||||
DestReg = FPR[FPR_idx++];
|
||||
} else {
|
||||
assert(MVT::isVector(N->getOperand(i).getValueType()) && "unknown arg!");
|
||||
assert(VR_idx < 12 && "Too many vector args");
|
||||
DestReg = VR[VR_idx++];
|
||||
}
|
||||
|
||||
if (N->getOperand(i).getOpcode() != ISD::UNDEF) {
|
||||
@ -955,28 +961,36 @@ SDOperand PPCDAGToDAGISel::SelectCALL(SDOperand Op) {
|
||||
|
||||
// If the call has results, copy the values out of the ret val registers.
|
||||
switch (N->getValueType(0)) {
|
||||
default: assert(0 && "Unexpected ret value!");
|
||||
case MVT::Other: break;
|
||||
case MVT::i32:
|
||||
if (N->getValueType(1) == MVT::i32) {
|
||||
Chain = CurDAG->getCopyFromReg(Chain, PPC::R4, MVT::i32,
|
||||
Chain.getValue(1)).getValue(1);
|
||||
CallResults.push_back(Chain.getValue(0));
|
||||
Chain = CurDAG->getCopyFromReg(Chain, PPC::R3, MVT::i32,
|
||||
Chain.getValue(2)).getValue(1);
|
||||
CallResults.push_back(Chain.getValue(0));
|
||||
} else {
|
||||
Chain = CurDAG->getCopyFromReg(Chain, PPC::R3, MVT::i32,
|
||||
Chain.getValue(1)).getValue(1);
|
||||
CallResults.push_back(Chain.getValue(0));
|
||||
}
|
||||
break;
|
||||
case MVT::f32:
|
||||
case MVT::f64:
|
||||
Chain = CurDAG->getCopyFromReg(Chain, PPC::F1, N->getValueType(0),
|
||||
default: assert(0 && "Unexpected ret value!");
|
||||
case MVT::Other: break;
|
||||
case MVT::i32:
|
||||
if (N->getValueType(1) == MVT::i32) {
|
||||
Chain = CurDAG->getCopyFromReg(Chain, PPC::R4, MVT::i32,
|
||||
Chain.getValue(1)).getValue(1);
|
||||
CallResults.push_back(Chain.getValue(0));
|
||||
break;
|
||||
Chain = CurDAG->getCopyFromReg(Chain, PPC::R3, MVT::i32,
|
||||
Chain.getValue(2)).getValue(1);
|
||||
CallResults.push_back(Chain.getValue(0));
|
||||
} else {
|
||||
Chain = CurDAG->getCopyFromReg(Chain, PPC::R3, MVT::i32,
|
||||
Chain.getValue(1)).getValue(1);
|
||||
CallResults.push_back(Chain.getValue(0));
|
||||
}
|
||||
break;
|
||||
case MVT::f32:
|
||||
case MVT::f64:
|
||||
Chain = CurDAG->getCopyFromReg(Chain, PPC::F1, N->getValueType(0),
|
||||
Chain.getValue(1)).getValue(1);
|
||||
CallResults.push_back(Chain.getValue(0));
|
||||
break;
|
||||
case MVT::v4f32:
|
||||
case MVT::v4i32:
|
||||
case MVT::v8i16:
|
||||
case MVT::v16i8:
|
||||
Chain = CurDAG->getCopyFromReg(Chain, PPC::V2, N->getValueType(0),
|
||||
Chain.getValue(1)).getValue(1);
|
||||
CallResults.push_back(Chain.getValue(0));
|
||||
break;
|
||||
}
|
||||
|
||||
CallResults.push_back(Chain);
|
||||
|
@ -920,7 +920,8 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
|
||||
unsigned ArgOffset = 24;
|
||||
unsigned GPR_remaining = 8;
|
||||
unsigned FPR_remaining = 13;
|
||||
|
||||
unsigned VR_remaining = 12;
|
||||
|
||||
std::vector<SDOperand> MemOps;
|
||||
for (unsigned i = 5, e = Op.getNumOperands(); i != e; ++i) {
|
||||
SDOperand Arg = Op.getOperand(i);
|
||||
@ -987,6 +988,16 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
|
||||
}
|
||||
ArgOffset += (Arg.getValueType() == MVT::f32) ? 4 : 8;
|
||||
break;
|
||||
case MVT::v4f32:
|
||||
case MVT::v4i32:
|
||||
case MVT::v8i16:
|
||||
case MVT::v16i8:
|
||||
assert(!isVarArg && "Don't support passing vectors to varargs yet!");
|
||||
assert(VR_remaining &&
|
||||
"Don't support passing more than 12 vector args yet!");
|
||||
args_to_use.push_back(Arg);
|
||||
--VR_remaining;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!MemOps.empty())
|
||||
|
Loading…
Reference in New Issue
Block a user