mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
Rewrite outgoing arg handling to handle more weird corner cases.
llvm-svn: 17722
This commit is contained in:
parent
294af88a7a
commit
1b3d701769
@ -784,53 +784,80 @@ void V8ISel::visitCallInst(CallInst &I) {
|
|||||||
// Deal with args
|
// Deal with args
|
||||||
static const unsigned OutgoingArgRegs[] = { V8::O0, V8::O1, V8::O2, V8::O3,
|
static const unsigned OutgoingArgRegs[] = { V8::O0, V8::O1, V8::O2, V8::O3,
|
||||||
V8::O4, V8::O5 };
|
V8::O4, V8::O5 };
|
||||||
|
const unsigned *OAREnd = &OutgoingArgRegs[6];
|
||||||
const unsigned *OAR = &OutgoingArgRegs[0];
|
const unsigned *OAR = &OutgoingArgRegs[0];
|
||||||
|
unsigned ArgOffset = 68;
|
||||||
for (unsigned i = 1; i < I.getNumOperands (); ++i) {
|
for (unsigned i = 1; i < I.getNumOperands (); ++i) {
|
||||||
unsigned ArgReg = getReg (I.getOperand (i));
|
unsigned ArgReg = getReg (I.getOperand (i));
|
||||||
if (i < 7) {
|
if (i == 7 && extraStack)
|
||||||
if (getClassB (I.getOperand (i)->getType ()) < cLong) {
|
BuildMI (BB, V8::ADJCALLSTACKDOWN, 1).addImm (extraStack);
|
||||||
// Schlep it over into the incoming arg register
|
if (getClassB (I.getOperand (i)->getType ()) < cLong) {
|
||||||
BuildMI (BB, V8::ORrr, 2, *OAR++).addReg (V8::G0)
|
// Schlep it over into the incoming arg register
|
||||||
.addReg (ArgReg);
|
if (ArgOffset < 92) {
|
||||||
} else if (getClassB (I.getOperand (i)->getType ()) == cFloat) {
|
assert (OAR != OAREnd && "About to dereference past end of OutgoingArgRegs");
|
||||||
// Single-fp args are passed in integer registers; go through
|
BuildMI (BB, V8::ORrr, 2, *OAR++).addReg (V8::G0).addReg (ArgReg);
|
||||||
// memory to get them out of FP registers. (Bleh!)
|
|
||||||
unsigned FltAlign = TM.getTargetData().getFloatAlignment();
|
|
||||||
int FI = F->getFrameInfo()->CreateStackObject(4, FltAlign);
|
|
||||||
BuildMI (BB, V8::STFri, 3).addFrameIndex (FI).addSImm (0)
|
|
||||||
.addReg (ArgReg);
|
|
||||||
BuildMI (BB, V8::LD, 2, *OAR++).addFrameIndex (FI)
|
|
||||||
.addSImm (0);
|
|
||||||
} else if (getClassB (I.getOperand (i)->getType ()) == cDouble) {
|
|
||||||
// Double-fp args are passed in pairs of integer registers; go through
|
|
||||||
// memory to get them out of FP registers. (Bleh!)
|
|
||||||
assert (i <= 5 && "Can't deal with double-fp args past #5 yet");
|
|
||||||
unsigned DblAlign = TM.getTargetData().getDoubleAlignment();
|
|
||||||
int FI = F->getFrameInfo()->CreateStackObject(8, DblAlign);
|
|
||||||
BuildMI (BB, V8::STDFri, 3).addFrameIndex (FI).addSImm (0)
|
|
||||||
.addReg (ArgReg);
|
|
||||||
BuildMI (BB, V8::LD, 2, *OAR++).addFrameIndex (FI)
|
|
||||||
.addSImm (0);
|
|
||||||
BuildMI (BB, V8::LD, 2, *OAR++).addFrameIndex (FI)
|
|
||||||
.addSImm (4);
|
|
||||||
} else if (getClassB (I.getOperand (i)->getType ()) == cLong) {
|
|
||||||
BuildMI (BB, V8::ORrr, 2, *OAR++).addReg (V8::G0)
|
|
||||||
.addReg (ArgReg);
|
|
||||||
BuildMI (BB, V8::ORrr, 2, *OAR++).addReg (V8::G0)
|
|
||||||
.addReg (ArgReg+1);
|
|
||||||
} else {
|
} else {
|
||||||
assert (0 && "Unknown class?!");
|
BuildMI (BB, V8::ST, 3).addReg (V8::SP).addSImm (ArgOffset).addReg (ArgReg);
|
||||||
}
|
}
|
||||||
|
ArgOffset += 4;
|
||||||
|
} else if (getClassB (I.getOperand (i)->getType ()) == cFloat) {
|
||||||
|
if (ArgOffset < 92) {
|
||||||
|
// Single-fp args are passed in integer registers; go through
|
||||||
|
// memory to get them out of FP registers. (Bleh!)
|
||||||
|
unsigned FltAlign = TM.getTargetData().getFloatAlignment();
|
||||||
|
int FI = F->getFrameInfo()->CreateStackObject(4, FltAlign);
|
||||||
|
BuildMI (BB, V8::STFri, 3).addFrameIndex (FI).addSImm (0).addReg (ArgReg);
|
||||||
|
assert (OAR != OAREnd && "About to dereference past end of OutgoingArgRegs");
|
||||||
|
BuildMI (BB, V8::LD, 2, *OAR++).addFrameIndex (FI).addSImm (0);
|
||||||
|
} else {
|
||||||
|
BuildMI (BB, V8::STFri, 3).addReg (V8::SP).addSImm (ArgOffset).addReg (ArgReg);
|
||||||
|
}
|
||||||
|
ArgOffset += 4;
|
||||||
|
} else if (getClassB (I.getOperand (i)->getType ()) == cDouble) {
|
||||||
|
// Double-fp args are passed in pairs of integer registers; go through
|
||||||
|
// memory to get them out of FP registers. (Bleh!)
|
||||||
|
// We'd like to 'std' these right onto the outgoing-args area, but it might
|
||||||
|
// not be 8-byte aligned (e.g., call x(int x, double d)). sigh.
|
||||||
|
unsigned DblAlign = TM.getTargetData().getDoubleAlignment();
|
||||||
|
int FI = F->getFrameInfo()->CreateStackObject(8, DblAlign);
|
||||||
|
BuildMI (BB, V8::STDFri, 3).addFrameIndex (FI).addSImm (0).addReg (ArgReg);
|
||||||
|
if (ArgOffset < 92 && OAR != OAREnd) {
|
||||||
|
assert (OAR != OAREnd && "About to dereference past end of OutgoingArgRegs");
|
||||||
|
BuildMI (BB, V8::LD, 2, *OAR++).addFrameIndex (FI).addSImm (0);
|
||||||
|
} else {
|
||||||
|
unsigned TempReg = makeAnotherReg (Type::IntTy);
|
||||||
|
BuildMI (BB, V8::LD, 2, TempReg).addFrameIndex (FI).addSImm (0);
|
||||||
|
BuildMI (BB, V8::ST, 3).addReg (V8::SP).addSImm (ArgOffset).addReg (TempReg);
|
||||||
|
}
|
||||||
|
ArgOffset += 4;
|
||||||
|
if (ArgOffset < 92 && OAR != OAREnd) {
|
||||||
|
assert (OAR != OAREnd && "About to dereference past end of OutgoingArgRegs");
|
||||||
|
BuildMI (BB, V8::LD, 2, *OAR++).addFrameIndex (FI).addSImm (4);
|
||||||
|
} else {
|
||||||
|
unsigned TempReg = makeAnotherReg (Type::IntTy);
|
||||||
|
BuildMI (BB, V8::LD, 2, TempReg).addFrameIndex (FI).addSImm (4);
|
||||||
|
BuildMI (BB, V8::ST, 3).addReg (V8::SP).addSImm (ArgOffset).addReg (TempReg);
|
||||||
|
}
|
||||||
|
ArgOffset += 4;
|
||||||
|
} else if (getClassB (I.getOperand (i)->getType ()) == cLong) {
|
||||||
|
// do the first half...
|
||||||
|
if (ArgOffset < 92) {
|
||||||
|
assert (OAR != OAREnd && "About to dereference past end of OutgoingArgRegs");
|
||||||
|
BuildMI (BB, V8::ORrr, 2, *OAR++).addReg (V8::G0).addReg (ArgReg);
|
||||||
|
} else {
|
||||||
|
BuildMI (BB, V8::ST, 3).addReg (V8::SP).addSImm (ArgOffset).addReg (ArgReg);
|
||||||
|
}
|
||||||
|
ArgOffset += 4;
|
||||||
|
// ...then do the second half
|
||||||
|
if (ArgOffset < 92) {
|
||||||
|
assert (OAR != OAREnd && "About to dereference past end of OutgoingArgRegs");
|
||||||
|
BuildMI (BB, V8::ORrr, 2, *OAR++).addReg (V8::G0).addReg (ArgReg+1);
|
||||||
|
} else {
|
||||||
|
BuildMI (BB, V8::ST, 3).addReg (V8::SP).addSImm (ArgOffset).addReg (ArgReg+1);
|
||||||
|
}
|
||||||
|
ArgOffset += 4;
|
||||||
} else {
|
} else {
|
||||||
if (i == 7 && extraStack)
|
assert (0 && "Unknown class?!");
|
||||||
BuildMI (BB, V8::ADJCALLSTACKDOWN, 1).addImm (extraStack);
|
|
||||||
// Store arg into designated outgoing-arg stack slot
|
|
||||||
if (getClassB (I.getOperand (i)->getType ()) < cLong) {
|
|
||||||
BuildMI (BB, V8::ST, 3).addReg (V8::SP).addSImm (64+4*i)
|
|
||||||
.addReg (ArgReg);
|
|
||||||
} else {
|
|
||||||
assert (0 && "can't push this kind of excess arg on stack yet");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user