Skip to content

Commit f356c0a

Browse files
committed
Generate constants
1 parent 7c4aef4 commit f356c0a

File tree

7 files changed

+170
-67
lines changed

7 files changed

+170
-67
lines changed

etc/generate-constants.jl

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
using Printf
2+
3+
function main()
4+
repo_root = dirname(@__DIR__)
5+
out_dir = joinpath(repo_root, "libm/src/math/generic/generated")
6+
7+
mod_contents = "// autogenerated\n\n"
8+
9+
cfg = Config(out_dir)
10+
mod_contents *= update_rem_pio2(cfg)
11+
12+
path = joinpath(cfg.out_dir, "mod.rs")
13+
write(path, mod_contents)
14+
println("wrote $path")
15+
end
16+
17+
struct Config
18+
out_dir::String
19+
end
20+
21+
@enum FloatTy F16 F32 F64 F128
22+
23+
struct TyInfo
24+
bits::UInt32
25+
sig_bits::UInt32
26+
ity::Type
27+
ty_name::String
28+
end
29+
30+
function ty_info(fty::FloatTy)::TyInfo
31+
if fty == F16
32+
bits = 16
33+
sig_bits = 10
34+
ity = UInt16
35+
elseif fty == F32
36+
bits = 32
37+
sig_bits = 23
38+
ity = UInt32
39+
elseif fty == F64
40+
bits = 64
41+
sig_bits = 52
42+
ity = UInt64
43+
elseif fty == F128
44+
bits = 128
45+
sig_bits = 112
46+
ity = UInt128
47+
else
48+
@assert(false)
49+
end
50+
51+
return TyInfo(
52+
bits,
53+
sig_bits,
54+
ity,
55+
lowercase(string(fty)),
56+
)
57+
end
58+
59+
function update_rem_pio2(cfg::Config)::String
60+
prefix= """
61+
use crate::support::HalfRep;
62+
use super::super::rem_pio2::RemPio2Support;
63+
"""
64+
ret = ""
65+
66+
for fty in [F64]
67+
info = ty_info(fty)
68+
ty_name = info.ty_name
69+
halfbits = info.bits / 2
70+
71+
if info.bits == 32 || info.bits == 64
72+
to_bits = "$(ty_name)_to_bits"
73+
prefix *= "use crate::support::$to_bits;\n"
74+
else
75+
to_bits = "$ty_name::to_bits"
76+
end
77+
78+
hi_int(x::BigFloat) = @sprintf "(%s(hf%d!(\"%a\")) >> %d) as u%d" to_bits info.bits x halfbits halfbits
79+
80+
setprecision(ty_info(fty).sig_bits + 1)
81+
82+
ty_impl = """
83+
impl RemPio2Support for $ty_name {
84+
const TO_INT: Self = 1.5 / $ty_name::EPSILON;
85+
const INV_PIO2: Self = 6.36619772367581382433e-01;
86+
const PIO2_1: Self = 1.57079632673412561417e+00;
87+
const PIO2_1T: Self = 6.07710050650619224932e-11;
88+
const PIO2_2: Self = 6.07710050630396597660e-11;
89+
const PIO2_2T: Self = 2.02226624879595063154e-21;
90+
const PIO2_3: Self = 2.02226624871116645580e-21;
91+
const PIO2_3T: Self = 8.47842766036889956997e-32;
92+
93+
const FRAC_5PI_4_HI: HalfRep<Self> = $(hi_int(big(pi)*5/4));
94+
const FRAC_3PI_4_HI: HalfRep<Self> = $(hi_int(big(pi)*3/4));
95+
const FRAC_9PI_4_HI: HalfRep<Self> = $(hi_int(big(pi)*9/4));
96+
const FRAC_7PI_4_HI: HalfRep<Self> = $(hi_int(big(pi)*7/4));
97+
const FRAC_3PI_2_HI: HalfRep<Self> = $(hi_int(big(pi)*3/2));
98+
const TAU_HI: HalfRep<Self> = $(hi_int(big(pi)*2));
99+
const FRAC_PI_2_HI: HalfRep<Self> = 0x921fb;
100+
const FRAC_2_POW_20_PI_2: HalfRep<Self> = $(hi_int((big(2)^20) * pi / 2));
101+
102+
const MAGIC_F: Self = hf64!("0x1p24");
103+
104+
fn large(x: &[Self], y: &mut [Self], e0: i32, prec: usize) -> i32 {
105+
super::super::super::rem_pio2_large(x, y, e0, prec)
106+
}
107+
}
108+
"""
109+
ret *= ty_impl
110+
end
111+
112+
ret = prefix * "\n" * ret
113+
path = joinpath(cfg.out_dir, "rem_pio2.rs")
114+
write(path, ret)
115+
println("wrote $path")
116+
117+
return "mod rem_pio2;"
118+
end
119+
120+
main()
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// autogenerated
2+
3+
mod rem_pio2;
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
use crate::support::HalfRep;
2+
use super::super::rem_pio2::RemPio2Support;
3+
use crate::support::f64_to_bits;
4+
5+
impl RemPio2Support for f64 {
6+
const TO_INT: Self = 1.5 / f64::EPSILON;
7+
const INV_PIO2: Self = 6.36619772367581382433e-01;
8+
const PIO2_1: Self = 1.57079632673412561417e+00;
9+
const PIO2_1T: Self = 6.07710050650619224932e-11;
10+
const PIO2_2: Self = 6.07710050630396597660e-11;
11+
const PIO2_2T: Self = 2.02226624879595063154e-21;
12+
const PIO2_3: Self = 2.02226624871116645580e-21;
13+
const PIO2_3T: Self = 8.47842766036889956997e-32;
14+
15+
const FRAC_5PI_4_HI: HalfRep<Self> = (f64_to_bits(hf64!("0x3.ed4f452aa70bcp+0")) >> 32) as u32;
16+
const FRAC_3PI_4_HI: HalfRep<Self> = (f64_to_bits(hf64!("0x2.5b2f8fe6643a4p+0")) >> 32) as u32;
17+
const FRAC_9PI_4_HI: HalfRep<Self> = (f64_to_bits(hf64!("0x7.118eafb32caecp+0")) >> 32) as u32;
18+
const FRAC_7PI_4_HI: HalfRep<Self> = (f64_to_bits(hf64!("0x5.7f6efa6ee9dd4p+0")) >> 32) as u32;
19+
const FRAC_3PI_2_HI: HalfRep<Self> = (f64_to_bits(hf64!("0x4.b65f1fccc8748p+0")) >> 32) as u32;
20+
const TAU_HI: HalfRep<Self> = (f64_to_bits(hf64!("0x6.487ed5110b46p+0")) >> 32) as u32;
21+
const FRAC_PI_2_HI: HalfRep<Self> = 0x921fb;
22+
const FRAC_2_POW_20_PI_2: HalfRep<Self> = (f64_to_bits(hf64!("0x1.921fb54442d18p+20")) >> 32) as u32;
23+
24+
const MAGIC_F: Self = hf64!("0x1p24");
25+
26+
fn large(x: &[Self], y: &mut [Self], e0: i32, prec: usize) -> i32 {
27+
super::super::super::rem_pio2_large(x, y, e0, prec)
28+
}
29+
}

