cgen_shift(int op, Node *nl, Node *nr, Node *res)
{
Node n1, n2, n3;
- int a, rcl;
+ int a;
Prog *p1;
a = optoas(op, nl->type);
goto ret;
}
- rcl = reg[D_CX];
-
- nodreg(&n1, types[TINT64], D_CX);
- regalloc(&n1, nr->type, &n1);
+ nodreg(&n1, types[TUINT32], D_CX);
+ regalloc(&n1, nr->type, &n1); // to hold the shift type in CX
+ regalloc(&n3, types[TUINT64], &n1); // to clear high bits of CX
regalloc(&n2, nl->type, res);
if(nl->ullman >= nr->ullman) {
cgen(nl, &n2);
cgen(nr, &n1);
+ gmove(&n1, &n3);
} else {
cgen(nr, &n1);
+ gmove(&n1, &n3);
cgen(nl, &n2);
}
+ regfree(&n3);
+
// test and fix up large shifts
- nodconst(&n3, types[TUINT32], nl->type->width*8);
- gins(optoas(OCMP, types[TUINT32]), &n1, &n3);
- p1 = gbranch(optoas(OLT, types[TUINT32]), T);
+ nodconst(&n3, types[TUINT64], nl->type->width*8);
+ gins(optoas(OCMP, types[TUINT64]), &n1, &n3);
+ p1 = gbranch(optoas(OLT, types[TUINT64]), T);
if(op == ORSH && issigned[nl->type->etype]) {
nodconst(&n3, types[TUINT32], nl->type->width*8-1);
gins(a, &n3, &n2);