diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2019-04-01 11:31:57 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-04-01 11:31:57 -0400 |
| commit | 3199792ade2dfcb88f6668849c54352e51fc1ae0 (patch) | |
| tree | 886189ac1a1bfcae8124ac18684f1e180c8abb0f /std | |
| parent | c76d51de975a4e2e8b549d37161f1e0056384e0b (diff) | |
| parent | bfbfb7b3b04b9c98dd14f932b08d1c058e2c5b25 (diff) | |
| download | zig-3199792ade2dfcb88f6668849c54352e51fc1ae0.tar.gz zig-3199792ade2dfcb88f6668849c54352e51fc1ae0.zip | |
Merge pull request #2150 from vegecode/armv7m-compiler-rt
Armv7m compiler rt
Diffstat (limited to 'std')
| -rw-r--r-- | std/special/builtin.zig | 25 | ||||
| -rw-r--r-- | std/special/compiler_rt.zig | 157 | ||||
| -rw-r--r-- | std/special/compiler_rt/addXf3.zig | 38 | ||||
| -rw-r--r-- | std/special/compiler_rt/negXf2.zig | 21 |
4 files changed, 233 insertions, 8 deletions
diff --git a/std/special/builtin.zig b/std/special/builtin.zig index 868b880dcf..3776cc22bf 100644 --- a/std/special/builtin.zig +++ b/std/special/builtin.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 diff --git a/std/special/compiler_rt.zig b/std/special/compiler_rt.zig index b62bc6dd69..193899d1af 100644 --- a/std/special/compiler_rt.zig +++ b/std/special/compiler_rt.zig @@ -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 diff --git a/std/special/compiler_rt/addXf3.zig b/std/special/compiler_rt/addXf3.zig index c7e80e4e71..3a70461eca 100644 --- a/std/special/compiler_rt/addXf3.zig +++ b/std/special/compiler_rt/addXf3.zig @@ -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; } diff --git a/std/special/compiler_rt/negXf2.zig b/std/special/compiler_rt/negXf2.zig new file mode 100644 index 0000000000..b71a503c1d --- /dev/null +++ b/std/special/compiler_rt/negXf2.zig @@ -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); +} |
