ref: 231bd721e2aa5545540a189a9b2c6ceb14569155
parent: f80fa5e7c0dea2a1c512535dff394cebcda52d5c
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Wed Jan 5 12:40:41 EST 2022
cc2/qbe: Unify operands in rhs() Rhs() was obscure because it had an implicit depedency with the encoding of the different assembler instructions that was not obvious in the code. This patch removes it and use an explicit table composed of several subtables.
--- a/src/cmd/cc/cc2/target/qbe/cgen.c
+++ b/src/cmd/cc/cc2/target/qbe/cgen.c
@@ -7,69 +7,75 @@
#include "arch.h"
#include "../../cc2.h"
-static char opasmw[] = {
- [OADD] = ASADDW,
- [OSUB] = ASSUBW,
- [OMUL] = ASMULW,
- [OMOD] = ASMODW,
- [ODIV] = ASDIVW,
- [OSHL] = ASSHLW,
- [OSHR] = ASSHRW,
- [OLT] = ASLTW,
- [OGT] = ASGTW,
- [OLE] = ASLEW,
- [OGE] = ASGEW,
- [OEQ] = ASEQW,
- [ONE] = ASNEW,
- [OBAND] = ASBANDW,
- [OBOR] = ASBORW,
- [OBXOR] = ASBXORW,
+static char opasmw[][2] = {
+ [OADD] = {ASADDW, ASADDW},
+ [OSUB] = {ASSUBW, ASSUBW},
+ [OMUL] = {ASMULW, ASMULW},
+ [OMOD] = {ASMODW, ASUMODW},
+ [ODIV] = {ASDIVW, ASUDIVW},
+ [OSHL] = {ASSHLW, ASSHLW},
+ [OSHR] = {ASSHRW, ASUSHRW},
+ [OLT] = {ASLTW, ASULTW},
+ [OGT] = {ASGTW, ASUGTW},
+ [OLE] = {ASLEW, ASULEW},
+ [OGE] = {ASGEW, ASUGEW},
+ [OEQ] = {ASEQW, ASEQW},
+ [ONE] = {ASNEW, ASNEW},
+ [OBAND] = {ASBANDW, ASBANDW},
+ [OBOR] = {ASBORW, ASBORW},
+ [OBXOR] = {ASBXORW, ASBXORW},
};
-static char opasml[] = {
- [OADD] = ASADDL,
- [OSUB] = ASSUBL,
- [OMUL] = ASMULL,
- [OMOD] = ASMODL,
- [ODIV] = ASDIVL,
- [OSHL] = ASSHLL,
- [OSHR] = ASSHRL,
- [OLT] = ASLTL,
- [OGT] = ASGTL,
- [OLE] = ASLEL,
- [OGE] = ASGEL,
- [OEQ] = ASEQL,
- [ONE] = ASNEL,
- [OBAND] = ASBANDL,
- [OBOR] = ASBORL,
- [OBXOR] = ASBXORL,
+static char opasml[][2] = {
+ [OADD] = {ASADDL, ASADDL},
+ [OSUB] = {ASSUBL, ASSUBL},
+ [OMUL] = {ASMULL, ASMULL},
+ [OMOD] = {ASMODL, ASUMODL},
+ [ODIV] = {ASDIVL, ASUDIVL},
+ [OSHL] = {ASSHLL, ASSHLL},
+ [OSHR] = {ASSHRL, ASUSHRL},
+ [OLT] = {ASLTL, ASULTL},
+ [OGT] = {ASGTL, ASUGTL},
+ [OLE] = {ASLEL, ASULEL},
+ [OGE] = {ASGEL, ASUGEL},
+ [OEQ] = {ASEQL, ASEQL},
+ [ONE] = {ASNEL, ASNEL},
+ [OBAND] = {ASBANDL, ASBANDL},
+ [OBOR] = {ASBORL, ASBORL},
+ [OBXOR] = {ASBXORL, ASBXORL},
};
-static char opasms[] = {
- [OADD] = ASADDS,
- [OSUB] = ASSUBS,
- [OMUL] = ASMULS,
- [ODIV] = ASDIVS,
- [OLT] = ASLTS,
- [OGT] = ASGTS,
- [OLE] = ASLES,
- [OGE] = ASGES,
- [OEQ] = ASEQS,
- [ONE] = ASNES,
+static char opasms[][2] = {
+ [OADD] = {ASADDS, ASADDS},
+ [OSUB] = {ASSUBS, ASSUBS},
+ [OMUL] = {ASMULS, ASMULS},
+ [ODIV] = {ASDIVS, ASDIVS},
+ [OLT] = {ASLTS, ASLTS},
+ [OGT] = {ASGTS, ASGTS},
+ [OLE] = {ASLES, ASLES},
+ [OGE] = {ASGES, ASGES},
+ [OEQ] = {ASEQS, ASEQS},
+ [ONE] = {ASNES, ASNES},
};
-static char opasmd[] = {
- [OADD] = ASADDD,
- [OSUB] = ASSUBD,
- [OMUL] = ASMULD,
- [ODIV] = ASDIVD,
- [OLT] = ASLTD,
- [OGT] = ASGTD,
- [OLE] = ASLED,
- [OGE] = ASGED,
- [OEQ] = ASEQD,
- [ONE] = ASNED,
+
+static char opasmd[][2] = {
+ [OADD] = {ASADDD, ASADDD},
+ [OSUB] = {ASSUBD, ASSUBD},
+ [OMUL] = {ASMULD, ASMULD},
+ [ODIV] = {ASDIVD, ASDIVD},
+ [OLT] = {ASLTD, ASLTD},
+ [OGT] = {ASGTD, ASGTD},
+ [OLE] = {ASLED, ASLED},
+ [OGE] = {ASGED, ASGED},
+ [OEQ] = {ASEQD, ASEQD},
+ [ONE] = {ASNED, ASNED},
};
+static char (*opbin[][2])[2] = {
+ {opasmw, opasml},
+ {opasms, opasmd},
+};
+
extern Type int32type, uint32type, ptrtype;
/*
@@ -559,8 +565,7 @@
Node *tmp, aux1, aux2;
Node *phi, *l = np->left, *r = np->right;
Type *tp;
- int off, op;
- char *tbl;
+ int sign, size, isfloat, op;
Symbol *true, *false;
tp = &np->type;
@@ -600,6 +605,10 @@
setlabel(phi->u.sym);
return tmp;
case OMOD:
+ case OSHL:
+ case OBAND:
+ case OBOR:
+ case OBXOR:
case OSHR:
assert(tp->flags & INTF);
case ODIV:
@@ -607,24 +616,18 @@
case OGT:
case OLE:
case OGE:
- /*
- * unsigned version of operations are always +1 the
- * signed version
- */
- off = (tp->flags & SIGNF) == 0;
- goto binary;
- case OSHL:
- case OBAND:
- case OBOR:
- case OBXOR:
- assert(tp->flags & INTF);
case OADD:
case OSUB:
case OMUL:
case OEQ:
case ONE:
- off = 0;
- binary:
+ assert(tp->size == 4 || tp->size == 8);
+
+ sign = (tp->flags & SIGNF) == 0;
+ size = tp->size == 8;
+ isfloat = (tp->flags & FLOATF) != 0;
+ op = opbin[isfloat][size][np->op][sign];
+
if (l->complex >= r->complex) {
l = rhs(l);
r = rhs(r);
@@ -633,17 +636,6 @@
l = rhs(l);
}
- switch (tp->size) {
- case 4:
- tbl = (tp->flags & FLOATF) ? opasms : opasmw;
- break;
- case 8:
- tbl = (tp->flags & FLOATF) ? opasmd : opasml;
- break;
- default:
- abort();
- }
- op = tbl[np->op] + off;
tmp = tmpnode(tp);
code(op, tmp, l, r);
return tmp;