1
0
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:
Brian Gaeke 2004-11-14 03:22:07 +00:00
parent 294af88a7a
commit 1b3d701769

View File

@ -784,54 +784,81 @@ void V8ISel::visitCallInst(CallInst &I) {
// Deal with args
static const unsigned OutgoingArgRegs[] = { V8::O0, V8::O1, V8::O2, V8::O3,
V8::O4, V8::O5 };
const unsigned *OAREnd = &OutgoingArgRegs[6];
const unsigned *OAR = &OutgoingArgRegs[0];
unsigned ArgOffset = 68;
for (unsigned i = 1; i < I.getNumOperands (); ++i) {
unsigned ArgReg = getReg (I.getOperand (i));
if (i < 7) {
if (i == 7 && extraStack)
BuildMI (BB, V8::ADJCALLSTACKDOWN, 1).addImm (extraStack);
if (getClassB (I.getOperand (i)->getType ()) < cLong) {
// Schlep it over into the incoming arg register
BuildMI (BB, V8::ORrr, 2, *OAR++).addReg (V8::G0)
.addReg (ArgReg);
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;
} 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);
BuildMI (BB, V8::LD, 2, *OAR++).addFrameIndex (FI)
.addSImm (0);
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!)
assert (i <= 5 && "Can't deal with double-fp args past #5 yet");
// 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);
BuildMI (BB, V8::LD, 2, *OAR++).addFrameIndex (FI)
.addSImm (0);
BuildMI (BB, V8::LD, 2, *OAR++).addFrameIndex (FI)
.addSImm (4);
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) {
BuildMI (BB, V8::ORrr, 2, *OAR++).addReg (V8::G0)
.addReg (ArgReg);
BuildMI (BB, V8::ORrr, 2, *OAR++).addReg (V8::G0)
.addReg (ArgReg+1);
// 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 {
assert (0 && "Unknown class?!");
}
} else {
if (i == 7 && extraStack)
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");
}
}
}
// Emit call instruction