ref: 3e2ddf390374b77222c3e8f966aabaf58c8a6ea6
parent: b89dac3b626de7901c14bfec3c2372c841496810
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Thu Dec 14 10:27:25 EST 2017
[as] Add ASYM argument type In some pseudo instructions we need an argument of symbol type, that is different to string (enclosed between "") or of an immediate, which can be a symbol or a numeric value.
--- a/as/as.h
+++ b/as/as.h
@@ -37,6 +37,7 @@
AINDEX,
ADIRECT,
AREG_OFF,
+ ASYM,
AMAX,
AREP = 128
};
--- a/as/expr.c
+++ b/as/expr.c
@@ -356,7 +356,11 @@
case AIMM:
op = ADIRECT;
new_node:
- return node(op, np, NULL);
+ np = node(op, np, NULL);
+ np->addr = op;
+ break;
+ default:
+ abort();
}
return np;
}
--- a/as/target/gen.awk
+++ b/as/target/gen.awk
@@ -87,6 +87,8 @@
out = out "AINDER_HL"
} else if (match(a, /^HL/)) {
out = out "AREG_HL"
+ } else if (match(a, /^sym/)) {
+ out = out "ASYM"
} else {
print "wrong arg", a > "/dev/stderr"
exit 1
--- a/as/target/z80/proc.c
+++ b/as/target/z80/proc.c
@@ -66,36 +66,38 @@
np = *args++;
switch (arg & ~AREP) {
case AINDER_HL:
- if (np->op != AINDIR)
+ if (np->addr != AINDIR)
return 0;
if (np->left->sym->argtype != AREG_HL)
return 0;
break;
case AREG_A:
- if (np->op != AREG || np->sym->argtype != AREG_A)
+ if (np->addr != AREG || np->sym->argtype != AREG_A)
return 0;
break;
case AREG_RCLASS:
- if (np->op != AREG)
+ if (np->addr != AREG)
return 0;
if (!rclass(np->sym->argtype))
return 0;
break;
case AREG_PCLASS:
- if (np->op != AREG)
+ if (np->addr != AREG)
return 0;
if (!pclass(np->sym->argtype))
return 0;
break;
case AREG_QCLASS:
- if (np->op != AREG)
+ if (np->addr != AREG)
return 0;
if (!qclass(np->sym->argtype))
return 0;
break;
case AREG_HL:
- if (np->op != AREG && np->sym->argtype != AREG_HL)
+ if (np->addr != AREG)
return 0;
+ if (np->sym->argtype != AREG_HL)
+ return 0;
break;
case AIMM8:
case AIMM16:
@@ -105,6 +107,10 @@
return 0;
if (toobig(np, arg))
error("overflow in immediate operand");
+ break;
+ case ASYM:
+ if (np->op != ASYM)
+ return 0;
break;
default:
abort();