A tiny addition to the empty function. Returning zero:
int foo() { return 0; }
Remember, we will not care about returning values to the calculator registers (at not least for now). We will only generate functions callable from MCODE. So as a convention we will choose to return values in the C register.
So we will need an instruction to load 0
into the C register:
def Ceq0ALL : HP41MCODEInst<0x04E, (outs RC:$r), (ins), "C=0 ALL", [(set RC:$r, 0)]>;
This replacement pattern will make sure a constant 0
is loaded with this instruction:
def : Pat<(i32 0), (Ceq0ALL)>;
A register class for just this register (the instruction is only used with the C register, i.e. implicit addressing):
def RC : RegisterClass<"HP41MCODE", [i32], 8, (add C)>;
Defining the calling convention to return values in the C register:
def RetCC_HP41MCODE : CallingConv<[ CCAssignToReg<[C]> ]>;
Adding this calling convention to the LowerReturn()
function mentioned earlier, to analyze returns:
SDValue HP41MCODETargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl &Outs, const SmallVectorImpl &OutVals, const SDLoc &DL, SelectionDAG &DAG) const { ... // Analyze return values. CCInfo.AnalyzeReturn(Outs, RetCC_HP41MCODE); ... return DAG.getNode(HP41MCODEISD::RTN, DL, MVT::Other, RetOps); }
That gives us this MCODE assembly:
.file "hello.c" .text .globl foo ! -- Begin function foo .type foo,@function foo: ! @foo ! %bb.0: ! %entry C=0 ALL RTN .Lfunc_end0: .size foo, .Lfunc_end0-foo ! -- End function .ident "clang version 20.0.0git (https://github.com/llvm/llvm-project.git ea1dfd50bfdfbd75969fd7653bc71c81f2a2350f)" .section ".note.GNU-stack" .addrsig