[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