1
0
mirror of https://github.com/golang/go synced 2024-11-25 10:07:56 -07:00

shift operations to new spec

R=r
OCL=14641
CL=14641
This commit is contained in:
Ken Thompson 2008-08-28 19:59:42 -07:00
parent df49fb3dc3
commit 53010efe01
3 changed files with 52 additions and 6 deletions

View File

@ -1077,8 +1077,9 @@ ret:
void
cgen_shift(int op, Node *nl, Node *nr, Node *res)
{
Node n1, n2;
Node n1, n2, n3;
int a, rcl;
Prog *p1;
a = optoas(op, nl->type);
@ -1111,7 +1112,7 @@ cgen_shift(int op, Node *nl, Node *nr, Node *res)
goto ret;
}
regalloc(&n2, nl->type, res); // can one shift the CL register?
regalloc(&n2, nl->type, res); // can one shift the CL register
if(nl->ullman >= nr->ullman) {
cgen(nl, &n2);
cgen(nr, &n1);
@ -1119,7 +1120,21 @@ cgen_shift(int op, Node *nl, Node *nr, Node *res)
cgen(nr, &n1);
cgen(nl, &n2);
}
// 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);
if(op == ORSH && issigned[nl->type->etype]) {
nodconst(&n3, types[TUINT32], nl->type->width*8-1);
gins(a, &n3, &n2);
} else {
nodconst(&n3, nl->type, 0);
gmove(&n3, &n2);
}
patch(p1, pc);
gins(a, &n1, &n2);
gmove(&n2, res);
regfree(&n1);

View File

@ -71,10 +71,11 @@ mplshw(Mpint *a)
static void
mprsh(Mpint *a)
{
long *a1, x;
long *a1, x, lo;
int i, c;
c = 0;
lo = a->a[0] & 1;
a1 = &a->a[Mpprec];
for(i=0; i<Mpprec; i++) {
x = *--a1;
@ -83,6 +84,8 @@ mprsh(Mpint *a)
if(x & 1)
c = Mpbase;
}
if(a->neg && lo == 0)
mpaddcfix(a, -1);
}
//
@ -92,15 +95,18 @@ mprsh(Mpint *a)
static void
mprshw(Mpint *a)
{
long *a1;
long *a1, lo;
int i;
lo = a->a[0];
a1 = &a->a[0];
for(i=1; i<Mpprec; i++) {
a1[0] = a1[1];
*a1++;
}
a1[0] = 0;
if(a->neg && lo == 0)
mpaddcfix(a, -1);
}
//
@ -411,7 +417,10 @@ mprshfixfix(Mpint *a, Mpint *b)
s = mpgetfix(b);
if(s < 0 || s >= Mpprec*Mpscale) {
warn("stupid shift: %lld", s);
mpmovecfix(a, 0);
if(a->neg)
mpmovecfix(a, -1);
else
mpmovecfix(a, 0);
return;
}

View File

@ -473,8 +473,11 @@ loop:
goto nottop;
walktype(n->left, Elv);
l = n->left;
if(l->op != OINDEX)
if(l->op != OINDEX) {
if(n->etype == OLSH || n->etype == ORSH)
goto shft;
goto com;
}
if(!isptrto(l->left->type, TMAP))
goto com;
*n = *mapop(n, top);
@ -482,6 +485,25 @@ loop:
case OLSH:
case ORSH:
if(top != Erv)
goto nottop;
walktype(n->left, Erv);
shft:
walktype(n->right, Erv);
if(n->left == N || n->right == N)
goto ret;
evconst(n);
if(n->op == OLITERAL)
goto ret;
convlit(n->left, n->left->type);
convlit(n->right, types[TUINT32]);
if(n->left->type == T || n->right->type == T)
goto ret;
if(issigned[n->right->type->etype])
goto badt;
break;
case OMOD:
case OAND:
case OOR: