scc

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

commit 9d32ef80ba084bba1a97f81f5b2859388716ab7b
parent cb8cc84adef24f807f3c9ce4480329344c1aa474
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Sat, 19 May 2018 20:02:59 +0100

[as] Don't use bitfields for AOPT and AREP

Using 1 bit for AOPT and other bit for AREP reduce the number of
addressing modes to only 64. This number is to small and it is
better to use pseudo addressing modes for them.

Diffstat:
Mas/as.h | 4++--
Mas/gentbl.awk | 14+++++++++-----
Mas/target/x80/ins.c | 14++++++++++----
Mas/target/x86/ins.c | 14++++++++++----
4 files changed, 31 insertions(+), 15 deletions(-)

diff --git a/as/as.h b/as/as.h @@ -41,9 +41,9 @@ enum common_args { ADIRECT, AREG_OFF, ASYM, + AOPT, + AREP, AMAX, - AOPT = 64, - AREP = 128, }; enum tokens { diff --git a/as/gentbl.awk b/as/gentbl.awk @@ -77,6 +77,12 @@ function str2args(s, args, i, j, out, n, found) for (i = 1; i <= n; i++) { a = args[i] found = 0 + + if (a ~ /\?$/) + out = out "AOPT ," + else if (a ~ /\+$/) + out = out "AREP ," + for (j = 1; j <= nregs; j++) { if (match(a, "^" regex[j])) { out = out value[j] @@ -92,11 +98,9 @@ function str2args(s, args, i, j, out, n, found) } a = substr(a, RLENGTH+1) - if (a ~ /^\+$/) { - return out "|AREP" - } else if (a ~ /^\?$/) { - return out "|AOPT" - } else if (a != "") { + sub(/\?$/, "", a) + sub(/\+$/, "", a) + if (a != "") { print FILENAME ":" NR ":" \ $0 ": trailing chars: ", a > "/dev/stderr" exit 1 diff --git a/as/target/x80/ins.c b/as/target/x80/ins.c @@ -68,20 +68,26 @@ int match(Op *op, Node **args) { unsigned char *p; - int arg, class; + int arg, class, rep, opt; Node *np; if (!op->args) return args == NULL; + opt = rep = 0; for (p = op->args; arg = *p; ++p) { - if (arg & AREP) + if (rep) --p; if ((np = *args++) == NULL) - return (arg & (AREP|AOPT)) != 0; + return (rep|opt) != 0; - arg &= ~(AREP|AOPT); switch (arg) { + case AOPT: + opt = 1; + break; + case AREP: + rep = 1; + break; case AINDER_C: arg = AREG_C; goto indirect; diff --git a/as/target/x86/ins.c b/as/target/x86/ins.c @@ -180,20 +180,26 @@ int match(Op *op, Node **args) { unsigned char *p; - int arg, class; + int arg, class, rep, opt; Node *np; if (!op->args) return args == NULL; + opt = rep = 0; for (p = op->args; arg = *p; ++p) { - if (arg & AREP) + if (rep) --p; if ((np = *args++) == NULL) - return (arg & (AREP|AOPT)) != 0; + return (rep|opt) != 0; - arg &= ~(AREP|AOPT); switch (arg) { + case AOPT: + opt = 1; + break; + case AREP: + rep = 1; + break; case AREG_R8CLASS: class = R8CLASS; check_class: