Let us add some local variables:
int foo() { int retval = 0x0AB; int dummy = 0; return retval; }
This requires adding some information about accessing memory. I will just postulate that I have memory available from address 1 growing upwards. As anyone that really knows the HP-41 understands, this is a very bad idea. However we are still just showing some basic LLVM principles, not producing actually useful Nut code. I am however excluding the possibility of generating READ 0
, as that instruction does not even exist.
Some code snippets:
// Addressing modes. def ADDR : ComplexPattern<iPTR, 2, "SelectADDR", [frameindex], []>; // Address operands def MEM : Operand { let MIOperandInfo = (ops RC, i16imm); let PrintMethod = "printMemOperand"; let DecoderMethod = "decodeMemOperand"; } ... let mayLoad=1 in { def READ : HP41MCODEInst<0x078, (outs RC:$r), (ins MEM:$addr), "READ $addr", [(set RC:$r, (load ADDR:$addr))]>; } let mayStore=1 in { def WRIT : HP41MCODEInst<0x068, (outs), (ins MEM:$addr, RC:$r), "WRIT $addr", [(store RC:$r, ADDR:$addr)]>; } ... bool HP41MCODERegisterInfo::eliminateFrameIndex( MachineBasicBlock::iterator II, int SPAdj, unsigned FIOperandNum, RegScavenger *RS) const { MachineInstr &MI = *II; int FrameIndex = MI.getOperand(FIOperandNum).getIndex(); MachineFunction &MF = *MI.getParent()->getParent(); const HP41MCODEFrameLowering *TFI = getFrameLowering(MF); llvm::Register FrameReg; int Offset; Offset = TFI->getFrameIndexReference(MF, FrameIndex, FrameReg).getFixed()/4+1; MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false); MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset); return false; } ... void HP41MCODEInstPrinter::printMemOperand(const MCInst *MI, int opNum, const MCSubtargetInfo &STI, raw_ostream &O, const char *Modifier) { const MCOperand &MO = MI->getOperand(opNum+1); if (MO.isImm()) { O << format_decimal((int)MO.getImm(), 1); return; } assert(MO.isExpr() && "Unknown operand kind in printMemOperand"); MO.getExpr()->print(O, &MAI); } ... bool HP41MCODEDAGToDAGISel::SelectADDR(SDValue Addr, SDValue &Base, SDValue &Offset) { if (FrameIndexSDNode *FIN = dyn_cast(Addr)) { Base = CurDAG->getTargetFrameIndex( FIN->getIndex(), TLI->getPointerTy( CurDAG->getDataLayout())); Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32); return true; } return false; }
Then we end up with:
.file "hello.c" .text .globl foo ! -- Begin function foo .type foo,@function foo: ! @foo ! %bb.0: ! %entry LDI S&X HEX: 0AB WRIT 2 C=0 ALL WRIT 1 READ 2 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