summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBrian Gaeke <gaeke@uiuc.edu>2004-11-18 07:43:33 +0000
committerBrian Gaeke <gaeke@uiuc.edu>2004-11-18 07:43:33 +0000
commit7c0afe04ab82962ebd78a203ee17a5545170ea7b (patch)
tree2e968b060cf9d8ba7da32e4a9a782484a46d44b4 /lib
parent7ba2a43866674075578053aeb79ef945b047f7a2 (diff)
downloadllvm-7c0afe04ab82962ebd78a203ee17a5545170ea7b.tar.gz
llvm-7c0afe04ab82962ebd78a203ee17a5545170ea7b.tar.bz2
llvm-7c0afe04ab82962ebd78a203ee17a5545170ea7b.tar.xz
Rewrite LoadArgumentsToVirtualRegs, making it match almost exactly how
visitCallInst works. Support cast of byte/short/int to long. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@17949 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/Sparc/SparcV8ISelSimple.cpp160
-rw-r--r--lib/Target/SparcV8/SparcV8ISelSimple.cpp160
2 files changed, 180 insertions, 140 deletions
diff --git a/lib/Target/Sparc/SparcV8ISelSimple.cpp b/lib/Target/Sparc/SparcV8ISelSimple.cpp
index 6af0bf9ab5..d26c77ee40 100644
--- a/lib/Target/Sparc/SparcV8ISelSimple.cpp
+++ b/lib/Target/Sparc/SparcV8ISelSimple.cpp
@@ -314,28 +314,27 @@ void V8ISel::copyConstantToRegister(MachineBasicBlock *MBB,
}
void V8ISel::LoadArgumentsToVirtualRegs (Function *LF) {
- unsigned ArgOffset;
static const unsigned IncomingArgRegs[] = { V8::I0, V8::I1, V8::I2,
V8::I3, V8::I4, V8::I5 };
+
// Add IMPLICIT_DEFs of input regs.
- ArgOffset = 0;
+ unsigned ArgNo = 0;
for (Function::aiterator I = LF->abegin(), E = LF->aend();
- I != E && ArgOffset < 6; ++I, ++ArgOffset) {
- unsigned Reg = getReg(*I);
+ I != E && ArgNo < 6; ++I, ++ArgNo) {
switch (getClassB(I->getType())) {
case cByte:
case cShort:
case cInt:
case cFloat:
- BuildMI(BB, V8::IMPLICIT_DEF, 0, IncomingArgRegs[ArgOffset]);
+ BuildMI(BB, V8::IMPLICIT_DEF, 0, IncomingArgRegs[ArgNo]);
break;
case cDouble:
case cLong:
// Double and Long use register pairs.
- BuildMI(BB, V8::IMPLICIT_DEF, 0, IncomingArgRegs[ArgOffset]);
- ++ArgOffset;
- if (ArgOffset < 6)
- BuildMI(BB, V8::IMPLICIT_DEF, 0, IncomingArgRegs[ArgOffset]);
+ BuildMI(BB, V8::IMPLICIT_DEF, 0, IncomingArgRegs[ArgNo]);
+ ++ArgNo;
+ if (ArgNo < 6)
+ BuildMI(BB, V8::IMPLICIT_DEF, 0, IncomingArgRegs[ArgNo]);
break;
default:
assert (0 && "type not handled");
@@ -343,76 +342,88 @@ void V8ISel::LoadArgumentsToVirtualRegs (Function *LF) {
}
}
- ArgOffset = 0;
- for (Function::aiterator I = LF->abegin(), E = LF->aend(); I != E;
- ++I, ++ArgOffset) {
- unsigned Reg = getReg(*I);
- if (ArgOffset < 6) {
-
- switch (getClassB(I->getType())) {
- case cByte:
- case cShort:
- case cInt:
- BuildMI(BB, V8::ORrr, 2, Reg).addReg (V8::G0)
- .addReg (IncomingArgRegs[ArgOffset]);
- break;
- case cFloat: {
+ // Copy args out of their incoming hard regs or stack slots into virtual regs.
+ const unsigned *IAREnd = &IncomingArgRegs[6];
+ const unsigned *IAR = &IncomingArgRegs[0];
+ unsigned ArgOffset = 68;
+ for (Function::aiterator I = LF->abegin(), E = LF->aend(); I != E; ++I) {
+ Argument &A = *I;
+ unsigned ArgReg = getReg (A);
+ if (getClassB (A.getType ()) < cLong) {
+ // Get it out of the incoming arg register
+ if (ArgOffset < 92) {
+ assert (IAR != IAREnd
+ && "About to dereference past end of IncomingArgRegs");
+ BuildMI (BB, V8::ORrr, 2, ArgReg).addReg (V8::G0).addReg (*IAR++);
+ } else {
+ int FI = F->getFrameInfo()->CreateFixedObject(4, ArgOffset);
+ BuildMI (BB, V8::LD, 3, ArgReg).addFrameIndex (FI).addSImm (0);
+ }
+ ArgOffset += 4;
+ } else if (getClassB (A.getType ()) == cFloat) {
+ if (ArgOffset < 92) {
// Single-fp args are passed in integer registers; go through
- // memory to get them into FP registers. (Bleh!)
+ // memory to get them out of integer registers and back into fp. (Bleh!)
unsigned FltAlign = TM.getTargetData().getFloatAlignment();
int FI = F->getFrameInfo()->CreateStackObject(4, FltAlign);
- BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (0)
- .addReg (IncomingArgRegs[ArgOffset]);
- BuildMI (BB, V8::LDFri, 2, Reg).addFrameIndex (FI).addSImm (0);
- break;
- }
- case cDouble: {
- // Double-fp args are passed in pairs of integer registers; go through
- // memory to get them into FP registers. (Double bleh!)
- unsigned DblAlign = TM.getTargetData().getDoubleAlignment();
- int FI = F->getFrameInfo()->CreateStackObject(8, DblAlign);
- BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (0)
- .addReg (IncomingArgRegs[ArgOffset]);
- ++ArgOffset;
- BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (4)
- .addReg (IncomingArgRegs[ArgOffset]);
- BuildMI (BB, V8::LDDFri, 2, Reg).addFrameIndex (FI).addSImm (0);
- break;
- }
- default:
- // FIXME: handle cLong
- assert (0 && "64-bit int (long/ulong) function args not handled");
- return;
+ assert (IAR != IAREnd
+ && "About to dereference past end of IncomingArgRegs");
+ BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (0).addReg (*IAR++);
+ BuildMI (BB, V8::LDFri, 2, ArgReg).addFrameIndex (FI).addSImm (0);
+ } else {
+ int FI = F->getFrameInfo()->CreateFixedObject(4, ArgOffset);
+ BuildMI (BB, V8::LDFri, 3, ArgReg).addFrameIndex (FI).addSImm (0);
}
-
- } else {
-
- switch (getClassB(I->getType())) {
- case cByte:
- case cShort:
- case cInt: {
- int FI = F->getFrameInfo()->CreateFixedObject(4, 68 + (4 * ArgOffset));
- BuildMI (BB, V8::LD, 2, Reg).addFrameIndex (FI).addSImm(0);
- break;
+ ArgOffset += 4;
+ } else if (getClassB (A.getType ()) == cDouble) {
+ // Double-fp args are passed in pairs of integer registers; go through
+ // memory to get them out of integer registers and back into fp. (Bleh!)
+ // We'd like to 'ldd' these right out of the incoming-args area,
+ // but it might not be 8-byte aligned (e.g., call x(int x, double d)).
+ unsigned DblAlign = TM.getTargetData().getDoubleAlignment();
+ int FI = F->getFrameInfo()->CreateStackObject(8, DblAlign);
+ if (ArgOffset < 92 && IAR != IAREnd) {
+ BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (0).addReg (*IAR++);
+ } else {
+ unsigned TempReg = makeAnotherReg (Type::IntTy);
+ BuildMI (BB, V8::LD, 2, TempReg).addFrameIndex (FI).addSImm (0);
+ BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (0).addReg (TempReg);
}
- case cFloat: {
- int FI = F->getFrameInfo()->CreateFixedObject(4, 68 + (4 * ArgOffset));
- BuildMI (BB, V8::LDFri, 2, Reg).addFrameIndex (FI).addSImm(0);
- break;
+ ArgOffset += 4;
+ if (ArgOffset < 92 && IAR != IAREnd) {
+ BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (4).addReg (*IAR++);
+ } else {
+ unsigned TempReg = makeAnotherReg (Type::IntTy);
+ BuildMI (BB, V8::LD, 2, TempReg).addFrameIndex (FI).addSImm (4);
+ BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (4).addReg (TempReg);
}
- case cDouble: {
- int FI = F->getFrameInfo()->CreateFixedObject(8, 68 + (4 * ArgOffset));
- BuildMI (BB, V8::LDDFri, 2, Reg).addFrameIndex (FI).addSImm(0);
- break;
+ ArgOffset += 4;
+ BuildMI (BB, V8::LDDFri, 2, ArgReg).addFrameIndex (FI).addSImm (0);
+ } else if (getClassB (A.getType ()) == cLong) {
+ // do the first half...
+ if (ArgOffset < 92) {
+ assert (IAR != IAREnd
+ && "About to dereference past end of IncomingArgRegs");
+ BuildMI (BB, V8::ORrr, 2, ArgReg).addReg (V8::G0).addReg (*IAR++);
+ } else {
+ int FI = F->getFrameInfo()->CreateFixedObject(4, ArgOffset);
+ BuildMI (BB, V8::LD, 2, ArgReg).addFrameIndex (FI).addSImm (0);
}
- default:
- // FIXME: handle cLong
- assert (0 && "64-bit integer (long/ulong) function args not handled");
- return;
+ ArgOffset += 4;
+ // ...then do the second half
+ if (ArgOffset < 92) {
+ assert (IAR != IAREnd
+ && "About to dereference past end of IncomingArgRegs");
+ BuildMI (BB, V8::ORrr, 2, ArgReg+1).addReg (V8::G0).addReg (*IAR++);
+ } else {
+ int FI = F->getFrameInfo()->CreateFixedObject(4, ArgOffset);
+ BuildMI (BB, V8::LD, 2, ArgReg+1).addFrameIndex (FI).addSImm (0);
}
+ ArgOffset += 4;
+ } else {
+ assert (0 && "Unknown class?!");
}
}
-
}
void V8ISel::SelectPHINodes() {
@@ -674,8 +685,17 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB,
case cLong:
switch (oldTyClass) {
+ case cByte:
+ case cShort:
+ case cInt:
+ // Just copy it to the bottom half, and put a zero in the top half.
+ BuildMI (*BB, IP, V8::ORrr, 2, DestReg).addReg (V8::G0)
+ .addReg (V8::G0);
+ BuildMI (*BB, IP, V8::ORrr, 2, DestReg+1).addReg (V8::G0)
+ .addReg (SrcReg);
+ break;
case cLong:
- // Just copy it
+ // Just copy both halves.
BuildMI (*BB, IP, V8::ORrr, 2, DestReg).addReg (V8::G0).addReg (SrcReg);
BuildMI (*BB, IP, V8::ORrr, 2, DestReg+1).addReg (V8::G0)
.addReg (SrcReg+1);
diff --git a/lib/Target/SparcV8/SparcV8ISelSimple.cpp b/lib/Target/SparcV8/SparcV8ISelSimple.cpp
index 6af0bf9ab5..d26c77ee40 100644
--- a/lib/Target/SparcV8/SparcV8ISelSimple.cpp
+++ b/lib/Target/SparcV8/SparcV8ISelSimple.cpp
@@ -314,28 +314,27 @@ void V8ISel::copyConstantToRegister(MachineBasicBlock *MBB,
}
void V8ISel::LoadArgumentsToVirtualRegs (Function *LF) {
- unsigned ArgOffset;
static const unsigned IncomingArgRegs[] = { V8::I0, V8::I1, V8::I2,
V8::I3, V8::I4, V8::I5 };
+
// Add IMPLICIT_DEFs of input regs.
- ArgOffset = 0;
+ unsigned ArgNo = 0;
for (Function::aiterator I = LF->abegin(), E = LF->aend();
- I != E && ArgOffset < 6; ++I, ++ArgOffset) {
- unsigned Reg = getReg(*I);
+ I != E && ArgNo < 6; ++I, ++ArgNo) {
switch (getClassB(I->getType())) {
case cByte:
case cShort:
case cInt:
case cFloat:
- BuildMI(BB, V8::IMPLICIT_DEF, 0, IncomingArgRegs[ArgOffset]);
+ BuildMI(BB, V8::IMPLICIT_DEF, 0, IncomingArgRegs[ArgNo]);
break;
case cDouble:
case cLong:
// Double and Long use register pairs.
- BuildMI(BB, V8::IMPLICIT_DEF, 0, IncomingArgRegs[ArgOffset]);
- ++ArgOffset;
- if (ArgOffset < 6)
- BuildMI(BB, V8::IMPLICIT_DEF, 0, IncomingArgRegs[ArgOffset]);
+ BuildMI(BB, V8::IMPLICIT_DEF, 0, IncomingArgRegs[ArgNo]);
+ ++ArgNo;
+ if (ArgNo < 6)
+ BuildMI(BB, V8::IMPLICIT_DEF, 0, IncomingArgRegs[ArgNo]);
break;
default:
assert (0 && "type not handled");
@@ -343,76 +342,88 @@ void V8ISel::LoadArgumentsToVirtualRegs (Function *LF) {
}
}
- ArgOffset = 0;
- for (Function::aiterator I = LF->abegin(), E = LF->aend(); I != E;
- ++I, ++ArgOffset) {
- unsigned Reg = getReg(*I);
- if (ArgOffset < 6) {
-
- switch (getClassB(I->getType())) {
- case cByte:
- case cShort:
- case cInt:
- BuildMI(BB, V8::ORrr, 2, Reg).addReg (V8::G0)
- .addReg (IncomingArgRegs[ArgOffset]);
- break;
- case cFloat: {
+ // Copy args out of their incoming hard regs or stack slots into virtual regs.
+ const unsigned *IAREnd = &IncomingArgRegs[6];
+ const unsigned *IAR = &IncomingArgRegs[0];
+ unsigned ArgOffset = 68;
+ for (Function::aiterator I = LF->abegin(), E = LF->aend(); I != E; ++I) {
+ Argument &A = *I;
+ unsigned ArgReg = getReg (A);
+ if (getClassB (A.getType ()) < cLong) {
+ // Get it out of the incoming arg register
+ if (ArgOffset < 92) {
+ assert (IAR != IAREnd
+ && "About to dereference past end of IncomingArgRegs");
+ BuildMI (BB, V8::ORrr, 2, ArgReg).addReg (V8::G0).addReg (*IAR++);
+ } else {
+ int FI = F->getFrameInfo()->CreateFixedObject(4, ArgOffset);
+ BuildMI (BB, V8::LD, 3, ArgReg).addFrameIndex (FI).addSImm (0);
+ }
+ ArgOffset += 4;
+ } else if (getClassB (A.getType ()) == cFloat) {
+ if (ArgOffset < 92) {
// Single-fp args are passed in integer registers; go through
- // memory to get them into FP registers. (Bleh!)
+ // memory to get them out of integer registers and back into fp. (Bleh!)
unsigned FltAlign = TM.getTargetData().getFloatAlignment();
int FI = F->getFrameInfo()->CreateStackObject(4, FltAlign);
- BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (0)
- .addReg (IncomingArgRegs[ArgOffset]);
- BuildMI (BB, V8::LDFri, 2, Reg).addFrameIndex (FI).addSImm (0);
- break;
- }
- case cDouble: {
- // Double-fp args are passed in pairs of integer registers; go through
- // memory to get them into FP registers. (Double bleh!)
- unsigned DblAlign = TM.getTargetData().getDoubleAlignment();
- int FI = F->getFrameInfo()->CreateStackObject(8, DblAlign);
- BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (0)
- .addReg (IncomingArgRegs[ArgOffset]);
- ++ArgOffset;
- BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (4)
- .addReg (IncomingArgRegs[ArgOffset]);
- BuildMI (BB, V8::LDDFri, 2, Reg).addFrameIndex (FI).addSImm (0);
- break;
- }
- default:
- // FIXME: handle cLong
- assert (0 && "64-bit int (long/ulong) function args not handled");
- return;
+ assert (IAR != IAREnd
+ && "About to dereference past end of IncomingArgRegs");
+ BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (0).addReg (*IAR++);
+ BuildMI (BB, V8::LDFri, 2, ArgReg).addFrameIndex (FI).addSImm (0);
+ } else {
+ int FI = F->getFrameInfo()->CreateFixedObject(4, ArgOffset);
+ BuildMI (BB, V8::LDFri, 3, ArgReg).addFrameIndex (FI).addSImm (0);
}
-
- } else {
-
- switch (getClassB(I->getType())) {
- case cByte:
- case cShort:
- case cInt: {
- int FI = F->getFrameInfo()->CreateFixedObject(4, 68 + (4 * ArgOffset));
- BuildMI (BB, V8::LD, 2, Reg).addFrameIndex (FI).addSImm(0);
- break;
+ ArgOffset += 4;
+ } else if (getClassB (A.getType ()) == cDouble) {
+ // Double-fp args are passed in pairs of integer registers; go through
+ // memory to get them out of integer registers and back into fp. (Bleh!)
+ // We'd like to 'ldd' these right out of the incoming-args area,
+ // but it might not be 8-byte aligned (e.g., call x(int x, double d)).
+ unsigned DblAlign = TM.getTargetData().getDoubleAlignment();
+ int FI = F->getFrameInfo()->CreateStackObject(8, DblAlign);
+ if (ArgOffset < 92 && IAR != IAREnd) {
+ BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (0).addReg (*IAR++);
+ } else {
+ unsigned TempReg = makeAnotherReg (Type::IntTy);
+ BuildMI (BB, V8::LD, 2, TempReg).addFrameIndex (FI).addSImm (0);
+ BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (0).addReg (TempReg);
}
- case cFloat: {
- int FI = F->getFrameInfo()->CreateFixedObject(4, 68 + (4 * ArgOffset));
- BuildMI (BB, V8::LDFri, 2, Reg).addFrameIndex (FI).addSImm(0);
- break;
+ ArgOffset += 4;
+ if (ArgOffset < 92 && IAR != IAREnd) {
+ BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (4).addReg (*IAR++);
+ } else {
+ unsigned TempReg = makeAnotherReg (Type::IntTy);
+ BuildMI (BB, V8::LD, 2, TempReg).addFrameIndex (FI).addSImm (4);
+ BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (4).addReg (TempReg);
}
- case cDouble: {
- int FI = F->getFrameInfo()->CreateFixedObject(8, 68 + (4 * ArgOffset));
- BuildMI (BB, V8::LDDFri, 2, Reg).addFrameIndex (FI).addSImm(0);
- break;
+ ArgOffset += 4;
+ BuildMI (BB, V8::LDDFri, 2, ArgReg).addFrameIndex (FI).addSImm (0);
+ } else if (getClassB (A.getType ()) == cLong) {
+ // do the first half...
+ if (ArgOffset < 92) {
+ assert (IAR != IAREnd
+ && "About to dereference past end of IncomingArgRegs");
+ BuildMI (BB, V8::ORrr, 2, ArgReg).addReg (V8::G0).addReg (*IAR++);
+ } else {
+ int FI = F->getFrameInfo()->CreateFixedObject(4, ArgOffset);
+ BuildMI (BB, V8::LD, 2, ArgReg).addFrameIndex (FI).addSImm (0);
}
- default:
- // FIXME: handle cLong
- assert (0 && "64-bit integer (long/ulong) function args not handled");
- return;
+ ArgOffset += 4;
+ // ...then do the second half
+ if (ArgOffset < 92) {
+ assert (IAR != IAREnd
+ && "About to dereference past end of IncomingArgRegs");
+ BuildMI (BB, V8::ORrr, 2, ArgReg+1).addReg (V8::G0).addReg (*IAR++);
+ } else {
+ int FI = F->getFrameInfo()->CreateFixedObject(4, ArgOffset);
+ BuildMI (BB, V8::LD, 2, ArgReg+1).addFrameIndex (FI).addSImm (0);
}
+ ArgOffset += 4;
+ } else {
+ assert (0 && "Unknown class?!");
}
}
-
}
void V8ISel::SelectPHINodes() {
@@ -674,8 +685,17 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB,
case cLong:
switch (oldTyClass) {
+ case cByte:
+ case cShort:
+ case cInt:
+ // Just copy it to the bottom half, and put a zero in the top half.
+ BuildMI (*BB, IP, V8::ORrr, 2, DestReg).addReg (V8::G0)
+ .addReg (V8::G0);
+ BuildMI (*BB, IP, V8::ORrr, 2, DestReg+1).addReg (V8::G0)
+ .addReg (SrcReg);
+ break;
case cLong:
- // Just copy it
+ // Just copy both halves.
BuildMI (*BB, IP, V8::ORrr, 2, DestReg).addReg (V8::G0).addReg (SrcReg);
BuildMI (*BB, IP, V8::ORrr, 2, DestReg+1).addReg (V8::G0)
.addReg (SrcReg+1);