+//---------------------------------------------------------------------------
+// Helper method for UltraSparcRegInfo::colorCallArgs().
+//---------------------------------------------------------------------------
+
+void
+UltraSparcRegInfo::InitializeOutgoingArg(MachineInstr* CallMI,
+ AddedInstrns *CallAI,
+ PhyRegAlloc &PRA, LiveRange* LR,
+ unsigned regType, unsigned RegClassID,
+ int UniArgRegOrNone, unsigned int argNo,
+ std::vector<MachineInstr *>& AddedInstrnsBefore)
+ const
+{
+ MachineInstr *AdMI;
+ bool isArgInReg = false;
+ unsigned UniArgReg = MAXINT; // unused unless initialized below
+ if (UniArgRegOrNone != InvalidRegNum)
+ {
+ isArgInReg = true;
+ UniArgReg = (unsigned) UniArgRegOrNone;
+ CallMI->insertUsedReg(UniArgReg); // mark the reg as used
+ }
+
+ if (LR->hasColor()) {
+ unsigned UniLRReg = getUnifiedRegNum(RegClassID, LR->getColor());
+
+ // if LR received the correct color, nothing to do
+ if( isArgInReg && UniArgReg == UniLRReg )
+ return;
+
+ // The LR is allocated to a register UniLRReg and must be copied
+ // to UniArgReg or to the stack slot.
+ //
+ if( isArgInReg ) {
+ // Copy UniLRReg to UniArgReg
+ cpReg2RegMI(AddedInstrnsBefore, UniLRReg, UniArgReg, regType);
+ }
+ else {
+ // Copy UniLRReg to the stack to pass the arg on stack.
+ const MachineFrameInfo& frameInfo = target.getFrameInfo();
+ int argOffset = frameInfo.getOutgoingArgOffset(PRA.MF, argNo);
+ cpReg2MemMI(CallAI->InstrnsBefore,
+ UniLRReg, getStackPointer(), argOffset, regType);
+ }
+
+ } else { // LR is not colored (i.e., spilled)
+
+ if( isArgInReg ) {
+ // Insert a load instruction to load the LR to UniArgReg
+ cpMem2RegMI(AddedInstrnsBefore, getFramePointer(),
+ LR->getSpillOffFromFP(), UniArgReg, regType);
+ // Now add the instruction
+ }
+
+ else {
+ // Now, we have to pass the arg on stack. Since LR also did NOT
+ // receive a register we have to move an argument in memory to
+ // outgoing parameter on stack.
+ // Use TReg to load and store the value.
+ // Use TmpOff to save TReg, since that may have a live value.
+ //
+ int TReg = PRA.getUniRegNotUsedByThisInst( LR->getRegClass(), CallMI );
+ int TmpOff = PRA.MF.pushTempValue(target,
+ getSpilledRegSize(getRegType(LR)));
+ const MachineFrameInfo& frameInfo = target.getFrameInfo();
+ int argOffset = frameInfo.getOutgoingArgOffset(PRA.MF, argNo);
+
+ MachineInstr *Ad1, *Ad2, *Ad3, *Ad4;
+
+ // Sequence:
+ // (1) Save TReg on stack
+ // (2) Load LR value into TReg from stack pos of LR
+ // (3) Store Treg on outgoing Arg pos on stack
+ // (4) Load the old value of TReg from stack to TReg (restore it)
+ //
+ // OPTIMIZE THIS:
+ // When reverse pointers in MahineInstr are introduced:
+ // Call PRA.getUnusedRegAtMI(....) to get an unused reg. Step 1 is
+ // needed only if this fails. Currently, we cannot call the
+ // above method since we cannot find LVSetBefore without the BB
+ //
+ // NOTE: We directly add to CallAI->InstrnsBefore instead of adding to
+ // AddedInstrnsBefore since these instructions must not be reordered.
+ cpReg2MemMI(CallAI->InstrnsBefore,
+ TReg, getFramePointer(), TmpOff, regType);
+ cpMem2RegMI(CallAI->InstrnsBefore,
+ getFramePointer(), LR->getSpillOffFromFP(), TReg, regType);
+ cpReg2MemMI(CallAI->InstrnsBefore,
+ TReg, getStackPointer(), argOffset, regType);
+ cpMem2RegMI(CallAI->InstrnsBefore,
+ getFramePointer(), TmpOff, TReg, regType);
+ }
+ }
+}
+