diff options
author | Brian Gaeke <gaeke@uiuc.edu> | 2004-07-16 10:31:25 +0000 |
---|---|---|
committer | Brian Gaeke <gaeke@uiuc.edu> | 2004-07-16 10:31:25 +0000 |
commit | 812c488f0a2d9d0fb39c3eb1a2446214d5de7efc (patch) | |
tree | 34ae76ef31192b26c680eaf230b4a1b1f2f7bc8d /lib/Target/Sparc/InstSelectSimple.cpp | |
parent | 81d54465d9c245bbc3cdf18ef99a50df470ad773 (diff) |
Do IMPLICIT_DEFs on incoming args' hard regs, to avoid confusing the regalloc.
Support single-fp incoming args.
Support single-fp outgoing args ('call' operands).
Support double-fp return values.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@14880 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/Sparc/InstSelectSimple.cpp')
-rw-r--r-- | lib/Target/Sparc/InstSelectSimple.cpp | 71 |
1 files changed, 61 insertions, 10 deletions
diff --git a/lib/Target/Sparc/InstSelectSimple.cpp b/lib/Target/Sparc/InstSelectSimple.cpp index 14f13cf470..bc1f6c40f7 100644 --- a/lib/Target/Sparc/InstSelectSimple.cpp +++ b/lib/Target/Sparc/InstSelectSimple.cpp @@ -302,14 +302,34 @@ void V8ISel::copyConstantToRegister(MachineBasicBlock *MBB, } } -void V8ISel::LoadArgumentsToVirtualRegs (Function *F) { - unsigned ArgOffset = 0; +void V8ISel::LoadArgumentsToVirtualRegs (Function *LF) { + unsigned ArgOffset; static const unsigned IncomingArgRegs[] = { V8::I0, V8::I1, V8::I2, V8::I3, V8::I4, V8::I5 }; - assert (F->asize () < 7 + assert (LF->asize () < 7 && "Can't handle loading excess call args off the stack yet"); - for (Function::aiterator I = F->abegin(), E = F->aend(); I != E; ++I) { + // Add IMPLICIT_DEFs of input regs. + ArgOffset = 0; + for (Function::aiterator I = LF->abegin(), E = LF->aend(); I != E; ++I) { + unsigned Reg = getReg(*I); + switch (getClassB(I->getType())) { + case cByte: + case cShort: + case cInt: + case cFloat: + BuildMI(BB, V8::IMPLICIT_DEF, 0, IncomingArgRegs[ArgOffset]); + break; + default: + // FIXME: handle cDouble, cLong + assert (0 && "64-bit (double, long, etc.) function args not handled"); + return; + } + ++ArgOffset; + } + + ArgOffset = 0; + for (Function::aiterator I = LF->abegin(), E = LF->aend(); I != E; ++I) { unsigned Reg = getReg(*I); switch (getClassB(I->getType())) { case cByte: @@ -318,12 +338,24 @@ void V8ISel::LoadArgumentsToVirtualRegs (Function *F) { BuildMI(BB, V8::ORrr, 2, Reg).addReg (V8::G0) .addReg (IncomingArgRegs[ArgOffset]); break; + case cFloat: { + // Single-fp args are passed in integer registers; go through + // memory to get them into FP registers. (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; + } default: - assert (0 && "Only <=32-bit, integral arguments currently handled"); + // FIXME: handle cDouble, cLong + assert (0 && "64-bit (double, long, etc.) function args not handled"); return; } ++ArgOffset; } + } void V8ISel::SelectPHINodes() { @@ -668,12 +700,23 @@ void V8ISel::visitCallInst(CallInst &I) { V8::O4, V8::O5 }; for (unsigned i = 1; i < 7; ++i) if (i < I.getNumOperands ()) { - assert (getClassB (I.getOperand (i)->getType ()) < cLong - && "Can't handle long or fp function call arguments yet"); unsigned ArgReg = getReg (I.getOperand (i)); - // Schlep it over into the incoming arg register - BuildMI (BB, V8::ORrr, 2, OutgoingArgRegs[i - 1]).addReg (V8::G0) - .addReg (ArgReg); + if (getClassB (I.getOperand (i)->getType ()) < cLong) { + // Schlep it over into the incoming arg register + BuildMI (BB, V8::ORrr, 2, OutgoingArgRegs[i - 1]).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, OutgoingArgRegs[i - 1]).addFrameIndex (FI) + .addSImm (0); + } else { + assert (0 && "64-bit (double, long, etc.) 'call' opnds not handled"); + } } // Emit call instruction @@ -716,6 +759,14 @@ void V8ISel::visitReturnInst(ReturnInst &I) { case cFloat: BuildMI (BB, V8::FMOVS, 2, V8::F0).addReg(RetValReg); break; + case cDouble: { + unsigned DoubleAlignment = TM.getTargetData().getDoubleAlignment(); + int FI = F->getFrameInfo()->CreateStackObject(8, DoubleAlignment); + BuildMI (BB, V8::STDFri, 3).addFrameIndex (FI).addSImm (0) + .addReg (RetValReg); + BuildMI (BB, V8::LDDFri, 2, V8::F0).addFrameIndex (FI).addSImm (0); + break; + } case cLong: BuildMI (BB, V8::ORrr, 2, V8::I0).addReg(V8::G0).addReg(RetValReg); BuildMI (BB, V8::ORrr, 2, V8::I1).addReg(V8::G0).addReg(RetValReg+1); |