goto sbop;
// asymmetric binary
- case OMOD:
case OSUB:
- case ODIV:
case OLSH:
case ORSH:
a = optoas(n->op, nl->type);
cgen_call(n);
cgen_callret(n, res);
break;
+
+ case OMOD:
+ case ODIV:
+ cgen_div(n->op, nl, nr, res);
+ break;
}
goto ret;
}
cgen(nr, nl);
}
+
+void
+cgen_div(int op, Node *nl, Node *nr, Node *res)
+{
+ Node n1, n2, n3;
+ int a;
+
+ if(reg[D_AX] || reg[D_DX]) {
+ fatal("registers occupide");
+ }
+
+ a = optoas(op, nl->type);
+
+ // hold down the DX:AX registers
+ nodreg(&n1, types[TINT64], D_AX);
+ nodreg(&n2, types[TINT64], D_DX);
+ regalloc(&n1, nr->type, &n1);
+ regalloc(&n2, nr->type, &n2);
+
+ if(!issigned[nl->type->etype]) {
+ nodconst(&n3, nl->type, 0);
+ gmove(&n3, &n2);
+ }
+
+ if(nl->ullman >= nr->ullman) {
+ cgen(nl, &n1);
+ if(issigned[nl->type->etype])
+ gins(ACDQ, N, N);
+ if(!nr->addable) {
+ regalloc(&n3, nr->type, res);
+ cgen(nr, &n3);
+ gins(a, &n3, N);
+ regfree(&n3);
+ } else
+ gins(a, nr, N);
+ } else {
+ regalloc(&n3, nr->type, res);
+ cgen(nr, &n3);
+ cgen(nl, &n1);
+ if(issigned[nl->type->etype])
+ gins(ACDQ, N, N);
+ gins(a, &n3, N);
+ regfree(&n3);
+ }
+
+ if(op == ODIV)
+ gmove(&n1, res);
+ else
+ gmove(&n2, res);
+
+ regfree(&n1);
+ regfree(&n2);
+}
void cgen_callmeth(Node*);
void cgen_callinter(Node*, Node*);
void cgen_callret(Node*, Node*);
+void cgen_div(int, Node*, Node*, Node*);
void genpanic(void);
int needconvert(Type*, Type*);
void genconv(Type*, Type*);
break;
case CASE(ODIV, TINT8):
+ case CASE(OMOD, TINT8):
a = AIDIVB;
break;
case CASE(ODIV, TUINT8):
+ case CASE(OMOD, TUINT8):
a = ADIVB;
break;
case CASE(ODIV, TINT16):
+ case CASE(OMOD, TINT16):
a = AIDIVW;
break;
case CASE(ODIV, TUINT16):
+ case CASE(OMOD, TUINT16):
a = ADIVW;
break;
case CASE(ODIV, TINT32):
+ case CASE(OMOD, TINT32):
a = AIDIVL;
break;
case CASE(ODIV, TUINT32):
case CASE(ODIV, TPTR32):
+ case CASE(OMOD, TUINT32):
+ case CASE(OMOD, TPTR32):
a = ADIVL;
break;
case CASE(ODIV, TINT64):
+ case CASE(OMOD, TINT64):
a = AIDIVQ;
break;
case CASE(ODIV, TUINT64):
case CASE(ODIV, TPTR64):
+ case CASE(OMOD, TUINT64):
+ case CASE(OMOD, TPTR64):
a = ADIVQ;
break;