libm/src/math/generic/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ mod fmin;
1313
mod fminimum;
1414
mod fminimum_num;
1515
mod fmod;
16-
mod rem_frac_pi_2;
16+
mod generated;
17+
mod rem_pio2;
1718
mod rint;
1819
mod round;
1920
mod scalbn;
@@ -32,7 +33,7 @@ pub use fmin::fmin;
3233
pub use fminimum::fminimum;
3334
pub use fminimum_num::fminimum_num;
3435
pub use fmod::fmod;
35-
pub(crate) use rem_frac_pi_2::{medium, rem_frac_pi_2};
36+
pub(crate) use rem_pio2::rem_pio2;
3637
pub use rint::rint_round;
3738
pub use round::round;
3839
pub use scalbn::scalbn;

libm/src/math/generic/rem_frac_pi_2.rs renamed to libm/src/math/generic/rem_pio2.rs

Lines changed: 13 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,21 @@ use core::f64::consts;
44

55
use crate::support::{CastFrom, CastInto, DInt, Float, HInt, HalfRep, Int, MinInt};
66

7-
pub(crate) trait RemFracPi2Support: Float<Int: DInt<H: Int>> {
7+
pub(crate) trait RemPio2Support: Float<Int: DInt<H: Int>> {
88
const TO_INT: Self;
9+
/// 53 bits of 2/pi
910
const INV_PIO2: Self;
11+
/// first 33 bits of pi/2
1012
const PIO2_1: Self;
13+
/// pi/2 - PIO2_1
1114
const PIO2_1T: Self;
15+
/// second 33 bits of pi/2
1216
const PIO2_2: Self;
17+
/// pi/2 - (PIO2_1+PIO2_2)
1318
const PIO2_2T: Self;
19+
/// third 33 bits of pi/2
1420
const PIO2_3: Self;
21+
/// pi/2 - (PIO2_1+PIO2_2+PIO2_3)
1522
const PIO2_3T: Self;
1623

1724
const FRAC_5PI_4_HI: HalfRep<Self>;
@@ -31,42 +38,12 @@ pub(crate) trait RemFracPi2Support: Float<Int: DInt<H: Int>> {
3138
fn large(x: &[Self], y: &mut [Self], e0: i32, prec: usize) -> i32;
3239
}
3340

34-
const EPS: f64 = 2.2204460492503131e-16;
35-
36-
impl RemFracPi2Support for f64 {
37-
const TO_INT: Self = 1.5 / EPS;
38-
const INV_PIO2: Self = 6.36619772367581382433e-01;
39-
const PIO2_1: Self = 1.57079632673412561417e+00;
40-
const PIO2_1T: Self = 6.07710050650619224932e-11;
41-
const PIO2_2: Self = 6.07710050630396597660e-11;
42-
const PIO2_2T: Self = 2.02226624879595063154e-21;
43-
const PIO2_3: Self = 2.02226624871116645580e-21;
44-
const PIO2_3T: Self = 8.47842766036889956997e-32;
45-
const FRAC_5PI_4_HI: HalfRep<Self> = 0x400f6a7a;
46-
const FRAC_3PI_4_HI: HalfRep<Self> = 0x4002d97c;
47-
const FRAC_9PI_4_HI: HalfRep<Self> = 0x401c463b;
48-
const FRAC_7PI_4_HI: HalfRep<Self> = 0x4015fdbc;
49-
const FRAC_3PI_2_HI: HalfRep<Self> = 0x4012d97c;
50-
const TAU_HI: HalfRep<Self> = 0x401921fb;
51-
const FRAC_PI_2_HI: HalfRep<Self> = 0x921fb;
52-
const FRAC_2_POW_20_PI_2: HalfRep<Self> = 0x413921fb;
53-
54-
const MAGIC_F: Self = hf64!("0x1p24");
55-
56-
fn large(x: &[Self], y: &mut [Self], e0: i32, prec: usize) -> i32 {
57-
super::super::rem_pio2_large(x, y, e0, prec)
58-
}
59-
}
60-
61-
pub(crate) fn rem_frac_pi_2<F>(x: F) -> (i32, F, F)
41+
pub(crate) fn rem_pio2<F>(x: F) -> (i32, F, F)
6242
where
63-
F: RemFracPi2Support,
43+
F: RemPio2Support,
6444
F: CastInto<i32>,
6545
HalfRep<F>: Int + MinInt<Unsigned: Int<OtherSign: Int>>,
66-
// <HalfRep<F> as Int>::Unsigned: Int,
6746
{
68-
// let sign = x.is_sign_positive()
69-
7047
let ix: HalfRep<F> = x.abs().to_bits().hi();
7148
let pos = x.is_sign_positive();
7249

@@ -148,9 +125,8 @@ where
148125
return medium(x, ix);
149126
}
150127
/*
151-
152-
* all other (large) arguments
153-
*/
128+
* all other (large) arguments
129+
*/
154130
if ix >= F::EXP_MASK.hi() {
155131
/* x is inf or NaN */
156132
let y0 = x - x;
@@ -161,7 +137,6 @@ where
161137
/* set z = scalbn(|x|,-ilogb(x)+23) */
162138
let mut ui = x.to_bits();
163139
ui &= F::SIG_MASK;
164-
// ui |= F::Int::cast_from((F::EXP_BIAS + F::MAGIC) << F::SIG_BITS);
165140
ui |= F::Int::cast_from(F::EXP_BIAS + F::MAGIC) << F::SIG_BITS;
166141

167142
let mut z = F::from_bits(ui);
@@ -195,7 +170,7 @@ where
195170

196171
pub fn medium<F>(x: F, ix: HalfRep<F>) -> (i32, F, F)
197172
where
198-
F: RemFracPi2Support,
173+
F: RemPio2Support,
199174
F: CastInto<i32>,
200175
HalfRep<F>: Int,
201176
{

libm/src/math/rem_pio2.rs

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,38 +13,13 @@
1313
// Optimized by Bruce D. Evans. */
1414
use super::rem_pio2_large;
1515

16-
// #if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
17-
// #define EPS DBL_EPSILON
18-
const EPS: f64 = 2.2204460492503131e-16;
19-
// #elif FLT_EVAL_METHOD==2
20-
// #define EPS LDBL_EPSILON
21-
// #endif
22-
23-
// TODO: Support FLT_EVAL_METHOD?
24-
25-
const TO_INT: f64 = 1.5 / EPS;
26-
/// 53 bits of 2/pi
27-
const INV_PIO2: f64 = 6.36619772367581382433e-01; /* 0x3FE45F30, 0x6DC9C883 */
28-
/// first 33 bits of pi/2
29-
const PIO2_1: f64 = 1.57079632673412561417e+00; /* 0x3FF921FB, 0x54400000 */
30-
/// pi/2 - PIO2_1
31-
const PIO2_1T: f64 = 6.07710050650619224932e-11; /* 0x3DD0B461, 0x1A626331 */
32-
/// second 33 bits of pi/2
33-
const PIO2_2: f64 = 6.07710050630396597660e-11; /* 0x3DD0B461, 0x1A600000 */
34-
/// pi/2 - (PIO2_1+PIO2_2)
35-
const PIO2_2T: f64 = 2.02226624879595063154e-21; /* 0x3BA3198A, 0x2E037073 */
36-
/// third 33 bits of pi/2
37-
const PIO2_3: f64 = 2.02226624871116645580e-21; /* 0x3BA3198A, 0x2E000000 */
38-
/// pi/2 - (PIO2_1+PIO2_2+PIO2_3)
39-
const PIO2_3T: f64 = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */
40-
4116
// return the remainder of x rem pi/2 in y[0]+y[1]
4217
// use rem_pio2_large() for large x
4318
//
4419
// caller must handle the case when reduction is not needed: |x| ~<= pi/4 */
4520
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
4621
pub(crate) fn rem_pio2(x: f64) -> (i32, f64, f64) {
47-
return super::generic::rem_frac_pi_2(x);
22+
return super::generic::rem_pio2(x);
4823
}
4924

5025
#[cfg(test)]

libm/src/math/support/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ pub use big::{i256, u256};
1111
pub use env::{FpResult, Round, Status};
1212
#[allow(unused_imports)]
1313
pub use float_traits::{DFloat, Float, HFloat, HalfRep, IntTy};
14-
pub(crate) use float_traits::{f32_from_bits, f64_from_bits};
14+
pub(crate) use float_traits::{f32_from_bits, f64_from_bits, f64_to_bits};
1515
#[cfg(f16_enabled)]
1616
#[allow(unused_imports)]
1717
pub use hex_float::hf16;

0 commit comments

Comments
 (0)