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
This commit is contained in:
Jonathan Marler 2021-09-07 10:44:21 -06:00 committed by GitHub
parent 16c3cd3d19
commit fd2c1d8605
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 272 additions and 0 deletions

55
lib/libc/mingw/math/arm-common/log2.c vendored Normal file
View File

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

21
lib/libc/mingw/math/arm-common/pow.c vendored Normal file
View File

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

148
lib/libc/mingw/math/bsd_private_base.h vendored Normal file
View File

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

12
lib/libc/mingw/misc/initenv.c vendored Normal file
View File

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

View File

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

View File

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

View File

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

View File

@ -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(.{