Commit c18db5aa authored by Ken Thompson's avatar Ken Thompson

bug in shift of longer operand

by a shorter operand. the bits
in the difference were not cheared.

R=r
OCL=27705
CL=27705
parent dc08ad4f
...@@ -549,7 +549,7 @@ void ...@@ -549,7 +549,7 @@ void
cgen_shift(int op, Node *nl, Node *nr, Node *res) cgen_shift(int op, Node *nl, Node *nr, Node *res)
{ {
Node n1, n2, n3; Node n1, n2, n3;
int a, rcl; int a;
Prog *p1; Prog *p1;
a = optoas(op, nl->type); a = optoas(op, nl->type);
...@@ -569,23 +569,26 @@ cgen_shift(int op, Node *nl, Node *nr, Node *res) ...@@ -569,23 +569,26 @@ cgen_shift(int op, Node *nl, Node *nr, Node *res)
goto ret; goto ret;
} }
rcl = reg[D_CX]; nodreg(&n1, types[TUINT32], D_CX);
regalloc(&n1, nr->type, &n1); // to hold the shift type in CX
nodreg(&n1, types[TINT64], D_CX); regalloc(&n3, types[TUINT64], &n1); // to clear high bits of CX
regalloc(&n1, nr->type, &n1);
regalloc(&n2, nl->type, res); regalloc(&n2, nl->type, res);
if(nl->ullman >= nr->ullman) { if(nl->ullman >= nr->ullman) {
cgen(nl, &n2); cgen(nl, &n2);
cgen(nr, &n1); cgen(nr, &n1);
gmove(&n1, &n3);
} else { } else {
cgen(nr, &n1); cgen(nr, &n1);
gmove(&n1, &n3);
cgen(nl, &n2); cgen(nl, &n2);
} }
regfree(&n3);
// test and fix up large shifts // test and fix up large shifts
nodconst(&n3, types[TUINT32], nl->type->width*8); nodconst(&n3, types[TUINT64], nl->type->width*8);
gins(optoas(OCMP, types[TUINT32]), &n1, &n3); gins(optoas(OCMP, types[TUINT64]), &n1, &n3);
p1 = gbranch(optoas(OLT, types[TUINT32]), T); p1 = gbranch(optoas(OLT, types[TUINT64]), T);
if(op == ORSH && issigned[nl->type->etype]) { if(op == ORSH && issigned[nl->type->etype]) {
nodconst(&n3, types[TUINT32], nl->type->width*8-1); nodconst(&n3, types[TUINT32], nl->type->width*8-1);
gins(a, &n3, &n2); gins(a, &n3, &n2);
......
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