scc

Simple C99 Compiler
Log | Files | Refs | README | LICENSE

commit a5ecfeb71efdc36674c5197b87289db4ec41135e
parent 06406a58ad2731e634939b4abd2e5d1bf5905245
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Thu, 21 Apr 2016 17:14:10 +0200

[cc2-qbe] Add support for operations in long and for floats

This commits add 4 tables, one for w, one for l, one for s
and one for d. We need these tables because we don't have
the semantic information about the types in the address.

Diffstat:
cc2/arch/qbe/arch.h | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
cc2/arch/qbe/cgen.c | 115+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
cc2/arch/qbe/code.c | 76+++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
3 files changed, 220 insertions(+), 60 deletions(-)

diff --git a/cc2/arch/qbe/arch.h b/cc2/arch/qbe/arch.h @@ -6,24 +6,77 @@ enum asmop { ASLOAD, - ASADD, - ASSUB, - ASMUL, - ASMOD, - ASDIV, - ASSHL, - ASSHR, - ASLT, - ASGT, - ASLE, - ASGE, - ASEQ, + ASASSIG, + + ASADDW, + ASSUBW, + ASMULW, + ASMODW, + ASDIVW, + ASSHLW, + ASSHRW, + ASLTW, + ASGTW, + ASLEW, + ASGEW, + ASEQW, + ASNEW, + ASBANDW, + ASBORW, + ASBXORW, + ASCPLW, + + ASADDL, + ASSUBL, + ASMULL, + ASMODL, + ASDIVL, + ASSHLL, + ASSHRL, + ASLTL, + ASGTL, + ASLEL, + ASGEL, ASEQL, - ASNE, ASNEL, - ASBAND, - ASBOR, - ASBXOR, - ASCPL, - ASASSIG + ASBANDL, + ASBORL, + ASBXORL, + ASCPLL, + + ASADDS, + ASSUBS, + ASMULS, + ASMODS, + ASDIVS, + ASSHLS, + ASSHRS, + ASLTS, + ASGTS, + ASLES, + ASGES, + ASEQS, + ASNES, + ASBANDS, + ASBORS, + ASBXORS, + ASCPLS, + + ASADDD, + ASSUBD, + ASMULD, + ASMODD, + ASDIVD, + ASSHLD, + ASSHRD, + ASLTD, + ASGTD, + ASLED, + ASGED, + ASEQD, + ASNED, + ASBANDD, + ASBORD, + ASBXORD, + ASCPLD, }; diff --git a/cc2/arch/qbe/cgen.c b/cc2/arch/qbe/cgen.c @@ -9,24 +9,84 @@ enum sflags { ISCONS = 2 }; -static char opasm[] = { - [OADD] = ASADD, - [OSUB] = ASSUB, - [OMUL] = ASMUL, - [OMOD] = ASMOD, - [ODIV] = ASDIV, - [OSHL] = ASSHL, - [OSHR] = ASSHR, - [OLT] = ASLT, - [OGT] = ASGT, - [OLE] = ASLE, - [OGE] = ASGE, - [OEQ] = ASEQ, - [ONE] = ASNE, - [OBAND] = ASBAND, - [OBOR] = ASBOR, - [OBXOR] = ASBXOR, - [OCPL] = ASCPL +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, + [OCPL] = ASCPLW +}; + +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, + [OCPL] = ASCPLL +}; + +static char opasms[] = { + [OADD] = ASADDS, + [OSUB] = ASSUBS, + [OMUL] = ASMULS, + [OMOD] = ASMODS, + [ODIV] = ASDIVS, + [OSHL] = ASSHLS, + [OSHR] = ASSHRS, + [OLT] = ASLTS, + [OGT] = ASGTS, + [OLE] = ASLES, + [OGE] = ASGES, + [OEQ] = ASEQS, + [ONE] = ASNES, + [OBAND] = ASBANDS, + [OBOR] = ASBORS, + [OBXOR] = ASBXORS, + [OCPL] = ASCPLS +}; + +static char opasmd[] = { + [OADD] = ASADDD, + [OSUB] = ASSUBD, + [OMUL] = ASMULD, + [OMOD] = ASMODD, + [ODIV] = ASDIVD, + [OSHL] = ASSHLD, + [OSHR] = ASSHRD, + [OLT] = ASLTD, + [OGT] = ASGTD, + [OLE] = ASLED, + [OGE] = ASGED, + [OEQ] = ASEQD, + [ONE] = ASNED, + [OBAND] = ASBANDD, + [OBOR] = ASBORD, + [OBXOR] = ASBXORD, + [OCPL] = ASCPLD }; static Node * @@ -63,6 +123,7 @@ cgen(Node *np) Symbol *sym; Type *tp; int op; + char *tbl; if (!np) return NULL; @@ -81,10 +142,6 @@ cgen(Node *np) case OMEM: case OAUTO: return np; - case OEQ: - case ONE: - op = opasm[np->op] + (tp->size == 8); - goto binary; case OADD: case OSUB: case OMUL: @@ -100,7 +157,19 @@ cgen(Node *np) case OBOR: case OBXOR: case OCPL: - op = opasm[np->op]; + case OEQ: + case ONE: + switch (tp->size) { + case 4: + tbl = (tp->flags & INTF) ? opasmw : opasms; + break; + case 8: + tbl = (tp->flags & INTF) ? opasml : opasmd; + break; + default: + abort(); + } + op = tbl[np->op]; binary: if ((l->flags & (ISTMP|ISCONS)) == 0) l = np->left = load(l); diff --git a/cc2/arch/qbe/code.c b/cc2/arch/qbe/code.c @@ -16,26 +16,64 @@ static struct opdata { char *txt; char letter; } optbl [] = { - [ASADD] = {.fun = binary, .txt = "add", .letter = 'w'}, - [ASSUB] = {.fun = binary, .txt = "sub", .letter = 'w'}, - [ASMUL] = {.fun = binary, .txt = "mul", .letter = 'w'}, - [ASMOD] = {.fun = binary, .txt = "rem", .letter = 'w'}, - [ASDIV] = {.fun = binary, .txt = "div", .letter = 'w'}, - [ASSHL] = {.fun = binary, .txt = "shl", .letter = 'w'}, - [ASSHR] = {.fun = binary, .txt = "shr", .letter = 'w'}, - [ASLT] = {.fun = binary, .txt = "clt", .letter = 'w'}, - [ASGT] = {.fun = binary, .txt = "cgt", .letter = 'w'}, - [ASLE] = {.fun = binary, .txt = "cle", .letter = 'w'}, - [ASGE] = {.fun = binary, .txt = "cge", .letter = 'w'}, - [ASEQ] = {.fun = binary, .txt = "ceqw", .letter = 'w'}, - [ASEQL] = {.fun = binary, .txt = "ceql", .letter = 'w'}, - [ASNE] = {.fun = binary, .txt = "cnew", .letter = 'w'}, - [ASNEL] = {.fun = binary, .txt = "cnel", .letter = 'w'}, - [ASBAND] = {.fun = binary, .txt = "and", .letter = 'w'}, - [ASBOR] = {.fun = binary, .txt = "or", .letter = 'w'}, - [ASBXOR] = {.fun = binary, .txt = "xor", .letter = 'w'}, [ASLOAD] = {.fun = load, .txt = "load", .letter = 'w'}, - [ASASSIG] = {.fun = store, .txt = "store", .letter = 'w'} + [ASASSIG] = {.fun = store, .txt = "store", .letter = 'w'}, + + [ASADDW] = {.fun = binary, .txt = "add", .letter = 'w'}, + [ASSUBW] = {.fun = binary, .txt = "sub", .letter = 'w'}, + [ASMULW] = {.fun = binary, .txt = "mul", .letter = 'w'}, + [ASMODW] = {.fun = binary, .txt = "rem", .letter = 'w'}, + [ASDIVW] = {.fun = binary, .txt = "div", .letter = 'w'}, + [ASSHLW] = {.fun = binary, .txt = "shl", .letter = 'w'}, + [ASSHRW] = {.fun = binary, .txt = "shr", .letter = 'w'}, + [ASLTW] = {.fun = binary, .txt = "cltw", .letter = 'w'}, + [ASGTW] = {.fun = binary, .txt = "cgtw", .letter = 'w'}, + [ASLEW] = {.fun = binary, .txt = "clew", .letter = 'w'}, + [ASGEW] = {.fun = binary, .txt = "cgew", .letter = 'w'}, + [ASEQW] = {.fun = binary, .txt = "ceqw", .letter = 'w'}, + [ASNEW] = {.fun = binary, .txt = "cnew", .letter = 'w'}, + [ASBANDW] = {.fun = binary, .txt = "and", .letter = 'w'}, + [ASBORW] = {.fun = binary, .txt = "or", .letter = 'w'}, + [ASBXORW] = {.fun = binary, .txt = "xor", .letter = 'w'}, + + [ASADDL] = {.fun = binary, .txt = "add", .letter = 'l'}, + [ASSUBL] = {.fun = binary, .txt = "sub", .letter = 'l'}, + [ASMULL] = {.fun = binary, .txt = "mul", .letter = 'l'}, + [ASMODL] = {.fun = binary, .txt = "rem", .letter = 'l'}, + [ASDIVL] = {.fun = binary, .txt = "div", .letter = 'l'}, + [ASSHLL] = {.fun = binary, .txt = "shl", .letter = 'l'}, + [ASSHRL] = {.fun = binary, .txt = "shr", .letter = 'l'}, + [ASLTL] = {.fun = binary, .txt = "cltl", .letter = 'w'}, + [ASGTL] = {.fun = binary, .txt = "cgtl", .letter = 'w'}, + [ASLEL] = {.fun = binary, .txt = "clel", .letter = 'w'}, + [ASGEL] = {.fun = binary, .txt = "cgel", .letter = 'w'}, + [ASEQL] = {.fun = binary, .txt = "ceql", .letter = 'w'}, + [ASNEL] = {.fun = binary, .txt = "cnel", .letter = 'w'}, + [ASBANDL] = {.fun = binary, .txt = "and", .letter = 'l'}, + [ASBORL] = {.fun = binary, .txt = "or", .letter = 'l'}, + [ASBXORL] = {.fun = binary, .txt = "xor", .letter = 'l'}, + + [ASADDS] = {.fun = binary, .txt = "add", .letter = 's'}, + [ASSUBS] = {.fun = binary, .txt = "sub", .letter = 's'}, + [ASMULS] = {.fun = binary, .txt = "mul", .letter = 's'}, + [ASDIVS] = {.fun = binary, .txt = "div", .letter = 's'}, + [ASLTS] = {.fun = binary, .txt = "clts", .letter = 'w'}, + [ASGTS] = {.fun = binary, .txt = "cgts", .letter = 'w'}, + [ASLES] = {.fun = binary, .txt = "cles", .letter = 'w'}, + [ASGES] = {.fun = binary, .txt = "cges", .letter = 'w'}, + [ASEQS] = {.fun = binary, .txt = "ceqs", .letter = 'w'}, + [ASNES] = {.fun = binary, .txt = "cnes", .letter = 'w'}, + + [ASADDD] = {.fun = binary, .txt = "add", .letter = 'd'}, + [ASSUBD] = {.fun = binary, .txt = "sub", .letter = 'd'}, + [ASMULD] = {.fun = binary, .txt = "mul", .letter = 'd'}, + [ASDIVD] = {.fun = binary, .txt = "div", .letter = 'd'}, + [ASLTD] = {.fun = binary, .txt = "cltd", .letter = 'w'}, + [ASGTD] = {.fun = binary, .txt = "cgtd", .letter = 'w'}, + [ASLED] = {.fun = binary, .txt = "cled", .letter = 'w'}, + [ASGED] = {.fun = binary, .txt = "cged", .letter = 'w'}, + [ASEQD] = {.fun = binary, .txt = "ceqd", .letter = 'w'}, + [ASNED] = {.fun = binary, .txt = "cned", .letter = 'w'}, }; /*