break;
}
+ if(is64(nr->type)) {
+ if(!nl->addable) {
+ tempalloc(&n1, nl->type);
+ cgen(nl, &n1);
+ nl = &n1;
+ }
+ if(!nr->addable) {
+ tempalloc(&n2, nr->type);
+ cgen(nr, &n2);
+ nr = &n2;
+ }
+ cmp64(nl, nr, a, to);
+ if(nr == &n2)
+ tempfree(&n2);
+ if(nl == &n1)
+ tempfree(&n1);
+ break;
+ }
+
a = optoas(a, nr->type);
if(nr->ullman >= UINF) {
if(osrc % 4 != 0 || odst %4 != 0)
fatal("sgen: non word(4) aligned offset src %d or dst %d", osrc, odst);
- regalloc(&dst, types[tptr], N);
- regalloc(&src, types[tptr], N);
- regalloc(&tmp, types[TUINT32], N);
+ regalloc(&dst, types[tptr], res);
if(n->ullman >= res->ullman) {
- agen(n, &src);
+ agen(n, &dst);
+ regalloc(&src, types[tptr], N);
+ gins(AMOVW, &dst, &src);
agen(res, &dst);
} else {
agen(res, &dst);
+ regalloc(&src, types[tptr], N);
agen(n, &src);
}
+ regalloc(&tmp, types[TUINT32], N);
+
c = w % 4; // bytes
q = w / 4; // quads
void
cmp64(Node *nl, Node *nr, int op, Prog *to)
{
- fatal("cmp64 not implemented");
-// Node lo1, hi1, lo2, hi2, rr;
-// Prog *br;
-// Type *t;
-
-// split64(nl, &lo1, &hi1);
-// split64(nr, &lo2, &hi2);
-
-// // compare most significant word;
-// // if they differ, we're done.
-// t = hi1.type;
-// if(nl->op == OLITERAL || nr->op == OLITERAL)
-// gins(ACMPL, &hi1, &hi2);
-// else {
-// regalloc(&rr, types[TINT32], N);
-// gins(AMOVL, &hi1, &rr);
-// gins(ACMPL, &rr, &hi2);
-// regfree(&rr);
-// }
-// br = P;
-// switch(op) {
-// default:
-// fatal("cmp64 %O %T", op, t);
-// case OEQ:
-// // cmp hi
-// // jne L
-// // cmp lo
-// // jeq to
-// // L:
-// br = gbranch(AJNE, T);
-// break;
-// case ONE:
-// // cmp hi
-// // jne to
-// // cmp lo
-// // jne to
-// patch(gbranch(AJNE, T), to);
-// break;
-// case OGE:
-// case OGT:
-// // cmp hi
-// // jgt to
-// // jlt L
-// // cmp lo
-// // jge to (or jgt to)
-// // L:
-// patch(gbranch(optoas(OGT, t), T), to);
-// br = gbranch(optoas(OLT, t), T);
-// break;
-// case OLE:
-// case OLT:
-// // cmp hi
-// // jlt to
-// // jgt L
-// // cmp lo
-// // jle to (or jlt to)
-// // L:
-// patch(gbranch(optoas(OLT, t), T), to);
-// br = gbranch(optoas(OGT, t), T);
-// break;
-// }
-
-// // compare least significant word
-// t = lo1.type;
-// if(nl->op == OLITERAL || nr->op == OLITERAL)
-// gins(ACMPL, &lo1, &lo2);
-// else {
-// regalloc(&rr, types[TINT32], N);
-// gins(AMOVL, &lo1, &rr);
-// gins(ACMPL, &rr, &lo2);
-// regfree(&rr);
-// }
-
-// // jump again
-// patch(gbranch(optoas(op, t), T), to);
-
-// // point first branch down here if appropriate
-// if(br != P)
-// patch(br, pc);
-
-// splitclean();
-// splitclean();
+ Node lo1, hi1, lo2, hi2, r1, r2;
+ Prog *br;
+ Type *t;
+
+ split64(nl, &lo1, &hi1);
+ split64(nr, &lo2, &hi2);
+
+ // compare most significant word;
+ // if they differ, we're done.
+ t = hi1.type;
+ regalloc(&r1, types[TINT32], N);
+ regalloc(&r2, types[TINT32], N);
+ gins(AMOVW, &hi1, &r1);
+ gins(AMOVW, &hi2, &r2);
+ gcmp(ACMP, &r1, &r2);
+ regfree(&r1);
+ regfree(&r2);
+
+ br = P;
+ switch(op) {
+ default:
+ fatal("cmp64 %O %T", op, t);
+ case OEQ:
+ // cmp hi
+ // bne L
+ // cmp lo
+ // beq to
+ // L:
+ br = gbranch(ABNE, T);
+ break;
+ case ONE:
+ // cmp hi
+ // bne to
+ // cmp lo
+ // bne to
+ patch(gbranch(ABNE, T), to);
+ break;
+ case OGE:
+ case OGT:
+ // cmp hi
+ // bgt to
+ // blt L
+ // cmp lo
+ // bge to (or bgt to)
+ // L:
+ patch(gbranch(optoas(OGT, t), T), to);
+ br = gbranch(optoas(OLT, t), T);
+ break;
+ case OLE:
+ case OLT:
+ // cmp hi
+ // blt to
+ // bgt L
+ // cmp lo
+ // ble to (or jlt to)
+ // L:
+ patch(gbranch(optoas(OLT, t), T), to);
+ br = gbranch(optoas(OGT, t), T);
+ break;
+ }
+
+ // compare least significant word
+ t = lo1.type;
+ regalloc(&r1, types[TINT32], N);
+ regalloc(&r2, types[TINT32], N);
+ gins(AMOVW, &lo1, &r1);
+ gins(AMOVW, &lo2, &r2);
+ gcmp(ACMP, &r1, &r2);
+ regfree(&r1);
+ regfree(&r2);
+
+ // jump again
+ patch(gbranch(optoas(op, t), T), to);
+
+ // point first branch down here if appropriate
+ if(br != P)
+ patch(br, pc);
+
+ splitclean();
+ splitclean();
}
void
regalloc(Node *n, Type *t, Node *o)
{
- int i, et;
+ int i, et, fixfree, floatfree;
+
+ if(debug['r']) {
+ fixfree = 0;
+ for(i=REGALLOC_R0; i<=REGALLOC_RMAX; i++)
+ if(reg[i] == 0)
+ fixfree++;
+ floatfree = 0;
+ for(i=REGALLOC_F0; i<=REGALLOC_FMAX; i++)
+ if(reg[i] == 0)
+ floatfree++;
+ print("regalloc fix %d float %d\n", fixfree, floatfree);
+ }
if(t == T)
fatal("regalloc: t nil");
void
regfree(Node *n)
{
- int i;
+ int i, fixfree, floatfree;
+
+ if(debug['r']) {
+ fixfree = 0;
+ for(i=REGALLOC_R0; i<=REGALLOC_RMAX; i++)
+ if(reg[i] == 0)
+ fixfree++;
+ floatfree = 0;
+ for(i=REGALLOC_F0; i<=REGALLOC_FMAX; i++)
+ if(reg[i] == 0)
+ floatfree++;
+ print("regalloc fix %d float %d\n", fixfree, floatfree);
+ }
if(n->op != OREGISTER && n->op != OINDREG)
fatal("regfree: not a register");
a = AGOK;
switch(CASE(op, simtype[t->etype])) {
default:
- fatal("optoas: no entry %O-%T", op, t);
+ fatal("optoas: no entry %O-%T etype %T simtype %T", op, t, types[t->etype], types[simtype[t->etype]]);
break;
/* case CASE(OADDR, TPTR32):