]> Cypherpunks repositories - gostls13.git/commitdiff
runtime/internal/math: add Add64
authorRuss Cox <rsc@golang.org>
Mon, 7 Aug 2023 19:52:18 +0000 (15:52 -0400)
committerGopher Robot <gobot@golang.org>
Wed, 16 Aug 2023 16:03:04 +0000 (16:03 +0000)
This makes the intrinsic available on 64-bit platforms,
since the runtime cannot import math/bits.

Change-Id: I5296cc6a97d1cb4756ab369d96dc9605df9f8247
Reviewed-on: https://go-review.googlesource.com/c/go/+/516861
Reviewed-by: Keith Randall <khr@google.com>
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Auto-Submit: Russ Cox <rsc@golang.org>
TryBot-Bypass: Russ Cox <rsc@golang.org>

src/cmd/compile/internal/ssagen/ssa.go
src/runtime/internal/math/math.go

index 1143d58bf3f2846d9827d74ecfaef12ed46f7612..171f99522d9c3eb3fe8c2ff973278ab7c44dd900 100644 (file)
@@ -4870,6 +4870,7 @@ func InitTables() {
                },
                sys.AMD64, sys.ARM64, sys.PPC64, sys.S390X, sys.RISCV64, sys.Loong64, sys.MIPS64)
        alias("math/bits", "Add", "math/bits", "Add64", p8...)
+       alias("runtime/internal/math", "Add64", "math/bits", "Add64", all...)
        addF("math/bits", "Sub64",
                func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
                        return s.newValue3(ssa.OpSub64borrow, types.NewTuple(types.Types[types.TUINT64], types.Types[types.TUINT64]), args[0], args[1], args[2])
index c3fac366be0210979ce9beee890eb5394df909f5..b2e55086511d3f934daa77d994988012d5f6c64e 100644 (file)
@@ -38,3 +38,18 @@ func Mul64(x, y uint64) (hi, lo uint64) {
        lo = x * y
        return
 }
+
+// Add64 returns the sum with carry of x, y and carry: sum = x + y + carry.
+// The carry input must be 0 or 1; otherwise the behavior is undefined.
+// The carryOut output is guaranteed to be 0 or 1.
+//
+// This function's execution time does not depend on the inputs.
+// On supported platforms this is an intrinsic lowered by the compiler.
+func Add64(x, y, carry uint64) (sum, carryOut uint64) {
+       sum = x + y + carry
+       // The sum will overflow if both top bits are set (x & y) or if one of them
+       // is (x | y), and a carry from the lower place happened. If such a carry
+       // happens, the top bit will be 1 + 0 + 1 = 0 (&^ sum).
+       carryOut = ((x & y) | ((x | y) &^ sum)) >> 63
+       return
+}