Basic Backend: Load Indirect

Hi,

I am Georg, a student for Embedded System Design at the University of Applied Sciences Upper Austria, Campus Hagenberg. (https://www.fh-ooe.at/en/hagenberg-campus/studiengaenge/master/embedded-systems-design/)

In some lectures at my university, a simple 16-bit CPU with a very small instruction set of only 24 instructions called PROL16 is used to teach CPU architecture and chip design.

I currently try to create a LLVM backend support for the PROL16 as part of a compiler example for my professor.

I started to use your LEG CPU framework(https://github.com/frasercrmck/llvm-leg/blob/master/lib/Target/LEG/) as base for the PROL16 as it is much simpler than the CPU0.

I put some time into implementing the Load/Store from/to Memory instruction.

In difference to the LEG Load/Store or most other CPUs, the PROL16 does not support an indirect memory load with an immediate.

So in LEG single instruction command like
ldr r5, sp #8

would result in a PROL16 Code more like this:

mov r4,#8 // no immediate support for arithmetic or logic instructions, therefore load the constant first into a register

add r4, r4, sp // calc the memory address

ldr r5, r4 // load indirect from memory address in r4 to register

I looked into other backends, eg. AVR or CPU0.

I found out that most likely the main topic is to adapt the SelectAddr function in LEGISelDAGToDAG.cpp so the offset it not used anymore.

I do not know how to solve this.

Does someone have a hint for me? I would very much appreciate it.

Best regards

Georg

Hi Georg,

ldr r5, r4 // load indirect from memory address in r4 to register

[...]

Does someone have a hint for me? I would very much appreciate it.

This CPU sounds simple enough that it won't need SelectAddrMode
functions at all. They're there mostly for targets with lots of
different possible ways to form an address with different trade-offs
in efficiency & size..

For you, an address has to be in a register, so you can probably just
write a TableGen pattern on the load instruction itself. Something
like:

   (set GPR:$Rd, (load GPR:$addr))

ought to work for the load.

Cheers.

Tim.

Hello Tim,

Thanks for rely.

I tried for some days now, and still was not able to solve it.

As you recommended, I tried removed the SelectAddrMode.

I took the LEG backend and only tried to change the LDR(LOAD from register + offset) instruction in to a register-only based instruction for now.

I uploaded the code to github (llvm-leg/LEGInstrInfo.td at master · ATSchorsch/llvm-leg · GitHub) . I tried to reduce the changes to a minimum in "LEGInstrInfo.td" and "LEGOperators.td".

The first try was to only change the LDR instruction and added an basic Load-Immidiate (LOADi) instruction. With this I got the following error when compiling a simple IR code:

sample.ll (819 Bytes)

ERROR2.txt (1.86 KB)