[LLVMdev] LLVM Backend for Z80. ADD -> replaced -> OR

Peter Hanzel hanzelpeter at gmail.com
Wed Apr 25 01:57:37 PDT 2012


Hello.

I am playing with LLVM and trying to make Z80 (Zilog Z80) backend.
The source code is attached.

I have succesfully made some simple test. But now I have problem with ADD 
instruction.
The source C code is:

typedef struct
{
 unsigned char id1;
 unsigned char id2;
 unsigned char id3;

} testS;

void simple()
{
 testS test;
 test.id1 = 0x40;
 test.id2 = 0x80;
 test.id3 = 0xc0;
}

It produces this LLVM IR:

%struct.testS = type { i8, i8, i8 }

define void @simple() nounwind {
entry:
  %test = alloca %struct.testS, align 1
  %id1 = getelementptr inbounds %struct.testS* %test, i32 0, i32 0
  store i8 64, i8* %id1, align 1
  %id2 = getelementptr inbounds %struct.testS* %test, i32 0, i32 1
  store i8 -128, i8* %id2, align 1
  %id3 = getelementptr inbounds %struct.testS* %test, i32 0, i32 2
  store i8 -64, i8* %id3, align 1
  ret void
}

And with llc -filetype=asm -march=z80 a get this .s file:

 .file "simple4.bc"
 .text
 .globl simple
 .type simple, at function
simple:                                 # @simple
# BB#0:                                 # %entry
 ld HL, 8
 add HL,SP                        <--- problem line
 ld DE, 1
 ld BC, 2
 ld (SP+6), BC
 ld B, H
 ld C, L
 or BC, DE
 ld (SP+4), BC
 ld (HL),64
 ld D, H
 ld E, L
 ld BC, (SP+6)
 or DE, BC
 ld BC, (SP+4)
 ld H, B
 ld L, C
 ld (HL),-128
 ld H, D
 ld L, E
 ld (HL),-64
$tmp0:
 .size simple, ($tmp0)-simple


The problem is that llc replaces ADD instruction with OR.

Without defining OR16 function, the .S is not generated and claims that it 
cannot select OR instruction.
So I added OR16 (that's the or BC,DE piece of code).

But problem is that I am using the first two lines:

 ld HL, 8
 add HL,SP

For FrameIndex and the HL register will contain SP which is only two 2bytes 
aligned.
So "OR with 1" will work, but for second assigned :OR with 2" will not work.

I suspect that llc is assuming that HL will contain 8 (that's the start) and 
or-ing 8 with 1 or with 2 is ok.
But my HL has also added SP to it.
This is how my ISD::FrameIndex instruction look like:

def addHLdisp : Z80Instr<(outs HL16:$dst), (ins i16imm:$disp, GPR16:$src),
 "ld $dst, $disp\n\tadd $dst,$src",
 [(set HL16:$dst, (add GPR16:$src, (i16 imm:$disp)))]>;

So it say that HL16:$dst wich is only HL register, will be changed.
I also tried to change it to
<(outs HL16:$dst), (ins i16imm:$disp, SP16:$src),

But the output is the same.

Can someone tell me what I am doing wrong?

Peter.








-------------- next part --------------
A non-text attachment was scrubbed...
Name: llvm_to_send.tgz
Type: application/x-compressed
Size: 20867 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20120425/837febdd/attachment.bin>


More information about the llvm-dev mailing list