Commit d89b7173 authored by Anthony Martin's avatar Anthony Martin Committed by Russ Cox

5c, 6c, 8c: support 64-bit switch value

For real this time. :-)

R=rsc, ken
CC=golang-dev
https://golang.org/cl/5486061
parent 8fbeb945
...@@ -304,6 +304,7 @@ void gpseudo(int, Sym*, Node*); ...@@ -304,6 +304,7 @@ void gpseudo(int, Sym*, Node*);
int swcmp(const void*, const void*); int swcmp(const void*, const void*);
void doswit(Node*); void doswit(Node*);
void swit1(C1*, int, int32, Node*); void swit1(C1*, int, int32, Node*);
void swit2(C1*, int, int32, Node*);
void newcase(void); void newcase(void);
void bitload(Node*, Node*, Node*, Node*, Node*); void bitload(Node*, Node*, Node*, Node*, Node*);
void bitstore(Node*, Node*, Node*, Node*, Node*); void bitstore(Node*, Node*, Node*, Node*, Node*);
......
...@@ -28,11 +28,30 @@ ...@@ -28,11 +28,30 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
#include "gc.h" #include "gc.h"
void void
swit1(C1 *q, int nc, int32 def, Node *n) swit1(C1 *q, int nc, int32 def, Node *n)
{
Node nreg;
if(typev[n->type->etype]) {
regsalloc(&nreg, n);
nreg.type = types[TVLONG];
cgen(n, &nreg);
swit2(q, nc, def, &nreg);
return;
}
regalloc(&nreg, n, Z);
nreg.type = types[TLONG];
cgen(n, &nreg);
swit2(q, nc, def, &nreg);
regfree(&nreg);
}
void
swit2(C1 *q, int nc, int32 def, Node *n)
{ {
C1 *r; C1 *r;
int i; int i;
...@@ -65,12 +84,12 @@ swit1(C1 *q, int nc, int32 def, Node *n) ...@@ -65,12 +84,12 @@ swit1(C1 *q, int nc, int32 def, Node *n)
sp = p; sp = p;
gopcode(OEQ, nodconst(r->val), n, Z); /* just gen the B.EQ */ gopcode(OEQ, nodconst(r->val), n, Z); /* just gen the B.EQ */
patch(p, r->label); patch(p, r->label);
swit1(q, i, def, n); swit2(q, i, def, n);
if(debug['W']) if(debug['W'])
print("case < %.8ux\n", r->val); print("case < %.8ux\n", r->val);
patch(sp, pc); patch(sp, pc);
swit1(r+1, nc-i-1, def, n); swit2(r+1, nc-i-1, def, n);
return; return;
direct: direct:
......
...@@ -299,6 +299,7 @@ void gpseudo(int, Sym*, Node*); ...@@ -299,6 +299,7 @@ void gpseudo(int, Sym*, Node*);
int swcmp(const void*, const void*); int swcmp(const void*, const void*);
void doswit(Node*); void doswit(Node*);
void swit1(C1*, int, int32, Node*); void swit1(C1*, int, int32, Node*);
void swit2(C1*, int, int32, Node*);
void newcase(void); void newcase(void);
void bitload(Node*, Node*, Node*, Node*, Node*); void bitload(Node*, Node*, Node*, Node*, Node*);
void bitstore(Node*, Node*, Node*, Node*, Node*); void bitstore(Node*, Node*, Node*, Node*, Node*);
......
...@@ -32,6 +32,21 @@ ...@@ -32,6 +32,21 @@
void void
swit1(C1 *q, int nc, int32 def, Node *n) swit1(C1 *q, int nc, int32 def, Node *n)
{
Node nreg;
regalloc(&nreg, n, Z);
if(typev[n->type->etype])
nreg.type = types[TVLONG];
else
nreg.type = types[TLONG];
cgen(n, &nreg);
swit2(q, nc, def, &nreg);
regfree(&nreg);
}
void
swit2(C1 *q, int nc, int32 def, Node *n)
{ {
C1 *r; C1 *r;
int i; int i;
...@@ -58,12 +73,12 @@ swit1(C1 *q, int nc, int32 def, Node *n) ...@@ -58,12 +73,12 @@ swit1(C1 *q, int nc, int32 def, Node *n)
gbranch(OGOTO); gbranch(OGOTO);
p->as = AJEQ; p->as = AJEQ;
patch(p, r->label); patch(p, r->label);
swit1(q, i, def, n); swit2(q, i, def, n);
if(debug['W']) if(debug['W'])
print("case < %.8llux\n", r->val); print("case < %.8llux\n", r->val);
patch(sp, pc); patch(sp, pc);
swit1(r+1, nc-i-1, def, n); swit2(r+1, nc-i-1, def, n);
} }
void void
......
...@@ -304,6 +304,7 @@ void gpseudo(int, Sym*, Node*); ...@@ -304,6 +304,7 @@ void gpseudo(int, Sym*, Node*);
int swcmp(const void*, const void*); int swcmp(const void*, const void*);
void doswit(Node*); void doswit(Node*);
void swit1(C1*, int, int32, Node*); void swit1(C1*, int, int32, Node*);
void swit2(C1*, int, int32, Node*);
void newcase(void); void newcase(void);
void bitload(Node*, Node*, Node*, Node*, Node*); void bitload(Node*, Node*, Node*, Node*, Node*);
void bitstore(Node*, Node*, Node*, Node*, Node*); void bitstore(Node*, Node*, Node*, Node*, Node*);
......
...@@ -32,6 +32,26 @@ ...@@ -32,6 +32,26 @@
void void
swit1(C1 *q, int nc, int32 def, Node *n) swit1(C1 *q, int nc, int32 def, Node *n)
{
Node nreg;
if(typev[n->type->etype]) {
regsalloc(&nreg, n);
nreg.type = types[TVLONG];
cgen(n, &nreg);
swit2(q, nc, def, &nreg);
return;
}
regalloc(&nreg, n, Z);
nreg.type = types[TLONG];
cgen(n, &nreg);
swit2(q, nc, def, &nreg);
regfree(&nreg);
}
void
swit2(C1 *q, int nc, int32 def, Node *n)
{ {
C1 *r; C1 *r;
int i; int i;
...@@ -58,12 +78,12 @@ swit1(C1 *q, int nc, int32 def, Node *n) ...@@ -58,12 +78,12 @@ swit1(C1 *q, int nc, int32 def, Node *n)
gbranch(OGOTO); gbranch(OGOTO);
p->as = AJEQ; p->as = AJEQ;
patch(p, r->label); patch(p, r->label);
swit1(q, i, def, n); swit2(q, i, def, n);
if(debug['W']) if(debug['W'])
print("case < %.8ux\n", r->val); print("case < %.8ux\n", r->val);
patch(sp, pc); patch(sp, pc);
swit1(r+1, nc-i-1, def, n); swit2(r+1, nc-i-1, def, n);
} }
void void
......
...@@ -293,7 +293,7 @@ loop: ...@@ -293,7 +293,7 @@ loop:
complex(l); complex(l);
if(l->type == T) if(l->type == T)
break; break;
if(!typeword[l->type->etype] || l->type->etype == TIND) { if(!typechlvp[l->type->etype] || l->type->etype == TIND) {
diag(n, "switch expression must be integer"); diag(n, "switch expression must be integer");
break; break;
} }
...@@ -320,15 +320,7 @@ loop: ...@@ -320,15 +320,7 @@ loop:
} }
patch(sp, pc); patch(sp, pc);
regalloc(&nod, l, Z); doswit(l);
/* always signed */
if(typev[l->type->etype])
nod.type = types[TVLONG];
else
nod.type = types[TLONG];
cgen(l, &nod);
doswit(&nod);
regfree(&nod);
patch(spb, pc); patch(spb, pc);
cases = cn; cases = cn;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment