failsafe path, as first time compile with tcc, second time compile with gcc ...

This commit is contained in:
kbkpbot 2025-08-09 17:00:07 +08:00
parent acbb12f96f
commit 677852fe66
3 changed files with 48 additions and 62 deletions

View file

@ -18,6 +18,7 @@ pub fn mul_64(x u64, y u64) (u64, u64) {
mut lo := u64(0)
$if msvc {
lo = C._umul128(x, y, &hi)
return hi, lo
} $else $if amd64 {
asm amd64 {
mulq rdx
@ -27,11 +28,10 @@ pub fn mul_64(x u64, y u64) (u64, u64) {
d (y)
; cc
}
} $else {
// cross compile
hi, lo = mul_64_default(x, y)
return hi, lo
}
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
@ -45,6 +45,7 @@ pub fn mul_add_64(x u64, y u64, z u64) (u64, u64) {
lo = C._umul128(x, y, &hi)
carry := C._addcarry_u64(0, lo, z, &lo)
hi += carry
return hi, lo
} $else $if amd64 {
asm amd64 {
mulq rdx
@ -57,11 +58,10 @@ pub fn mul_add_64(x u64, y u64, z u64) (u64, u64) {
r (z)
; cc
}
} $else {
// cross compile
hi, lo = mul_add_64_default(x, y, z)
return hi, lo
}
return hi, lo
// cross compile
return mul_add_64_default(x, y, z)
}
// div_64 returns the quotient and remainder of (hi, lo) divided by y:
@ -82,6 +82,7 @@ pub fn div_64(hi u64, lo u64, y1 u64) (u64, u64) {
mut rem := u64(0)
$if msvc {
quo = C._udiv128(hi, lo, y, &rem)
return quo, rem
} $else $if amd64 {
asm amd64 {
div y
@ -92,9 +93,8 @@ pub fn div_64(hi u64, lo u64, y1 u64) (u64, u64) {
r (y)
; cc
}
} $else {
// cross compile
quo, rem = div_64_default(hi, lo, y1)
return quo, rem
}
return quo, rem
// cross compile
return div_64_default(hi, lo, y1)
}

View file

@ -12,21 +12,20 @@ module bits
pub fn mul_64(x u64, y u64) (u64, u64) {
mut hi := u64(0)
mut lo := u64(0)
$if arm64 {
$if arm64 && !tinyc {
asm arm64 {
mul lo, x, y
umulh hi, x, y
; +r (hi)
+r (lo)
; =&r (hi)
=&r (lo)
; r (x)
r (y)
; cc
}
} $else {
// cross compile
hi, lo = mul_64_default(x, y)
return hi, lo
}
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
@ -36,22 +35,21 @@ pub fn mul_64(x u64, y u64) (u64, u64) {
pub fn mul_add_64(x u64, y u64, z u64) (u64, u64) {
mut hi := u64(0)
mut lo := u64(0)
$if arm64 {
$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 (hi)
=&r (lo)
; r (x)
r (y)
r (z)
; cc
}
} $else {
// cross compile
hi, lo = mul_add_64_default(x, y, z)
return hi, lo
}
return hi, lo
// cross compile
return mul_add_64_default(x, y, z)
}

View file

@ -17,11 +17,10 @@ pub fn leading_zeros_8(x u8) int {
}
$if msvc {
return C.__lzcnt(x) - 24
} $else $if tinyc && windows {
return leading_zeros_8_default(x)
} $else {
} $else $if !(tinyc && (windows || arm64)) {
return C.__builtin_clz(x) - 24
}
return leading_zeros_8_default(x)
}
// leading_zeros_16 returns the number of leading zero bits in x; the result is 16 for x == 0.
@ -32,11 +31,10 @@ pub fn leading_zeros_16(x u16) int {
}
$if msvc {
return C.__lzcnt(x) - 16
} $else $if tinyc && windows {
return leading_zeros_16_default(x)
} $else {
} $else $if !(tinyc && (windows || arm64)) {
return C.__builtin_clz(x) - 16
}
return leading_zeros_16_default(x)
}
// leading_zeros_32 returns the number of leading zero bits in x; the result is 32 for x == 0.
@ -47,11 +45,10 @@ pub fn leading_zeros_32(x u32) int {
}
$if msvc {
return C.__lzcnt(x)
} $else $if tinyc && windows {
return leading_zeros_32_default(x)
} $else {
} $else $if !(tinyc && (windows || arm64)) {
return C.__builtin_clz(x)
}
return leading_zeros_32_default(x)
}
// leading_zeros_64 returns the number of leading zero bits in x; the result is 64 for x == 0.
@ -62,11 +59,10 @@ pub fn leading_zeros_64(x u64) int {
}
$if msvc {
return C.__lzcnt64(x)
} $else $if tinyc && windows {
return leading_zeros_64_default(x)
} $else {
} $else $if !(tinyc && (windows || arm64)) {
return C.__builtin_clzll(x)
}
return leading_zeros_64_default(x)
}
fn C.__builtin_ctz(x u32) int
@ -85,11 +81,10 @@ pub fn trailing_zeros_8(x u8) int {
mut pos := 0
_ := C._BitScanForward(&pos, x)
return pos
} $else $if tinyc && windows {
return trailing_zeros_8_default(x)
} $else {
} $else $if !(tinyc && (windows || arm64)) {
return C.__builtin_ctz(x)
}
return trailing_zeros_8_default(x)
}
// trailing_zeros_16 returns the number of trailing zero bits in x; the result is 16 for x == 0.
@ -102,11 +97,10 @@ pub fn trailing_zeros_16(x u16) int {
mut pos := 0
_ := C._BitScanForward(&pos, x)
return pos
} $else $if tinyc && windows {
return trailing_zeros_16_default(x)
} $else {
} $else $if !(tinyc && (windows || arm64)) {
return C.__builtin_ctz(x)
}
return trailing_zeros_16_default(x)
}
// trailing_zeros_32 returns the number of trailing zero bits in x; the result is 32 for x == 0.
@ -119,11 +113,10 @@ pub fn trailing_zeros_32(x u32) int {
mut pos := 0
_ := C._BitScanForward(&pos, x)
return pos
} $else $if tinyc && windows {
return trailing_zeros_32_default(x)
} $else {
} $else $if !(tinyc && (windows || arm64)) {
return C.__builtin_ctz(x)
}
return trailing_zeros_32_default(x)
}
// trailing_zeros_64 returns the number of trailing zero bits in x; the result is 64 for x == 0.
@ -136,11 +129,10 @@ pub fn trailing_zeros_64(x u64) int {
mut pos := 0
_ := C._BitScanForward64(&pos, x)
return pos
} $else $if tinyc && windows {
return trailing_zeros_64_default(x)
} $else {
} $else $if !(tinyc && (windows || arm64)) {
return C.__builtin_ctzll(x)
}
return trailing_zeros_64_default(x)
}
fn C.__builtin_popcount(x u32) int
@ -154,11 +146,10 @@ fn C.__popcnt64(x u64) int
pub fn ones_count_8(x u8) int {
$if msvc {
return C.__popcnt(x)
} $else $if tinyc && windows {
return ones_count_8_default(x)
} $else {
} $else $if !(tinyc && (windows || arm64)) {
return C.__builtin_popcount(x)
}
return ones_count_8_default(x)
}
// ones_count_16 returns the number of one bits ("population count") in x.
@ -166,11 +157,10 @@ pub fn ones_count_8(x u8) int {
pub fn ones_count_16(x u16) int {
$if msvc {
return C.__popcnt(x)
} $else $if tinyc && windows {
return ones_count_16_default(x)
} $else {
} $else $if !(tinyc && (windows || arm64)) {
return C.__builtin_popcount(x)
}
return ones_count_16_default(x)
}
// ones_count_32 returns the number of one bits ("population count") in x.
@ -178,11 +168,10 @@ pub fn ones_count_16(x u16) int {
pub fn ones_count_32(x u32) int {
$if msvc {
return C.__popcnt(x)
} $else $if tinyc && windows {
return ones_count_32_default(x)
} $else {
} $else $if !(tinyc && (windows || arm64)) {
return C.__builtin_popcount(x)
}
return ones_count_32_default(x)
}
// ones_count_64 returns the number of one bits ("population count") in x.
@ -190,9 +179,8 @@ pub fn ones_count_32(x u32) int {
pub fn ones_count_64(x u64) int {
$if msvc {
return C.__popcnt64(x)
} $else $if tinyc && windows {
return ones_count_64_default(x)
} $else {
} $else $if !(tinyc && (windows || arm64)) {
return C.__builtin_popcountll(x)
}
return ones_count_64_default(x)
}