<div dir="ltr">Hi, All,<div><br></div><div>I'm trying to build a customized backend and I need to lower the formal arguments like this: </div><div><br></div><div>There are several specific registers just for storing formal arguments. And also there are several general purpose registers for computation. If there is an instruction which uses parameters, I should first use a move instruction, which moves the value to general purpose register. For example, in RegisterInfo.td , I have following register classes:</div><div><br></div><div>// this is for storing parameters only </div><div><div>def PRegs : RegisterClass<"FOO", [i32], 32,</div><div> (add P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15)>;</div><div><br></div><div>// this is general purpose register class </div><div>def GRRegs : RegisterClass<"FOO", [i32], 32,</div><div> (add R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10)>;</div></div><div><br></div><div>// this is also general purpose register class</div><div><div>def GRRegsAdditional : RegisterClass<"FOO", [i32], 32,</div><div> (add R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, SP)>;</div></div><div><br></div><div><div>If I have a piece of bitcode looks like this:<br></div><div><br></div><div><div>define i32 @_Z3fooii(i32 %a, i32 %b) #0 {</div><div> %1 = add nsw i32 %a, %b</div><div> ret i32 %1</div><div>}</div></div></div><div><br></div><div>I want the assembly looks like this:</div><div> move v0, p0</div><div> move v1, p1</div><div><div> add-int v10, v0, v1</div><div> return v10</div></div><div><br></div><div>So far, I have tried is to implement the LowerFormalArguments() like this:</div><div><br></div><div><div>SDValue FOOTargetLowering::LowerFormalArguments(</div><div> SDValue Chain, CallingConv::ID CallConv, bool isVarArg,</div><div> const SmallVectorImpl<ISD::InputArg> &Ins, SDLoc dl, SelectionDAG &DAG,</div><div> SmallVectorImpl<SDValue> &InVals) const {</div><div> MachineFunction &MF = DAG.getMachineFunction();</div><div> MachineRegisterInfo &RegInfo = MF.getRegInfo();</div><div><br></div><div> assert(!isVarArg && "VarArg not supported");</div><div><br></div><div> // Assign locations to all of the incoming arguments.</div><div> SmallVector<CCValAssign, 16> ArgLocs;</div><div> CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,</div><div> *DAG.getContext());</div><div><br></div><div> CCInfo.AnalyzeFormalArguments(Ins, CC_FOO);</div><div><br></div><div> for (auto &VA : ArgLocs) {</div><div> if (VA.isRegLoc()) {</div><div> // Arguments passed in registers</div><div> EVT RegVT = VA.getLocVT();</div><div> const unsigned VReg = RegInfo.createVirtualRegister(&FOO::PRegsRegClass);</div><div> RegInfo.addLiveIn(VA.getLocReg(), VReg);</div><div> SDValue ArgIn = DAG.getCopyFromReg(Chain, dl, VReg, RegVT);</div><div> </div><div> InVals.push_back(ArgIn);</div><div> continue;</div><div> }</div><div> // assume the parameter registers are enough, no need to store in frame right now</div><div> }</div><div> return Chain;</div><div>}</div></div><div><br></div><div>In the above function, CC_FOO is defined in CallingConv.td and "CCIfType<[i32], CCAssignToReg<[P0,P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15]>>" is used. </div><div>Also I define a move instruction which move the value from PRegs to GRRegs because my add instruction's source registers should belong to GRRegs or GRRegsAdditional. </div><div>I define 'move' and 'add' instructions like this:</div><div><br></div><div><div>def MoveRRTy : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisInt<0>]>;</div><div><br></div><div>def moverr : SDNode<"FOOISD::MOVERR", MoveRRTy>;</div></div><div><br></div><div><div>def MOVE : InstFOO<(outs GRRegsAdditional:$dst), </div><div> (ins PRegs:$src), </div><div> "move $dst, $src",[(set i32:$dst, (moverr i32:$src))]>;</div></div><div><br></div><div><div>def ADDINT: InstFOO<(outs GRRegsAdditional:$dst),</div><div> (ins GRRegsAdditional:$src1, GRRegsAdditional:$src2),</div><div> "add-int $dst, $src1, $src2",</div><div> [(set i32:$dst, (add i32:$src1, i32:$src2))]>;</div></div><div><br></div><div>I assume this could work.</div><div><br></div><div>However, when I use llc and print-after-all to check the machine instructions. At very beginning, the machine instructions look like this:</div><div><br></div><div> <span style="white-space:pre-wrap">%vreg1<def> = COPY %P1; PRegs:%vreg1
%vreg0<def> = COPY %P0; PRegs:%vreg0
%vreg3<def> = COPY %vreg0; GRRegsAdditional:%vreg3 PRegs:%vreg0
%vreg4<def> = COPY %vreg1; GRRegsAdditional:%vreg4 PRegs:%vreg1
%vreg2<def> = ADDINT %vreg3, %vreg4; GRRegsAdditional:%vreg2,%vreg3,%vreg4
%R10<def> = COPY %vreg2; GRRegsAdditional:%vreg2
RET %R10
<br></span></div><div>And after "Post-RA pseudo instruction expansion pass", it looks like this</div><div><br></div><div><div>Function Live Ins: %P0 in %vreg0, %P1 in %vreg1</div><div>BB#0: derived from LLVM BB %0</div><div> Live Ins: %P0 %P1</div><div><span class="" style="white-space:pre"> </span>%R10<def> = ADDINT %R0<kill>, %R1<kill></div><div><span class="" style="white-space:pre"> </span>RET %R10</div></div><div><br></div><div>And eventually, the assembly file .s looks like this</div><div><br></div><div><div># BB#0:</div><div> add-int v10, v0, v1</div><div> return v10</div></div><div><br></div><div>It seems that there is no "move v0, p0" and "move v1, p1" at all. But I'm not sure why is this. I appreciate any suggestions and points.</div><div><br></div><div>Regards,</div><div><br></div><div>Xiangyang</div><div><br></div><div><br></div></div>