For my target, I handle incoming memory arguments by creating a store to memory (in LowerCall, [1]), then creating a fixed object on the stack and loading from it (in LowerFormalArguments[2]). This approach was based on MSP430. <div>
<br></div><div>I now have the problem that the resulting loads in my output assembly are done assuming that the call stack looks something like:</div><div><br></div><div><font face="courier new, monospace">------</font></div>
<div><font face="courier new, monospace">MemArg</font></div><div><font face="courier new, monospace">------</font></div><div><font face="courier new, monospace">MemArg</font></div><div><font face="courier new, monospace">------ <-- Frame Pointer</font></div>
<div><br></div><div>This isn't true, because during prologue I emit a number of instructions to store the return address, the old frame pointer value, etc[3], so that the stack ends up looking like:</div><div><br></div>
<div><div><font face="courier new, monospace">------</font></div><div><font face="courier new, monospace">MemArg</font></div><div><font face="courier new, monospace">------</font></div><div><font face="courier new, monospace">MemArg</font></div>
<div><font face="courier new, monospace">------</font></div><div><font face="courier new, monospace">VarArg</font></div><div><font face="courier new, monospace">------</font></div><div><span style="font-family:'courier new',monospace">Return Addr Register</span></div>
<div><span style="font-family:'courier new',monospace">------</span></div><div><span style="font-family:'courier new',monospace">Old Frame Pointer</span></div><div><span style="font-family:'courier new',monospace">------ <-- Frame Pointer</span></div>
</div><div><br></div><div>At this point, the memory-argument instructions like 'ld rX, [fp]' (load from frame-pointer) now obviously load the wrong data.</div><div><br></div><div>How can I 'fix' the load instructions to point to the right locations in memory? (That is, increase their offset by the space that the prologue adds to the stack)?</div>
<div><br></div><div>One thing that I've just realized may be notable is that my prologue code (see [3]) uses a special "st.a" instruction that both stores to a memory location and decrements the address-argument-register. (i.e. st.a r1, [r2, 4] does r2 = r2 - 4 then stores to [r2]). So if LLVM normally guesses these things automatically from the instructions, it wouldn't be able to guess that. But here I'm just conjecturing - may not be relevant!</div>
<div><br>Thanks,<br>Stephen</div><div><br></div><div><div>[1]: LowerCall</div><div><font face="courier new, monospace">...</font></div><div><div><font face="courier new, monospace">    // Arguments that can be passed in a register must be kept in the</font></div>
<div><font face="courier new, monospace">    // RegsToPass vector.</font></div><div><font face="courier new, monospace">    if (VA.isRegLoc()) {</font></div><div><font face="courier new, monospace">      RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));</font></div>
<div><font face="courier new, monospace">    } else {</font></div><div><font face="courier new, monospace">      // Sanity check.</font></div><div><font face="courier new, monospace">      assert(VA.isMemLoc());</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">      // Get the stack pointer if needed.</font></div><div><font face="courier new, monospace">      if (StackPtr.getNode() == 0) {</font></div>
<div><font face="courier new, monospace">        StackPtr = DAG.getCopyFromReg(Chain, dl, ARC::SP, getPointerTy());</font></div><div><font face="courier new, monospace">      }   </font></div><div><font face="courier new, monospace"><br>
</font></div><div><font face="courier new, monospace">      SDValue PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(), StackPtr,</font></div><div><font face="courier new, monospace">          DAG.getIntPtrConstant(VA.getLocMemOffset()));</font></div>
<div><font face="courier new, monospace">      MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff,</font></div><div><font face="courier new, monospace">          MachinePointerInfo(),false, false, 0));</font></div>
<div><font face="courier new, monospace">    }</font></div></div><div><font face="courier new, monospace">...</font></div><div><br></div><div>[2]: LowerFormalArguments</div><div><font face="courier new, monospace">...</font></div>
<div><div><font face="courier new, monospace">    if (VA.isRegLoc()) {</font></div><div><font face="courier new, monospace">      // Arguments passed in registers.</font></div><div><font face="courier new, monospace"><br>
</font></div><div><font face="courier new, monospace">      const TargetRegisterClass *RC = ARC::CPURegsRegisterClass;</font></div><div><font face="courier new, monospace">      unsigned int Register = MF.addLiveIn(VA.getLocReg(), RC);</font></div>
<div><font face="courier new, monospace">      EVT RegisterValueType = VA.getLocVT();</font></div><div><font face="courier new, monospace">      ArgValue = DAG.getCopyFromReg(Chain, dl, Register, RegisterValueType);</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">      InVals.push_back(ArgValue);</font></div><div><font face="courier new, monospace">    } else {</font></div><div><font face="courier new, monospace">      // Sanity check</font></div>
<div><font face="courier new, monospace">      assert(VA.isMemLoc());</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">      // Load the argument to a virtual register</font></div>
<div><font face="courier new, monospace">      unsigned ObjSize = VA.getLocVT().getSizeInBits()/8;</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">      if (ObjSize != 4) {</font></div>
<div><font face="courier new, monospace">        llvm_unreachable("Memory argument is wrong size - not 32 bit!");</font></div><div><font face="courier new, monospace">      }</font></div><div><font face="courier new, monospace"><br>
</font></div><div><font face="courier new, monospace">      // Create the frame index object for this incoming parameter...</font></div><div><font face="courier new, monospace">      int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset(), true);</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">      // Create the SelectionDAG nodes corresponding to a load from this</font></div><div><font face="courier new, monospace">      // parameter.</font></div>
<div><font face="courier new, monospace">      SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);</font></div><div><font face="courier new, monospace">      InVals.push_back(DAG.getLoad(VA.getLocVT(), dl, Chain, FIN,</font></div>
<div><font face="courier new, monospace">                                   MachinePointerInfo::getFixedStack(FI),</font></div><div><font face="courier new, monospace">                                   false, false, false, 0));</font></div>
<div><font face="courier new, monospace">    }</font></div></div><div><font face="courier new, monospace">...</font></div></div><div><font face="courier new, monospace"><br></font></div><div><font face="arial, helvetica, sans-serif">[3] Example of prologue moving stack pointer (which the frame pointer is then set to.)</font></div>
<div><font face="arial, helvetica, sans-serif">...</font></div><div><div><font face="courier new, monospace">  if (VARegSaveSize) {</font></div><div><font face="courier new, monospace">    BuildMI(MBB, MBBI, dl, TII.get(ARC::SUBrsi), ARC::SP).addReg(ARC::SP)</font></div>
<div><font face="courier new, monospace">        .addImm(VARegSaveSize);</font></div><div><font face="courier new, monospace">  }</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">  // Save the return address register, if necessary</font></div>
<div><font face="courier new, monospace">  if (MFI->adjustsStack()) {</font></div><div><font face="courier new, monospace">    BuildMI(MBB, MBBI, dl, TII.get(ARC::STrri_a)).addReg(ARC::SP)</font></div><div><font face="courier new, monospace">        .addImm(-UNITS_PER_WORD).addReg(ARC::BLINK);</font></div>
<div><font face="courier new, monospace">  }</font></div><div><br></div><div><font face="courier new, monospace">  // Save the caller's frame pointer (if required), and set new FP to this</font></div><div><font face="courier new, monospace">  // location.</font></div>
<div><font face="courier new, monospace">  BuildMI(MBB, MBBI, dl, TII.get(ARC::STrri_a)).addReg(ARC::SP)</font></div><div><font face="courier new, monospace">      .addImm(-UNITS_PER_WORD).addReg(ARC::FP);</font></div><div>
<font face="courier new, monospace">  BuildMI(MBB, MBBI, dl, TII.get(ARC::MOVrr), ARC::FP).addReg(ARC::SP);</font></div><div style="font-family:arial,helvetica,sans-serif">...</div></div>