| ... | @@ -40,7 +40,8 @@ comptime { | ... | @@ -40,7 +40,8 @@ comptime { |
| 40 | @export(__aeabi_read_tp, .{ .name = "__aeabi_read_tp", .linkage = common.linkage, .visibility = common.visibility }); | 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 | @export(__aeabi_drsub, .{ .name = "__aeabi_drsub", .linkage = common.linkage, .visibility = common.visibility }); | 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,7 +192,68 @@ pub fn __aeabi_ldivmod() callconv(.Naked) void { |
| 191 | unreachable; | 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 | const neg_a: f64 = @bitCast(@as(u64, @bitCast(a)) ^ (@as(u64, 1) << 63)); | 203 | const neg_a: f64 = @bitCast(@as(u64, @bitCast(a)) ^ (@as(u64, 1) << 63)); |
| 196 | return b + neg_a; | 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 | } |