mirror of https://github.com/golang/go.git
cmd/6c: Optimize rotate expressions to use rotate instructions.
For simplicity, only recognizes expressions of the exact form "(x << a) | (x >> b)" where x is a variable and a and b are integer constant expressions that add to x's bit width. Fixes #4629. $ cat rotate.c unsigned int rotate(unsigned int x) { x = (x << 3) | (x >> (sizeof(x) * 8 - 3)); return x; } ## BEFORE $ go tool 6c -S rotate.c (rotate.c:2) TEXT rotate+0(SB),$0-8 (rotate.c:2) MOVL x+0(FP),!!DX (rotate.c:4) MOVL DX,!!AX (rotate.c:4) SALL $3,!!AX (rotate.c:4) MOVL DX,!!CX (rotate.c:4) SHRL $29,!!CX (rotate.c:4) ORL CX,!!AX (rotate.c:5) RET ,!! (rotate.c:5) RET ,!! (rotate.c:5) END ,!! ## AFTER $ go tool 6c -S rotate.c (rotate.c:2) TEXT rotate+0(SB),$0-8 (rotate.c:4) MOVL x+0(FP),!!AX (rotate.c:4) ROLL $3,!!AX (rotate.c:5) RET ,!! (rotate.c:5) RET ,!! (rotate.c:5) END ,!! R=rsc, minux.ma CC=golang-dev https://golang.org/cl/7069056
This commit is contained in:
parent
4730a226ca
commit
bb192d1399
|
|
@ -265,6 +265,18 @@ cgen(Node *n, Node *nn)
|
|||
break;
|
||||
}
|
||||
}
|
||||
if(n->op == OOR && l->op == OASHL && r->op == OLSHR
|
||||
&& l->right->op == OCONST && r->right->op == OCONST
|
||||
&& l->left->op == ONAME && r->left->op == ONAME
|
||||
&& l->left->sym == r->left->sym
|
||||
&& l->right->vconst + r->right->vconst == 8 * l->left->type->width) {
|
||||
regalloc(&nod, l->left, nn);
|
||||
cgen(l->left, &nod);
|
||||
gopcode(OROTL, n->type, l->right, &nod);
|
||||
gmove(&nod, nn);
|
||||
regfree(&nod);
|
||||
break;
|
||||
}
|
||||
if(n->op == OADD && l->op == OASHL && l->right->op == OCONST
|
||||
&& (r->op != OCONST || r->vconst < -128 || r->vconst > 127)) {
|
||||
c = l->right->vconst;
|
||||
|
|
|
|||
|
|
@ -1360,6 +1360,16 @@ gopcode(int o, Type *ty, Node *f, Node *t)
|
|||
a = ASALQ;
|
||||
break;
|
||||
|
||||
case OROTL:
|
||||
a = AROLL;
|
||||
if(et == TCHAR || et == TUCHAR)
|
||||
a = AROLB;
|
||||
if(et == TSHORT || et == TUSHORT)
|
||||
a = AROLW;
|
||||
if(et == TVLONG || et == TUVLONG || et == TIND)
|
||||
a = AROLQ;
|
||||
break;
|
||||
|
||||
case OFUNC:
|
||||
a = ACALL;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -277,6 +277,18 @@ cgen(Node *n, Node *nn)
|
|||
break;
|
||||
}
|
||||
}
|
||||
if(n->op == OOR && l->op == OASHL && r->op == OLSHR
|
||||
&& l->right->op == OCONST && r->right->op == OCONST
|
||||
&& l->left->op == ONAME && r->left->op == ONAME
|
||||
&& l->left->sym == r->left->sym
|
||||
&& l->right->vconst + r->right->vconst == 8 * l->left->type->width) {
|
||||
regalloc(&nod, l->left, nn);
|
||||
cgen(l->left, &nod);
|
||||
gopcode(OROTL, n->type, l->right, &nod);
|
||||
gmove(&nod, nn);
|
||||
regfree(&nod);
|
||||
break;
|
||||
}
|
||||
if(n->op == OADD && l->op == OASHL && l->right->op == OCONST
|
||||
&& (r->op != OCONST || r->vconst < -128 || r->vconst > 127)) {
|
||||
c = l->right->vconst;
|
||||
|
|
|
|||
|
|
@ -1253,6 +1253,14 @@ gopcode(int o, Type *ty, Node *f, Node *t)
|
|||
a = ASALW;
|
||||
break;
|
||||
|
||||
case OROTL:
|
||||
a = AROLL;
|
||||
if(et == TCHAR || et == TUCHAR)
|
||||
a = AROLB;
|
||||
if(et == TSHORT || et == TUSHORT)
|
||||
a = AROLW;
|
||||
break;
|
||||
|
||||
case OFUNC:
|
||||
a = ACALL;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -325,6 +325,7 @@ enum
|
|||
OINDEX,
|
||||
OFAS,
|
||||
OREGPAIR,
|
||||
OROTL,
|
||||
|
||||
OEND
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1515,6 +1515,7 @@ Init onamesinit[] =
|
|||
OINDEX, 0, "INDEX",
|
||||
OFAS, 0, "FAS",
|
||||
OREGPAIR, 0, "REGPAIR",
|
||||
OROTL, 0, "ROTL",
|
||||
OEND, 0, "END",
|
||||
-1, 0, 0,
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue