shithub: scc

Download patch

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: