commit 6b9a0f241f50fce7e358ac90508d5be9a8a4cb61
parent 3c2f03ea118cacf8da600c395071a4b0113504b1
Author: Roberto E. Vargas Caballero <Roberto E. Vargas Caballero>
Date: Wed, 20 Apr 2016 03:44:11 +0200
[cc2-qbe] Fix equality operators
These operators have different form depending of the size of the
operands, so we have to use different opcodes based in the size
of the operands.
Diffstat:
3 files changed, 36 insertions(+), 23 deletions(-)
diff --git a/cc2/arch/qbe/arch.h b/cc2/arch/qbe/arch.h
@@ -18,7 +18,9 @@ enum asmop {
ASLE,
ASGE,
ASEQ,
+ ASEQL,
ASNE,
+ ASNEL,
ASBAND,
ASBOR,
ASBXOR,
diff --git a/cc2/arch/qbe/cgen.c b/cc2/arch/qbe/cgen.c
@@ -61,6 +61,7 @@ cgen(Node *np)
{
Node *l, *r;
Symbol *sym;
+ Type *tp;
int op;
if (!np)
@@ -68,8 +69,9 @@ cgen(Node *np)
l = cgen(np->left);
r = cgen(np->right);
+ tp = &np->type;
- switch (op = np->op) {
+ switch (np->op) {
case OREG:
case OSTRING:
abort();
@@ -79,6 +81,10 @@ 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:
@@ -90,18 +96,18 @@ cgen(Node *np)
case OGT:
case OLE:
case OGE:
- case OEQ:
- case ONE:
case OBAND:
case OBOR:
case OBXOR:
case OCPL:
+ op = opasm[np->op];
+ binary:
if ((l->flags & (ISTMP|ISCONS)) == 0)
l = np->left = load(l);
if ((r->flags & (ISTMP|ISCONS)) == 0)
r = np->right = load(r);
tmpnode(np);
- code(opasm[op], np, l, r);
+ code(op, np, l, r);
return np;
case ONOP:
case OBLOOP:
diff --git a/cc2/arch/qbe/code.c b/cc2/arch/qbe/code.c
@@ -11,25 +11,28 @@ static void binary(void), load(void), store(void);
static struct opdata {
void (*fun)(void);
char *txt;
+ char letter;
} optbl [] = {
- [ASADD] = {.fun = binary, .txt = "add"},
- [ASSUB] = {.fun = binary, .txt = "sub"},
- [ASMUL] = {.fun = binary, .txt = "mul"},
- [ASMOD] = {.fun = binary, .txt = "rem"},
- [ASDIV] = {.fun = binary, .txt = "div"},
- [ASSHL] = {.fun = binary, .txt = "shl"},
- [ASSHR] = {.fun = binary, .txt = "shr"},
- [ASLT] = {.fun = binary, .txt = "clt"},
- [ASGT] = {.fun = binary, .txt = "cgt"},
- [ASLE] = {.fun = binary, .txt = "cle"},
- [ASGE] = {.fun = binary, .txt = "cge"},
- [ASEQ] = {.fun = binary, .txt = "ceq"},
- [ASNE] = {.fun = binary, .txt = "cne"},
- [ASBAND] = {.fun = binary, .txt = "and"},
- [ASBOR] = {.fun = binary, .txt = "or"},
- [ASBXOR] = {.fun = binary, .txt = "xor"},
- [ASLOAD] = {.fun = load, .txt = "load"},
- [ASASSIG] = {.fun = store, .txt = "store"}
+ [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'}
};
/*
@@ -241,8 +244,10 @@ addr2txt(Addr *a)
static void
binary(void)
{
+ struct opdata *p = &optbl[pc->op];
+
printf("\t%s %c=\t%s\t",
- addr2txt(&pc->to), 'w', optbl[pc->op].txt);
+ addr2txt(&pc->to), p->letter, p->txt);
fputs(addr2txt(&pc->from1), stdout);
putchar(',');
fputs(addr2txt(&pc->from2), stdout);