summaryrefslogtreecommitdiff
path: root/src/cmd/6c
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2013-01-18 17:29:53 -0500
committerMatthew Dempsky <mdempsky@google.com>2013-01-18 17:29:53 -0500
commitdf1ad20b3f949ac7154133b10ed2b8c230a2678b (patch)
tree7215dd8ce776e0ec08c5d3273607219c74bd68af /src/cmd/6c
parent431793477499ec24686b519cb427c3ff7ba7b4bc (diff)
downloadgo-df1ad20b3f949ac7154133b10ed2b8c230a2678b.tar.gz
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 issue 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://codereview.appspot.com/7069056 Committer: Russ Cox <rsc@golang.org>
Diffstat (limited to 'src/cmd/6c')
-rw-r--r--src/cmd/6c/cgen.c12
-rw-r--r--src/cmd/6c/txt.c10
2 files changed, 22 insertions, 0 deletions
diff --git a/src/cmd/6c/cgen.c b/src/cmd/6c/cgen.c
index 1fe0156c6..95400c445 100644
--- a/src/cmd/6c/cgen.c
+++ b/src/cmd/6c/cgen.c
@@ -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;
diff --git a/src/cmd/6c/txt.c b/src/cmd/6c/txt.c
index fcc97ee6e..364b189f2 100644
--- a/src/cmd/6c/txt.c
+++ b/src/cmd/6c/txt.c
@@ -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;