As a small update, I switched out my 'special' store instruction for a store and then a sub (both of which are fully described), and yet the resulting assembly still doesn't seem to realize that the SP/FP has moved:<div>
<br></div><div><a href="http://pastebin.com/RLj8B8Pe">http://pastebin.com/RLj8B8Pe</a><br><div><div><br></div><div>I considered handling this *in* LowerFormalArguments, by working out the offset there, but that depends on knowing if the function makes calls or not, and I'm not sure if that information is around then. Plus it also feels very hacky!</div>
<div><br></div><div>Stephen<br><br><div class="gmail_quote">On 26 October 2012 11:54, Stephen McGruer <span dir="ltr"><<a href="mailto:stephen.mcgruer@gmail.com" target="_blank">stephen.mcgruer@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">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>
</blockquote></div><br></div></div></div>