Merge pull request #2150 from vegecode/armv7m-compiler-rt

Armv7m compiler rt
This commit is contained in:
Andrew Kelley 2019-04-01 11:31:57 -04:00 committed by GitHub
commit 3199792ade
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 234 additions and 8 deletions

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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;
}

View 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);
}