aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target
diff options
context:
space:
mode:
authorBrian Gaeke <gaeke@uiuc.edu>2004-11-14 03:22:07 +0000
committerBrian Gaeke <gaeke@uiuc.edu>2004-11-14 03:22:07 +0000
commit24b90c364766629e68c07b84c8e65c93790d4e43 (patch)
tree7f464844a64bbdfdc9175df181d9d7da29d1ced4 /lib/Target
parent54799c2a516520c3f669c46439f8f6b250ac0274 (diff)
downloadexternal_llvm-24b90c364766629e68c07b84c8e65c93790d4e43.zip
external_llvm-24b90c364766629e68c07b84c8e65c93790d4e43.tar.gz
external_llvm-24b90c364766629e68c07b84c8e65c93790d4e43.tar.bz2
Rewrite outgoing arg handling to handle more weird corner cases.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@17722 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r--lib/Target/Sparc/SparcV8ISelSimple.cpp107
-rw-r--r--lib/Target/SparcV8/SparcV8ISelSimple.cpp107
2 files changed, 134 insertions, 80 deletions
diff --git a/lib/Target/Sparc/SparcV8ISelSimple.cpp b/lib/Target/Sparc/SparcV8ISelSimple.cpp
index 5a19ccb..fde13bf 100644
--- a/lib/Target/Sparc/SparcV8ISelSimple.cpp
+++ b/lib/Target/Sparc/SparcV8ISelSimple.cpp
@@ -784,53 +784,80 @@ 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 (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);
- } else if (getClassB (I.getOperand (i)->getType ()) == cFloat) {
- // 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);
- } 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);
+ 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
+ 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 {
- assert (0 && "Unknown class?!");
+ BuildMI (BB, V8::ST, 3).addReg (V8::SP).addSImm (ArgOffset).addReg (ArgReg);
}
- } 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);
+ 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 {
- assert (0 && "can't push this kind of excess arg on stack yet");
+ BuildMI (BB, V8::ST, 3).addReg (V8::SP).addSImm (ArgOffset).addReg (ArgReg+1);
}
+ ArgOffset += 4;
+ } else {
+ assert (0 && "Unknown class?!");
}
}
diff --git a/lib/Target/SparcV8/SparcV8ISelSimple.cpp b/lib/Target/SparcV8/SparcV8ISelSimple.cpp
index 5a19ccb..fde13bf 100644
--- a/lib/Target/SparcV8/SparcV8ISelSimple.cpp
+++ b/lib/Target/SparcV8/SparcV8ISelSimple.cpp
@@ -784,53 +784,80 @@ 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 (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);
- } else if (getClassB (I.getOperand (i)->getType ()) == cFloat) {
- // 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);
- } 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);
+ 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
+ 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 {
- assert (0 && "Unknown class?!");
+ BuildMI (BB, V8::ST, 3).addReg (V8::SP).addSImm (ArgOffset).addReg (ArgReg);
}
- } 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);
+ 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 {
- assert (0 && "can't push this kind of excess arg on stack yet");
+ BuildMI (BB, V8::ST, 3).addReg (V8::SP).addSImm (ArgOffset).addReg (ArgReg+1);
}
+ ArgOffset += 4;
+ } else {
+ assert (0 && "Unknown class?!");
}
}