mirror of
https://github.com/golang/go
synced 2024-11-20 10:04:45 -07:00
6g: save all 64 bits of AX/DX
8g: save AX/DX around div R=ken OCL=33094 CL=33096
This commit is contained in:
parent
66bb399fdd
commit
dd5f32330c
@ -2,7 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
||||
#undef EXTERN
|
||||
#define EXTERN
|
||||
#include "gg.h"
|
||||
@ -531,17 +530,17 @@ savex(int dr, Node *x, Node *oldx, Node *res, Type *t)
|
||||
int r;
|
||||
|
||||
r = reg[dr];
|
||||
|
||||
nodreg(x, types[TINT64], dr);
|
||||
regalloc(x, t, x);
|
||||
|
||||
// save current ax and dx if they are live
|
||||
// and not the destination
|
||||
memset(oldx, 0, sizeof *oldx);
|
||||
if(r > 0 && !samereg(x, res)) {
|
||||
regalloc(oldx, t, N);
|
||||
regalloc(oldx, types[TINT64], N);
|
||||
gmove(x, oldx);
|
||||
}
|
||||
|
||||
regalloc(x, t, x);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -550,6 +549,7 @@ restx(Node *x, Node *oldx)
|
||||
regfree(x);
|
||||
|
||||
if(oldx->op != 0) {
|
||||
x->type = types[TINT64];
|
||||
gmove(oldx, x);
|
||||
regfree(oldx);
|
||||
}
|
||||
|
@ -524,27 +524,28 @@ samereg(Node *a, Node *b)
|
||||
void
|
||||
dodiv(int op, Type *t, Node *nl, Node *nr, Node *res, Node *ax, Node *dx)
|
||||
{
|
||||
int a;
|
||||
Node n3, n4;
|
||||
Node n1, t1, t2, nz;
|
||||
|
||||
regalloc(&n3, t, res);
|
||||
a = optoas(op, t);
|
||||
tempalloc(&t1, nl->type);
|
||||
tempalloc(&t2, nr->type);
|
||||
cgen(nl, &t1);
|
||||
cgen(nr, &t2);
|
||||
|
||||
if(nl->ullman >= UINF) {
|
||||
cgen(nl, &n3);
|
||||
gmove(&n3, ax);
|
||||
cgen(nr, &n3);
|
||||
} else {
|
||||
cgen(nr, &n3);
|
||||
cgen(nl, ax);
|
||||
}
|
||||
if(!samereg(ax, res) && !samereg(dx, res))
|
||||
regalloc(&n1, t, res);
|
||||
else
|
||||
regalloc(&n1, t, N);
|
||||
gmove(&t2, &n1);
|
||||
gmove(&t1, ax);
|
||||
if(!issigned[t->etype]) {
|
||||
nodconst(&n4, t, 0);
|
||||
gmove(&n4, dx);
|
||||
nodconst(&nz, t, 0);
|
||||
gmove(&nz, dx);
|
||||
} else
|
||||
gins(optoas(OEXTEND, t), N, N);
|
||||
gins(a, &n3, N);
|
||||
regfree(&n3);
|
||||
gins(optoas(op, t), &n1, N);
|
||||
regfree(&n1);
|
||||
tempfree(&t2);
|
||||
tempfree(&t1);
|
||||
|
||||
if(op == ODIV)
|
||||
gmove(ax, res);
|
||||
@ -552,6 +553,37 @@ dodiv(int op, Type *t, Node *nl, Node *nr, Node *res, Node *ax, Node *dx)
|
||||
gmove(dx, res);
|
||||
}
|
||||
|
||||
static void
|
||||
savex(int dr, Node *x, Node *oldx, Node *res, Type *t)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = reg[dr];
|
||||
nodreg(x, types[TINT32], dr);
|
||||
|
||||
// save current ax and dx if they are live
|
||||
// and not the destination
|
||||
memset(oldx, 0, sizeof *oldx);
|
||||
if(r > 0 && !samereg(x, res)) {
|
||||
tempalloc(oldx, types[TINT32]);
|
||||
gmove(x, oldx);
|
||||
}
|
||||
|
||||
regalloc(x, t, x);
|
||||
}
|
||||
|
||||
static void
|
||||
restx(Node *x, Node *oldx)
|
||||
{
|
||||
regfree(x);
|
||||
|
||||
if(oldx->op != 0) {
|
||||
x->type = types[TINT32];
|
||||
gmove(oldx, x);
|
||||
tempfree(oldx);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* generate division according to op, one of:
|
||||
* res = nl / nr
|
||||
@ -560,7 +592,7 @@ dodiv(int op, Type *t, Node *nl, Node *nr, Node *res, Node *ax, Node *dx)
|
||||
void
|
||||
cgen_div(int op, Node *nl, Node *nr, Node *res)
|
||||
{
|
||||
Node ax, dx;
|
||||
Node ax, dx, oldax, olddx;
|
||||
int rax, rdx;
|
||||
Type *t;
|
||||
|
||||
@ -574,15 +606,11 @@ cgen_div(int op, Node *nl, Node *nr, Node *res)
|
||||
if(t->width == 1)
|
||||
t = types[t->etype+2]; // int8 -> int16, uint8 -> uint16
|
||||
|
||||
nodreg(&ax, types[TINT32], D_AX);
|
||||
nodreg(&dx, types[TINT32], D_DX);
|
||||
regalloc(&ax, t, &ax);
|
||||
regalloc(&dx, t, &dx);
|
||||
|
||||
savex(D_AX, &ax, &oldax, res, t);
|
||||
savex(D_DX, &dx, &olddx, res, t);
|
||||
dodiv(op, t, nl, nr, res, &ax, &dx);
|
||||
|
||||
regfree(&ax);
|
||||
regfree(&dx);
|
||||
restx(&dx, &olddx);
|
||||
restx(&ax, &oldax);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -601,9 +629,6 @@ cgen_shift(int op, Node *nl, Node *nr, Node *res)
|
||||
if(nl->type->width > 4)
|
||||
fatal("cgen_shift %T", nl->type->width);
|
||||
|
||||
if(nl->type->width == 1 && nl->type->etype != TUINT8)
|
||||
fatal("cgen_shift %T", nl->type);
|
||||
|
||||
w = nl->type->width * 8;
|
||||
|
||||
a = optoas(op, nl->type);
|
||||
@ -655,7 +680,7 @@ cgen_shift(int op, Node *nl, Node *nr, Node *res)
|
||||
}
|
||||
patch(p1, pc);
|
||||
gins(a, &n1, &n2);
|
||||
|
||||
|
||||
if(oldcx.op != 0) {
|
||||
gmove(&oldcx, &cx);
|
||||
regfree(&oldcx);
|
||||
|
Loading…
Reference in New Issue
Block a user