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