Commit fd2c1d8605
Changed files (8)
lib
libc
mingw
math
misc
std
special
compiler_rt
src
test
lib/libc/mingw/math/arm-common/log2.c
@@ -0,0 +1,55 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+
+#include <math.h>
+#include <stdint.h>
+
+typedef union ieee754_double_ {
+ struct __attribute__((__packed__)) {
+ uint64_t f52 : 52;
+ uint64_t exp : 11;
+ uint64_t sgn : 1;
+ };
+ double f;
+} ieee754_double;
+
+typedef union ieee754_float_ {
+ struct __attribute__((__packed__)) {
+ uint32_t f23 : 23;
+ uint32_t exp : 8;
+ uint32_t sgn : 1;
+ };
+ float f;
+} ieee754_float;
+
+double log2(double x)
+{
+ ieee754_double u = { .f = x };
+ if (u.sgn == 0 && u.f52 == 0 && u.exp > 0 && u.exp < 0x7ff) {
+ // Handle exact powers of two exactly
+ return (int)u.exp - 1023;
+ }
+ return log(x) / 0.69314718246459960938;
+}
+
+float log2f(float x)
+{
+ ieee754_float u = { .f = x };
+ if (u.sgn == 0 && u.f23 == 0 && u.exp > 0 && u.exp < 0xff) {
+ // Handle exact powers of two exactly
+ return (int)u.exp - 127;
+ }
+ return logf(x) / 0.69314718246459960938f;
+}
+
+long double log2l(long double x)
+{
+#if defined(__arm__) || defined(_ARM_) || defined(__aarch64__) || defined(_ARM64_)
+ return log2(x);
+#else
+#error Not supported on your platform yet
+#endif
+}
lib/libc/mingw/math/arm-common/pow.c
@@ -0,0 +1,21 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+
+#include <math.h>
+#include <limits.h>
+
+extern double (* __MINGW_IMP_SYMBOL(pow))(double, double);
+
+double pow(double x, double y)
+{
+ if (x == 1.0)
+ return 1.0;
+ if (y == 0.0)
+ return 1.0;
+ if (x == -1.0 && isinf(y))
+ return 1.0;
+ return __MINGW_IMP_SYMBOL(pow)(x, y);
+}
lib/libc/mingw/math/bsd_private_base.h
@@ -0,0 +1,148 @@
+/*
+* ====================================================
+* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+*
+* Developed at SunPro, a Sun Microsystems, Inc. business.
+* Permission to use, copy, modify, and distribute this
+* software is freely granted, provided that this notice
+* is preserved.
+* ====================================================
+*/
+
+#include <inttypes.h>
+#include <float.h>
+
+typedef unsigned int u_int32_t;
+
+typedef union
+{
+ double value;
+ struct
+ {
+ u_int32_t lsw;
+ u_int32_t msw;
+ } parts;
+} ieee_double_shape_type;
+
+typedef union {
+ float value;
+ u_int32_t word;
+} ieee_float_shape_type;
+
+/* Get two 32 bit ints from a double. */
+
+#define EXTRACT_WORDS(ix0,ix1,d) \
+do { \
+ ieee_double_shape_type ew_u; \
+ ew_u.value = (d); \
+ (ix0) = ew_u.parts.msw; \
+ (ix1) = ew_u.parts.lsw; \
+} while (0)
+
+/* Get the most significant 32 bit int from a double. */
+
+#define GET_HIGH_WORD(i,d) \
+do { \
+ ieee_double_shape_type gh_u; \
+ gh_u.value = (d); \
+ (i) = gh_u.parts.msw; \
+} while (0)
+
+/* Get the less significant 32 bit int from a double. */
+
+#define GET_LOW_WORD(i,d) \
+do { \
+ ieee_double_shape_type gl_u; \
+ gl_u.value = (d); \
+ (i) = gl_u.parts.lsw; \
+} while (0)
+
+/* Set a double from two 32 bit ints. */
+
+#define INSERT_WORDS(d,ix0,ix1) \
+do { \
+ ieee_double_shape_type iw_u; \
+ iw_u.parts.msw = (ix0); \
+ iw_u.parts.lsw = (ix1); \
+ (d) = iw_u.value; \
+} while (0)
+
+/* Set the more significant 32 bits of a double from an int. */
+
+#define SET_HIGH_WORD(d,v) \
+do { \
+ ieee_double_shape_type sh_u; \
+ sh_u.value = (d); \
+ sh_u.parts.msw = (v); \
+ (d) = sh_u.value; \
+} while (0)
+
+/* Set the less significant 32 bits of a double from an int. */
+
+#define SET_LOW_WORD(d,v) \
+do { \
+ ieee_double_shape_type sl_u; \
+ sl_u.value = (d); \
+ sl_u.parts.lsw = (v); \
+ (d) = sl_u.value; \
+} while (0)
+
+#define GET_FLOAT_WORD(i,d) do \
+{ \
+ ieee_float_shape_type gf_u; \
+ gf_u.value = (d); \
+ (i) = gf_u.word; \
+} while(0)
+
+#define SET_FLOAT_WORD(d,i) do \
+{ \
+ ieee_float_shape_type gf_u; \
+ gf_u.word = (i); \
+ (d) = gf_u.value; \
+} while(0)
+
+
+#ifdef FLT_EVAL_METHOD
+/*
+ * Attempt to get strict C99 semantics for assignment with non-C99 compilers.
+ */
+#if FLT_EVAL_METHOD == 0 || __GNUC__ == 0
+#define STRICT_ASSIGN(type, lval, rval) ((lval) = (rval))
+#else
+#define STRICT_ASSIGN(type, lval, rval) do { \
+ volatile type __lval; \
+ \
+ if (sizeof(type) >= sizeof(long double)) \
+ (lval) = (rval); \
+ else { \
+ __lval = (rval); \
+ (lval) = __lval; \
+ } \
+} while (0)
+#endif
+#endif /* FLT_EVAL_METHOD */
+
+/*
+ * Mix 0, 1 or 2 NaNs. First add 0 to each arg. This normally just turns
+ * signaling NaNs into quiet NaNs by setting a quiet bit. We do this
+ * because we want to never return a signaling NaN, and also because we
+ * don't want the quiet bit to affect the result. Then mix the converted
+ * args using the specified operation.
+ *
+ * When one arg is NaN, the result is typically that arg quieted. When both
+ * args are NaNs, the result is typically the quietening of the arg whose
+ * mantissa is largest after quietening. When neither arg is NaN, the
+ * result may be NaN because it is indeterminate, or finite for subsequent
+ * construction of a NaN as the indeterminate 0.0L/0.0L.
+ *
+ * Technical complications: the result in bits after rounding to the final
+ * precision might depend on the runtime precision and/or on compiler
+ * optimizations, especially when different register sets are used for
+ * different precisions. Try to make the result not depend on at least the
+ * runtime precision by always doing the main mixing step in long double
+ * precision. Try to reduce dependencies on optimizations by adding the
+ * the 0's in different precisions (unless everything is in long double
+ * precision).
+ */
+#define nan_mix(x, y) (nan_mix_op((x), (y), +))
+#define nan_mix_op(x, y, op) (((x) + 0.0L) op ((y) + 0))
lib/libc/mingw/misc/initenv.c
@@ -0,0 +1,12 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+
+#include <wchar.h>
+
+static char ** local__initenv;
+static wchar_t ** local__winitenv;
+char *** __MINGW_IMP_SYMBOL(__initenv) = &local__initenv;
+wchar_t *** __MINGW_IMP_SYMBOL(__winitenv) = &local__winitenv;
lib/std/special/compiler_rt/stack_probe.zig
@@ -53,6 +53,19 @@ pub fn zig_probe_stack() callconv(.Naked) void {
},
else => {},
}
+ if (comptime native_arch.isAARCH64()) {
+ asm volatile (
+ \\ lsl x16, x15, #4
+ \\ mov x17, sp
+ \\1:
+ \\ sub x17, x17, #PAGE_SIZE
+ \\ subs x16, x16, #PAGE_SIZE
+ \\ ldr xzr, [x17]
+ \\ b.gt 1b
+ \\
+ \\ ret
+ );
+ }
unreachable;
}
lib/std/special/compiler_rt.zig
@@ -576,6 +576,18 @@ comptime {
},
else => {},
}
+ if (arch.isAARCH64()) {
+ const __chkstk = @import("compiler_rt/stack_probe.zig").__chkstk;
+ @export(__chkstk, .{ .name = "__chkstk", .linkage = strong_linkage });
+ const __divti3_windows = @import("compiler_rt/divti3.zig").__divti3;
+ @export(__divti3_windows, .{ .name = "__divti3", .linkage = linkage });
+ const __modti3 = @import("compiler_rt/modti3.zig").__modti3;
+ @export(__modti3, .{ .name = "__modti3", .linkage = linkage });
+ const __udivti3_windows = @import("compiler_rt/udivti3.zig").__udivti3;
+ @export(__udivti3_windows, .{ .name = "__udivti3", .linkage = linkage });
+ const __umodti3 = @import("compiler_rt/umodti3.zig").__umodti3;
+ @export(__umodti3, .{ .name = "__umodti3", .linkage = linkage });
+ }
} else {
const __divti3 = @import("compiler_rt/divti3.zig").__divti3;
@export(__divti3, .{ .name = "__divti3", .linkage = linkage });
src/mingw.zig
@@ -1022,6 +1022,9 @@ const mingwex_arm32_src = [_][]const u8{
};
const mingwex_arm64_src = [_][]const u8{
+ "misc" ++ path.sep_str ++ "initenv.c",
+ "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "log2.c",
+ "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "pow.c",
"math" ++ path.sep_str ++ "arm64" ++ path.sep_str ++ "_chgsignl.S",
"math" ++ path.sep_str ++ "arm64" ++ path.sep_str ++ "rint.c",
"math" ++ path.sep_str ++ "arm64" ++ path.sep_str ++ "rintf.c",
test/tests.zig
@@ -137,6 +137,14 @@ const test_targets = blk: {
},
.link_libc = true,
},
+ TestTarget{
+ .target = .{
+ .cpu_arch = .aarch64,
+ .os_tag = .windows,
+ .abi = .gnu,
+ },
+ .link_libc = true,
+ },
TestTarget{
.target = CrossTarget.parse(.{