| ... | @@ -191,6 +191,49 @@ pub inline fn __builtin_expect(expr: c_long, c: c_long) c_long { | ... | @@ -191,6 +191,49 @@ pub inline fn __builtin_expect(expr: c_long, c: c_long) c_long { |
| 191 | return expr; | 191 | return expr; |
| 192 | } | 192 | } |
| 193 | | 193 | |
| | 194 | /// returns a quiet NaN. Quiet NaNs have many representations; tagp is used to select one in an |
| | 195 | /// implementation-defined way. |
| | 196 | /// This implementation is based on the description for __builtin_nan provided in the GCC docs at |
| | 197 | /// https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#index-_005f_005fbuiltin_005fnan |
| | 198 | /// Comment is reproduced below: |
| | 199 | /// Since ISO C99 defines this function in terms of strtod, which we do not implement, a description |
| | 200 | /// of the parsing is in order. |
| | 201 | /// The string is parsed as by strtol; that is, the base is recognized by leading ‘0’ or ‘0x’ prefixes. |
| | 202 | /// The number parsed is placed in the significand such that the least significant bit of the number is |
| | 203 | /// at the least significant bit of the significand. |
| | 204 | /// The number is truncated to fit the significand field provided. |
| | 205 | /// The significand is forced to be a quiet NaN. |
| | 206 | /// |
| | 207 | /// If tagp contains any non-numeric characters, the function returns a NaN whose significand is zero. |
| | 208 | /// If tagp is empty, the function returns a NaN whose significand is zero. |
| | 209 | pub inline fn __builtin_nanf(tagp: []const u8) f32 { |
| | 210 | const parsed = std.fmt.parseUnsigned(c_ulong, tagp, 0) catch 0; |
| | 211 | const bits = @truncate(u23, parsed); // single-precision float trailing significand is 23 bits |
| | 212 | return @bitCast(f32, @as(u32, bits) | std.math.qnan_u32); |
| | 213 | } |
| | 214 | |
| | 215 | pub inline fn __builtin_huge_valf() f32 { |
| | 216 | return std.math.inf(f32); |
| | 217 | } |
| | 218 | |
| | 219 | pub inline fn __builtin_inff() f32 { |
| | 220 | return std.math.inf(f32); |
| | 221 | } |
| | 222 | |
| | 223 | pub inline fn __builtin_isnan(x: anytype) c_int { |
| | 224 | return @boolToInt(std.math.isNan(x)); |
| | 225 | } |
| | 226 | |
| | 227 | pub inline fn __builtin_isinf(x: anytype) c_int { |
| | 228 | return @boolToInt(std.math.isInf(x)); |
| | 229 | } |
| | 230 | |
| | 231 | /// Similar to isinf, except the return value is -1 for an argument of -Inf and 1 for an argument of +Inf. |
| | 232 | pub inline fn __builtin_isinf_sign(x: anytype) c_int { |
| | 233 | if (!std.math.isInf(x)) return 0; |
| | 234 | return if (std.math.isPositiveInf(x)) 1 else -1; |
| | 235 | } |
| | 236 | |
| 194 | // __builtin_alloca_with_align is not currently implemented. | 237 | // __builtin_alloca_with_align is not currently implemented. |
| 195 | // It is used in a run-translated-c test and a test-translate-c test to ensure that non-implemented | 238 | // It is used in a run-translated-c test and a test-translate-c test to ensure that non-implemented |
| 196 | // builtins are correctly demoted. If you implement __builtin_alloca_with_align, please update the | 239 | // builtins are correctly demoted. If you implement __builtin_alloca_with_align, please update the |