shithub: scc

Download patch

ref: 3a1fdd58d1df1f03f38e29a7f578cb22b2728efc
parent: c2677b83f943373787dd200c425fc2cbb90a49c0
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Sat May 19 16:02:59 EDT 2018

[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.

--- a/as/as.h
+++ b/as/as.h
@@ -41,9 +41,9 @@
 	ADIRECT,
 	AREG_OFF,
 	ASYM,
+	AOPT,
+	AREP,
 	AMAX,
-	AOPT = 64,
-	AREP = 128,
 };
 
 enum tokens {
--- a/as/gentbl.awk
+++ b/as/gentbl.awk
@@ -77,6 +77,12 @@
 	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 @@
 		}
 
 		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
--- a/as/target/x80/ins.c
+++ b/as/target/x80/ins.c
@@ -68,20 +68,26 @@
 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;
--- a/as/target/x86/ins.c
+++ b/as/target/x86/ins.c
@@ -180,20 +180,26 @@
 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: