Commit 888767fc authored by Robert Griesemer's avatar Robert Griesemer

cmd/internal/gc: use big.Int to represent Mpint bits

- renamed (existing) Mpint -> Mpfix
- defined (new) Mpint using big.Int
- modified funcs mpxxx operating on new Mpint
- renamed funcs mpxxx -> _mpxxx if still needed with Mpfix
- left old (possibly unused) code in place for comparison

Passes all.bash.

Change-Id: I1fc7bba7dc4b6386f2f0950d745cec17c1e67615

cmd/internal/gc: renamed Mpint -> Mpfix

Change-Id: Ia06aeae1081ef29d5ad9b711fb57e4c5579ce29b
Reviewed-on: https://go-review.googlesource.com/7830Reviewed-by: default avatarRuss Cox <rsc@golang.org>
parent 653426f0
......@@ -7,6 +7,7 @@ package gc
import (
"bytes"
"cmd/internal/obj"
"math/big"
)
// avoid <ctype.h>
......@@ -65,14 +66,22 @@ const (
Mpdebug = 0
)
// Mpint represents an integer constant.
type Mpint struct {
Val big.Int
Ovf bool // set if Val overflowed compiler limit (sticky)
}
// Mpfix is the original (old) representation of an integer constant.
// Still needed for Mpflt.
type Mpfix struct {
A [Mpprec]int
Neg uint8
Ovf uint8
}
type Mpflt struct {
Val Mpint
Val Mpfix
Exp int16
}
......
......@@ -1401,7 +1401,7 @@ ncu:
str = lexbuf.String()
yylval.val.U.Xval = new(Mpint)
mpatofix(yylval.val.U.Xval, str)
if yylval.val.U.Xval.Ovf != 0 {
if yylval.val.U.Xval.Ovf {
Yyerror("overflow in constant")
Mpmovecfix(yylval.val.U.Xval, 0)
}
......
......@@ -8,39 +8,48 @@ import (
"cmd/internal/obj"
"fmt"
"math"
"math/big"
)
/// uses arithmetic
func mpcmpfixflt(a *Mpint, b *Mpflt) int {
func mpcmpfixflt(a *Mpfix, b *Mpflt) int {
var c Mpflt
buf := Bconv(a, 0)
buf := _Bconv(a, 0)
mpatoflt(&c, buf)
return mpcmpfltflt(&c, b)
}
func mpcmpfltfix(a *Mpflt, b *Mpint) int {
func mpcmpfltfix(a *Mpflt, b *Mpfix) int {
var c Mpflt
buf := Bconv(b, 0)
buf := _Bconv(b, 0)
mpatoflt(&c, buf)
return mpcmpfltflt(a, &c)
}
func Mpcmpfixfix(a *Mpint, b *Mpint) int {
var c Mpint
func Mpcmpfixfix(a, b *Mpint) int {
return a.Val.Cmp(&b.Val)
}
func _Mpcmpfixfix(a *Mpfix, b *Mpfix) int {
var c Mpfix
mpmovefixfix(&c, a)
mpsubfixfix(&c, b)
_mpmovefixfix(&c, a)
_mpsubfixfix(&c, b)
return mptestfix(&c)
}
func mpcmpfixc(b *Mpint, c int64) int {
var c1 Mpint
return b.Val.Cmp(big.NewInt(c))
}
Mpmovecfix(&c1, c)
return Mpcmpfixfix(b, &c1)
func _mpcmpfixc(b *Mpfix, c int64) int {
var c1 Mpfix
_Mpmovecfix(&c1, c)
return _Mpcmpfixfix(b, &c1)
}
func mpcmpfltflt(a *Mpflt, b *Mpflt) int {
......@@ -58,10 +67,14 @@ func mpcmpfltc(b *Mpflt, c float64) int {
return mpcmpfltflt(b, &a)
}
func mpsubfixfix(a *Mpint, b *Mpint) {
mpnegfix(a)
mpaddfixfix(a, b, 0)
mpnegfix(a)
func mpsubfixfix(a, b *Mpint) {
a.Val.Sub(&a.Val, &b.Val)
}
func _mpsubfixfix(a *Mpfix, b *Mpfix) {
_mpnegfix(a)
_mpaddfixfix(a, b, 0)
_mpnegfix(a)
}
func mpsubfltflt(a *Mpflt, b *Mpflt) {
......@@ -70,11 +83,11 @@ func mpsubfltflt(a *Mpflt, b *Mpflt) {
mpnegflt(a)
}
func mpaddcfix(a *Mpint, c int64) {
var b Mpint
func mpaddcfix(a *Mpfix, c int64) {
var b Mpfix
Mpmovecfix(&b, c)
mpaddfixfix(a, &b, 0)
_Mpmovecfix(&b, c)
_mpaddfixfix(a, &b, 0)
}
func mpaddcflt(a *Mpflt, c float64) {
......@@ -84,11 +97,11 @@ func mpaddcflt(a *Mpflt, c float64) {
mpaddfltflt(a, &b)
}
func mpmulcfix(a *Mpint, c int64) {
var b Mpint
func mpmulcfix(a *Mpfix, c int64) {
var b Mpfix
Mpmovecfix(&b, c)
mpmulfixfix(a, &b)
_Mpmovecfix(&b, c)
_mpmulfixfix(a, &b)
}
func mpmulcflt(a *Mpflt, c float64) {
......@@ -98,41 +111,136 @@ func mpmulcflt(a *Mpflt, c float64) {
mpmulfltflt(a, &b)
}
func mpdivfixfix(a *Mpint, b *Mpint) {
var q Mpint
var r Mpint
func mpdivfixfix(a, b *Mpint) {
a.Val.Quo(&a.Val, &b.Val)
}
func _mpdivfixfix(a *Mpfix, b *Mpfix) {
var q Mpfix
var r Mpfix
mpdivmodfixfix(&q, &r, a, b)
mpmovefixfix(a, &q)
_mpmovefixfix(a, &q)
}
func mpmodfixfix(a, b *Mpint) {
a.Val.Rem(&a.Val, &b.Val)
}
func mpmodfixfix(a *Mpint, b *Mpint) {
var q Mpint
var r Mpint
func _mpmodfixfix(a *Mpfix, b *Mpfix) {
var q Mpfix
var r Mpfix
mpdivmodfixfix(&q, &r, a, b)
mpmovefixfix(a, &r)
_mpmovefixfix(a, &r)
}
func mpcomfix(a *Mpfix) {
var b Mpfix
_Mpmovecfix(&b, 1)
_mpnegfix(a)
_mpsubfixfix(a, &b)
}
// *a = Mpfix(*b)
func mpmoveintfix(a *Mpfix, b *Mpint) {
if b.Ovf {
_Mpmovecfix(a, 0)
a.Ovf = 1
return
}
var bb big.Int
bb.Abs(&b.Val)
i := 0
for ; i < Mpprec && bb.Sign() != 0; i++ {
// depends on (unspecified) behavior of Int.Uint64
a.A[i] = int(bb.Uint64() & Mpmask)
bb.Rsh(&bb, Mpscale)
}
if bb.Sign() != 0 {
// MPint overflows
_Mpmovecfix(a, 0)
a.Ovf = 1
return
}
for ; i < Mpprec; i++ {
a.A[i] = 0
}
a.Neg = 0
if b.Val.Sign() < 0 {
a.Neg = 1
}
a.Ovf = 0
// leave for debugging
// println("mpmoveintfix:", b.Val.String(), "->", _Bconv(a, 0))
}
func mpcomfix(a *Mpint) {
var b Mpint
// *a = big.Int(*b)
func mpmovefixint(a *Mpint, b *Mpfix) {
if b.Ovf != 0 {
mpsetovf(a)
return
}
i := Mpprec - 1
for ; i >= 0 && b.A[i] == 0; i-- {
}
a.Val.SetUint64(0)
var x big.Int
for ; i >= 0; i-- {
a.Val.Lsh(&a.Val, Mpscale)
a.Val.Or(&a.Val, x.SetUint64(uint64(b.A[i]&Mpmask)))
}
if b.Neg != 0 {
a.Val.Neg(&a.Val)
}
a.Ovf = false
Mpmovecfix(&b, 1)
mpnegfix(a)
mpsubfixfix(a, &b)
// leave for debugging
// println("mpmovefixint:", _Bconv(b, 0), "->", a.Val.String())
}
func Mpmovefixflt(a *Mpflt, b *Mpint) {
mpmoveintfix(&a.Val, b) // a.Val = *b
a.Exp = 0
mpnorm(a)
}
func _Mpmovefixflt(a *Mpflt, b *Mpfix) {
a.Val = *b
a.Exp = 0
mpnorm(a)
}
func mpexactfltfix(a *Mpint, b *Mpflt) int {
mpmovefixint(a, &b.Val) // *a = b.Val
Mpshiftfix(a, int(b.Exp))
if b.Exp < 0 {
var f Mpflt
mpmoveintfix(&f.Val, a) // f.Val = *a
f.Exp = 0
mpnorm(&f)
if mpcmpfltflt(b, &f) != 0 {
return -1
}
}
return 0
}
// convert (truncate) b to a.
// return -1 (but still convert) if b was non-integer.
func mpexactfltfix(a *Mpint, b *Mpflt) int {
func _mpexactfltfix(a *Mpfix, b *Mpflt) int {
*a = b.Val
Mpshiftfix(a, int(b.Exp))
_Mpshiftfix(a, int(b.Exp))
if b.Exp < 0 {
var f Mpflt
f.Val = *a
......@@ -176,7 +284,41 @@ func mpmovefltfix(a *Mpint, b *Mpflt) int {
return -1
}
func mpmovefixfix(a *Mpint, b *Mpint) {
func _mpmovefltfix(a *Mpfix, b *Mpflt) int {
if _mpexactfltfix(a, b) == 0 {
return 0
}
// try rounding down a little
f := *b
f.Val.A[0] = 0
if _mpexactfltfix(a, &f) == 0 {
return 0
}
// try rounding up a little
for i := 1; i < Mpprec; i++ {
f.Val.A[i]++
if f.Val.A[i] != Mpbase {
break
}
f.Val.A[i] = 0
}
mpnorm(&f)
if _mpexactfltfix(a, &f) == 0 {
return 0
}
return -1
}
func mpmovefixfix(a, b *Mpint) {
a.Val.Set(&b.Val)
}
func _mpmovefixfix(a *Mpfix, b *Mpfix) {
*a = *b
}
......@@ -202,7 +344,7 @@ func mppow10flt(a *Mpflt, p int) {
}
}
func mphextofix(a *Mpint, s string) {
func mphextofix(a *Mpfix, s string) {
for s != "" && s[0] == '0' {
s = s[1:]
}
......@@ -445,16 +587,35 @@ bad:
Mpmovecflt(a, 0.0)
}
func mpatofix(a *Mpint, as string) {
_, ok := a.Val.SetString(as, 0)
if !ok {
// required syntax is [+-][0[x]]d*
// At the moment we lose precise error cause;
// the old code distinguished between:
// - malformed hex constant
// - malformed octal constant
// - malformed decimal constant
// TODO(gri) use different conversion function
Yyerror("malformed integer constant: %s", as)
a.Val.SetUint64(0)
return
}
if mptestovf(a, 0) {
Yyerror("constant too large: %s", as)
}
}
//
// fixed point input
// required syntax is [+-][0[x]]d*
//
func mpatofix(a *Mpint, as string) {
func _mpatofix(a *Mpfix, as string) {
var c int
s := as
f := 0
Mpmovecfix(a, 0)
_Mpmovecfix(a, 0)
c, s = intstarstringplusplus(s)
switch c {
......@@ -525,36 +686,43 @@ func mpatofix(a *Mpint, as string) {
out:
if f != 0 {
mpnegfix(a)
_mpnegfix(a)
}
return
bad:
Mpmovecfix(a, 0)
_Mpmovecfix(a, 0)
}
func Bconv(xval *Mpint, flag int) string {
var q Mpint
if flag&obj.FmtSharp != 0 {
return fmt.Sprintf("%#x", &xval.Val)
}
return xval.Val.String()
}
func _Bconv(xval *Mpfix, flag int) string {
var q Mpfix
mpmovefixfix(&q, xval)
_mpmovefixfix(&q, xval)
f := 0
if mptestfix(&q) < 0 {
f = 1
mpnegfix(&q)
_mpnegfix(&q)
}
var buf [500]byte
p := len(buf)
var r Mpint
var r Mpfix
if flag&obj.FmtSharp != 0 /*untyped*/ {
// Hexadecimal
var sixteen Mpint
Mpmovecfix(&sixteen, 16)
var sixteen Mpfix
_Mpmovecfix(&sixteen, 16)
var digit int
for {
mpdivmodfixfix(&q, &r, &q, &sixteen)
digit = int(Mpgetfix(&r))
digit = int(_Mpgetfix(&r))
if digit < 10 {
p--
buf[p] = byte(digit + '0')
......@@ -573,13 +741,13 @@ func Bconv(xval *Mpint, flag int) string {
buf[p] = '0'
} else {
// Decimal
var ten Mpint
Mpmovecfix(&ten, 10)
var ten Mpfix
_Mpmovecfix(&ten, 10)
for {
mpdivmodfixfix(&q, &r, &q, &ten)
p--
buf[p] = byte(Mpgetfix(&r) + '0')
buf[p] = byte(_Mpgetfix(&r) + '0')
if mptestfix(&q) <= 0 {
break
}
......@@ -646,21 +814,21 @@ func Fconv(fvp *Mpflt, flag int) string {
fv = *fvp
for fv.Val.A[0] == 0 {
Mpshiftfix(&fv.Val, -Mpscale)
_Mpshiftfix(&fv.Val, -Mpscale)
fv.Exp += Mpscale
}
for fv.Val.A[0]&1 == 0 {
Mpshiftfix(&fv.Val, -1)
_Mpshiftfix(&fv.Val, -1)
fv.Exp += 1
}
if fv.Exp >= 0 {
buf = fmt.Sprintf("%vp+%d", Bconv(&fv.Val, obj.FmtSharp), fv.Exp)
buf = fmt.Sprintf("%vp+%d", _Bconv(&fv.Val, obj.FmtSharp), fv.Exp)
goto out
}
buf = fmt.Sprintf("%vp-%d", Bconv(&fv.Val, obj.FmtSharp), -fv.Exp)
buf = fmt.Sprintf("%vp-%d", _Bconv(&fv.Val, obj.FmtSharp), -fv.Exp)
out:
var fp string
......
This diff is collapsed.
......@@ -80,7 +80,7 @@ func mpnorm(a *Mpflt) {
}
}
Mpshiftfix(&a.Val, s)
_Mpshiftfix(&a.Val, s)
mpsetexp(a, int(a.Exp)-s)
}
......@@ -110,21 +110,21 @@ func mpaddfltflt(a *Mpflt, b *Mpflt) {
var c Mpflt
mpmovefltflt(&c, b)
Mpshiftfix(&c.Val, -s)
mpaddfixfix(&a.Val, &c.Val, 0)
_Mpshiftfix(&c.Val, -s)
_mpaddfixfix(&a.Val, &c.Val, 0)
goto out
}
if s < 0 {
// b is larger, shift a right
Mpshiftfix(&a.Val, s)
_Mpshiftfix(&a.Val, s)
mpsetexp(a, int(a.Exp)-s)
mpaddfixfix(&a.Val, &b.Val, 0)
_mpaddfixfix(&a.Val, &b.Val, 0)
goto out
}
mpaddfixfix(&a.Val, &b.Val, 0)
_mpaddfixfix(&a.Val, &b.Val, 0)
out:
mpnorm(a)
......@@ -193,7 +193,7 @@ func mpdivfltflt(a *Mpflt, b *Mpflt) {
var c Mpflt
mpmovefltflt(&c, b)
Mpshiftfix(&c.Val, Mpscale)
_Mpshiftfix(&c.Val, Mpscale)
// divide
mpdivfract(&a.Val, &c.Val)
......@@ -222,7 +222,7 @@ func mpgetfltN(a *Mpflt, prec int, bias int) float64 {
}
for a.Val.A[Mpnorm-1]&Mpsign == 0 {
Mpshiftfix(&a.Val, 1)
_Mpshiftfix(&a.Val, 1)
mpsetexp(a, int(a.Exp)-1) // can set 'a' to zero
s = sigfig(a)
if s == 0 {
......@@ -298,7 +298,7 @@ func Mpmovecflt(a *Mpflt, c float64) {
if Mpdebug != 0 /*TypeKind(100016)*/ {
fmt.Printf("\nconst %g", c)
}
Mpmovecfix(&a.Val, 0)
_Mpmovecfix(&a.Val, 0)
a.Exp = 0
var f float64
var l int
......@@ -323,7 +323,7 @@ func Mpmovecflt(a *Mpflt, c float64) {
if f == 0 {
break
}
Mpshiftfix(&a.Val, Mpscale)
_Mpshiftfix(&a.Val, Mpscale)
}
out:
......
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