* returns Prog* to patch to panic call.
*/
Prog*
-cgenindex(Node *n, Node *res)
+cgenindex(Node *n, Node *res, int bounded)
{
Node tmp, lo, hi, zero, n1, n2;
cgen(n, &tmp);
split64(&tmp, &lo, &hi);
gmove(&lo, res);
- if(debug['B']) {
+ if(bounded) {
splitclean();
return nil;
}
Prog *p1, *p2;
uint32 w;
uint64 v;
+ int bounded;
if(debug['g'])
dump("agenr-n", n);
case OINDEX:
p2 = nil; // to be patched to panicindex.
w = n->type->width;
+ bounded = debug['B'] || n->bounded;
if(nr->addable) {
if(!isconst(nr, CTINT))
tempname(&tmp, types[TINT32]);
if(!isconst(nl, CTSTR))
agenr(nl, &n3, res);
if(!isconst(nr, CTINT)) {
- p2 = cgenindex(nr, &tmp);
+ p2 = cgenindex(nr, &tmp, bounded);
regalloc(&n1, tmp.type, N);
gmove(&tmp, &n1);
}
if(nl->addable) {
if(!isconst(nr, CTINT)) {
tempname(&tmp, types[TINT32]);
- p2 = cgenindex(nr, &tmp);
+ p2 = cgenindex(nr, &tmp, bounded);
regalloc(&n1, tmp.type, N);
gmove(&tmp, &n1);
}
}
} else {
tempname(&tmp, types[TINT32]);
- p2 = cgenindex(nr, &tmp);
+ p2 = cgenindex(nr, &tmp, bounded);
nr = &tmp;
if(!isconst(nl, CTSTR))
agenr(nl, &n3, res);
* cgen
*/
void agen(Node*, Node*);
-Prog* cgenindex(Node *, Node *);
+Prog* cgenindex(Node *, Node *, int);
void igen(Node*, Node*, Node*);
void agenr(Node *n, Node *a, Node *res);
vlong fieldoffset(Type*, Node*);
t = types[TINT32];
regalloc(reg1, t, N);
regalloc(&n3, types[TINT32], reg1);
- p2 = cgenindex(r, &n3);
+ p2 = cgenindex(r, &n3, debug['B'] || n->bounded);
gmove(&n3, reg1);
regfree(&n3);
* n is an array index, and might be any size; res width is <= 32-bit.
* returns Prog* to patch to panic call.
*/
-Prog*
-igenindex(Node *n, Node *res)
+static Prog*
+igenindex(Node *n, Node *res, int bounded)
{
Node tmp, lo, hi, zero;
split64(&tmp, &lo, &hi);
tempname(res, types[TUINT32]);
gmove(&lo, res);
- if(debug['B']) {
+ if(bounded) {
splitclean();
return nil;
}
uint32 w;
uint64 v;
Prog *p1, *p2;
+ int bounded;
if(debug['g']) {
dump("\nagen-res", res);
case OINDEX:
p2 = nil; // to be patched to panicindex.
w = n->type->width;
+ bounded = debug['B'] || n->bounded;
if(nr->addable) {
// Generate &nl first, and move nr into register.
if(!isconst(nl, CTSTR))
igen(nl, &n3, res);
if(!isconst(nr, CTINT)) {
- p2 = igenindex(nr, &tmp);
+ p2 = igenindex(nr, &tmp, bounded);
regalloc(&n1, tmp.type, N);
gmove(&tmp, &n1);
}
} else if(nl->addable) {
// Generate nr first, and move &nl into register.
if(!isconst(nr, CTINT)) {
- p2 = igenindex(nr, &tmp);
+ p2 = igenindex(nr, &tmp, bounded);
regalloc(&n1, tmp.type, N);
gmove(&tmp, &n1);
}
if(!isconst(nl, CTSTR))
igen(nl, &n3, res);
} else {
- p2 = igenindex(nr, &tmp);
+ p2 = igenindex(nr, &tmp, bounded);
nr = &tmp;
if(!isconst(nl, CTSTR))
igen(nl, &n3, res);
--- /dev/null
+// run
+
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 4448: 64-bit indices that are statically known
+// to be bounded make 5g and 8g generate a dangling branch.
+
+package main
+
+const b26 uint64 = 0x022fdd63cc95386d
+
+var bitPos [64]int
+
+func init() {
+ for p := uint(0); p < 64; p++ {
+ bitPos[b26<<p>>58] = int(p)
+ }
+}
+
+func MinPos(w uint64) int {
+ if w == 0 {
+ panic("bit: MinPos(0) undefined")
+ }
+ return bitPos[((w&-w)*b26)>>58]
+}
+
+func main() {
+ const one = uint64(1)
+ for i := 0; i < 64; i++ {
+ if MinPos(1<<uint(i)) != i {
+ println("i =", i)
+ panic("MinPos(1<<uint(i)) != i")
+ }
+ }
+}