authorgravatar for johnnymarler@gmail.comJonathan Marler <johnnymarler@gmail.com> 2021-09-07 10:44:21-06:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2021-09-07 19:44:21+03:00
logfd2c1d860503ec6cd71ab9a692ad2dbf6bd3c269
tree3e6b25a478390b5e1797637a019456baf8d7b2d7
parent16c3cd3d19624595f9a840b2147bdf57f4b9e284
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Fix building aarch64-windows-gnu by adding missing libc files and compiler_rt functions (#9555)

* fix issue 9519 Added some missing files from mingw * add missing compiler_rt functions * finish PR * add aarch64-windows-gnu to test targets * add more compiler_rt * add log2 * add pow * add modti3

8 files changed, 272 insertions(+), 0 deletions(-)

lib/libc/mingw/math/arm-common/log2.c created+55
......@@ -0,0 +1,55 @@
1/**
2 * This file has no copyright assigned and is placed in the Public Domain.
3 * This file is part of the mingw-w64 runtime package.
4 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
5 */
6
7#include <math.h>
8#include <stdint.h>
9
10typedef union ieee754_double_ {
11 struct __attribute__((__packed__)) {
12 uint64_t f52 : 52;
13 uint64_t exp : 11;
14 uint64_t sgn : 1;
15 };
16 double f;
17} ieee754_double;
18
19typedef union ieee754_float_ {
20 struct __attribute__((__packed__)) {
21 uint32_t f23 : 23;
22 uint32_t exp : 8;
23 uint32_t sgn : 1;
24 };
25 float f;
26} ieee754_float;
27
28double log2(double x)
29{
30 ieee754_double u = { .f = x };
31 if (u.sgn == 0 && u.f52 == 0 && u.exp > 0 && u.exp < 0x7ff) {
32 // Handle exact powers of two exactly
33 return (int)u.exp - 1023;
34 }
35 return log(x) / 0.69314718246459960938;
36}
37
38float log2f(float x)
39{
40 ieee754_float u = { .f = x };
41 if (u.sgn == 0 && u.f23 == 0 && u.exp > 0 && u.exp < 0xff) {
42 // Handle exact powers of two exactly
43 return (int)u.exp - 127;
44 }
45 return logf(x) / 0.69314718246459960938f;
46}
47
48long double log2l(long double x)
49{
50#if defined(__arm__) || defined(_ARM_) || defined(__aarch64__) || defined(_ARM64_)
51 return log2(x);
52#else
53#error Not supported on your platform yet
54#endif
55}
lib/libc/mingw/math/arm-common/pow.c created+21
......@@ -0,0 +1,21 @@
1/**
2 * This file has no copyright assigned and is placed in the Public Domain.
3 * This file is part of the mingw-w64 runtime package.
4 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
5 */
6
7#include <math.h>
8#include <limits.h>
9
10extern double (* __MINGW_IMP_SYMBOL(pow))(double, double);
11
12double pow(double x, double y)
13{
14 if (x == 1.0)
15 return 1.0;
16 if (y == 0.0)
17 return 1.0;
18 if (x == -1.0 && isinf(y))
19 return 1.0;
20 return __MINGW_IMP_SYMBOL(pow)(x, y);
21}
lib/libc/mingw/math/bsd_private_base.h created+148
......@@ -0,0 +1,148 @@
1/*
2* ====================================================
3* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
4*
5* Developed at SunPro, a Sun Microsystems, Inc. business.
6* Permission to use, copy, modify, and distribute this
7* software is freely granted, provided that this notice
8* is preserved.
9* ====================================================
10*/
11
12#include <inttypes.h>
13#include <float.h>
14
15typedef unsigned int u_int32_t;
16
17typedef union
18{
19 double value;
20 struct
21 {
22 u_int32_t lsw;
23 u_int32_t msw;
24 } parts;
25} ieee_double_shape_type;
26
27typedef union {
28 float value;
29 u_int32_t word;
30} ieee_float_shape_type;
31
32/* Get two 32 bit ints from a double. */
33
34#define EXTRACT_WORDS(ix0,ix1,d) \
35do { \
36 ieee_double_shape_type ew_u; \
37 ew_u.value = (d); \
38 (ix0) = ew_u.parts.msw; \
39 (ix1) = ew_u.parts.lsw; \
40} while (0)
41
42/* Get the most significant 32 bit int from a double. */
43
44#define GET_HIGH_WORD(i,d) \
45do { \
46 ieee_double_shape_type gh_u; \
47 gh_u.value = (d); \
48 (i) = gh_u.parts.msw; \
49} while (0)
50
51/* Get the less significant 32 bit int from a double. */
52
53#define GET_LOW_WORD(i,d) \
54do { \
55 ieee_double_shape_type gl_u; \
56 gl_u.value = (d); \
57 (i) = gl_u.parts.lsw; \
58} while (0)
59
60/* Set a double from two 32 bit ints. */
61
62#define INSERT_WORDS(d,ix0,ix1) \
63do { \
64 ieee_double_shape_type iw_u; \
65 iw_u.parts.msw = (ix0); \
66 iw_u.parts.lsw = (ix1); \
67 (d) = iw_u.value; \
68} while (0)
69
70/* Set the more significant 32 bits of a double from an int. */
71
72#define SET_HIGH_WORD(d,v) \
73do { \
74 ieee_double_shape_type sh_u; \
75 sh_u.value = (d); \
76 sh_u.parts.msw = (v); \
77 (d) = sh_u.value; \
78} while (0)
79
80/* Set the less significant 32 bits of a double from an int. */
81
82#define SET_LOW_WORD(d,v) \
83do { \
84 ieee_double_shape_type sl_u; \
85 sl_u.value = (d); \
86 sl_u.parts.lsw = (v); \
87 (d) = sl_u.value; \
88} while (0)
89
90#define GET_FLOAT_WORD(i,d) do \
91{ \
92 ieee_float_shape_type gf_u; \
93 gf_u.value = (d); \
94 (i) = gf_u.word; \
95} while(0)
96
97#define SET_FLOAT_WORD(d,i) do \
98{ \
99 ieee_float_shape_type gf_u; \
100 gf_u.word = (i); \
101 (d) = gf_u.value; \
102} while(0)
103
104
105#ifdef FLT_EVAL_METHOD
106/*
107 * Attempt to get strict C99 semantics for assignment with non-C99 compilers.
108 */
109#if FLT_EVAL_METHOD == 0 || __GNUC__ == 0
110#define STRICT_ASSIGN(type, lval, rval) ((lval) = (rval))
111#else
112#define STRICT_ASSIGN(type, lval, rval) do { \
113 volatile type __lval; \
114 \
115 if (sizeof(type) >= sizeof(long double)) \
116 (lval) = (rval); \
117 else { \
118 __lval = (rval); \
119 (lval) = __lval; \
120 } \
121} while (0)
122#endif
123#endif /* FLT_EVAL_METHOD */
124
125/*
126 * Mix 0, 1 or 2 NaNs. First add 0 to each arg. This normally just turns
127 * signaling NaNs into quiet NaNs by setting a quiet bit. We do this
128 * because we want to never return a signaling NaN, and also because we
129 * don't want the quiet bit to affect the result. Then mix the converted
130 * args using the specified operation.
131 *
132 * When one arg is NaN, the result is typically that arg quieted. When both
133 * args are NaNs, the result is typically the quietening of the arg whose
134 * mantissa is largest after quietening. When neither arg is NaN, the
135 * result may be NaN because it is indeterminate, or finite for subsequent
136 * construction of a NaN as the indeterminate 0.0L/0.0L.
137 *
138 * Technical complications: the result in bits after rounding to the final
139 * precision might depend on the runtime precision and/or on compiler
140 * optimizations, especially when different register sets are used for
141 * different precisions. Try to make the result not depend on at least the
142 * runtime precision by always doing the main mixing step in long double
143 * precision. Try to reduce dependencies on optimizations by adding the
144 * the 0's in different precisions (unless everything is in long double
145 * precision).
146 */
147#define nan_mix(x, y) (nan_mix_op((x), (y), +))
148#define nan_mix_op(x, y, op) (((x) + 0.0L) op ((y) + 0))
lib/libc/mingw/misc/initenv.c created+12
......@@ -0,0 +1,12 @@
1/**
2 * This file has no copyright assigned and is placed in the Public Domain.
3 * This file is part of the mingw-w64 runtime package.
4 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
5 */
6
7#include <wchar.h>
8
9static char ** local__initenv;
10static wchar_t ** local__winitenv;
11char *** __MINGW_IMP_SYMBOL(__initenv) = &local__initenv;
12wchar_t *** __MINGW_IMP_SYMBOL(__winitenv) = &local__winitenv;
lib/std/special/compiler_rt.zig+12
......@@ -576,6 +576,18 @@ comptime {
576576 },
577577 else => {},
578578 }
579 if (arch.isAARCH64()) {
580 const __chkstk = @import("compiler_rt/stack_probe.zig").__chkstk;
581 @export(__chkstk, .{ .name = "__chkstk", .linkage = strong_linkage });
582 const __divti3_windows = @import("compiler_rt/divti3.zig").__divti3;
583 @export(__divti3_windows, .{ .name = "__divti3", .linkage = linkage });
584 const __modti3 = @import("compiler_rt/modti3.zig").__modti3;
585 @export(__modti3, .{ .name = "__modti3", .linkage = linkage });
586 const __udivti3_windows = @import("compiler_rt/udivti3.zig").__udivti3;
587 @export(__udivti3_windows, .{ .name = "__udivti3", .linkage = linkage });
588 const __umodti3 = @import("compiler_rt/umodti3.zig").__umodti3;
589 @export(__umodti3, .{ .name = "__umodti3", .linkage = linkage });
590 }
579591 } else {
580592 const __divti3 = @import("compiler_rt/divti3.zig").__divti3;
581593 @export(__divti3, .{ .name = "__divti3", .linkage = linkage });
lib/std/special/compiler_rt/stack_probe.zig+13
......@@ -53,6 +53,19 @@ pub fn zig_probe_stack() callconv(.Naked) void {
5353 },
5454 else => {},
5555 }
56 if (comptime native_arch.isAARCH64()) {
57 asm volatile (
58 \\ lsl x16, x15, #4
59 \\ mov x17, sp
60 \\1:
61 \\ sub x17, x17, #PAGE_SIZE
62 \\ subs x16, x16, #PAGE_SIZE
63 \\ ldr xzr, [x17]
64 \\ b.gt 1b
65 \\
66 \\ ret
67 );
68 }
5669
5770 unreachable;
5871}
src/mingw.zig+3
......@@ -1022,6 +1022,9 @@ const mingwex_arm32_src = [_][]const u8{
10221022};
10231023
10241024const mingwex_arm64_src = [_][]const u8{
1025 "misc" ++ path.sep_str ++ "initenv.c",
1026 "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "log2.c",
1027 "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "pow.c",
10251028 "math" ++ path.sep_str ++ "arm64" ++ path.sep_str ++ "_chgsignl.S",
10261029 "math" ++ path.sep_str ++ "arm64" ++ path.sep_str ++ "rint.c",
10271030 "math" ++ path.sep_str ++ "arm64" ++ path.sep_str ++ "rintf.c",
test/tests.zig+8
......@@ -137,6 +137,14 @@ const test_targets = blk: {
137137 },
138138 .link_libc = true,
139139 },
140 TestTarget{
141 .target = .{
142 .cpu_arch = .aarch64,
143 .os_tag = .windows,
144 .abi = .gnu,
145 },
146 .link_libc = true,
147 },
140148
141149 TestTarget{
142150 .target = CrossTarget.parse(.{