cmptf2.zig (4739B) - Raw
1 ///! The quoted behavior definitions are from 2 ///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines 3 const common = @import("./common.zig"); 4 const comparef = @import("./comparef.zig"); 5 6 pub const panic = common.panic; 7 8 comptime { 9 if (common.want_ppc_abi) { 10 @export(&__eqtf2, .{ .name = "__eqkf2", .linkage = common.linkage, .visibility = common.visibility }); 11 @export(&__netf2, .{ .name = "__nekf2", .linkage = common.linkage, .visibility = common.visibility }); 12 @export(&__lttf2, .{ .name = "__ltkf2", .linkage = common.linkage, .visibility = common.visibility }); 13 @export(&__letf2, .{ .name = "__lekf2", .linkage = common.linkage, .visibility = common.visibility }); 14 } else if (common.want_sparc_abi) { 15 @export(&_Qp_cmp, .{ .name = "_Qp_cmp", .linkage = common.linkage, .visibility = common.visibility }); 16 @export(&_Qp_feq, .{ .name = "_Qp_feq", .linkage = common.linkage, .visibility = common.visibility }); 17 @export(&_Qp_fne, .{ .name = "_Qp_fne", .linkage = common.linkage, .visibility = common.visibility }); 18 @export(&_Qp_flt, .{ .name = "_Qp_flt", .linkage = common.linkage, .visibility = common.visibility }); 19 @export(&_Qp_fle, .{ .name = "_Qp_fle", .linkage = common.linkage, .visibility = common.visibility }); 20 @export(&_Qp_fgt, .{ .name = "_Qp_fgt", .linkage = common.linkage, .visibility = common.visibility }); 21 @export(&_Qp_fge, .{ .name = "_Qp_fge", .linkage = common.linkage, .visibility = common.visibility }); 22 } 23 @export(&__eqtf2, .{ .name = "__eqtf2", .linkage = common.linkage, .visibility = common.visibility }); 24 @export(&__netf2, .{ .name = "__netf2", .linkage = common.linkage, .visibility = common.visibility }); 25 @export(&__letf2, .{ .name = "__letf2", .linkage = common.linkage, .visibility = common.visibility }); 26 @export(&__cmptf2, .{ .name = "__cmptf2", .linkage = common.linkage, .visibility = common.visibility }); 27 @export(&__lttf2, .{ .name = "__lttf2", .linkage = common.linkage, .visibility = common.visibility }); 28 } 29 30 /// "These functions calculate a <=> b. That is, if a is less than b, they return -1; 31 /// if a is greater than b, they return 1; and if a and b are equal they return 0. 32 /// If either argument is NaN they return 1..." 33 /// 34 /// Note that this matches the definition of `__letf2`, `__eqtf2`, `__netf2`, `__cmptf2`, 35 /// and `__lttf2`. 36 fn __cmptf2(a: f128, b: f128) callconv(.c) i32 { 37 return @intFromEnum(comparef.cmpf2(f128, comparef.LE, a, b)); 38 } 39 40 /// "These functions return a value less than or equal to zero if neither argument is NaN, 41 /// and a is less than or equal to b." 42 fn __letf2(a: f128, b: f128) callconv(.c) i32 { 43 return __cmptf2(a, b); 44 } 45 46 /// "These functions return zero if neither argument is NaN, and a and b are equal." 47 /// Note that due to some kind of historical accident, __eqtf2 and __netf2 are defined 48 /// to have the same return value. 49 fn __eqtf2(a: f128, b: f128) callconv(.c) i32 { 50 return __cmptf2(a, b); 51 } 52 53 /// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal." 54 /// Note that due to some kind of historical accident, __eqtf2 and __netf2 are defined 55 /// to have the same return value. 56 fn __netf2(a: f128, b: f128) callconv(.c) i32 { 57 return __cmptf2(a, b); 58 } 59 60 /// "These functions return a value less than zero if neither argument is NaN, and a 61 /// is strictly less than b." 62 fn __lttf2(a: f128, b: f128) callconv(.c) i32 { 63 return __cmptf2(a, b); 64 } 65 66 const SparcFCMP = enum(i32) { 67 Equal = 0, 68 Less = 1, 69 Greater = 2, 70 Unordered = 3, 71 }; 72 73 fn _Qp_cmp(a: *const f128, b: *const f128) callconv(.c) i32 { 74 return @intFromEnum(comparef.cmpf2(f128, SparcFCMP, a.*, b.*)); 75 } 76 77 fn _Qp_feq(a: *const f128, b: *const f128) callconv(.c) bool { 78 return @as(SparcFCMP, @enumFromInt(_Qp_cmp(a, b))) == .Equal; 79 } 80 81 fn _Qp_fne(a: *const f128, b: *const f128) callconv(.c) bool { 82 return @as(SparcFCMP, @enumFromInt(_Qp_cmp(a, b))) != .Equal; 83 } 84 85 fn _Qp_flt(a: *const f128, b: *const f128) callconv(.c) bool { 86 return @as(SparcFCMP, @enumFromInt(_Qp_cmp(a, b))) == .Less; 87 } 88 89 fn _Qp_fgt(a: *const f128, b: *const f128) callconv(.c) bool { 90 return @as(SparcFCMP, @enumFromInt(_Qp_cmp(a, b))) == .Greater; 91 } 92 93 fn _Qp_fge(a: *const f128, b: *const f128) callconv(.c) bool { 94 return switch (@as(SparcFCMP, @enumFromInt(_Qp_cmp(a, b)))) { 95 .Equal, .Greater => true, 96 .Less, .Unordered => false, 97 }; 98 } 99 100 fn _Qp_fle(a: *const f128, b: *const f128) callconv(.c) bool { 101 return switch (@as(SparcFCMP, @enumFromInt(_Qp_cmp(a, b)))) { 102 .Equal, .Less => true, 103 .Greater, .Unordered => false, 104 }; 105 }