shithub: scc

Download patch

ref: 1f95241f529adc736e20be2919696a8dab11a2e7
parent: d040c845b7be94d9d2882f7880999880c5d4b092
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Fri Dec 29 10:48:03 EST 2017

[as-z80] Add relative jumps

These jumps are relative to the pc. These instructions
need further test, because the current tests are very
basic.

--- a/as/target/x80/ins.c
+++ b/as/target/x80/ins.c
@@ -22,7 +22,7 @@
 
 	switch (np->sym->value) {
 	case AREG_C:
-		return RCLASS | PCLASS | QCLASS | CCCLASS;
+		return RCLASS | PCLASS | QCLASS | CCCLASS | SSCLASS;
 	case AREG_A:
 	case AREG_B:
 	case AREG_D:
@@ -50,14 +50,15 @@
 		return PPCLASS;
 	case AREG_IY:
 		return RRCLASS;
-	case AREG_NZ:
-	case AREG_Z:
-	case AREG_NC:
 	case AREG_PO:
 	case AREG_PE:
 	case AREG_P:
 	case AREG_M:
 		return CCCLASS;
+	case AREG_NZ:
+	case AREG_Z:
+	case AREG_NC:
+		return CCCLASS | SSCLASS;
 	default:
 		return 0;
 	}
@@ -91,7 +92,7 @@
 }
 
 static int
-flag2int(Node *np)
+cc2int(Node *np)
 {
 	switch (np->sym->value) {
 	case AREG_NZ:  return 0;
@@ -106,6 +107,18 @@
 	}
 }
 
+static int
+ss2int(Node *np)
+{
+	switch (np->sym->value) {
+	case AREG_NZ:  return 4;
+	case AREG_Z:   return 5;
+	case AREG_NC:  return 6;
+	case AREG_C:   return 7;
+	default:       abort();
+	}
+}
+
 void
 dir(Op *op, Node **args)
 {
@@ -338,12 +351,13 @@
 }
 
 void
-branch(Op *op, Node **args)
+branch(int relative, Op *op, Node **args)
 {
 	unsigned char buf[4];
 	Node *flag, *imm;
 	int n = op->size, i = n;
 	unsigned val;
+	int (*fun)(Node *);
 
 	flag = imm = NULL;
 	if (args[0]->addr == AREG) {
@@ -356,13 +370,32 @@
 
 	if (imm) {
 		val = imm->sym->value;
-		buf[--i] = val >> 8;
+		if (!relative) {
+			fun = cc2int;
+			buf[--i] = val >> 8;
+		} else {
+			fun = ss2int;
+			val -= cursec->curpc - 2;
+		}
 		buf[--i] = val;
+
+		if (flag)
+			buf[--i] |= (*fun)(flag) << 3;
 	}
-	if (flag)
-		buf[--i] |= flag2int(flag) << 3;
 
 	emit(buf, n);
+}
+
+void
+jp(Op *op, Node **args)
+{
+	branch(0, op, args);
+}
+
+void
+jr(Op *op, Node **args)
+{
+	branch(1, op, args);
 }
 
 void
--- a/as/target/x80/proc.h
+++ b/as/target/x80/proc.h
@@ -44,8 +44,8 @@
 	AREG_QQCLASS, /* register class for BC, DE, HL and AF */
 	AREG_PPCLASS, /* register class for BC, DE, IX and SP */
 	AREG_RRCLASS, /* register class for BC, DE, IY and SP */
-	AREG_SSCLASS, /* flag class for NZ, Z, NC, C, PO, PE, P, M */
-	AREG_CCCLASS, /* flag class for C, NC, Z, NZ */
+	AREG_SSCLASS, /* flag class for C, NC, Z, NZ */
+	AREG_CCCLASS, /* flag class for NZ, Z, NC, C, PO, PE, P, M */
 
 	AINDEX_IX,    /* (IX+d) */
 	AINDEX_IY,    /* (IX+d) */
@@ -72,6 +72,7 @@
 	PPCLASS = 1 << 5,
 	RRCLASS = 1 << 6,
 	CCCLASS = 1 << 7,
+	SSCLASS = 1 << 8,
 };
 
 extern int getclass(Node *np);
--- a/as/target/x80/x80.dat
+++ b/as/target/x80/x80.dat
@@ -1,4 +1,4 @@
-# Tab 16, tabs 16, :set ts=16
+# Tab 18, tabs 16, :set ts=18
 # op	args	size	bytes	format	cpu
 .SECTION	sym,string?	0	none	section	Z80,R800,GB80
 .TEXT	none	0	none	text	Z80,R800,GB80
@@ -332,20 +332,20 @@
 OTDR	none	2	0xed,0xbb	noargs	Z80,R800
 
 # Jump group
