Commit d83b994d authored by Ken Thompson's avatar Ken Thompson

div and mod operators

SVN=121576
parent feb1c77f
......@@ -112,9 +112,7 @@ cgen(Node *n, Node *res)
goto sbop;
// asymmetric binary
case OMOD:
case OSUB:
case ODIV:
case OLSH:
case ORSH:
a = optoas(n->op, nl->type);
......@@ -237,6 +235,11 @@ cgen(Node *n, Node *res)
cgen_call(n);
cgen_callret(n, res);
break;
case OMOD:
case ODIV:
cgen_div(n->op, nl, nr, res);
break;
}
goto ret;
......
......@@ -826,3 +826,56 @@ cgen_as(Node *nl, Node *nr, int op)
}
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);
}
......@@ -117,6 +117,7 @@ void cgen_call(Node*);
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*);
......
......@@ -1397,36 +1397,46 @@ optoas(int op, Type *t)
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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment