Uncategorized
LLVM Exercise VII
So why does the code produced in the last exercise contain the labels .LBB0_2 and .LBB0_3 but no .LBB0_1? Well that is because I have added a code generation pass that deletes useless jumps like: JNC .LBB0_1 .LBB0_1: Code snippets: void HP41MCODEPassConfig::addPreEmitPass() { addPass(new RemoveUselessJMP()); } … bool RemoveUselessJMP::runOnMachineBasicBlock( MachineBasicBlock &MBB, MachineBasicBlock &MBBN) { bool … Continue reading
LLVM Exercise VI
It is time to bring in some conditionals. Adding an “if” to our friend foo(): int foo() { int retval1 = 0x0AB; int retval2 = 0; if (retval2) return retval2; return retval1; } We need to implement instructions for both conditional and unconditional branches (i.e jumps). An unconditional branch is just like this (assuming no … Continue reading
LLVM Exercise V
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 … Continue reading
LLVM Exercise IV
How about calling another function: int foo() { return 0xFF; } int bar() { return foo(); } Code snippets: … def CC_HP41MCODE : CallingConv<[]>; … def SDT_HP41MCODENCXQ : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>; def HP41MCODENCXQ : SDNode<“HP41MCODEISD::NCXQ”, SDT_HP41MCODENCXQ, [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>; … def calltarget : Operand; … let isCall=1 in { def NCXQ : HP41MCODEInst<0x001, … Continue reading
Superdense Coding Emulation on a TI-84 Plus CE-T
This is sort of the opposite of the Quantum Teleportation we have covered earlier. Here you use quantum bits to transfer classical bits: We have all the building blocks we need from the previous episode, so let me just show you the additional code: #Alice bits a1=1 a2=1 print(“Alice bits:”,a1,a2) #Initialize inputs q=[[1],[0],[0],[0]] #Build circuit … Continue reading
LLVM Exercise III
Let us return a larger constant: int foo() { return 0xFF; } For numbers up to 12 bits we can use the LDI S&X instruction. Some code snippets: def immSExt12 : PatLeaf<(imm), [{ return isInt<12>(N->getSExtValue()); }]>; def : Pat<(i32 immSExt12:$in), (LDI imm:$in)>; def LDI : HP41MCODEInst<0x130, (outs RC:$r), (ins i32imm:$sx), “LDI S&X HEX: $sx”, [(set … Continue reading
LLVM Exercise II
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 … Continue reading
LLVM Exercise I
How to make a compiler? As an exercise I have already threatened to produce at least some assembly code for the Nut CPU used in the HP-41 calculator. There will be huge compromises (it is after all just an exercise): I will copy and strip down an existing compiler backend in the LLVM project, then … Continue reading
HP-41CV Microcode
The HP-41 calculators can be programmed with microcode, aka MCODE. This is how their normal instructions are implemented. The emulator even has an MCODE console where you can step though its instructions. On the physical machine running your own MCODE requires making ROMs (or something that pretends to be a ROM…). I am not familiar … Continue reading