| ... | ... | @@ -40,7 +40,8 @@ comptime { |
| 40 | 40 | @export(__aeabi_read_tp, .{ .name = "__aeabi_read_tp", .linkage = common.linkage, .visibility = common.visibility }); |
| 41 | 41 | } |
| 42 | 42 | |
| 43 | | // floating-point helper functions (double-precision reverse subtraction, y – x), see subdf3.zig |
| 43 | // floating-point helper functions (single+double-precision reverse subtraction, y – x), see subdf3.zig |
| 44 | @export(__aeabi_frsub, .{ .name = "__aeabi_frsub", .linkage = common.linkage, .visibility = common.visibility }); |
| 44 | 45 | @export(__aeabi_drsub, .{ .name = "__aeabi_drsub", .linkage = common.linkage, .visibility = common.visibility }); |
| 45 | 46 | } |
| 46 | 47 | } |
| ... | ... | @@ -191,7 +192,68 @@ pub fn __aeabi_ldivmod() callconv(.Naked) void { |
| 191 | 192 | unreachable; |
| 192 | 193 | } |
| 193 | 194 | |
| 194 | | pub fn __aeabi_drsub(a: f64, b: f64) callconv(.AAPCS) f64 { |
| 195 | // Float Arithmetic |
| 196 | |
| 197 | fn __aeabi_frsub(a: f32, b: f32) callconv(.AAPCS) f32 { |
| 198 | const neg_a: f32 = @bitCast(@as(u32, @bitCast(a)) ^ (@as(u32, 1) << 31)); |
| 199 | return b + neg_a; |
| 200 | } |
| 201 | |
| 202 | fn __aeabi_drsub(a: f64, b: f64) callconv(.AAPCS) f64 { |
| 195 | 203 | const neg_a: f64 = @bitCast(@as(u64, @bitCast(a)) ^ (@as(u64, 1) << 63)); |
| 196 | 204 | return b + neg_a; |
| 197 | 205 | } |
| 206 | |
| 207 | test "__aeabi_frsub" { |
| 208 | if (!builtin.cpu.arch.isARM()) return error.SkipZigTest; |
| 209 | const inf32 = std.math.inf(f32); |
| 210 | const maxf32 = std.math.floatMax(f32); |
| 211 | const frsub_data = [_][3]f32{ |
| 212 | [_]f32{ 0.0, 0.0, -0.0 }, |
| 213 | [_]f32{ 0.0, -0.0, -0.0 }, |
| 214 | [_]f32{ -0.0, 0.0, 0.0 }, |
| 215 | [_]f32{ -0.0, -0.0, -0.0 }, |
| 216 | [_]f32{ 0.0, 1.0, 1.0 }, |
| 217 | [_]f32{ 1.0, 0.0, -1.0 }, |
| 218 | [_]f32{ 1.0, 1.0, 0.0 }, |
| 219 | [_]f32{ 1234.56789, 9876.54321, 8641.97532 }, |
| 220 | [_]f32{ 9876.54321, 1234.56789, -8641.97532 }, |
| 221 | [_]f32{ -8641.97532, 1234.56789, 9876.54321 }, |
| 222 | [_]f32{ 8641.97532, 9876.54321, 1234.56789 }, |
| 223 | [_]f32{ -maxf32, -maxf32, 0.0 }, |
| 224 | [_]f32{ maxf32, maxf32, 0.0 }, |
| 225 | [_]f32{ maxf32, -maxf32, -inf32 }, |
| 226 | [_]f32{ -maxf32, maxf32, inf32 }, |
| 227 | }; |
| 228 | if (!builtin.cpu.arch.isARM()) return error.SkipZigTest; |
| 229 | for (frsub_data) |data| { |
| 230 | try std.testing.expectApproxEqAbs(data[2], __aeabi_frsub(data[0], data[1]), 0.001); |
| 231 | } |
| 232 | } |
| 233 | |
| 234 | test "__aeabi_drsub" { |
| 235 | if (!builtin.cpu.arch.isARM()) return error.SkipZigTest; |
| 236 | const inf64 = std.math.inf(f64); |
| 237 | const maxf64 = std.math.floatMax(f64); |
| 238 | const frsub_data = [_][3]f64{ |
| 239 | [_]f64{ 0.0, 0.0, -0.0 }, |
| 240 | [_]f64{ 0.0, -0.0, -0.0 }, |
| 241 | [_]f64{ -0.0, 0.0, 0.0 }, |
| 242 | [_]f64{ -0.0, -0.0, -0.0 }, |
| 243 | [_]f64{ 0.0, 1.0, 1.0 }, |
| 244 | [_]f64{ 1.0, 0.0, -1.0 }, |
| 245 | [_]f64{ 1.0, 1.0, 0.0 }, |
| 246 | [_]f64{ 1234.56789, 9876.54321, 8641.97532 }, |
| 247 | [_]f64{ 9876.54321, 1234.56789, -8641.97532 }, |
| 248 | [_]f64{ -8641.97532, 1234.56789, 9876.54321 }, |
| 249 | [_]f64{ 8641.97532, 9876.54321, 1234.56789 }, |
| 250 | [_]f64{ -maxf64, -maxf64, 0.0 }, |
| 251 | [_]f64{ maxf64, maxf64, 0.0 }, |
| 252 | [_]f64{ maxf64, -maxf64, -inf64 }, |
| 253 | [_]f64{ -maxf64, maxf64, inf64 }, |
| 254 | }; |
| 255 | if (!builtin.cpu.arch.isARM()) return error.SkipZigTest; |
| 256 | for (frsub_data) |data| { |
| 257 | try std.testing.expectApproxEqAbs(data[2], __aeabi_drsub(data[0], data[1]), 0.000001); |
| 258 | } |
| 259 | } |