Skip to content

Commit

Permalink
refactor(add-carry): with Clang on non-x86 (for example MacOS) use bu…
Browse files Browse the repository at this point in the history
…iltin add-carry instead of u128
  • Loading branch information
mratsim committed Jun 28, 2024
1 parent ee818f0 commit 635ffd2
Showing 1 changed file with 24 additions and 0 deletions.
24 changes: 24 additions & 0 deletions constantine/platforms/intrinsics/addcarry_subborrow.nim
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import
# See https://gcc.godbolt.org/z/2h768y (Mar 2020 compilers)
# https://gcc.godbolt.org/z/WP38PzsMs
# (Dec 2023 compilers improved but __builtin_addcll leads to very poor GCC codegen)
# Tracking compiler inefficients - https://github.com/mratsim/constantine/issues/357
#
# ```C
# #include <stdint.h>
Expand Down Expand Up @@ -100,6 +101,13 @@ when X86:
func addcarry_u64(carryIn: Carry, a, b: Ct[uint64], sum: var Ct[uint64]): Carry {.importc: "_addcarry_u64", intrinsics.}
func subborrow_u64(borrowIn: Borrow, a, b: Ct[uint64], diff: var Ct[uint64]): Borrow {.importc: "_subborrow_u64", intrinsics.}

elif defined(clang):
func builtin_addcl(x, y: Ct[uint32], carryIn: Ct[uint32], carryOut: var Ct[uint32]): Ct[uint32] {.importc: "__builtin_addcl", nodecl.}
func builtin_subcl(x, y: Ct[uint32], carryIn: Ct[uint32], carryOut: var Ct[uint32]): Ct[uint32] {.importc: "__builtin_subcl", nodecl.}

func builtin_addcll(x, y: Ct[uint64], carryIn: Ct[uint64], carryOut: var Ct[uint64]): Ct[uint64] {.importc: "__builtin_addcll", nodecl.}
func builtin_subcll(x, y: Ct[uint64], carryIn: Ct[uint64], carryOut: var Ct[uint64]): Ct[uint64] {.importc: "__builtin_subcll", nodecl.}

# ############################################################
#
# Public
Expand All @@ -116,6 +124,10 @@ func addC*(cOut: var Carry, sum: var Ct[uint32], a, b: Ct[uint32], cIn: Carry) {
## (CarryOut, Sum) <- a + b + CarryIn
when X86:
cOut = addcarry_u32(cIn, a, b, sum)
elif defined(clang):
var carryOut: Ct[uint32]
sum = builtin_addcl(a, b, cast[Ct[uint32]](cIn), carryOut)
cOut = cast[Carry](carryOut)
else:
let dblPrec = uint64(cIn) + uint64(a) + uint64(b)
sum = (Ct[uint32])(dblPrec)
Expand All @@ -126,6 +138,10 @@ func subB*(bOut: var Borrow, diff: var Ct[uint32], a, b: Ct[uint32], bIn: Borrow
## (BorrowOut, Diff) <- a - b - borrowIn
when X86:
bOut = subborrow_u32(bIn, a, b, diff)
elif defined(clang):
var borrowOut: Ct[uint32]
diff = builtin_subcl(a, b, cast[Ct[uint32]](bIn), borrowOut)
bOut = cast[Borrow](borrowOut)
else:
let dblPrec = uint64(a) - uint64(b) - uint64(bIn)
diff = (Ct[uint32])(dblPrec)
Expand All @@ -137,6 +153,10 @@ func addC*(cOut: var Carry, sum: var Ct[uint64], a, b: Ct[uint64], cIn: Carry) {
## (CarryOut, Sum) <- a + b + CarryIn
when X86:
cOut = addcarry_u64(cIn, a, b, sum)
elif defined(clang):
var carryOut: Ct[uint64]
sum = builtin_addcll(a, b, cast[Ct[uint64]](cIn), carryOut)
cOut = cast[Carry](carryOut)
else:
block:
static:
Expand All @@ -158,6 +178,10 @@ func subB*(bOut: var Borrow, diff: var Ct[uint64], a, b: Ct[uint64], bIn: Borrow
## (BorrowOut, Diff) <- a - b - borrowIn
when X86:
bOut = subborrow_u64(bIn, a, b, diff)
elif defined(clang):
var borrowOut: Ct[uint64]
diff = builtin_subcll(a, b, cast[Ct[uint64]](bIn), borrowOut)
bOut = cast[Borrow](borrowOut)
else:
block:
static:
Expand Down

0 comments on commit 635ffd2

Please sign in to comment.