╭ int_from_float.zig ───────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭ find file ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╮ ╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │ │ │http│ ssh │ │ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╯ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
.. aarch64_outline_atomics.zig absv.zig absvdi2.zig absvdi2_test.zig absvsi2.zig absvsi2_test.zig absvti2.zig absvti2_test.zig addf3.zig addf3_test.zig addvdi3.zig addvsi3.zig arm.zig atomics.zig aulldiv.zig aullrem.zig bitreverse.zig bitreversedi2_test.zig bitreversesi2_test.zig bitreverseti2_test.zig bswap.zig bswapdi2_test.zig bswapsi2_test.zig bswapti2_test.zig clear_cache.zig clzdi2_test.zig clzsi2_test.zig clzti2_test.zig cmp.zig cmpdi2_test.zig cmpsi2_test.zig cmpti2_test.zig comparedf2_test.zig comparef.zig comparesf2_test.zig cos.zig count0bits.zig ctzdi2_test.zig ctzsi2_test.zig ctzti2_test.zig divc3.zig divc3_test.zig divdf3.zig divdf3_test.zig divmodei4.zig divsf3.zig divsf3_test.zig divtf3.zig divtf3_test.zig divti3_test.zig divxf3.zig divxf3_test.zig emutls.zig exp.zig exp2.zig exp_f128.zig extendf.zig extendf_test.zig fabs.zig ffsdi2_test.zig ffssi2_test.zig ffsti2_test.zig float_from_int.zig float_from_int_test.zig floor_ceil.zig fma.zig fmax.zig fmin.zig fmod.zig fmodq_test.zig fmodx_test.zig hexagon.zig int.zig ╭─────────────────────────────────╮ │int_from_float.zig │ ╰─────────────────────────────────╯ int_from_float_test.zig limb64.zig log.zig log10.zig log2.zig log_f128.zig memcpy.zig memmove.zig modti3_test.zig mulXi3.zig mulXi3_test.zig mulc3.zig mulc3_test.zig mulf3.zig mulf3_test.zig mulo.zig mulodi4_test.zig mulosi4_test.zig muloti4_test.zig mulvsi3.zig negdi2_test.zig negsi2_test.zig negti2_test.zig negv.zig negvdi2_test.zig negvsi2_test.zig negvti2_test.zig os_version_check.zig parity.zig paritydi2_test.zig paritysi2_test.zig parityti2_test.zig popcount.zig popcountdi2_test.zig popcountsi2_test.zig popcountti2_test.zig powiXf2.zig powiXf2_test.zig rem_pio2.zig rem_pio2_large.zig rem_pio2f.zig rem_pio2l.zig round.zig shift.zig shift_test.zig sin.zig sincos.zig sqrt.zig ssp.zig stack_probe.zig subvdi3.zig subvsi3.zig tan.zig trig.zig trunc.zig truncf.zig truncf_test.zig ucmpdi2_test.zig ucmpsi2_test.zig ucmpti2_test.zig udivmod.zig udivmoddi4_test.zig udivmodei4.zig udivmodsi4_test.zig udivmodti4_test.zig
1 const builtin = @import("builtin"); 2 const std = @import("std"); 3 const math = std.math; 4 const Log2Int = std.math.Log2Int; 5 6 const compiler_rt = @import("../compiler_rt.zig"); 7 const symbol = compiler_rt.symbol; 8 9 comptime { 10 symbol(&__fixhfsi, "__fixhfsi"); 11 symbol(&__fixhfdi, "__fixhfdi"); 12 symbol(&__fixhfti, "__fixhfti"); 13 symbol(&__fixhfei, "__fixhfei"); 14 15 if (compiler_rt.want_aeabi) { 16 symbol(&__aeabi_f2iz, "__aeabi_f2iz"); 17 symbol(&__aeabi_f2lz, "__aeabi_f2lz"); 18 symbol(&__aeabi_fixsfti, "__fixsfti"); 19 } else { 20 symbol(&__fixsfsi, "__fixsfsi"); 21 symbol(&__fixsfdi, "__fixsfdi"); 22 if (compiler_rt.want_windows_arm_abi) symbol(&__fixsfdi, "__stoi64"); 23 symbol(&__fixsfti, "__fixsfti"); 24 } 25 symbol(&__fixsfei, "__fixsfei"); 26 27 if (compiler_rt.want_aeabi) { 28 symbol(&__aeabi_d2iz, "__aeabi_d2iz"); 29 symbol(&__aeabi_d2lz, "__aeabi_d2lz"); 30 symbol(&__aeabi_fixdfti, "__fixdfti"); 31 } else { 32 symbol(&__fixdfsi, "__fixdfsi"); 33 symbol(&__fixdfdi, "__fixdfdi"); 34 if (compiler_rt.want_windows_arm_abi) symbol(&__fixdfdi, "__dtoi64"); 35 symbol(&__fixdfti, "__fixdfti"); 36 } 37 symbol(&__fixdfei, "__fixdfei"); 38 39 symbol(&__fixxfsi, "__fixxfsi"); 40 symbol(&__fixxfdi, "__fixxfdi"); 41 symbol(&__fixxfti, "__fixxfti"); 42 symbol(&__fixxfei, "__fixxfei"); 43 44 if (compiler_rt.want_ppc_abi) { 45 symbol(&__fixtfsi, "__fixkfsi"); 46 symbol(&__fixtfdi, "__fixkfdi"); 47 } else if (compiler_rt.want_sparc64_abi) { 48 symbol(&_Qp_qtoi, "_Qp_qtoi"); 49 symbol(&_Qp_qtox, "_Qp_qtox"); 50 } else if (compiler_rt.want_sparc32_abi) { 51 symbol(&__fixtfsi, "_Q_qtoi"); 52 symbol(&__fixtfdi, "_Q_qtoll"); 53 } else { 54 symbol(&__fixtfsi, "__fixtfsi"); 55 symbol(&__fixtfdi, "__fixtfdi"); 56 } 57 if (compiler_rt.want_ppc_abi) { 58 symbol(&__fixtfti, "__fixkfti"); 59 symbol(&__fixtfei, "__fixkfei"); 60 } else { 61 symbol(&__fixtfti, "__fixtfti"); 62 symbol(&__fixtfei, "__fixtfei"); 63 } 64 } 65 66 fn __fixhfsi(a: compiler_rt.f16.Abi) callconv(.c) i32 { 67 return i32_intFromFloat_f16(compiler_rt.f16.fromAbi(a)); 68 } 69 pub fn i32_intFromFloat_f16(a: f16) i32 { 70 return intFromFloat(i32, a); 71 } 72 73 fn __fixhfdi(a: compiler_rt.f16.Abi) callconv(.c) i64 { 74 return i64_intFromFloat_f16(compiler_rt.f16.fromAbi(a)); 75 } 76 pub fn i64_intFromFloat_f16(a: f16) i64 { 77 return intFromFloat(i64, a); 78 } 79 80 fn __fixhfti(a: compiler_rt.f16.Abi) callconv(.c) i128 { 81 return i128_intFromFloat_f16(compiler_rt.f16.fromAbi(a)); 82 } 83 pub fn i128_intFromFloat_f16(a: f16) i128 { 84 return intFromFloat(i128, a); 85 } 86 87 fn __fixhfei(r: [*]u8, bits: usize, a: compiler_rt.f16.Abi) callconv(.c) void { 88 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); 89 return signed_intFromFloat_f16(r[0..byte_size], compiler_rt.f16.fromAbi(a)); 90 } 91 pub fn signed_intFromFloat_f16(result: []u8, a: f16) void { 92 bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a); 93 } 94 95 fn __fixsfsi(a: compiler_rt.f32.Abi) callconv(.c) i32 { 96 return i32_intFromFloat_f32(compiler_rt.f32.fromAbi(a)); 97 } 98 fn __aeabi_f2iz(a: f32) callconv(.{ .arm_aapcs = .{} }) i32 { 99 return i32_intFromFloat_f32(a); 100 } 101 pub fn i32_intFromFloat_f32(a: f32) i32 { 102 return intFromFloat(i32, a); 103 } 104 105 fn __fixsfdi(a: compiler_rt.f32.Abi) callconv(.c) i64 { 106 return i64_intFromFloat_f32(compiler_rt.f32.fromAbi(a)); 107 } 108 fn __aeabi_f2lz(a: f32) callconv(.{ .arm_aapcs = .{} }) i64 { 109 return i64_intFromFloat_f32(a); 110 } 111 pub fn i64_intFromFloat_f32(a: f32) i64 { 112 return intFromFloat(i64, a); 113 } 114 115 fn __fixsfti(a: compiler_rt.f32.Abi) callconv(.c) i128 { 116 return i128_intFromFloat_f32(compiler_rt.f32.fromAbi(a)); 117 } 118 fn __aeabi_fixsfti(_: compiler_rt.f32.Abi) callconv(.naked) i128 { 119 switch (builtin.abi.float()) { 120 .soft => asm volatile ( 121 \\ push {r0-r4, lr} 122 \\ movs r1, r0 123 \\ mov r0, sp 124 \\ bl %[__fixsfti] 125 \\ pop {r0-r4, pc} 126 : 127 : [__fixsfti] "X" (&__fixsfti), 128 ), 129 .hard => asm volatile ( 130 \\ push {r0-r4, lr} 131 \\ mov r0, sp 132 \\ bl %[__fixsfti] 133 \\ pop {r0-r4, pc} 134 : 135 : [__fixsfti] "X" (&__fixsfti), 136 ), 137 } 138 } 139 pub fn i128_intFromFloat_f32(a: f32) i128 { 140 return intFromFloat(i128, a); 141 } 142 143 fn __fixsfei(r: [*]u8, bits: usize, a: compiler_rt.f32.Abi) callconv(.c) void { 144 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); 145 return signed_intFromFloat_f32(r[0..byte_size], compiler_rt.f32.fromAbi(a)); 146 } 147 pub fn signed_intFromFloat_f32(result: []u8, a: f32) void { 148 bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a); 149 } 150 151 fn __fixdfsi(a: compiler_rt.f64.Abi) callconv(.c) i32 { 152 return i32_intFromFloat_f64(compiler_rt.f64.fromAbi(a)); 153 } 154 fn __aeabi_d2iz(a: f64) callconv(.{ .arm_aapcs = .{} }) i32 { 155 return i32_intFromFloat_f64(a); 156 } 157 pub fn i32_intFromFloat_f64(a: f64) i32 { 158 return intFromFloat(i32, a); 159 } 160 161 fn __fixdfdi(a: compiler_rt.f64.Abi) callconv(.c) i64 { 162 return i64_intFromFloat_f64(compiler_rt.f64.fromAbi(a)); 163 } 164 fn __aeabi_d2lz(a: f64) callconv(.{ .arm_aapcs = .{} }) i64 { 165 return i64_intFromFloat_f64(a); 166 } 167 pub fn i64_intFromFloat_f64(a: f64) i64 { 168 return intFromFloat(i64, a); 169 } 170 171 fn __fixdfti(a: compiler_rt.f64.Abi) callconv(.c) i128 { 172 return i128_intFromFloat_f64(compiler_rt.f64.fromAbi(a)); 173 } 174 fn __aeabi_fixdfti(_: compiler_rt.f64.Abi) callconv(.naked) i128 { 175 switch (builtin.abi.float()) { 176 .soft => asm volatile ( 177 \\ push {r0-r4, lr} 178 \\ movs r3, r1 179 \\ movs r2, r0 180 \\ mov r0, sp 181 \\ bl %[__fixdfti] 182 \\ pop {r0-r4, pc} 183 : 184 : [__fixdfti] "X" (&__fixdfti), 185 ), 186 .hard => asm volatile ( 187 \\ push {r0-r4, lr} 188 \\ mov r0, sp 189 \\ bl %[__fixdfti] 190 \\ pop {r0-r4, pc} 191 : 192 : [__fixdfti] "X" (&__fixdfti), 193 ), 194 } 195 } 196 pub fn i128_intFromFloat_f64(a: f64) i128 { 197 return intFromFloat(i128, a); 198 } 199 200 fn __fixdfei(r: [*]u8, bits: usize, a: compiler_rt.f64.Abi) callconv(.c) void { 201 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); 202 return signed_intFromFloat_f64(r[0..byte_size], compiler_rt.f64.fromAbi(a)); 203 } 204 pub fn signed_intFromFloat_f64(result: []u8, a: f64) void { 205 bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a); 206 } 207 208 fn __fixxfsi(a: compiler_rt.f80.Abi) callconv(.c) i32 { 209 return i32_intFromFloat_f80(compiler_rt.f80.fromAbi(a)); 210 } 211 pub fn i32_intFromFloat_f80(a: f80) i32 { 212 return intFromFloat(i32, a); 213 } 214 215 fn __fixxfdi(a: compiler_rt.f80.Abi) callconv(.c) i64 { 216 return i64_intFromFloat_f80(compiler_rt.f80.fromAbi(a)); 217 } 218 pub fn i64_intFromFloat_f80(a: f80) i64 { 219 return intFromFloat(i64, a); 220 } 221 222 fn __fixxfti(a: compiler_rt.f80.Abi) callconv(.c) i128 { 223 return i128_intFromFloat_f80(compiler_rt.f80.fromAbi(a)); 224 } 225 pub fn i128_intFromFloat_f80(a: f80) i128 { 226 return intFromFloat(i128, a); 227 } 228 229 fn __fixxfei(r: [*]u8, bits: usize, a: compiler_rt.f80.Abi) callconv(.c) void { 230 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); 231 return signed_intFromFloat_f80(r[0..byte_size], compiler_rt.f80.fromAbi(a)); 232 } 233 pub fn signed_intFromFloat_f80(result: []u8, a: f80) void { 234 bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a); 235 } 236 237 fn __fixtfsi(a: compiler_rt.f128.Abi) callconv(.c) i32 { 238 return i32_intFromFloat_f128(compiler_rt.f128.fromAbi(a)); 239 } 240 fn _Qp_qtoi(a: *const f128) callconv(.c) i32 { 241 return i32_intFromFloat_f128(a.*); 242 } 243 pub fn i32_intFromFloat_f128(a: f128) i32 { 244 return intFromFloat(i32, a); 245 } 246 247 fn __fixtfdi(a: compiler_rt.f128.Abi) callconv(.c) i64 { 248 return i64_intFromFloat_f128(compiler_rt.f128.fromAbi(a)); 249 } 250 fn _Qp_qtox(a: *const f128) callconv(.c) i64 { 251 return i64_intFromFloat_f128(a.*); 252 } 253 pub fn i64_intFromFloat_f128(a: f128) i64 { 254 return intFromFloat(i64, a); 255 } 256 257 fn __fixtfti(a: compiler_rt.f128.Abi) callconv(.c) i128 { 258 return i128_intFromFloat_f128(compiler_rt.f128.fromAbi(a)); 259 } 260 pub fn i128_intFromFloat_f128(a: f128) i128 { 261 return intFromFloat(i128, a); 262 } 263 264 fn __fixtfei(r: [*]u8, bits: usize, a: compiler_rt.f128.Abi) callconv(.c) void { 265 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); 266 return signed_intFromFloat_f128(r[0..byte_size], compiler_rt.f128.fromAbi(a)); 267 } 268 pub fn signed_intFromFloat_f128(result: []u8, a: f128) void { 269 bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a); 270 } 271 272 comptime { 273 symbol(&__fixunshfsi, "__fixunshfsi"); 274 symbol(&__fixunshfdi, "__fixunshfdi"); 275 symbol(&__fixunshfti, "__fixunshfti"); 276 symbol(&__fixunshfei, "__fixunshfei"); 277 278 if (compiler_rt.want_aeabi) { 279 symbol(&__aeabi_f2uiz, "__aeabi_f2uiz"); 280 symbol(&__aeabi_f2ulz, "__aeabi_f2ulz"); 281 symbol(&__aeabi_fixunssfti, "__fixunssfti"); 282 } else { 283 symbol(&__fixunssfsi, "__fixunssfsi"); 284 symbol(&__fixunssfdi, "__fixunssfdi"); 285 if (compiler_rt.want_windows_arm_abi) symbol(&__fixunssfdi, "__stou64"); 286 symbol(&__fixunssfti, "__fixunssfti"); 287 } 288 symbol(&__fixunssfei, "__fixunssfei"); 289 290 if (compiler_rt.want_aeabi) { 291 symbol(&__aeabi_d2uiz, "__aeabi_d2uiz"); 292 symbol(&__aeabi_d2ulz, "__aeabi_d2ulz"); 293 symbol(&__aeabi_fixunsdfti, "__fixunsdfti"); 294 } else { 295 symbol(&__fixunsdfsi, "__fixunsdfsi"); 296 symbol(&__fixunsdfdi, "__fixunsdfdi"); 297 if (compiler_rt.want_windows_arm_abi) symbol(&__fixunsdfdi, "__dtou64"); 298 symbol(&__fixunsdfti, "__fixunsdfti"); 299 } 300 symbol(&__fixunsdfei, "__fixunsdfei"); 301 302 symbol(&__fixunsxfsi, "__fixunsxfsi"); 303 symbol(&__fixunsxfdi, "__fixunsxfdi"); 304 symbol(&__fixunsxfti, "__fixunsxfti"); 305 symbol(&__fixunsxfei, "__fixunsxfei"); 306 307 if (compiler_rt.want_ppc_abi) { 308 symbol(&__fixunstfsi, "__fixunskfsi"); 309 symbol(&__fixunstfdi, "__fixunskfdi"); 310 } else if (compiler_rt.want_sparc64_abi) { 311 symbol(&_Qp_qtoui, "_Qp_qtoui"); 312 symbol(&_Qp_qtoux, "_Qp_qtoux"); 313 } else if (compiler_rt.want_sparc32_abi) { 314 symbol(&__fixunstfsi, "_Q_qtou"); 315 symbol(&__fixunstfdi, "_Q_qtoull"); 316 } else { 317 symbol(&__fixunstfsi, "__fixunstfsi"); 318 symbol(&__fixunstfdi, "__fixunstfdi"); 319 } 320 if (compiler_rt.want_ppc_abi) { 321 symbol(&__fixunstfti, "__fixunskfti"); 322 symbol(&__fixunstfei, "__fixunskfei"); 323 } else { 324 symbol(&__fixunstfti, "__fixunstfti"); 325 symbol(&__fixunstfei, "__fixunstfei"); 326 } 327 } 328 329 fn __fixunshfsi(a: compiler_rt.f16.Abi) callconv(.c) u32 { 330 return u32_intFromFloat_f16(compiler_rt.f16.fromAbi(a)); 331 } 332 pub fn u32_intFromFloat_f16(a: f16) u32 { 333 return intFromFloat(u32, a); 334 } 335 336 fn __fixunshfdi(a: compiler_rt.f16.Abi) callconv(.c) u64 { 337 return u64_intFromFloat_f16(compiler_rt.f16.fromAbi(a)); 338 } 339 pub fn u64_intFromFloat_f16(a: f16) u64 { 340 return intFromFloat(u64, a); 341 } 342 343 fn __fixunshfti(a: compiler_rt.f16.Abi) callconv(.c) u128 { 344 return u128_intFromFloat_f16(compiler_rt.f16.fromAbi(a)); 345 } 346 pub fn u128_intFromFloat_f16(a: f16) u128 { 347 return intFromFloat(u128, a); 348 } 349 350 fn __fixunshfei(r: [*]u8, bits: usize, a: compiler_rt.f16.Abi) callconv(.c) void { 351 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); 352 return unsigned_intFromFloat_f16(r[0..byte_size], compiler_rt.f16.fromAbi(a)); 353 } 354 pub fn unsigned_intFromFloat_f16(result: []u8, a: f16) void { 355 bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a); 356 } 357 358 fn __fixunssfsi(a: compiler_rt.f32.Abi) callconv(.c) u32 { 359 return u32_intFromFloat_f32(compiler_rt.f32.fromAbi(a)); 360 } 361 fn __aeabi_f2uiz(a: f32) callconv(.{ .arm_aapcs = .{} }) u32 { 362 return u32_intFromFloat_f32(a); 363 } 364 pub fn u32_intFromFloat_f32(a: f32) u32 { 365 return intFromFloat(u32, a); 366 } 367 368 fn __fixunssfdi(a: compiler_rt.f32.Abi) callconv(.c) u64 { 369 return u64_intFromFloat_f32(compiler_rt.f32.fromAbi(a)); 370 } 371 fn __aeabi_f2ulz(a: f32) callconv(.{ .arm_aapcs = .{} }) u64 { 372 return u64_intFromFloat_f32(a); 373 } 374 pub fn u64_intFromFloat_f32(a: f32) u64 { 375 return intFromFloat(u64, a); 376 } 377 378 fn __fixunssfti(a: compiler_rt.f32.Abi) callconv(.c) u128 { 379 return u128_intFromFloat_f32(compiler_rt.f32.fromAbi(a)); 380 } 381 fn __aeabi_fixunssfti(_: compiler_rt.f32.Abi) callconv(.naked) u128 { 382 switch (builtin.abi.float()) { 383 .soft => asm volatile ( 384 \\ push {r0-r4, lr} 385 \\ movs r1, r0 386 \\ mov r0, sp 387 \\ bl %[__fixunssfti] 388 \\ pop {r0-r4, pc} 389 : 390 : [__fixunssfti] "X" (&__fixunssfti), 391 ), 392 .hard => asm volatile ( 393 \\ push {r0-r4, lr} 394 \\ mov r0, sp 395 \\ bl %[__fixunssfti] 396 \\ pop {r0-r4, pc} 397 : 398 : [__fixunssfti] "X" (&__fixunssfti), 399 ), 400 } 401 } 402 pub fn u128_intFromFloat_f32(a: f32) u128 { 403 return intFromFloat(u128, a); 404 } 405 406 fn __fixunssfei(r: [*]u8, bits: usize, a: compiler_rt.f32.Abi) callconv(.c) void { 407 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); 408 return unsigned_intFromFloat_f32(r[0..byte_size], compiler_rt.f32.fromAbi(a)); 409 } 410 pub fn unsigned_intFromFloat_f32(result: []u8, a: f32) void { 411 bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a); 412 } 413 414 fn __fixunsdfsi(a: compiler_rt.f64.Abi) callconv(.c) u32 { 415 return u32_intFromFloat_f64(compiler_rt.f64.fromAbi(a)); 416 } 417 fn __aeabi_d2uiz(a: f64) callconv(.{ .arm_aapcs = .{} }) u32 { 418 return u32_intFromFloat_f64(a); 419 } 420 pub fn u32_intFromFloat_f64(a: f64) u32 { 421 return intFromFloat(u32, a); 422 } 423 424 fn __fixunsdfdi(a: compiler_rt.f64.Abi) callconv(.c) u64 { 425 return u64_intFromFloat_f64(compiler_rt.f64.fromAbi(a)); 426 } 427 fn __aeabi_d2ulz(a: f64) callconv(.{ .arm_aapcs = .{} }) u64 { 428 return u64_intFromFloat_f64(a); 429 } 430 pub fn u64_intFromFloat_f64(a: f64) u64 { 431 return intFromFloat(u64, a); 432 } 433 434 fn __fixunsdfti(a: compiler_rt.f64.Abi) callconv(.c) u128 { 435 return u128_intFromFloat_f64(compiler_rt.f64.fromAbi(a)); 436 } 437 fn __aeabi_fixunsdfti(_: compiler_rt.f64.Abi) callconv(.naked) u128 { 438 switch (builtin.abi.float()) { 439 .soft => asm volatile ( 440 \\ push {r0-r4, lr} 441 \\ movs r3, r1 442 \\ movs r2, r0 443 \\ mov r0, sp 444 \\ bl %[__fixunsdfti] 445 \\ pop {r0-r4, pc} 446 : 447 : [__fixunsdfti] "X" (&__fixunsdfti), 448 ), 449 .hard => asm volatile ( 450 \\ push {r0-r4, lr} 451 \\ mov r0, sp 452 \\ bl %[__fixunsdfti] 453 \\ pop {r0-r4, pc} 454 : 455 : [__fixunsdfti] "X" (&__fixunsdfti), 456 ), 457 } 458 } 459 pub fn u128_intFromFloat_f64(a: f64) u128 { 460 return intFromFloat(u128, a); 461 } 462 463 fn __fixunsdfei(r: [*]u8, bits: usize, a: compiler_rt.f64.Abi) callconv(.c) void { 464 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); 465 return unsigned_intFromFloat_f64(r[0..byte_size], compiler_rt.f64.fromAbi(a)); 466 } 467 pub fn unsigned_intFromFloat_f64(result: []u8, a: f64) void { 468 bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a); 469 } 470 471 fn __fixunsxfsi(a: compiler_rt.f80.Abi) callconv(.c) u32 { 472 return u32_intFromFloat_f80(compiler_rt.f80.fromAbi(a)); 473 } 474 pub fn u32_intFromFloat_f80(a: f80) u32 { 475 return intFromFloat(u32, a); 476 } 477 478 fn __fixunsxfdi(a: compiler_rt.f80.Abi) callconv(.c) u64 { 479 return u64_intFromFloat_f80(compiler_rt.f80.fromAbi(a)); 480 } 481 pub fn u64_intFromFloat_f80(a: f80) u64 { 482 return intFromFloat(u64, a); 483 } 484 485 fn __fixunsxfti(a: compiler_rt.f80.Abi) callconv(.c) u128 { 486 return u128_intFromFloat_f80(compiler_rt.f80.fromAbi(a)); 487 } 488 pub fn u128_intFromFloat_f80(a: f80) u128 { 489 return intFromFloat(u128, a); 490 } 491 492 fn __fixunsxfei(r: [*]u8, bits: usize, a: compiler_rt.f80.Abi) callconv(.c) void { 493 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); 494 return unsigned_intFromFloat_f80(r[0..byte_size], compiler_rt.f80.fromAbi(a)); 495 } 496 pub fn unsigned_intFromFloat_f80(result: []u8, a: f80) void { 497 bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a); 498 } 499 500 fn __fixunstfsi(a: compiler_rt.f128.Abi) callconv(.c) u32 { 501 return u32_intFromFloat_f128(compiler_rt.f128.fromAbi(a)); 502 } 503 fn _Qp_qtoui(a: *const f128) callconv(.c) u32 { 504 return u32_intFromFloat_f128(a.*); 505 } 506 pub fn u32_intFromFloat_f128(a: f128) u32 { 507 return intFromFloat(u32, a); 508 } 509 510 fn __fixunstfdi(a: compiler_rt.f128.Abi) callconv(.c) u64 { 511 return u64_intFromFloat_f128(compiler_rt.f128.fromAbi(a)); 512 } 513 fn _Qp_qtoux(a: *const f128) callconv(.c) u64 { 514 return u64_intFromFloat_f128(a.*); 515 } 516 pub fn u64_intFromFloat_f128(a: f128) u64 { 517 return intFromFloat(u64, a); 518 } 519 520 fn __fixunstfti(a: compiler_rt.f128.Abi) callconv(.c) u128 { 521 return u128_intFromFloat_f128(compiler_rt.f128.fromAbi(a)); 522 } 523 pub fn u128_intFromFloat_f128(a: f128) u128 { 524 return intFromFloat(u128, a); 525 } 526 527 fn __fixunstfei(r: [*]u8, bits: usize, a: compiler_rt.f128.Abi) callconv(.c) void { 528 const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); 529 return unsigned_intFromFloat_f128(r[0..byte_size], compiler_rt.f128.fromAbi(a)); 530 } 531 pub fn unsigned_intFromFloat_f128(result: []u8, a: f128) void { 532 bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a); 533 } 534 535 inline fn intFromFloat(comptime I: type, a: anytype) I { 536 const F = @TypeOf(a); 537 const float_bits = @typeInfo(F).float.bits; 538 const int_bits = @typeInfo(I).int.bits; 539 const rep_t = @Int(.unsigned, float_bits); 540 const sig_bits = math.floatMantissaBits(F); 541 const exp_bits = math.floatExponentBits(F); 542 const fractional_bits = math.floatFractionalBits(F); 543 544 const implicit_bit = if (F != f80) (@as(rep_t, 1) << sig_bits) else 0; 545 const max_exp = (1 << (exp_bits - 1)); 546 const exp_bias = max_exp - 1; 547 const sig_mask = (@as(rep_t, 1) << sig_bits) - 1; 548 549 // Break a into sign, exponent, significand 550 const a_rep: rep_t = @bitCast(a); 551 const negative = (a_rep >> (float_bits - 1)) != 0; 552 const exponent = @as(i32, @intCast((a_rep << 1) >> (sig_bits + 1))) - exp_bias; 553 const significand: rep_t = (a_rep & sig_mask) | implicit_bit; 554 555 // If the exponent is negative, the result rounds to zero. 556 if (exponent < 0) return 0; 557 558 // If the value is too large for the integer type, saturate. 559 switch (@typeInfo(I).int.signedness) { 560 .unsigned => { 561 if (negative) return 0; 562 if (@as(c_uint, @intCast(exponent)) >= @min(int_bits, max_exp)) return math.maxInt(I); 563 }, 564 .signed => if (@as(c_uint, @intCast(exponent)) >= @min(int_bits - 1, max_exp)) { 565 return if (negative) math.minInt(I) else math.maxInt(I); 566 }, 567 } 568 569 // If 0 <= exponent < sig_bits, right shift to get the result. 570 // Otherwise, shift left. 571 var result: I = undefined; 572 if (exponent < fractional_bits) { 573 result = @intCast(significand >> @intCast(fractional_bits - exponent)); 574 } else { 575 result = @as(I, @intCast(significand)) << @intCast(exponent - fractional_bits); 576 } 577 578 if ((@typeInfo(I).int.signedness == .signed) and negative) 579 return ~result +% 1; 580 return result; 581 } 582 583 inline fn bigIntFromFloat(comptime signedness: std.lang.Signedness, result: []u32, a: anytype) void { 584 const endian = builtin.cpu.arch.endian(); 585 switch (result.len) { 586 0 => return, 587 inline 1...4 => |limbs_len| { 588 const I = @Int(signedness, 32 * limbs_len); 589 const low_to_high: [limbs_len]u32 = @bitCast(@as(I, @intFromFloat(a))); 590 result[0..limbs_len].* = switch (endian) { 591 .little => low_to_high, 592 .big => switch (limbs_len) { 593 1 => .{low_to_high[0]}, 594 2 => .{ low_to_high[1], low_to_high[0] }, 595 3 => .{ low_to_high[2], low_to_high[1], low_to_high[0] }, 596 4 => .{ low_to_high[3], low_to_high[2], low_to_high[1], low_to_high[0] }, 597 else => comptime unreachable, 598 }, 599 }; 600 return; 601 }, 602 else => {}, 603 } 604 605 // sign implicit fraction 606 const significand_bits = 1 + math.floatFractionalBits(@TypeOf(a)); 607 const I = @Int(signedness, @as(u16, @intFromBool(signedness == .signed)) + significand_bits); 608 609 const parts = math.frexp(a); 610 const significand_bits_adjusted_to_handle_smin = @as(i32, significand_bits) + 611 @intFromBool(signedness == .signed and parts.exponent == 32 * result.len); 612 const exponent: usize = @intCast(@max(parts.exponent - significand_bits_adjusted_to_handle_smin, 0)); 613 const int: I = @intFromFloat(switch (exponent) { 614 0 => a, 615 else => math.ldexp(parts.significand, significand_bits_adjusted_to_handle_smin), 616 }); 617 switch (signedness) { 618 .signed => { 619 const exponent_limb = switch (endian) { 620 .little => exponent / 32, 621 .big => result.len - 1 - exponent / 32, 622 }; 623 const sign_bits: u32 = if (int < 0) math.maxInt(u32) else 0; 624 @memset(result[0..exponent_limb], switch (endian) { 625 .little => 0, 626 .big => sign_bits, 627 }); 628 result[exponent_limb] = sign_bits << @truncate(exponent); 629 @memset(result[exponent_limb + 1 ..], switch (endian) { 630 .little => sign_bits, 631 .big => 0, 632 }); 633 }, 634 .unsigned => @memset(result, 0), 635 } 636 std.mem.writePackedInt(I, std.mem.sliceAsBytes(result), exponent, int, .native); 637 } 638 639 test { 640 _ = @import("int_from_float_test.zig"); 641 } 642