diff options
| author | LemonBoy <thatlemon@gmail.com> | 2019-05-10 12:45:01 +0200 |
|---|---|---|
| committer | LemonBoy <thatlemon@gmail.com> | 2019-05-10 13:26:33 +0200 |
| commit | 7db2aa1c252919caf6120d890dde4ccb052dce93 (patch) | |
| tree | 40c8e81b72bb897f8539104a4a77e24653111f09 /std/special/compiler_rt/ashlti3.zig | |
| parent | 1c0223899cfe6c1c73f186330f6eff2cc9e78579 (diff) | |
| download | zig-7db2aa1c252919caf6120d890dde4ccb052dce93.tar.gz zig-7db2aa1c252919caf6120d890dde4ccb052dce93.zip | |
compiler-rt: Add __ashlti3
Diffstat (limited to 'std/special/compiler_rt/ashlti3.zig')
| -rw-r--r-- | std/special/compiler_rt/ashlti3.zig | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/std/special/compiler_rt/ashlti3.zig b/std/special/compiler_rt/ashlti3.zig new file mode 100644 index 0000000000..65b23f22e5 --- /dev/null +++ b/std/special/compiler_rt/ashlti3.zig @@ -0,0 +1,41 @@ +const builtin = @import("builtin"); +const compiler_rt = @import("../compiler_rt.zig"); + +pub extern fn __ashlti3(a: i128, b: i32) i128 { + var input = twords{ .all = a }; + var result: twords = undefined; + + if (b > 63) { + // 64 <= b < 128 + result.s.low = 0; + result.s.high = input.s.low << @intCast(u6, b - 64); + } else { + // 0 <= b < 64 + if (b == 0) return a; + result.s.low = input.s.low << @intCast(u6, b); + result.s.high = input.s.low >> @intCast(u6, 64 - 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 ashlti3" { + _ = @import("ashlti3_test.zig"); +} |
