mirror of
https://github.com/golang/go
synced 2024-11-20 10:54:49 -07:00
Implement divWW_g in Go.
R=gri DELTA=105 (77 added, 23 deleted, 5 changed) OCL=33890 CL=33910
This commit is contained in:
parent
396b47bbbd
commit
06cac23d28
@ -138,8 +138,55 @@ func mulAddWWW_g(x, y, c Word) (z1, z0 Word) {
|
||||
}
|
||||
|
||||
|
||||
// TODO(gri) get rid of this eventually
|
||||
func divWWW_s(x1, x0, y Word) (q, r Word)
|
||||
// q = (x1<<_W + x0 - r)/y
|
||||
// The most significant bit of y must be 1.
|
||||
func divStep(x1, x0, y Word) (q, r Word) {
|
||||
d1, d0 := y>>_W2, y&_M2;
|
||||
q1, r1 := x1/d1, x1%d1;
|
||||
m := q1*d0;
|
||||
r1 = r1*_B2 | x0>>_W2;
|
||||
if r1 < m {
|
||||
q1--;
|
||||
r1 += y;
|
||||
if r1 >= y && r1 < m {
|
||||
q1--;
|
||||
r1 += y;
|
||||
}
|
||||
}
|
||||
r1 -= m;
|
||||
|
||||
r0 := r1%d1;
|
||||
q0 := r1/d1;
|
||||
m = q0*d0;
|
||||
r0 = r0*_B2 | x0&_M2;
|
||||
if r0 < m {
|
||||
q0--;
|
||||
r0 += y;
|
||||
if r0 >= y && r0 < m {
|
||||
q0--;
|
||||
r0 += y;
|
||||
}
|
||||
}
|
||||
r0 -= m;
|
||||
|
||||
q = q1*_B2 | q0;
|
||||
r = r0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Number of leading zeros in x.
|
||||
func leadingZeros(x Word) (n uint) {
|
||||
if x == 0 {
|
||||
return uint(_W);
|
||||
}
|
||||
for x & (1<<(_W-1)) == 0 {
|
||||
n++;
|
||||
x <<= 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// q = (x1<<_W + x0 - r)/y
|
||||
func divWW_g(x1, x0, y Word) (q, r Word) {
|
||||
@ -148,9 +195,39 @@ func divWW_g(x1, x0, y Word) (q, r Word) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(gri) implement general case w/o assembly code
|
||||
q, r = divWWW_s(x1, x0, y);
|
||||
return;
|
||||
var q0, q1 Word;
|
||||
z := leadingZeros(y);
|
||||
if y > x1 {
|
||||
if z != 0 {
|
||||
y <<= z;
|
||||
x1 = (x1 << z) | (x0 >> (uint(_W) - z));
|
||||
x0 <<= z;
|
||||
}
|
||||
q0, x0 = divStep(x1, x0, y);
|
||||
q1 = 0;
|
||||
} else {
|
||||
if z == 0 {
|
||||
x1 -= y;
|
||||
q1 = 1;
|
||||
} else {
|
||||
z1 := uint(_W) - z;
|
||||
y <<= z;
|
||||
x2 := x1 >> z1;
|
||||
x1 = (x1 << z) | (x0 >> z1);
|
||||
x0 <<= z;
|
||||
q1, x1 = divStep(x2, x1, y);
|
||||
}
|
||||
|
||||
q0, x0 = divStep(x1, x0, y);
|
||||
}
|
||||
|
||||
r = x0 >> z;
|
||||
|
||||
if q1 != 0 {
|
||||
panic("div out of range");
|
||||
}
|
||||
|
||||
return q0, r;
|
||||
}
|
||||
|
||||
|
||||
|
@ -19,15 +19,3 @@ TEXT big·mulAddVWW_s(SB),7,$0
|
||||
TEXT big·addMulVVW_s(SB),7,$0
|
||||
TEXT big·divWVW_s(SB),7,$0
|
||||
RET
|
||||
|
||||
|
||||
// func divWWW_s(x1, x0, y Word) (q, r Word)
|
||||
// TODO(gri) Implement this routine completely in Go.
|
||||
// At the moment we need this assembly version.
|
||||
TEXT big·divWWW_s(SB),7,$0
|
||||
MOVL x1+0(FP), DX
|
||||
MOVL x0+4(FP), AX
|
||||
DIVL y+8(FP)
|
||||
MOVL AX, q+12(FP)
|
||||
MOVL DX, r+16(FP)
|
||||
RET
|
||||
|
@ -176,14 +176,3 @@ E7: SUBL $1, BX // i--
|
||||
|
||||
MOVQ DX, r+40(FP)
|
||||
RET
|
||||
|
||||
|
||||
// TODO(gri) Implement this routine completely in Go.
|
||||
// At the moment we need this assembly version.
|
||||
TEXT big·divWWW_s(SB),7,$0
|
||||
MOVQ x1+0(FP), DX
|
||||
MOVQ x0+8(FP), AX
|
||||
DIVQ y+16(FP)
|
||||
MOVQ AX, q+24(FP)
|
||||
MOVQ DX, r+32(FP)
|
||||
RET
|
||||
|
Loading…
Reference in New Issue
Block a user