scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | README | LICENSE

commit 64c517abb155aa64a3f5267636cdb0156045999b
parent f01ce7cafd22de4ac8a66b2ad16328926e8ceecb
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Mon, 18 Dec 2017 08:28:00 +0000

[as-z80] Add missed exchange instructions

Diffstat:
Mas/target/gen.awk | 12++++++++++--
Mas/target/x80/proc.h | 1+
Mas/target/x80/x80.dat | 7+++++++
Mas/target/z80/proc.c | 18+++++++++++++++---
4 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/as/target/gen.awk b/as/target/gen.awk @@ -95,22 +95,30 @@ function str2args(s, args, i, out, n) out = out "AREG_RCLASS" } else if (match(a, /^R/)) { out = out "AREG_R" - } else if (match(a, /^A/)) { - out = out "AREG_A" } else if (match(a, /^\(DE\)/)) { out = out "AINDER_DE" } else if (match(a, /^\(BC\)/)) { out = out "AINDER_BC" } else if (match(a, /^\(HL\)/)) { out = out "AINDER_HL" + } else if (match(a, /^\(SP\)/)) { + out = out "AINDER_SP" } else if (match(a, /^SP/)) { out = out "AREG_SP" } else if (match(a, /^HL/)) { out = out "AREG_HL" + } else if (match(a, /^DE/)) { + out = out "AREG_DE" } else if (match(a, /^IX/)) { out = out "AREG_IX" } else if (match(a, /^IY/)) { out = out "AREG_IY" + } else if (match(a, /^AF'/)) { + out = out "AREG_AF_" + } else if (match(a, /^AF/)) { + out = out "AREG_AF" + } else if (match(a, /^A/)) { + out = out "AREG_A" } else if (match(a, /^\(n\)/)) { out = out "ADIRECT" } else if (match(a, /^I/)) { diff --git a/as/target/x80/proc.h b/as/target/x80/proc.h @@ -43,6 +43,7 @@ enum args { AINDER_HL, /* (HL) */ AINDER_DE, /* (DE) */ AINDER_BC, /* (BC) */ + AINDER_SP, /* (SP) */ }; extern int rclass(int reg); diff --git a/as/target/x80/x80.dat b/as/target/x80/x80.dat @@ -224,11 +224,18 @@ EI none 1 0xfb noargs Z80,R800,GB80 IM imm8 2 0xed im Z80,R800 # Exchange, block transfer and search groups +EX DE,HL 1 0xeb noargs Z80,R800 +EX AF,AF' 1 0x08 noargs Z80,R800 EXX none 1 0xd9 noargs Z80,R800 +EX (SP),HL 1 0xe3 noargs Z80,R800 +EX (SP),IX 2 0xdd,0xe3 noargs Z80,R800 +EX (SP),IY 2 0xfd,0xe3 noargs Z80,R800 + LDI none 2 0xed,0xa0 noargs Z80,R800 LDIR none 2 0xed,0xb0 noargs Z80,R800 LDD none 2 0xed,0xa8 noargs Z80,R800 LDDR none 2 0xed,0xb8 noargs Z80,R800 + CPI none 2 0xed,0xa1 noargs Z80,R800 CPIR none 2 0xed,0xb1 noargs Z80,R800 CPD none 2 0xed,0xa9 noargs Z80,R800 diff --git a/as/target/z80/proc.c b/as/target/z80/proc.c @@ -71,16 +71,28 @@ match(Op *op, Node **args) arg &= ~(AREP|AOPT); switch (arg) { case AINDER_HL: + arg = AREG_HL; + goto indirect; + case AINDER_DE: + arg = AREG_DE; + goto indirect; + case AINDER_BC: + arg = AREG_BC; + goto indirect; + case AINDER_SP: + arg = AREG_SP; + indirect: if (np->addr != AINDIR) return 0; - if (np->left->sym->argtype != AREG_HL) - return 0; - break; + np = np->left; case AREG_A: case AREG_HL: + case AREG_DE: case AREG_IY: case AREG_IX: case AREG_SP: + case AREG_AF: + case AREG_AF_: if (np->addr != AREG || np->sym->argtype != arg) return 0; break;