mirror of
https://github.com/ziglang/zig.git
synced 2024-11-15 00:26:57 +00:00
Merge pull request #2150 from vegecode/armv7m-compiler-rt
Armv7m compiler rt
This commit is contained in:
commit
3199792ade
@ -664,6 +664,7 @@ set(ZIG_STD_FILES
|
||||
"special/compiler_rt/muloti4.zig"
|
||||
"special/compiler_rt/mulXf3.zig"
|
||||
"special/compiler_rt/multi3.zig"
|
||||
"special/compiler_rt/negXf2.zig"
|
||||
"special/compiler_rt/popcountdi2.zig"
|
||||
"special/compiler_rt/truncXfYf2.zig"
|
||||
"special/compiler_rt/udivmod.zig"
|
||||
|
@ -55,6 +55,31 @@ export fn memmove(dest: ?[*]u8, src: ?[*]const u8, n: usize) ?[*]u8 {
|
||||
return dest;
|
||||
}
|
||||
|
||||
export fn memcmp(vl: ?[*]const u8, vr: ?[*]const u8, n: usize) isize {
|
||||
@setRuntimeSafety(false);
|
||||
|
||||
var index: usize = 0;
|
||||
while (index != n) : (index += 1) {
|
||||
const compare_val = @bitCast(i8, vl.?[index] -% vr.?[index]);
|
||||
if (compare_val != 0) {
|
||||
return compare_val;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
test "test_memcmp" {
|
||||
const base_arr = []u8{ 1, 1, 1 };
|
||||
const arr1 = []u8{ 1, 1, 1 };
|
||||
const arr2 = []u8{ 1, 0, 1 };
|
||||
const arr3 = []u8{ 1, 2, 1 };
|
||||
|
||||
std.testing.expect(memcmp(base_arr[0..].ptr, arr1[0..].ptr, base_arr.len) == 0);
|
||||
std.testing.expect(memcmp(base_arr[0..].ptr, arr2[0..].ptr, base_arr.len) == 1);
|
||||
std.testing.expect(memcmp(base_arr[0..].ptr, arr3[0..].ptr, base_arr.len) == -1);
|
||||
}
|
||||
|
||||
comptime {
|
||||
if (builtin.mode != builtin.Mode.ReleaseFast and
|
||||
builtin.mode != builtin.Mode.ReleaseSmall and
|
||||
|
@ -21,7 +21,11 @@ comptime {
|
||||
|
||||
@export("__unordtf2", @import("compiler_rt/comparetf2.zig").__unordtf2, linkage);
|
||||
|
||||
@export("__addsf3", @import("compiler_rt/addXf3.zig").__addsf3, linkage);
|
||||
@export("__adddf3", @import("compiler_rt/addXf3.zig").__adddf3, linkage);
|
||||
@export("__addtf3", @import("compiler_rt/addXf3.zig").__addtf3, linkage);
|
||||
@export("__subsf3", @import("compiler_rt/addXf3.zig").__subsf3, linkage);
|
||||
@export("__subdf3", @import("compiler_rt/addXf3.zig").__subdf3, linkage);
|
||||
@export("__subtf3", @import("compiler_rt/addXf3.zig").__subtf3, linkage);
|
||||
|
||||
@export("__mulsf3", @import("compiler_rt/mulXf3.zig").__mulsf3, linkage);
|
||||
@ -78,10 +82,62 @@ comptime {
|
||||
@export("__umoddi3", __umoddi3, linkage);
|
||||
@export("__udivmodsi4", __udivmodsi4, linkage);
|
||||
|
||||
@export("__negsf2", @import("compiler_rt/negXf2.zig").__negsf2, linkage);
|
||||
@export("__negdf2", @import("compiler_rt/negXf2.zig").__negdf2, linkage);
|
||||
|
||||
if (is_arm_arch and !is_arm_64) {
|
||||
@export("__aeabi_uldivmod", __aeabi_uldivmod, linkage);
|
||||
@export("__aeabi_uidivmod", __aeabi_uidivmod, linkage);
|
||||
@export("__aeabi_uidiv", __udivsi3, linkage);
|
||||
|
||||
@export("__aeabi_memcpy", __aeabi_memcpy, linkage);
|
||||
@export("__aeabi_memcpy4", __aeabi_memcpy, linkage);
|
||||
@export("__aeabi_memcpy8", __aeabi_memcpy, linkage);
|
||||
|
||||
@export("__aeabi_memmove", __aeabi_memmove, linkage);
|
||||
@export("__aeabi_memmove4", __aeabi_memmove, linkage);
|
||||
@export("__aeabi_memmove8", __aeabi_memmove, linkage);
|
||||
|
||||
@export("__aeabi_memset", __aeabi_memset, linkage);
|
||||
@export("__aeabi_memset4", __aeabi_memset, linkage);
|
||||
@export("__aeabi_memset8", __aeabi_memset, linkage);
|
||||
|
||||
@export("__aeabi_memclr", __aeabi_memclr, linkage);
|
||||
@export("__aeabi_memclr4", __aeabi_memclr, linkage);
|
||||
@export("__aeabi_memclr8", __aeabi_memclr, linkage);
|
||||
|
||||
@export("__aeabi_memcmp", __aeabi_memcmp, linkage);
|
||||
@export("__aeabi_memcmp4", __aeabi_memcmp, linkage);
|
||||
@export("__aeabi_memcmp8", __aeabi_memcmp, linkage);
|
||||
|
||||
@export("__aeabi_fneg", @import("compiler_rt/negXf2.zig").__negsf2, linkage);
|
||||
@export("__aeabi_dneg", @import("compiler_rt/negXf2.zig").__negdf2, linkage);
|
||||
|
||||
@export("__aeabi_fmul", @import("compiler_rt/mulXf3.zig").__mulsf3, linkage);
|
||||
@export("__aeabi_dmul", @import("compiler_rt/mulXf3.zig").__muldf3, linkage);
|
||||
|
||||
@export("__aeabi_d2h", @import("compiler_rt/truncXfYf2.zig").__truncdfhf2, linkage);
|
||||
|
||||
@export("__aeabi_f2ulz", @import("compiler_rt/fixunssfdi.zig").__fixunssfdi, linkage);
|
||||
@export("__aeabi_d2ulz", @import("compiler_rt/fixunsdfdi.zig").__fixunsdfdi, linkage);
|
||||
|
||||
@export("__aeabi_f2lz", @import("compiler_rt/fixsfdi.zig").__fixsfdi, linkage);
|
||||
@export("__aeabi_d2lz", @import("compiler_rt/fixdfdi.zig").__fixdfdi, linkage);
|
||||
|
||||
@export("__aeabi_d2uiz", @import("compiler_rt/fixunsdfsi.zig").__fixunsdfsi, linkage);
|
||||
|
||||
@export("__aeabi_h2f", @import("compiler_rt/extendXfYf2.zig").__extendhfsf2, linkage);
|
||||
@export("__aeabi_f2h", @import("compiler_rt/truncXfYf2.zig").__truncsfhf2, linkage);
|
||||
|
||||
@export("__aeabi_fadd", @import("compiler_rt/addXf3.zig").__addsf3, linkage);
|
||||
@export("__aeabi_dadd", @import("compiler_rt/addXf3.zig").__adddf3, linkage);
|
||||
@export("__aeabi_fsub", @import("compiler_rt/addXf3.zig").__subsf3, linkage);
|
||||
@export("__aeabi_dsub", @import("compiler_rt/addXf3.zig").__subdf3, linkage);
|
||||
|
||||
@export("__aeabi_f2uiz", @import("compiler_rt/fixunssfsi.zig").__fixunssfsi, linkage);
|
||||
|
||||
@export("__aeabi_f2iz", @import("compiler_rt/fixsfsi.zig").__fixsfsi, linkage);
|
||||
@export("__aeabi_d2iz", @import("compiler_rt/fixdfsi.zig").__fixdfsi, linkage);
|
||||
}
|
||||
if (builtin.os == builtin.Os.windows) {
|
||||
switch (builtin.arch) {
|
||||
@ -187,6 +243,17 @@ const is_arm_arch = switch (builtin.arch) {
|
||||
else => false,
|
||||
};
|
||||
|
||||
const is_arm_32 = is_arm_arch and !is_arm_64;
|
||||
|
||||
const use_thumb_1 = is_arm_32 and switch (builtin.arch.arm) {
|
||||
builtin.Arch.Arm32.v6,
|
||||
builtin.Arch.Arm32.v6m,
|
||||
builtin.Arch.Arm32.v6k,
|
||||
builtin.Arch.Arm32.v6t2,
|
||||
=> true,
|
||||
else => false,
|
||||
};
|
||||
|
||||
nakedcc fn __aeabi_uidivmod() void {
|
||||
@setRuntimeSafety(false);
|
||||
asm volatile (
|
||||
@ -203,6 +270,96 @@ nakedcc fn __aeabi_uidivmod() void {
|
||||
);
|
||||
}
|
||||
|
||||
nakedcc fn __aeabi_memcpy() noreturn {
|
||||
@setRuntimeSafety(false);
|
||||
if (use_thumb_1) {
|
||||
asm volatile (
|
||||
\\ push {r7, lr}
|
||||
\\ bl memcpy
|
||||
\\ pop {r7, pc}
|
||||
);
|
||||
} else {
|
||||
asm volatile (
|
||||
\\ b memcpy
|
||||
);
|
||||
}
|
||||
unreachable;
|
||||
}
|
||||
|
||||
nakedcc fn __aeabi_memmove() noreturn {
|
||||
@setRuntimeSafety(false);
|
||||
if (use_thumb_1) {
|
||||
asm volatile (
|
||||
\\ push {r7, lr}
|
||||
\\ bl memmove
|
||||
\\ pop {r7, pc}
|
||||
);
|
||||
} else {
|
||||
asm volatile (
|
||||
\\ b memmove
|
||||
);
|
||||
}
|
||||
unreachable;
|
||||
}
|
||||
|
||||
nakedcc fn __aeabi_memset() noreturn {
|
||||
@setRuntimeSafety(false);
|
||||
if (use_thumb_1) {
|
||||
asm volatile (
|
||||
\\ mov r3, r1
|
||||
\\ mov r1, r2
|
||||
\\ mov r2, r3
|
||||
\\ push {r7, lr}
|
||||
\\ b memset
|
||||
\\ pop {r7, pc}
|
||||
);
|
||||
} else {
|
||||
asm volatile (
|
||||
\\ mov r3, r1
|
||||
\\ mov r1, r2
|
||||
\\ mov r2, r3
|
||||
\\ b memset
|
||||
);
|
||||
}
|
||||
unreachable;
|
||||
}
|
||||
|
||||
nakedcc fn __aeabi_memclr() noreturn {
|
||||
@setRuntimeSafety(false);
|
||||
if (use_thumb_1) {
|
||||
asm volatile (
|
||||
\\ mov r2, r1
|
||||
\\ movs r1, #0
|
||||
\\ push {r7, lr}
|
||||
\\ bl memset
|
||||
\\ pop {r7, pc}
|
||||
);
|
||||
} else {
|
||||
asm volatile (
|
||||
\\ mov r2, r1
|
||||
\\ movs r1, #0
|
||||
\\ b memset
|
||||
);
|
||||
}
|
||||
unreachable;
|
||||
}
|
||||
|
||||
nakedcc fn __aeabi_memcmp() noreturn {
|
||||
@setRuntimeSafety(false);
|
||||
if (use_thumb_1) {
|
||||
asm volatile (
|
||||
\\ push {r7, lr}
|
||||
\\ bl memcmp
|
||||
\\ pop {r7, pc}
|
||||
);
|
||||
} else {
|
||||
asm volatile (
|
||||
\\ b memcmp
|
||||
);
|
||||
}
|
||||
unreachable;
|
||||
}
|
||||
|
||||
// _chkstk (_alloca) routine - probe stack between %esp and (%esp-%eax) in 4k increments,
|
||||
// then decrement %esp by %eax. Preserves all registers except %esp and flags.
|
||||
// This routine is windows specific
|
||||
|
@ -6,27 +6,49 @@ const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const compiler_rt = @import("../compiler_rt.zig");
|
||||
|
||||
pub extern fn __addsf3(a: f32, b: f32) f32 {
|
||||
return addXf3(f32, a, b);
|
||||
}
|
||||
|
||||
pub extern fn __adddf3(a: f64, b: f64) f64 {
|
||||
return addXf3(f64, a, b);
|
||||
}
|
||||
|
||||
pub extern fn __addtf3(a: f128, b: f128) f128 {
|
||||
return addXf3(f128, a, b);
|
||||
}
|
||||
|
||||
pub extern fn __subsf3(a: f32, b: f32) f32 {
|
||||
const neg_b = @bitCast(f32, @bitCast(u32, b) ^ (u32(1) << 31));
|
||||
return addXf3(f32, a, neg_b);
|
||||
}
|
||||
|
||||
pub extern fn __subdf3(a: f64, b: f64) f64 {
|
||||
const neg_b = @bitCast(f64, @bitCast(u64, b) ^ (u64(1) << 63));
|
||||
return addXf3(f64, a, neg_b);
|
||||
}
|
||||
|
||||
pub extern fn __subtf3(a: f128, b: f128) f128 {
|
||||
const neg_b = @bitCast(f128, @bitCast(u128, b) ^ (u128(1) << 127));
|
||||
return addXf3(f128, a, neg_b);
|
||||
}
|
||||
|
||||
inline fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {
|
||||
// TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154
|
||||
fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {
|
||||
const Z = @IntType(false, T.bit_count);
|
||||
const S = @IntType(false, T.bit_count - @clz(Z(T.bit_count) - 1));
|
||||
const significandBits = std.math.floatMantissaBits(T);
|
||||
const implicitBit = Z(1) << significandBits;
|
||||
|
||||
const shift = @clz(significand.*) - @clz(implicitBit);
|
||||
significand.* <<= @intCast(u7, shift);
|
||||
significand.* <<= @intCast(S, shift);
|
||||
return 1 - shift;
|
||||
}
|
||||
|
||||
inline fn addXf3(comptime T: type, a: T, b: T) T {
|
||||
// TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154
|
||||
fn addXf3(comptime T: type, a: T, b: T) T {
|
||||
const Z = @IntType(false, T.bit_count);
|
||||
const S = @IntType(false, T.bit_count - @clz(Z(T.bit_count) - 1));
|
||||
|
||||
const typeWidth = T.bit_count;
|
||||
const significandBits = std.math.floatMantissaBits(T);
|
||||
@ -126,8 +148,8 @@ inline fn addXf3(comptime T: type, a: T, b: T) T {
|
||||
const @"align" = @intCast(Z, aExponent - bExponent);
|
||||
if (@"align" != 0) {
|
||||
if (@"align" < typeWidth) {
|
||||
const sticky = if (bSignificand << @intCast(u7, typeWidth - @"align") != 0) Z(1) else 0;
|
||||
bSignificand = (bSignificand >> @truncate(u7, @"align")) | sticky;
|
||||
const sticky = if (bSignificand << @intCast(S, typeWidth - @"align") != 0) Z(1) else 0;
|
||||
bSignificand = (bSignificand >> @truncate(S, @"align")) | sticky;
|
||||
} else {
|
||||
bSignificand = 1; // sticky; b is known to be non-zero.
|
||||
}
|
||||
@ -141,7 +163,7 @@ inline fn addXf3(comptime T: type, a: T, b: T) T {
|
||||
// and adjust the exponent:
|
||||
if (aSignificand < implicitBit << 3) {
|
||||
const shift = @intCast(i32, @clz(aSignificand)) - @intCast(i32, @clz(implicitBit << 3));
|
||||
aSignificand <<= @intCast(u7, shift);
|
||||
aSignificand <<= @intCast(S, shift);
|
||||
aExponent -= shift;
|
||||
}
|
||||
} else { // addition
|
||||
@ -163,8 +185,8 @@ inline fn addXf3(comptime T: type, a: T, b: T) T {
|
||||
// Result is denormal before rounding; the exponent is zero and we
|
||||
// need to shift the significand.
|
||||
const shift = @intCast(Z, 1 - aExponent);
|
||||
const sticky = if (aSignificand << @intCast(u7, typeWidth - shift) != 0) Z(1) else 0;
|
||||
aSignificand = aSignificand >> @intCast(u7, shift | sticky);
|
||||
const sticky = if (aSignificand << @intCast(S, typeWidth - shift) != 0) Z(1) else 0;
|
||||
aSignificand = aSignificand >> @intCast(S, shift | sticky);
|
||||
aExponent = 0;
|
||||
}
|
||||
|
||||
|
21
std/special/compiler_rt/negXf2.zig
Normal file
21
std/special/compiler_rt/negXf2.zig
Normal file
@ -0,0 +1,21 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub extern fn __negsf2(a: f32) f32 {
|
||||
return negXf2(f32, a);
|
||||
}
|
||||
|
||||
pub extern fn __negdf2(a: f64) f64 {
|
||||
return negXf2(f64, a);
|
||||
}
|
||||
|
||||
fn negXf2(comptime T: type, a: T) T {
|
||||
const Z = @IntType(false, T.bit_count);
|
||||
|
||||
const typeWidth = T.bit_count;
|
||||
const significandBits = std.math.floatMantissaBits(T);
|
||||
const exponentBits = std.math.floatExponentBits(T);
|
||||
|
||||
const signBit = (Z(1) << (significandBits + exponentBits));
|
||||
|
||||
return @bitCast(T, @bitCast(Z, a) ^ signBit);
|
||||
}
|
Loading…
Reference in New Issue
Block a user