authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-04-01 11:31:57-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2019-04-01 11:31:57-04:00
log3199792ade2dfcb88f6668849c54352e51fc1ae0
tree886189ac1a1bfcae8124ac18684f1e180c8abb0f
parentc76d51de975a4e2e8b549d37161f1e0056384e0b
parentbfbfb7b3b04b9c98dd14f932b08d1c058e2c5b25
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

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

Armv7m compiler rt

5 files changed, 234 insertions(+), 8 deletions(-)

CMakeLists.txt+1
......@@ -664,6 +664,7 @@ set(ZIG_STD_FILES
664664 "special/compiler_rt/muloti4.zig"
665665 "special/compiler_rt/mulXf3.zig"
666666 "special/compiler_rt/multi3.zig"
667 "special/compiler_rt/negXf2.zig"
667668 "special/compiler_rt/popcountdi2.zig"
668669 "special/compiler_rt/truncXfYf2.zig"
669670 "special/compiler_rt/udivmod.zig"
std/special/builtin.zig+25
......@@ -55,6 +55,31 @@ export fn memmove(dest: ?[*]u8, src: ?[*]const u8, n: usize) ?[*]u8 {
5555 return dest;
5656}
5757
58export fn memcmp(vl: ?[*]const u8, vr: ?[*]const u8, n: usize) isize {
59 @setRuntimeSafety(false);
60
61 var index: usize = 0;
62 while (index != n) : (index += 1) {
63 const compare_val = @bitCast(i8, vl.?[index] -% vr.?[index]);
64 if (compare_val != 0) {
65 return compare_val;
66 }
67 }
68
69 return 0;
70}
71
72test "test_memcmp" {
73 const base_arr = []u8{ 1, 1, 1 };
74 const arr1 = []u8{ 1, 1, 1 };
75 const arr2 = []u8{ 1, 0, 1 };
76 const arr3 = []u8{ 1, 2, 1 };
77
78 std.testing.expect(memcmp(base_arr[0..].ptr, arr1[0..].ptr, base_arr.len) == 0);
79 std.testing.expect(memcmp(base_arr[0..].ptr, arr2[0..].ptr, base_arr.len) == 1);
80 std.testing.expect(memcmp(base_arr[0..].ptr, arr3[0..].ptr, base_arr.len) == -1);
81}
82
5883comptime {
5984 if (builtin.mode != builtin.Mode.ReleaseFast and
6085 builtin.mode != builtin.Mode.ReleaseSmall and
std/special/compiler_rt.zig+157
......@@ -21,7 +21,11 @@ comptime {
2121
2222 @export("__unordtf2", @import("compiler_rt/comparetf2.zig").__unordtf2, linkage);
2323
24 @export("__addsf3", @import("compiler_rt/addXf3.zig").__addsf3, linkage);
25 @export("__adddf3", @import("compiler_rt/addXf3.zig").__adddf3, linkage);
2426 @export("__addtf3", @import("compiler_rt/addXf3.zig").__addtf3, linkage);
27 @export("__subsf3", @import("compiler_rt/addXf3.zig").__subsf3, linkage);
28 @export("__subdf3", @import("compiler_rt/addXf3.zig").__subdf3, linkage);
2529 @export("__subtf3", @import("compiler_rt/addXf3.zig").__subtf3, linkage);
2630
2731 @export("__mulsf3", @import("compiler_rt/mulXf3.zig").__mulsf3, linkage);
......@@ -78,10 +82,62 @@ comptime {
7882 @export("__umoddi3", __umoddi3, linkage);
7983 @export("__udivmodsi4", __udivmodsi4, linkage);
8084
85 @export("__negsf2", @import("compiler_rt/negXf2.zig").__negsf2, linkage);
86 @export("__negdf2", @import("compiler_rt/negXf2.zig").__negdf2, linkage);
87
8188 if (is_arm_arch and !is_arm_64) {
8289 @export("__aeabi_uldivmod", __aeabi_uldivmod, linkage);
8390 @export("__aeabi_uidivmod", __aeabi_uidivmod, linkage);
8491 @export("__aeabi_uidiv", __udivsi3, linkage);
92
93 @export("__aeabi_memcpy", __aeabi_memcpy, linkage);
94 @export("__aeabi_memcpy4", __aeabi_memcpy, linkage);
95 @export("__aeabi_memcpy8", __aeabi_memcpy, linkage);
96
97 @export("__aeabi_memmove", __aeabi_memmove, linkage);
98 @export("__aeabi_memmove4", __aeabi_memmove, linkage);
99 @export("__aeabi_memmove8", __aeabi_memmove, linkage);
100
101 @export("__aeabi_memset", __aeabi_memset, linkage);
102 @export("__aeabi_memset4", __aeabi_memset, linkage);
103 @export("__aeabi_memset8", __aeabi_memset, linkage);
104
105 @export("__aeabi_memclr", __aeabi_memclr, linkage);
106 @export("__aeabi_memclr4", __aeabi_memclr, linkage);
107 @export("__aeabi_memclr8", __aeabi_memclr, linkage);
108
109 @export("__aeabi_memcmp", __aeabi_memcmp, linkage);
110 @export("__aeabi_memcmp4", __aeabi_memcmp, linkage);
111 @export("__aeabi_memcmp8", __aeabi_memcmp, linkage);
112
113 @export("__aeabi_fneg", @import("compiler_rt/negXf2.zig").__negsf2, linkage);
114 @export("__aeabi_dneg", @import("compiler_rt/negXf2.zig").__negdf2, linkage);
115
116 @export("__aeabi_fmul", @import("compiler_rt/mulXf3.zig").__mulsf3, linkage);
117 @export("__aeabi_dmul", @import("compiler_rt/mulXf3.zig").__muldf3, linkage);
118
119 @export("__aeabi_d2h", @import("compiler_rt/truncXfYf2.zig").__truncdfhf2, linkage);
120
121 @export("__aeabi_f2ulz", @import("compiler_rt/fixunssfdi.zig").__fixunssfdi, linkage);
122 @export("__aeabi_d2ulz", @import("compiler_rt/fixunsdfdi.zig").__fixunsdfdi, linkage);
123
124 @export("__aeabi_f2lz", @import("compiler_rt/fixsfdi.zig").__fixsfdi, linkage);
125 @export("__aeabi_d2lz", @import("compiler_rt/fixdfdi.zig").__fixdfdi, linkage);
126
127 @export("__aeabi_d2uiz", @import("compiler_rt/fixunsdfsi.zig").__fixunsdfsi, linkage);
128
129 @export("__aeabi_h2f", @import("compiler_rt/extendXfYf2.zig").__extendhfsf2, linkage);
130 @export("__aeabi_f2h", @import("compiler_rt/truncXfYf2.zig").__truncsfhf2, linkage);
131
132 @export("__aeabi_fadd", @import("compiler_rt/addXf3.zig").__addsf3, linkage);
133 @export("__aeabi_dadd", @import("compiler_rt/addXf3.zig").__adddf3, linkage);
134 @export("__aeabi_fsub", @import("compiler_rt/addXf3.zig").__subsf3, linkage);
135 @export("__aeabi_dsub", @import("compiler_rt/addXf3.zig").__subdf3, linkage);
136
137 @export("__aeabi_f2uiz", @import("compiler_rt/fixunssfsi.zig").__fixunssfsi, linkage);
138
139 @export("__aeabi_f2iz", @import("compiler_rt/fixsfsi.zig").__fixsfsi, linkage);
140 @export("__aeabi_d2iz", @import("compiler_rt/fixdfsi.zig").__fixdfsi, linkage);
85141 }
86142 if (builtin.os == builtin.Os.windows) {
87143 switch (builtin.arch) {
......@@ -187,6 +243,17 @@ const is_arm_arch = switch (builtin.arch) {
187243 else => false,
188244};
189245
246const is_arm_32 = is_arm_arch and !is_arm_64;
247
248const use_thumb_1 = is_arm_32 and switch (builtin.arch.arm) {
249 builtin.Arch.Arm32.v6,
250 builtin.Arch.Arm32.v6m,
251 builtin.Arch.Arm32.v6k,
252 builtin.Arch.Arm32.v6t2,
253 => true,
254 else => false,
255};
256
190257nakedcc fn __aeabi_uidivmod() void {
191258 @setRuntimeSafety(false);
192259 asm volatile (
......@@ -203,6 +270,96 @@ nakedcc fn __aeabi_uidivmod() void {
203270 );
204271}
205272
273nakedcc fn __aeabi_memcpy() noreturn {
274 @setRuntimeSafety(false);
275 if (use_thumb_1) {
276 asm volatile (
277 \\ push {r7, lr}
278 \\ bl memcpy
279 \\ pop {r7, pc}
280 );
281 } else {
282 asm volatile (
283 \\ b memcpy
284 );
285 }
286 unreachable;
287}
288
289nakedcc fn __aeabi_memmove() noreturn {
290 @setRuntimeSafety(false);
291 if (use_thumb_1) {
292 asm volatile (
293 \\ push {r7, lr}
294 \\ bl memmove
295 \\ pop {r7, pc}
296 );
297 } else {
298 asm volatile (
299 \\ b memmove
300 );
301 }
302 unreachable;
303}
304
305nakedcc fn __aeabi_memset() noreturn {
306 @setRuntimeSafety(false);
307 if (use_thumb_1) {
308 asm volatile (
309 \\ mov r3, r1
310 \\ mov r1, r2
311 \\ mov r2, r3
312 \\ push {r7, lr}
313 \\ b memset
314 \\ pop {r7, pc}
315 );
316 } else {
317 asm volatile (
318 \\ mov r3, r1
319 \\ mov r1, r2
320 \\ mov r2, r3
321 \\ b memset
322 );
323 }
324 unreachable;
325}
326
327nakedcc fn __aeabi_memclr() noreturn {
328 @setRuntimeSafety(false);
329 if (use_thumb_1) {
330 asm volatile (
331 \\ mov r2, r1
332 \\ movs r1, #0
333 \\ push {r7, lr}
334 \\ bl memset
335 \\ pop {r7, pc}
336 );
337 } else {
338 asm volatile (
339 \\ mov r2, r1
340 \\ movs r1, #0
341 \\ b memset
342 );
343 }
344 unreachable;
345}
346
347nakedcc fn __aeabi_memcmp() noreturn {
348 @setRuntimeSafety(false);
349 if (use_thumb_1) {
350 asm volatile (
351 \\ push {r7, lr}
352 \\ bl memcmp
353 \\ pop {r7, pc}
354 );
355 } else {
356 asm volatile (
357 \\ b memcmp
358 );
359 }
360 unreachable;
361}
362
206363// _chkstk (_alloca) routine - probe stack between %esp and (%esp-%eax) in 4k increments,
207364// then decrement %esp by %eax. Preserves all registers except %esp and flags.
208365// This routine is windows specific
std/special/compiler_rt/addXf3.zig+30-8
......@@ -6,27 +6,49 @@ const std = @import("std");
66const builtin = @import("builtin");
77const compiler_rt = @import("../compiler_rt.zig");
88
9pub extern fn __addsf3(a: f32, b: f32) f32 {
10 return addXf3(f32, a, b);
11}
12
13pub extern fn __adddf3(a: f64, b: f64) f64 {
14 return addXf3(f64, a, b);
15}
16
917pub extern fn __addtf3(a: f128, b: f128) f128 {
1018 return addXf3(f128, a, b);
1119}
1220
21pub extern fn __subsf3(a: f32, b: f32) f32 {
22 const neg_b = @bitCast(f32, @bitCast(u32, b) ^ (u32(1) << 31));
23 return addXf3(f32, a, neg_b);
24}
25
26pub extern fn __subdf3(a: f64, b: f64) f64 {
27 const neg_b = @bitCast(f64, @bitCast(u64, b) ^ (u64(1) << 63));
28 return addXf3(f64, a, neg_b);
29}
30
1331pub extern fn __subtf3(a: f128, b: f128) f128 {
1432 const neg_b = @bitCast(f128, @bitCast(u128, b) ^ (u128(1) << 127));
1533 return addXf3(f128, a, neg_b);
1634}
1735
18inline fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {
36// TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154
37fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {
1938 const Z = @IntType(false, T.bit_count);
39 const S = @IntType(false, T.bit_count - @clz(Z(T.bit_count) - 1));
2040 const significandBits = std.math.floatMantissaBits(T);
2141 const implicitBit = Z(1) << significandBits;
2242
2343 const shift = @clz(significand.*) - @clz(implicitBit);
24 significand.* <<= @intCast(u7, shift);
44 significand.* <<= @intCast(S, shift);
2545 return 1 - shift;
2646}
2747
28inline fn addXf3(comptime T: type, a: T, b: T) T {
48// TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154
49fn addXf3(comptime T: type, a: T, b: T) T {
2950 const Z = @IntType(false, T.bit_count);
51 const S = @IntType(false, T.bit_count - @clz(Z(T.bit_count) - 1));
3052
3153 const typeWidth = T.bit_count;
3254 const significandBits = std.math.floatMantissaBits(T);
......@@ -126,8 +148,8 @@ inline fn addXf3(comptime T: type, a: T, b: T) T {
126148 const @"align" = @intCast(Z, aExponent - bExponent);
127149 if (@"align" != 0) {
128150 if (@"align" < typeWidth) {
129 const sticky = if (bSignificand << @intCast(u7, typeWidth - @"align") != 0) Z(1) else 0;
130 bSignificand = (bSignificand >> @truncate(u7, @"align")) | sticky;
151 const sticky = if (bSignificand << @intCast(S, typeWidth - @"align") != 0) Z(1) else 0;
152 bSignificand = (bSignificand >> @truncate(S, @"align")) | sticky;
131153 } else {
132154 bSignificand = 1; // sticky; b is known to be non-zero.
133155 }
......@@ -141,7 +163,7 @@ inline fn addXf3(comptime T: type, a: T, b: T) T {
141163 // and adjust the exponent:
142164 if (aSignificand < implicitBit << 3) {
143165 const shift = @intCast(i32, @clz(aSignificand)) - @intCast(i32, @clz(implicitBit << 3));
144 aSignificand <<= @intCast(u7, shift);
166 aSignificand <<= @intCast(S, shift);
145167 aExponent -= shift;
146168 }
147169 } else { // addition
......@@ -163,8 +185,8 @@ inline fn addXf3(comptime T: type, a: T, b: T) T {
163185 // Result is denormal before rounding; the exponent is zero and we
164186 // need to shift the significand.
165187 const shift = @intCast(Z, 1 - aExponent);
166 const sticky = if (aSignificand << @intCast(u7, typeWidth - shift) != 0) Z(1) else 0;
167 aSignificand = aSignificand >> @intCast(u7, shift | sticky);
188 const sticky = if (aSignificand << @intCast(S, typeWidth - shift) != 0) Z(1) else 0;
189 aSignificand = aSignificand >> @intCast(S, shift | sticky);
168190 aExponent = 0;
169191 }
170192
std/special/compiler_rt/negXf2.zig created+21
......@@ -0,0 +1,21 @@
1const std = @import("std");
2
3pub extern fn __negsf2(a: f32) f32 {
4 return negXf2(f32, a);
5}
6
7pub extern fn __negdf2(a: f64) f64 {
8 return negXf2(f64, a);
9}
10
11fn negXf2(comptime T: type, a: T) T {
12 const Z = @IntType(false, T.bit_count);
13
14 const typeWidth = T.bit_count;
15 const significandBits = std.math.floatMantissaBits(T);
16 const exponentBits = std.math.floatExponentBits(T);
17
18 const signBit = (Z(1) << (significandBits + exponentBits));
19
20 return @bitCast(T, @bitCast(Z, a) ^ signBit);
21}