master
 1//! a raised to integer power of b
 2//! ported from https://github.com/llvm-mirror/compiler-rt/blob/release_80/lib/builtins/powisf2.c
 3//! Multiplication order (left-to-right or right-to-left) does not matter for
 4//! error propagation and this method is optimized for performance, not accuracy.
 5
 6const builtin = @import("builtin");
 7const common = @import("common.zig");
 8const std = @import("std");
 9
10pub const panic = common.panic;
11
12comptime {
13    @export(&__powihf2, .{ .name = "__powihf2", .linkage = common.linkage, .visibility = common.visibility });
14    @export(&__powisf2, .{ .name = "__powisf2", .linkage = common.linkage, .visibility = common.visibility });
15    @export(&__powidf2, .{ .name = "__powidf2", .linkage = common.linkage, .visibility = common.visibility });
16    if (common.want_ppc_abi)
17        @export(&__powitf2, .{ .name = "__powikf2", .linkage = common.linkage, .visibility = common.visibility });
18    @export(&__powitf2, .{ .name = "__powitf2", .linkage = common.linkage, .visibility = common.visibility });
19    @export(&__powixf2, .{ .name = "__powixf2", .linkage = common.linkage, .visibility = common.visibility });
20}
21
22inline fn powiXf2(comptime FT: type, a: FT, b: i32) FT {
23    var x_a: FT = a;
24    var x_b: i32 = b;
25    const is_recip: bool = b < 0;
26    var r: FT = 1.0;
27    while (true) {
28        if (@as(u32, @bitCast(x_b)) & @as(u32, 1) != 0) {
29            r *= x_a;
30        }
31        x_b = @divTrunc(x_b, @as(i32, 2));
32        if (x_b == 0) break;
33        x_a *= x_a; // Multiplication of x_a propagates the error
34    }
35    return if (is_recip) 1 / r else r;
36}
37
38pub fn __powihf2(a: f16, b: i32) callconv(.c) f16 {
39    return powiXf2(f16, a, b);
40}
41
42pub fn __powisf2(a: f32, b: i32) callconv(.c) f32 {
43    return powiXf2(f32, a, b);
44}
45
46pub fn __powidf2(a: f64, b: i32) callconv(.c) f64 {
47    return powiXf2(f64, a, b);
48}
49
50pub fn __powitf2(a: f128, b: i32) callconv(.c) f128 {
51    return powiXf2(f128, a, b);
52}
53
54pub fn __powixf2(a: f80, b: i32) callconv(.c) f80 {
55    return powiXf2(f80, a, b);
56}
57
58test {
59    _ = @import("powiXf2_test.zig");
60}