6g, 8g: handle slice by sub-word-sized index (uint8, int8, uint16, int16)
R=ken2
CC=golang-dev
https://golang.org/cl/1960042
diff --git a/src/cmd/8g/ggen.c b/src/cmd/8g/ggen.c
index 40f348c..5c51833 100644
--- a/src/cmd/8g/ggen.c
+++ b/src/cmd/8g/ggen.c
@@ -857,7 +857,8 @@
vlong cl;
Prog *p1;
int op;
- Node *c;
+ Node *c, n1;
+ Type *t;
op = OLE;
if(smallintconst(nl)) {
@@ -872,16 +873,34 @@
nl = nr;
nr = c;
}
-
- gins(optoas(OCMP, types[TUINT32]), nl, nr);
+
+ // Arguments are known not to be 64-bit,
+ // but they might be smaller than 32 bits.
+ // Check if we need to use a temporary.
+ // At least one of the arguments is 32 bits
+ // (the len or cap) so one temporary suffices.
+ n1.op = OXXX;
+ t = types[TUINT32];
+ if(nl->type->width != t->width) {
+ regalloc(&n1, t, nl);
+ gmove(nl, &n1);
+ nl = &n1;
+ } else if(nr->type->width != t->width) {
+ regalloc(&n1, t, nr);
+ gmove(nr, &n1);
+ nr = &n1;
+ }
+ gins(optoas(OCMP, t), nl, nr);
+ if(n1.op != OXXX)
+ regfree(&n1);
if(throwpc == nil) {
- p1 = gbranch(optoas(op, types[TUINT32]), T);
+ p1 = gbranch(optoas(op, t), T);
throwpc = pc;
ginscall(panicslice, 0);
patch(p1, pc);
} else {
op = brcom(op);
- p1 = gbranch(optoas(op, types[TUINT32]), T);
+ p1 = gbranch(optoas(op, t), T);
patch(p1, throwpc);
}
}
@@ -1045,6 +1064,7 @@
// if(lb[1] > old.nel[0]) goto throw;
n2 = nodes[0];
n2.xoffset += Array_nel;
+ n2.type = types[TUINT32];
cmpandthrow(&nodes[1], &n2);
// ret.nel = old.nel[0]-lb[1];
@@ -1064,6 +1084,7 @@
// if(hb[2] > old.cap[0]) goto throw;
n2 = nodes[0];
n2.xoffset += Array_cap;
+ n2.type = types[TUINT32];
cmpandthrow(&nodes[2], &n2);
// if(lb[1] > hb[2]) goto throw;