mirror of https://github.com/golang/go.git
cmd/internal/gc: Use shifts for powers-of-two indexing
Fixes #10638 Change-Id: I7bbaad7e5a599aa94d1d158e903596231c7e9897 Reviewed-on: https://go-review.googlesource.com/9535 Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
This commit is contained in:
parent
71274e4857
commit
135389d0ff
|
|
@ -1132,12 +1132,18 @@ func Agenr(n *Node, a *Node, res *Node) {
|
|||
} else if w == 1 {
|
||||
Thearch.Gins(Thearch.Optoas(OADD, Types[Tptr]), &n2, &n3)
|
||||
} else {
|
||||
Regalloc(&n4, Types[TUINT32], nil)
|
||||
Nodconst(&n1, Types[TUINT32], int64(w))
|
||||
Thearch.Gmove(&n1, &n4)
|
||||
Thearch.Gins(Thearch.Optoas(OMUL, Types[TUINT32]), &n4, &n2)
|
||||
if w&(w-1) == 0 {
|
||||
// Power of 2. Use shift.
|
||||
Thearch.Ginscon(Thearch.Optoas(OLSH, Types[TUINT32]), int64(log2(uint64(w))), &n2)
|
||||
} else {
|
||||
// Not a power of 2. Use multiply.
|
||||
Regalloc(&n4, Types[TUINT32], nil)
|
||||
Nodconst(&n1, Types[TUINT32], int64(w))
|
||||
Thearch.Gmove(&n1, &n4)
|
||||
Thearch.Gins(Thearch.Optoas(OMUL, Types[TUINT32]), &n4, &n2)
|
||||
Regfree(&n4)
|
||||
}
|
||||
Thearch.Gins(Thearch.Optoas(OADD, Types[Tptr]), &n2, &n3)
|
||||
Regfree(&n4)
|
||||
}
|
||||
*a = n3
|
||||
Regfree(&n2)
|
||||
|
|
@ -1292,8 +1298,13 @@ func Agenr(n *Node, a *Node, res *Node) {
|
|||
} else if w == 1 {
|
||||
Thearch.Gins(Thearch.Optoas(OADD, Types[Tptr]), &n2, &n3)
|
||||
} else {
|
||||
Nodconst(&tmp, Types[TUINT32], int64(w))
|
||||
Thearch.Gins(Thearch.Optoas(OMUL, Types[TUINT32]), &tmp, &n2)
|
||||
if w&(w-1) == 0 {
|
||||
// Power of 2. Use shift.
|
||||
Thearch.Ginscon(Thearch.Optoas(OLSH, Types[TUINT32]), int64(log2(uint64(w))), &n2)
|
||||
} else {
|
||||
// Not a power of 2. Use multiply.
|
||||
Thearch.Ginscon(Thearch.Optoas(OMUL, Types[TUINT32]), int64(w), &n2)
|
||||
}
|
||||
Thearch.Gins(Thearch.Optoas(OADD, Types[Tptr]), &n2, &n3)
|
||||
}
|
||||
|
||||
|
|
@ -1485,7 +1496,13 @@ func Agenr(n *Node, a *Node, res *Node) {
|
|||
} else if w == 1 {
|
||||
Thearch.Gins(Thearch.Optoas(OADD, Types[Tptr]), &n2, &n3)
|
||||
} else {
|
||||
Thearch.Ginscon(Thearch.Optoas(OMUL, t), int64(w), &n2)
|
||||
if w&(w-1) == 0 {
|
||||
// Power of 2. Use shift.
|
||||
Thearch.Ginscon(Thearch.Optoas(OLSH, t), int64(log2(w)), &n2)
|
||||
} else {
|
||||
// Not a power of 2. Use multiply.
|
||||
Thearch.Ginscon(Thearch.Optoas(OMUL, t), int64(w), &n2)
|
||||
}
|
||||
Thearch.Gins(Thearch.Optoas(OADD, Types[Tptr]), &n2, &n3)
|
||||
}
|
||||
|
||||
|
|
@ -1502,6 +1519,15 @@ func Agenr(n *Node, a *Node, res *Node) {
|
|||
}
|
||||
}
|
||||
|
||||
// log2 returns the logarithm base 2 of n. n must be a power of 2.
|
||||
func log2(n uint64) int {
|
||||
x := 0
|
||||
for n>>uint(x) != 1 {
|
||||
x++
|
||||
}
|
||||
return x
|
||||
}
|
||||
|
||||
/*
|
||||
* generate:
|
||||
* res = &n;
|
||||
|
|
|
|||
Loading…
Reference in New Issue