diff options
author | Ian Lance Taylor <iant@golang.org> | 2022-02-11 14:53:56 -0800 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2022-02-11 15:01:19 -0800 |
commit | 8dc2499aa62f768c6395c9754b8cabc1ce25c494 (patch) | |
tree | 43d7fd2bbfd7ad8c9625a718a5e8718889351994 /libgo/go/math | |
parent | 9a56779dbc4e2d9c15be8d31e36f2f59be7331a8 (diff) | |
download | gcc-8dc2499aa62f768c6395c9754b8cabc1ce25c494.zip gcc-8dc2499aa62f768c6395c9754b8cabc1ce25c494.tar.gz gcc-8dc2499aa62f768c6395c9754b8cabc1ce25c494.tar.bz2 |
libgo: update to Go1.18beta2
gotools/
* Makefile.am (go_cmd_cgo_files): Add ast_go118.go
(check-go-tool): Copy golang.org/x/tools directories.
* Makefile.in: Regenerate.
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/384695
Diffstat (limited to 'libgo/go/math')
-rw-r--r-- | libgo/go/math/all_test.go | 2 | ||||
-rw-r--r-- | libgo/go/math/big/float.go | 4 | ||||
-rw-r--r-- | libgo/go/math/big/floatconv_test.go | 2 | ||||
-rw-r--r-- | libgo/go/math/big/rat.go | 2 | ||||
-rw-r--r-- | libgo/go/math/big/rat_test.go | 18 | ||||
-rw-r--r-- | libgo/go/math/big/ratconv.go | 5 | ||||
-rw-r--r-- | libgo/go/math/big/ratconv_test.go | 1 | ||||
-rw-r--r-- | libgo/go/math/bits/example_math_test.go | 202 | ||||
-rw-r--r-- | libgo/go/math/bits/make_examples.go | 20 | ||||
-rw-r--r-- | libgo/go/math/cmplx/huge_test.go | 1 | ||||
-rw-r--r-- | libgo/go/math/dim_noasm.go | 1 | ||||
-rw-r--r-- | libgo/go/math/example_test.go | 5 | ||||
-rw-r--r-- | libgo/go/math/exp2_noasm.go | 1 | ||||
-rw-r--r-- | libgo/go/math/exp_amd64.go | 1 | ||||
-rw-r--r-- | libgo/go/math/exp_noasm.go | 1 | ||||
-rw-r--r-- | libgo/go/math/floor_noasm.go | 1 | ||||
-rw-r--r-- | libgo/go/math/huge_test.go | 1 | ||||
-rw-r--r-- | libgo/go/math/modf_noasm.go | 1 | ||||
-rw-r--r-- | libgo/go/math/rand/gen_cooked.go | 1 | ||||
-rw-r--r-- | libgo/go/math/rand/regress_test.go | 6 | ||||
-rw-r--r-- | libgo/go/math/stubs.go | 1 |
21 files changed, 250 insertions, 27 deletions
diff --git a/libgo/go/math/all_test.go b/libgo/go/math/all_test.go index 55c805e..c11d823 100644 --- a/libgo/go/math/all_test.go +++ b/libgo/go/math/all_test.go @@ -3175,7 +3175,7 @@ func TestTrigReduce(t *testing.T) { // https://golang.org/issue/201 type floatTest struct { - val interface{} + val any name string str string } diff --git a/libgo/go/math/big/float.go b/libgo/go/math/big/float.go index 42050e2..a8c91a6 100644 --- a/libgo/go/math/big/float.go +++ b/libgo/go/math/big/float.go @@ -304,7 +304,9 @@ func (z *Float) setExpAndRound(exp int64, sbit uint) { // SetMantExp sets z to mant × 2**exp and returns z. // The result z has the same precision and rounding mode // as mant. SetMantExp is an inverse of MantExp but does -// not require 0.5 <= |mant| < 1.0. Specifically: +// not require 0.5 <= |mant| < 1.0. Specifically, for a +// given x of type *Float, SetMantExp relates to MantExp +// as follows: // // mant := new(Float) // new(Float).SetMantExp(mant, x.MantExp(mant)).Cmp(x) == 0 diff --git a/libgo/go/math/big/floatconv_test.go b/libgo/go/math/big/floatconv_test.go index 3aa6834..a1cc38a 100644 --- a/libgo/go/math/big/floatconv_test.go +++ b/libgo/go/math/big/floatconv_test.go @@ -576,7 +576,7 @@ func TestFloatText(t *testing.T) { func TestFloatFormat(t *testing.T) { for _, test := range []struct { format string - value interface{} // float32, float64, or string (== 512bit *Float) + value any // float32, float64, or string (== 512bit *Float) want string }{ // from fmt/fmt_test.go diff --git a/libgo/go/math/big/rat.go b/libgo/go/math/big/rat.go index d35cd4c..731a979 100644 --- a/libgo/go/math/big/rat.go +++ b/libgo/go/math/big/rat.go @@ -418,7 +418,7 @@ func (x *Rat) Num() *Int { // If the result is a reference to x's denominator it // may change if a new value is assigned to x, and vice versa. func (x *Rat) Denom() *Int { - x.b.neg = false // the result is always >= 0 + // Note that x.b.neg is guaranteed false. if len(x.b.abs) == 0 { // Note: If this proves problematic, we could // panic instead and require the Rat to diff --git a/libgo/go/math/big/rat_test.go b/libgo/go/math/big/rat_test.go index 02569c1..d98c89b 100644 --- a/libgo/go/math/big/rat_test.go +++ b/libgo/go/math/big/rat_test.go @@ -726,3 +726,21 @@ func TestIssue34919(t *testing.T) { } } } + +func TestDenomRace(t *testing.T) { + x := NewRat(1, 2) + const N = 3 + c := make(chan bool, N) + for i := 0; i < N; i++ { + go func() { + // Denom (also used by Float.SetRat) used to mutate x unnecessarily, + // provoking race reports when run in the race detector. + x.Denom() + new(Float).SetRat(x) + c <- true + }() + } + for i := 0; i < N; i++ { + <-c + } +} diff --git a/libgo/go/math/big/ratconv.go b/libgo/go/math/big/ratconv.go index ac3c8bd..90053a9 100644 --- a/libgo/go/math/big/ratconv.go +++ b/libgo/go/math/big/ratconv.go @@ -169,6 +169,11 @@ func (z *Rat) SetString(s string) (*Rat, bool) { n := exp5 if n < 0 { n = -n + if n < 0 { + // This can occur if -n overflows. -(-1 << 63) would become + // -1 << 63, which is still negative. + return nil, false + } } if n > 1e6 { return nil, false // avoid excessively large exponents diff --git a/libgo/go/math/big/ratconv_test.go b/libgo/go/math/big/ratconv_test.go index 15d206c..e55e655 100644 --- a/libgo/go/math/big/ratconv_test.go +++ b/libgo/go/math/big/ratconv_test.go @@ -104,6 +104,7 @@ var setStringTests = []StringTest{ {in: "4/3/"}, {in: "4/3."}, {in: "4/"}, + {in: "13e-9223372036854775808"}, // CVE-2022-23772 // valid {"0", "0", true}, diff --git a/libgo/go/math/bits/example_math_test.go b/libgo/go/math/bits/example_math_test.go new file mode 100644 index 0000000..4bb466f --- /dev/null +++ b/libgo/go/math/bits/example_math_test.go @@ -0,0 +1,202 @@ +// Copyright 2021 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 bits_test + +import ( + "fmt" + "math/bits" +) + +func ExampleAdd32() { + // First number is 33<<32 + 12 + n1 := []uint32{33, 12} + // Second number is 21<<32 + 23 + n2 := []uint32{21, 23} + // Add them together without producing carry. + d1, carry := bits.Add32(n1[1], n2[1], 0) + d0, _ := bits.Add32(n1[0], n2[0], carry) + nsum := []uint32{d0, d1} + fmt.Printf("%v + %v = %v (carry bit was %v)\n", n1, n2, nsum, carry) + + // First number is 1<<32 + 2147483648 + n1 = []uint32{1, 0x80000000} + // Second number is 1<<32 + 2147483648 + n2 = []uint32{1, 0x80000000} + // Add them together producing carry. + d1, carry = bits.Add32(n1[1], n2[1], 0) + d0, _ = bits.Add32(n1[0], n2[0], carry) + nsum = []uint32{d0, d1} + fmt.Printf("%v + %v = %v (carry bit was %v)\n", n1, n2, nsum, carry) + // Output: + // [33 12] + [21 23] = [54 35] (carry bit was 0) + // [1 2147483648] + [1 2147483648] = [3 0] (carry bit was 1) +} + +func ExampleAdd64() { + // First number is 33<<64 + 12 + n1 := []uint64{33, 12} + // Second number is 21<<64 + 23 + n2 := []uint64{21, 23} + // Add them together without producing carry. + d1, carry := bits.Add64(n1[1], n2[1], 0) + d0, _ := bits.Add64(n1[0], n2[0], carry) + nsum := []uint64{d0, d1} + fmt.Printf("%v + %v = %v (carry bit was %v)\n", n1, n2, nsum, carry) + + // First number is 1<<64 + 9223372036854775808 + n1 = []uint64{1, 0x8000000000000000} + // Second number is 1<<64 + 9223372036854775808 + n2 = []uint64{1, 0x8000000000000000} + // Add them together producing carry. + d1, carry = bits.Add64(n1[1], n2[1], 0) + d0, _ = bits.Add64(n1[0], n2[0], carry) + nsum = []uint64{d0, d1} + fmt.Printf("%v + %v = %v (carry bit was %v)\n", n1, n2, nsum, carry) + // Output: + // [33 12] + [21 23] = [54 35] (carry bit was 0) + // [1 9223372036854775808] + [1 9223372036854775808] = [3 0] (carry bit was 1) +} + +func ExampleSub32() { + // First number is 33<<32 + 23 + n1 := []uint32{33, 23} + // Second number is 21<<32 + 12 + n2 := []uint32{21, 12} + // Sub them together without producing carry. + d1, carry := bits.Sub32(n1[1], n2[1], 0) + d0, _ := bits.Sub32(n1[0], n2[0], carry) + nsum := []uint32{d0, d1} + fmt.Printf("%v - %v = %v (carry bit was %v)\n", n1, n2, nsum, carry) + + // First number is 3<<32 + 2147483647 + n1 = []uint32{3, 0x7fffffff} + // Second number is 1<<32 + 2147483648 + n2 = []uint32{1, 0x80000000} + // Sub them together producing carry. + d1, carry = bits.Sub32(n1[1], n2[1], 0) + d0, _ = bits.Sub32(n1[0], n2[0], carry) + nsum = []uint32{d0, d1} + fmt.Printf("%v - %v = %v (carry bit was %v)\n", n1, n2, nsum, carry) + // Output: + // [33 23] - [21 12] = [12 11] (carry bit was 0) + // [3 2147483647] - [1 2147483648] = [1 4294967295] (carry bit was 1) +} + +func ExampleSub64() { + // First number is 33<<64 + 23 + n1 := []uint64{33, 23} + // Second number is 21<<64 + 12 + n2 := []uint64{21, 12} + // Sub them together without producing carry. + d1, carry := bits.Sub64(n1[1], n2[1], 0) + d0, _ := bits.Sub64(n1[0], n2[0], carry) + nsum := []uint64{d0, d1} + fmt.Printf("%v - %v = %v (carry bit was %v)\n", n1, n2, nsum, carry) + + // First number is 3<<64 + 9223372036854775807 + n1 = []uint64{3, 0x7fffffffffffffff} + // Second number is 1<<64 + 9223372036854775808 + n2 = []uint64{1, 0x8000000000000000} + // Sub them together producing carry. + d1, carry = bits.Sub64(n1[1], n2[1], 0) + d0, _ = bits.Sub64(n1[0], n2[0], carry) + nsum = []uint64{d0, d1} + fmt.Printf("%v - %v = %v (carry bit was %v)\n", n1, n2, nsum, carry) + // Output: + // [33 23] - [21 12] = [12 11] (carry bit was 0) + // [3 9223372036854775807] - [1 9223372036854775808] = [1 18446744073709551615] (carry bit was 1) +} + +func ExampleMul32() { + // First number is 0<<32 + 12 + n1 := []uint32{0, 12} + // Second number is 0<<32 + 12 + n2 := []uint32{0, 12} + // Multiply them together without producing overflow. + hi, lo := bits.Mul32(n1[1], n2[1]) + nsum := []uint32{hi, lo} + fmt.Printf("%v * %v = %v\n", n1[1], n2[1], nsum) + + // First number is 0<<32 + 2147483648 + n1 = []uint32{0, 0x80000000} + // Second number is 0<<32 + 2 + n2 = []uint32{0, 2} + // Multiply them together producing overflow. + hi, lo = bits.Mul32(n1[1], n2[1]) + nsum = []uint32{hi, lo} + fmt.Printf("%v * %v = %v\n", n1[1], n2[1], nsum) + // Output: + // 12 * 12 = [0 144] + // 2147483648 * 2 = [1 0] +} + +func ExampleMul64() { + // First number is 0<<64 + 12 + n1 := []uint64{0, 12} + // Second number is 0<<64 + 12 + n2 := []uint64{0, 12} + // Multiply them together without producing overflow. + hi, lo := bits.Mul64(n1[1], n2[1]) + nsum := []uint64{hi, lo} + fmt.Printf("%v * %v = %v\n", n1[1], n2[1], nsum) + + // First number is 0<<64 + 9223372036854775808 + n1 = []uint64{0, 0x8000000000000000} + // Second number is 0<<64 + 2 + n2 = []uint64{0, 2} + // Multiply them together producing overflow. + hi, lo = bits.Mul64(n1[1], n2[1]) + nsum = []uint64{hi, lo} + fmt.Printf("%v * %v = %v\n", n1[1], n2[1], nsum) + // Output: + // 12 * 12 = [0 144] + // 9223372036854775808 * 2 = [1 0] +} + +func ExampleDiv32() { + // First number is 0<<32 + 6 + n1 := []uint32{0, 6} + // Second number is 0<<32 + 3 + n2 := []uint32{0, 3} + // Divide them together. + quo, rem := bits.Div32(n1[0], n1[1], n2[1]) + nsum := []uint32{quo, rem} + fmt.Printf("[%v %v] / %v = %v\n", n1[0], n1[1], n2[1], nsum) + + // First number is 2<<32 + 2147483648 + n1 = []uint32{2, 0x80000000} + // Second number is 0<<32 + 2147483648 + n2 = []uint32{0, 0x80000000} + // Divide them together. + quo, rem = bits.Div32(n1[0], n1[1], n2[1]) + nsum = []uint32{quo, rem} + fmt.Printf("[%v %v] / %v = %v\n", n1[0], n1[1], n2[1], nsum) + // Output: + // [0 6] / 3 = [2 0] + // [2 2147483648] / 2147483648 = [5 0] +} + +func ExampleDiv64() { + // First number is 0<<64 + 6 + n1 := []uint64{0, 6} + // Second number is 0<<64 + 3 + n2 := []uint64{0, 3} + // Divide them together. + quo, rem := bits.Div64(n1[0], n1[1], n2[1]) + nsum := []uint64{quo, rem} + fmt.Printf("[%v %v] / %v = %v\n", n1[0], n1[1], n2[1], nsum) + + // First number is 2<<64 + 9223372036854775808 + n1 = []uint64{2, 0x8000000000000000} + // Second number is 0<<64 + 9223372036854775808 + n2 = []uint64{0, 0x8000000000000000} + // Divide them together. + quo, rem = bits.Div64(n1[0], n1[1], n2[1]) + nsum = []uint64{quo, rem} + fmt.Printf("[%v %v] / %v = %v\n", n1[0], n1[1], n2[1], nsum) + // Output: + // [0 6] / 3 = [2 0] + // [2 9223372036854775808] / 9223372036854775808 = [5 0] +} diff --git a/libgo/go/math/bits/make_examples.go b/libgo/go/math/bits/make_examples.go index ac4004d..92e9aab 100644 --- a/libgo/go/math/bits/make_examples.go +++ b/libgo/go/math/bits/make_examples.go @@ -37,44 +37,44 @@ func main() { for _, e := range []struct { name string in int - out [4]interface{} - out2 [4]interface{} + out [4]any + out2 [4]any }{ { name: "LeadingZeros", in: 1, - out: [4]interface{}{bits.LeadingZeros8(1), bits.LeadingZeros16(1), bits.LeadingZeros32(1), bits.LeadingZeros64(1)}, + out: [4]any{bits.LeadingZeros8(1), bits.LeadingZeros16(1), bits.LeadingZeros32(1), bits.LeadingZeros64(1)}, }, { name: "TrailingZeros", in: 14, - out: [4]interface{}{bits.TrailingZeros8(14), bits.TrailingZeros16(14), bits.TrailingZeros32(14), bits.TrailingZeros64(14)}, + out: [4]any{bits.TrailingZeros8(14), bits.TrailingZeros16(14), bits.TrailingZeros32(14), bits.TrailingZeros64(14)}, }, { name: "OnesCount", in: 14, - out: [4]interface{}{bits.OnesCount8(14), bits.OnesCount16(14), bits.OnesCount32(14), bits.OnesCount64(14)}, + out: [4]any{bits.OnesCount8(14), bits.OnesCount16(14), bits.OnesCount32(14), bits.OnesCount64(14)}, }, { name: "RotateLeft", in: 15, - out: [4]interface{}{bits.RotateLeft8(15, 2), bits.RotateLeft16(15, 2), bits.RotateLeft32(15, 2), bits.RotateLeft64(15, 2)}, - out2: [4]interface{}{bits.RotateLeft8(15, -2), bits.RotateLeft16(15, -2), bits.RotateLeft32(15, -2), bits.RotateLeft64(15, -2)}, + out: [4]any{bits.RotateLeft8(15, 2), bits.RotateLeft16(15, 2), bits.RotateLeft32(15, 2), bits.RotateLeft64(15, 2)}, + out2: [4]any{bits.RotateLeft8(15, -2), bits.RotateLeft16(15, -2), bits.RotateLeft32(15, -2), bits.RotateLeft64(15, -2)}, }, { name: "Reverse", in: 19, - out: [4]interface{}{bits.Reverse8(19), bits.Reverse16(19), bits.Reverse32(19), bits.Reverse64(19)}, + out: [4]any{bits.Reverse8(19), bits.Reverse16(19), bits.Reverse32(19), bits.Reverse64(19)}, }, { name: "ReverseBytes", in: 15, - out: [4]interface{}{nil, bits.ReverseBytes16(15), bits.ReverseBytes32(15), bits.ReverseBytes64(15)}, + out: [4]any{nil, bits.ReverseBytes16(15), bits.ReverseBytes32(15), bits.ReverseBytes64(15)}, }, { name: "Len", in: 8, - out: [4]interface{}{bits.Len8(8), bits.Len16(8), bits.Len32(8), bits.Len64(8)}, + out: [4]any{bits.Len8(8), bits.Len16(8), bits.Len32(8), bits.Len64(8)}, }, } { for i, size := range []int{8, 16, 32, 64} { diff --git a/libgo/go/math/cmplx/huge_test.go b/libgo/go/math/cmplx/huge_test.go index 78b4231..e794cf2 100644 --- a/libgo/go/math/cmplx/huge_test.go +++ b/libgo/go/math/cmplx/huge_test.go @@ -6,7 +6,6 @@ // accurate for huge arguments. //go:build !s390x -// +build !s390x package cmplx diff --git a/libgo/go/math/dim_noasm.go b/libgo/go/math/dim_noasm.go index 9a052c0..58d0714 100644 --- a/libgo/go/math/dim_noasm.go +++ b/libgo/go/math/dim_noasm.go @@ -3,7 +3,6 @@ // license that can be found in the LICENSE file. //-go:build !amd64 && !arm64 && !riscv64 && !s390x -// -build !amd64,!arm64,!riscv64,!s390x package math diff --git a/libgo/go/math/example_test.go b/libgo/go/math/example_test.go index 9fc1967..a26d8cb 100644 --- a/libgo/go/math/example_test.go +++ b/libgo/go/math/example_test.go @@ -162,6 +162,11 @@ func ExampleLog10() { // Output: 2.0 } +func ExampleRemainder() { + fmt.Printf("%.1f", math.Remainder(100, 30)) + // Output: 10.0 +} + func ExampleMod() { c := math.Mod(7, 4) fmt.Printf("%.1f", c) diff --git a/libgo/go/math/exp2_noasm.go b/libgo/go/math/exp2_noasm.go index 9b81544..36791ce 100644 --- a/libgo/go/math/exp2_noasm.go +++ b/libgo/go/math/exp2_noasm.go @@ -3,7 +3,6 @@ // license that can be found in the LICENSE file. //-go:build !arm64 -// -build !arm64 package math diff --git a/libgo/go/math/exp_amd64.go b/libgo/go/math/exp_amd64.go index 654ccce..0f701b1 100644 --- a/libgo/go/math/exp_amd64.go +++ b/libgo/go/math/exp_amd64.go @@ -3,7 +3,6 @@ // license that can be found in the LICENSE file. //go:build amd64 -// +build amd64 package math diff --git a/libgo/go/math/exp_noasm.go b/libgo/go/math/exp_noasm.go index 4f90604..52f72e2 100644 --- a/libgo/go/math/exp_noasm.go +++ b/libgo/go/math/exp_noasm.go @@ -3,7 +3,6 @@ // license that can be found in the LICENSE file. //-go:build !amd64 && !arm64 && !s390x -// -build !amd64,!arm64,!s390x package math diff --git a/libgo/go/math/floor_noasm.go b/libgo/go/math/floor_noasm.go index bcdc5b0..c0711c4 100644 --- a/libgo/go/math/floor_noasm.go +++ b/libgo/go/math/floor_noasm.go @@ -3,7 +3,6 @@ // license that can be found in the LICENSE file. //-go:build !386 && !amd64 && !arm64 && !ppc64 && !ppc64le && !s390x && !wasm -// -build !386,!amd64,!arm64,!ppc64,!ppc64le,!s390x,!wasm package math diff --git a/libgo/go/math/huge_test.go b/libgo/go/math/huge_test.go index ec81a4a..bc28c6f 100644 --- a/libgo/go/math/huge_test.go +++ b/libgo/go/math/huge_test.go @@ -6,7 +6,6 @@ // accurate for huge arguments. //go:build !s390x -// +build !s390x package math_test diff --git a/libgo/go/math/modf_noasm.go b/libgo/go/math/modf_noasm.go index 42d4734..28bcf8f 100644 --- a/libgo/go/math/modf_noasm.go +++ b/libgo/go/math/modf_noasm.go @@ -3,7 +3,6 @@ // license that can be found in the LICENSE file. //-go:build !arm64 && !ppc64 && !ppc64le -// -build !arm64,!ppc64,!ppc64le package math diff --git a/libgo/go/math/rand/gen_cooked.go b/libgo/go/math/rand/gen_cooked.go index 7950e09..782bb66 100644 --- a/libgo/go/math/rand/gen_cooked.go +++ b/libgo/go/math/rand/gen_cooked.go @@ -3,7 +3,6 @@ // license that can be found in the LICENSE file. //go:build ignore -// +build ignore // This program computes the value of rngCooked in rng.go, // which is used for seeding all instances of rand.Source. diff --git a/libgo/go/math/rand/regress_test.go b/libgo/go/math/rand/regress_test.go index 1f30be8..813098e 100644 --- a/libgo/go/math/rand/regress_test.go +++ b/libgo/go/math/rand/regress_test.go @@ -46,7 +46,7 @@ func TestRegress(t *testing.T) { var args []reflect.Value var argstr string if mt.NumIn() == 1 { - var x interface{} + var x any switch mt.In(0).Kind() { default: t.Fatalf("unexpected argument type for r.%s", m.Name) @@ -83,7 +83,7 @@ func TestRegress(t *testing.T) { args = append(args, reflect.ValueOf(x)) } - var out interface{} + var out any out = mv.Call(args)[0].Interface() if m.Name == "Int" || m.Name == "Intn" { out = int64(out.(int)) @@ -120,7 +120,7 @@ func TestRegress(t *testing.T) { } } -var regressGolden = []interface{}{ +var regressGolden = []any{ float64(4.668112973579268), // ExpFloat64() float64(0.1601593871172866), // ExpFloat64() float64(3.0465834105636), // ExpFloat64() diff --git a/libgo/go/math/stubs.go b/libgo/go/math/stubs.go index fe56800..551920d 100644 --- a/libgo/go/math/stubs.go +++ b/libgo/go/math/stubs.go @@ -3,7 +3,6 @@ // license that can be found in the LICENSE file. //-go:build !s390x -// -build !s390x // This is a large group of functions that most architectures don't // implement in assembly. |