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