scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | README | LICENSE

commit 1a8e74a551e14e9971a1db05b86a1824d53694cf
parent 9995649367b583855c106ac53a1992b507b58d18
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Wed, 13 Dec 2017 07:38:44 +0000

Merge branch 'master' of ssh://simple-cc.org:/var/gitrepos/scc

Diffstat:
Mas/as.h | 2+-
Mas/ins.c | 4++--
Mas/symbol.c | 11+++++++----
Mas/target/gen.awk | 4+++-
Mas/target/x80/ins.c | 29+++++++++++++++++++++++------
Mas/target/x80/x80.dat | 2++
Mas/target/z80/proc.c | 4++++
7 files changed, 42 insertions(+), 14 deletions(-)

diff --git a/as/as.h b/as/as.h @@ -119,7 +119,7 @@ struct node { /* symbol.c */ extern void isections(void); -extern void emit(Section *sec, char *bytes, int nbytes); +extern void emit(char *bytes, int nbytes); extern Section *section(char *name); extern Symbol *tmpsym(TUINT val); extern void killtmp(void); diff --git a/as/ins.c b/as/ins.c @@ -24,7 +24,7 @@ tobytes(TUINT v, int nbytes, int inc) void noargs(Op *op, Node **args) { - emit(cursec, op->bytes, op->size); + emit(op->bytes, op->size); } void @@ -37,7 +37,7 @@ def(Node **args, int siz) if (sym->flags & FUNDEF) reloc(sym, 0, siz, siz * 8, 0); - emit(cursec, tobytes(sym->value, siz, endian), siz); + emit(tobytes(sym->value, siz, endian), siz); } } diff --git a/as/symbol.c b/as/symbol.c @@ -135,7 +135,8 @@ deflabel(char *name) sym = lookup(name, FUNDEF); if (pass == 1 && (sym->flags & FUNDEF) == 0) error("redefinition of label '%s'", name); - sym->flags &= ~FUNDEF; + if (cursec->flags & SABS) + sym->flags &= ~FUNDEF; sym->value = cursec->curpc; if (*name != '.') @@ -222,10 +223,12 @@ isections(void) } void -emit(Section *sec, char *bytes, int n) +emit(char *bytes, int n) { - if (sec->mem) - memcpy(&sec->mem[sec->pc - sec->base], bytes, n); + if (cursec->mem) { + size_t len = cursec->pc - cursec->base; + memcpy(&cursec->mem[len], bytes, n); + } incpc(n); } diff --git a/as/target/gen.awk b/as/target/gen.awk @@ -85,8 +85,10 @@ function str2args(s, args, i, out, n) out = out "AREG_A" } else if (match(a, /^indir_HL/)) { out = out "AINDER_HL" + } else if (match(a, /^HL/)) { + out = out "AREG_HL" } else { - print "wrong arg", a + print "wrong arg", a > "/dev/stderr" exit 1 } a = substr(a, RLENGTH+1) diff --git a/as/target/x80/ins.c b/as/target/x80/ins.c @@ -90,7 +90,7 @@ r8_imm8(Op *op, Node **args) memcpy(buf, op->bytes, n-1); buf[n-1] = par2->sym->value; buf[n-2] |= reg2int(par1->sym->argtype) << 3; - emit(cursec, buf, n); + emit(buf, n); } void @@ -104,7 +104,24 @@ imm8(Op *op, Node **args) memcpy(buf, op->bytes, n-1); buf[n-1] = par2->sym->value; - emit(cursec, buf, n); + emit(buf, n); +} + +void +r_imm16(Op *op, Node **args) +{ + Node *par1, *par2; + unsigned char buf[3]; + unsigned val; + int n = op->size; + + par2 = args[1]; + + memcpy(buf, op->bytes, n-2); + val = par2->sym->value; + buf[n-1] = val >> 8; + buf[n-2] = val; + emit(buf, n); } void @@ -119,7 +136,7 @@ r8_r8(Op *op, Node **args) memcpy(buf, op->bytes, n); buf[n-1] |= reg2int(par1->sym->argtype) << 3 | reg2int(par2->sym->argtype); - emit(cursec, buf, n); + emit(buf, n); } void @@ -134,7 +151,7 @@ xx_r8_2(Op *op, Node **args) memcpy(buf, op->bytes, n); buf[n-1] |= reg2int(par2->sym->argtype); - emit(cursec, buf, n); + emit(buf, n); } void @@ -149,7 +166,7 @@ r8_xx_2(Op *op, Node **args) memcpy(buf, op->bytes, n); buf[n-1] |= reg2int(par2->sym->argtype) << 3; - emit(cursec, buf, n); + emit(buf, n); } void @@ -164,5 +181,5 @@ r8_xx_1(Op *op, Node **args) memcpy(buf, op->bytes, n); buf[n-1] |= reg2int(par1->sym->argtype) << 3; - emit(cursec, buf, n); + emit(buf, n); } diff --git a/as/target/x80/x80.dat b/as/target/x80/x80.dat @@ -67,6 +67,8 @@ LD reg_q,reg_q 2 0xfd,0x40 r8_r8 Z80,R800 LD indir_HL,reg_r 1 0x70 xx_r8_2 Z80,R800,GB80 LD reg_r,indir_HL 1 0x46 r8_xx_1 Z80,R800,GB80 +LD HL,imm16 3 0x21 r_imm16 Z80,R800,GB80 + ADD regA,reg_r 1 0x80 xx_r8_2 Z80,R800,GB80 ADD regA,reg_p 2 0xdd,0x80 xx_r8_2 Z80,R800 ADD regA,reg_q 2 0xfd,0x80 xx_r8_2 Z80,R800 diff --git a/as/target/z80/proc.c b/as/target/z80/proc.c @@ -93,6 +93,10 @@ match(Op *op, Node **args) if (!qclass(np->sym->argtype)) return 0; break; + case AREG_HL: + if (np->op != AREG && np->sym->argtype != AREG_HL) + return 0; + return 1; case AIMM8: case AIMM16: case AIMM32: