ref: 2b760d39218681e0bd7ff9a73d008b4072c091c3
parent: e00bb1e5ac3291539ba6df03248290496edb9814
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Sun Dec 17 12:48:01 EST 2017
[as-z80] Add qq 16 bit load instructions These are mainly PUSH and POP operations.
--- a/as/target/gen.awk
+++ b/as/target/gen.awk
@@ -75,6 +75,10 @@
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/)) {
@@ -81,8 +85,6 @@
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/)) {
--- a/as/target/x80/ins.c
+++ b/as/target/x80/ins.c
@@ -72,6 +72,20 @@
}
}
+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)
{
@@ -194,6 +208,20 @@
memcpy(buf, op->bytes, n);
buf[n-1] |= reg2int(par1->sym->argtype) << 3;
+ emit(buf, n);
+}
+
+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);
}
--- a/as/target/x80/proc.h
+++ b/as/target/x80/proc.h
@@ -33,6 +33,7 @@
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 pclass(int reg);
extern int qclass(int reg);
extern int ddclass(int reg);
+extern int qqclass(int reg);
--- a/as/target/x80/x80.dat
+++ b/as/target/x80/x80.dat
@@ -75,6 +75,7 @@
# 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
@@ -105,6 +106,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
--- a/as/target/z80/proc.c
+++ b/as/target/z80/proc.c
@@ -93,6 +93,9 @@
case AREG_QCLASS:
class = qclass;
goto register_class;
+ case AREG_QQCLASS:
+ class = qqclass;
+ goto register_class;
case AREG_DDCLASS:
class = ddclass;
register_class: