mirror of
https://github.com/vlang/v.git
synced 2025-09-07 22:30:57 -04:00
56 lines
1.2 KiB
V
56 lines
1.2 KiB
V
// Copyright (c) 2019-2024 Alexander Medvednikov. All rights reserved.
|
|
// Use of this source code is governed by an MIT license
|
|
// that can be found in the LICENSE file.
|
|
module bits
|
|
|
|
// mul_64 returns the 128-bit product of x and y: (hi, lo) = x * y
|
|
// with the product bits' upper half returned in hi and the lower
|
|
// half returned in lo.
|
|
//
|
|
// This function's execution time does not depend on the inputs.
|
|
@[inline]
|
|
pub fn mul_64(x u64, y u64) (u64, u64) {
|
|
mut hi := u64(0)
|
|
mut lo := u64(0)
|
|
$if arm64 && !tinyc {
|
|
asm arm64 {
|
|
mul lo, x, y
|
|
umulh hi, x, y
|
|
; =&r (hi)
|
|
=&r (lo)
|
|
; r (x)
|
|
r (y)
|
|
; cc
|
|
}
|
|
return hi, lo
|
|
}
|
|
// cross compile
|
|
return mul_64_default(x, y)
|
|
}
|
|
|
|
// mul_add_64 returns the 128-bit result of x * y + z: (hi, lo) = x * y + z
|
|
// with the result bits' upper half returned in hi and the lower
|
|
// half returned in lo.
|
|
@[inline]
|
|
pub fn mul_add_64(x u64, y u64, z u64) (u64, u64) {
|
|
mut hi := u64(0)
|
|
mut lo := u64(0)
|
|
$if arm64 && !tinyc {
|
|
asm arm64 {
|
|
mul lo, x, y
|
|
umulh hi, x, y
|
|
adds lo, lo, z
|
|
adc hi, hi, xzr
|
|
; =&r (hi)
|
|
=&r (lo)
|
|
; r (x)
|
|
r (y)
|
|
r (z)
|
|
; cc
|
|
}
|
|
return hi, lo
|
|
}
|
|
// cross compile
|
|
return mul_add_64_default(x, y, z)
|
|
}
|