scc

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

commit 0dc11ffd0af669fcb98ba8412d2a089d410314d5
parent f5a2ddedc976d715bd43a8667c35882c12cf3b9c
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Sun, 17 Dec 2017 17:48:01 +0100

[as-z80] Add qq 16 bit load instructions

These are mainly PUSH and POP operations.

Diffstat:
Mas/target/gen.awk | 6++++--
Mas/target/x80/ins.c | 28++++++++++++++++++++++++++++
Mas/target/x80/proc.h | 2++
Mas/target/x80/x80.dat | 8++++++++
Mas/target/z80/proc.c | 3+++
5 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/as/target/gen.awk b/as/target/gen.awk @@ -75,14 +75,16 @@ function str2args(s, args, i, out, n) out = out "AIMM32" } else if (match(a, /^imm64/)) { out = "AIMM64" + } else if (match(a, /^reg_dd/)) { + out = out "AREG_DDCLASS" + } else if (match(a, /^reg_qq/)) { + out = out "AREG_QQCLASS" } else if (match(a, /^reg_p/)) { out = out "AREG_PCLASS" } else if (match(a, /^reg_q/)) { out = out "AREG_QCLASS" } else if (match(a, /^reg_r/)) { out = out "AREG_RCLASS" - } else if (match(a, /^reg_dd/)) { - out = out "AREG_DDCLASS" } else if (match(a, /^regA/)) { out = out "AREG_A" } else if (match(a, /^indir_HL/)) { diff --git a/as/target/x80/ins.c b/as/target/x80/ins.c @@ -72,6 +72,20 @@ ddclass(int reg) } } +int +qqclass(int reg) +{ + switch (reg) { + case AREG_BC: + case AREG_DE: + case AREG_HL: + case AREG_AF: + return 1; + default: + return 0; + } +} + static int reg2int(int reg) { @@ -198,6 +212,20 @@ r8_xx(Op *op, Node **args) } void +r16(Op *op, Node **args) +{ + Node *par1, *par2; + unsigned char buf[4]; + int n = op->size; + + par1 = args[0]; + + memcpy(buf, op->bytes, n-1); + buf[n-1] |= reg2int(par1->sym->argtype) << 4; + emit(buf, n); +} + +void r16_imm16(Op *op, Node **args) { Node *par1, *par2; diff --git a/as/target/x80/proc.h b/as/target/x80/proc.h @@ -33,6 +33,7 @@ enum args { AREG_PCLASS, /* register class for B, C, D, E, IXH, IXL and A */ AREG_QCLASS, /* register class for B, C, D, E, IYH, IYL and A */ AREG_DDCLASS, /* register class for BC, DE, HL and SP */ + AREG_QQCLASS, /* register class for BC, DE, HL and AF */ AINDER_HL, /* (HL) */ }; @@ -41,3 +42,4 @@ extern int rclass(int reg); extern int pclass(int reg); extern int qclass(int reg); extern int ddclass(int reg); +extern int qqclass(int reg); diff --git a/as/target/x80/x80.dat b/as/target/x80/x80.dat @@ -75,6 +75,7 @@ OTDR none 2 0xed,0xbb noargs Z80,R800 # q is any register from B, C, D, E, IYL, IYH, A # r is any register from B, C, D, E, L, H, A # dd is any register from BC, DE, HL, SP +# qq is any register from BC, DE, HL, AF LD reg_r,imm8 2 0x06 r8_imm8 Z80,R800,GB80 LD reg_p,imm8 3 0xdd,0x06 r8_imm8 Z80,R800 @@ -106,6 +107,13 @@ LD regSP,regHL 1 0xf9 noargs Z80,R800,GB80 LD regSP,regIX 2 0xdd,0xf9 noargs Z80,R800 LD regSP,regIY 2 0xfd,0xf9 noargs Z80,R800 +PUSH reg_qq 1 0xc5 r16 Z80,R800,GB80 +PUSH regIX 2 0xdd,0xe5 noargs Z80,R800 +PUSH regIY 2 0xdd,0xe5 noargs Z80,R800 +POP reg_qq 1 0xc1 r16 Z80,R800,GB80 +POP regIX 2 0xdd,0xe1 noargs Z80,R800 +POP regIY 2 0xfd,0xe1 noargs Z80,R800 + ADD regA,reg_r 1 0x80 xx_r8 Z80,R800,GB80 ADD regA,reg_p 2 0xdd,0x80 xx_r8 Z80,R800 ADD regA,reg_q 2 0xfd,0x80 xx_r8 Z80,R800 diff --git a/as/target/z80/proc.c b/as/target/z80/proc.c @@ -93,6 +93,9 @@ match(Op *op, Node **args) case AREG_QCLASS: class = qclass; goto register_class; + case AREG_QQCLASS: + class = qqclass; + goto register_class; case AREG_DDCLASS: class = ddclass; register_class: