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:
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: