mirror of
https://github.com/golang/go
synced 2024-11-20 01:54:41 -07:00
cmd/internal/gc: move fix and flt functions into respective files (cleanups)
Also: - introduce Mpprec (remove old constants) - no semantic changes Change-Id: Ie0e77e8e09bd68e09bcf8747a3d875270e736081 Reviewed-on: https://go-review.googlesource.com/8171 Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
parent
5bb89eb009
commit
5750b7118f
@ -24,8 +24,6 @@ func truncfltlit(oldv *Mpflt, t *Type) *Mpflt {
|
||||
overflow(v, t)
|
||||
|
||||
fv := newMpflt()
|
||||
|
||||
// *fv = *oldv
|
||||
mpmovefltflt(fv, oldv)
|
||||
|
||||
// convert large precision literal floating
|
||||
|
@ -57,9 +57,9 @@ const (
|
||||
)
|
||||
|
||||
const (
|
||||
// TODO(gri) replace these with a single precision constant.
|
||||
Mpscale = 29 // safely smaller than bits in a long
|
||||
Mpprec = 16 // Mpscale*Mpprec is max number of bits
|
||||
// TODO(gri) consider increasing Mpprec to 512 or perhaps 1024
|
||||
// (this would permit enabling additional tests).
|
||||
Mpprec = 16 * 29 // == 464, to match original value
|
||||
Mpdebug = 0
|
||||
)
|
||||
|
||||
|
@ -1,172 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package gc
|
||||
|
||||
import (
|
||||
"cmd/internal/gc/big"
|
||||
"cmd/internal/obj"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func Mpcmpfixfix(a, b *Mpint) int {
|
||||
return a.Val.Cmp(&b.Val)
|
||||
}
|
||||
|
||||
func mpcmpfixc(b *Mpint, c int64) int {
|
||||
return b.Val.Cmp(big.NewInt(c))
|
||||
}
|
||||
|
||||
func mpcmpfltflt(a *Mpflt, b *Mpflt) int {
|
||||
return a.Val.Cmp(&b.Val)
|
||||
}
|
||||
|
||||
func mpcmpfltc(b *Mpflt, c float64) int {
|
||||
var a Mpflt
|
||||
|
||||
Mpmovecflt(&a, c)
|
||||
return mpcmpfltflt(b, &a)
|
||||
}
|
||||
|
||||
func mpsubfixfix(a, b *Mpint) {
|
||||
a.Val.Sub(&a.Val, &b.Val)
|
||||
}
|
||||
|
||||
func mpsubfltflt(a *Mpflt, b *Mpflt) {
|
||||
if Mpdebug != 0 {
|
||||
fmt.Printf("\n%v - %v", Fconv(a, 0), Fconv(b, 0))
|
||||
}
|
||||
|
||||
a.Val.Sub(&a.Val, &b.Val)
|
||||
|
||||
if Mpdebug != 0 {
|
||||
fmt.Printf(" = %v\n\n", Fconv(a, 0))
|
||||
}
|
||||
}
|
||||
|
||||
func mpaddcflt(a *Mpflt, c float64) {
|
||||
var b Mpflt
|
||||
|
||||
Mpmovecflt(&b, c)
|
||||
mpaddfltflt(a, &b)
|
||||
}
|
||||
|
||||
func mpmulcflt(a *Mpflt, c float64) {
|
||||
var b Mpflt
|
||||
|
||||
Mpmovecflt(&b, c)
|
||||
mpmulfltflt(a, &b)
|
||||
}
|
||||
|
||||
func mpdivfixfix(a, b *Mpint) {
|
||||
a.Val.Quo(&a.Val, &b.Val)
|
||||
}
|
||||
|
||||
func mpmodfixfix(a, b *Mpint) {
|
||||
a.Val.Rem(&a.Val, &b.Val)
|
||||
}
|
||||
|
||||
func Mpmovefixflt(a *Mpflt, b *Mpint) {
|
||||
if b.Ovf {
|
||||
// sign doesn't really matter but copy anyway
|
||||
a.Val.SetInf(b.Val.Sign() < 0)
|
||||
return
|
||||
}
|
||||
a.Val.SetInt(&b.Val)
|
||||
}
|
||||
|
||||
func mpmovefltfix(a *Mpint, b *Mpflt) int {
|
||||
if _, acc := b.Val.Int(&a.Val); acc == big.Exact {
|
||||
return 0
|
||||
}
|
||||
|
||||
const delta = Mpscale // a reasonably small number of bits > 0
|
||||
var t big.Float
|
||||
t.SetPrec(Mpscale*Mpprec - delta)
|
||||
|
||||
// try rounding down a little
|
||||
t.SetMode(big.ToZero)
|
||||
t.Set(&b.Val)
|
||||
if _, acc := t.Int(&a.Val); acc == big.Exact {
|
||||
return 0
|
||||
}
|
||||
|
||||
// try rounding up a little
|
||||
t.SetMode(big.AwayFromZero)
|
||||
t.Set(&b.Val)
|
||||
if _, acc := t.Int(&a.Val); acc == big.Exact {
|
||||
return 0
|
||||
}
|
||||
|
||||
return -1
|
||||
}
|
||||
|
||||
func mpmovefixfix(a, b *Mpint) {
|
||||
a.Val.Set(&b.Val)
|
||||
}
|
||||
|
||||
func mpmovefltflt(a *Mpflt, b *Mpflt) {
|
||||
a.Val.Set(&b.Val)
|
||||
}
|
||||
|
||||
//
|
||||
// floating point input
|
||||
// required syntax is [+-]d*[.]d*[e[+-]d*] or [+-]0xH*[e[+-]d*]
|
||||
//
|
||||
func mpatoflt(a *Mpflt, as string) {
|
||||
for len(as) > 0 && (as[0] == ' ' || as[0] == '\t') {
|
||||
as = as[1:]
|
||||
}
|
||||
|
||||
f, ok := a.Val.SetString(as)
|
||||
if !ok {
|
||||
// At the moment we lose precise error cause;
|
||||
// the old code additionally distinguished between:
|
||||
// - malformed hex constant
|
||||
// - decimal point in hex constant
|
||||
// - constant exponent out of range
|
||||
// - decimal point and binary point in constant
|
||||
// TODO(gri) use different conversion function or check separately
|
||||
Yyerror("malformed constant: %s", as)
|
||||
a.Val.SetUint64(0)
|
||||
}
|
||||
|
||||
if f.IsInf() {
|
||||
Yyerror("constant too large: %s", as)
|
||||
a.Val.SetUint64(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)
|
||||
}
|
||||
}
|
||||
|
||||
func Bconv(xval *Mpint, flag int) string {
|
||||
if flag&obj.FmtSharp != 0 {
|
||||
return fmt.Sprintf("%#x", &xval.Val)
|
||||
}
|
||||
return xval.Val.String()
|
||||
}
|
||||
|
||||
func Fconv(fvp *Mpflt, flag int) string {
|
||||
if flag&obj.FmtSharp != 0 {
|
||||
return fvp.Val.Format('g', 6)
|
||||
}
|
||||
return fvp.Val.Format('b', 0)
|
||||
}
|
@ -4,19 +4,11 @@
|
||||
|
||||
package gc
|
||||
|
||||
// shift left by s (or right by -s)
|
||||
func Mpshiftfix(a *Mpint, s int) {
|
||||
switch {
|
||||
case s > 0:
|
||||
if mptestovf(a, s) {
|
||||
Yyerror("constant shift overflow")
|
||||
return
|
||||
}
|
||||
a.Val.Lsh(&a.Val, uint(s))
|
||||
case s < 0:
|
||||
a.Val.Rsh(&a.Val, uint(-s))
|
||||
}
|
||||
}
|
||||
import (
|
||||
"cmd/internal/gc/big"
|
||||
"cmd/internal/obj"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
/// implements fix arithmetic
|
||||
|
||||
@ -28,17 +20,49 @@ func mpsetovf(a *Mpint) {
|
||||
func mptestovf(a *Mpint, extra int) bool {
|
||||
// We don't need to be precise here, any reasonable upper limit would do.
|
||||
// For now, use existing limit so we pass all the tests unchanged.
|
||||
const limit = Mpscale * Mpprec
|
||||
if a.Val.BitLen()+extra > limit {
|
||||
if a.Val.BitLen()+extra > Mpprec {
|
||||
mpsetovf(a)
|
||||
}
|
||||
return a.Ovf
|
||||
}
|
||||
|
||||
func mpmovefixfix(a, b *Mpint) {
|
||||
a.Val.Set(&b.Val)
|
||||
}
|
||||
|
||||
func mpmovefltfix(a *Mpint, b *Mpflt) int {
|
||||
if _, acc := b.Val.Int(&a.Val); acc == big.Exact {
|
||||
return 0
|
||||
}
|
||||
|
||||
// TODO(gri) reduce the value of delta - currently
|
||||
// we use the size of a mp-word of the old implementation
|
||||
// for approximately similar behavior.
|
||||
const delta = 29 // a reasonably small number of bits > 0
|
||||
var t big.Float
|
||||
t.SetPrec(Mpprec - delta)
|
||||
|
||||
// try rounding down a little
|
||||
t.SetMode(big.ToZero)
|
||||
t.Set(&b.Val)
|
||||
if _, acc := t.Int(&a.Val); acc == big.Exact {
|
||||
return 0
|
||||
}
|
||||
|
||||
// try rounding up a little
|
||||
t.SetMode(big.AwayFromZero)
|
||||
t.Set(&b.Val)
|
||||
if _, acc := t.Int(&a.Val); acc == big.Exact {
|
||||
return 0
|
||||
}
|
||||
|
||||
return -1
|
||||
}
|
||||
|
||||
func mpaddfixfix(a, b *Mpint, quiet int) {
|
||||
if a.Ovf || b.Ovf {
|
||||
if nsavederrors+nerrors == 0 {
|
||||
Yyerror("ovf in mpaddxx")
|
||||
Yyerror("ovf in mpaddfixfix")
|
||||
}
|
||||
mpsetovf(a)
|
||||
return
|
||||
@ -51,6 +75,22 @@ func mpaddfixfix(a, b *Mpint, quiet int) {
|
||||
}
|
||||
}
|
||||
|
||||
func mpsubfixfix(a, b *Mpint) {
|
||||
if a.Ovf || b.Ovf {
|
||||
if nsavederrors+nerrors == 0 {
|
||||
Yyerror("ovf in mpsubfixfix")
|
||||
}
|
||||
mpsetovf(a)
|
||||
return
|
||||
}
|
||||
|
||||
a.Val.Sub(&a.Val, &b.Val)
|
||||
|
||||
if mptestovf(a, 0) {
|
||||
Yyerror("constant subtraction overflow")
|
||||
}
|
||||
}
|
||||
|
||||
func mpmulfixfix(a, b *Mpint) {
|
||||
if a.Ovf || b.Ovf {
|
||||
if nsavederrors+nerrors == 0 {
|
||||
@ -67,6 +107,40 @@ func mpmulfixfix(a, b *Mpint) {
|
||||
}
|
||||
}
|
||||
|
||||
func mpdivfixfix(a, b *Mpint) {
|
||||
if a.Ovf || b.Ovf {
|
||||
if nsavederrors+nerrors == 0 {
|
||||
Yyerror("ovf in mpdivfixfix")
|
||||
}
|
||||
mpsetovf(a)
|
||||
return
|
||||
}
|
||||
|
||||
a.Val.Quo(&a.Val, &b.Val)
|
||||
|
||||
if mptestovf(a, 0) {
|
||||
// can only happen for div-0 which should be checked elsewhere
|
||||
Yyerror("constant division overflow")
|
||||
}
|
||||
}
|
||||
|
||||
func mpmodfixfix(a, b *Mpint) {
|
||||
if a.Ovf || b.Ovf {
|
||||
if nsavederrors+nerrors == 0 {
|
||||
Yyerror("ovf in mpmodfixfix")
|
||||
}
|
||||
mpsetovf(a)
|
||||
return
|
||||
}
|
||||
|
||||
a.Val.Rem(&a.Val, &b.Val)
|
||||
|
||||
if mptestovf(a, 0) {
|
||||
// should never happen
|
||||
Yyerror("constant modulo overflow")
|
||||
}
|
||||
}
|
||||
|
||||
func mporfixfix(a, b *Mpint) {
|
||||
if a.Ovf || b.Ovf {
|
||||
if nsavederrors+nerrors == 0 {
|
||||
@ -115,6 +189,20 @@ func mpxorfixfix(a, b *Mpint) {
|
||||
a.Val.Xor(&a.Val, &b.Val)
|
||||
}
|
||||
|
||||
// shift left by s (or right by -s)
|
||||
func Mpshiftfix(a *Mpint, s int) {
|
||||
switch {
|
||||
case s > 0:
|
||||
if mptestovf(a, s) {
|
||||
Yyerror("constant shift overflow")
|
||||
return
|
||||
}
|
||||
a.Val.Lsh(&a.Val, uint(s))
|
||||
case s < 0:
|
||||
a.Val.Rsh(&a.Val, uint(-s))
|
||||
}
|
||||
}
|
||||
|
||||
func mplshfixfix(a, b *Mpint) {
|
||||
if a.Ovf || b.Ovf {
|
||||
if nsavederrors+nerrors == 0 {
|
||||
@ -125,7 +213,7 @@ func mplshfixfix(a, b *Mpint) {
|
||||
}
|
||||
|
||||
s := Mpgetfix(b)
|
||||
if s < 0 || s >= Mpprec*Mpscale {
|
||||
if s < 0 || s >= Mpprec {
|
||||
Yyerror("stupid shift: %d", s)
|
||||
Mpmovecfix(a, 0)
|
||||
return
|
||||
@ -144,7 +232,7 @@ func mprshfixfix(a, b *Mpint) {
|
||||
}
|
||||
|
||||
s := Mpgetfix(b)
|
||||
if s < 0 || s >= Mpprec*Mpscale {
|
||||
if s < 0 || s >= Mpprec {
|
||||
Yyerror("stupid shift: %d", s)
|
||||
if a.Val.Sign() < 0 {
|
||||
Mpmovecfix(a, -1)
|
||||
@ -157,6 +245,14 @@ func mprshfixfix(a, b *Mpint) {
|
||||
Mpshiftfix(a, int(-s))
|
||||
}
|
||||
|
||||
func Mpcmpfixfix(a, b *Mpint) int {
|
||||
return a.Val.Cmp(&b.Val)
|
||||
}
|
||||
|
||||
func mpcmpfixc(b *Mpint, c int64) int {
|
||||
return b.Val.Cmp(big.NewInt(c))
|
||||
}
|
||||
|
||||
func mpnegfix(a *Mpint) {
|
||||
a.Val.Neg(&a.Val)
|
||||
}
|
||||
@ -175,3 +271,29 @@ func Mpgetfix(a *Mpint) int64 {
|
||||
func Mpmovecfix(a *Mpint, c int64) {
|
||||
a.Val.SetInt64(c)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
func Bconv(xval *Mpint, flag int) string {
|
||||
if flag&obj.FmtSharp != 0 {
|
||||
return fmt.Sprintf("%#x", &xval.Val)
|
||||
}
|
||||
return xval.Val.String()
|
||||
}
|
||||
|
@ -5,17 +5,31 @@
|
||||
package gc
|
||||
|
||||
import (
|
||||
"cmd/internal/obj"
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
/// implements float arihmetic
|
||||
|
||||
func newMpflt() *Mpflt {
|
||||
var a Mpflt
|
||||
a.Val.SetPrec(Mpscale * Mpprec)
|
||||
a.Val.SetPrec(Mpprec)
|
||||
return &a
|
||||
}
|
||||
|
||||
/// implements float arihmetic
|
||||
func Mpmovefixflt(a *Mpflt, b *Mpint) {
|
||||
if b.Ovf {
|
||||
// sign doesn't really matter but copy anyway
|
||||
a.Val.SetInf(b.Val.Sign() < 0)
|
||||
return
|
||||
}
|
||||
a.Val.SetInt(&b.Val)
|
||||
}
|
||||
|
||||
func mpmovefltflt(a *Mpflt, b *Mpflt) {
|
||||
a.Val.Set(&b.Val)
|
||||
}
|
||||
|
||||
func mpaddfltflt(a *Mpflt, b *Mpflt) {
|
||||
if Mpdebug != 0 {
|
||||
@ -29,6 +43,25 @@ func mpaddfltflt(a *Mpflt, b *Mpflt) {
|
||||
}
|
||||
}
|
||||
|
||||
func mpaddcflt(a *Mpflt, c float64) {
|
||||
var b Mpflt
|
||||
|
||||
Mpmovecflt(&b, c)
|
||||
mpaddfltflt(a, &b)
|
||||
}
|
||||
|
||||
func mpsubfltflt(a *Mpflt, b *Mpflt) {
|
||||
if Mpdebug != 0 {
|
||||
fmt.Printf("\n%v - %v", Fconv(a, 0), Fconv(b, 0))
|
||||
}
|
||||
|
||||
a.Val.Sub(&a.Val, &b.Val)
|
||||
|
||||
if Mpdebug != 0 {
|
||||
fmt.Printf(" = %v\n\n", Fconv(a, 0))
|
||||
}
|
||||
}
|
||||
|
||||
func mpmulfltflt(a *Mpflt, b *Mpflt) {
|
||||
if Mpdebug != 0 {
|
||||
fmt.Printf("%v\n * %v\n", Fconv(a, 0), Fconv(b, 0))
|
||||
@ -41,6 +74,13 @@ func mpmulfltflt(a *Mpflt, b *Mpflt) {
|
||||
}
|
||||
}
|
||||
|
||||
func mpmulcflt(a *Mpflt, c float64) {
|
||||
var b Mpflt
|
||||
|
||||
Mpmovecflt(&b, c)
|
||||
mpmulfltflt(a, &b)
|
||||
}
|
||||
|
||||
func mpdivfltflt(a *Mpflt, b *Mpflt) {
|
||||
if Mpdebug != 0 {
|
||||
fmt.Printf("%v\n / %v\n", Fconv(a, 0), Fconv(b, 0))
|
||||
@ -53,6 +93,17 @@ func mpdivfltflt(a *Mpflt, b *Mpflt) {
|
||||
}
|
||||
}
|
||||
|
||||
func mpcmpfltflt(a *Mpflt, b *Mpflt) int {
|
||||
return a.Val.Cmp(&b.Val)
|
||||
}
|
||||
|
||||
func mpcmpfltc(b *Mpflt, c float64) int {
|
||||
var a Mpflt
|
||||
|
||||
Mpmovecflt(&a, c)
|
||||
return mpcmpfltflt(b, &a)
|
||||
}
|
||||
|
||||
func mpgetfltN(a *Mpflt, prec int, bias int) float64 {
|
||||
var x float64
|
||||
switch prec {
|
||||
@ -103,3 +154,38 @@ func Mpmovecflt(a *Mpflt, c float64) {
|
||||
func mpnegflt(a *Mpflt) {
|
||||
a.Val.Neg(&a.Val)
|
||||
}
|
||||
|
||||
//
|
||||
// floating point input
|
||||
// required syntax is [+-]d*[.]d*[e[+-]d*] or [+-]0xH*[e[+-]d*]
|
||||
//
|
||||
func mpatoflt(a *Mpflt, as string) {
|
||||
for len(as) > 0 && (as[0] == ' ' || as[0] == '\t') {
|
||||
as = as[1:]
|
||||
}
|
||||
|
||||
f, ok := a.Val.SetString(as)
|
||||
if !ok {
|
||||
// At the moment we lose precise error cause;
|
||||
// the old code additionally distinguished between:
|
||||
// - malformed hex constant
|
||||
// - decimal point in hex constant
|
||||
// - constant exponent out of range
|
||||
// - decimal point and binary point in constant
|
||||
// TODO(gri) use different conversion function or check separately
|
||||
Yyerror("malformed constant: %s", as)
|
||||
a.Val.SetUint64(0)
|
||||
}
|
||||
|
||||
if f.IsInf() {
|
||||
Yyerror("constant too large: %s", as)
|
||||
a.Val.SetUint64(0)
|
||||
}
|
||||
}
|
||||
|
||||
func Fconv(fvp *Mpflt, flag int) string {
|
||||
if flag&obj.FmtSharp != 0 {
|
||||
return fvp.Val.Format('g', 6)
|
||||
}
|
||||
return fvp.Val.Format('b', 0)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user