diff options
Diffstat (limited to 'lib/std/special/compiler_rt/lshrti3.zig')
| -rw-r--r-- | lib/std/special/compiler_rt/lshrti3.zig | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/lib/std/special/compiler_rt/lshrti3.zig b/lib/std/special/compiler_rt/lshrti3.zig new file mode 100644 index 0000000000..329968ae40 --- /dev/null +++ b/lib/std/special/compiler_rt/lshrti3.zig @@ -0,0 +1,41 @@ +const builtin = @import("builtin"); +const compiler_rt = @import("../compiler_rt.zig"); + +pub extern fn __lshrti3(a: i128, b: i32) i128 { + var input = twords{ .all = a }; + var result: twords = undefined; + + if (b > 63) { + // 64 <= b < 128 + result.s.low = input.s.high >> @intCast(u6, b - 64); + result.s.high = 0; + } else { + // 0 <= b < 64 + if (b == 0) return a; + result.s.low = input.s.high << @intCast(u6, 64 - b); + result.s.low |= input.s.low >> @intCast(u6, b); + result.s.high = input.s.high >> @intCast(u6, b); + } + + return result.all; +} + +const twords = extern union { + all: i128, + s: S, + + const S = if (builtin.endian == builtin.Endian.Little) + struct { + low: u64, + high: u64, + } + else + struct { + high: u64, + low: u64, + }; +}; + +test "import lshrti3" { + _ = @import("lshrti3_test.zig"); +} |
