scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit 36ae36d877ddd8e3ecd6ec6934747d0ff205e3d7
parent 31b9dcca7a6cdf594f692382a1ca97171cbf95bc
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Fri, 29 Sep 2017 09:55:23 +0100

[as] Add r8_imm format instruction in z80

This instruction format is used in that instruction that
uses a register from A, B, C, D, E, H, L and a 8 bit
inmediate.

Diffstat:
as/expr.c | 2++
as/main.c | 1+
as/target/gen.awk | 2++
as/target/x80/ins.c | 33+++++++++++++++++++++++++++++++++
as/target/x80/proc.h | 5+++++
as/target/x80/x80.dat | 1+
as/target/z80/ins.c | 2+-
as/target/z80/proc.c | 9++++++++-
as/target/z80/target.mk | 2+-
9 files changed, 54 insertions(+), 3 deletions(-)

diff --git a/as/expr.c b/as/expr.c @@ -260,6 +260,8 @@ reg(void) int c; char *p; + if (*textp == '%') + ++textp, ++endp; while (isalnum(c = *endp)) ++endp; tok2str(); diff --git a/as/main.c b/as/main.c @@ -105,6 +105,7 @@ main(int argc, char *argv[]) if (argc != 2) usage(); + iarch(); filename = argv[1]; for (pass = 1; pass <= 2; pass++) { if (!dopass(filename)) diff --git a/as/target/gen.awk b/as/target/gen.awk @@ -74,6 +74,8 @@ function str2args(s, args, i, out) out = out "AIMM32" } else if (match(a, /^imm64/)) { out = "AIMM64" + } else if (match(a, /^reg_8/)) { + out = out "AREG_8" } else { print "wrong arg", a exit 1 diff --git a/as/target/x80/ins.c b/as/target/x80/ins.c @@ -0,0 +1,33 @@ +static char sccsid[] = "@(#) ./as/target/z80/ins.c"; + +#include "../../../inc/scc.h" +#include "../../as.h" +#include "proc.h" + +int +r8(int reg) +{ + switch (reg) { + case AREG_B: return 0; + case AREG_C: return 1; + case AREG_D: return 2; + case AREG_E: return 3; + case AREG_H: return 4; + case AREG_L: return 5; + case AREG_A: return 7; + default: return -1; + } +} + +void +r8_imm(Op *op, Node **args) +{ + Node *par1, *par2; + unsigned char buf[2]; + + par1 = *args++; + par2 = *args; + buf[0] = *op->bytes | r8(par1->sym->argtype) << 3; + buf[1] = par2->sym->value; + emit(cursec, buf, 2); +} diff --git a/as/target/x80/proc.h b/as/target/x80/proc.h @@ -27,4 +27,8 @@ enum args { AREG_R, AREG_I, AREG_AF_, + + AREG_8, /* class register for B, C, D, E, H, L and A */ }; + +extern int r8(int reg);+ \ No newline at end of file diff --git a/as/target/x80/x80.dat b/as/target/x80/x80.dat @@ -51,3 +51,4 @@ OUTI none 2 0xed,0xa3 noargs Z80,R800 OTIR none 2 0xed,0xb3 noargs Z80,R800 OUTD none 2 0xed,0xab noargs Z80,R800 OTDR none 2 0xed,0xbb noargs Z80,R800 +LD reg_8,imm8 2 0x06 r8_imm Z80,R800,GB80 diff --git a/as/target/z80/ins.c b/as/target/z80/ins.c @@ -1,4 +1,4 @@ -static char sccsid[] = "@(#) ./as/target/i386/ins.c"; +static char sccsid[] = "@(#) ./as/target/z80/ins.c"; #include "../../../inc/scc.h" #include "../../as.h" diff --git a/as/target/z80/proc.c b/as/target/z80/proc.c @@ -64,6 +64,12 @@ match(Op *op, Node **args) if (arg & AREP) --p; switch (arg & ~AREP) { + case AREG_8: + if (np->op != AREG) + return 0; + if (r8(np->sym->argtype) == -1) + return 0; + break; case AIMM8: case AIMM16: case AIMM32: @@ -78,5 +84,6 @@ match(Op *op, Node **args) abort(); } } - return 1; + + return (!arg || arg & AREP) && !*args; } diff --git a/as/target/z80/target.mk b/as/target/z80/target.mk @@ -1,5 +1,5 @@ -Z80_LST = target/z80/instbl.o target/z80/ins.o target/z80/proc.o +Z80_LST = target/z80/instbl.o target/z80/ins.o target/z80/proc.o target/x80/ins.o $(Z80_LST): target/x80/proc.h