v2 / vlib / math / bits / bits.arm64.v
55 lines · 53 sloc · 1.19 KB · 350747793bfdf74d3be70ea3df075706871b0099
Raw
1// Copyright (c) 2019-2024 Alexander Medvednikov. All rights reserved.
2// Use of this source code is governed by an MIT license
3// that can be found in the LICENSE file.
4module bits
5
6// mul_64 returns the 128-bit product of x and y: (hi, lo) = x * y
7// with the product bits' upper half returned in hi and the lower
8// half returned in lo.
9//
10// This function's execution time does not depend on the inputs.
11@[inline]
12pub fn mul_64(x u64, y u64) (u64, u64) {
13 mut hi := u64(0)
14 mut lo := u64(0)
15 $if arm64 && !tinyc {
16 asm arm64 {
17 mul lo, x, y
18 umulh hi, x, y
19 ; =&r (hi)
20 =&r (lo)
21 ; r (x)
22 r (y)
23 ; cc
24 }
25 return hi, lo
26 }
27 // cross compile
28 return mul_64_default(x, y)
29}
30
31// mul_add_64 returns the 128-bit result of x * y + z: (hi, lo) = x * y + z
32// with the result bits' upper half returned in hi and the lower
33// half returned in lo.
34@[inline]
35pub fn mul_add_64(x u64, y u64, z u64) (u64, u64) {
36 mut hi := u64(0)
37 mut lo := u64(0)
38 $if arm64 && !tinyc {
39 asm arm64 {
40 mul lo, x, y
41 umulh hi, x, y
42 adds lo, lo, z
43 adc hi, hi, xzr
44 ; =&r (hi)
45 =&r (lo)
46 ; r (x)
47 r (y)
48 r (z)
49 ; cc
50 }
51 return hi, lo
52 }
53 // cross compile
54 return mul_add_64_default(x, y, z)
55}
56