-JP	imm16	3	0xc3	branch	Z80,R800,GB80
-JP	cc,imm16	3	0xc2	branch	Z80,R800,GB80
-JR	imm8	2	0x18	branch	Z80,R800,GB80
-JR	ss,imm8	2	0x00	branch	Z80,R800,GB80
-JP	(HL)	1	0xe9	branch	Z80,R800,GB80
-JP	(IX)	2	0xdd,0xe9	branch	Z80,R800
-JP	(IY)	2	0xfd,0xe9	branch	Z80,R800
-DJNZ	imm8	2	0x10	branch	Z80,R800,GB80
+JP	imm16	3	0xc3	jp	Z80,R800,GB80
+JP	cc,imm16	3	0xc2	jp	Z80,R800,GB80
+JR	imm16	2	0x18	jr	Z80,R800,GB80
+JR	ss,imm16	2	0x00	jr	Z80,R800,GB80
+JP	(HL)	1	0xe9	jp	Z80,R800,GB80
+JP	(IX)	2	0xdd,0xe9	jp	Z80,R800
+JP	(IY)	2	0xfd,0xe9	jp	Z80,R800
+DJNZ	imm16	2	0x10	jr	Z80,R800,GB80
 
 # Call and return group
-CALL	imm16	3	0xcd	branch	Z80,R800,GB80
-CALL	cc,imm16	3	0xc4	branch	Z80,R800
+CALL	imm16	3	0xcd	jp	Z80,R800,GB80
+CALL	cc,imm16	3	0xc4	jp	Z80,R800
 RET	none	1	0xc9	noargs	Z80,R800,GB80
-RET	cc	1	0xc0	branch	Z80,R800
+RET	cc	1	0xc0	jp	Z80,R800
 RETI	none	2	0xed,0x4d	noargs	Z80,R800
 RETN	none	2	0xed,0x45	noargs	Z80,R800
 RST	rst	1	0xc7	rst	Z80,R800,GB80
--- a/as/target/z80/proc.c
+++ b/as/target/z80/proc.c
@@ -138,6 +138,9 @@
 		case AREG_CCCLASS:
 			class = CCCLASS;
 			goto check_class;
+		case AREG_SSCLASS:
+			class = SSCLASS;
+			goto check_class;
 		case AREG_DDCLASS:
 			class = DDCLASS;
 		check_class:
--- a/as/target/z80/test.s
+++ b/as/target/z80/test.s
@@ -14,7 +14,7 @@
 	DEC	%C	/ 0D
 	LD	%C,64	/ 0E 40
 	RRCA		/ 0F
-/10 n	DJNZ PC + n
+L1:	DJNZ	L1	/ 10 02
 	LD	%DE,32	/ 11 20 00
 	LD	(%DE),%A	/ 12
 	INC	%DE	/ 13
@@ -22,7 +22,7 @@
 	DEC	%D	/ 15
 	LD	%D,64	/ 16 40
 	RLA		/ 17
-/18 n	JR PC + n
+L2:	JR	L2	/ 18 02
 	ADD	%HL,%DE	/ 19
 	LD	%A,(%DE)	/ 1A
 	DEC	%DE	/ 1B
@@ -30,7 +30,7 @@
 	DEC	%E	/ 1D
 	LD	%E,64	/ 1E 40
 	RRA		/ 1F
-/20 n	JR NZ, PC + n
+L3:	JR	%NZ,L3	/ 20 02
 	LD	%HL,32	/ 21 20 00
 	LD	(32768),%HL	/ 22 00 80
 	INC	%HL	/ 23
@@ -38,7 +38,7 @@
 	DEC	%H	/ 25
 	LD	%H,64	/ 26 40
 	DAA		/ 27
-/28 n	JR Z, PC + n
+L4:	JR	%Z,L4	/ 28 02
 	ADD	%HL,%HL	/ 29
 	LD	%HL, (16384)	/ 2A 00 40
 	DEC	%HL	/ 2B
@@ -46,7 +46,7 @@
 	DEC	%L	/ 2D
 	LD	%L,32	/ 2E 20
 	CPL		/ 2F
-/30 n	JR NC, PC + n
+L5:	JR	%NC,L5	/ 30 02
 	LD	%SP,64	/ 31 40 00
 	LD	(32768),%A	/ 32 00 80
 	INC	%SP	/ 33
@@ -54,7 +54,7 @@
 	DEC	(%HL)	/ 35
 	LD	(%HL),32	/ 36 20
 	SCF		/ 37
-/38 n	JR C, PC + n
+L6:	JR	%C,L6	/ 38 02
 	ADD	%HL,%SP	/ 39
 	LD	%A,(16384)	/ 3A 00 40
 	DEC	%SP	/ 3B