mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-03-08 07:44:51 +01:00
use the "symbol" helper function in all exports move all declarations from common.zig to compiler_rt.zig flatten the tree structure somewhat (move contents of tiny files into parent files) No functional changes.
142 lines
3.9 KiB
Zig
142 lines
3.9 KiB
Zig
const std = @import("std");
|
|
const builtin = @import("builtin");
|
|
const Log2Int = std.math.Log2Int;
|
|
const compiler_rt = @import("../compiler_rt.zig");
|
|
const symbol = compiler_rt.symbol;
|
|
|
|
comptime {
|
|
// symbol compatibility with libgcc
|
|
symbol(&__ashlsi3, "__ashlsi3");
|
|
symbol(&__ashrsi3, "__ashrsi3");
|
|
symbol(&__lshrsi3, "__lshrsi3");
|
|
|
|
symbol(&__ashlti3, "__ashlti3");
|
|
symbol(&__ashrti3, "__ashrti3");
|
|
symbol(&__lshrti3, "__lshrti3");
|
|
|
|
if (compiler_rt.want_aeabi) {
|
|
symbol(&__aeabi_llsl, "__aeabi_llsl");
|
|
symbol(&__aeabi_lasr, "__aeabi_lasr");
|
|
symbol(&__aeabi_llsr, "__aeabi_llsr");
|
|
} else {
|
|
symbol(&__ashldi3, "__ashldi3");
|
|
symbol(&__ashrdi3, "__ashrdi3");
|
|
symbol(&__lshrdi3, "__lshrdi3");
|
|
}
|
|
}
|
|
|
|
// Arithmetic shift left: shift in 0 from right to left
|
|
// Precondition: 0 <= b < bits_in_dword
|
|
inline fn ashlXi3(comptime T: type, a: T, b: i32) T {
|
|
const word_t = compiler_rt.HalveInt(T, false);
|
|
|
|
const input = word_t{ .all = a };
|
|
var output: word_t = undefined;
|
|
|
|
if (b >= word_t.bits) {
|
|
output.s.low = 0;
|
|
output.s.high = input.s.low << @intCast(b - word_t.bits);
|
|
} else if (b == 0) {
|
|
return a;
|
|
} else {
|
|
output.s.low = input.s.low << @intCast(b);
|
|
output.s.high = input.s.high << @intCast(b);
|
|
output.s.high |= input.s.low >> @intCast(word_t.bits - b);
|
|
}
|
|
|
|
return output.all;
|
|
}
|
|
|
|
// Arithmetic shift right: shift in 1 from left to right
|
|
// Precondition: 0 <= b < T.bit_count
|
|
inline fn ashrXi3(comptime T: type, a: T, b: i32) T {
|
|
const word_t = compiler_rt.HalveInt(T, true);
|
|
|
|
const input = word_t{ .all = a };
|
|
var output: word_t = undefined;
|
|
|
|
if (b >= word_t.bits) {
|
|
output.s.high = input.s.high >> (word_t.bits - 1);
|
|
output.s.low = input.s.high >> @intCast(b - word_t.bits);
|
|
} else if (b == 0) {
|
|
return a;
|
|
} else {
|
|
output.s.high = input.s.high >> @intCast(b);
|
|
output.s.low = input.s.high << @intCast(word_t.bits - b);
|
|
// Avoid sign-extension here
|
|
output.s.low |= @bitCast(@as(word_t.HalfTU, @bitCast(input.s.low)) >> @intCast(b));
|
|
}
|
|
|
|
return output.all;
|
|
}
|
|
|
|
// Logical shift right: shift in 0 from left to right
|
|
// Precondition: 0 <= b < T.bit_count
|
|
inline fn lshrXi3(comptime T: type, a: T, b: i32) T {
|
|
const word_t = compiler_rt.HalveInt(T, false);
|
|
|
|
const input = word_t{ .all = a };
|
|
var output: word_t = undefined;
|
|
|
|
if (b >= word_t.bits) {
|
|
output.s.high = 0;
|
|
output.s.low = input.s.high >> @intCast(b - word_t.bits);
|
|
} else if (b == 0) {
|
|
return a;
|
|
} else {
|
|
output.s.high = input.s.high >> @intCast(b);
|
|
output.s.low = input.s.high << @intCast(word_t.bits - b);
|
|
output.s.low |= input.s.low >> @intCast(b);
|
|
}
|
|
|
|
return output.all;
|
|
}
|
|
|
|
pub fn __ashlsi3(a: i32, b: i32) callconv(.c) i32 {
|
|
return ashlXi3(i32, a, b);
|
|
}
|
|
|
|
pub fn __ashrsi3(a: i32, b: i32) callconv(.c) i32 {
|
|
return ashrXi3(i32, a, b);
|
|
}
|
|
|
|
pub fn __lshrsi3(a: i32, b: i32) callconv(.c) i32 {
|
|
return lshrXi3(i32, a, b);
|
|
}
|
|
|
|
pub fn __ashldi3(a: i64, b: i32) callconv(.c) i64 {
|
|
return ashlXi3(i64, a, b);
|
|
}
|
|
fn __aeabi_llsl(a: i64, b: i32) callconv(.{ .arm_aapcs = .{} }) i64 {
|
|
return ashlXi3(i64, a, b);
|
|
}
|
|
|
|
pub fn __ashlti3(a: i128, b: i32) callconv(.c) i128 {
|
|
return ashlXi3(i128, a, b);
|
|
}
|
|
|
|
pub fn __ashrdi3(a: i64, b: i32) callconv(.c) i64 {
|
|
return ashrXi3(i64, a, b);
|
|
}
|
|
fn __aeabi_lasr(a: i64, b: i32) callconv(.{ .arm_aapcs = .{} }) i64 {
|
|
return ashrXi3(i64, a, b);
|
|
}
|
|
|
|
pub fn __ashrti3(a: i128, b: i32) callconv(.c) i128 {
|
|
return ashrXi3(i128, a, b);
|
|
}
|
|
|
|
pub fn __lshrdi3(a: i64, b: i32) callconv(.c) i64 {
|
|
return lshrXi3(i64, a, b);
|
|
}
|
|
fn __aeabi_llsr(a: i64, b: i32) callconv(.{ .arm_aapcs = .{} }) i64 {
|
|
return lshrXi3(i64, a, b);
|
|
}
|
|
|
|
pub fn __lshrti3(a: i128, b: i32) callconv(.c) i128 {
|
|
return lshrXi3(i128, a, b);
|
|
}
|
|
|
|
test {
|
|
_ = @import("shift_test.zig");
|
|
}
|