LLVM Exercise II

Posted by on January 24, 2025

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

Comments are closed.