mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
Merge remote-tracking branch 'origin/master' into llvm14
This commit is contained in:
commit
c89dd15e1b
7
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
7
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
contact_links:
|
||||||
|
- name: Language Proposal
|
||||||
|
about: Propose to improve the Zig language
|
||||||
|
url: https://github.com/ziglang/zig/wiki/Language-Proposals
|
||||||
|
- name: Question
|
||||||
|
about: Please use one of the community spaces for questions or general discussions.
|
||||||
|
url: https://github.com/ziglang/zig/wiki/Community
|
||||||
16
.github/ISSUE_TEMPLATE/proposal.yml
vendored
16
.github/ISSUE_TEMPLATE/proposal.yml
vendored
@ -1,16 +0,0 @@
|
|||||||
name: Language Proposal
|
|
||||||
description: Propose to improve the Zig language
|
|
||||||
labels: ["proposal"]
|
|
||||||
body:
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
Thank you for your interest in improving the Zig language. However, we are
|
|
||||||
not accepting new proposals to change the language at this time.
|
|
||||||
- type: checkboxes
|
|
||||||
id: trash
|
|
||||||
attributes:
|
|
||||||
label: Please do not file a proposal to change the language
|
|
||||||
options:
|
|
||||||
- label: "I understand, thank you. I will not submit a new proposal at this time"
|
|
||||||
required: true
|
|
||||||
20
.github/ISSUE_TEMPLATE/question.yml
vendored
20
.github/ISSUE_TEMPLATE/question.yml
vendored
@ -1,20 +0,0 @@
|
|||||||
name: Question
|
|
||||||
description: Ask a Zig-related question
|
|
||||||
labels: ["question"]
|
|
||||||
body:
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
Welcome! There are a bunch of great places to ask Zig-related questions.
|
|
||||||
Please take a look at
|
|
||||||
[The Community Wiki Page](https://github.com/ziglang/zig/wiki/Community) and
|
|
||||||
find a comfy place to ask questions. You will find plenty of helpful people in
|
|
||||||
these spaces. However, this issue tracker is not for questions. It is for
|
|
||||||
more actionable items such as bug reports and enhancements.
|
|
||||||
- type: checkboxes
|
|
||||||
id: trash
|
|
||||||
attributes:
|
|
||||||
label: Please do not open a question issue on the bug tracker
|
|
||||||
options:
|
|
||||||
- label: "I understand, thank you. I will take my question to one of the community spaces instead"
|
|
||||||
required: true
|
|
||||||
275
CMakeLists.txt
275
CMakeLists.txt
@ -12,7 +12,7 @@ if(NOT CMAKE_BUILD_TYPE)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT CMAKE_INSTALL_PREFIX)
|
if(NOT CMAKE_INSTALL_PREFIX)
|
||||||
set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}" CACHE STRING
|
set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/stage1" CACHE STRING
|
||||||
"Directory to install zig to" FORCE)
|
"Directory to install zig to" FORCE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ if("${ZIG_VERSION}" STREQUAL "")
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
message("Configuring zig version ${ZIG_VERSION}")
|
message(STATUS "Configuring zig version ${ZIG_VERSION}")
|
||||||
|
|
||||||
set(ZIG_STATIC off CACHE BOOL "Attempt to build a static zig executable (not compatible with glibc)")
|
set(ZIG_STATIC off CACHE BOOL "Attempt to build a static zig executable (not compatible with glibc)")
|
||||||
set(ZIG_STATIC_LLVM off CACHE BOOL "Prefer linking against static LLVM libraries")
|
set(ZIG_STATIC_LLVM off CACHE BOOL "Prefer linking against static LLVM libraries")
|
||||||
@ -398,6 +398,9 @@ set(ZIG_STAGE2_SOURCES
|
|||||||
"${CMAKE_SOURCE_DIR}/lib/std/debug.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/debug.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/dwarf.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/dwarf.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/dwarf/AT.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/dwarf/AT.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/std/dwarf/ATE.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/std/dwarf/FORM.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/std/dwarf/LANG.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/dwarf/OP.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/dwarf/OP.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/dwarf/TAG.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/dwarf/TAG.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/elf.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/elf.zig"
|
||||||
@ -441,9 +444,8 @@ set(ZIG_STAGE2_SOURCES
|
|||||||
"${CMAKE_SOURCE_DIR}/lib/std/math.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/math.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/math/big.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/math/big.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/math/big/int.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/math/big/int.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/math/floor.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/math/float.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/math/frexp.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/math/frexp.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/math/inf.zig"
|
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/math/isinf.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/math/isinf.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/math/isnan.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/math/isnan.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/math/ln.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/math/ln.zig"
|
||||||
@ -460,12 +462,14 @@ set(ZIG_STAGE2_SOURCES
|
|||||||
"${CMAKE_SOURCE_DIR}/lib/std/meta/trait.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/meta/trait.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/multi_array_list.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/multi_array_list.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/os.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/os.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/std/os/darwin.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/os/linux.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/os/linux.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/os/linux/errno/generic.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/os/linux/errno/generic.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/os/linux/x86_64.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/os/linux/x86_64.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/os/linux.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/os/linux.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/os/linux/io_uring.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/os/linux/io_uring.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/os/linux/x86_64.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/os/linux/x86_64.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/std/os/posix_spawn.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/os/windows.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/os/windows.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/os/windows/ntstatus.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/os/windows/ntstatus.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/os/windows/win32error.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/os/windows/win32error.zig"
|
||||||
@ -474,74 +478,180 @@ set(ZIG_STAGE2_SOURCES
|
|||||||
"${CMAKE_SOURCE_DIR}/lib/std/process.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/process.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/rand.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/rand.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/sort.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/sort.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/absv.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/absv.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/addXf3.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/absvdi2.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/atomics.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/absvsi2.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/bswap.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/absvti2.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/clear_cache.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/adddf3.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/cmp.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/addf3.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/compareXf2.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/addo.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/count0bits.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/addsf3.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/divdf3.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/addtf3.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/divsf3.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/addxf3.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/divtf3.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/arm.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/divti3.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/atomics.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/extendXfYf2.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/aulldiv.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixdfdi.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/aullrem.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixdfsi.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/bswap.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixdfti.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/ceil.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixint.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/clear_cache.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixsfdi.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/cmp.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixsfsi.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/cmpdf2.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixsfti.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/cmpsf2.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixtfdi.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/cmptf2.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixtfsi.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/cmpxf2.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixtfti.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/common.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixuint.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/comparef.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixunsdfdi.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/cos.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixunsdfsi.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/count0bits.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixunsdfti.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/divdf3.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixunssfdi.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/divsf3.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixunssfsi.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/divtf3.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixunssfti.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/divti3.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixunstfdi.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/divxf3.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixunstfsi.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/emutls.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/fixunstfti.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/exp.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/floatXisf.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/exp2.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/floatdidf.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/extenddftf2.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/floatditf.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/extenddfxf2.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/floatsiXf.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/extendf.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/floattidf.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/extendhfsf2.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/floattitf.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/extendhftf2.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/floatundidf.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/extendhfxf2.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/floatundisf.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/extendsfdf2.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/floatunditf.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/extendsftf2.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/floatunsidf.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/extendsfxf2.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/floatunsisf.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/extendxftf2.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/floatunsitf.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fabs.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/floatuntidf.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fixdfdi.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/floatuntisf.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fixdfsi.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/floatuntitf.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fixdfti.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/int.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fixhfdi.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/modti3.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fixhfsi.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/mulXf3.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fixhfti.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/muldi3.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fixsfdi.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/mulo.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fixsfsi.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/multi3.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fixsfti.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/negXf2.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fixtfdi.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/negXi2.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fixtfsi.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/negv.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fixtfti.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/os_version_check.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fixunsdfdi.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/parity.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fixunsdfsi.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/popcount.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fixunsdfti.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/shift.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fixunshfdi.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/stack_probe.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fixunshfsi.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/truncXfYf2.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fixunshfti.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/udivmod.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fixunssfdi.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/udivmodti4.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fixunssfsi.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/udivti3.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fixunssfti.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/umodti3.zig"
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fixunstfdi.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fixunstfsi.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fixunstfti.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fixunsxfdi.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fixunsxfsi.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fixunsxfti.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fixxfdi.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fixxfsi.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fixxfti.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/float_to_int.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/floatdidf.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/floatdihf.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/floatdisf.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/floatditf.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/floatdixf.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/floatsidf.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/floatsihf.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/floatsisf.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/floatsitf.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/floatsixf.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/floattidf.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/floattihf.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/floattisf.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/floattitf.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/floattixf.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/floatundidf.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/floatundihf.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/floatundisf.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/floatunditf.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/floatundixf.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/floatunsidf.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/floatunsihf.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/floatunsisf.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/floatunsitf.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/floatunsixf.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/floatuntidf.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/floatuntihf.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/floatuntisf.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/floatuntitf.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/floatuntixf.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/floor.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fma.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fmax.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fmin.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/fmod.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/gedf2.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/gesf2.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/getf2.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/gexf2.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/int.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/int_to_float.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/log.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/log10.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/log2.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/modti3.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/muldf3.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/muldi3.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/mulf3.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/mulo.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/mulsf3.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/multf3.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/multi3.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/mulxf3.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/negXi2.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/negv.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/os_version_check.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/parity.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/popcount.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/rem_pio2.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/rem_pio2_large.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/rem_pio2f.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/round.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/shift.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/sin.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/sincos.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/sqrt.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/stack_probe.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/subo.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/subsf3.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/subdf3.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/subtf3.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/subxf3.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/negsf2.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/negdf2.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/negtf2.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/negxf2.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/tan.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/trig.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/trunc.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/truncdfhf2.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/truncdfsf2.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/truncf.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/truncsfhf2.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/trunctfdf2.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/trunctfhf2.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/trunctfsf2.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/trunctfxf2.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/truncxfdf2.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/truncxfhf2.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/truncxfsf2.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/udivmod.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/udivmodti4.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/udivti3.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/umodti3.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/unorddf2.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/unordsf2.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/compiler_rt/unordtf2.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/start.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/start.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/std.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/std.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/target.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/target.zig"
|
||||||
@ -561,16 +671,16 @@ set(ZIG_STAGE2_SOURCES
|
|||||||
"${CMAKE_SOURCE_DIR}/lib/std/target/wasm.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/target/wasm.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/target/x86.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/target/x86.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/Thread.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/Thread.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/Thread/AutoResetEvent.zig"
|
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/Thread/Futex.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/Thread/Futex.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/Thread/Mutex.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/Thread/Mutex.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/Thread/ResetEvent.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/Thread/ResetEvent.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/Thread/StaticResetEvent.zig"
|
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/time.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/time.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/std/treap.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/unicode.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/unicode.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/zig.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/zig.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/zig/Ast.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/zig/Ast.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/zig/CrossTarget.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/zig/CrossTarget.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib/std/zig/c_builtins.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/zig/parse.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/zig/parse.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/zig/render.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/zig/render.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/lib/std/zig/string_literal.zig"
|
"${CMAKE_SOURCE_DIR}/lib/std/zig/string_literal.zig"
|
||||||
@ -597,14 +707,22 @@ set(ZIG_STAGE2_SOURCES
|
|||||||
"${CMAKE_SOURCE_DIR}/src/arch/aarch64/Emit.zig"
|
"${CMAKE_SOURCE_DIR}/src/arch/aarch64/Emit.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/src/arch/aarch64/Mir.zig"
|
"${CMAKE_SOURCE_DIR}/src/arch/aarch64/Mir.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/src/arch/aarch64/bits.zig"
|
"${CMAKE_SOURCE_DIR}/src/arch/aarch64/bits.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/src/arch/aarch64/abi.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/src/arch/arm/CodeGen.zig"
|
"${CMAKE_SOURCE_DIR}/src/arch/arm/CodeGen.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/src/arch/arm/Emit.zig"
|
"${CMAKE_SOURCE_DIR}/src/arch/arm/Emit.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/src/arch/arm/Mir.zig"
|
"${CMAKE_SOURCE_DIR}/src/arch/arm/Mir.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/src/arch/arm/bits.zig"
|
"${CMAKE_SOURCE_DIR}/src/arch/arm/bits.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/src/arch/arm/abi.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/src/arch/riscv64/CodeGen.zig"
|
"${CMAKE_SOURCE_DIR}/src/arch/riscv64/CodeGen.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/src/arch/riscv64/Emit.zig"
|
"${CMAKE_SOURCE_DIR}/src/arch/riscv64/Emit.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/src/arch/riscv64/Mir.zig"
|
"${CMAKE_SOURCE_DIR}/src/arch/riscv64/Mir.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/src/arch/riscv64/bits.zig"
|
"${CMAKE_SOURCE_DIR}/src/arch/riscv64/bits.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/src/arch/riscv64/abi.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/src/arch/sparc64/CodeGen.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/src/arch/sparc64/Emit.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/src/arch/sparc64/Mir.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/src/arch/sparc64/bits.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/src/arch/sparc64/abi.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/src/arch/wasm/CodeGen.zig"
|
"${CMAKE_SOURCE_DIR}/src/arch/wasm/CodeGen.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/src/arch/wasm/Emit.zig"
|
"${CMAKE_SOURCE_DIR}/src/arch/wasm/Emit.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/src/arch/wasm/Mir.zig"
|
"${CMAKE_SOURCE_DIR}/src/arch/wasm/Mir.zig"
|
||||||
@ -612,6 +730,7 @@ set(ZIG_STAGE2_SOURCES
|
|||||||
"${CMAKE_SOURCE_DIR}/src/arch/x86_64/Emit.zig"
|
"${CMAKE_SOURCE_DIR}/src/arch/x86_64/Emit.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/src/arch/x86_64/Mir.zig"
|
"${CMAKE_SOURCE_DIR}/src/arch/x86_64/Mir.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/src/arch/x86_64/bits.zig"
|
"${CMAKE_SOURCE_DIR}/src/arch/x86_64/bits.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/src/arch/x86_64/abi.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/src/clang.zig"
|
"${CMAKE_SOURCE_DIR}/src/clang.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/src/clang_options.zig"
|
"${CMAKE_SOURCE_DIR}/src/clang_options.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/src/clang_options_data.zig"
|
"${CMAKE_SOURCE_DIR}/src/clang_options_data.zig"
|
||||||
@ -655,6 +774,7 @@ set(ZIG_STAGE2_SOURCES
|
|||||||
"${CMAKE_SOURCE_DIR}/src/print_env.zig"
|
"${CMAKE_SOURCE_DIR}/src/print_env.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/src/print_targets.zig"
|
"${CMAKE_SOURCE_DIR}/src/print_targets.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/src/print_zir.zig"
|
"${CMAKE_SOURCE_DIR}/src/print_zir.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/src/register_manager.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/src/stage1.zig"
|
"${CMAKE_SOURCE_DIR}/src/stage1.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/src/target.zig"
|
"${CMAKE_SOURCE_DIR}/src/target.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/src/tracy.zig"
|
"${CMAKE_SOURCE_DIR}/src/tracy.zig"
|
||||||
@ -791,6 +911,9 @@ add_library(opt_c_util STATIC ${OPTIMIZED_C_SOURCES})
|
|||||||
set_target_properties(opt_c_util PROPERTIES
|
set_target_properties(opt_c_util PROPERTIES
|
||||||
COMPILE_FLAGS "${OPTIMIZED_C_FLAGS}"
|
COMPILE_FLAGS "${OPTIMIZED_C_FLAGS}"
|
||||||
)
|
)
|
||||||
|
target_include_directories(opt_c_util PRIVATE
|
||||||
|
"${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e-prebuilt"
|
||||||
|
)
|
||||||
|
|
||||||
add_library(zigstage1 STATIC ${STAGE1_SOURCES})
|
add_library(zigstage1 STATIC ${STAGE1_SOURCES})
|
||||||
set_target_properties(zigstage1 PROPERTIES
|
set_target_properties(zigstage1 PROPERTIES
|
||||||
@ -834,7 +957,7 @@ else()
|
|||||||
set(ZIG1_RELEASE_ARG -OReleaseFast --strip)
|
set(ZIG1_RELEASE_ARG -OReleaseFast --strip)
|
||||||
endif()
|
endif()
|
||||||
if(ZIG_SINGLE_THREADED)
|
if(ZIG_SINGLE_THREADED)
|
||||||
set(ZIG1_SINGLE_THREADED_ARG "--single-threaded")
|
set(ZIG1_SINGLE_THREADED_ARG "-fsingle-threaded")
|
||||||
else()
|
else()
|
||||||
set(ZIG1_SINGLE_THREADED_ARG "")
|
set(ZIG1_SINGLE_THREADED_ARG "")
|
||||||
endif()
|
endif()
|
||||||
@ -852,7 +975,7 @@ set(BUILD_ZIG1_ARGS
|
|||||||
-lc
|
-lc
|
||||||
--pkg-begin build_options "${ZIG_CONFIG_ZIG_OUT}"
|
--pkg-begin build_options "${ZIG_CONFIG_ZIG_OUT}"
|
||||||
--pkg-end
|
--pkg-end
|
||||||
--pkg-begin compiler_rt "${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt.zig"
|
--pkg-begin compiler_rt "${CMAKE_SOURCE_DIR}/lib/compiler_rt.zig"
|
||||||
--pkg-end
|
--pkg-end
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -9,8 +9,8 @@ A general-purpose programming language and toolchain for maintaining
|
|||||||
* [Download & Documentation](https://ziglang.org/download)
|
* [Download & Documentation](https://ziglang.org/download)
|
||||||
* [Chapter 0 - Getting Started | ZigLearn.org](https://ziglearn.org/)
|
* [Chapter 0 - Getting Started | ZigLearn.org](https://ziglearn.org/)
|
||||||
* [Community](https://github.com/ziglang/zig/wiki/Community)
|
* [Community](https://github.com/ziglang/zig/wiki/Community)
|
||||||
* [Contributing](https://github.com/ziglang/zig/blob/master/CONTRIBUTING.md)
|
* [Contributing](https://github.com/ziglang/zig/blob/master/.github/CONTRIBUTING.md)
|
||||||
* [Code of Conduct](https://github.com/ziglang/zig/blob/master/CODE_OF_CONDUCT.md)
|
* [Code of Conduct](https://github.com/ziglang/zig/blob/master/.github/CODE_OF_CONDUCT.md)
|
||||||
* [Frequently Asked Questions](https://github.com/ziglang/zig/wiki/FAQ)
|
* [Frequently Asked Questions](https://github.com/ziglang/zig/wiki/FAQ)
|
||||||
* [Community Projects](https://github.com/ziglang/zig/wiki/Community-Projects)
|
* [Community Projects](https://github.com/ziglang/zig/wiki/Community-Projects)
|
||||||
|
|
||||||
|
|||||||
312
build.zig
312
build.zig
@ -19,7 +19,7 @@ pub fn build(b: *Builder) !void {
|
|||||||
const single_threaded = b.option(bool, "single-threaded", "Build artifacts that run in single threaded mode");
|
const single_threaded = b.option(bool, "single-threaded", "Build artifacts that run in single threaded mode");
|
||||||
const use_zig_libcxx = b.option(bool, "use-zig-libcxx", "If libc++ is needed, use zig's bundled version, don't try to integrate with the system") orelse false;
|
const use_zig_libcxx = b.option(bool, "use-zig-libcxx", "If libc++ is needed, use zig's bundled version, don't try to integrate with the system") orelse false;
|
||||||
|
|
||||||
var docgen_exe = b.addExecutable("docgen", "doc/docgen.zig");
|
const docgen_exe = b.addExecutable("docgen", "doc/docgen.zig");
|
||||||
docgen_exe.single_threaded = single_threaded;
|
docgen_exe.single_threaded = single_threaded;
|
||||||
|
|
||||||
const rel_zig_exe = try fs.path.relative(b.allocator, b.build_root, b.zig_exe);
|
const rel_zig_exe = try fs.path.relative(b.allocator, b.build_root, b.zig_exe);
|
||||||
@ -27,7 +27,7 @@ pub fn build(b: *Builder) !void {
|
|||||||
b.allocator,
|
b.allocator,
|
||||||
&[_][]const u8{ b.cache_root, "langref.html" },
|
&[_][]const u8{ b.cache_root, "langref.html" },
|
||||||
) catch unreachable;
|
) catch unreachable;
|
||||||
var docgen_cmd = docgen_exe.run();
|
const docgen_cmd = docgen_exe.run();
|
||||||
docgen_cmd.addArgs(&[_][]const u8{
|
docgen_cmd.addArgs(&[_][]const u8{
|
||||||
rel_zig_exe,
|
rel_zig_exe,
|
||||||
"doc" ++ fs.path.sep_str ++ "langref.html.in",
|
"doc" ++ fs.path.sep_str ++ "langref.html.in",
|
||||||
@ -40,10 +40,10 @@ pub fn build(b: *Builder) !void {
|
|||||||
|
|
||||||
const toolchain_step = b.step("test-toolchain", "Run the tests for the toolchain");
|
const toolchain_step = b.step("test-toolchain", "Run the tests for the toolchain");
|
||||||
|
|
||||||
var test_stage2 = b.addTest("src/test.zig");
|
var test_cases = b.addTest("src/test.zig");
|
||||||
test_stage2.setBuildMode(mode);
|
test_cases.setBuildMode(mode);
|
||||||
test_stage2.addPackagePath("test_cases", "test/cases.zig");
|
test_cases.addPackagePath("test_cases", "test/cases.zig");
|
||||||
test_stage2.single_threaded = single_threaded;
|
test_cases.single_threaded = single_threaded;
|
||||||
|
|
||||||
const fmt_build_zig = b.addFmt(&[_][]const u8{"build.zig"});
|
const fmt_build_zig = b.addFmt(&[_][]const u8{"build.zig"});
|
||||||
|
|
||||||
@ -54,12 +54,14 @@ pub fn build(b: *Builder) !void {
|
|||||||
const skip_release_safe = b.option(bool, "skip-release-safe", "Main test suite skips release-safe builds") orelse skip_release;
|
const skip_release_safe = b.option(bool, "skip-release-safe", "Main test suite skips release-safe builds") orelse skip_release;
|
||||||
const skip_non_native = b.option(bool, "skip-non-native", "Main test suite skips non-native builds") orelse false;
|
const skip_non_native = b.option(bool, "skip-non-native", "Main test suite skips non-native builds") orelse false;
|
||||||
const skip_libc = b.option(bool, "skip-libc", "Main test suite skips tests that link libc") orelse false;
|
const skip_libc = b.option(bool, "skip-libc", "Main test suite skips tests that link libc") orelse false;
|
||||||
const skip_compile_errors = b.option(bool, "skip-compile-errors", "Main test suite skips compile error tests") orelse false;
|
const skip_single_threaded = b.option(bool, "skip-single-threaded", "Main test suite skips tests that are single-threaded") orelse false;
|
||||||
|
const skip_stage1 = b.option(bool, "skip-stage1", "Main test suite skips stage1 compile error tests") orelse false;
|
||||||
const skip_run_translated_c = b.option(bool, "skip-run-translated-c", "Main test suite skips run-translated-c tests") orelse false;
|
const skip_run_translated_c = b.option(bool, "skip-run-translated-c", "Main test suite skips run-translated-c tests") orelse false;
|
||||||
const skip_stage2_tests = b.option(bool, "skip-stage2-tests", "Main test suite skips self-hosted compiler tests") orelse false;
|
const skip_stage2_tests = b.option(bool, "skip-stage2-tests", "Main test suite skips self-hosted compiler tests") orelse false;
|
||||||
const skip_install_lib_files = b.option(bool, "skip-install-lib-files", "Do not copy lib/ files to installation prefix") orelse false;
|
const skip_install_lib_files = b.option(bool, "skip-install-lib-files", "Do not copy lib/ files to installation prefix") orelse false;
|
||||||
|
|
||||||
const only_install_lib_files = b.option(bool, "lib-files-only", "Only install library files") orelse false;
|
const only_install_lib_files = b.option(bool, "lib-files-only", "Only install library files") orelse false;
|
||||||
|
|
||||||
const is_stage1 = b.option(bool, "stage1", "Build the stage1 compiler, put stage2 behind a feature flag") orelse false;
|
const is_stage1 = b.option(bool, "stage1", "Build the stage1 compiler, put stage2 behind a feature flag") orelse false;
|
||||||
const omit_stage2 = b.option(bool, "omit-stage2", "Do not include stage2 behind a feature flag inside stage1") orelse false;
|
const omit_stage2 = b.option(bool, "omit-stage2", "Do not include stage2 behind a feature flag inside stage1") orelse false;
|
||||||
const static_llvm = b.option(bool, "static-llvm", "Disable integration with system-installed LLVM, Clang, LLD, and libc++") orelse false;
|
const static_llvm = b.option(bool, "static-llvm", "Disable integration with system-installed LLVM, Clang, LLD, and libc++") orelse false;
|
||||||
@ -128,6 +130,8 @@ pub fn build(b: *Builder) !void {
|
|||||||
const force_gpa = b.option(bool, "force-gpa", "Force the compiler to use GeneralPurposeAllocator") orelse false;
|
const force_gpa = b.option(bool, "force-gpa", "Force the compiler to use GeneralPurposeAllocator") orelse false;
|
||||||
const link_libc = b.option(bool, "force-link-libc", "Force self-hosted compiler to link libc") orelse enable_llvm;
|
const link_libc = b.option(bool, "force-link-libc", "Force self-hosted compiler to link libc") orelse enable_llvm;
|
||||||
const strip = b.option(bool, "strip", "Omit debug information") orelse false;
|
const strip = b.option(bool, "strip", "Omit debug information") orelse false;
|
||||||
|
const use_zig0 = b.option(bool, "zig0", "Bootstrap using zig0") orelse false;
|
||||||
|
const value_tracing = b.option(bool, "value-tracing", "Enable extra state tracking to help troubleshoot bugs in the compiler (using the std.debug.Trace API)") orelse false;
|
||||||
|
|
||||||
const mem_leak_frames: u32 = b.option(u32, "mem-leak-frames", "How many stack frames to print when a memory leak occurs. Tests get 2x this amount.") orelse blk: {
|
const mem_leak_frames: u32 = b.option(u32, "mem-leak-frames", "How many stack frames to print when a memory leak occurs. Tests get 2x this amount.") orelse blk: {
|
||||||
if (strip) break :blk @as(u32, 0);
|
if (strip) break :blk @as(u32, 0);
|
||||||
@ -135,23 +139,29 @@ pub fn build(b: *Builder) !void {
|
|||||||
break :blk 4;
|
break :blk 4;
|
||||||
};
|
};
|
||||||
|
|
||||||
const main_file = if (is_stage1) "src/stage1.zig" else "src/main.zig";
|
const main_file: ?[]const u8 = mf: {
|
||||||
|
if (!is_stage1) break :mf "src/main.zig";
|
||||||
|
if (use_zig0) break :mf null;
|
||||||
|
break :mf "src/stage1.zig";
|
||||||
|
};
|
||||||
|
|
||||||
var exe = b.addExecutable("zig", main_file);
|
const exe = b.addExecutable("zig", main_file);
|
||||||
exe.strip = strip;
|
exe.strip = strip;
|
||||||
|
exe.build_id = b.option(bool, "build-id", "Include a build id note") orelse false;
|
||||||
exe.install();
|
exe.install();
|
||||||
exe.setBuildMode(mode);
|
exe.setBuildMode(mode);
|
||||||
exe.setTarget(target);
|
exe.setTarget(target);
|
||||||
if (!skip_stage2_tests) {
|
if (!skip_stage2_tests) {
|
||||||
toolchain_step.dependOn(&exe.step);
|
toolchain_step.dependOn(&exe.step);
|
||||||
}
|
}
|
||||||
|
|
||||||
b.default_step.dependOn(&exe.step);
|
b.default_step.dependOn(&exe.step);
|
||||||
exe.single_threaded = single_threaded;
|
exe.single_threaded = single_threaded;
|
||||||
|
|
||||||
if (target.isWindows() and target.getAbi() == .gnu) {
|
if (target.isWindows() and target.getAbi() == .gnu) {
|
||||||
// LTO is currently broken on mingw, this can be removed when it's fixed.
|
// LTO is currently broken on mingw, this can be removed when it's fixed.
|
||||||
exe.want_lto = false;
|
exe.want_lto = false;
|
||||||
test_stage2.want_lto = false;
|
test_cases.want_lto = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const exe_options = b.addOptions();
|
const exe_options = b.addOptions();
|
||||||
@ -166,59 +176,9 @@ pub fn build(b: *Builder) !void {
|
|||||||
exe_options.addOption(bool, "llvm_has_arc", llvm_has_arc);
|
exe_options.addOption(bool, "llvm_has_arc", llvm_has_arc);
|
||||||
exe_options.addOption(bool, "force_gpa", force_gpa);
|
exe_options.addOption(bool, "force_gpa", force_gpa);
|
||||||
|
|
||||||
if (enable_llvm) {
|
|
||||||
const cmake_cfg = if (static_llvm) null else findAndParseConfigH(b, config_h_path_option);
|
|
||||||
|
|
||||||
if (is_stage1) {
|
|
||||||
exe.addIncludePath("src");
|
|
||||||
exe.addIncludePath("deps/SoftFloat-3e/source/include");
|
|
||||||
|
|
||||||
test_stage2.addIncludePath("src");
|
|
||||||
test_stage2.addIncludePath("deps/SoftFloat-3e/source/include");
|
|
||||||
// This is intentionally a dummy path. stage1.zig tries to @import("compiler_rt") in case
|
|
||||||
// of being built by cmake. But when built by zig it's gonna get a compiler_rt so that
|
|
||||||
// is pointless.
|
|
||||||
exe.addPackagePath("compiler_rt", "src/empty.zig");
|
|
||||||
exe.defineCMacro("ZIG_LINK_MODE", "Static");
|
|
||||||
test_stage2.defineCMacro("ZIG_LINK_MODE", "Static");
|
|
||||||
|
|
||||||
const softfloat = b.addStaticLibrary("softfloat", null);
|
|
||||||
softfloat.setBuildMode(.ReleaseFast);
|
|
||||||
softfloat.setTarget(target);
|
|
||||||
softfloat.addIncludePath("deps/SoftFloat-3e-prebuilt");
|
|
||||||
softfloat.addIncludePath("deps/SoftFloat-3e/source/8086");
|
|
||||||
softfloat.addIncludePath("deps/SoftFloat-3e/source/include");
|
|
||||||
softfloat.addCSourceFiles(&softfloat_sources, &[_][]const u8{ "-std=c99", "-O3" });
|
|
||||||
softfloat.single_threaded = single_threaded;
|
|
||||||
|
|
||||||
exe.linkLibrary(softfloat);
|
|
||||||
test_stage2.linkLibrary(softfloat);
|
|
||||||
|
|
||||||
exe.addCSourceFiles(&stage1_sources, &exe_cflags);
|
|
||||||
exe.addCSourceFiles(&optimized_c_sources, &[_][]const u8{ "-std=c99", "-O3" });
|
|
||||||
|
|
||||||
test_stage2.addCSourceFiles(&stage1_sources, &exe_cflags);
|
|
||||||
test_stage2.addCSourceFiles(&optimized_c_sources, &[_][]const u8{ "-std=c99", "-O3" });
|
|
||||||
}
|
|
||||||
if (cmake_cfg) |cfg| {
|
|
||||||
// Inside this code path, we have to coordinate with system packaged LLVM, Clang, and LLD.
|
|
||||||
// That means we also have to rely on stage1 compiled c++ files. We parse config.h to find
|
|
||||||
// the information passed on to us from cmake.
|
|
||||||
if (cfg.cmake_prefix_path.len > 0) {
|
|
||||||
b.addSearchPrefix(cfg.cmake_prefix_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
try addCmakeCfgOptionsToExe(b, cfg, exe, use_zig_libcxx);
|
|
||||||
try addCmakeCfgOptionsToExe(b, cfg, test_stage2, use_zig_libcxx);
|
|
||||||
} else {
|
|
||||||
// Here we are -Denable-llvm but no cmake integration.
|
|
||||||
try addStaticLlvmOptionsToExe(exe);
|
|
||||||
try addStaticLlvmOptionsToExe(test_stage2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (link_libc) {
|
if (link_libc) {
|
||||||
exe.linkLibC();
|
exe.linkLibC();
|
||||||
test_stage2.linkLibC();
|
test_cases.linkLibC();
|
||||||
}
|
}
|
||||||
|
|
||||||
const is_debug = mode == .Debug;
|
const is_debug = mode == .Debug;
|
||||||
@ -227,6 +187,10 @@ pub fn build(b: *Builder) !void {
|
|||||||
|
|
||||||
const opt_version_string = b.option([]const u8, "version-string", "Override Zig version string. Default is to find out with git.");
|
const opt_version_string = b.option([]const u8, "version-string", "Override Zig version string. Default is to find out with git.");
|
||||||
const version = if (opt_version_string) |version| version else v: {
|
const version = if (opt_version_string) |version| version else v: {
|
||||||
|
if (!std.process.can_spawn) {
|
||||||
|
std.debug.print("error: version info cannot be retrieved from git. Zig version must be provided using -Dversion-string\n", .{});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
const version_string = b.fmt("{d}.{d}.{d}", .{ zig_version.major, zig_version.minor, zig_version.patch });
|
const version_string = b.fmt("{d}.{d}.{d}", .{ zig_version.major, zig_version.minor, zig_version.patch });
|
||||||
|
|
||||||
var code: u8 = undefined;
|
var code: u8 = undefined;
|
||||||
@ -276,6 +240,112 @@ pub fn build(b: *Builder) !void {
|
|||||||
};
|
};
|
||||||
exe_options.addOption([:0]const u8, "version", try b.allocator.dupeZ(u8, version));
|
exe_options.addOption([:0]const u8, "version", try b.allocator.dupeZ(u8, version));
|
||||||
|
|
||||||
|
if (enable_llvm) {
|
||||||
|
const cmake_cfg = if (static_llvm) null else findAndParseConfigH(b, config_h_path_option);
|
||||||
|
|
||||||
|
if (is_stage1) {
|
||||||
|
const softfloat = b.addStaticLibrary("softfloat", null);
|
||||||
|
softfloat.setBuildMode(.ReleaseFast);
|
||||||
|
softfloat.setTarget(target);
|
||||||
|
softfloat.addIncludePath("deps/SoftFloat-3e-prebuilt");
|
||||||
|
softfloat.addIncludePath("deps/SoftFloat-3e/source/8086");
|
||||||
|
softfloat.addIncludePath("deps/SoftFloat-3e/source/include");
|
||||||
|
softfloat.addCSourceFiles(&softfloat_sources, &[_][]const u8{ "-std=c99", "-O3" });
|
||||||
|
softfloat.single_threaded = single_threaded;
|
||||||
|
|
||||||
|
const zig0 = b.addExecutable("zig0", null);
|
||||||
|
zig0.addCSourceFiles(&.{"src/stage1/zig0.cpp"}, &exe_cflags);
|
||||||
|
zig0.addIncludePath("zig-cache/tmp"); // for config.h
|
||||||
|
zig0.defineCMacro("ZIG_VERSION_MAJOR", b.fmt("{d}", .{zig_version.major}));
|
||||||
|
zig0.defineCMacro("ZIG_VERSION_MINOR", b.fmt("{d}", .{zig_version.minor}));
|
||||||
|
zig0.defineCMacro("ZIG_VERSION_PATCH", b.fmt("{d}", .{zig_version.patch}));
|
||||||
|
zig0.defineCMacro("ZIG_VERSION_STRING", b.fmt("\"{s}\"", .{version}));
|
||||||
|
|
||||||
|
for ([_]*std.build.LibExeObjStep{ zig0, exe, test_cases }) |artifact| {
|
||||||
|
artifact.addIncludePath("src");
|
||||||
|
artifact.addIncludePath("deps/SoftFloat-3e/source/include");
|
||||||
|
artifact.addIncludePath("deps/SoftFloat-3e-prebuilt");
|
||||||
|
|
||||||
|
artifact.defineCMacro("ZIG_LINK_MODE", "Static");
|
||||||
|
|
||||||
|
artifact.addCSourceFiles(&stage1_sources, &exe_cflags);
|
||||||
|
artifact.addCSourceFiles(&optimized_c_sources, &[_][]const u8{ "-std=c99", "-O3" });
|
||||||
|
|
||||||
|
artifact.linkLibrary(softfloat);
|
||||||
|
artifact.linkLibCpp();
|
||||||
|
}
|
||||||
|
|
||||||
|
try addStaticLlvmOptionsToExe(zig0);
|
||||||
|
|
||||||
|
const zig1_obj_ext = target.getObjectFormat().fileExt(target.getCpuArch());
|
||||||
|
const zig1_obj_path = b.pathJoin(&.{ "zig-cache", "tmp", b.fmt("zig1{s}", .{zig1_obj_ext}) });
|
||||||
|
const zig1_compiler_rt_path = b.pathJoin(&.{ b.pathFromRoot("lib"), "std", "special", "compiler_rt.zig" });
|
||||||
|
|
||||||
|
const zig1_obj = zig0.run();
|
||||||
|
zig1_obj.addArgs(&.{
|
||||||
|
"src/stage1.zig",
|
||||||
|
"-target",
|
||||||
|
try target.zigTriple(b.allocator),
|
||||||
|
"-mcpu=baseline",
|
||||||
|
"--name",
|
||||||
|
"zig1",
|
||||||
|
"--zig-lib-dir",
|
||||||
|
b.pathFromRoot("lib"),
|
||||||
|
b.fmt("-femit-bin={s}", .{b.pathFromRoot(zig1_obj_path)}),
|
||||||
|
"-fcompiler-rt",
|
||||||
|
"-lc",
|
||||||
|
});
|
||||||
|
{
|
||||||
|
zig1_obj.addArgs(&.{ "--pkg-begin", "build_options" });
|
||||||
|
zig1_obj.addFileSourceArg(exe_options.getSource());
|
||||||
|
zig1_obj.addArgs(&.{ "--pkg-end", "--pkg-begin", "compiler_rt", zig1_compiler_rt_path, "--pkg-end" });
|
||||||
|
}
|
||||||
|
switch (mode) {
|
||||||
|
.Debug => {},
|
||||||
|
.ReleaseFast => {
|
||||||
|
zig1_obj.addArg("-OReleaseFast");
|
||||||
|
zig1_obj.addArg("--strip");
|
||||||
|
},
|
||||||
|
.ReleaseSafe => {
|
||||||
|
zig1_obj.addArg("-OReleaseSafe");
|
||||||
|
zig1_obj.addArg("--strip");
|
||||||
|
},
|
||||||
|
.ReleaseSmall => {
|
||||||
|
zig1_obj.addArg("-OReleaseSmall");
|
||||||
|
zig1_obj.addArg("--strip");
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if (single_threaded orelse false) {
|
||||||
|
zig1_obj.addArg("-fsingle-threaded");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_zig0) {
|
||||||
|
exe.step.dependOn(&zig1_obj.step);
|
||||||
|
exe.addObjectFile(zig1_obj_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is intentionally a dummy path. stage1.zig tries to @import("compiler_rt") in case
|
||||||
|
// of being built by cmake. But when built by zig it's gonna get a compiler_rt so that
|
||||||
|
// is pointless.
|
||||||
|
exe.addPackagePath("compiler_rt", "src/empty.zig");
|
||||||
|
}
|
||||||
|
if (cmake_cfg) |cfg| {
|
||||||
|
// Inside this code path, we have to coordinate with system packaged LLVM, Clang, and LLD.
|
||||||
|
// That means we also have to rely on stage1 compiled c++ files. We parse config.h to find
|
||||||
|
// the information passed on to us from cmake.
|
||||||
|
if (cfg.cmake_prefix_path.len > 0) {
|
||||||
|
b.addSearchPrefix(cfg.cmake_prefix_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
try addCmakeCfgOptionsToExe(b, cfg, exe, use_zig_libcxx);
|
||||||
|
try addCmakeCfgOptionsToExe(b, cfg, test_cases, use_zig_libcxx);
|
||||||
|
} else {
|
||||||
|
// Here we are -Denable-llvm but no cmake integration.
|
||||||
|
try addStaticLlvmOptionsToExe(exe);
|
||||||
|
try addStaticLlvmOptionsToExe(test_cases);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const semver = try std.SemanticVersion.parse(version);
|
const semver = try std.SemanticVersion.parse(version);
|
||||||
exe_options.addOption(std.SemanticVersion, "semver", semver);
|
exe_options.addOption(std.SemanticVersion, "semver", semver);
|
||||||
|
|
||||||
@ -284,6 +354,7 @@ pub fn build(b: *Builder) !void {
|
|||||||
exe_options.addOption(bool, "enable_tracy", tracy != null);
|
exe_options.addOption(bool, "enable_tracy", tracy != null);
|
||||||
exe_options.addOption(bool, "enable_tracy_callstack", tracy_callstack);
|
exe_options.addOption(bool, "enable_tracy_callstack", tracy_callstack);
|
||||||
exe_options.addOption(bool, "enable_tracy_allocation", tracy_allocation);
|
exe_options.addOption(bool, "enable_tracy_allocation", tracy_allocation);
|
||||||
|
exe_options.addOption(bool, "value_tracing", value_tracing);
|
||||||
exe_options.addOption(bool, "is_stage1", is_stage1);
|
exe_options.addOption(bool, "is_stage1", is_stage1);
|
||||||
exe_options.addOption(bool, "omit_stage2", omit_stage2);
|
exe_options.addOption(bool, "omit_stage2", omit_stage2);
|
||||||
if (tracy) |tracy_path| {
|
if (tracy) |tracy_path| {
|
||||||
@ -313,34 +384,37 @@ pub fn build(b: *Builder) !void {
|
|||||||
|
|
||||||
const test_filter = b.option([]const u8, "test-filter", "Skip tests that do not match filter");
|
const test_filter = b.option([]const u8, "test-filter", "Skip tests that do not match filter");
|
||||||
|
|
||||||
const test_stage2_options = b.addOptions();
|
const test_cases_options = b.addOptions();
|
||||||
test_stage2.addOptions("build_options", test_stage2_options);
|
test_cases.addOptions("build_options", test_cases_options);
|
||||||
|
|
||||||
test_stage2_options.addOption(bool, "enable_logging", enable_logging);
|
test_cases_options.addOption(bool, "enable_logging", enable_logging);
|
||||||
test_stage2_options.addOption(bool, "enable_link_snapshots", enable_link_snapshots);
|
test_cases_options.addOption(bool, "enable_link_snapshots", enable_link_snapshots);
|
||||||
test_stage2_options.addOption(bool, "skip_non_native", skip_non_native);
|
test_cases_options.addOption(bool, "skip_non_native", skip_non_native);
|
||||||
test_stage2_options.addOption(bool, "skip_compile_errors", skip_compile_errors);
|
test_cases_options.addOption(bool, "skip_stage1", skip_stage1);
|
||||||
test_stage2_options.addOption(bool, "is_stage1", is_stage1);
|
test_cases_options.addOption(bool, "is_stage1", is_stage1);
|
||||||
test_stage2_options.addOption(bool, "omit_stage2", omit_stage2);
|
test_cases_options.addOption(bool, "omit_stage2", omit_stage2);
|
||||||
test_stage2_options.addOption(bool, "have_llvm", enable_llvm);
|
test_cases_options.addOption(bool, "have_llvm", enable_llvm);
|
||||||
test_stage2_options.addOption(bool, "llvm_has_m68k", llvm_has_m68k);
|
test_cases_options.addOption(bool, "llvm_has_m68k", llvm_has_m68k);
|
||||||
test_stage2_options.addOption(bool, "llvm_has_csky", llvm_has_csky);
|
test_cases_options.addOption(bool, "llvm_has_csky", llvm_has_csky);
|
||||||
test_stage2_options.addOption(bool, "llvm_has_ve", llvm_has_ve);
|
test_cases_options.addOption(bool, "llvm_has_ve", llvm_has_ve);
|
||||||
test_stage2_options.addOption(bool, "llvm_has_arc", llvm_has_arc);
|
test_cases_options.addOption(bool, "llvm_has_arc", llvm_has_arc);
|
||||||
test_stage2_options.addOption(bool, "enable_qemu", b.enable_qemu);
|
test_cases_options.addOption(bool, "force_gpa", force_gpa);
|
||||||
test_stage2_options.addOption(bool, "enable_wine", b.enable_wine);
|
test_cases_options.addOption(bool, "enable_qemu", b.enable_qemu);
|
||||||
test_stage2_options.addOption(bool, "enable_wasmtime", b.enable_wasmtime);
|
test_cases_options.addOption(bool, "enable_wine", b.enable_wine);
|
||||||
test_stage2_options.addOption(bool, "enable_rosetta", b.enable_rosetta);
|
test_cases_options.addOption(bool, "enable_wasmtime", b.enable_wasmtime);
|
||||||
test_stage2_options.addOption(bool, "enable_darling", b.enable_darling);
|
test_cases_options.addOption(bool, "enable_rosetta", b.enable_rosetta);
|
||||||
test_stage2_options.addOption(u32, "mem_leak_frames", mem_leak_frames * 2);
|
test_cases_options.addOption(bool, "enable_darling", b.enable_darling);
|
||||||
test_stage2_options.addOption(?[]const u8, "glibc_runtimes_dir", b.glibc_runtimes_dir);
|
test_cases_options.addOption(u32, "mem_leak_frames", mem_leak_frames * 2);
|
||||||
test_stage2_options.addOption([:0]const u8, "version", try b.allocator.dupeZ(u8, version));
|
test_cases_options.addOption(bool, "value_tracing", value_tracing);
|
||||||
test_stage2_options.addOption(std.SemanticVersion, "semver", semver);
|
test_cases_options.addOption(?[]const u8, "glibc_runtimes_dir", b.glibc_runtimes_dir);
|
||||||
|
test_cases_options.addOption([:0]const u8, "version", try b.allocator.dupeZ(u8, version));
|
||||||
|
test_cases_options.addOption(std.SemanticVersion, "semver", semver);
|
||||||
|
test_cases_options.addOption(?[]const u8, "test_filter", test_filter);
|
||||||
|
|
||||||
const test_stage2_step = b.step("test-stage2", "Run the stage2 compiler tests");
|
const test_cases_step = b.step("test-cases", "Run the main compiler test cases");
|
||||||
test_stage2_step.dependOn(&test_stage2.step);
|
test_cases_step.dependOn(&test_cases.step);
|
||||||
if (!skip_stage2_tests) {
|
if (!skip_stage2_tests) {
|
||||||
toolchain_step.dependOn(test_stage2_step);
|
toolchain_step.dependOn(test_cases_step);
|
||||||
}
|
}
|
||||||
|
|
||||||
var chosen_modes: [4]builtin.Mode = undefined;
|
var chosen_modes: [4]builtin.Mode = undefined;
|
||||||
@ -375,41 +449,50 @@ pub fn build(b: *Builder) !void {
|
|||||||
"behavior",
|
"behavior",
|
||||||
"Run the behavior tests",
|
"Run the behavior tests",
|
||||||
modes,
|
modes,
|
||||||
false, // skip_single_threaded
|
skip_single_threaded,
|
||||||
skip_non_native,
|
skip_non_native,
|
||||||
skip_libc,
|
skip_libc,
|
||||||
|
skip_stage1,
|
||||||
|
omit_stage2,
|
||||||
|
is_stage1,
|
||||||
));
|
));
|
||||||
|
|
||||||
toolchain_step.dependOn(tests.addPkgTests(
|
toolchain_step.dependOn(tests.addPkgTests(
|
||||||
b,
|
b,
|
||||||
test_filter,
|
test_filter,
|
||||||
"lib/std/special/compiler_rt.zig",
|
"lib/compiler_rt.zig",
|
||||||
"compiler-rt",
|
"compiler-rt",
|
||||||
"Run the compiler_rt tests",
|
"Run the compiler_rt tests",
|
||||||
modes,
|
modes,
|
||||||
true, // skip_single_threaded
|
true, // skip_single_threaded
|
||||||
skip_non_native,
|
skip_non_native,
|
||||||
true, // skip_libc
|
true, // skip_libc
|
||||||
|
skip_stage1,
|
||||||
|
omit_stage2 or true, // TODO get these all passing
|
||||||
|
is_stage1,
|
||||||
));
|
));
|
||||||
|
|
||||||
toolchain_step.dependOn(tests.addPkgTests(
|
toolchain_step.dependOn(tests.addPkgTests(
|
||||||
b,
|
b,
|
||||||
test_filter,
|
test_filter,
|
||||||
"lib/std/special/c.zig",
|
"lib/c.zig",
|
||||||
"minilibc",
|
"universal-libc",
|
||||||
"Run the mini libc tests",
|
"Run the universal libc tests",
|
||||||
modes,
|
modes,
|
||||||
true, // skip_single_threaded
|
true, // skip_single_threaded
|
||||||
skip_non_native,
|
skip_non_native,
|
||||||
true, // skip_libc
|
true, // skip_libc
|
||||||
|
skip_stage1,
|
||||||
|
omit_stage2 or true, // TODO get these all passing
|
||||||
|
is_stage1,
|
||||||
));
|
));
|
||||||
|
|
||||||
toolchain_step.dependOn(tests.addCompareOutputTests(b, test_filter, modes));
|
toolchain_step.dependOn(tests.addCompareOutputTests(b, test_filter, modes));
|
||||||
toolchain_step.dependOn(tests.addStandaloneTests(b, test_filter, modes, skip_non_native, enable_macos_sdk, target));
|
toolchain_step.dependOn(tests.addStandaloneTests(b, test_filter, modes, skip_non_native, enable_macos_sdk, target));
|
||||||
|
toolchain_step.dependOn(tests.addLinkTests(b, test_filter, modes, enable_macos_sdk));
|
||||||
toolchain_step.dependOn(tests.addStackTraceTests(b, test_filter, modes));
|
toolchain_step.dependOn(tests.addStackTraceTests(b, test_filter, modes));
|
||||||
toolchain_step.dependOn(tests.addCliTests(b, test_filter, modes));
|
toolchain_step.dependOn(tests.addCliTests(b, test_filter, modes));
|
||||||
toolchain_step.dependOn(tests.addAssembleAndLinkTests(b, test_filter, modes));
|
toolchain_step.dependOn(tests.addAssembleAndLinkTests(b, test_filter, modes));
|
||||||
toolchain_step.dependOn(tests.addRuntimeSafetyTests(b, test_filter, modes));
|
|
||||||
toolchain_step.dependOn(tests.addTranslateCTests(b, test_filter));
|
toolchain_step.dependOn(tests.addTranslateCTests(b, test_filter));
|
||||||
if (!skip_run_translated_c) {
|
if (!skip_run_translated_c) {
|
||||||
toolchain_step.dependOn(tests.addRunTranslatedCTests(b, test_filter, target));
|
toolchain_step.dependOn(tests.addRunTranslatedCTests(b, test_filter, target));
|
||||||
@ -424,9 +507,12 @@ pub fn build(b: *Builder) !void {
|
|||||||
"std",
|
"std",
|
||||||
"Run the standard library tests",
|
"Run the standard library tests",
|
||||||
modes,
|
modes,
|
||||||
false,
|
skip_single_threaded,
|
||||||
skip_non_native,
|
skip_non_native,
|
||||||
skip_libc,
|
skip_libc,
|
||||||
|
skip_stage1,
|
||||||
|
omit_stage2 or true, // TODO get these all passing
|
||||||
|
is_stage1,
|
||||||
);
|
);
|
||||||
|
|
||||||
const test_step = b.step("test", "Run all the tests");
|
const test_step = b.step("test", "Run all the tests");
|
||||||
@ -499,9 +585,7 @@ fn addCmakeCfgOptionsToExe(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn addStaticLlvmOptionsToExe(
|
fn addStaticLlvmOptionsToExe(exe: *std.build.LibExeObjStep) !void {
|
||||||
exe: *std.build.LibExeObjStep,
|
|
||||||
) !void {
|
|
||||||
// Adds the Zig C++ sources which both stage1 and stage2 need.
|
// Adds the Zig C++ sources which both stage1 and stage2 need.
|
||||||
//
|
//
|
||||||
// We need this because otherwise zig_clang_cc1_main.cpp ends up pulling
|
// We need this because otherwise zig_clang_cc1_main.cpp ends up pulling
|
||||||
@ -542,11 +626,14 @@ fn addCxxKnownPath(
|
|||||||
errtxt: ?[]const u8,
|
errtxt: ?[]const u8,
|
||||||
need_cpp_includes: bool,
|
need_cpp_includes: bool,
|
||||||
) !void {
|
) !void {
|
||||||
|
if (!std.process.can_spawn)
|
||||||
|
return error.RequiredLibraryNotFound;
|
||||||
const path_padded = try b.exec(&[_][]const u8{
|
const path_padded = try b.exec(&[_][]const u8{
|
||||||
ctx.cxx_compiler,
|
ctx.cxx_compiler,
|
||||||
b.fmt("-print-file-name={s}", .{objname}),
|
b.fmt("-print-file-name={s}", .{objname}),
|
||||||
});
|
});
|
||||||
const path_unpadded = mem.tokenize(u8, path_padded, "\r\n").next().?;
|
var tokenizer = mem.tokenize(u8, path_padded, "\r\n");
|
||||||
|
const path_unpadded = tokenizer.next().?;
|
||||||
if (mem.eql(u8, path_unpadded, objname)) {
|
if (mem.eql(u8, path_unpadded, objname)) {
|
||||||
if (errtxt) |msg| {
|
if (errtxt) |msg| {
|
||||||
std.debug.print("{s}", .{msg});
|
std.debug.print("{s}", .{msg});
|
||||||
@ -688,15 +775,19 @@ fn toNativePathSep(b: *Builder, s: []const u8) []u8 {
|
|||||||
|
|
||||||
const softfloat_sources = [_][]const u8{
|
const softfloat_sources = [_][]const u8{
|
||||||
"deps/SoftFloat-3e/source/8086/f128M_isSignalingNaN.c",
|
"deps/SoftFloat-3e/source/8086/f128M_isSignalingNaN.c",
|
||||||
|
"deps/SoftFloat-3e/source/8086/extF80M_isSignalingNaN.c",
|
||||||
"deps/SoftFloat-3e/source/8086/s_commonNaNToF128M.c",
|
"deps/SoftFloat-3e/source/8086/s_commonNaNToF128M.c",
|
||||||
|
"deps/SoftFloat-3e/source/8086/s_commonNaNToExtF80M.c",
|
||||||
"deps/SoftFloat-3e/source/8086/s_commonNaNToF16UI.c",
|
"deps/SoftFloat-3e/source/8086/s_commonNaNToF16UI.c",
|
||||||
"deps/SoftFloat-3e/source/8086/s_commonNaNToF32UI.c",
|
"deps/SoftFloat-3e/source/8086/s_commonNaNToF32UI.c",
|
||||||
"deps/SoftFloat-3e/source/8086/s_commonNaNToF64UI.c",
|
"deps/SoftFloat-3e/source/8086/s_commonNaNToF64UI.c",
|
||||||
"deps/SoftFloat-3e/source/8086/s_f128MToCommonNaN.c",
|
"deps/SoftFloat-3e/source/8086/s_f128MToCommonNaN.c",
|
||||||
|
"deps/SoftFloat-3e/source/8086/s_extF80MToCommonNaN.c",
|
||||||
"deps/SoftFloat-3e/source/8086/s_f16UIToCommonNaN.c",
|
"deps/SoftFloat-3e/source/8086/s_f16UIToCommonNaN.c",
|
||||||
"deps/SoftFloat-3e/source/8086/s_f32UIToCommonNaN.c",
|
"deps/SoftFloat-3e/source/8086/s_f32UIToCommonNaN.c",
|
||||||
"deps/SoftFloat-3e/source/8086/s_f64UIToCommonNaN.c",
|
"deps/SoftFloat-3e/source/8086/s_f64UIToCommonNaN.c",
|
||||||
"deps/SoftFloat-3e/source/8086/s_propagateNaNF128M.c",
|
"deps/SoftFloat-3e/source/8086/s_propagateNaNF128M.c",
|
||||||
|
"deps/SoftFloat-3e/source/8086/s_propagateNaNExtF80M.c",
|
||||||
"deps/SoftFloat-3e/source/8086/s_propagateNaNF16UI.c",
|
"deps/SoftFloat-3e/source/8086/s_propagateNaNF16UI.c",
|
||||||
"deps/SoftFloat-3e/source/8086/softfloat_raiseFlags.c",
|
"deps/SoftFloat-3e/source/8086/softfloat_raiseFlags.c",
|
||||||
"deps/SoftFloat-3e/source/f128M_add.c",
|
"deps/SoftFloat-3e/source/f128M_add.c",
|
||||||
@ -716,6 +807,7 @@ const softfloat_sources = [_][]const u8{
|
|||||||
"deps/SoftFloat-3e/source/f128M_to_f16.c",
|
"deps/SoftFloat-3e/source/f128M_to_f16.c",
|
||||||
"deps/SoftFloat-3e/source/f128M_to_f32.c",
|
"deps/SoftFloat-3e/source/f128M_to_f32.c",
|
||||||
"deps/SoftFloat-3e/source/f128M_to_f64.c",
|
"deps/SoftFloat-3e/source/f128M_to_f64.c",
|
||||||
|
"deps/SoftFloat-3e/source/f128M_to_extF80M.c",
|
||||||
"deps/SoftFloat-3e/source/f128M_to_i32.c",
|
"deps/SoftFloat-3e/source/f128M_to_i32.c",
|
||||||
"deps/SoftFloat-3e/source/f128M_to_i32_r_minMag.c",
|
"deps/SoftFloat-3e/source/f128M_to_i32_r_minMag.c",
|
||||||
"deps/SoftFloat-3e/source/f128M_to_i64.c",
|
"deps/SoftFloat-3e/source/f128M_to_i64.c",
|
||||||
@ -724,6 +816,20 @@ const softfloat_sources = [_][]const u8{
|
|||||||
"deps/SoftFloat-3e/source/f128M_to_ui32_r_minMag.c",
|
"deps/SoftFloat-3e/source/f128M_to_ui32_r_minMag.c",
|
||||||
"deps/SoftFloat-3e/source/f128M_to_ui64.c",
|
"deps/SoftFloat-3e/source/f128M_to_ui64.c",
|
||||||
"deps/SoftFloat-3e/source/f128M_to_ui64_r_minMag.c",
|
"deps/SoftFloat-3e/source/f128M_to_ui64_r_minMag.c",
|
||||||
|
"deps/SoftFloat-3e/source/extF80M_add.c",
|
||||||
|
"deps/SoftFloat-3e/source/extF80M_div.c",
|
||||||
|
"deps/SoftFloat-3e/source/extF80M_eq.c",
|
||||||
|
"deps/SoftFloat-3e/source/extF80M_le.c",
|
||||||
|
"deps/SoftFloat-3e/source/extF80M_lt.c",
|
||||||
|
"deps/SoftFloat-3e/source/extF80M_mul.c",
|
||||||
|
"deps/SoftFloat-3e/source/extF80M_rem.c",
|
||||||
|
"deps/SoftFloat-3e/source/extF80M_roundToInt.c",
|
||||||
|
"deps/SoftFloat-3e/source/extF80M_sqrt.c",
|
||||||
|
"deps/SoftFloat-3e/source/extF80M_sub.c",
|
||||||
|
"deps/SoftFloat-3e/source/extF80M_to_f16.c",
|
||||||
|
"deps/SoftFloat-3e/source/extF80M_to_f32.c",
|
||||||
|
"deps/SoftFloat-3e/source/extF80M_to_f64.c",
|
||||||
|
"deps/SoftFloat-3e/source/extF80M_to_f128M.c",
|
||||||
"deps/SoftFloat-3e/source/f16_add.c",
|
"deps/SoftFloat-3e/source/f16_add.c",
|
||||||
"deps/SoftFloat-3e/source/f16_div.c",
|
"deps/SoftFloat-3e/source/f16_div.c",
|
||||||
"deps/SoftFloat-3e/source/f16_eq.c",
|
"deps/SoftFloat-3e/source/f16_eq.c",
|
||||||
@ -735,9 +841,12 @@ const softfloat_sources = [_][]const u8{
|
|||||||
"deps/SoftFloat-3e/source/f16_roundToInt.c",
|
"deps/SoftFloat-3e/source/f16_roundToInt.c",
|
||||||
"deps/SoftFloat-3e/source/f16_sqrt.c",
|
"deps/SoftFloat-3e/source/f16_sqrt.c",
|
||||||
"deps/SoftFloat-3e/source/f16_sub.c",
|
"deps/SoftFloat-3e/source/f16_sub.c",
|
||||||
|
"deps/SoftFloat-3e/source/f16_to_extF80M.c",
|
||||||
"deps/SoftFloat-3e/source/f16_to_f128M.c",
|
"deps/SoftFloat-3e/source/f16_to_f128M.c",
|
||||||
"deps/SoftFloat-3e/source/f16_to_f64.c",
|
"deps/SoftFloat-3e/source/f16_to_f64.c",
|
||||||
|
"deps/SoftFloat-3e/source/f32_to_extF80M.c",
|
||||||
"deps/SoftFloat-3e/source/f32_to_f128M.c",
|
"deps/SoftFloat-3e/source/f32_to_f128M.c",
|
||||||
|
"deps/SoftFloat-3e/source/f64_to_extF80M.c",
|
||||||
"deps/SoftFloat-3e/source/f64_to_f128M.c",
|
"deps/SoftFloat-3e/source/f64_to_f128M.c",
|
||||||
"deps/SoftFloat-3e/source/f64_to_f16.c",
|
"deps/SoftFloat-3e/source/f64_to_f16.c",
|
||||||
"deps/SoftFloat-3e/source/i32_to_f128M.c",
|
"deps/SoftFloat-3e/source/i32_to_f128M.c",
|
||||||
@ -745,6 +854,7 @@ const softfloat_sources = [_][]const u8{
|
|||||||
"deps/SoftFloat-3e/source/s_addCarryM.c",
|
"deps/SoftFloat-3e/source/s_addCarryM.c",
|
||||||
"deps/SoftFloat-3e/source/s_addComplCarryM.c",
|
"deps/SoftFloat-3e/source/s_addComplCarryM.c",
|
||||||
"deps/SoftFloat-3e/source/s_addF128M.c",
|
"deps/SoftFloat-3e/source/s_addF128M.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_addExtF80M.c",
|
||||||
"deps/SoftFloat-3e/source/s_addM.c",
|
"deps/SoftFloat-3e/source/s_addM.c",
|
||||||
"deps/SoftFloat-3e/source/s_addMagsF16.c",
|
"deps/SoftFloat-3e/source/s_addMagsF16.c",
|
||||||
"deps/SoftFloat-3e/source/s_addMagsF32.c",
|
"deps/SoftFloat-3e/source/s_addMagsF32.c",
|
||||||
@ -755,12 +865,14 @@ const softfloat_sources = [_][]const u8{
|
|||||||
"deps/SoftFloat-3e/source/s_approxRecip_1Ks.c",
|
"deps/SoftFloat-3e/source/s_approxRecip_1Ks.c",
|
||||||
"deps/SoftFloat-3e/source/s_compare128M.c",
|
"deps/SoftFloat-3e/source/s_compare128M.c",
|
||||||
"deps/SoftFloat-3e/source/s_compare96M.c",
|
"deps/SoftFloat-3e/source/s_compare96M.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_compareNonnormExtF80M.c",
|
||||||
"deps/SoftFloat-3e/source/s_countLeadingZeros16.c",
|
"deps/SoftFloat-3e/source/s_countLeadingZeros16.c",
|
||||||
"deps/SoftFloat-3e/source/s_countLeadingZeros32.c",
|
"deps/SoftFloat-3e/source/s_countLeadingZeros32.c",
|
||||||
"deps/SoftFloat-3e/source/s_countLeadingZeros64.c",
|
"deps/SoftFloat-3e/source/s_countLeadingZeros64.c",
|
||||||
"deps/SoftFloat-3e/source/s_countLeadingZeros8.c",
|
"deps/SoftFloat-3e/source/s_countLeadingZeros8.c",
|
||||||
"deps/SoftFloat-3e/source/s_eq128.c",
|
"deps/SoftFloat-3e/source/s_eq128.c",
|
||||||
"deps/SoftFloat-3e/source/s_invalidF128M.c",
|
"deps/SoftFloat-3e/source/s_invalidF128M.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_invalidExtF80M.c",
|
||||||
"deps/SoftFloat-3e/source/s_isNaNF128M.c",
|
"deps/SoftFloat-3e/source/s_isNaNF128M.c",
|
||||||
"deps/SoftFloat-3e/source/s_le128.c",
|
"deps/SoftFloat-3e/source/s_le128.c",
|
||||||
"deps/SoftFloat-3e/source/s_lt128.c",
|
"deps/SoftFloat-3e/source/s_lt128.c",
|
||||||
@ -771,7 +883,9 @@ const softfloat_sources = [_][]const u8{
|
|||||||
"deps/SoftFloat-3e/source/s_mulAddF32.c",
|
"deps/SoftFloat-3e/source/s_mulAddF32.c",
|
||||||
"deps/SoftFloat-3e/source/s_mulAddF64.c",
|
"deps/SoftFloat-3e/source/s_mulAddF64.c",
|
||||||
"deps/SoftFloat-3e/source/s_negXM.c",
|
"deps/SoftFloat-3e/source/s_negXM.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_normExtF80SigM.c",
|
||||||
"deps/SoftFloat-3e/source/s_normRoundPackMToF128M.c",
|
"deps/SoftFloat-3e/source/s_normRoundPackMToF128M.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_normRoundPackMToExtF80M.c",
|
||||||
"deps/SoftFloat-3e/source/s_normRoundPackToF16.c",
|
"deps/SoftFloat-3e/source/s_normRoundPackToF16.c",
|
||||||
"deps/SoftFloat-3e/source/s_normRoundPackToF32.c",
|
"deps/SoftFloat-3e/source/s_normRoundPackToF32.c",
|
||||||
"deps/SoftFloat-3e/source/s_normRoundPackToF64.c",
|
"deps/SoftFloat-3e/source/s_normRoundPackToF64.c",
|
||||||
@ -782,6 +896,7 @@ const softfloat_sources = [_][]const u8{
|
|||||||
"deps/SoftFloat-3e/source/s_remStepMBy32.c",
|
"deps/SoftFloat-3e/source/s_remStepMBy32.c",
|
||||||
"deps/SoftFloat-3e/source/s_roundMToI64.c",
|
"deps/SoftFloat-3e/source/s_roundMToI64.c",
|
||||||
"deps/SoftFloat-3e/source/s_roundMToUI64.c",
|
"deps/SoftFloat-3e/source/s_roundMToUI64.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_roundPackMToExtF80M.c",
|
||||||
"deps/SoftFloat-3e/source/s_roundPackMToF128M.c",
|
"deps/SoftFloat-3e/source/s_roundPackMToF128M.c",
|
||||||
"deps/SoftFloat-3e/source/s_roundPackToF16.c",
|
"deps/SoftFloat-3e/source/s_roundPackToF16.c",
|
||||||
"deps/SoftFloat-3e/source/s_roundPackToF32.c",
|
"deps/SoftFloat-3e/source/s_roundPackToF32.c",
|
||||||
@ -810,9 +925,12 @@ const softfloat_sources = [_][]const u8{
|
|||||||
"deps/SoftFloat-3e/source/s_subMagsF32.c",
|
"deps/SoftFloat-3e/source/s_subMagsF32.c",
|
||||||
"deps/SoftFloat-3e/source/s_subMagsF64.c",
|
"deps/SoftFloat-3e/source/s_subMagsF64.c",
|
||||||
"deps/SoftFloat-3e/source/s_tryPropagateNaNF128M.c",
|
"deps/SoftFloat-3e/source/s_tryPropagateNaNF128M.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_tryPropagateNaNExtF80M.c",
|
||||||
"deps/SoftFloat-3e/source/softfloat_state.c",
|
"deps/SoftFloat-3e/source/softfloat_state.c",
|
||||||
"deps/SoftFloat-3e/source/ui32_to_f128M.c",
|
"deps/SoftFloat-3e/source/ui32_to_f128M.c",
|
||||||
"deps/SoftFloat-3e/source/ui64_to_f128M.c",
|
"deps/SoftFloat-3e/source/ui64_to_f128M.c",
|
||||||
|
"deps/SoftFloat-3e/source/ui32_to_extF80M.c",
|
||||||
|
"deps/SoftFloat-3e/source/ui64_to_extF80M.c",
|
||||||
};
|
};
|
||||||
|
|
||||||
const stage1_sources = [_][]const u8{
|
const stage1_sources = [_][]const u8{
|
||||||
|
|||||||
980
ci/azure/build.zig
Normal file
980
ci/azure/build.zig
Normal file
@ -0,0 +1,980 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const builtin = std.builtin;
|
||||||
|
const Builder = std.build.Builder;
|
||||||
|
const BufMap = std.BufMap;
|
||||||
|
const mem = std.mem;
|
||||||
|
const ArrayList = std.ArrayList;
|
||||||
|
const io = std.io;
|
||||||
|
const fs = std.fs;
|
||||||
|
const InstallDirectoryOptions = std.build.InstallDirectoryOptions;
|
||||||
|
const assert = std.debug.assert;
|
||||||
|
|
||||||
|
const zig_version = std.builtin.Version{ .major = 0, .minor = 10, .patch = 0 };
|
||||||
|
|
||||||
|
pub fn build(b: *Builder) !void {
|
||||||
|
b.setPreferredReleaseMode(.ReleaseFast);
|
||||||
|
const mode = b.standardReleaseOptions();
|
||||||
|
const target = b.standardTargetOptions(.{});
|
||||||
|
const single_threaded = b.option(bool, "single-threaded", "Build artifacts that run in single threaded mode");
|
||||||
|
const use_zig_libcxx = b.option(bool, "use-zig-libcxx", "If libc++ is needed, use zig's bundled version, don't try to integrate with the system") orelse false;
|
||||||
|
|
||||||
|
const docgen_exe = b.addExecutable("docgen", "doc/docgen.zig");
|
||||||
|
docgen_exe.single_threaded = single_threaded;
|
||||||
|
|
||||||
|
const rel_zig_exe = try fs.path.relative(b.allocator, b.build_root, b.zig_exe);
|
||||||
|
const langref_out_path = fs.path.join(
|
||||||
|
b.allocator,
|
||||||
|
&[_][]const u8{ b.cache_root, "langref.html" },
|
||||||
|
) catch unreachable;
|
||||||
|
const docgen_cmd = docgen_exe.run();
|
||||||
|
docgen_cmd.addArgs(&[_][]const u8{
|
||||||
|
rel_zig_exe,
|
||||||
|
"doc" ++ fs.path.sep_str ++ "langref.html.in",
|
||||||
|
langref_out_path,
|
||||||
|
});
|
||||||
|
docgen_cmd.step.dependOn(&docgen_exe.step);
|
||||||
|
|
||||||
|
const docs_step = b.step("docs", "Build documentation");
|
||||||
|
docs_step.dependOn(&docgen_cmd.step);
|
||||||
|
|
||||||
|
const is_stage1 = b.option(bool, "stage1", "Build the stage1 compiler, put stage2 behind a feature flag") orelse false;
|
||||||
|
const omit_stage2 = b.option(bool, "omit-stage2", "Do not include stage2 behind a feature flag inside stage1") orelse false;
|
||||||
|
const static_llvm = b.option(bool, "static-llvm", "Disable integration with system-installed LLVM, Clang, LLD, and libc++") orelse false;
|
||||||
|
const enable_llvm = b.option(bool, "enable-llvm", "Build self-hosted compiler with LLVM backend enabled") orelse (is_stage1 or static_llvm);
|
||||||
|
const llvm_has_m68k = b.option(
|
||||||
|
bool,
|
||||||
|
"llvm-has-m68k",
|
||||||
|
"Whether LLVM has the experimental target m68k enabled",
|
||||||
|
) orelse false;
|
||||||
|
const llvm_has_csky = b.option(
|
||||||
|
bool,
|
||||||
|
"llvm-has-csky",
|
||||||
|
"Whether LLVM has the experimental target csky enabled",
|
||||||
|
) orelse false;
|
||||||
|
const llvm_has_ve = b.option(
|
||||||
|
bool,
|
||||||
|
"llvm-has-ve",
|
||||||
|
"Whether LLVM has the experimental target ve enabled",
|
||||||
|
) orelse false;
|
||||||
|
const llvm_has_arc = b.option(
|
||||||
|
bool,
|
||||||
|
"llvm-has-arc",
|
||||||
|
"Whether LLVM has the experimental target arc enabled",
|
||||||
|
) orelse false;
|
||||||
|
const config_h_path_option = b.option([]const u8, "config_h", "Path to the generated config.h");
|
||||||
|
|
||||||
|
b.installDirectory(InstallDirectoryOptions{
|
||||||
|
.source_dir = "lib",
|
||||||
|
.install_dir = .lib,
|
||||||
|
.install_subdir = "zig",
|
||||||
|
.exclude_extensions = &[_][]const u8{
|
||||||
|
// exclude files from lib/std/compress/
|
||||||
|
".gz",
|
||||||
|
".z.0",
|
||||||
|
".z.9",
|
||||||
|
"rfc1951.txt",
|
||||||
|
"rfc1952.txt",
|
||||||
|
// exclude files from lib/std/compress/deflate/testdata
|
||||||
|
".expect",
|
||||||
|
".expect-noinput",
|
||||||
|
".golden",
|
||||||
|
".input",
|
||||||
|
"compress-e.txt",
|
||||||
|
"compress-gettysburg.txt",
|
||||||
|
"compress-pi.txt",
|
||||||
|
"rfc1951.txt",
|
||||||
|
// exclude files from lib/std/tz/
|
||||||
|
".tzif",
|
||||||
|
// others
|
||||||
|
"README.md",
|
||||||
|
},
|
||||||
|
.blank_extensions = &[_][]const u8{
|
||||||
|
"test.zig",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const tracy = b.option([]const u8, "tracy", "Enable Tracy integration. Supply path to Tracy source");
|
||||||
|
const tracy_callstack = b.option(bool, "tracy-callstack", "Include callstack information with Tracy data. Does nothing if -Dtracy is not provided") orelse false;
|
||||||
|
const tracy_allocation = b.option(bool, "tracy-allocation", "Include allocation information with Tracy data. Does nothing if -Dtracy is not provided") orelse false;
|
||||||
|
const force_gpa = b.option(bool, "force-gpa", "Force the compiler to use GeneralPurposeAllocator") orelse false;
|
||||||
|
const link_libc = b.option(bool, "force-link-libc", "Force self-hosted compiler to link libc") orelse enable_llvm;
|
||||||
|
const strip = b.option(bool, "strip", "Omit debug information") orelse false;
|
||||||
|
const value_tracing = b.option(bool, "value-tracing", "Enable extra state tracking to help troubleshoot bugs in the compiler (using the std.debug.Trace API)") orelse false;
|
||||||
|
|
||||||
|
const mem_leak_frames: u32 = b.option(u32, "mem-leak-frames", "How many stack frames to print when a memory leak occurs. Tests get 2x this amount.") orelse blk: {
|
||||||
|
if (strip) break :blk @as(u32, 0);
|
||||||
|
if (mode != .Debug) break :blk 0;
|
||||||
|
break :blk 4;
|
||||||
|
};
|
||||||
|
|
||||||
|
const main_file: ?[]const u8 = if (is_stage1) null else "src/main.zig";
|
||||||
|
|
||||||
|
const exe = b.addExecutable("zig", main_file);
|
||||||
|
exe.strip = strip;
|
||||||
|
exe.install();
|
||||||
|
exe.setBuildMode(mode);
|
||||||
|
exe.setTarget(target);
|
||||||
|
|
||||||
|
b.default_step.dependOn(&exe.step);
|
||||||
|
exe.single_threaded = single_threaded;
|
||||||
|
|
||||||
|
if (target.isWindows() and target.getAbi() == .gnu) {
|
||||||
|
// LTO is currently broken on mingw, this can be removed when it's fixed.
|
||||||
|
exe.want_lto = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const exe_options = b.addOptions();
|
||||||
|
exe.addOptions("build_options", exe_options);
|
||||||
|
|
||||||
|
exe_options.addOption(u32, "mem_leak_frames", mem_leak_frames);
|
||||||
|
exe_options.addOption(bool, "skip_non_native", false);
|
||||||
|
exe_options.addOption(bool, "have_llvm", enable_llvm);
|
||||||
|
exe_options.addOption(bool, "llvm_has_m68k", llvm_has_m68k);
|
||||||
|
exe_options.addOption(bool, "llvm_has_csky", llvm_has_csky);
|
||||||
|
exe_options.addOption(bool, "llvm_has_ve", llvm_has_ve);
|
||||||
|
exe_options.addOption(bool, "llvm_has_arc", llvm_has_arc);
|
||||||
|
exe_options.addOption(bool, "force_gpa", force_gpa);
|
||||||
|
|
||||||
|
if (link_libc) {
|
||||||
|
exe.linkLibC();
|
||||||
|
}
|
||||||
|
|
||||||
|
const is_debug = mode == .Debug;
|
||||||
|
const enable_logging = b.option(bool, "log", "Enable debug logging with --debug-log") orelse is_debug;
|
||||||
|
const enable_link_snapshots = b.option(bool, "link-snapshot", "Whether to enable linker state snapshots") orelse false;
|
||||||
|
|
||||||
|
const opt_version_string = b.option([]const u8, "version-string", "Override Zig version string. Default is to find out with git.");
|
||||||
|
const version = if (opt_version_string) |version| version else v: {
|
||||||
|
const version_string = b.fmt("{d}.{d}.{d}", .{ zig_version.major, zig_version.minor, zig_version.patch });
|
||||||
|
|
||||||
|
var code: u8 = undefined;
|
||||||
|
const git_describe_untrimmed = b.execAllowFail(&[_][]const u8{
|
||||||
|
"git", "-C", b.build_root, "describe", "--match", "*.*.*", "--tags",
|
||||||
|
}, &code, .Ignore) catch {
|
||||||
|
break :v version_string;
|
||||||
|
};
|
||||||
|
const git_describe = mem.trim(u8, git_describe_untrimmed, " \n\r");
|
||||||
|
|
||||||
|
switch (mem.count(u8, git_describe, "-")) {
|
||||||
|
0 => {
|
||||||
|
// Tagged release version (e.g. 0.9.0).
|
||||||
|
if (!mem.eql(u8, git_describe, version_string)) {
|
||||||
|
std.debug.print("Zig version '{s}' does not match Git tag '{s}'\n", .{ version_string, git_describe });
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
break :v version_string;
|
||||||
|
},
|
||||||
|
2 => {
|
||||||
|
// Untagged development build (e.g. 0.9.0-dev.2025+ecf0050a9).
|
||||||
|
var it = mem.split(u8, git_describe, "-");
|
||||||
|
const tagged_ancestor = it.next() orelse unreachable;
|
||||||
|
const commit_height = it.next() orelse unreachable;
|
||||||
|
const commit_id = it.next() orelse unreachable;
|
||||||
|
|
||||||
|
const ancestor_ver = try std.builtin.Version.parse(tagged_ancestor);
|
||||||
|
if (zig_version.order(ancestor_ver) != .gt) {
|
||||||
|
std.debug.print("Zig version '{}' must be greater than tagged ancestor '{}'\n", .{ zig_version, ancestor_ver });
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that the commit hash is prefixed with a 'g' (a Git convention).
|
||||||
|
if (commit_id.len < 1 or commit_id[0] != 'g') {
|
||||||
|
std.debug.print("Unexpected `git describe` output: {s}\n", .{git_describe});
|
||||||
|
break :v version_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The version is reformatted in accordance with the https://semver.org specification.
|
||||||
|
break :v b.fmt("{s}-dev.{s}+{s}", .{ version_string, commit_height, commit_id[1..] });
|
||||||
|
},
|
||||||
|
else => {
|
||||||
|
std.debug.print("Unexpected `git describe` output: {s}\n", .{git_describe});
|
||||||
|
break :v version_string;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
exe_options.addOption([:0]const u8, "version", try b.allocator.dupeZ(u8, version));
|
||||||
|
|
||||||
|
if (enable_llvm) {
|
||||||
|
const cmake_cfg = if (static_llvm) null else findAndParseConfigH(b, config_h_path_option);
|
||||||
|
|
||||||
|
if (is_stage1) {
|
||||||
|
const softfloat = b.addStaticLibrary("softfloat", null);
|
||||||
|
softfloat.setBuildMode(.ReleaseFast);
|
||||||
|
softfloat.setTarget(target);
|
||||||
|
softfloat.addIncludeDir("deps/SoftFloat-3e-prebuilt");
|
||||||
|
softfloat.addIncludeDir("deps/SoftFloat-3e/source/8086");
|
||||||
|
softfloat.addIncludeDir("deps/SoftFloat-3e/source/include");
|
||||||
|
softfloat.addCSourceFiles(&softfloat_sources, &[_][]const u8{ "-std=c99", "-O3" });
|
||||||
|
softfloat.single_threaded = single_threaded;
|
||||||
|
|
||||||
|
const zig0 = b.addExecutable("zig0", null);
|
||||||
|
zig0.addCSourceFiles(&.{"src/stage1/zig0.cpp"}, &exe_cflags);
|
||||||
|
zig0.addIncludeDir("zig-cache/tmp"); // for config.h
|
||||||
|
zig0.defineCMacro("ZIG_VERSION_MAJOR", b.fmt("{d}", .{zig_version.major}));
|
||||||
|
zig0.defineCMacro("ZIG_VERSION_MINOR", b.fmt("{d}", .{zig_version.minor}));
|
||||||
|
zig0.defineCMacro("ZIG_VERSION_PATCH", b.fmt("{d}", .{zig_version.patch}));
|
||||||
|
zig0.defineCMacro("ZIG_VERSION_STRING", b.fmt("\"{s}\"", .{version}));
|
||||||
|
|
||||||
|
for ([_]*std.build.LibExeObjStep{ zig0, exe }) |artifact| {
|
||||||
|
artifact.addIncludeDir("src");
|
||||||
|
artifact.addIncludeDir("deps/SoftFloat-3e/source/include");
|
||||||
|
artifact.addIncludeDir("deps/SoftFloat-3e-prebuilt");
|
||||||
|
|
||||||
|
artifact.defineCMacro("ZIG_LINK_MODE", "Static");
|
||||||
|
|
||||||
|
artifact.addCSourceFiles(&stage1_sources, &exe_cflags);
|
||||||
|
artifact.addCSourceFiles(&optimized_c_sources, &[_][]const u8{ "-std=c99", "-O3" });
|
||||||
|
|
||||||
|
artifact.linkLibrary(softfloat);
|
||||||
|
artifact.linkLibCpp();
|
||||||
|
}
|
||||||
|
|
||||||
|
try addStaticLlvmOptionsToExe(zig0);
|
||||||
|
|
||||||
|
const zig1_obj_ext = target.getObjectFormat().fileExt(target.getCpuArch());
|
||||||
|
const zig1_obj_path = b.pathJoin(&.{ "zig-cache", "tmp", b.fmt("zig1{s}", .{zig1_obj_ext}) });
|
||||||
|
const zig1_compiler_rt_path = b.pathJoin(&.{ b.pathFromRoot("lib"), "std", "special", "compiler_rt.zig" });
|
||||||
|
|
||||||
|
const zig1_obj = zig0.run();
|
||||||
|
zig1_obj.addArgs(&.{
|
||||||
|
"src/stage1.zig",
|
||||||
|
"-target",
|
||||||
|
try target.zigTriple(b.allocator),
|
||||||
|
"-mcpu=baseline",
|
||||||
|
"--name",
|
||||||
|
"zig1",
|
||||||
|
"--zig-lib-dir",
|
||||||
|
b.pathFromRoot("lib"),
|
||||||
|
b.fmt("-femit-bin={s}", .{b.pathFromRoot(zig1_obj_path)}),
|
||||||
|
"-fcompiler-rt",
|
||||||
|
"-lc",
|
||||||
|
});
|
||||||
|
{
|
||||||
|
zig1_obj.addArgs(&.{ "--pkg-begin", "build_options" });
|
||||||
|
zig1_obj.addFileSourceArg(exe_options.getSource());
|
||||||
|
zig1_obj.addArgs(&.{ "--pkg-end", "--pkg-begin", "compiler_rt", zig1_compiler_rt_path, "--pkg-end" });
|
||||||
|
}
|
||||||
|
switch (mode) {
|
||||||
|
.Debug => {},
|
||||||
|
.ReleaseFast => {
|
||||||
|
zig1_obj.addArg("-OReleaseFast");
|
||||||
|
zig1_obj.addArg("--strip");
|
||||||
|
},
|
||||||
|
.ReleaseSafe => {
|
||||||
|
zig1_obj.addArg("-OReleaseSafe");
|
||||||
|
zig1_obj.addArg("--strip");
|
||||||
|
},
|
||||||
|
.ReleaseSmall => {
|
||||||
|
zig1_obj.addArg("-OReleaseSmall");
|
||||||
|
zig1_obj.addArg("--strip");
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if (single_threaded orelse false) {
|
||||||
|
zig1_obj.addArg("-fsingle-threaded");
|
||||||
|
}
|
||||||
|
|
||||||
|
exe.step.dependOn(&zig1_obj.step);
|
||||||
|
exe.addObjectFile(zig1_obj_path);
|
||||||
|
|
||||||
|
// This is intentionally a dummy path. stage1.zig tries to @import("compiler_rt") in case
|
||||||
|
// of being built by cmake. But when built by zig it's gonna get a compiler_rt so that
|
||||||
|
// is pointless.
|
||||||
|
exe.addPackagePath("compiler_rt", "src/empty.zig");
|
||||||
|
}
|
||||||
|
if (cmake_cfg) |cfg| {
|
||||||
|
// Inside this code path, we have to coordinate with system packaged LLVM, Clang, and LLD.
|
||||||
|
// That means we also have to rely on stage1 compiled c++ files. We parse config.h to find
|
||||||
|
// the information passed on to us from cmake.
|
||||||
|
if (cfg.cmake_prefix_path.len > 0) {
|
||||||
|
b.addSearchPrefix(cfg.cmake_prefix_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
try addCmakeCfgOptionsToExe(b, cfg, exe, use_zig_libcxx);
|
||||||
|
} else {
|
||||||
|
// Here we are -Denable-llvm but no cmake integration.
|
||||||
|
try addStaticLlvmOptionsToExe(exe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const semver = try std.SemanticVersion.parse(version);
|
||||||
|
exe_options.addOption(std.SemanticVersion, "semver", semver);
|
||||||
|
|
||||||
|
exe_options.addOption(bool, "enable_logging", enable_logging);
|
||||||
|
exe_options.addOption(bool, "enable_link_snapshots", enable_link_snapshots);
|
||||||
|
exe_options.addOption(bool, "enable_tracy", tracy != null);
|
||||||
|
exe_options.addOption(bool, "enable_tracy_callstack", tracy_callstack);
|
||||||
|
exe_options.addOption(bool, "enable_tracy_allocation", tracy_allocation);
|
||||||
|
exe_options.addOption(bool, "value_tracing", value_tracing);
|
||||||
|
exe_options.addOption(bool, "is_stage1", is_stage1);
|
||||||
|
exe_options.addOption(bool, "omit_stage2", omit_stage2);
|
||||||
|
if (tracy) |tracy_path| {
|
||||||
|
const client_cpp = fs.path.join(
|
||||||
|
b.allocator,
|
||||||
|
&[_][]const u8{ tracy_path, "TracyClient.cpp" },
|
||||||
|
) catch unreachable;
|
||||||
|
|
||||||
|
// On mingw, we need to opt into windows 7+ to get some features required by tracy.
|
||||||
|
const tracy_c_flags: []const []const u8 = if (target.isWindows() and target.getAbi() == .gnu)
|
||||||
|
&[_][]const u8{ "-DTRACY_ENABLE=1", "-fno-sanitize=undefined", "-D_WIN32_WINNT=0x601" }
|
||||||
|
else
|
||||||
|
&[_][]const u8{ "-DTRACY_ENABLE=1", "-fno-sanitize=undefined" };
|
||||||
|
|
||||||
|
exe.addIncludeDir(tracy_path);
|
||||||
|
exe.addCSourceFile(client_cpp, tracy_c_flags);
|
||||||
|
if (!enable_llvm) {
|
||||||
|
exe.linkSystemLibraryName("c++");
|
||||||
|
}
|
||||||
|
exe.linkLibC();
|
||||||
|
|
||||||
|
if (target.isWindows()) {
|
||||||
|
exe.linkSystemLibrary("dbghelp");
|
||||||
|
exe.linkSystemLibrary("ws2_32");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const exe_cflags = [_][]const u8{
|
||||||
|
"-std=c++14",
|
||||||
|
"-D__STDC_CONSTANT_MACROS",
|
||||||
|
"-D__STDC_FORMAT_MACROS",
|
||||||
|
"-D__STDC_LIMIT_MACROS",
|
||||||
|
"-D_GNU_SOURCE",
|
||||||
|
"-fvisibility-inlines-hidden",
|
||||||
|
"-fno-exceptions",
|
||||||
|
"-fno-rtti",
|
||||||
|
"-Werror=type-limits",
|
||||||
|
"-Wno-missing-braces",
|
||||||
|
"-Wno-comment",
|
||||||
|
};
|
||||||
|
|
||||||
|
fn addCmakeCfgOptionsToExe(
|
||||||
|
b: *Builder,
|
||||||
|
cfg: CMakeConfig,
|
||||||
|
exe: *std.build.LibExeObjStep,
|
||||||
|
use_zig_libcxx: bool,
|
||||||
|
) !void {
|
||||||
|
exe.addObjectFile(fs.path.join(b.allocator, &[_][]const u8{
|
||||||
|
cfg.cmake_binary_dir,
|
||||||
|
"zigcpp",
|
||||||
|
b.fmt("{s}{s}{s}", .{ exe.target.libPrefix(), "zigcpp", exe.target.staticLibSuffix() }),
|
||||||
|
}) catch unreachable);
|
||||||
|
assert(cfg.lld_include_dir.len != 0);
|
||||||
|
exe.addIncludeDir(cfg.lld_include_dir);
|
||||||
|
addCMakeLibraryList(exe, cfg.clang_libraries);
|
||||||
|
addCMakeLibraryList(exe, cfg.lld_libraries);
|
||||||
|
addCMakeLibraryList(exe, cfg.llvm_libraries);
|
||||||
|
|
||||||
|
if (use_zig_libcxx) {
|
||||||
|
exe.linkLibCpp();
|
||||||
|
} else {
|
||||||
|
const need_cpp_includes = true;
|
||||||
|
|
||||||
|
// System -lc++ must be used because in this code path we are attempting to link
|
||||||
|
// against system-provided LLVM, Clang, LLD.
|
||||||
|
if (exe.target.getOsTag() == .linux) {
|
||||||
|
// First we try to static link against gcc libstdc++. If that doesn't work,
|
||||||
|
// we fall back to -lc++ and cross our fingers.
|
||||||
|
addCxxKnownPath(b, cfg, exe, "libstdc++.a", "", need_cpp_includes) catch |err| switch (err) {
|
||||||
|
error.RequiredLibraryNotFound => {
|
||||||
|
exe.linkSystemLibrary("c++");
|
||||||
|
},
|
||||||
|
else => |e| return e,
|
||||||
|
};
|
||||||
|
exe.linkSystemLibrary("unwind");
|
||||||
|
} else if (exe.target.isFreeBSD()) {
|
||||||
|
try addCxxKnownPath(b, cfg, exe, "libc++.a", null, need_cpp_includes);
|
||||||
|
exe.linkSystemLibrary("pthread");
|
||||||
|
} else if (exe.target.getOsTag() == .openbsd) {
|
||||||
|
try addCxxKnownPath(b, cfg, exe, "libc++.a", null, need_cpp_includes);
|
||||||
|
try addCxxKnownPath(b, cfg, exe, "libc++abi.a", null, need_cpp_includes);
|
||||||
|
} else if (exe.target.isDarwin()) {
|
||||||
|
exe.linkSystemLibrary("c++");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfg.dia_guids_lib.len != 0) {
|
||||||
|
exe.addObjectFile(cfg.dia_guids_lib);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn addStaticLlvmOptionsToExe(
|
||||||
|
exe: *std.build.LibExeObjStep,
|
||||||
|
) !void {
|
||||||
|
// Adds the Zig C++ sources which both stage1 and stage2 need.
|
||||||
|
//
|
||||||
|
// We need this because otherwise zig_clang_cc1_main.cpp ends up pulling
|
||||||
|
// in a dependency on llvm::cfg::Update<llvm::BasicBlock*>::dump() which is
|
||||||
|
// unavailable when LLVM is compiled in Release mode.
|
||||||
|
const zig_cpp_cflags = exe_cflags ++ [_][]const u8{"-DNDEBUG=1"};
|
||||||
|
exe.addCSourceFiles(&zig_cpp_sources, &zig_cpp_cflags);
|
||||||
|
|
||||||
|
for (clang_libs) |lib_name| {
|
||||||
|
exe.linkSystemLibrary(lib_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (lld_libs) |lib_name| {
|
||||||
|
exe.linkSystemLibrary(lib_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (llvm_libs) |lib_name| {
|
||||||
|
exe.linkSystemLibrary(lib_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
exe.linkSystemLibrary("z");
|
||||||
|
|
||||||
|
// This means we rely on clang-or-zig-built LLVM, Clang, LLD libraries.
|
||||||
|
exe.linkSystemLibrary("c++");
|
||||||
|
|
||||||
|
if (exe.target.getOs().tag == .windows) {
|
||||||
|
exe.linkSystemLibrary("version");
|
||||||
|
exe.linkSystemLibrary("uuid");
|
||||||
|
exe.linkSystemLibrary("ole32");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn addCxxKnownPath(
|
||||||
|
b: *Builder,
|
||||||
|
ctx: CMakeConfig,
|
||||||
|
exe: *std.build.LibExeObjStep,
|
||||||
|
objname: []const u8,
|
||||||
|
errtxt: ?[]const u8,
|
||||||
|
need_cpp_includes: bool,
|
||||||
|
) !void {
|
||||||
|
const path_padded = try b.exec(&[_][]const u8{
|
||||||
|
ctx.cxx_compiler,
|
||||||
|
b.fmt("-print-file-name={s}", .{objname}),
|
||||||
|
});
|
||||||
|
const path_unpadded = mem.tokenize(u8, path_padded, "\r\n").next().?;
|
||||||
|
if (mem.eql(u8, path_unpadded, objname)) {
|
||||||
|
if (errtxt) |msg| {
|
||||||
|
std.debug.print("{s}", .{msg});
|
||||||
|
} else {
|
||||||
|
std.debug.print("Unable to determine path to {s}\n", .{objname});
|
||||||
|
}
|
||||||
|
return error.RequiredLibraryNotFound;
|
||||||
|
}
|
||||||
|
exe.addObjectFile(path_unpadded);
|
||||||
|
|
||||||
|
// TODO a way to integrate with system c++ include files here
|
||||||
|
// cc -E -Wp,-v -xc++ /dev/null
|
||||||
|
if (need_cpp_includes) {
|
||||||
|
// I used these temporarily for testing something but we obviously need a
|
||||||
|
// more general purpose solution here.
|
||||||
|
//exe.addIncludeDir("/nix/store/fvf3qjqa5qpcjjkq37pb6ypnk1mzhf5h-gcc-9.3.0/lib/gcc/x86_64-unknown-linux-gnu/9.3.0/../../../../include/c++/9.3.0");
|
||||||
|
//exe.addIncludeDir("/nix/store/fvf3qjqa5qpcjjkq37pb6ypnk1mzhf5h-gcc-9.3.0/lib/gcc/x86_64-unknown-linux-gnu/9.3.0/../../../../include/c++/9.3.0/x86_64-unknown-linux-gnu");
|
||||||
|
//exe.addIncludeDir("/nix/store/fvf3qjqa5qpcjjkq37pb6ypnk1mzhf5h-gcc-9.3.0/lib/gcc/x86_64-unknown-linux-gnu/9.3.0/../../../../include/c++/9.3.0/backward");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn addCMakeLibraryList(exe: *std.build.LibExeObjStep, list: []const u8) void {
|
||||||
|
var it = mem.tokenize(u8, list, ";");
|
||||||
|
while (it.next()) |lib| {
|
||||||
|
if (mem.startsWith(u8, lib, "-l")) {
|
||||||
|
exe.linkSystemLibrary(lib["-l".len..]);
|
||||||
|
} else {
|
||||||
|
exe.addObjectFile(lib);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const CMakeConfig = struct {
|
||||||
|
cmake_binary_dir: []const u8,
|
||||||
|
cmake_prefix_path: []const u8,
|
||||||
|
cxx_compiler: []const u8,
|
||||||
|
lld_include_dir: []const u8,
|
||||||
|
lld_libraries: []const u8,
|
||||||
|
clang_libraries: []const u8,
|
||||||
|
llvm_libraries: []const u8,
|
||||||
|
dia_guids_lib: []const u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
const max_config_h_bytes = 1 * 1024 * 1024;
|
||||||
|
|
||||||
|
fn findAndParseConfigH(b: *Builder, config_h_path_option: ?[]const u8) ?CMakeConfig {
|
||||||
|
const config_h_text: []const u8 = if (config_h_path_option) |config_h_path| blk: {
|
||||||
|
break :blk fs.cwd().readFileAlloc(b.allocator, config_h_path, max_config_h_bytes) catch unreachable;
|
||||||
|
} else blk: {
|
||||||
|
// TODO this should stop looking for config.h once it detects we hit the
|
||||||
|
// zig source root directory.
|
||||||
|
var check_dir = fs.path.dirname(b.zig_exe).?;
|
||||||
|
while (true) {
|
||||||
|
var dir = fs.cwd().openDir(check_dir, .{}) catch unreachable;
|
||||||
|
defer dir.close();
|
||||||
|
|
||||||
|
break :blk dir.readFileAlloc(b.allocator, "config.h", max_config_h_bytes) catch |err| switch (err) {
|
||||||
|
error.FileNotFound => {
|
||||||
|
const new_check_dir = fs.path.dirname(check_dir);
|
||||||
|
if (new_check_dir == null or mem.eql(u8, new_check_dir.?, check_dir)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
check_dir = new_check_dir.?;
|
||||||
|
continue;
|
||||||
|
},
|
||||||
|
else => unreachable,
|
||||||
|
};
|
||||||
|
} else unreachable; // TODO should not need `else unreachable`.
|
||||||
|
};
|
||||||
|
|
||||||
|
var ctx: CMakeConfig = .{
|
||||||
|
.cmake_binary_dir = undefined,
|
||||||
|
.cmake_prefix_path = undefined,
|
||||||
|
.cxx_compiler = undefined,
|
||||||
|
.lld_include_dir = undefined,
|
||||||
|
.lld_libraries = undefined,
|
||||||
|
.clang_libraries = undefined,
|
||||||
|
.llvm_libraries = undefined,
|
||||||
|
.dia_guids_lib = undefined,
|
||||||
|
};
|
||||||
|
|
||||||
|
const mappings = [_]struct { prefix: []const u8, field: []const u8 }{
|
||||||
|
.{
|
||||||
|
.prefix = "#define ZIG_CMAKE_BINARY_DIR ",
|
||||||
|
.field = "cmake_binary_dir",
|
||||||
|
},
|
||||||
|
.{
|
||||||
|
.prefix = "#define ZIG_CMAKE_PREFIX_PATH ",
|
||||||
|
.field = "cmake_prefix_path",
|
||||||
|
},
|
||||||
|
.{
|
||||||
|
.prefix = "#define ZIG_CXX_COMPILER ",
|
||||||
|
.field = "cxx_compiler",
|
||||||
|
},
|
||||||
|
.{
|
||||||
|
.prefix = "#define ZIG_LLD_INCLUDE_PATH ",
|
||||||
|
.field = "lld_include_dir",
|
||||||
|
},
|
||||||
|
.{
|
||||||
|
.prefix = "#define ZIG_LLD_LIBRARIES ",
|
||||||
|
.field = "lld_libraries",
|
||||||
|
},
|
||||||
|
.{
|
||||||
|
.prefix = "#define ZIG_CLANG_LIBRARIES ",
|
||||||
|
.field = "clang_libraries",
|
||||||
|
},
|
||||||
|
.{
|
||||||
|
.prefix = "#define ZIG_LLVM_LIBRARIES ",
|
||||||
|
.field = "llvm_libraries",
|
||||||
|
},
|
||||||
|
.{
|
||||||
|
.prefix = "#define ZIG_DIA_GUIDS_LIB ",
|
||||||
|
.field = "dia_guids_lib",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
var lines_it = mem.tokenize(u8, config_h_text, "\r\n");
|
||||||
|
while (lines_it.next()) |line| {
|
||||||
|
inline for (mappings) |mapping| {
|
||||||
|
if (mem.startsWith(u8, line, mapping.prefix)) {
|
||||||
|
var it = mem.split(u8, line, "\"");
|
||||||
|
_ = it.next().?; // skip the stuff before the quote
|
||||||
|
const quoted = it.next().?; // the stuff inside the quote
|
||||||
|
@field(ctx, mapping.field) = toNativePathSep(b, quoted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn toNativePathSep(b: *Builder, s: []const u8) []u8 {
|
||||||
|
const duplicated = b.allocator.dupe(u8, s) catch unreachable;
|
||||||
|
for (duplicated) |*byte| switch (byte.*) {
|
||||||
|
'/' => byte.* = fs.path.sep,
|
||||||
|
else => {},
|
||||||
|
};
|
||||||
|
return duplicated;
|
||||||
|
}
|
||||||
|
|
||||||
|
const softfloat_sources = [_][]const u8{
|
||||||
|
"deps/SoftFloat-3e/source/8086/f128M_isSignalingNaN.c",
|
||||||
|
"deps/SoftFloat-3e/source/8086/extF80M_isSignalingNaN.c",
|
||||||
|
"deps/SoftFloat-3e/source/8086/s_commonNaNToF128M.c",
|
||||||
|
"deps/SoftFloat-3e/source/8086/s_commonNaNToExtF80M.c",
|
||||||
|
"deps/SoftFloat-3e/source/8086/s_commonNaNToF16UI.c",
|
||||||
|
"deps/SoftFloat-3e/source/8086/s_commonNaNToF32UI.c",
|
||||||
|
"deps/SoftFloat-3e/source/8086/s_commonNaNToF64UI.c",
|
||||||
|
"deps/SoftFloat-3e/source/8086/s_f128MToCommonNaN.c",
|
||||||
|
"deps/SoftFloat-3e/source/8086/s_extF80MToCommonNaN.c",
|
||||||
|
"deps/SoftFloat-3e/source/8086/s_f16UIToCommonNaN.c",
|
||||||
|
"deps/SoftFloat-3e/source/8086/s_f32UIToCommonNaN.c",
|
||||||
|
"deps/SoftFloat-3e/source/8086/s_f64UIToCommonNaN.c",
|
||||||
|
"deps/SoftFloat-3e/source/8086/s_propagateNaNF128M.c",
|
||||||
|
"deps/SoftFloat-3e/source/8086/s_propagateNaNExtF80M.c",
|
||||||
|
"deps/SoftFloat-3e/source/8086/s_propagateNaNF16UI.c",
|
||||||
|
"deps/SoftFloat-3e/source/8086/softfloat_raiseFlags.c",
|
||||||
|
"deps/SoftFloat-3e/source/f128M_add.c",
|
||||||
|
"deps/SoftFloat-3e/source/f128M_div.c",
|
||||||
|
"deps/SoftFloat-3e/source/f128M_eq.c",
|
||||||
|
"deps/SoftFloat-3e/source/f128M_eq_signaling.c",
|
||||||
|
"deps/SoftFloat-3e/source/f128M_le.c",
|
||||||
|
"deps/SoftFloat-3e/source/f128M_le_quiet.c",
|
||||||
|
"deps/SoftFloat-3e/source/f128M_lt.c",
|
||||||
|
"deps/SoftFloat-3e/source/f128M_lt_quiet.c",
|
||||||
|
"deps/SoftFloat-3e/source/f128M_mul.c",
|
||||||
|
"deps/SoftFloat-3e/source/f128M_mulAdd.c",
|
||||||
|
"deps/SoftFloat-3e/source/f128M_rem.c",
|
||||||
|
"deps/SoftFloat-3e/source/f128M_roundToInt.c",
|
||||||
|
"deps/SoftFloat-3e/source/f128M_sqrt.c",
|
||||||
|
"deps/SoftFloat-3e/source/f128M_sub.c",
|
||||||
|
"deps/SoftFloat-3e/source/f128M_to_f16.c",
|
||||||
|
"deps/SoftFloat-3e/source/f128M_to_f32.c",
|
||||||
|
"deps/SoftFloat-3e/source/f128M_to_f64.c",
|
||||||
|
"deps/SoftFloat-3e/source/f128M_to_extF80M.c",
|
||||||
|
"deps/SoftFloat-3e/source/f128M_to_i32.c",
|
||||||
|
"deps/SoftFloat-3e/source/f128M_to_i32_r_minMag.c",
|
||||||
|
"deps/SoftFloat-3e/source/f128M_to_i64.c",
|
||||||
|
"deps/SoftFloat-3e/source/f128M_to_i64_r_minMag.c",
|
||||||
|
"deps/SoftFloat-3e/source/f128M_to_ui32.c",
|
||||||
|
"deps/SoftFloat-3e/source/f128M_to_ui32_r_minMag.c",
|
||||||
|
"deps/SoftFloat-3e/source/f128M_to_ui64.c",
|
||||||
|
"deps/SoftFloat-3e/source/f128M_to_ui64_r_minMag.c",
|
||||||
|
"deps/SoftFloat-3e/source/extF80M_add.c",
|
||||||
|
"deps/SoftFloat-3e/source/extF80M_div.c",
|
||||||
|
"deps/SoftFloat-3e/source/extF80M_eq.c",
|
||||||
|
"deps/SoftFloat-3e/source/extF80M_le.c",
|
||||||
|
"deps/SoftFloat-3e/source/extF80M_lt.c",
|
||||||
|
"deps/SoftFloat-3e/source/extF80M_mul.c",
|
||||||
|
"deps/SoftFloat-3e/source/extF80M_rem.c",
|
||||||
|
"deps/SoftFloat-3e/source/extF80M_roundToInt.c",
|
||||||
|
"deps/SoftFloat-3e/source/extF80M_sqrt.c",
|
||||||
|
"deps/SoftFloat-3e/source/extF80M_sub.c",
|
||||||
|
"deps/SoftFloat-3e/source/extF80M_to_f16.c",
|
||||||
|
"deps/SoftFloat-3e/source/extF80M_to_f32.c",
|
||||||
|
"deps/SoftFloat-3e/source/extF80M_to_f64.c",
|
||||||
|
"deps/SoftFloat-3e/source/extF80M_to_f128M.c",
|
||||||
|
"deps/SoftFloat-3e/source/f16_add.c",
|
||||||
|
"deps/SoftFloat-3e/source/f16_div.c",
|
||||||
|
"deps/SoftFloat-3e/source/f16_eq.c",
|
||||||
|
"deps/SoftFloat-3e/source/f16_isSignalingNaN.c",
|
||||||
|
"deps/SoftFloat-3e/source/f16_lt.c",
|
||||||
|
"deps/SoftFloat-3e/source/f16_mul.c",
|
||||||
|
"deps/SoftFloat-3e/source/f16_mulAdd.c",
|
||||||
|
"deps/SoftFloat-3e/source/f16_rem.c",
|
||||||
|
"deps/SoftFloat-3e/source/f16_roundToInt.c",
|
||||||
|
"deps/SoftFloat-3e/source/f16_sqrt.c",
|
||||||
|
"deps/SoftFloat-3e/source/f16_sub.c",
|
||||||
|
"deps/SoftFloat-3e/source/f16_to_extF80M.c",
|
||||||
|
"deps/SoftFloat-3e/source/f16_to_f128M.c",
|
||||||
|
"deps/SoftFloat-3e/source/f16_to_f64.c",
|
||||||
|
"deps/SoftFloat-3e/source/f32_to_extF80M.c",
|
||||||
|
"deps/SoftFloat-3e/source/f32_to_f128M.c",
|
||||||
|
"deps/SoftFloat-3e/source/f64_to_extF80M.c",
|
||||||
|
"deps/SoftFloat-3e/source/f64_to_f128M.c",
|
||||||
|
"deps/SoftFloat-3e/source/f64_to_f16.c",
|
||||||
|
"deps/SoftFloat-3e/source/i32_to_f128M.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_add256M.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_addCarryM.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_addComplCarryM.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_addF128M.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_addExtF80M.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_addM.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_addMagsF16.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_addMagsF32.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_addMagsF64.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_approxRecip32_1.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_approxRecipSqrt32_1.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_approxRecipSqrt_1Ks.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_approxRecip_1Ks.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_compare128M.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_compare96M.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_compareNonnormExtF80M.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_countLeadingZeros16.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_countLeadingZeros32.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_countLeadingZeros64.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_countLeadingZeros8.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_eq128.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_invalidF128M.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_invalidExtF80M.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_isNaNF128M.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_le128.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_lt128.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_mul128MTo256M.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_mul64To128M.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_mulAddF128M.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_mulAddF16.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_mulAddF32.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_mulAddF64.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_negXM.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_normExtF80SigM.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_normRoundPackMToF128M.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_normRoundPackMToExtF80M.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_normRoundPackToF16.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_normRoundPackToF32.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_normRoundPackToF64.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_normSubnormalF128SigM.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_normSubnormalF16Sig.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_normSubnormalF32Sig.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_normSubnormalF64Sig.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_remStepMBy32.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_roundMToI64.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_roundMToUI64.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_roundPackMToExtF80M.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_roundPackMToF128M.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_roundPackToF16.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_roundPackToF32.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_roundPackToF64.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_roundToI32.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_roundToI64.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_roundToUI32.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_roundToUI64.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_shiftLeftM.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_shiftNormSigF128M.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_shiftRightJam256M.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_shiftRightJam32.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_shiftRightJam64.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_shiftRightJamM.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_shiftRightM.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_shortShiftLeft64To96M.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_shortShiftLeftM.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_shortShiftRightExtendM.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_shortShiftRightJam64.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_shortShiftRightJamM.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_shortShiftRightM.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_sub1XM.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_sub256M.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_subM.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_subMagsF16.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_subMagsF32.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_subMagsF64.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_tryPropagateNaNF128M.c",
|
||||||
|
"deps/SoftFloat-3e/source/s_tryPropagateNaNExtF80M.c",
|
||||||
|
"deps/SoftFloat-3e/source/softfloat_state.c",
|
||||||
|
"deps/SoftFloat-3e/source/ui32_to_f128M.c",
|
||||||
|
"deps/SoftFloat-3e/source/ui64_to_f128M.c",
|
||||||
|
"deps/SoftFloat-3e/source/ui32_to_extF80M.c",
|
||||||
|
"deps/SoftFloat-3e/source/ui64_to_extF80M.c",
|
||||||
|
};
|
||||||
|
|
||||||
|
const stage1_sources = [_][]const u8{
|
||||||
|
"src/stage1/analyze.cpp",
|
||||||
|
"src/stage1/astgen.cpp",
|
||||||
|
"src/stage1/bigfloat.cpp",
|
||||||
|
"src/stage1/bigint.cpp",
|
||||||
|
"src/stage1/buffer.cpp",
|
||||||
|
"src/stage1/codegen.cpp",
|
||||||
|
"src/stage1/dump_analysis.cpp",
|
||||||
|
"src/stage1/errmsg.cpp",
|
||||||
|
"src/stage1/error.cpp",
|
||||||
|
"src/stage1/heap.cpp",
|
||||||
|
"src/stage1/ir.cpp",
|
||||||
|
"src/stage1/ir_print.cpp",
|
||||||
|
"src/stage1/mem.cpp",
|
||||||
|
"src/stage1/os.cpp",
|
||||||
|
"src/stage1/parser.cpp",
|
||||||
|
"src/stage1/range_set.cpp",
|
||||||
|
"src/stage1/stage1.cpp",
|
||||||
|
"src/stage1/target.cpp",
|
||||||
|
"src/stage1/tokenizer.cpp",
|
||||||
|
"src/stage1/util.cpp",
|
||||||
|
"src/stage1/softfloat_ext.cpp",
|
||||||
|
};
|
||||||
|
const optimized_c_sources = [_][]const u8{
|
||||||
|
"src/stage1/parse_f128.c",
|
||||||
|
};
|
||||||
|
const zig_cpp_sources = [_][]const u8{
|
||||||
|
// These are planned to stay even when we are self-hosted.
|
||||||
|
"src/zig_llvm.cpp",
|
||||||
|
"src/zig_clang.cpp",
|
||||||
|
"src/zig_llvm-ar.cpp",
|
||||||
|
"src/zig_clang_driver.cpp",
|
||||||
|
"src/zig_clang_cc1_main.cpp",
|
||||||
|
"src/zig_clang_cc1as_main.cpp",
|
||||||
|
// https://github.com/ziglang/zig/issues/6363
|
||||||
|
"src/windows_sdk.cpp",
|
||||||
|
};
|
||||||
|
|
||||||
|
const clang_libs = [_][]const u8{
|
||||||
|
"clangFrontendTool",
|
||||||
|
"clangCodeGen",
|
||||||
|
"clangFrontend",
|
||||||
|
"clangDriver",
|
||||||
|
"clangSerialization",
|
||||||
|
"clangSema",
|
||||||
|
"clangStaticAnalyzerFrontend",
|
||||||
|
"clangStaticAnalyzerCheckers",
|
||||||
|
"clangStaticAnalyzerCore",
|
||||||
|
"clangAnalysis",
|
||||||
|
"clangASTMatchers",
|
||||||
|
"clangAST",
|
||||||
|
"clangParse",
|
||||||
|
"clangSema",
|
||||||
|
"clangBasic",
|
||||||
|
"clangEdit",
|
||||||
|
"clangLex",
|
||||||
|
"clangARCMigrate",
|
||||||
|
"clangRewriteFrontend",
|
||||||
|
"clangRewrite",
|
||||||
|
"clangCrossTU",
|
||||||
|
"clangIndex",
|
||||||
|
"clangToolingCore",
|
||||||
|
};
|
||||||
|
const lld_libs = [_][]const u8{
|
||||||
|
"lldDriver",
|
||||||
|
"lldMinGW",
|
||||||
|
"lldELF",
|
||||||
|
"lldCOFF",
|
||||||
|
"lldMachO",
|
||||||
|
"lldWasm",
|
||||||
|
"lldReaderWriter",
|
||||||
|
"lldCore",
|
||||||
|
"lldYAML",
|
||||||
|
"lldCommon",
|
||||||
|
};
|
||||||
|
// This list can be re-generated with `llvm-config --libfiles` and then
|
||||||
|
// reformatting using your favorite text editor. Note we do not execute
|
||||||
|
// `llvm-config` here because we are cross compiling. Also omit LLVMTableGen
|
||||||
|
// from these libs.
|
||||||
|
const llvm_libs = [_][]const u8{
|
||||||
|
"LLVMWindowsManifest",
|
||||||
|
"LLVMXRay",
|
||||||
|
"LLVMLibDriver",
|
||||||
|
"LLVMDlltoolDriver",
|
||||||
|
"LLVMCoverage",
|
||||||
|
"LLVMLineEditor",
|
||||||
|
"LLVMXCoreDisassembler",
|
||||||
|
"LLVMXCoreCodeGen",
|
||||||
|
"LLVMXCoreDesc",
|
||||||
|
"LLVMXCoreInfo",
|
||||||
|
"LLVMX86Disassembler",
|
||||||
|
"LLVMX86AsmParser",
|
||||||
|
"LLVMX86CodeGen",
|
||||||
|
"LLVMX86Desc",
|
||||||
|
"LLVMX86Info",
|
||||||
|
"LLVMWebAssemblyDisassembler",
|
||||||
|
"LLVMWebAssemblyAsmParser",
|
||||||
|
"LLVMWebAssemblyCodeGen",
|
||||||
|
"LLVMWebAssemblyDesc",
|
||||||
|
"LLVMWebAssemblyUtils",
|
||||||
|
"LLVMWebAssemblyInfo",
|
||||||
|
"LLVMSystemZDisassembler",
|
||||||
|
"LLVMSystemZAsmParser",
|
||||||
|
"LLVMSystemZCodeGen",
|
||||||
|
"LLVMSystemZDesc",
|
||||||
|
"LLVMSystemZInfo",
|
||||||
|
"LLVMSparcDisassembler",
|
||||||
|
"LLVMSparcAsmParser",
|
||||||
|
"LLVMSparcCodeGen",
|
||||||
|
"LLVMSparcDesc",
|
||||||
|
"LLVMSparcInfo",
|
||||||
|
"LLVMRISCVDisassembler",
|
||||||
|
"LLVMRISCVAsmParser",
|
||||||
|
"LLVMRISCVCodeGen",
|
||||||
|
"LLVMRISCVDesc",
|
||||||
|
"LLVMRISCVInfo",
|
||||||
|
"LLVMPowerPCDisassembler",
|
||||||
|
"LLVMPowerPCAsmParser",
|
||||||
|
"LLVMPowerPCCodeGen",
|
||||||
|
"LLVMPowerPCDesc",
|
||||||
|
"LLVMPowerPCInfo",
|
||||||
|
"LLVMNVPTXCodeGen",
|
||||||
|
"LLVMNVPTXDesc",
|
||||||
|
"LLVMNVPTXInfo",
|
||||||
|
"LLVMMSP430Disassembler",
|
||||||
|
"LLVMMSP430AsmParser",
|
||||||
|
"LLVMMSP430CodeGen",
|
||||||
|
"LLVMMSP430Desc",
|
||||||
|
"LLVMMSP430Info",
|
||||||
|
"LLVMMipsDisassembler",
|
||||||
|
"LLVMMipsAsmParser",
|
||||||
|
"LLVMMipsCodeGen",
|
||||||
|
"LLVMMipsDesc",
|
||||||
|
"LLVMMipsInfo",
|
||||||
|
"LLVMLanaiDisassembler",
|
||||||
|
"LLVMLanaiCodeGen",
|
||||||
|
"LLVMLanaiAsmParser",
|
||||||
|
"LLVMLanaiDesc",
|
||||||
|
"LLVMLanaiInfo",
|
||||||
|
"LLVMHexagonDisassembler",
|
||||||
|
"LLVMHexagonCodeGen",
|
||||||
|
"LLVMHexagonAsmParser",
|
||||||
|
"LLVMHexagonDesc",
|
||||||
|
"LLVMHexagonInfo",
|
||||||
|
"LLVMBPFDisassembler",
|
||||||
|
"LLVMBPFAsmParser",
|
||||||
|
"LLVMBPFCodeGen",
|
||||||
|
"LLVMBPFDesc",
|
||||||
|
"LLVMBPFInfo",
|
||||||
|
"LLVMAVRDisassembler",
|
||||||
|
"LLVMAVRAsmParser",
|
||||||
|
"LLVMAVRCodeGen",
|
||||||
|
"LLVMAVRDesc",
|
||||||
|
"LLVMAVRInfo",
|
||||||
|
"LLVMARMDisassembler",
|
||||||
|
"LLVMARMAsmParser",
|
||||||
|
"LLVMARMCodeGen",
|
||||||
|
"LLVMARMDesc",
|
||||||
|
"LLVMARMUtils",
|
||||||
|
"LLVMARMInfo",
|
||||||
|
"LLVMAMDGPUDisassembler",
|
||||||
|
"LLVMAMDGPUAsmParser",
|
||||||
|
"LLVMAMDGPUCodeGen",
|
||||||
|
"LLVMAMDGPUDesc",
|
||||||
|
"LLVMAMDGPUUtils",
|
||||||
|
"LLVMAMDGPUInfo",
|
||||||
|
"LLVMAArch64Disassembler",
|
||||||
|
"LLVMAArch64AsmParser",
|
||||||
|
"LLVMAArch64CodeGen",
|
||||||
|
"LLVMAArch64Desc",
|
||||||
|
"LLVMAArch64Utils",
|
||||||
|
"LLVMAArch64Info",
|
||||||
|
"LLVMOrcJIT",
|
||||||
|
"LLVMMCJIT",
|
||||||
|
"LLVMJITLink",
|
||||||
|
"LLVMInterpreter",
|
||||||
|
"LLVMExecutionEngine",
|
||||||
|
"LLVMRuntimeDyld",
|
||||||
|
"LLVMOrcTargetProcess",
|
||||||
|
"LLVMOrcShared",
|
||||||
|
"LLVMDWP",
|
||||||
|
"LLVMSymbolize",
|
||||||
|
"LLVMDebugInfoPDB",
|
||||||
|
"LLVMDebugInfoGSYM",
|
||||||
|
"LLVMOption",
|
||||||
|
"LLVMObjectYAML",
|
||||||
|
"LLVMMCA",
|
||||||
|
"LLVMMCDisassembler",
|
||||||
|
"LLVMLTO",
|
||||||
|
"LLVMPasses",
|
||||||
|
"LLVMCFGuard",
|
||||||
|
"LLVMCoroutines",
|
||||||
|
"LLVMObjCARCOpts",
|
||||||
|
"LLVMipo",
|
||||||
|
"LLVMVectorize",
|
||||||
|
"LLVMLinker",
|
||||||
|
"LLVMInstrumentation",
|
||||||
|
"LLVMFrontendOpenMP",
|
||||||
|
"LLVMFrontendOpenACC",
|
||||||
|
"LLVMExtensions",
|
||||||
|
"LLVMDWARFLinker",
|
||||||
|
"LLVMGlobalISel",
|
||||||
|
"LLVMMIRParser",
|
||||||
|
"LLVMAsmPrinter",
|
||||||
|
"LLVMDebugInfoMSF",
|
||||||
|
"LLVMDebugInfoDWARF",
|
||||||
|
"LLVMSelectionDAG",
|
||||||
|
"LLVMCodeGen",
|
||||||
|
"LLVMIRReader",
|
||||||
|
"LLVMAsmParser",
|
||||||
|
"LLVMInterfaceStub",
|
||||||
|
"LLVMFileCheck",
|
||||||
|
"LLVMFuzzMutate",
|
||||||
|
"LLVMTarget",
|
||||||
|
"LLVMScalarOpts",
|
||||||
|
"LLVMInstCombine",
|
||||||
|
"LLVMAggressiveInstCombine",
|
||||||
|
"LLVMTransformUtils",
|
||||||
|
"LLVMBitWriter",
|
||||||
|
"LLVMAnalysis",
|
||||||
|
"LLVMProfileData",
|
||||||
|
"LLVMObject",
|
||||||
|
"LLVMTextAPI",
|
||||||
|
"LLVMMCParser",
|
||||||
|
"LLVMMC",
|
||||||
|
"LLVMDebugInfoCodeView",
|
||||||
|
"LLVMBitReader",
|
||||||
|
"LLVMCore",
|
||||||
|
"LLVMRemarks",
|
||||||
|
"LLVMBitstreamReader",
|
||||||
|
"LLVMBinaryFormat",
|
||||||
|
"LLVMSupport",
|
||||||
|
"LLVMDemangle",
|
||||||
|
};
|
||||||
@ -8,15 +8,15 @@ brew update && brew install ncurses s3cmd
|
|||||||
ZIGDIR="$(pwd)"
|
ZIGDIR="$(pwd)"
|
||||||
|
|
||||||
HOST_ARCH="x86_64"
|
HOST_ARCH="x86_64"
|
||||||
HOST_TARGET="$HOST_ARCH-macos-gnu"
|
HOST_TARGET="$HOST_ARCH-macos-none"
|
||||||
HOST_MCPU="baseline"
|
HOST_MCPU="baseline"
|
||||||
HOST_CACHE_BASENAME="zig+llvm+lld+clang-$HOST_TARGET-0.9.0-dev.1249+210ef5af8"
|
HOST_CACHE_BASENAME="zig+llvm+lld+clang-$HOST_TARGET-0.10.0-dev.2348+d43761808"
|
||||||
HOST_PREFIX="$HOME/$HOST_CACHE_BASENAME"
|
HOST_PREFIX="$HOME/$HOST_CACHE_BASENAME"
|
||||||
|
|
||||||
ARCH="aarch64"
|
ARCH="aarch64"
|
||||||
TARGET="$ARCH-macos-gnu"
|
TARGET="$ARCH-macos-none"
|
||||||
MCPU="apple_a14"
|
MCPU="apple_a14"
|
||||||
CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.9.0-dev.1249+210ef5af8"
|
CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.10.0-dev.2348+d43761808"
|
||||||
PREFIX="$HOME/$CACHE_BASENAME"
|
PREFIX="$HOME/$CACHE_BASENAME"
|
||||||
|
|
||||||
JOBS="-j2"
|
JOBS="-j2"
|
||||||
|
|||||||
@ -7,9 +7,9 @@ brew update && brew install ncurses s3cmd
|
|||||||
|
|
||||||
ZIGDIR="$(pwd)"
|
ZIGDIR="$(pwd)"
|
||||||
ARCH="x86_64"
|
ARCH="x86_64"
|
||||||
TARGET="$ARCH-macos-gnu"
|
TARGET="$ARCH-macos-none"
|
||||||
MCPU="baseline"
|
MCPU="baseline"
|
||||||
CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.9.0-dev.1249+210ef5af8"
|
CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.10.0-dev.2348+d43761808"
|
||||||
PREFIX="$HOME/$CACHE_BASENAME"
|
PREFIX="$HOME/$CACHE_BASENAME"
|
||||||
JOBS="-j2"
|
JOBS="-j2"
|
||||||
|
|
||||||
@ -55,12 +55,28 @@ make $JOBS install
|
|||||||
cmake .. -DZIG_EXECUTABLE="$(pwd)/release/bin/zig"
|
cmake .. -DZIG_EXECUTABLE="$(pwd)/release/bin/zig"
|
||||||
make $JOBS install
|
make $JOBS install
|
||||||
|
|
||||||
# TODO figure out why this causes a segmentation fault
|
# Build stage2 standalone so that we can test stage2 against stage2 compiler-rt.
|
||||||
# release/bin/zig test ../test/behavior.zig -fno-stage1 -fLLVM -I ../test
|
release/bin/zig build -p stage2 -Denable-llvm
|
||||||
|
|
||||||
release/bin/zig build test-toolchain -Denable-macos-sdk
|
stage2/bin/zig build test-behavior
|
||||||
release/bin/zig build test-std
|
|
||||||
release/bin/zig build docs
|
# TODO: upgrade these to test stage2 instead of stage1
|
||||||
|
# TODO: upgrade these to test stage3 instead of stage2
|
||||||
|
release/bin/zig build test-behavior -Denable-macos-sdk -Domit-stage2
|
||||||
|
release/bin/zig build test-compiler-rt -Denable-macos-sdk
|
||||||
|
release/bin/zig build test-std -Denable-macos-sdk
|
||||||
|
release/bin/zig build test-universal-libc -Denable-macos-sdk
|
||||||
|
release/bin/zig build test-compare-output -Denable-macos-sdk
|
||||||
|
release/bin/zig build test-standalone -Denable-macos-sdk
|
||||||
|
release/bin/zig build test-stack-traces -Denable-macos-sdk
|
||||||
|
release/bin/zig build test-cli -Denable-macos-sdk
|
||||||
|
release/bin/zig build test-asm-link -Denable-macos-sdk
|
||||||
|
release/bin/zig build test-translate-c -Denable-macos-sdk
|
||||||
|
release/bin/zig build test-run-translated-c -Denable-macos-sdk
|
||||||
|
release/bin/zig build docs -Denable-macos-sdk
|
||||||
|
release/bin/zig build test-fmt -Denable-macos-sdk
|
||||||
|
release/bin/zig build test-cases -Denable-macos-sdk -Dsingle-threaded
|
||||||
|
release/bin/zig build test-link -Denable-macos-sdk
|
||||||
|
|
||||||
if [ "${BUILD_REASON}" != "PullRequest" ]; then
|
if [ "${BUILD_REASON}" != "PullRequest" ]; then
|
||||||
mv ../LICENSE release/
|
mv ../LICENSE release/
|
||||||
|
|||||||
@ -22,29 +22,149 @@ jobs:
|
|||||||
name: main
|
name: main
|
||||||
displayName: 'Build'
|
displayName: 'Build'
|
||||||
- job: BuildWindows
|
- job: BuildWindows
|
||||||
|
timeoutInMinutes: 360
|
||||||
pool:
|
pool:
|
||||||
vmImage: 'windows-2019'
|
vmImage: 'windows-2019'
|
||||||
timeoutInMinutes: 360
|
variables:
|
||||||
|
TARGET: 'x86_64-windows-gnu'
|
||||||
|
ZIG_LLVM_CLANG_LLD_NAME: 'zig+llvm+lld+clang-${{ variables.TARGET }}-0.9.1'
|
||||||
|
ZIG_LLVM_CLANG_LLD_URL: 'https://ziglang.org/deps/${{ variables.ZIG_LLVM_CLANG_LLD_NAME }}.zip'
|
||||||
steps:
|
steps:
|
||||||
- powershell: |
|
- pwsh: |
|
||||||
(New-Object Net.WebClient).DownloadFile("https://github.com/msys2/msys2-installer/releases/download/2022-01-28/msys2-base-x86_64-20220128.sfx.exe", "sfx.exe")
|
(New-Object Net.WebClient).DownloadFile("$(ZIG_LLVM_CLANG_LLD_URL)", "${ZIG_LLVM_CLANG_LLD_NAME}.zip")
|
||||||
.\sfx.exe -y -o\
|
& 'C:\Program Files\7-Zip\7z.exe' x "${ZIG_LLVM_CLANG_LLD_NAME}.zip"
|
||||||
displayName: Download/Extract/Install MSYS2
|
name: install
|
||||||
- script: |
|
displayName: 'Install ZIG/LLVM/CLANG/LLD'
|
||||||
@REM install updated filesystem package first without dependency checking
|
|
||||||
@REM because of: https://github.com/msys2/MSYS2-packages/issues/2021
|
- pwsh: |
|
||||||
%CD:~0,2%\msys64\usr\bin\bash -lc "pacman --noconfirm -Sydd filesystem"
|
Set-Variable -Name ZIGBUILDDIR -Value "$(Get-Location)\build"
|
||||||
displayName: Workaround filesystem dash MSYS2 dependency issue
|
Set-Variable -Name ZIGINSTALLDIR -Value "${ZIGBUILDDIR}\dist"
|
||||||
- script: |
|
Set-Variable -Name ZIGPREFIXPATH -Value "$(Get-Location)\$(ZIG_LLVM_CLANG_LLD_NAME)"
|
||||||
%CD:~0,2%\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu"
|
|
||||||
%CD:~0,2%\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu"
|
# Make the `zig version` number consistent.
|
||||||
displayName: Update MSYS2
|
# This will affect the `zig build` command below which uses `git describe`.
|
||||||
|
git config core.abbrev 9
|
||||||
|
git fetch --tags
|
||||||
|
if ((git rev-parse --is-shallow-repository) -eq "true") {
|
||||||
|
git fetch --unshallow # `git describe` won't work on a shallow repo
|
||||||
|
}
|
||||||
|
|
||||||
|
# The dev kit zip file that we have here is old, and may be incompatible with
|
||||||
|
# the build.zig script of master branch. So we keep an old version of build.zig
|
||||||
|
# here in the CI directory.
|
||||||
|
mv build.zig build.zig.master
|
||||||
|
mv ci/azure/build.zig build.zig
|
||||||
|
|
||||||
|
mkdir $ZIGBUILDDIR
|
||||||
|
cd $ZIGBUILDDIR
|
||||||
|
|
||||||
|
& "${ZIGPREFIXPATH}/bin/zig.exe" build `
|
||||||
|
--prefix "$ZIGINSTALLDIR" `
|
||||||
|
--search-prefix "$ZIGPREFIXPATH" `
|
||||||
|
-Dstage1 `
|
||||||
|
<# stage2 is omitted until we resolve https://github.com/ziglang/zig/issues/6485 #> `
|
||||||
|
-Domit-stage2 `
|
||||||
|
-Dstatic-llvm `
|
||||||
|
-Drelease `
|
||||||
|
-Dstrip `
|
||||||
|
-Duse-zig-libcxx `
|
||||||
|
-Dtarget=$(TARGET)
|
||||||
|
|
||||||
|
cd -
|
||||||
|
|
||||||
|
# Now that we have built an up-to-date zig.exe, we restore the original
|
||||||
|
# build script from master branch.
|
||||||
|
rm build.zig
|
||||||
|
mv build.zig.master build.zig
|
||||||
|
|
||||||
|
name: build
|
||||||
|
displayName: 'Build'
|
||||||
|
|
||||||
|
- pwsh: |
|
||||||
|
Set-Variable -Name ZIGINSTALLDIR -Value "$(Get-Location)\build\dist"
|
||||||
|
|
||||||
|
# Sadly, stage2 is omitted from this build to save memory on the CI server. Once self-hosted is
|
||||||
|
# built with itself and does not gobble as much memory, we can enable these tests.
|
||||||
|
#& "$ZIGINSTALLDIR\bin\zig.exe" test "..\test\behavior.zig" -fno-stage1 -fLLVM -I "..\test" 2>&1
|
||||||
|
|
||||||
|
& "$ZIGINSTALLDIR\bin\zig.exe" build test-toolchain -Dskip-non-native -Dskip-stage2-tests 2>&1
|
||||||
|
& "$ZIGINSTALLDIR\bin\zig.exe" build test-std -Dskip-non-native 2>&1
|
||||||
|
name: test
|
||||||
|
displayName: 'Test'
|
||||||
|
|
||||||
|
- pwsh: |
|
||||||
|
Set-Variable -Name ZIGINSTALLDIR -Value "$(Get-Location)\build\dist"
|
||||||
|
|
||||||
|
& "$ZIGINSTALLDIR\bin\zig.exe" build docs
|
||||||
|
timeoutInMinutes: 60
|
||||||
|
name: doc
|
||||||
|
displayName: 'Documentation'
|
||||||
|
|
||||||
- task: DownloadSecureFile@1
|
- task: DownloadSecureFile@1
|
||||||
inputs:
|
inputs:
|
||||||
secureFile: s3cfg
|
name: aws_credentials
|
||||||
- script: ci/azure/windows_msvc_script.bat
|
secureFile: aws_credentials
|
||||||
name: main
|
|
||||||
displayName: 'Build and test'
|
- pwsh: |
|
||||||
|
Set-Variable -Name ZIGBUILDDIR -Value "$(Get-Location)\build"
|
||||||
|
$Env:AWS_SHARED_CREDENTIALS_FILE = "$Env:DOWNLOADSECUREFILE_SECUREFILEPATH"
|
||||||
|
|
||||||
|
# Workaround Azure networking issue
|
||||||
|
# https://github.com/aws/aws-cli/issues/5749
|
||||||
|
$Env:AWS_EC2_METADATA_DISABLED = "true"
|
||||||
|
$Env:AWS_REGION = "us-west-2"
|
||||||
|
|
||||||
|
cd "$ZIGBUILDDIR"
|
||||||
|
mv ../LICENSE dist/
|
||||||
|
mv ../zig-cache/langref.html dist/
|
||||||
|
mv dist/bin/zig.exe dist/
|
||||||
|
rmdir dist/bin
|
||||||
|
|
||||||
|
# Remove the unnecessary zig dir in $prefix/lib/zig/std/std.zig
|
||||||
|
mv dist/lib/zig dist/lib2
|
||||||
|
rmdir dist/lib
|
||||||
|
mv dist/lib2 dist/lib
|
||||||
|
|
||||||
|
Set-Variable -Name VERSION -Value $(./dist/zig.exe version)
|
||||||
|
Set-Variable -Name DIRNAME -Value "zig-windows-x86_64-$VERSION"
|
||||||
|
Set-Variable -Name TARBALL -Value "$DIRNAME.zip"
|
||||||
|
mv dist "$DIRNAME"
|
||||||
|
7z a "$TARBALL" "$DIRNAME"
|
||||||
|
|
||||||
|
aws s3 cp `
|
||||||
|
"$TARBALL" `
|
||||||
|
s3://ziglang.org/builds/ `
|
||||||
|
--acl public-read `
|
||||||
|
--cache-control 'public, max-age=31536000, immutable'
|
||||||
|
|
||||||
|
Set-Variable -Name SHASUM -Value (Get-FileHash "$TARBALL" -Algorithm SHA256 | select-object -ExpandProperty Hash).ToLower()
|
||||||
|
Set-Variable -Name BYTESIZE -Value (Get-Item "$TARBALL").length
|
||||||
|
|
||||||
|
Set-Variable -Name JSONFILE -Value "windows-${Env:BUILD_SOURCEBRANCHNAME}.json"
|
||||||
|
echo $null > $JSONFILE
|
||||||
|
echo ('{"tarball": "' + $TARBALL + '",') >> $JSONFILE
|
||||||
|
echo ('"shasum": "' + $SHASUM + '",') >> $JSONFILE
|
||||||
|
echo ('"size": ' + $BYTESIZE + '}' ) >> $JSONFILE
|
||||||
|
|
||||||
|
aws s3 cp `
|
||||||
|
"$JSONFILE" `
|
||||||
|
s3://ziglang.org/builds/ `
|
||||||
|
--acl public-read `
|
||||||
|
--cache-control 'max-age=0, must-revalidate'
|
||||||
|
|
||||||
|
aws s3 cp `
|
||||||
|
"$JSONFILE" `
|
||||||
|
"s3://ziglang.org/builds/x86_64-windows-${VERSION}.json" `
|
||||||
|
--acl public-read
|
||||||
|
|
||||||
|
echo "##vso[task.setvariable variable=tarball;isOutput=true]$TARBALL"
|
||||||
|
echo "##vso[task.setvariable variable=shasum;isOutput=true]$SHASUM"
|
||||||
|
echo "##vso[task.setvariable variable=bytesize;isOutput=true]$BYTESIZE"
|
||||||
|
|
||||||
|
name: upload
|
||||||
|
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
|
||||||
|
displayName: 'Upload'
|
||||||
|
|
||||||
- job: OnMasterSuccess
|
- job: OnMasterSuccess
|
||||||
dependsOn:
|
dependsOn:
|
||||||
- BuildMacOS
|
- BuildMacOS
|
||||||
@ -54,7 +174,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
maxParallel: 1
|
maxParallel: 1
|
||||||
pool:
|
pool:
|
||||||
vmImage: 'ubuntu-18.04'
|
vmImage: 'ubuntu-20.04'
|
||||||
variables:
|
variables:
|
||||||
version: $[ dependencies.BuildMacOS.outputs['main.version'] ]
|
version: $[ dependencies.BuildMacOS.outputs['main.version'] ]
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
@ -1,16 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -x
|
|
||||||
set -e
|
|
||||||
|
|
||||||
pacman -Suy --needed --noconfirm
|
|
||||||
pacman -S --needed --noconfirm wget p7zip python3-pip tar xz
|
|
||||||
|
|
||||||
TARBALL="llvm+clang+lld-13.0.0-x86_64-windows-msvc-release-mt.tar.xz"
|
|
||||||
|
|
||||||
pip install s3cmd
|
|
||||||
wget -nv "https://ziglang.org/deps/$TARBALL"
|
|
||||||
# If the first extraction fails, re-try it once; this can happen if the tarball
|
|
||||||
# contains symlinks that are in the table of contents before the files that
|
|
||||||
# they point to.
|
|
||||||
tar -xf $TARBALL || tar --overwrite -xf $TARBALL
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
@echo on
|
|
||||||
SET "SRCROOT=%cd%"
|
|
||||||
SET "PREVPATH=%PATH%"
|
|
||||||
SET "PREVMSYSTEM=%MSYSTEM%"
|
|
||||||
|
|
||||||
set "PATH=%CD:~0,2%\msys64\usr\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem"
|
|
||||||
SET "MSYSTEM=MINGW64"
|
|
||||||
bash -lc "cd ${SRCROOT} && ci/azure/windows_msvc_install" || exit /b
|
|
||||||
SET "PATH=%PREVPATH%"
|
|
||||||
SET "MSYSTEM=%PREVMSYSTEM%"
|
|
||||||
|
|
||||||
SET "ZIGBUILDDIR=%SRCROOT%\build"
|
|
||||||
SET "ZIGINSTALLDIR=%ZIGBUILDDIR%\dist"
|
|
||||||
SET "ZIGPREFIXPATH=%SRCROOT%\llvm+clang+lld-13.0.0-x86_64-windows-msvc-release-mt"
|
|
||||||
|
|
||||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
|
|
||||||
|
|
||||||
REM Make the `zig version` number consistent.
|
|
||||||
REM This will affect the cmake command below.
|
|
||||||
git.exe config core.abbrev 9
|
|
||||||
git.exe fetch --unshallow
|
|
||||||
git.exe fetch --tags
|
|
||||||
|
|
||||||
mkdir %ZIGBUILDDIR%
|
|
||||||
cd %ZIGBUILDDIR%
|
|
||||||
cmake.exe .. -Thost=x64 -G"Visual Studio 16 2019" -A x64 "-DCMAKE_INSTALL_PREFIX=%ZIGINSTALLDIR%" "-DCMAKE_PREFIX_PATH=%ZIGPREFIXPATH%" -DCMAKE_BUILD_TYPE=Release -DZIG_OMIT_STAGE2=ON || exit /b
|
|
||||||
msbuild /maxcpucount /p:Configuration=Release INSTALL.vcxproj || exit /b
|
|
||||||
|
|
||||||
REM Sadly, stage2 is omitted from this build to save memory on the CI server. Once self-hosted is
|
|
||||||
REM built with itself and does not gobble as much memory, we can enable these tests.
|
|
||||||
REM "%ZIGINSTALLDIR%\bin\zig.exe" test "..\test\behavior.zig" -fno-stage1 -fLLVM -I "..\test" || exit /b
|
|
||||||
|
|
||||||
"%ZIGINSTALLDIR%\bin\zig.exe" build test-toolchain -Dskip-non-native -Dskip-stage2-tests || exit /b
|
|
||||||
"%ZIGINSTALLDIR%\bin\zig.exe" build test-std -Dskip-non-native || exit /b
|
|
||||||
"%ZIGINSTALLDIR%\bin\zig.exe" build docs || exit /b
|
|
||||||
|
|
||||||
set "PATH=%CD:~0,2%\msys64\usr\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem"
|
|
||||||
SET "MSYSTEM=MINGW64"
|
|
||||||
bash -lc "cd ${SRCROOT} && ci/azure/windows_upload" || exit /b
|
|
||||||
@ -1,46 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -x
|
|
||||||
set -e
|
|
||||||
|
|
||||||
if [ "${BUILD_REASON}" != "PullRequest" ]; then
|
|
||||||
cd "$ZIGBUILDDIR"
|
|
||||||
|
|
||||||
mv ../LICENSE dist/
|
|
||||||
mv ../zig-cache/langref.html dist/
|
|
||||||
mv dist/bin/zig.exe dist/
|
|
||||||
rmdir dist/bin
|
|
||||||
|
|
||||||
# Remove the unnecessary zig dir in $prefix/lib/zig/std/std.zig
|
|
||||||
mv dist/lib/zig dist/lib2
|
|
||||||
rmdir dist/lib
|
|
||||||
mv dist/lib2 dist/lib
|
|
||||||
|
|
||||||
VERSION=$(dist/zig.exe version)
|
|
||||||
DIRNAME="zig-windows-x86_64-$VERSION"
|
|
||||||
TARBALL="$DIRNAME.zip"
|
|
||||||
mv dist "$DIRNAME"
|
|
||||||
7z a "$TARBALL" "$DIRNAME"
|
|
||||||
|
|
||||||
# mv "$DOWNLOADSECUREFILE_SECUREFILEPATH" "$HOME/.s3cfg"
|
|
||||||
s3cmd -c "$DOWNLOADSECUREFILE_SECUREFILEPATH" put -P --add-header="cache-control: public, max-age=31536000, immutable" "$TARBALL" s3://ziglang.org/builds/
|
|
||||||
|
|
||||||
SHASUM=$(sha256sum $TARBALL | cut '-d ' -f1)
|
|
||||||
BYTESIZE=$(wc -c < $TARBALL)
|
|
||||||
|
|
||||||
JSONFILE="windows-$GITBRANCH.json"
|
|
||||||
touch $JSONFILE
|
|
||||||
echo "{\"tarball\": \"$TARBALL\"," >>$JSONFILE
|
|
||||||
echo "\"shasum\": \"$SHASUM\"," >>$JSONFILE
|
|
||||||
echo "\"size\": \"$BYTESIZE\"}" >>$JSONFILE
|
|
||||||
|
|
||||||
s3cmd -c "$DOWNLOADSECUREFILE_SECUREFILEPATH" put -P --add-header="Cache-Control: max-age=0, must-revalidate" "$JSONFILE" "s3://ziglang.org/builds/$JSONFILE"
|
|
||||||
s3cmd -c "$DOWNLOADSECUREFILE_SECUREFILEPATH" put -P "$JSONFILE" "s3://ziglang.org/builds/x86_64-windows-$VERSION.json"
|
|
||||||
|
|
||||||
# `set -x` causes these variables to be mangled.
|
|
||||||
# See https://developercommunity.visualstudio.com/content/problem/375679/pipeline-variable-incorrectly-inserts-single-quote.html
|
|
||||||
set +x
|
|
||||||
echo "##vso[task.setvariable variable=tarball;isOutput=true]$TARBALL"
|
|
||||||
echo "##vso[task.setvariable variable=shasum;isOutput=true]$SHASUM"
|
|
||||||
echo "##vso[task.setvariable variable=bytesize;isOutput=true]$BYTESIZE"
|
|
||||||
fi
|
|
||||||
@ -17,29 +17,28 @@ case "$1" in
|
|||||||
;;
|
;;
|
||||||
3)
|
3)
|
||||||
# ReleaseSafe
|
# ReleaseSafe
|
||||||
./build/zig build $BUILD_FLAGS test-std -Dskip-debug -Dskip-release-fast -Dskip-release-small
|
./build/zig build $BUILD_FLAGS test-std -Dskip-debug -Dskip-release-fast -Dskip-release-small -Dskip-non-native -Dskip-single-threaded
|
||||||
;;
|
;;
|
||||||
4)
|
4)
|
||||||
# Releasefast
|
# ReleaseFast
|
||||||
./build/zig build $BUILD_FLAGS test-std -Dskip-debug -Dskip-release-safe -Dskip-release-small
|
./build/zig build $BUILD_FLAGS test-std -Dskip-debug -Dskip-release-safe -Dskip-release-small -Dskip-non-native -Dskip-single-threaded
|
||||||
;;
|
;;
|
||||||
5)
|
5)
|
||||||
# ReleaseSmall
|
# ReleaseSmall
|
||||||
./build/zig build $BUILD_FLAGS test-std -Dskip-debug -Dskip-release-safe -Dskip-release-fast
|
./build/zig build $BUILD_FLAGS test-std -Dskip-debug -Dskip-release-safe -Dskip-release-fast
|
||||||
;;
|
;;
|
||||||
6)
|
6)
|
||||||
./build/zig build $BUILD_FLAGS test-minilibc
|
./build/zig build $BUILD_FLAGS test-universal-libc
|
||||||
./build/zig build $BUILD_FLAGS test-compare-output
|
./build/zig build $BUILD_FLAGS test-compare-output
|
||||||
./build/zig build $BUILD_FLAGS test-standalone -Dskip-release-safe
|
./build/zig build $BUILD_FLAGS test-standalone -Dskip-release-safe
|
||||||
./build/zig build $BUILD_FLAGS test-stack-traces
|
./build/zig build $BUILD_FLAGS test-stack-traces
|
||||||
./build/zig build $BUILD_FLAGS test-cli
|
./build/zig build $BUILD_FLAGS test-cli
|
||||||
./build/zig build $BUILD_FLAGS test-asm-link
|
./build/zig build $BUILD_FLAGS test-asm-link
|
||||||
./build/zig build $BUILD_FLAGS test-runtime-safety
|
|
||||||
./build/zig build $BUILD_FLAGS test-translate-c
|
./build/zig build $BUILD_FLAGS test-translate-c
|
||||||
;;
|
;;
|
||||||
7)
|
7)
|
||||||
./build/zig build $BUILD_FLAGS # test building self-hosted without LLVM
|
./build/zig build $BUILD_FLAGS # test building self-hosted without LLVM
|
||||||
./build/zig build $BUILD_FLAGS test-stage2
|
./build/zig build $BUILD_FLAGS test-cases
|
||||||
;;
|
;;
|
||||||
'')
|
'')
|
||||||
echo "error: expecting test group argument"
|
echo "error: expecting test group argument"
|
||||||
|
|||||||
@ -4,10 +4,10 @@ set -x
|
|||||||
set -e
|
set -e
|
||||||
|
|
||||||
sudo pkg update -fq
|
sudo pkg update -fq
|
||||||
sudo pkg install -y cmake py38-s3cmd wget curl jq samurai
|
sudo pkg install -y cmake py39-s3cmd wget curl jq samurai
|
||||||
|
|
||||||
ZIGDIR="$(pwd)"
|
ZIGDIR="$(pwd)"
|
||||||
CACHE_BASENAME="zig+llvm+lld+clang-x86_64-freebsd-gnu-0.9.0-dev.1243+456d7e5f5"
|
CACHE_BASENAME="zig+llvm+lld+clang-x86_64-freebsd-gnu-0.9.1"
|
||||||
PREFIX="$HOME/$CACHE_BASENAME"
|
PREFIX="$HOME/$CACHE_BASENAME"
|
||||||
|
|
||||||
cd $HOME
|
cd $HOME
|
||||||
@ -44,7 +44,7 @@ samu install
|
|||||||
#release/bin/zig test ../test/behavior.zig -fno-stage1 -fLLVM -I ../test
|
#release/bin/zig test ../test/behavior.zig -fno-stage1 -fLLVM -I ../test
|
||||||
|
|
||||||
# Here we skip some tests to save time.
|
# Here we skip some tests to save time.
|
||||||
release/bin/zig build test -Dskip-compile-errors -Dskip-non-native
|
release/bin/zig build test -Dskip-stage1 -Dskip-non-native
|
||||||
|
|
||||||
if [ -f ~/.s3cfg ]; then
|
if [ -f ~/.s3cfg ]; then
|
||||||
mv ../LICENSE release/
|
mv ../LICENSE release/
|
||||||
|
|||||||
@ -40,6 +40,77 @@
|
|||||||
"size": "{{AARCH64_LINUX_BYTESIZE}}"
|
"size": "{{AARCH64_LINUX_BYTESIZE}}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"0.9.1": {
|
||||||
|
"date": "2022-02-14",
|
||||||
|
"docs": "https://ziglang.org/documentation/0.9.1/",
|
||||||
|
"stdDocs": "https://ziglang.org/documentation/0.9.1/std/",
|
||||||
|
"notes": "https://ziglang.org/download/0.9.1/release-notes.html",
|
||||||
|
"src": {
|
||||||
|
"tarball": "https://ziglang.org/download/0.9.1/zig-0.9.1.tar.xz",
|
||||||
|
"shasum": "38cf4e84481f5facc766ba72783e7462e08d6d29a5d47e3b75c8ee3142485210",
|
||||||
|
"size": "13940828"
|
||||||
|
},
|
||||||
|
"bootstrap": {
|
||||||
|
"tarball": "https://ziglang.org/download/0.9.1/zig-bootstrap-0.9.1.tar.xz",
|
||||||
|
"shasum": "0a8e221c71860d8975c15662b3ed3bd863e81c4fe383455a596e5e0e490d6109",
|
||||||
|
"size": "42488812"
|
||||||
|
},
|
||||||
|
"x86_64-freebsd": {
|
||||||
|
"tarball": "https://ziglang.org/download/0.9.1/zig-freebsd-x86_64-0.9.1.tar.xz",
|
||||||
|
"shasum": "4e06009bd3ede34b72757eec1b5b291b30aa0d5046dadd16ecb6b34a02411254",
|
||||||
|
"size": "39028848"
|
||||||
|
},
|
||||||
|
"aarch64-linux": {
|
||||||
|
"tarball": "https://ziglang.org/download/0.9.1/zig-linux-aarch64-0.9.1.tar.xz",
|
||||||
|
"shasum": "5d99a39cded1870a3fa95d4de4ce68ac2610cca440336cfd252ffdddc2b90e66",
|
||||||
|
"size": "37034860"
|
||||||
|
},
|
||||||
|
"armv7a-linux": {
|
||||||
|
"tarball": "https://ziglang.org/download/0.9.1/zig-linux-armv7a-0.9.1.tar.xz",
|
||||||
|
"shasum": "6de64456cb4757a555816611ea697f86fba7681d8da3e1863fa726a417de49be",
|
||||||
|
"size": "37974652"
|
||||||
|
},
|
||||||
|
"i386-linux": {
|
||||||
|
"tarball": "https://ziglang.org/download/0.9.1/zig-linux-i386-0.9.1.tar.xz",
|
||||||
|
"shasum": "e776844fecd2e62fc40d94718891057a1dbca1816ff6013369e9a38c874374ca",
|
||||||
|
"size": "44969172"
|
||||||
|
},
|
||||||
|
"riscv64-linux": {
|
||||||
|
"tarball": "https://ziglang.org/download/0.9.1/zig-linux-riscv64-0.9.1.tar.xz",
|
||||||
|
"shasum": "208dea53662c2c52777bd9e3076115d2126a4f71aed7f2ff3b8fe224dc3881aa",
|
||||||
|
"size": "39390868"
|
||||||
|
},
|
||||||
|
"x86_64-linux": {
|
||||||
|
"tarball": "https://ziglang.org/download/0.9.1/zig-linux-x86_64-0.9.1.tar.xz",
|
||||||
|
"shasum": "be8da632c1d3273f766b69244d80669fe4f5e27798654681d77c992f17c237d7",
|
||||||
|
"size": "41011464"
|
||||||
|
},
|
||||||
|
"aarch64-macos": {
|
||||||
|
"tarball": "https://ziglang.org/download/0.9.1/zig-macos-aarch64-0.9.1.tar.xz",
|
||||||
|
"shasum": "8c473082b4f0f819f1da05de2dbd0c1e891dff7d85d2c12b6ee876887d438287",
|
||||||
|
"size": "38995640"
|
||||||
|
},
|
||||||
|
"x86_64-macos": {
|
||||||
|
"tarball": "https://ziglang.org/download/0.9.1/zig-macos-x86_64-0.9.1.tar.xz",
|
||||||
|
"shasum": "2d94984972d67292b55c1eb1c00de46580e9916575d083003546e9a01166754c",
|
||||||
|
"size": "43713044"
|
||||||
|
},
|
||||||
|
"i386-windows": {
|
||||||
|
"tarball": "https://ziglang.org/download/0.9.1/zig-windows-i386-0.9.1.zip",
|
||||||
|
"shasum": "74a640ed459914b96bcc572183a8db687bed0af08c30d2ea2f8eba03ae930f69",
|
||||||
|
"size": "67929868"
|
||||||
|
},
|
||||||
|
"x86_64-windows": {
|
||||||
|
"tarball": "https://ziglang.org/download/0.9.1/zig-windows-x86_64-0.9.1.zip",
|
||||||
|
"shasum": "443da53387d6ae8ba6bac4b3b90e9fef4ecbe545e1c5fa3a89485c36f5c0e3a2",
|
||||||
|
"size": "65047697"
|
||||||
|
},
|
||||||
|
"aarch64-windows": {
|
||||||
|
"tarball": "https://ziglang.org/download/0.9.1/zig-windows-aarch64-0.9.1.zip",
|
||||||
|
"shasum": "621bf95f54dc3ff71466c5faae67479419951d7489e40e87fd26d195825fb842",
|
||||||
|
"size": "61478151"
|
||||||
|
}
|
||||||
|
},
|
||||||
"0.9.0": {
|
"0.9.0": {
|
||||||
"date": "2021-12-20",
|
"date": "2021-12-20",
|
||||||
"docs": "https://ziglang.org/documentation/0.9.0/",
|
"docs": "https://ziglang.org/documentation/0.9.0/",
|
||||||
|
|||||||
@ -57,7 +57,7 @@ unset CXX
|
|||||||
#release/bin/zig test ../test/behavior.zig -fno-stage1 -fLLVM -I ../test
|
#release/bin/zig test ../test/behavior.zig -fno-stage1 -fLLVM -I ../test
|
||||||
|
|
||||||
# Here we skip some tests to save time.
|
# Here we skip some tests to save time.
|
||||||
release/bin/zig build test -Dskip-compile-errors -Dskip-non-native
|
release/bin/zig build test -Dskip-stage1 -Dskip-non-native
|
||||||
|
|
||||||
if [ -f ~/.s3cfg ]; then
|
if [ -f ~/.s3cfg ]; then
|
||||||
mv ../LICENSE release/
|
mv ../LICENSE release/
|
||||||
|
|||||||
@ -9,20 +9,8 @@ workspace:
|
|||||||
path: /workspace
|
path: /workspace
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: probe
|
|
||||||
image: ci/debian-amd64:11.1-2
|
|
||||||
commands:
|
|
||||||
- ./ci/zinc/linux_probe.sh
|
|
||||||
|
|
||||||
- name: build
|
|
||||||
image: ci/debian-amd64:11.1-2
|
|
||||||
commands:
|
|
||||||
- ./ci/zinc/linux_build.sh
|
|
||||||
|
|
||||||
- name: test
|
- name: test
|
||||||
depends_on:
|
image: ci/debian-amd64:11.1-3
|
||||||
- build
|
|
||||||
image: ci/debian-amd64:11.1-2
|
|
||||||
commands:
|
commands:
|
||||||
- ./ci/zinc/linux_test.sh
|
- ./ci/zinc/linux_test.sh
|
||||||
|
|
||||||
@ -34,7 +22,7 @@ steps:
|
|||||||
- master
|
- master
|
||||||
event:
|
event:
|
||||||
- push
|
- push
|
||||||
image: ci/debian-amd64:11.1-2
|
image: ci/debian-amd64:11.1-3
|
||||||
environment:
|
environment:
|
||||||
AWS_ACCESS_KEY_ID:
|
AWS_ACCESS_KEY_ID:
|
||||||
from_secret: AWS_ACCESS_KEY_ID
|
from_secret: AWS_ACCESS_KEY_ID
|
||||||
|
|||||||
@ -17,7 +17,6 @@ set -x
|
|||||||
set -e
|
set -e
|
||||||
|
|
||||||
ARCH="$(uname -m)"
|
ARCH="$(uname -m)"
|
||||||
JOBS="-j$(nproc)"
|
|
||||||
|
|
||||||
DEPS_LOCAL="/deps/local"
|
DEPS_LOCAL="/deps/local"
|
||||||
WORKSPACE="$DRONE_WORKSPACE"
|
WORKSPACE="$DRONE_WORKSPACE"
|
||||||
|
|||||||
@ -1,72 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
. ./ci/zinc/linux_base.sh
|
|
||||||
|
|
||||||
ZIG="$DEPS_LOCAL/bin/zig"
|
|
||||||
TARGET="${ARCH}-linux-musl"
|
|
||||||
MCPU="baseline"
|
|
||||||
|
|
||||||
# Make the `zig version` number consistent.
|
|
||||||
# This will affect the cmake command below.
|
|
||||||
git config core.abbrev 9
|
|
||||||
|
|
||||||
# Build debug zig.
|
|
||||||
echo "BUILD debug zig with zig:$($ZIG version)"
|
|
||||||
|
|
||||||
export CC="$ZIG cc -target $TARGET -mcpu=$MCPU"
|
|
||||||
export CXX="$ZIG c++ -target $TARGET -mcpu=$MCPU"
|
|
||||||
|
|
||||||
mkdir _debug
|
|
||||||
cd _debug
|
|
||||||
cmake .. \
|
|
||||||
-DCMAKE_INSTALL_PREFIX="$DEBUG_STAGING" \
|
|
||||||
-DCMAKE_PREFIX_PATH="$DEPS_LOCAL" \
|
|
||||||
-DCMAKE_BUILD_TYPE=Debug \
|
|
||||||
-DZIG_TARGET_TRIPLE="$TARGET" \
|
|
||||||
-DZIG_TARGET_MCPU="$MCPU" \
|
|
||||||
-DZIG_STATIC=ON \
|
|
||||||
-GNinja
|
|
||||||
|
|
||||||
# Now cmake will use zig as the C/C++ compiler. We reset the environment variables
|
|
||||||
# so that installation and testing do not get affected by them.
|
|
||||||
unset CC
|
|
||||||
unset CXX
|
|
||||||
|
|
||||||
ninja $JOBS install
|
|
||||||
|
|
||||||
ZIG=$DEBUG_STAGING/bin/zig
|
|
||||||
|
|
||||||
# Here we rebuild zig but this time using the Zig binary we just now produced to
|
|
||||||
# build zig1.o rather than relying on the one built with stage0. See
|
|
||||||
# https://github.com/ziglang/zig/issues/6830 for more details.
|
|
||||||
cmake .. -DZIG_EXECUTABLE="$ZIG"
|
|
||||||
ninja $JOBS install
|
|
||||||
|
|
||||||
cd $WORKSPACE
|
|
||||||
|
|
||||||
# Build release zig.
|
|
||||||
echo "BUILD release zig with zig:$($ZIG version)"
|
|
||||||
export CC="$ZIG cc -target $TARGET -mcpu=$MCPU"
|
|
||||||
export CXX="$ZIG c++ -target $TARGET -mcpu=$MCPU"
|
|
||||||
mkdir _release
|
|
||||||
cd _release
|
|
||||||
cmake .. \
|
|
||||||
-DCMAKE_INSTALL_PREFIX="$RELEASE_STAGING" \
|
|
||||||
-DCMAKE_PREFIX_PATH="$DEPS_LOCAL" \
|
|
||||||
-DCMAKE_BUILD_TYPE=Release \
|
|
||||||
-DZIG_TARGET_TRIPLE="$TARGET" \
|
|
||||||
-DZIG_TARGET_MCPU="$MCPU" \
|
|
||||||
-DZIG_STATIC=ON \
|
|
||||||
-GNinja
|
|
||||||
unset CC
|
|
||||||
unset CXX
|
|
||||||
ninja $JOBS install
|
|
||||||
|
|
||||||
cd $WORKSPACE
|
|
||||||
|
|
||||||
# Look for non-conforming code formatting.
|
|
||||||
# Formatting errors can be fixed by running `zig fmt` on the files printed here.
|
|
||||||
$ZIG fmt --check .
|
|
||||||
|
|
||||||
# Explicit exit helps show last command duration.
|
|
||||||
exit
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
. ./ci/zinc/linux_base.sh
|
|
||||||
|
|
||||||
# Probe CPU/brand details.
|
|
||||||
echo "lscpu:"
|
|
||||||
(lscpu | sed 's,^, : ,') 1>&2
|
|
||||||
|
|
||||||
# Explicit exit helps show last command duration.
|
|
||||||
exit
|
|
||||||
@ -2,34 +2,82 @@
|
|||||||
|
|
||||||
. ./ci/zinc/linux_base.sh
|
. ./ci/zinc/linux_base.sh
|
||||||
|
|
||||||
ZIG=$DEBUG_STAGING/bin/zig
|
ZIG="$DEPS_LOCAL/bin/zig"
|
||||||
|
TARGET="${ARCH}-linux-musl"
|
||||||
|
MCPU="baseline"
|
||||||
|
|
||||||
$ZIG test test/behavior.zig -fno-stage1 -I test -fLLVM
|
# Make the `zig version` number consistent.
|
||||||
$ZIG test test/behavior.zig -fno-stage1 -I test -ofmt=c
|
# This will affect the cmake command below.
|
||||||
$ZIG test test/behavior.zig -fno-stage1 -I test -target wasm32-wasi --test-cmd wasmtime --test-cmd-bin
|
git config core.abbrev 9
|
||||||
$ZIG test test/behavior.zig -fno-stage1 -I test -target arm-linux --test-cmd qemu-arm --test-cmd-bin
|
|
||||||
$ZIG test test/behavior.zig -fno-stage1 -I test
|
|
||||||
|
|
||||||
$ZIG build test-behavior -fqemu -fwasmtime
|
echo "BUILD debug zig with zig:$($ZIG version)"
|
||||||
|
|
||||||
|
export CC="$ZIG cc -target $TARGET -mcpu=$MCPU"
|
||||||
|
export CXX="$ZIG c++ -target $TARGET -mcpu=$MCPU"
|
||||||
|
|
||||||
|
mkdir _debug
|
||||||
|
cd _debug
|
||||||
|
cmake .. \
|
||||||
|
-DCMAKE_INSTALL_PREFIX="$DEBUG_STAGING" \
|
||||||
|
-DCMAKE_PREFIX_PATH="$DEPS_LOCAL" \
|
||||||
|
-DCMAKE_BUILD_TYPE=Debug \
|
||||||
|
-DZIG_TARGET_TRIPLE="$TARGET" \
|
||||||
|
-DZIG_TARGET_MCPU="$MCPU" \
|
||||||
|
-DZIG_STATIC=ON \
|
||||||
|
-GNinja
|
||||||
|
|
||||||
|
# Now cmake will use zig as the C/C++ compiler. We reset the environment variables
|
||||||
|
# so that installation and testing do not get affected by them.
|
||||||
|
unset CC
|
||||||
|
unset CXX
|
||||||
|
|
||||||
|
ninja install
|
||||||
|
|
||||||
|
ZIG="$DEBUG_STAGING/bin/zig"
|
||||||
|
|
||||||
|
# Here we rebuild zig but this time using the Zig binary we just now produced to
|
||||||
|
# build zig1.o rather than relying on the one built with stage0. See
|
||||||
|
# https://github.com/ziglang/zig/issues/6830 for more details.
|
||||||
|
cmake .. -DZIG_EXECUTABLE="$ZIG"
|
||||||
|
ninja install
|
||||||
|
|
||||||
|
cd $WORKSPACE
|
||||||
|
|
||||||
|
# Look for non-conforming code formatting.
|
||||||
|
# Formatting errors can be fixed by running `zig fmt` on the files printed here.
|
||||||
|
$ZIG fmt --check . --exclude test/cases/
|
||||||
|
|
||||||
|
# Build stage2 standalone so that we can test stage2 against stage2 compiler-rt.
|
||||||
|
$ZIG build -p stage2 -Dstatic-llvm -Dtarget=native-native-musl --search-prefix "$DEPS_LOCAL"
|
||||||
|
|
||||||
|
# Ensure that stage2 can build itself.
|
||||||
|
stage2/bin/zig build -p stage3 -Dstatic-llvm -Dtarget=native-native-musl --search-prefix "$DEPS_LOCAL"
|
||||||
|
stage2/bin/zig build # test building self-hosted without LLVM
|
||||||
|
stage2/bin/zig build -Dtarget=arm-linux-musleabihf # test building self-hosted for 32-bit arm
|
||||||
|
|
||||||
|
# Here we use stage2 instead of stage3 because of two bugs remaining:
|
||||||
|
# * https://github.com/ziglang/zig/issues/11367 (and corresponding workaround in compiler source)
|
||||||
|
# * https://github.com/ziglang/zig/pull/11492#issuecomment-1112871321
|
||||||
|
stage2/bin/zig build test-behavior -fqemu -fwasmtime
|
||||||
|
stage2/bin/zig test lib/std/std.zig --zig-lib-dir lib
|
||||||
|
|
||||||
|
$ZIG build test-behavior -fqemu -fwasmtime -Domit-stage2
|
||||||
$ZIG build test-compiler-rt -fqemu -fwasmtime
|
$ZIG build test-compiler-rt -fqemu -fwasmtime
|
||||||
$ZIG build test-std -fqemu -fwasmtime
|
$ZIG build test-std -fqemu -fwasmtime
|
||||||
$ZIG build test-minilibc -fqemu -fwasmtime
|
$ZIG build test-universal-libc -fqemu -fwasmtime
|
||||||
$ZIG build test-compare-output -fqemu -fwasmtime
|
$ZIG build test-compare-output -fqemu -fwasmtime
|
||||||
$ZIG build test-standalone -fqemu -fwasmtime
|
$ZIG build test-standalone -fqemu -fwasmtime
|
||||||
$ZIG build test-stack-traces -fqemu -fwasmtime
|
$ZIG build test-stack-traces -fqemu -fwasmtime
|
||||||
$ZIG build test-cli -fqemu -fwasmtime
|
$ZIG build test-cli -fqemu -fwasmtime
|
||||||
$ZIG build test-asm-link -fqemu -fwasmtime
|
$ZIG build test-asm-link -fqemu -fwasmtime
|
||||||
$ZIG build test-runtime-safety -fqemu -fwasmtime
|
|
||||||
$ZIG build test-translate-c -fqemu -fwasmtime
|
$ZIG build test-translate-c -fqemu -fwasmtime
|
||||||
$ZIG build test-run-translated-c -fqemu -fwasmtime
|
$ZIG build test-run-translated-c -fqemu -fwasmtime
|
||||||
$ZIG build docs -fqemu -fwasmtime
|
$ZIG build docs -fqemu -fwasmtime
|
||||||
$ZIG build # test building self-hosted without LLVM
|
|
||||||
$ZIG build -Dtarget=arm-linux-musleabihf # test building self-hosted for 32-bit arm
|
|
||||||
$ZIG build test-fmt -fqemu -fwasmtime
|
$ZIG build test-fmt -fqemu -fwasmtime
|
||||||
$ZIG build test-stage2 -fqemu -fwasmtime
|
$ZIG build test-cases -fqemu -fwasmtime
|
||||||
|
|
||||||
# Produce the experimental std lib documentation.
|
# Produce the experimental std lib documentation.
|
||||||
mkdir -p $RELEASE_STAGING/docs/std
|
mkdir -p "$RELEASE_STAGING/docs/std"
|
||||||
$ZIG test lib/std/std.zig \
|
$ZIG test lib/std/std.zig \
|
||||||
--zig-lib-dir lib \
|
--zig-lib-dir lib \
|
||||||
-femit-docs=$RELEASE_STAGING/docs/std \
|
-femit-docs=$RELEASE_STAGING/docs/std \
|
||||||
@ -38,5 +86,15 @@ $ZIG test lib/std/std.zig \
|
|||||||
# Look for HTML errors.
|
# Look for HTML errors.
|
||||||
tidy --drop-empty-elements no -qe zig-cache/langref.html
|
tidy --drop-empty-elements no -qe zig-cache/langref.html
|
||||||
|
|
||||||
|
# Build release zig.
|
||||||
|
$ZIG build \
|
||||||
|
--prefix "$RELEASE_STAGING" \
|
||||||
|
--search-prefix "$DEPS_LOCAL" \
|
||||||
|
-Dstatic-llvm \
|
||||||
|
-Drelease \
|
||||||
|
-Dstrip \
|
||||||
|
-Dtarget="$TARGET" \
|
||||||
|
-Dstage1
|
||||||
|
|
||||||
# Explicit exit helps show last command duration.
|
# Explicit exit helps show last command duration.
|
||||||
exit
|
exit
|
||||||
|
|||||||
@ -49,6 +49,7 @@ else()
|
|||||||
FIND_AND_ADD_LLD_LIB(lldELF)
|
FIND_AND_ADD_LLD_LIB(lldELF)
|
||||||
FIND_AND_ADD_LLD_LIB(lldCOFF)
|
FIND_AND_ADD_LLD_LIB(lldCOFF)
|
||||||
FIND_AND_ADD_LLD_LIB(lldWasm)
|
FIND_AND_ADD_LLD_LIB(lldWasm)
|
||||||
|
FIND_AND_ADD_LLD_LIB(lldMachO)
|
||||||
FIND_AND_ADD_LLD_LIB(lldReaderWriter)
|
FIND_AND_ADD_LLD_LIB(lldReaderWriter)
|
||||||
FIND_AND_ADD_LLD_LIB(lldCore)
|
FIND_AND_ADD_LLD_LIB(lldCore)
|
||||||
FIND_AND_ADD_LLD_LIB(lldYAML)
|
FIND_AND_ADD_LLD_LIB(lldYAML)
|
||||||
|
|||||||
@ -12,6 +12,7 @@ find_path(LLVM_INCLUDE_DIRS NAMES llvm/IR/IRBuilder.h
|
|||||||
/usr/lib/llvm/14/include
|
/usr/lib/llvm/14/include
|
||||||
/usr/lib/llvm-14/include
|
/usr/lib/llvm-14/include
|
||||||
/usr/lib/llvm-14.0/include
|
/usr/lib/llvm-14.0/include
|
||||||
|
/usr/lib/llvm14/include
|
||||||
/usr/local/llvm14/include
|
/usr/local/llvm14/include
|
||||||
/usr/local/llvm140/include
|
/usr/local/llvm140/include
|
||||||
/usr/local/opt/llvm@14/include
|
/usr/local/opt/llvm@14/include
|
||||||
@ -31,6 +32,7 @@ if(ZIG_PREFER_CLANG_CPP_DYLIB)
|
|||||||
/usr/lib/llvm/14/lib
|
/usr/lib/llvm/14/lib
|
||||||
/usr/lib/llvm/14/lib64
|
/usr/lib/llvm/14/lib64
|
||||||
/usr/lib/llvm-14/lib
|
/usr/lib/llvm-14/lib
|
||||||
|
/usr/lib/llvm14/lib
|
||||||
/usr/local/llvm14/lib
|
/usr/local/llvm14/lib
|
||||||
/usr/local/llvm140/lib
|
/usr/local/llvm140/lib
|
||||||
/usr/local/opt/llvm@14/lib
|
/usr/local/opt/llvm@14/lib
|
||||||
@ -181,19 +183,7 @@ else()
|
|||||||
|
|
||||||
macro(FIND_AND_ADD_LLVM_LIB _libname_)
|
macro(FIND_AND_ADD_LLVM_LIB _libname_)
|
||||||
string(TOUPPER ${_libname_} _prettylibname_)
|
string(TOUPPER ${_libname_} _prettylibname_)
|
||||||
find_library(LLVM_${_prettylibname_}_LIB NAMES ${_libname_}
|
find_library(LLVM_${_prettylibname_}_LIB NAMES ${_libname_} PATHS ${LLVM_LIBDIRS})
|
||||||
PATHS
|
|
||||||
${LLVM_LIBDIRS}
|
|
||||||
/usr/lib/llvm/14/lib
|
|
||||||
/usr/lib/llvm-14/lib
|
|
||||||
/usr/lib/llvm-14.0/lib
|
|
||||||
/usr/local/llvm140/lib
|
|
||||||
/usr/local/llvm14/lib
|
|
||||||
/usr/local/opt/llvm@14/lib
|
|
||||||
/opt/homebrew/opt/llvm@14/lib
|
|
||||||
/mingw64/lib
|
|
||||||
/c/msys64/mingw64/lib
|
|
||||||
c:\\msys64\\mingw64\\lib)
|
|
||||||
set(LLVM_LIBRARIES ${LLVM_LIBRARIES} ${LLVM_${_prettylibname_}_LIB})
|
set(LLVM_LIBRARIES ${LLVM_LIBRARIES} ${LLVM_${_prettylibname_}_LIB})
|
||||||
endmacro(FIND_AND_ADD_LLVM_LIB)
|
endmacro(FIND_AND_ADD_LLVM_LIB)
|
||||||
|
|
||||||
|
|||||||
14
deps/SoftFloat-3e-prebuilt/platform.h
vendored
14
deps/SoftFloat-3e-prebuilt/platform.h
vendored
@ -17,8 +17,6 @@
|
|||||||
#define BIGENDIAN 1
|
#define BIGENDIAN 1
|
||||||
#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||||
#define BIGENDIAN 1
|
#define BIGENDIAN 1
|
||||||
#elif defined(_BIG_ENDIAN)
|
|
||||||
#define BIGENDIAN 1
|
|
||||||
#elif defined(__sparc)
|
#elif defined(__sparc)
|
||||||
#define BIGENDIAN 1
|
#define BIGENDIAN 1
|
||||||
#elif defined(__sparc__)
|
#elif defined(__sparc__)
|
||||||
@ -37,7 +35,9 @@
|
|||||||
#define BIGENDIAN 1
|
#define BIGENDIAN 1
|
||||||
#elif defined(__s390__)
|
#elif defined(__s390__)
|
||||||
#define BIGENDIAN 1
|
#define BIGENDIAN 1
|
||||||
#elif defined(__LITTLE_ENDIAN__)
|
#endif
|
||||||
|
|
||||||
|
#if defined(__LITTLE_ENDIAN__)
|
||||||
#define LITTLEENDIAN 1
|
#define LITTLEENDIAN 1
|
||||||
#elif defined(__ARMEL__)
|
#elif defined(__ARMEL__)
|
||||||
#define LITTLEENDIAN 1
|
#define LITTLEENDIAN 1
|
||||||
@ -53,8 +53,6 @@
|
|||||||
#define LITTLEENDIAN 1
|
#define LITTLEENDIAN 1
|
||||||
#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||||
#define LITTLEENDIAN 1
|
#define LITTLEENDIAN 1
|
||||||
#elif defined(_LITTLE_ENDIAN)
|
|
||||||
#define LITTLEENDIAN 1
|
|
||||||
#elif defined(__i386__)
|
#elif defined(__i386__)
|
||||||
#define LITTLEENDIAN 1
|
#define LITTLEENDIAN 1
|
||||||
#elif defined(__alpha__)
|
#elif defined(__alpha__)
|
||||||
@ -83,7 +81,11 @@
|
|||||||
#define LITTLEENDIAN 1
|
#define LITTLEENDIAN 1
|
||||||
#elif defined(__bfin__)
|
#elif defined(__bfin__)
|
||||||
#define LITTLEENDIAN 1
|
#define LITTLEENDIAN 1
|
||||||
#else
|
#endif
|
||||||
|
|
||||||
|
#if defined(LITTLEENDIAN) && defined(BIGENDIAN)
|
||||||
|
#error unable to detect endianness
|
||||||
|
#elif !defined(LITTLEENDIAN) && !defined(BIGENDIAN)
|
||||||
#error unable to detect endianness
|
#error unable to detect endianness
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@ -37,6 +37,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#ifndef primitiveTypes_h
|
#ifndef primitiveTypes_h
|
||||||
#define primitiveTypes_h 1
|
#define primitiveTypes_h 1
|
||||||
|
|
||||||
|
#include "platform.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifdef SOFTFLOAT_FAST_INT64
|
#ifdef SOFTFLOAT_FAST_INT64
|
||||||
|
|||||||
@ -37,6 +37,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#ifndef softfloat_types_h
|
#ifndef softfloat_types_h
|
||||||
#define softfloat_types_h 1
|
#define softfloat_types_h 1
|
||||||
|
|
||||||
|
#include "platform.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
|
|||||||
@ -1196,7 +1196,7 @@ fn genHtml(
|
|||||||
do_code_tests: bool,
|
do_code_tests: bool,
|
||||||
) !void {
|
) !void {
|
||||||
var progress = Progress{};
|
var progress = Progress{};
|
||||||
const root_node = try progress.start("Generating docgen examples", toc.nodes.len);
|
const root_node = progress.start("Generating docgen examples", toc.nodes.len);
|
||||||
defer root_node.end();
|
defer root_node.end();
|
||||||
|
|
||||||
var env_map = try process.getEnvMap(allocator);
|
var env_map = try process.getEnvMap(allocator);
|
||||||
@ -1708,7 +1708,7 @@ fn genHtml(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exec(allocator: Allocator, env_map: *std.BufMap, args: []const []const u8) !ChildProcess.ExecResult {
|
fn exec(allocator: Allocator, env_map: *process.EnvMap, args: []const []const u8) !ChildProcess.ExecResult {
|
||||||
const result = try ChildProcess.exec(.{
|
const result = try ChildProcess.exec(.{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.argv = args,
|
.argv = args,
|
||||||
@ -1732,7 +1732,7 @@ fn exec(allocator: Allocator, env_map: *std.BufMap, args: []const []const u8) !C
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getBuiltinCode(allocator: Allocator, env_map: *std.BufMap, zig_exe: []const u8) ![]const u8 {
|
fn getBuiltinCode(allocator: Allocator, env_map: *process.EnvMap, zig_exe: []const u8) ![]const u8 {
|
||||||
const result = try exec(allocator, env_map, &[_][]const u8{ zig_exe, "build-obj", "--show-builtin" });
|
const result = try exec(allocator, env_map, &[_][]const u8{ zig_exe, "build-obj", "--show-builtin" });
|
||||||
return result.stdout;
|
return result.stdout;
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -24,19 +24,19 @@ pub fn main() !void {
|
|||||||
var arg_idx: usize = 1;
|
var arg_idx: usize = 1;
|
||||||
|
|
||||||
const zig_exe = nextArg(args, &arg_idx) orelse {
|
const zig_exe = nextArg(args, &arg_idx) orelse {
|
||||||
std.debug.print("Expected first argument to be path to zig compiler\n", .{});
|
std.debug.print("Expected path to zig compiler\n", .{});
|
||||||
return error.InvalidArgs;
|
return error.InvalidArgs;
|
||||||
};
|
};
|
||||||
const build_root = nextArg(args, &arg_idx) orelse {
|
const build_root = nextArg(args, &arg_idx) orelse {
|
||||||
std.debug.print("Expected second argument to be build root directory path\n", .{});
|
std.debug.print("Expected build root directory path\n", .{});
|
||||||
return error.InvalidArgs;
|
return error.InvalidArgs;
|
||||||
};
|
};
|
||||||
const cache_root = nextArg(args, &arg_idx) orelse {
|
const cache_root = nextArg(args, &arg_idx) orelse {
|
||||||
std.debug.print("Expected third argument to be cache root directory path\n", .{});
|
std.debug.print("Expected cache root directory path\n", .{});
|
||||||
return error.InvalidArgs;
|
return error.InvalidArgs;
|
||||||
};
|
};
|
||||||
const global_cache_root = nextArg(args, &arg_idx) orelse {
|
const global_cache_root = nextArg(args, &arg_idx) orelse {
|
||||||
std.debug.print("Expected third argument to be global cache root directory path\n", .{});
|
std.debug.print("Expected global cache root directory path\n", .{});
|
||||||
return error.InvalidArgs;
|
return error.InvalidArgs;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -147,10 +147,6 @@ pub fn main() !void {
|
|||||||
std.debug.print("Expected argument after --glibc-runtimes\n\n", .{});
|
std.debug.print("Expected argument after --glibc-runtimes\n\n", .{});
|
||||||
return usageAndErr(builder, false, stderr_stream);
|
return usageAndErr(builder, false, stderr_stream);
|
||||||
};
|
};
|
||||||
} else if (mem.eql(u8, arg, "--verbose-tokenize")) {
|
|
||||||
builder.verbose_tokenize = true;
|
|
||||||
} else if (mem.eql(u8, arg, "--verbose-ast")) {
|
|
||||||
builder.verbose_ast = true;
|
|
||||||
} else if (mem.eql(u8, arg, "--verbose-link")) {
|
} else if (mem.eql(u8, arg, "--verbose-link")) {
|
||||||
builder.verbose_link = true;
|
builder.verbose_link = true;
|
||||||
} else if (mem.eql(u8, arg, "--verbose-air")) {
|
} else if (mem.eql(u8, arg, "--verbose-air")) {
|
||||||
@ -185,6 +181,10 @@ pub fn main() !void {
|
|||||||
builder.enable_darling = true;
|
builder.enable_darling = true;
|
||||||
} else if (mem.eql(u8, arg, "-fno-darling")) {
|
} else if (mem.eql(u8, arg, "-fno-darling")) {
|
||||||
builder.enable_darling = false;
|
builder.enable_darling = false;
|
||||||
|
} else if (mem.eql(u8, arg, "-fstage1")) {
|
||||||
|
builder.use_stage1 = true;
|
||||||
|
} else if (mem.eql(u8, arg, "-fno-stage1")) {
|
||||||
|
builder.use_stage1 = false;
|
||||||
} else if (mem.eql(u8, arg, "--")) {
|
} else if (mem.eql(u8, arg, "--")) {
|
||||||
builder.args = argsRest(args, arg_idx);
|
builder.args = argsRest(args, arg_idx);
|
||||||
break;
|
break;
|
||||||
@ -306,12 +306,13 @@ fn usage(builder: *Builder, already_ran_build: bool, out_stream: anytype) !void
|
|||||||
try out_stream.writeAll(
|
try out_stream.writeAll(
|
||||||
\\
|
\\
|
||||||
\\Advanced Options:
|
\\Advanced Options:
|
||||||
|
\\ -fstage1 Force using bootstrap compiler as the codegen backend
|
||||||
|
\\ -fno-stage1 Prevent using bootstrap compiler as the codegen backend
|
||||||
\\ --build-file [file] Override path to build.zig
|
\\ --build-file [file] Override path to build.zig
|
||||||
\\ --cache-dir [path] Override path to zig cache directory
|
\\ --cache-dir [path] Override path to local Zig cache directory
|
||||||
|
\\ --global-cache-dir [path] Override path to global Zig cache directory
|
||||||
\\ --zig-lib-dir [arg] Override path to Zig lib directory
|
\\ --zig-lib-dir [arg] Override path to Zig lib directory
|
||||||
\\ --debug-log [scope] Enable debugging the compiler
|
\\ --debug-log [scope] Enable debugging the compiler
|
||||||
\\ --verbose-tokenize Enable compiler debug output for tokenization
|
|
||||||
\\ --verbose-ast Enable compiler debug output for parsing into an AST
|
|
||||||
\\ --verbose-link Enable compiler debug output for linking
|
\\ --verbose-link Enable compiler debug output for linking
|
||||||
\\ --verbose-air Enable compiler debug output for Zig AIR
|
\\ --verbose-air Enable compiler debug output for Zig AIR
|
||||||
\\ --verbose-llvm-ir Enable compiler debug output for LLVM IR
|
\\ --verbose-llvm-ir Enable compiler debug output for LLVM IR
|
||||||
@ -1,11 +1,17 @@
|
|||||||
|
//! This is Zig's multi-target implementation of libc.
|
||||||
|
//! When builtin.link_libc is true, we need to export all the functions and
|
||||||
|
//! provide an entire C API.
|
||||||
|
//! Otherwise, only the functions which LLVM generates calls to need to be generated,
|
||||||
|
//! such as memcpy, memset, and some math functions.
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
const maxInt = std.math.maxInt;
|
const math = std.math;
|
||||||
const isNan = std.math.isNan;
|
const isNan = std.math.isNan;
|
||||||
|
const maxInt = std.math.maxInt;
|
||||||
|
const native_os = builtin.os.tag;
|
||||||
const native_arch = builtin.cpu.arch;
|
const native_arch = builtin.cpu.arch;
|
||||||
const native_abi = builtin.abi;
|
const native_abi = builtin.abi;
|
||||||
const native_os = builtin.os.tag;
|
|
||||||
const long_double_is_f128 = builtin.target.longDoubleIsF128();
|
|
||||||
|
|
||||||
const is_wasm = switch (native_arch) {
|
const is_wasm = switch (native_arch) {
|
||||||
.wasm32, .wasm64 => true,
|
.wasm32, .wasm64 => true,
|
||||||
@ -19,10 +25,23 @@ const is_freestanding = switch (native_os) {
|
|||||||
.freestanding => true,
|
.freestanding => true,
|
||||||
else => false,
|
else => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
comptime {
|
comptime {
|
||||||
if (is_freestanding and is_wasm and builtin.link_libc) {
|
if (is_freestanding and is_wasm and builtin.link_libc) {
|
||||||
@export(wasm_start, .{ .name = "_start", .linkage = .Strong });
|
@export(wasm_start, .{ .name = "_start", .linkage = .Strong });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (native_os == .linux) {
|
||||||
|
@export(clone, .{ .name = "clone" });
|
||||||
|
}
|
||||||
|
|
||||||
|
@export(memset, .{ .name = "memset", .linkage = .Strong });
|
||||||
|
@export(__memset, .{ .name = "__memset", .linkage = .Strong });
|
||||||
|
@export(memcpy, .{ .name = "memcpy", .linkage = .Strong });
|
||||||
|
@export(memmove, .{ .name = "memmove", .linkage = .Strong });
|
||||||
|
@export(memcmp, .{ .name = "memcmp", .linkage = .Strong });
|
||||||
|
@export(bcmp, .{ .name = "bcmp", .linkage = .Strong });
|
||||||
|
|
||||||
if (builtin.link_libc) {
|
if (builtin.link_libc) {
|
||||||
@export(strcmp, .{ .name = "strcmp", .linkage = .Strong });
|
@export(strcmp, .{ .name = "strcmp", .linkage = .Strong });
|
||||||
@export(strncmp, .{ .name = "strncmp", .linkage = .Strong });
|
@export(strncmp, .{ .name = "strncmp", .linkage = .Strong });
|
||||||
@ -37,13 +56,137 @@ comptime {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var _fltused: c_int = 1;
|
// Avoid dragging in the runtime safety mechanisms into this .o file,
|
||||||
|
// unless we're trying to test this file.
|
||||||
|
pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace) noreturn {
|
||||||
|
@setCold(true);
|
||||||
|
_ = error_return_trace;
|
||||||
|
if (builtin.is_test) {
|
||||||
|
std.debug.panic("{s}", .{msg});
|
||||||
|
}
|
||||||
|
if (native_os != .freestanding and native_os != .other) {
|
||||||
|
std.os.abort();
|
||||||
|
}
|
||||||
|
while (true) {}
|
||||||
|
}
|
||||||
|
|
||||||
extern fn main(argc: c_int, argv: [*:null]?[*:0]u8) c_int;
|
extern fn main(argc: c_int, argv: [*:null]?[*:0]u8) c_int;
|
||||||
fn wasm_start() callconv(.C) void {
|
fn wasm_start() callconv(.C) void {
|
||||||
_ = main(0, undefined);
|
_ = main(0, undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn memset(dest: ?[*]u8, c: u8, len: usize) callconv(.C) ?[*]u8 {
|
||||||
|
@setRuntimeSafety(false);
|
||||||
|
|
||||||
|
if (len != 0) {
|
||||||
|
var d = dest.?;
|
||||||
|
var n = len;
|
||||||
|
while (true) {
|
||||||
|
d[0] = c;
|
||||||
|
n -= 1;
|
||||||
|
if (n == 0) break;
|
||||||
|
d += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __memset(dest: ?[*]u8, c: u8, n: usize, dest_n: usize) callconv(.C) ?[*]u8 {
|
||||||
|
if (dest_n < n)
|
||||||
|
@panic("buffer overflow");
|
||||||
|
return memset(dest, c, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn memcpy(noalias dest: ?[*]u8, noalias src: ?[*]const u8, len: usize) callconv(.C) ?[*]u8 {
|
||||||
|
@setRuntimeSafety(false);
|
||||||
|
|
||||||
|
if (len != 0) {
|
||||||
|
var d = dest.?;
|
||||||
|
var s = src.?;
|
||||||
|
var n = len;
|
||||||
|
while (true) {
|
||||||
|
d[0] = s[0];
|
||||||
|
n -= 1;
|
||||||
|
if (n == 0) break;
|
||||||
|
d += 1;
|
||||||
|
s += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn memmove(dest: ?[*]u8, src: ?[*]const u8, n: usize) callconv(.C) ?[*]u8 {
|
||||||
|
@setRuntimeSafety(false);
|
||||||
|
|
||||||
|
if (@ptrToInt(dest) < @ptrToInt(src)) {
|
||||||
|
var index: usize = 0;
|
||||||
|
while (index != n) : (index += 1) {
|
||||||
|
dest.?[index] = src.?[index];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var index = n;
|
||||||
|
while (index != 0) {
|
||||||
|
index -= 1;
|
||||||
|
dest.?[index] = src.?[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn memcmp(vl: ?[*]const u8, vr: ?[*]const u8, n: usize) callconv(.C) c_int {
|
||||||
|
@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 "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 };
|
||||||
|
|
||||||
|
try std.testing.expect(memcmp(base_arr[0..], arr1[0..], base_arr.len) == 0);
|
||||||
|
try std.testing.expect(memcmp(base_arr[0..], arr2[0..], base_arr.len) > 0);
|
||||||
|
try std.testing.expect(memcmp(base_arr[0..], arr3[0..], base_arr.len) < 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bcmp(vl: [*]allowzero const u8, vr: [*]allowzero const u8, n: usize) callconv(.C) c_int {
|
||||||
|
@setRuntimeSafety(false);
|
||||||
|
|
||||||
|
var index: usize = 0;
|
||||||
|
while (index != n) : (index += 1) {
|
||||||
|
if (vl[index] != vr[index]) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
test "bcmp" {
|
||||||
|
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 };
|
||||||
|
|
||||||
|
try std.testing.expect(bcmp(base_arr[0..], arr1[0..], base_arr.len) == 0);
|
||||||
|
try std.testing.expect(bcmp(base_arr[0..], arr2[0..], base_arr.len) != 0);
|
||||||
|
try std.testing.expect(bcmp(base_arr[0..], arr3[0..], base_arr.len) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
var _fltused: c_int = 1;
|
||||||
|
|
||||||
fn strcpy(dest: [*:0]u8, src: [*:0]const u8) callconv(.C) [*:0]u8 {
|
fn strcpy(dest: [*:0]u8, src: [*:0]const u8) callconv(.C) [*:0]u8 {
|
||||||
var i: usize = 0;
|
var i: usize = 0;
|
||||||
while (src[i] != 0) : (i += 1) {
|
while (src[i] != 0) : (i += 1) {
|
||||||
@ -161,106 +304,6 @@ test "strncmp" {
|
|||||||
try std.testing.expect(strncmp("\xff", "\x02", 1) == 253);
|
try std.testing.expect(strncmp("\xff", "\x02", 1) == 253);
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn memset(dest: ?[*]u8, c: u8, n: usize) callconv(.C) ?[*]u8 {
|
|
||||||
@setRuntimeSafety(false);
|
|
||||||
|
|
||||||
var index: usize = 0;
|
|
||||||
while (index != n) : (index += 1)
|
|
||||||
dest.?[index] = c;
|
|
||||||
|
|
||||||
return dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn __memset(dest: ?[*]u8, c: u8, n: usize, dest_n: usize) callconv(.C) ?[*]u8 {
|
|
||||||
if (dest_n < n)
|
|
||||||
@panic("buffer overflow");
|
|
||||||
return memset(dest, c, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn memcpy(noalias dest: ?[*]u8, noalias src: ?[*]const u8, n: usize) callconv(.C) ?[*]u8 {
|
|
||||||
@setRuntimeSafety(false);
|
|
||||||
|
|
||||||
var index: usize = 0;
|
|
||||||
while (index != n) : (index += 1)
|
|
||||||
dest.?[index] = src.?[index];
|
|
||||||
|
|
||||||
return dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn memmove(dest: ?[*]u8, src: ?[*]const u8, n: usize) callconv(.C) ?[*]u8 {
|
|
||||||
@setRuntimeSafety(false);
|
|
||||||
|
|
||||||
if (@ptrToInt(dest) < @ptrToInt(src)) {
|
|
||||||
var index: usize = 0;
|
|
||||||
while (index != n) : (index += 1) {
|
|
||||||
dest.?[index] = src.?[index];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var index = n;
|
|
||||||
while (index != 0) {
|
|
||||||
index -= 1;
|
|
||||||
dest.?[index] = src.?[index];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn memcmp(vl: ?[*]const u8, vr: ?[*]const u8, n: usize) callconv(.C) c_int {
|
|
||||||
@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 "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 };
|
|
||||||
|
|
||||||
try std.testing.expect(memcmp(base_arr[0..], arr1[0..], base_arr.len) == 0);
|
|
||||||
try std.testing.expect(memcmp(base_arr[0..], arr2[0..], base_arr.len) > 0);
|
|
||||||
try std.testing.expect(memcmp(base_arr[0..], arr3[0..], base_arr.len) < 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn bcmp(vl: [*]allowzero const u8, vr: [*]allowzero const u8, n: usize) callconv(.C) c_int {
|
|
||||||
@setRuntimeSafety(false);
|
|
||||||
|
|
||||||
var index: usize = 0;
|
|
||||||
while (index != n) : (index += 1) {
|
|
||||||
if (vl[index] != vr[index]) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
test "bcmp" {
|
|
||||||
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 };
|
|
||||||
|
|
||||||
try std.testing.expect(bcmp(base_arr[0..], arr1[0..], base_arr.len) == 0);
|
|
||||||
try std.testing.expect(bcmp(base_arr[0..], arr2[0..], base_arr.len) != 0);
|
|
||||||
try std.testing.expect(bcmp(base_arr[0..], arr3[0..], base_arr.len) != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
comptime {
|
|
||||||
if (native_os == .linux) {
|
|
||||||
@export(clone, .{ .name = "clone" });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO we should be able to put this directly in std/linux/x86_64.zig but
|
// TODO we should be able to put this directly in std/linux/x86_64.zig but
|
||||||
// it causes a segfault in release mode. this is a workaround of calling it
|
// it causes a segfault in release mode. this is a workaround of calling it
|
||||||
// across .o file boundaries. fix comptime @ptrCast of nakedcc functions.
|
// across .o file boundaries. fix comptime @ptrCast of nakedcc functions.
|
||||||
@ -582,7 +625,7 @@ fn clone() callconv(.Naked) void {
|
|||||||
\\ sc
|
\\ sc
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
.sparcv9 => {
|
.sparc64 => {
|
||||||
// __clone(func, stack, flags, arg, ptid, tls, ctid)
|
// __clone(func, stack, flags, arg, ptid, tls, ctid)
|
||||||
// i0, i1, i2, i3, i4, i5, sp
|
// i0, i1, i2, i3, i4, i5, sp
|
||||||
// syscall(SYS_clone, flags, stack, ptid, tls, ctid)
|
// syscall(SYS_clone, flags, stack, ptid, tls, ctid)
|
||||||
@ -629,568 +672,3 @@ fn clone() callconv(.Naked) void {
|
|||||||
else => @compileError("Implement clone() for this arch."),
|
else => @compileError("Implement clone() for this arch."),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const math = std.math;
|
|
||||||
|
|
||||||
export fn fmodf(x: f32, y: f32) f32 {
|
|
||||||
return generic_fmod(f32, x, y);
|
|
||||||
}
|
|
||||||
export fn fmod(x: f64, y: f64) f64 {
|
|
||||||
return generic_fmod(f64, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn ceilf(x: f32) f32 {
|
|
||||||
return math.ceil(x);
|
|
||||||
}
|
|
||||||
export fn ceil(x: f64) f64 {
|
|
||||||
return math.ceil(x);
|
|
||||||
}
|
|
||||||
export fn ceill(x: c_longdouble) c_longdouble {
|
|
||||||
if (!long_double_is_f128) {
|
|
||||||
@panic("TODO implement this");
|
|
||||||
}
|
|
||||||
return math.ceil(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn fmaf(a: f32, b: f32, c: f32) f32 {
|
|
||||||
return math.fma(f32, a, b, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn fma(a: f64, b: f64, c: f64) f64 {
|
|
||||||
return math.fma(f64, a, b, c);
|
|
||||||
}
|
|
||||||
export fn fmal(a: c_longdouble, b: c_longdouble, c: c_longdouble) c_longdouble {
|
|
||||||
if (!long_double_is_f128) {
|
|
||||||
@panic("TODO implement this");
|
|
||||||
}
|
|
||||||
return math.fma(c_longdouble, a, b, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn sin(a: f64) f64 {
|
|
||||||
return math.sin(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn sinf(a: f32) f32 {
|
|
||||||
return math.sin(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn cos(a: f64) f64 {
|
|
||||||
return math.cos(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn cosf(a: f32) f32 {
|
|
||||||
return math.cos(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn sincos(a: f64, r_sin: *f64, r_cos: *f64) void {
|
|
||||||
r_sin.* = math.sin(a);
|
|
||||||
r_cos.* = math.cos(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn sincosf(a: f32, r_sin: *f32, r_cos: *f32) void {
|
|
||||||
r_sin.* = math.sin(a);
|
|
||||||
r_cos.* = math.cos(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn exp(a: f64) f64 {
|
|
||||||
return math.exp(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn expf(a: f32) f32 {
|
|
||||||
return math.exp(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn exp2(a: f64) f64 {
|
|
||||||
return math.exp2(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn exp2f(a: f32) f32 {
|
|
||||||
return math.exp2(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn log(a: f64) f64 {
|
|
||||||
return math.ln(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn logf(a: f32) f32 {
|
|
||||||
return math.ln(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn log2(a: f64) f64 {
|
|
||||||
return math.log2(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn log2f(a: f32) f32 {
|
|
||||||
return math.log2(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn log10(a: f64) f64 {
|
|
||||||
return math.log10(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn log10f(a: f32) f32 {
|
|
||||||
return math.log10(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn fabs(a: f64) f64 {
|
|
||||||
return math.fabs(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn fabsf(a: f32) f32 {
|
|
||||||
return math.fabs(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn trunc(a: f64) f64 {
|
|
||||||
return math.trunc(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn truncf(a: f32) f32 {
|
|
||||||
return math.trunc(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn truncl(a: c_longdouble) c_longdouble {
|
|
||||||
if (!long_double_is_f128) {
|
|
||||||
@panic("TODO implement this");
|
|
||||||
}
|
|
||||||
return math.trunc(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn round(a: f64) f64 {
|
|
||||||
return math.round(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn roundf(a: f32) f32 {
|
|
||||||
return math.round(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn generic_fmod(comptime T: type, x: T, y: T) T {
|
|
||||||
@setRuntimeSafety(false);
|
|
||||||
|
|
||||||
const bits = @typeInfo(T).Float.bits;
|
|
||||||
const uint = std.meta.Int(.unsigned, bits);
|
|
||||||
const log2uint = math.Log2Int(uint);
|
|
||||||
const digits = if (T == f32) 23 else 52;
|
|
||||||
const exp_bits = if (T == f32) 9 else 12;
|
|
||||||
const bits_minus_1 = bits - 1;
|
|
||||||
const mask = if (T == f32) 0xff else 0x7ff;
|
|
||||||
var ux = @bitCast(uint, x);
|
|
||||||
var uy = @bitCast(uint, y);
|
|
||||||
var ex = @intCast(i32, (ux >> digits) & mask);
|
|
||||||
var ey = @intCast(i32, (uy >> digits) & mask);
|
|
||||||
const sx = if (T == f32) @intCast(u32, ux & 0x80000000) else @intCast(i32, ux >> bits_minus_1);
|
|
||||||
var i: uint = undefined;
|
|
||||||
|
|
||||||
if (uy << 1 == 0 or isNan(@bitCast(T, uy)) or ex == mask)
|
|
||||||
return (x * y) / (x * y);
|
|
||||||
|
|
||||||
if (ux << 1 <= uy << 1) {
|
|
||||||
if (ux << 1 == uy << 1)
|
|
||||||
return 0 * x;
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
// normalize x and y
|
|
||||||
if (ex == 0) {
|
|
||||||
i = ux << exp_bits;
|
|
||||||
while (i >> bits_minus_1 == 0) : ({
|
|
||||||
ex -= 1;
|
|
||||||
i <<= 1;
|
|
||||||
}) {}
|
|
||||||
ux <<= @intCast(log2uint, @bitCast(u32, -ex + 1));
|
|
||||||
} else {
|
|
||||||
ux &= maxInt(uint) >> exp_bits;
|
|
||||||
ux |= 1 << digits;
|
|
||||||
}
|
|
||||||
if (ey == 0) {
|
|
||||||
i = uy << exp_bits;
|
|
||||||
while (i >> bits_minus_1 == 0) : ({
|
|
||||||
ey -= 1;
|
|
||||||
i <<= 1;
|
|
||||||
}) {}
|
|
||||||
uy <<= @intCast(log2uint, @bitCast(u32, -ey + 1));
|
|
||||||
} else {
|
|
||||||
uy &= maxInt(uint) >> exp_bits;
|
|
||||||
uy |= 1 << digits;
|
|
||||||
}
|
|
||||||
|
|
||||||
// x mod y
|
|
||||||
while (ex > ey) : (ex -= 1) {
|
|
||||||
i = ux -% uy;
|
|
||||||
if (i >> bits_minus_1 == 0) {
|
|
||||||
if (i == 0)
|
|
||||||
return 0 * x;
|
|
||||||
ux = i;
|
|
||||||
}
|
|
||||||
ux <<= 1;
|
|
||||||
}
|
|
||||||
i = ux -% uy;
|
|
||||||
if (i >> bits_minus_1 == 0) {
|
|
||||||
if (i == 0)
|
|
||||||
return 0 * x;
|
|
||||||
ux = i;
|
|
||||||
}
|
|
||||||
while (ux >> digits == 0) : ({
|
|
||||||
ux <<= 1;
|
|
||||||
ex -= 1;
|
|
||||||
}) {}
|
|
||||||
|
|
||||||
// scale result up
|
|
||||||
if (ex > 0) {
|
|
||||||
ux -%= 1 << digits;
|
|
||||||
ux |= @as(uint, @bitCast(u32, ex)) << digits;
|
|
||||||
} else {
|
|
||||||
ux >>= @intCast(log2uint, @bitCast(u32, -ex + 1));
|
|
||||||
}
|
|
||||||
if (T == f32) {
|
|
||||||
ux |= sx;
|
|
||||||
} else {
|
|
||||||
ux |= @intCast(uint, sx) << bits_minus_1;
|
|
||||||
}
|
|
||||||
return @bitCast(T, ux);
|
|
||||||
}
|
|
||||||
|
|
||||||
test "fmod, fmodf" {
|
|
||||||
inline for ([_]type{ f32, f64 }) |T| {
|
|
||||||
const nan_val = math.nan(T);
|
|
||||||
const inf_val = math.inf(T);
|
|
||||||
|
|
||||||
try std.testing.expect(isNan(generic_fmod(T, nan_val, 1.0)));
|
|
||||||
try std.testing.expect(isNan(generic_fmod(T, 1.0, nan_val)));
|
|
||||||
try std.testing.expect(isNan(generic_fmod(T, inf_val, 1.0)));
|
|
||||||
try std.testing.expect(isNan(generic_fmod(T, 0.0, 0.0)));
|
|
||||||
try std.testing.expect(isNan(generic_fmod(T, 1.0, 0.0)));
|
|
||||||
|
|
||||||
try std.testing.expectEqual(@as(T, 0.0), generic_fmod(T, 0.0, 2.0));
|
|
||||||
try std.testing.expectEqual(@as(T, -0.0), generic_fmod(T, -0.0, 2.0));
|
|
||||||
|
|
||||||
try std.testing.expectEqual(@as(T, -2.0), generic_fmod(T, -32.0, 10.0));
|
|
||||||
try std.testing.expectEqual(@as(T, -2.0), generic_fmod(T, -32.0, -10.0));
|
|
||||||
try std.testing.expectEqual(@as(T, 2.0), generic_fmod(T, 32.0, 10.0));
|
|
||||||
try std.testing.expectEqual(@as(T, 2.0), generic_fmod(T, 32.0, -10.0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn generic_fmin(comptime T: type, x: T, y: T) T {
|
|
||||||
if (isNan(x))
|
|
||||||
return y;
|
|
||||||
if (isNan(y))
|
|
||||||
return x;
|
|
||||||
return if (x < y) x else y;
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn fminf(x: f32, y: f32) callconv(.C) f32 {
|
|
||||||
return generic_fmin(f32, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn fmin(x: f64, y: f64) callconv(.C) f64 {
|
|
||||||
return generic_fmin(f64, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
test "fmin, fminf" {
|
|
||||||
inline for ([_]type{ f32, f64 }) |T| {
|
|
||||||
const nan_val = math.nan(T);
|
|
||||||
|
|
||||||
try std.testing.expect(isNan(generic_fmin(T, nan_val, nan_val)));
|
|
||||||
try std.testing.expectEqual(@as(T, 1.0), generic_fmin(T, nan_val, 1.0));
|
|
||||||
try std.testing.expectEqual(@as(T, 1.0), generic_fmin(T, 1.0, nan_val));
|
|
||||||
|
|
||||||
try std.testing.expectEqual(@as(T, 1.0), generic_fmin(T, 1.0, 10.0));
|
|
||||||
try std.testing.expectEqual(@as(T, -1.0), generic_fmin(T, 1.0, -1.0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn generic_fmax(comptime T: type, x: T, y: T) T {
|
|
||||||
if (isNan(x))
|
|
||||||
return y;
|
|
||||||
if (isNan(y))
|
|
||||||
return x;
|
|
||||||
return if (x < y) y else x;
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn fmaxf(x: f32, y: f32) callconv(.C) f32 {
|
|
||||||
return generic_fmax(f32, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn fmax(x: f64, y: f64) callconv(.C) f64 {
|
|
||||||
return generic_fmax(f64, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
test "fmax, fmaxf" {
|
|
||||||
inline for ([_]type{ f32, f64 }) |T| {
|
|
||||||
const nan_val = math.nan(T);
|
|
||||||
|
|
||||||
try std.testing.expect(isNan(generic_fmax(T, nan_val, nan_val)));
|
|
||||||
try std.testing.expectEqual(@as(T, 1.0), generic_fmax(T, nan_val, 1.0));
|
|
||||||
try std.testing.expectEqual(@as(T, 1.0), generic_fmax(T, 1.0, nan_val));
|
|
||||||
|
|
||||||
try std.testing.expectEqual(@as(T, 10.0), generic_fmax(T, 1.0, 10.0));
|
|
||||||
try std.testing.expectEqual(@as(T, 1.0), generic_fmax(T, 1.0, -1.0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: The original code is full of implicit signed -> unsigned assumptions and u32 wraparound
|
|
||||||
// behaviour. Most intermediate i32 values are changed to u32 where appropriate but there are
|
|
||||||
// potentially some edge cases remaining that are not handled in the same way.
|
|
||||||
export fn sqrt(x: f64) f64 {
|
|
||||||
const tiny: f64 = 1.0e-300;
|
|
||||||
const sign: u32 = 0x80000000;
|
|
||||||
const u = @bitCast(u64, x);
|
|
||||||
|
|
||||||
var ix0 = @intCast(u32, u >> 32);
|
|
||||||
var ix1 = @intCast(u32, u & 0xFFFFFFFF);
|
|
||||||
|
|
||||||
// sqrt(nan) = nan, sqrt(+inf) = +inf, sqrt(-inf) = nan
|
|
||||||
if (ix0 & 0x7FF00000 == 0x7FF00000) {
|
|
||||||
return x * x + x;
|
|
||||||
}
|
|
||||||
|
|
||||||
// sqrt(+-0) = +-0
|
|
||||||
if (x == 0.0) {
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
// sqrt(-ve) = snan
|
|
||||||
if (ix0 & sign != 0) {
|
|
||||||
return math.snan(f64);
|
|
||||||
}
|
|
||||||
|
|
||||||
// normalize x
|
|
||||||
var m = @intCast(i32, ix0 >> 20);
|
|
||||||
if (m == 0) {
|
|
||||||
// subnormal
|
|
||||||
while (ix0 == 0) {
|
|
||||||
m -= 21;
|
|
||||||
ix0 |= ix1 >> 11;
|
|
||||||
ix1 <<= 21;
|
|
||||||
}
|
|
||||||
|
|
||||||
// subnormal
|
|
||||||
var i: u32 = 0;
|
|
||||||
while (ix0 & 0x00100000 == 0) : (i += 1) {
|
|
||||||
ix0 <<= 1;
|
|
||||||
}
|
|
||||||
m -= @intCast(i32, i) - 1;
|
|
||||||
ix0 |= ix1 >> @intCast(u5, 32 - i);
|
|
||||||
ix1 <<= @intCast(u5, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
// unbias exponent
|
|
||||||
m -= 1023;
|
|
||||||
ix0 = (ix0 & 0x000FFFFF) | 0x00100000;
|
|
||||||
if (m & 1 != 0) {
|
|
||||||
ix0 += ix0 + (ix1 >> 31);
|
|
||||||
ix1 = ix1 +% ix1;
|
|
||||||
}
|
|
||||||
m >>= 1;
|
|
||||||
|
|
||||||
// sqrt(x) bit by bit
|
|
||||||
ix0 += ix0 + (ix1 >> 31);
|
|
||||||
ix1 = ix1 +% ix1;
|
|
||||||
|
|
||||||
var q: u32 = 0;
|
|
||||||
var q1: u32 = 0;
|
|
||||||
var s0: u32 = 0;
|
|
||||||
var s1: u32 = 0;
|
|
||||||
var r: u32 = 0x00200000;
|
|
||||||
var t: u32 = undefined;
|
|
||||||
var t1: u32 = undefined;
|
|
||||||
|
|
||||||
while (r != 0) {
|
|
||||||
t = s0 +% r;
|
|
||||||
if (t <= ix0) {
|
|
||||||
s0 = t + r;
|
|
||||||
ix0 -= t;
|
|
||||||
q += r;
|
|
||||||
}
|
|
||||||
ix0 = ix0 +% ix0 +% (ix1 >> 31);
|
|
||||||
ix1 = ix1 +% ix1;
|
|
||||||
r >>= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = sign;
|
|
||||||
while (r != 0) {
|
|
||||||
t1 = s1 +% r;
|
|
||||||
t = s0;
|
|
||||||
if (t < ix0 or (t == ix0 and t1 <= ix1)) {
|
|
||||||
s1 = t1 +% r;
|
|
||||||
if (t1 & sign == sign and s1 & sign == 0) {
|
|
||||||
s0 += 1;
|
|
||||||
}
|
|
||||||
ix0 -= t;
|
|
||||||
if (ix1 < t1) {
|
|
||||||
ix0 -= 1;
|
|
||||||
}
|
|
||||||
ix1 = ix1 -% t1;
|
|
||||||
q1 += r;
|
|
||||||
}
|
|
||||||
ix0 = ix0 +% ix0 +% (ix1 >> 31);
|
|
||||||
ix1 = ix1 +% ix1;
|
|
||||||
r >>= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// rounding direction
|
|
||||||
if (ix0 | ix1 != 0) {
|
|
||||||
var z = 1.0 - tiny; // raise inexact
|
|
||||||
if (z >= 1.0) {
|
|
||||||
z = 1.0 + tiny;
|
|
||||||
if (q1 == 0xFFFFFFFF) {
|
|
||||||
q1 = 0;
|
|
||||||
q += 1;
|
|
||||||
} else if (z > 1.0) {
|
|
||||||
if (q1 == 0xFFFFFFFE) {
|
|
||||||
q += 1;
|
|
||||||
}
|
|
||||||
q1 += 2;
|
|
||||||
} else {
|
|
||||||
q1 += q1 & 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ix0 = (q >> 1) + 0x3FE00000;
|
|
||||||
ix1 = q1 >> 1;
|
|
||||||
if (q & 1 != 0) {
|
|
||||||
ix1 |= 0x80000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: musl here appears to rely on signed twos-complement wraparound. +% has the same
|
|
||||||
// behaviour at least.
|
|
||||||
var iix0 = @intCast(i32, ix0);
|
|
||||||
iix0 = iix0 +% (m << 20);
|
|
||||||
|
|
||||||
const uz = (@intCast(u64, iix0) << 32) | ix1;
|
|
||||||
return @bitCast(f64, uz);
|
|
||||||
}
|
|
||||||
|
|
||||||
test "sqrt" {
|
|
||||||
const V = [_]f64{
|
|
||||||
0.0,
|
|
||||||
4.089288054930154,
|
|
||||||
7.538757127071935,
|
|
||||||
8.97780793672623,
|
|
||||||
5.304443821913729,
|
|
||||||
5.682408965311888,
|
|
||||||
0.5846878579110049,
|
|
||||||
3.650338664297043,
|
|
||||||
0.3178091951800732,
|
|
||||||
7.1505232436382835,
|
|
||||||
3.6589165881946464,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Note that @sqrt will either generate the sqrt opcode (if supported by the
|
|
||||||
// target ISA) or a call to `sqrtf` otherwise.
|
|
||||||
for (V) |val|
|
|
||||||
try std.testing.expectEqual(@sqrt(val), sqrt(val));
|
|
||||||
}
|
|
||||||
|
|
||||||
test "sqrt special" {
|
|
||||||
try std.testing.expect(std.math.isPositiveInf(sqrt(std.math.inf(f64))));
|
|
||||||
try std.testing.expect(sqrt(0.0) == 0.0);
|
|
||||||
try std.testing.expect(sqrt(-0.0) == -0.0);
|
|
||||||
try std.testing.expect(isNan(sqrt(-1.0)));
|
|
||||||
try std.testing.expect(isNan(sqrt(std.math.nan(f64))));
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn sqrtf(x: f32) f32 {
|
|
||||||
const tiny: f32 = 1.0e-30;
|
|
||||||
const sign: i32 = @bitCast(i32, @as(u32, 0x80000000));
|
|
||||||
var ix: i32 = @bitCast(i32, x);
|
|
||||||
|
|
||||||
if ((ix & 0x7F800000) == 0x7F800000) {
|
|
||||||
return x * x + x; // sqrt(nan) = nan, sqrt(+inf) = +inf, sqrt(-inf) = snan
|
|
||||||
}
|
|
||||||
|
|
||||||
// zero
|
|
||||||
if (ix <= 0) {
|
|
||||||
if (ix & ~sign == 0) {
|
|
||||||
return x; // sqrt (+-0) = +-0
|
|
||||||
}
|
|
||||||
if (ix < 0) {
|
|
||||||
return math.snan(f32);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// normalize
|
|
||||||
var m = ix >> 23;
|
|
||||||
if (m == 0) {
|
|
||||||
// subnormal
|
|
||||||
var i: i32 = 0;
|
|
||||||
while (ix & 0x00800000 == 0) : (i += 1) {
|
|
||||||
ix <<= 1;
|
|
||||||
}
|
|
||||||
m -= i - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
m -= 127; // unbias exponent
|
|
||||||
ix = (ix & 0x007FFFFF) | 0x00800000;
|
|
||||||
|
|
||||||
if (m & 1 != 0) { // odd m, double x to even
|
|
||||||
ix += ix;
|
|
||||||
}
|
|
||||||
|
|
||||||
m >>= 1; // m = [m / 2]
|
|
||||||
|
|
||||||
// sqrt(x) bit by bit
|
|
||||||
ix += ix;
|
|
||||||
var q: i32 = 0; // q = sqrt(x)
|
|
||||||
var s: i32 = 0;
|
|
||||||
var r: i32 = 0x01000000; // r = moving bit right -> left
|
|
||||||
|
|
||||||
while (r != 0) {
|
|
||||||
const t = s + r;
|
|
||||||
if (t <= ix) {
|
|
||||||
s = t + r;
|
|
||||||
ix -= t;
|
|
||||||
q += r;
|
|
||||||
}
|
|
||||||
ix += ix;
|
|
||||||
r >>= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// floating add to find rounding direction
|
|
||||||
if (ix != 0) {
|
|
||||||
var z = 1.0 - tiny; // inexact
|
|
||||||
if (z >= 1.0) {
|
|
||||||
z = 1.0 + tiny;
|
|
||||||
if (z > 1.0) {
|
|
||||||
q += 2;
|
|
||||||
} else {
|
|
||||||
if (q & 1 != 0) {
|
|
||||||
q += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ix = (q >> 1) + 0x3f000000;
|
|
||||||
ix += m << 23;
|
|
||||||
return @bitCast(f32, ix);
|
|
||||||
}
|
|
||||||
|
|
||||||
test "sqrtf" {
|
|
||||||
const V = [_]f32{
|
|
||||||
0.0,
|
|
||||||
4.089288054930154,
|
|
||||||
7.538757127071935,
|
|
||||||
8.97780793672623,
|
|
||||||
5.304443821913729,
|
|
||||||
5.682408965311888,
|
|
||||||
0.5846878579110049,
|
|
||||||
3.650338664297043,
|
|
||||||
0.3178091951800732,
|
|
||||||
7.1505232436382835,
|
|
||||||
3.6589165881946464,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Note that @sqrt will either generate the sqrt opcode (if supported by the
|
|
||||||
// target ISA) or a call to `sqrtf` otherwise.
|
|
||||||
for (V) |val|
|
|
||||||
try std.testing.expectEqual(@sqrt(val), sqrtf(val));
|
|
||||||
}
|
|
||||||
|
|
||||||
test "sqrtf special" {
|
|
||||||
try std.testing.expect(std.math.isPositiveInf(sqrtf(std.math.inf(f32))));
|
|
||||||
try std.testing.expect(sqrtf(0.0) == 0.0);
|
|
||||||
try std.testing.expect(sqrtf(-0.0) == -0.0);
|
|
||||||
try std.testing.expect(isNan(sqrtf(-1.0)));
|
|
||||||
try std.testing.expect(isNan(sqrtf(std.math.nan(f32))));
|
|
||||||
}
|
|
||||||
187
lib/compiler_rt.zig
Normal file
187
lib/compiler_rt.zig
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
pub const panic = @import("compiler_rt/common.zig").panic;
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
_ = @import("compiler_rt/atomics.zig");
|
||||||
|
|
||||||
|
_ = @import("compiler_rt/addf3.zig");
|
||||||
|
_ = @import("compiler_rt/addsf3.zig");
|
||||||
|
_ = @import("compiler_rt/adddf3.zig");
|
||||||
|
_ = @import("compiler_rt/addtf3.zig");
|
||||||
|
_ = @import("compiler_rt/addxf3.zig");
|
||||||
|
|
||||||
|
_ = @import("compiler_rt/subsf3.zig");
|
||||||
|
_ = @import("compiler_rt/subdf3.zig");
|
||||||
|
_ = @import("compiler_rt/subtf3.zig");
|
||||||
|
_ = @import("compiler_rt/subxf3.zig");
|
||||||
|
|
||||||
|
_ = @import("compiler_rt/mulf3.zig");
|
||||||
|
_ = @import("compiler_rt/muldf3.zig");
|
||||||
|
_ = @import("compiler_rt/mulsf3.zig");
|
||||||
|
_ = @import("compiler_rt/multf3.zig");
|
||||||
|
_ = @import("compiler_rt/mulxf3.zig");
|
||||||
|
|
||||||
|
_ = @import("compiler_rt/negsf2.zig");
|
||||||
|
_ = @import("compiler_rt/negdf2.zig");
|
||||||
|
_ = @import("compiler_rt/negtf2.zig");
|
||||||
|
_ = @import("compiler_rt/negxf2.zig");
|
||||||
|
|
||||||
|
_ = @import("compiler_rt/comparef.zig");
|
||||||
|
_ = @import("compiler_rt/cmpsf2.zig");
|
||||||
|
_ = @import("compiler_rt/cmpdf2.zig");
|
||||||
|
_ = @import("compiler_rt/cmptf2.zig");
|
||||||
|
_ = @import("compiler_rt/cmpxf2.zig");
|
||||||
|
_ = @import("compiler_rt/gesf2.zig");
|
||||||
|
_ = @import("compiler_rt/gedf2.zig");
|
||||||
|
_ = @import("compiler_rt/getf2.zig");
|
||||||
|
_ = @import("compiler_rt/gexf2.zig");
|
||||||
|
_ = @import("compiler_rt/unordsf2.zig");
|
||||||
|
_ = @import("compiler_rt/unorddf2.zig");
|
||||||
|
_ = @import("compiler_rt/unordtf2.zig");
|
||||||
|
|
||||||
|
_ = @import("compiler_rt/extendf.zig");
|
||||||
|
_ = @import("compiler_rt/extenddftf2.zig");
|
||||||
|
_ = @import("compiler_rt/extenddfxf2.zig");
|
||||||
|
_ = @import("compiler_rt/extendhfsf2.zig");
|
||||||
|
_ = @import("compiler_rt/extendhftf2.zig");
|
||||||
|
_ = @import("compiler_rt/extendhfxf2.zig");
|
||||||
|
_ = @import("compiler_rt/extendsfdf2.zig");
|
||||||
|
_ = @import("compiler_rt/extendsftf2.zig");
|
||||||
|
_ = @import("compiler_rt/extendsfxf2.zig");
|
||||||
|
_ = @import("compiler_rt/extendxftf2.zig");
|
||||||
|
|
||||||
|
_ = @import("compiler_rt/truncf.zig");
|
||||||
|
_ = @import("compiler_rt/truncsfhf2.zig");
|
||||||
|
_ = @import("compiler_rt/truncdfhf2.zig");
|
||||||
|
_ = @import("compiler_rt/truncdfsf2.zig");
|
||||||
|
_ = @import("compiler_rt/trunctfhf2.zig");
|
||||||
|
_ = @import("compiler_rt/trunctfsf2.zig");
|
||||||
|
_ = @import("compiler_rt/trunctfdf2.zig");
|
||||||
|
_ = @import("compiler_rt/trunctfxf2.zig");
|
||||||
|
_ = @import("compiler_rt/truncxfhf2.zig");
|
||||||
|
_ = @import("compiler_rt/truncxfsf2.zig");
|
||||||
|
_ = @import("compiler_rt/truncxfdf2.zig");
|
||||||
|
|
||||||
|
_ = @import("compiler_rt/divtf3.zig");
|
||||||
|
_ = @import("compiler_rt/divsf3.zig");
|
||||||
|
_ = @import("compiler_rt/divdf3.zig");
|
||||||
|
_ = @import("compiler_rt/divxf3.zig");
|
||||||
|
_ = @import("compiler_rt/sin.zig");
|
||||||
|
_ = @import("compiler_rt/cos.zig");
|
||||||
|
_ = @import("compiler_rt/sincos.zig");
|
||||||
|
_ = @import("compiler_rt/ceil.zig");
|
||||||
|
_ = @import("compiler_rt/exp.zig");
|
||||||
|
_ = @import("compiler_rt/exp2.zig");
|
||||||
|
_ = @import("compiler_rt/fabs.zig");
|
||||||
|
_ = @import("compiler_rt/floor.zig");
|
||||||
|
_ = @import("compiler_rt/fma.zig");
|
||||||
|
_ = @import("compiler_rt/fmax.zig");
|
||||||
|
_ = @import("compiler_rt/fmin.zig");
|
||||||
|
_ = @import("compiler_rt/fmod.zig");
|
||||||
|
_ = @import("compiler_rt/log.zig");
|
||||||
|
_ = @import("compiler_rt/log10.zig");
|
||||||
|
_ = @import("compiler_rt/log2.zig");
|
||||||
|
_ = @import("compiler_rt/round.zig");
|
||||||
|
_ = @import("compiler_rt/sqrt.zig");
|
||||||
|
_ = @import("compiler_rt/tan.zig");
|
||||||
|
_ = @import("compiler_rt/trunc.zig");
|
||||||
|
_ = @import("compiler_rt/stack_probe.zig");
|
||||||
|
_ = @import("compiler_rt/divti3.zig");
|
||||||
|
_ = @import("compiler_rt/modti3.zig");
|
||||||
|
_ = @import("compiler_rt/multi3.zig");
|
||||||
|
_ = @import("compiler_rt/udivti3.zig");
|
||||||
|
_ = @import("compiler_rt/udivmodti4.zig");
|
||||||
|
_ = @import("compiler_rt/umodti3.zig");
|
||||||
|
|
||||||
|
_ = @import("compiler_rt/int_to_float.zig");
|
||||||
|
_ = @import("compiler_rt/floatsihf.zig");
|
||||||
|
_ = @import("compiler_rt/floatsisf.zig");
|
||||||
|
_ = @import("compiler_rt/floatsidf.zig");
|
||||||
|
_ = @import("compiler_rt/floatsitf.zig");
|
||||||
|
_ = @import("compiler_rt/floatsixf.zig");
|
||||||
|
_ = @import("compiler_rt/floatdihf.zig");
|
||||||
|
_ = @import("compiler_rt/floatdisf.zig");
|
||||||
|
_ = @import("compiler_rt/floatdidf.zig");
|
||||||
|
_ = @import("compiler_rt/floatditf.zig");
|
||||||
|
_ = @import("compiler_rt/floatdixf.zig");
|
||||||
|
_ = @import("compiler_rt/floattihf.zig");
|
||||||
|
_ = @import("compiler_rt/floattisf.zig");
|
||||||
|
_ = @import("compiler_rt/floattidf.zig");
|
||||||
|
_ = @import("compiler_rt/floattitf.zig");
|
||||||
|
_ = @import("compiler_rt/floattixf.zig");
|
||||||
|
_ = @import("compiler_rt/floatundihf.zig");
|
||||||
|
_ = @import("compiler_rt/floatundisf.zig");
|
||||||
|
_ = @import("compiler_rt/floatundidf.zig");
|
||||||
|
_ = @import("compiler_rt/floatunditf.zig");
|
||||||
|
_ = @import("compiler_rt/floatundixf.zig");
|
||||||
|
_ = @import("compiler_rt/floatunsihf.zig");
|
||||||
|
_ = @import("compiler_rt/floatunsisf.zig");
|
||||||
|
_ = @import("compiler_rt/floatunsidf.zig");
|
||||||
|
_ = @import("compiler_rt/floatunsitf.zig");
|
||||||
|
_ = @import("compiler_rt/floatunsixf.zig");
|
||||||
|
_ = @import("compiler_rt/floatuntihf.zig");
|
||||||
|
_ = @import("compiler_rt/floatuntisf.zig");
|
||||||
|
_ = @import("compiler_rt/floatuntidf.zig");
|
||||||
|
_ = @import("compiler_rt/floatuntitf.zig");
|
||||||
|
_ = @import("compiler_rt/floatuntixf.zig");
|
||||||
|
|
||||||
|
_ = @import("compiler_rt/float_to_int.zig");
|
||||||
|
_ = @import("compiler_rt/fixhfsi.zig");
|
||||||
|
_ = @import("compiler_rt/fixhfdi.zig");
|
||||||
|
_ = @import("compiler_rt/fixhfti.zig");
|
||||||
|
_ = @import("compiler_rt/fixsfsi.zig");
|
||||||
|
_ = @import("compiler_rt/fixsfdi.zig");
|
||||||
|
_ = @import("compiler_rt/fixsfti.zig");
|
||||||
|
_ = @import("compiler_rt/fixdfsi.zig");
|
||||||
|
_ = @import("compiler_rt/fixdfdi.zig");
|
||||||
|
_ = @import("compiler_rt/fixdfti.zig");
|
||||||
|
_ = @import("compiler_rt/fixtfsi.zig");
|
||||||
|
_ = @import("compiler_rt/fixtfdi.zig");
|
||||||
|
_ = @import("compiler_rt/fixtfti.zig");
|
||||||
|
_ = @import("compiler_rt/fixxfsi.zig");
|
||||||
|
_ = @import("compiler_rt/fixxfdi.zig");
|
||||||
|
_ = @import("compiler_rt/fixxfti.zig");
|
||||||
|
_ = @import("compiler_rt/fixunshfsi.zig");
|
||||||
|
_ = @import("compiler_rt/fixunshfdi.zig");
|
||||||
|
_ = @import("compiler_rt/fixunshfti.zig");
|
||||||
|
_ = @import("compiler_rt/fixunssfsi.zig");
|
||||||
|
_ = @import("compiler_rt/fixunssfdi.zig");
|
||||||
|
_ = @import("compiler_rt/fixunssfti.zig");
|
||||||
|
_ = @import("compiler_rt/fixunsdfsi.zig");
|
||||||
|
_ = @import("compiler_rt/fixunsdfdi.zig");
|
||||||
|
_ = @import("compiler_rt/fixunsdfti.zig");
|
||||||
|
_ = @import("compiler_rt/fixunstfsi.zig");
|
||||||
|
_ = @import("compiler_rt/fixunstfdi.zig");
|
||||||
|
_ = @import("compiler_rt/fixunstfti.zig");
|
||||||
|
_ = @import("compiler_rt/fixunsxfsi.zig");
|
||||||
|
_ = @import("compiler_rt/fixunsxfdi.zig");
|
||||||
|
_ = @import("compiler_rt/fixunsxfti.zig");
|
||||||
|
|
||||||
|
_ = @import("compiler_rt/count0bits.zig");
|
||||||
|
_ = @import("compiler_rt/parity.zig");
|
||||||
|
_ = @import("compiler_rt/popcount.zig");
|
||||||
|
_ = @import("compiler_rt/bswap.zig");
|
||||||
|
_ = @import("compiler_rt/int.zig");
|
||||||
|
_ = @import("compiler_rt/shift.zig");
|
||||||
|
|
||||||
|
_ = @import("compiler_rt/negXi2.zig");
|
||||||
|
|
||||||
|
_ = @import("compiler_rt/muldi3.zig");
|
||||||
|
|
||||||
|
_ = @import("compiler_rt/absv.zig");
|
||||||
|
_ = @import("compiler_rt/absvsi2.zig");
|
||||||
|
_ = @import("compiler_rt/absvdi2.zig");
|
||||||
|
_ = @import("compiler_rt/absvti2.zig");
|
||||||
|
|
||||||
|
_ = @import("compiler_rt/negv.zig");
|
||||||
|
_ = @import("compiler_rt/addo.zig");
|
||||||
|
_ = @import("compiler_rt/subo.zig");
|
||||||
|
_ = @import("compiler_rt/mulo.zig");
|
||||||
|
_ = @import("compiler_rt/cmp.zig");
|
||||||
|
|
||||||
|
_ = @import("compiler_rt/os_version_check.zig");
|
||||||
|
_ = @import("compiler_rt/emutls.zig");
|
||||||
|
_ = @import("compiler_rt/arm.zig");
|
||||||
|
_ = @import("compiler_rt/aulldiv.zig");
|
||||||
|
_ = @import("compiler_rt/aullrem.zig");
|
||||||
|
_ = @import("compiler_rt/clear_cache.zig");
|
||||||
|
}
|
||||||
267
lib/compiler_rt/README.md
Normal file
267
lib/compiler_rt/README.md
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
If hardware lacks basic or specialized functionality, compiler-rt adds such functionality
|
||||||
|
for basic arithmetic(s).
|
||||||
|
One such example is 64-bit integer multiplication on 32-bit x86.
|
||||||
|
|
||||||
|
Goals:
|
||||||
|
1. zig as linker for object files produced by other compilers
|
||||||
|
=> `function compatibility` to compiler-rt and libgcc for same-named functions
|
||||||
|
* compatibility conflict between compiler-rt and libgcc: prefer compiler-rt
|
||||||
|
2. `symbol-level compatibility` low-priority compared to emitted calls by llvm
|
||||||
|
* symbol-level compatibility: libgcc even lower priority
|
||||||
|
3. add zig-specific language runtime features, see #7265
|
||||||
|
* example: arbitrary bit width integer arithmetic
|
||||||
|
* lower to call those functions for e.g. multiplying two i12345 numbers together
|
||||||
|
* proper naming + documention for standardizing (allow languages to follow our exmaple)
|
||||||
|
|
||||||
|
Current status (tracking libgcc documentation):
|
||||||
|
- Integer library routines => almost implemented
|
||||||
|
- Soft float library routines => only f80 routines missing
|
||||||
|
- Decimal float library routines => unimplemented (~120 functions)
|
||||||
|
- Fixed-point fractional library routines => unimplemented (~300 functions)
|
||||||
|
- Exception handling routines => unclear, if supported (~32+x undocumented functions)
|
||||||
|
- Miscellaneous routines => unclear, if supported (cache control and stack function)
|
||||||
|
- No zig-specific language runtime features in compiler-rt yet
|
||||||
|
|
||||||
|
This library is automatically built as-needed for the compilation target and
|
||||||
|
then statically linked and therefore is a transparent dependency for the
|
||||||
|
programmer.
|
||||||
|
For details see `../compiler_rt.zig`.
|
||||||
|
|
||||||
|
The routines in this folder are listed below.
|
||||||
|
Routines are annotated as `type source routine // description`, with `routine`
|
||||||
|
being the name used in aforementioned `compiler_rt.zig`.
|
||||||
|
`dev` means deviating from compiler_rt, `port` ported, `source` is the
|
||||||
|
information source for the implementation, `none` means unimplemented.
|
||||||
|
Some examples for the naming convention are:
|
||||||
|
- dev source name_routine, name_routine2 various implementations for performance, simplicity etc
|
||||||
|
- port llvm compiler-rt library routines from [LLVM](http://compiler-rt.llvm.org/)
|
||||||
|
* LLVM emits library calls to compiler-rt, if the hardware lacks functionality
|
||||||
|
- port musl libc routines from [musl](https://musl.libc.org/)
|
||||||
|
If the library or information source is uncommon, use the entry `other` for `source`.
|
||||||
|
Please do not break the search by inserting entries in another format than `impl space source`.
|
||||||
|
|
||||||
|
Bugs should be solved by trying to duplicate the bug upstream, if possible.
|
||||||
|
* If the bug exists upstream, get it fixed upstream and port the fix downstream to Zig.
|
||||||
|
* If the bug only exists in Zig, use the corresponding C code and debug
|
||||||
|
both implementations side by side to figure out what is wrong.
|
||||||
|
|
||||||
|
## Integer library routines
|
||||||
|
|
||||||
|
#### Integer Bit operations
|
||||||
|
- dev HackersDelight __clzsi2 // count leading zeros
|
||||||
|
- dev HackersDelight __clzdi2 // count leading zeros
|
||||||
|
- dev HackersDelight __clzti2 // count leading zeros
|
||||||
|
- dev HackersDelight __ctzsi2 // count trailing zeros
|
||||||
|
- dev HackersDelight __ctzdi2 // count trailing zeros
|
||||||
|
- dev HackersDelight __ctzti2 // count trailing zeros
|
||||||
|
- dev __ctzsi2 __ffssi2 // find least significant 1 bit
|
||||||
|
- dev __ctzsi2 __ffsdi2 // find least significant 1 bit
|
||||||
|
- dev __ctzsi2 __ffsti2 // find least significant 1 bit
|
||||||
|
- dev BitTwiddlingHacks __paritysi2 // bit parity
|
||||||
|
- dev BitTwiddlingHacks __paritydi2 // bit parity
|
||||||
|
- dev BitTwiddlingHacks __parityti2 // bit parity
|
||||||
|
- dev TAOCP __popcountsi2 // bit population
|
||||||
|
- dev TAOCP __popcountdi2 // bit population
|
||||||
|
- dev TAOCP __popcountti2 // bit population
|
||||||
|
- dev other __bswapsi2 // a byteswapped
|
||||||
|
- dev other __bswapdi2 // a byteswapped
|
||||||
|
- dev other __bswapti2 // a byteswapped
|
||||||
|
|
||||||
|
#### Integer Comparison
|
||||||
|
- port llvm __cmpsi2 // (a<b)=>output=0, (a==b)=>output=1, (a>b)=>output=2
|
||||||
|
- port llvm __cmpdi2
|
||||||
|
- port llvm __cmpti2
|
||||||
|
- port llvm __ucmpsi2 // (a<b)=>output=0, (a==b)=>output=1, (a>b)=>output=2
|
||||||
|
- port llvm __ucmpdi2
|
||||||
|
- port llvm __ucmpti2
|
||||||
|
|
||||||
|
#### Integer Arithmetic
|
||||||
|
- none none __ashlsi3 // a << b unused in llvm, missing (e.g. used by rl78)
|
||||||
|
- port llvm __ashldi3 // a << b
|
||||||
|
- port llvm __ashlti3 // a << b
|
||||||
|
- none none __ashrsi3 // a >> b arithmetic (sign fill) missing (e.g. used by rl78)
|
||||||
|
- port llvm __ashrdi3 // a >> b arithmetic (sign fill)
|
||||||
|
- port llvm __ashrti3 // a >> b arithmetic (sign fill)
|
||||||
|
- none none __lshrsi3 // a >> b logical (zero fill) missing (e.g. used by rl78)
|
||||||
|
- port llvm __lshrdi3 // a >> b logical (zero fill)
|
||||||
|
- port llvm __lshrti3 // a >> b logical (zero fill)
|
||||||
|
- port llvm __negdi2 // -a symbol-level compatibility: libgcc
|
||||||
|
- port llvm __negti2 // -a unnecessary: unused in backends
|
||||||
|
- port llvm __mulsi3 // a * b signed
|
||||||
|
- port llvm __muldi3 // a * b signed
|
||||||
|
- port llvm __multi3 // a * b signed
|
||||||
|
- port llvm __divsi3 // a / b signed
|
||||||
|
- port llvm __divdi3 // a / b signed
|
||||||
|
- port llvm __divti3 // a / b signed
|
||||||
|
- port llvm __udivsi3 // a / b unsigned
|
||||||
|
- port llvm __udivdi3 // a / b unsigned
|
||||||
|
- port llvm __udivti3 // a / b unsigned
|
||||||
|
- port llvm __modsi3 // a % b signed
|
||||||
|
- port llvm __moddi3 // a % b signed
|
||||||
|
- port llvm __modti3 // a % b signed
|
||||||
|
- port llvm __umodsi3 // a % b unsigned
|
||||||
|
- port llvm __umoddi3 // a % b unsigned
|
||||||
|
- port llvm __umodti3 // a % b unsigned
|
||||||
|
- port llvm __udivmoddi4 // a / b, rem.* = a % b unsigned
|
||||||
|
- port llvm __udivmodti4 // a / b, rem.* = a % b unsigned
|
||||||
|
- port llvm __udivmodsi4 // a / b, rem.* = a % b unsigned
|
||||||
|
- port llvm __divmodsi4 // a / b, rem.* = a % b signed, ARM
|
||||||
|
|
||||||
|
#### Integer Arithmetic with trapping overflow
|
||||||
|
- dev BitTwiddlingHacks __absvsi2 // abs(a)
|
||||||
|
- dev BitTwiddlingHacks __absvdi2 // abs(a)
|
||||||
|
- dev BitTwiddlingHacks __absvti2 // abs(a)
|
||||||
|
- port llvm __negvsi2 // -a symbol-level compatibility: libgcc
|
||||||
|
- port llvm __negvdi2 // -a unnecessary: unused in backends
|
||||||
|
- port llvm __negvti2 // -a
|
||||||
|
- TODO upstreaming __addvsi3..__mulvti3 after testing panics works
|
||||||
|
- dev HackersDelight __addvsi3 // a + b
|
||||||
|
- dev HackersDelight __addvdi3 // a + b
|
||||||
|
- dev HackersDelight __addvti3 // a + b
|
||||||
|
- dev HackersDelight __subvsi3 // a - b
|
||||||
|
- dev HackersDelight __subvdi3 // a - b
|
||||||
|
- dev HackersDelight __subvti3 // a - b
|
||||||
|
- dev HackersDelight __mulvsi3 // a * b
|
||||||
|
- dev HackersDelight __mulvdi3 // a * b
|
||||||
|
- dev HackersDelight __mulvti3 // a * b
|
||||||
|
|
||||||
|
#### Integer Arithmetic which returns if overflow (would be faster without pointer)
|
||||||
|
- dev HackersDelight __addosi4 // a + b, overflow=>ov.*=1 else 0
|
||||||
|
- dev HackersDelight __addodi4 // (completeness + performance, llvm does not use them)
|
||||||
|
- dev HackersDelight __addoti4 //
|
||||||
|
- dev HackersDelight __subosi4 // a - b, overflow=>ov.*=1 else 0
|
||||||
|
- dev HackersDelight __subodi4 // (completeness + performance, llvm does not use them)
|
||||||
|
- dev HackersDelight __suboti4 //
|
||||||
|
- dev HackersDelight __mulosi4 // a * b, overflow=>ov.*=1 else 0
|
||||||
|
- dev HackersDelight __mulodi4 // (required by llvm)
|
||||||
|
- dev HackersDelight __muloti4 //
|
||||||
|
|
||||||
|
## Float library routines
|
||||||
|
|
||||||
|
#### Float Conversion
|
||||||
|
- todo todo __extendsfdf2 // extend a f32 => f64
|
||||||
|
- todo todo __extendsftf2 // extend a f32 => f128
|
||||||
|
- dev llvm __extendsfxf2 // extend a f32 => f80
|
||||||
|
- todo todo __extenddftf2 // extend a f64 => f128
|
||||||
|
- dev llvm __extenddfxf2 // extend a f64 => f80
|
||||||
|
- todo todo __truncdfsf2 // truncate a to narrower mode of return type, rounding towards zero
|
||||||
|
- todo todo __trunctfdf2 //
|
||||||
|
- todo todo __trunctfsf2 //
|
||||||
|
- dev llvm __truncxfsf2 //
|
||||||
|
- dev llvm __truncxfdf2 //
|
||||||
|
- todo todo __fixsfsi // convert a to i32, rounding towards zero
|
||||||
|
- todo todo __fixdfsi //
|
||||||
|
- todo todo __fixtfsi //
|
||||||
|
- todo todo __fixxfsi //
|
||||||
|
- todo todo __fixsfdi // convert a to i64, rounding towards zero
|
||||||
|
- todo todo __fixdfdi //
|
||||||
|
- todo todo __fixtfdi //
|
||||||
|
- todo todo __fixxfdi //
|
||||||
|
- todo todo __fixsfti // convert a to i128, rounding towards zero
|
||||||
|
- todo todo __fixdfti //
|
||||||
|
- todo todo __fixtfdi //
|
||||||
|
- todo todo __fixxfti //
|
||||||
|
|
||||||
|
- __fixunssfsi // convert to u32, rounding towards zero. negative values become 0.
|
||||||
|
- __fixunsdfsi //
|
||||||
|
- __fixunstfsi //
|
||||||
|
- __fixunsxfsi //
|
||||||
|
- __fixunssfdi // convert to u64, rounding towards zero. negative values become 0.
|
||||||
|
- __fixunsdfdi //
|
||||||
|
- __fixunstfdi //
|
||||||
|
- __fixunsxfdi //
|
||||||
|
- __fixunssfti // convert to u128, rounding towards zero. negative values become 0.
|
||||||
|
- __fixunsdfti //
|
||||||
|
- __fixunstfdi //
|
||||||
|
- __fixunsxfti //
|
||||||
|
|
||||||
|
- __floatsisf // convert i32 to floating point
|
||||||
|
- __floatsidf //
|
||||||
|
- __floatsitf //
|
||||||
|
- __floatsixf //
|
||||||
|
- __floatdisf // convert i64 to floating point
|
||||||
|
- __floatdidf //
|
||||||
|
- __floatditf //
|
||||||
|
- __floatdixf //
|
||||||
|
- __floattisf // convert i128 to floating point
|
||||||
|
- __floattidf //
|
||||||
|
- __floattixf //
|
||||||
|
|
||||||
|
- __floatunsisf // convert u32 to floating point
|
||||||
|
- __floatunsidf //
|
||||||
|
- __floatunsitf //
|
||||||
|
- __floatunsixf //
|
||||||
|
- __floatundisf // convert u64 to floating point
|
||||||
|
- __floatundidf //
|
||||||
|
- __floatunditf //
|
||||||
|
- __floatundixf //
|
||||||
|
- __floatuntisf // convert u128 to floating point
|
||||||
|
- __floatuntidf //
|
||||||
|
- __floatuntitf //
|
||||||
|
- __floatuntixf //
|
||||||
|
|
||||||
|
#### Float Comparison
|
||||||
|
- __cmpsf2 // return (a<b)=>-1,(a==b)=>0,(a>b)=>1,Nan=>1 dont rely on this
|
||||||
|
- __cmpdf2 // exported from __lesf2, __ledf2, __letf2 (below)
|
||||||
|
- __cmptf2 //
|
||||||
|
- __unordsf2 // (input==NaN) => out!=0 else out=0,
|
||||||
|
- __unorddf2 // __only reliable for (input!=Nan)__
|
||||||
|
- __unordtf2 //
|
||||||
|
- __eqsf2 // (a!=NaN) and (b!=Nan) and (a==b) => output=0
|
||||||
|
- __eqdf2 //
|
||||||
|
- __eqtf2 //
|
||||||
|
- __nesf2 // (a==NaN) or (b==Nan) or (a!=b) => output!=0
|
||||||
|
- __nedf2 //
|
||||||
|
- __netf2 //
|
||||||
|
- __gesf2 // (a!=Nan) and (b!=Nan) and (a>=b) => output>=0
|
||||||
|
- __gedf2 //
|
||||||
|
- __getf2 //
|
||||||
|
- __ltsf2 // (a!=Nan) and (b!=Nan) and (a<b) => output<0
|
||||||
|
- __ltdf2 //
|
||||||
|
- __lttf2 //
|
||||||
|
- __lesf2 // (a!=Nan) and (b!=Nan) and (a<=b) => output<=0
|
||||||
|
- __ledf2 //
|
||||||
|
- __letf2 //
|
||||||
|
- __gtsf2 // (a!=Nan) and (b!=Nan) and (a>b) => output>0
|
||||||
|
- __gtdf2 //
|
||||||
|
- __gttf2 //
|
||||||
|
|
||||||
|
#### Float Arithmetic
|
||||||
|
- __addsf3 // a + b f32
|
||||||
|
- __adddf3 // a + b f64
|
||||||
|
- __addtf3 // a + b f128
|
||||||
|
- __addxf3 // a + b f80
|
||||||
|
- __aeabi_fadd // a + b f64 ARM: AAPCS
|
||||||
|
- __aeabi_dadd // a + b f64 ARM: AAPCS
|
||||||
|
- __subsf3 // a - b
|
||||||
|
- __subdf3 // a - b
|
||||||
|
- __subtf3 // a - b
|
||||||
|
- __subxf3 // a - b f80
|
||||||
|
- __aeabi_fsub // a - b f64 ARM: AAPCS
|
||||||
|
- __aeabi_dsub // a - b f64 ARM: AAPCS
|
||||||
|
- __mulsf3 // a * b
|
||||||
|
- __muldf3 // a * b
|
||||||
|
- __multf3 // a * b
|
||||||
|
- __mulxf3 // a * b
|
||||||
|
- __divsf3 // a / b
|
||||||
|
- __divdf3 // a / b
|
||||||
|
- __divtf3 // a / b
|
||||||
|
- __divxf3 // a / b
|
||||||
|
- __negsf2 // -a symbol-level compatibility: libgcc uses this for the rl78
|
||||||
|
- __negdf2 // -a unnecessary: can be lowered directly to a xor
|
||||||
|
- __negtf2 // -a
|
||||||
|
- __negxf2 // -a
|
||||||
|
|
||||||
|
#### Floating point raised to integer power
|
||||||
|
- __powisf2 // unclear, if supported a ^ b
|
||||||
|
- __powidf2 //
|
||||||
|
- __powitf2 //
|
||||||
|
- __powixf2 //
|
||||||
|
- __mulsc3 // unsupported (a+ib) * (c+id)
|
||||||
|
- __muldc3 //
|
||||||
|
- __multc3 //
|
||||||
|
- __mulxc3 //
|
||||||
|
- __divsc3 // unsupported (a+ib) * / (c+id)
|
||||||
|
- __divdc3 //
|
||||||
|
- __divtc3 //
|
||||||
|
- __divxc3 //
|
||||||
@ -1,8 +1,6 @@
|
|||||||
// absv - absolute oVerflow
|
/// absv - absolute oVerflow
|
||||||
// * @panic, if value can not be represented
|
/// * @panic if value can not be represented
|
||||||
// - absvXi4_generic for unoptimized version
|
pub inline fn absv(comptime ST: type, a: ST) ST {
|
||||||
|
|
||||||
inline fn absvXi(comptime ST: type, a: ST) ST {
|
|
||||||
const UT = switch (ST) {
|
const UT = switch (ST) {
|
||||||
i32 => u32,
|
i32 => u32,
|
||||||
i64 => u64,
|
i64 => u64,
|
||||||
@ -21,18 +19,6 @@ inline fn absvXi(comptime ST: type, a: ST) ST {
|
|||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn __absvsi2(a: i32) callconv(.C) i32 {
|
|
||||||
return absvXi(i32, a);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn __absvdi2(a: i64) callconv(.C) i64 {
|
|
||||||
return absvXi(i64, a);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn __absvti2(a: i128) callconv(.C) i128 {
|
|
||||||
return absvXi(i128, a);
|
|
||||||
}
|
|
||||||
|
|
||||||
test {
|
test {
|
||||||
_ = @import("absvsi2_test.zig");
|
_ = @import("absvsi2_test.zig");
|
||||||
_ = @import("absvdi2_test.zig");
|
_ = @import("absvdi2_test.zig");
|
||||||
12
lib/compiler_rt/absvdi2.zig
Normal file
12
lib/compiler_rt/absvdi2.zig
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
const common = @import("./common.zig");
|
||||||
|
const absv = @import("./absv.zig").absv;
|
||||||
|
|
||||||
|
pub const panic = common.panic;
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
@export(__absvdi2, .{ .name = "__absvdi2", .linkage = common.linkage });
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __absvdi2(a: i64) callconv(.C) i64 {
|
||||||
|
return absv(i64, a);
|
||||||
|
}
|
||||||
@ -1,8 +1,9 @@
|
|||||||
const absv = @import("absv.zig");
|
|
||||||
const testing = @import("std").testing;
|
const testing = @import("std").testing;
|
||||||
|
|
||||||
|
const __absvdi2 = @import("absvdi2.zig").__absvdi2;
|
||||||
|
|
||||||
fn test__absvdi2(a: i64, expected: i64) !void {
|
fn test__absvdi2(a: i64, expected: i64) !void {
|
||||||
var result = absv.__absvdi2(a);
|
var result = __absvdi2(a);
|
||||||
try testing.expectEqual(expected, result);
|
try testing.expectEqual(expected, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
12
lib/compiler_rt/absvsi2.zig
Normal file
12
lib/compiler_rt/absvsi2.zig
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
const common = @import("./common.zig");
|
||||||
|
const absv = @import("./absv.zig").absv;
|
||||||
|
|
||||||
|
pub const panic = common.panic;
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
@export(__absvsi2, .{ .name = "__absvsi2", .linkage = common.linkage });
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __absvsi2(a: i32) callconv(.C) i32 {
|
||||||
|
return absv(i32, a);
|
||||||
|
}
|
||||||
@ -1,8 +1,9 @@
|
|||||||
const absv = @import("absv.zig");
|
|
||||||
const testing = @import("std").testing;
|
const testing = @import("std").testing;
|
||||||
|
|
||||||
|
const __absvsi2 = @import("absvsi2.zig").__absvsi2;
|
||||||
|
|
||||||
fn test__absvsi2(a: i32, expected: i32) !void {
|
fn test__absvsi2(a: i32, expected: i32) !void {
|
||||||
var result = absv.__absvsi2(a);
|
var result = __absvsi2(a);
|
||||||
try testing.expectEqual(expected, result);
|
try testing.expectEqual(expected, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
12
lib/compiler_rt/absvti2.zig
Normal file
12
lib/compiler_rt/absvti2.zig
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
const common = @import("./common.zig");
|
||||||
|
const absv = @import("./absv.zig").absv;
|
||||||
|
|
||||||
|
pub const panic = common.panic;
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
@export(__absvti2, .{ .name = "__absvti2", .linkage = common.linkage });
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __absvti2(a: i128) callconv(.C) i128 {
|
||||||
|
return absv(i128, a);
|
||||||
|
}
|
||||||
@ -1,8 +1,9 @@
|
|||||||
const absv = @import("absv.zig");
|
|
||||||
const testing = @import("std").testing;
|
const testing = @import("std").testing;
|
||||||
|
|
||||||
|
const __absvti2 = @import("absvti2.zig").__absvti2;
|
||||||
|
|
||||||
fn test__absvti2(a: i128, expected: i128) !void {
|
fn test__absvti2(a: i128, expected: i128) !void {
|
||||||
var result = absv.__absvti2(a);
|
var result = __absvti2(a);
|
||||||
try testing.expectEqual(expected, result);
|
try testing.expectEqual(expected, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
20
lib/compiler_rt/adddf3.zig
Normal file
20
lib/compiler_rt/adddf3.zig
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
const common = @import("./common.zig");
|
||||||
|
const addf3 = @import("./addf3.zig").addf3;
|
||||||
|
|
||||||
|
pub const panic = common.panic;
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
if (common.want_aeabi) {
|
||||||
|
@export(__aeabi_dadd, .{ .name = "__aeabi_dadd", .linkage = common.linkage });
|
||||||
|
} else {
|
||||||
|
@export(__adddf3, .{ .name = "__adddf3", .linkage = common.linkage });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __adddf3(a: f64, b: f64) callconv(.C) f64 {
|
||||||
|
return addf3(f64, a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __aeabi_dadd(a: f64, b: f64) callconv(.AAPCS) f64 {
|
||||||
|
return addf3(f64, a, b);
|
||||||
|
}
|
||||||
@ -1,98 +1,37 @@
|
|||||||
// Ported from:
|
|
||||||
//
|
|
||||||
// https://github.com/llvm/llvm-project/blob/02d85149a05cb1f6dc49f0ba7a2ceca53718ae17/compiler-rt/lib/builtins/fp_add_impl.inc
|
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const builtin = @import("builtin");
|
const math = std.math;
|
||||||
const compiler_rt = @import("../compiler_rt.zig");
|
const common = @import("./common.zig");
|
||||||
|
const normalize = common.normalize;
|
||||||
|
|
||||||
pub fn __addsf3(a: f32, b: f32) callconv(.C) f32 {
|
/// Ported from:
|
||||||
return addXf3(f32, a, b);
|
///
|
||||||
}
|
/// https://github.com/llvm/llvm-project/blob/02d85149a05cb1f6dc49f0ba7a2ceca53718ae17/compiler-rt/lib/builtins/fp_add_impl.inc
|
||||||
|
pub inline fn addf3(comptime T: type, a: T, b: T) T {
|
||||||
pub fn __adddf3(a: f64, b: f64) callconv(.C) f64 {
|
|
||||||
return addXf3(f64, a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn __addtf3(a: f128, b: f128) callconv(.C) f128 {
|
|
||||||
return addXf3(f128, a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn __subsf3(a: f32, b: f32) callconv(.C) f32 {
|
|
||||||
const neg_b = @bitCast(f32, @bitCast(u32, b) ^ (@as(u32, 1) << 31));
|
|
||||||
return addXf3(f32, a, neg_b);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn __subdf3(a: f64, b: f64) callconv(.C) f64 {
|
|
||||||
const neg_b = @bitCast(f64, @bitCast(u64, b) ^ (@as(u64, 1) << 63));
|
|
||||||
return addXf3(f64, a, neg_b);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn __subtf3(a: f128, b: f128) callconv(.C) f128 {
|
|
||||||
const neg_b = @bitCast(f128, @bitCast(u128, b) ^ (@as(u128, 1) << 127));
|
|
||||||
return addXf3(f128, a, neg_b);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn __aeabi_fadd(a: f32, b: f32) callconv(.AAPCS) f32 {
|
|
||||||
@setRuntimeSafety(false);
|
|
||||||
return @call(.{ .modifier = .always_inline }, __addsf3, .{ a, b });
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn __aeabi_dadd(a: f64, b: f64) callconv(.AAPCS) f64 {
|
|
||||||
@setRuntimeSafety(false);
|
|
||||||
return @call(.{ .modifier = .always_inline }, __adddf3, .{ a, b });
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn __aeabi_fsub(a: f32, b: f32) callconv(.AAPCS) f32 {
|
|
||||||
@setRuntimeSafety(false);
|
|
||||||
return @call(.{ .modifier = .always_inline }, __subsf3, .{ a, b });
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn __aeabi_dsub(a: f64, b: f64) callconv(.AAPCS) f64 {
|
|
||||||
@setRuntimeSafety(false);
|
|
||||||
return @call(.{ .modifier = .always_inline }, __subdf3, .{ a, b });
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154
|
|
||||||
fn normalize(comptime T: type, significand: *std.meta.Int(.unsigned, @typeInfo(T).Float.bits)) i32 {
|
|
||||||
const bits = @typeInfo(T).Float.bits;
|
|
||||||
const Z = std.meta.Int(.unsigned, bits);
|
|
||||||
const S = std.meta.Int(.unsigned, bits - @clz(Z, @as(Z, bits) - 1));
|
|
||||||
const significandBits = std.math.floatMantissaBits(T);
|
|
||||||
const implicitBit = @as(Z, 1) << significandBits;
|
|
||||||
|
|
||||||
const shift = @clz(std.meta.Int(.unsigned, bits), significand.*) - @clz(Z, implicitBit);
|
|
||||||
significand.* <<= @intCast(S, shift);
|
|
||||||
return 1 - shift;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154
|
|
||||||
fn addXf3(comptime T: type, a: T, b: T) T {
|
|
||||||
const bits = @typeInfo(T).Float.bits;
|
const bits = @typeInfo(T).Float.bits;
|
||||||
const Z = std.meta.Int(.unsigned, bits);
|
const Z = std.meta.Int(.unsigned, bits);
|
||||||
const S = std.meta.Int(.unsigned, bits - @clz(Z, @as(Z, bits) - 1));
|
const S = std.meta.Int(.unsigned, bits - @clz(Z, @as(Z, bits) - 1));
|
||||||
|
|
||||||
const typeWidth = bits;
|
const typeWidth = bits;
|
||||||
const significandBits = std.math.floatMantissaBits(T);
|
const significandBits = math.floatMantissaBits(T);
|
||||||
const exponentBits = std.math.floatExponentBits(T);
|
const fractionalBits = math.floatFractionalBits(T);
|
||||||
|
const exponentBits = math.floatExponentBits(T);
|
||||||
|
|
||||||
const signBit = (@as(Z, 1) << (significandBits + exponentBits));
|
const signBit = (@as(Z, 1) << (significandBits + exponentBits));
|
||||||
const maxExponent = ((1 << exponentBits) - 1);
|
const maxExponent = ((1 << exponentBits) - 1);
|
||||||
|
|
||||||
const implicitBit = (@as(Z, 1) << significandBits);
|
const integerBit = (@as(Z, 1) << fractionalBits);
|
||||||
const quietBit = implicitBit >> 1;
|
const quietBit = integerBit >> 1;
|
||||||
const significandMask = implicitBit - 1;
|
const significandMask = (@as(Z, 1) << significandBits) - 1;
|
||||||
|
|
||||||
const absMask = signBit - 1;
|
const absMask = signBit - 1;
|
||||||
const exponentMask = absMask ^ significandMask;
|
const qnanRep = @bitCast(Z, math.nan(T)) | quietBit;
|
||||||
const qnanRep = exponentMask | quietBit;
|
|
||||||
|
|
||||||
var aRep = @bitCast(Z, a);
|
var aRep = @bitCast(Z, a);
|
||||||
var bRep = @bitCast(Z, b);
|
var bRep = @bitCast(Z, b);
|
||||||
const aAbs = aRep & absMask;
|
const aAbs = aRep & absMask;
|
||||||
const bAbs = bRep & absMask;
|
const bAbs = bRep & absMask;
|
||||||
|
|
||||||
const infRep = @bitCast(Z, std.math.inf(T));
|
const infRep = @bitCast(Z, math.inf(T));
|
||||||
|
|
||||||
// Detect if a or b is zero, infinity, or NaN.
|
// Detect if a or b is zero, infinity, or NaN.
|
||||||
if (aAbs -% @as(Z, 1) >= infRep - @as(Z, 1) or
|
if (aAbs -% @as(Z, 1) >= infRep - @as(Z, 1) or
|
||||||
@ -157,12 +96,12 @@ fn addXf3(comptime T: type, a: T, b: T) T {
|
|||||||
// implicit significand bit. (If we fell through from the denormal path it
|
// implicit significand bit. (If we fell through from the denormal path it
|
||||||
// was already set by normalize( ), but setting it twice won't hurt
|
// was already set by normalize( ), but setting it twice won't hurt
|
||||||
// anything.)
|
// anything.)
|
||||||
aSignificand = (aSignificand | implicitBit) << 3;
|
aSignificand = (aSignificand | integerBit) << 3;
|
||||||
bSignificand = (bSignificand | implicitBit) << 3;
|
bSignificand = (bSignificand | integerBit) << 3;
|
||||||
|
|
||||||
// Shift the significand of b by the difference in exponents, with a sticky
|
// Shift the significand of b by the difference in exponents, with a sticky
|
||||||
// bottom bit to get rounding correct.
|
// bottom bit to get rounding correct.
|
||||||
const @"align" = @intCast(Z, aExponent - bExponent);
|
const @"align" = @intCast(u32, aExponent - bExponent);
|
||||||
if (@"align" != 0) {
|
if (@"align" != 0) {
|
||||||
if (@"align" < typeWidth) {
|
if (@"align" < typeWidth) {
|
||||||
const sticky = if (bSignificand << @intCast(S, typeWidth - @"align") != 0) @as(Z, 1) else 0;
|
const sticky = if (bSignificand << @intCast(S, typeWidth - @"align") != 0) @as(Z, 1) else 0;
|
||||||
@ -178,8 +117,8 @@ fn addXf3(comptime T: type, a: T, b: T) T {
|
|||||||
|
|
||||||
// If partial cancellation occured, we need to left-shift the result
|
// If partial cancellation occured, we need to left-shift the result
|
||||||
// and adjust the exponent:
|
// and adjust the exponent:
|
||||||
if (aSignificand < implicitBit << 3) {
|
if (aSignificand < integerBit << 3) {
|
||||||
const shift = @intCast(i32, @clz(Z, aSignificand)) - @intCast(i32, @clz(std.meta.Int(.unsigned, bits), implicitBit << 3));
|
const shift = @intCast(i32, @clz(Z, aSignificand)) - @intCast(i32, @clz(std.meta.Int(.unsigned, bits), integerBit << 3));
|
||||||
aSignificand <<= @intCast(S, shift);
|
aSignificand <<= @intCast(S, shift);
|
||||||
aExponent -= shift;
|
aExponent -= shift;
|
||||||
}
|
}
|
||||||
@ -188,7 +127,7 @@ fn addXf3(comptime T: type, a: T, b: T) T {
|
|||||||
|
|
||||||
// If the addition carried up, we need to right-shift the result and
|
// If the addition carried up, we need to right-shift the result and
|
||||||
// adjust the exponent:
|
// adjust the exponent:
|
||||||
if (aSignificand & (implicitBit << 4) != 0) {
|
if (aSignificand & (integerBit << 4) != 0) {
|
||||||
const sticky = aSignificand & 1;
|
const sticky = aSignificand & 1;
|
||||||
aSignificand = aSignificand >> 1 | sticky;
|
aSignificand = aSignificand >> 1 | sticky;
|
||||||
aExponent += 1;
|
aExponent += 1;
|
||||||
@ -199,18 +138,16 @@ fn addXf3(comptime T: type, a: T, b: T) T {
|
|||||||
if (aExponent >= maxExponent) return @bitCast(T, infRep | resultSign);
|
if (aExponent >= maxExponent) return @bitCast(T, infRep | resultSign);
|
||||||
|
|
||||||
if (aExponent <= 0) {
|
if (aExponent <= 0) {
|
||||||
// Result is denormal before rounding; the exponent is zero and we
|
// Result is denormal; the exponent and round/sticky bits are zero.
|
||||||
// need to shift the significand.
|
// All we need to do is shift the significand and apply the correct sign.
|
||||||
const shift = @intCast(Z, 1 - aExponent);
|
aSignificand >>= @intCast(S, 4 - aExponent);
|
||||||
const sticky = if (aSignificand << @intCast(S, typeWidth - shift) != 0) @as(Z, 1) else 0;
|
return @bitCast(T, resultSign | aSignificand);
|
||||||
aSignificand = aSignificand >> @intCast(S, shift | sticky);
|
|
||||||
aExponent = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Low three bits are round, guard, and sticky.
|
// Low three bits are round, guard, and sticky.
|
||||||
const roundGuardSticky = aSignificand & 0x7;
|
const roundGuardSticky = aSignificand & 0x7;
|
||||||
|
|
||||||
// Shift the significand into place, and mask off the implicit bit.
|
// Shift the significand into place, and mask off the integer bit, if it's implicit.
|
||||||
var result = (aSignificand >> 3) & significandMask;
|
var result = (aSignificand >> 3) & significandMask;
|
||||||
|
|
||||||
// Insert the exponent and sign.
|
// Insert the exponent and sign.
|
||||||
@ -222,9 +159,14 @@ fn addXf3(comptime T: type, a: T, b: T) T {
|
|||||||
if (roundGuardSticky > 0x4) result += 1;
|
if (roundGuardSticky > 0x4) result += 1;
|
||||||
if (roundGuardSticky == 0x4) result += result & 1;
|
if (roundGuardSticky == 0x4) result += result & 1;
|
||||||
|
|
||||||
|
// Restore any explicit integer bit, if it was rounded off
|
||||||
|
if (significandBits != fractionalBits) {
|
||||||
|
if ((result >> significandBits) != 0) result |= integerBit;
|
||||||
|
}
|
||||||
|
|
||||||
return @bitCast(T, result);
|
return @bitCast(T, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
test {
|
test {
|
||||||
_ = @import("addXf3_test.zig");
|
_ = @import("addf3_test.zig");
|
||||||
}
|
}
|
||||||
156
lib/compiler_rt/addf3_test.zig
Normal file
156
lib/compiler_rt/addf3_test.zig
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
// Ported from:
|
||||||
|
//
|
||||||
|
// https://github.com/llvm/llvm-project/blob/02d85149a05cb1f6dc49f0ba7a2ceca53718ae17/compiler-rt/test/builtins/Unit/addtf3_test.c
|
||||||
|
// https://github.com/llvm/llvm-project/blob/02d85149a05cb1f6dc49f0ba7a2ceca53718ae17/compiler-rt/test/builtins/Unit/subtf3_test.c
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const math = std.math;
|
||||||
|
const qnan128 = @bitCast(f128, @as(u128, 0x7fff800000000000) << 64);
|
||||||
|
|
||||||
|
const __addtf3 = @import("addtf3.zig").__addtf3;
|
||||||
|
const __addxf3 = @import("addxf3.zig").__addxf3;
|
||||||
|
const __subtf3 = @import("subtf3.zig").__subtf3;
|
||||||
|
|
||||||
|
fn test__addtf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void {
|
||||||
|
const x = __addtf3(a, b);
|
||||||
|
|
||||||
|
const rep = @bitCast(u128, x);
|
||||||
|
const hi = @intCast(u64, rep >> 64);
|
||||||
|
const lo = @truncate(u64, rep);
|
||||||
|
|
||||||
|
if (hi == expected_hi and lo == expected_lo) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// test other possible NaN representation (signal NaN)
|
||||||
|
else if (expected_hi == 0x7fff800000000000 and expected_lo == 0x0) {
|
||||||
|
if ((hi & 0x7fff000000000000) == 0x7fff000000000000 and
|
||||||
|
((hi & 0xffffffffffff) > 0 or lo > 0))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return error.TestFailed;
|
||||||
|
}
|
||||||
|
|
||||||
|
test "addtf3" {
|
||||||
|
try test__addtf3(qnan128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);
|
||||||
|
|
||||||
|
// NaN + any = NaN
|
||||||
|
try test__addtf3(@bitCast(f128, (@as(u128, 0x7fff000000000000) << 64) | @as(u128, 0x800030000000)), 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);
|
||||||
|
|
||||||
|
// inf + inf = inf
|
||||||
|
try test__addtf3(math.inf(f128), math.inf(f128), 0x7fff000000000000, 0x0);
|
||||||
|
|
||||||
|
// inf + any = inf
|
||||||
|
try test__addtf3(math.inf(f128), 0x1.2335653452436234723489432abcdefp+5, 0x7fff000000000000, 0x0);
|
||||||
|
|
||||||
|
// any + any
|
||||||
|
try test__addtf3(0x1.23456734245345543849abcdefp+5, 0x1.edcba52449872455634654321fp-1, 0x40042afc95c8b579, 0x61e58dd6c51eb77c);
|
||||||
|
try test__addtf3(0x1.edcba52449872455634654321fp-1, 0x1.23456734245345543849abcdefp+5, 0x40042afc95c8b579, 0x61e58dd6c51eb77c);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test__subtf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void {
|
||||||
|
const x = __subtf3(a, b);
|
||||||
|
|
||||||
|
const rep = @bitCast(u128, x);
|
||||||
|
const hi = @intCast(u64, rep >> 64);
|
||||||
|
const lo = @truncate(u64, rep);
|
||||||
|
|
||||||
|
if (hi == expected_hi and lo == expected_lo) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// test other possible NaN representation (signal NaN)
|
||||||
|
else if (expected_hi == 0x7fff800000000000 and expected_lo == 0x0) {
|
||||||
|
if ((hi & 0x7fff000000000000) == 0x7fff000000000000 and
|
||||||
|
((hi & 0xffffffffffff) > 0 or lo > 0))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return error.TestFailed;
|
||||||
|
}
|
||||||
|
|
||||||
|
test "subtf3" {
|
||||||
|
// qNaN - any = qNaN
|
||||||
|
try test__subtf3(qnan128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);
|
||||||
|
|
||||||
|
// NaN + any = NaN
|
||||||
|
try test__subtf3(@bitCast(f128, (@as(u128, 0x7fff000000000000) << 64) | @as(u128, 0x800030000000)), 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);
|
||||||
|
|
||||||
|
// inf - any = inf
|
||||||
|
try test__subtf3(math.inf(f128), 0x1.23456789abcdefp+5, 0x7fff000000000000, 0x0);
|
||||||
|
|
||||||
|
// any + any
|
||||||
|
try test__subtf3(0x1.234567829a3bcdef5678ade36734p+5, 0x1.ee9d7c52354a6936ab8d7654321fp-1, 0x40041b8af1915166, 0xa44a7bca780a166c);
|
||||||
|
try test__subtf3(0x1.ee9d7c52354a6936ab8d7654321fp-1, 0x1.234567829a3bcdef5678ade36734p+5, 0xc0041b8af1915166, 0xa44a7bca780a166c);
|
||||||
|
}
|
||||||
|
|
||||||
|
const qnan80 = @bitCast(f80, @bitCast(u80, math.nan(f80)) | (1 << (math.floatFractionalBits(f80) - 1)));
|
||||||
|
|
||||||
|
fn test__addxf3(a: f80, b: f80, expected: u80) !void {
|
||||||
|
const x = __addxf3(a, b);
|
||||||
|
const rep = @bitCast(u80, x);
|
||||||
|
|
||||||
|
if (rep == expected)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (math.isNan(@bitCast(f80, expected)) and math.isNan(x))
|
||||||
|
return; // We don't currently test NaN payload propagation
|
||||||
|
|
||||||
|
return error.TestFailed;
|
||||||
|
}
|
||||||
|
|
||||||
|
test "addxf3" {
|
||||||
|
// NaN + any = NaN
|
||||||
|
try test__addxf3(qnan80, 0x1.23456789abcdefp+5, @bitCast(u80, qnan80));
|
||||||
|
try test__addxf3(@bitCast(f80, @as(u80, 0x7fff_8000_8000_3000_0000)), 0x1.23456789abcdefp+5, @bitCast(u80, qnan80));
|
||||||
|
|
||||||
|
// any + NaN = NaN
|
||||||
|
try test__addxf3(0x1.23456789abcdefp+5, qnan80, @bitCast(u80, qnan80));
|
||||||
|
try test__addxf3(0x1.23456789abcdefp+5, @bitCast(f80, @as(u80, 0x7fff_8000_8000_3000_0000)), @bitCast(u80, qnan80));
|
||||||
|
|
||||||
|
// NaN + inf = NaN
|
||||||
|
try test__addxf3(qnan80, math.inf(f80), @bitCast(u80, qnan80));
|
||||||
|
|
||||||
|
// inf + NaN = NaN
|
||||||
|
try test__addxf3(math.inf(f80), qnan80, @bitCast(u80, qnan80));
|
||||||
|
|
||||||
|
// inf + inf = inf
|
||||||
|
try test__addxf3(math.inf(f80), math.inf(f80), @bitCast(u80, math.inf(f80)));
|
||||||
|
|
||||||
|
// inf + -inf = NaN
|
||||||
|
try test__addxf3(math.inf(f80), -math.inf(f80), @bitCast(u80, qnan80));
|
||||||
|
|
||||||
|
// -inf + inf = NaN
|
||||||
|
try test__addxf3(-math.inf(f80), math.inf(f80), @bitCast(u80, qnan80));
|
||||||
|
|
||||||
|
// inf + any = inf
|
||||||
|
try test__addxf3(math.inf(f80), 0x1.2335653452436234723489432abcdefp+5, @bitCast(u80, math.inf(f80)));
|
||||||
|
|
||||||
|
// any + inf = inf
|
||||||
|
try test__addxf3(0x1.2335653452436234723489432abcdefp+5, math.inf(f80), @bitCast(u80, math.inf(f80)));
|
||||||
|
|
||||||
|
// any + any
|
||||||
|
try test__addxf3(0x1.23456789abcdp+5, 0x1.dcba987654321p+5, 0x4005_BFFFFFFFFFFFC400);
|
||||||
|
try test__addxf3(0x1.23456734245345543849abcdefp+5, 0x1.edcba52449872455634654321fp-1, 0x4004_957E_4AE4_5ABC_B0F3);
|
||||||
|
try test__addxf3(0x1.ffff_ffff_ffff_fffcp+0, 0x1.0p-63, 0x3FFF_FFFFFFFFFFFFFFFF); // exact
|
||||||
|
try test__addxf3(0x1.ffff_ffff_ffff_fffep+0, 0x0.0p0, 0x3FFF_FFFFFFFFFFFFFFFF); // exact
|
||||||
|
try test__addxf3(0x1.ffff_ffff_ffff_fffcp+0, 0x1.4p-63, 0x3FFF_FFFFFFFFFFFFFFFF); // round down
|
||||||
|
try test__addxf3(0x1.ffff_ffff_ffff_fffcp+0, 0x1.8p-63, 0x4000_8000000000000000); // round up to even
|
||||||
|
try test__addxf3(0x1.ffff_ffff_ffff_fffcp+0, 0x1.cp-63, 0x4000_8000000000000000); // round up
|
||||||
|
try test__addxf3(0x1.ffff_ffff_ffff_fffcp+0, 0x2.0p-63, 0x4000_8000000000000000); // exact
|
||||||
|
try test__addxf3(0x1.ffff_ffff_ffff_fffcp+0, 0x2.1p-63, 0x4000_8000000000000000); // round down
|
||||||
|
try test__addxf3(0x1.ffff_ffff_ffff_fffcp+0, 0x3.0p-63, 0x4000_8000000000000000); // round down to even
|
||||||
|
try test__addxf3(0x1.ffff_ffff_ffff_fffcp+0, 0x3.1p-63, 0x4000_8000000000000001); // round up
|
||||||
|
try test__addxf3(0x1.ffff_ffff_ffff_fffcp+0, 0x4.0p-63, 0x4000_8000000000000001); // exact
|
||||||
|
|
||||||
|
try test__addxf3(0x1.0fff_ffff_ffff_fffep+0, 0x1.0p-63, 0x3FFF_8800000000000000); // exact
|
||||||
|
try test__addxf3(0x1.0fff_ffff_ffff_fffep+0, 0x1.7p-63, 0x3FFF_8800000000000000); // round down
|
||||||
|
try test__addxf3(0x1.0fff_ffff_ffff_fffep+0, 0x1.8p-63, 0x3FFF_8800000000000000); // round down to even
|
||||||
|
try test__addxf3(0x1.0fff_ffff_ffff_fffep+0, 0x1.9p-63, 0x3FFF_8800000000000001); // round up
|
||||||
|
try test__addxf3(0x1.0fff_ffff_ffff_fffep+0, 0x2.0p-63, 0x3FFF_8800000000000001); // exact
|
||||||
|
try test__addxf3(0x0.ffff_ffff_ffff_fffcp-16382, 0x0.0000_0000_0000_0002p-16382, 0x0000_7FFFFFFFFFFFFFFF); // exact
|
||||||
|
try test__addxf3(0x0.1fff_ffff_ffff_fffcp-16382, 0x0.0000_0000_0000_0002p-16382, 0x0000_0FFFFFFFFFFFFFFF); // exact
|
||||||
|
}
|
||||||
48
lib/compiler_rt/addo.zig
Normal file
48
lib/compiler_rt/addo.zig
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const builtin = @import("builtin");
|
||||||
|
const is_test = builtin.is_test;
|
||||||
|
const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
|
||||||
|
pub const panic = @import("common.zig").panic;
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
@export(__addosi4, .{ .name = "__addosi4", .linkage = linkage });
|
||||||
|
@export(__addodi4, .{ .name = "__addodi4", .linkage = linkage });
|
||||||
|
@export(__addoti4, .{ .name = "__addoti4", .linkage = linkage });
|
||||||
|
}
|
||||||
|
|
||||||
|
// addo - add overflow
|
||||||
|
// * return a+%b.
|
||||||
|
// * return if a+b overflows => 1 else => 0
|
||||||
|
// - addoXi4_generic as default
|
||||||
|
|
||||||
|
inline fn addoXi4_generic(comptime ST: type, a: ST, b: ST, overflow: *c_int) ST {
|
||||||
|
@setRuntimeSafety(builtin.is_test);
|
||||||
|
overflow.* = 0;
|
||||||
|
var sum: ST = a +% b;
|
||||||
|
// Hackers Delight: section Overflow Detection, subsection Signed Add/Subtract
|
||||||
|
// Let sum = a +% b == a + b + carry == wraparound addition.
|
||||||
|
// Overflow in a+b+carry occurs, iff a and b have opposite signs
|
||||||
|
// and the sign of a+b+carry is the same as a (or equivalently b).
|
||||||
|
// Slower routine: res = ~(a ^ b) & ((sum ^ a)
|
||||||
|
// Faster routine: res = (sum ^ a) & (sum ^ b)
|
||||||
|
// Overflow occured, iff (res < 0)
|
||||||
|
if (((sum ^ a) & (sum ^ b)) < 0)
|
||||||
|
overflow.* = 1;
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __addosi4(a: i32, b: i32, overflow: *c_int) callconv(.C) i32 {
|
||||||
|
return addoXi4_generic(i32, a, b, overflow);
|
||||||
|
}
|
||||||
|
pub fn __addodi4(a: i64, b: i64, overflow: *c_int) callconv(.C) i64 {
|
||||||
|
return addoXi4_generic(i64, a, b, overflow);
|
||||||
|
}
|
||||||
|
pub fn __addoti4(a: i128, b: i128, overflow: *c_int) callconv(.C) i128 {
|
||||||
|
return addoXi4_generic(i128, a, b, overflow);
|
||||||
|
}
|
||||||
|
|
||||||
|
test {
|
||||||
|
_ = @import("addosi4_test.zig");
|
||||||
|
_ = @import("addodi4_test.zig");
|
||||||
|
_ = @import("addoti4_test.zig");
|
||||||
|
}
|
||||||
77
lib/compiler_rt/addodi4_test.zig
Normal file
77
lib/compiler_rt/addodi4_test.zig
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
const addv = @import("addo.zig");
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
const math = std.math;
|
||||||
|
|
||||||
|
fn test__addodi4(a: i64, b: i64) !void {
|
||||||
|
var result_ov: c_int = undefined;
|
||||||
|
var expected_ov: c_int = undefined;
|
||||||
|
var result = addv.__addodi4(a, b, &result_ov);
|
||||||
|
var expected: i64 = simple_addodi4(a, b, &expected_ov);
|
||||||
|
try testing.expectEqual(expected, result);
|
||||||
|
try testing.expectEqual(expected_ov, result_ov);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn simple_addodi4(a: i64, b: i64, overflow: *c_int) i64 {
|
||||||
|
overflow.* = 0;
|
||||||
|
const min: i64 = math.minInt(i64);
|
||||||
|
const max: i64 = math.maxInt(i64);
|
||||||
|
if (((a > 0) and (b > max - a)) or
|
||||||
|
((a < 0) and (b < min - a)))
|
||||||
|
overflow.* = 1;
|
||||||
|
return a +% b;
|
||||||
|
}
|
||||||
|
|
||||||
|
test "addodi4" {
|
||||||
|
const min: i64 = math.minInt(i64);
|
||||||
|
const max: i64 = math.maxInt(i64);
|
||||||
|
var i: i64 = 1;
|
||||||
|
while (i < max) : (i *|= 2) {
|
||||||
|
try test__addodi4(i, i);
|
||||||
|
try test__addodi4(-i, -i);
|
||||||
|
try test__addodi4(i, -i);
|
||||||
|
try test__addodi4(-i, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// edge cases
|
||||||
|
// 0 + 0 = 0
|
||||||
|
// MIN + MIN overflow
|
||||||
|
// MAX + MAX overflow
|
||||||
|
// 0 + MIN MIN
|
||||||
|
// 0 + MAX MAX
|
||||||
|
// MIN + 0 MIN
|
||||||
|
// MAX + 0 MAX
|
||||||
|
// MIN + MAX -1
|
||||||
|
// MAX + MIN -1
|
||||||
|
try test__addodi4(0, 0);
|
||||||
|
try test__addodi4(min, min);
|
||||||
|
try test__addodi4(max, max);
|
||||||
|
try test__addodi4(0, min);
|
||||||
|
try test__addodi4(0, max);
|
||||||
|
try test__addodi4(min, 0);
|
||||||
|
try test__addodi4(max, 0);
|
||||||
|
try test__addodi4(min, max);
|
||||||
|
try test__addodi4(max, min);
|
||||||
|
|
||||||
|
// derived edge cases
|
||||||
|
// MIN+1 + MIN overflow
|
||||||
|
// MAX-1 + MAX overflow
|
||||||
|
// 1 + MIN = MIN+1
|
||||||
|
// -1 + MIN overflow
|
||||||
|
// -1 + MAX = MAX-1
|
||||||
|
// +1 + MAX overflow
|
||||||
|
// MIN + 1 = MIN+1
|
||||||
|
// MIN + -1 overflow
|
||||||
|
// MAX + 1 overflow
|
||||||
|
// MAX + -1 = MAX-1
|
||||||
|
try test__addodi4(min + 1, min);
|
||||||
|
try test__addodi4(max - 1, max);
|
||||||
|
try test__addodi4(1, min);
|
||||||
|
try test__addodi4(-1, min);
|
||||||
|
try test__addodi4(-1, max);
|
||||||
|
try test__addodi4(1, max);
|
||||||
|
try test__addodi4(min, 1);
|
||||||
|
try test__addodi4(min, -1);
|
||||||
|
try test__addodi4(max, -1);
|
||||||
|
try test__addodi4(max, 1);
|
||||||
|
}
|
||||||
78
lib/compiler_rt/addosi4_test.zig
Normal file
78
lib/compiler_rt/addosi4_test.zig
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
const addv = @import("addo.zig");
|
||||||
|
const testing = @import("std").testing;
|
||||||
|
|
||||||
|
fn test__addosi4(a: i32, b: i32) !void {
|
||||||
|
var result_ov: c_int = undefined;
|
||||||
|
var expected_ov: c_int = undefined;
|
||||||
|
var result = addv.__addosi4(a, b, &result_ov);
|
||||||
|
var expected: i32 = simple_addosi4(a, b, &expected_ov);
|
||||||
|
try testing.expectEqual(expected, result);
|
||||||
|
try testing.expectEqual(expected_ov, result_ov);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn simple_addosi4(a: i32, b: i32, overflow: *c_int) i32 {
|
||||||
|
overflow.* = 0;
|
||||||
|
const min: i32 = -2147483648;
|
||||||
|
const max: i32 = 2147483647;
|
||||||
|
if (((a > 0) and (b > max - a)) or
|
||||||
|
((a < 0) and (b < min - a)))
|
||||||
|
overflow.* = 1;
|
||||||
|
return a +% b;
|
||||||
|
}
|
||||||
|
|
||||||
|
test "addosi4" {
|
||||||
|
// -2^31 <= i32 <= 2^31-1
|
||||||
|
// 2^31 = 2147483648
|
||||||
|
// 2^31-1 = 2147483647
|
||||||
|
const min: i32 = -2147483648;
|
||||||
|
const max: i32 = 2147483647;
|
||||||
|
var i: i32 = 1;
|
||||||
|
while (i < max) : (i *|= 2) {
|
||||||
|
try test__addosi4(i, i);
|
||||||
|
try test__addosi4(-i, -i);
|
||||||
|
try test__addosi4(i, -i);
|
||||||
|
try test__addosi4(-i, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// edge cases
|
||||||
|
// 0 + 0 = 0
|
||||||
|
// MIN + MIN overflow
|
||||||
|
// MAX + MAX overflow
|
||||||
|
// 0 + MIN MIN
|
||||||
|
// 0 + MAX MAX
|
||||||
|
// MIN + 0 MIN
|
||||||
|
// MAX + 0 MAX
|
||||||
|
// MIN + MAX -1
|
||||||
|
// MAX + MIN -1
|
||||||
|
try test__addosi4(0, 0);
|
||||||
|
try test__addosi4(min, min);
|
||||||
|
try test__addosi4(max, max);
|
||||||
|
try test__addosi4(0, min);
|
||||||
|
try test__addosi4(0, max);
|
||||||
|
try test__addosi4(min, 0);
|
||||||
|
try test__addosi4(max, 0);
|
||||||
|
try test__addosi4(min, max);
|
||||||
|
try test__addosi4(max, min);
|
||||||
|
|
||||||
|
// derived edge cases
|
||||||
|
// MIN+1 + MIN overflow
|
||||||
|
// MAX-1 + MAX overflow
|
||||||
|
// 1 + MIN = MIN+1
|
||||||
|
// -1 + MIN overflow
|
||||||
|
// -1 + MAX = MAX-1
|
||||||
|
// +1 + MAX overflow
|
||||||
|
// MIN + 1 = MIN+1
|
||||||
|
// MIN + -1 overflow
|
||||||
|
// MAX + 1 overflow
|
||||||
|
// MAX + -1 = MAX-1
|
||||||
|
try test__addosi4(min + 1, min);
|
||||||
|
try test__addosi4(max - 1, max);
|
||||||
|
try test__addosi4(1, min);
|
||||||
|
try test__addosi4(-1, min);
|
||||||
|
try test__addosi4(-1, max);
|
||||||
|
try test__addosi4(1, max);
|
||||||
|
try test__addosi4(min, 1);
|
||||||
|
try test__addosi4(min, -1);
|
||||||
|
try test__addosi4(max, -1);
|
||||||
|
try test__addosi4(max, 1);
|
||||||
|
}
|
||||||
77
lib/compiler_rt/addoti4_test.zig
Normal file
77
lib/compiler_rt/addoti4_test.zig
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
const addv = @import("addo.zig");
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
const math = std.math;
|
||||||
|
|
||||||
|
fn test__addoti4(a: i128, b: i128) !void {
|
||||||
|
var result_ov: c_int = undefined;
|
||||||
|
var expected_ov: c_int = undefined;
|
||||||
|
var result = addv.__addoti4(a, b, &result_ov);
|
||||||
|
var expected: i128 = simple_addoti4(a, b, &expected_ov);
|
||||||
|
try testing.expectEqual(expected, result);
|
||||||
|
try testing.expectEqual(expected_ov, result_ov);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn simple_addoti4(a: i128, b: i128, overflow: *c_int) i128 {
|
||||||
|
overflow.* = 0;
|
||||||
|
const min: i128 = math.minInt(i128);
|
||||||
|
const max: i128 = math.maxInt(i128);
|
||||||
|
if (((a > 0) and (b > max - a)) or
|
||||||
|
((a < 0) and (b < min - a)))
|
||||||
|
overflow.* = 1;
|
||||||
|
return a +% b;
|
||||||
|
}
|
||||||
|
|
||||||
|
test "addoti4" {
|
||||||
|
const min: i128 = math.minInt(i128);
|
||||||
|
const max: i128 = math.maxInt(i128);
|
||||||
|
var i: i128 = 1;
|
||||||
|
while (i < max) : (i *|= 2) {
|
||||||
|
try test__addoti4(i, i);
|
||||||
|
try test__addoti4(-i, -i);
|
||||||
|
try test__addoti4(i, -i);
|
||||||
|
try test__addoti4(-i, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// edge cases
|
||||||
|
// 0 + 0 = 0
|
||||||
|
// MIN + MIN overflow
|
||||||
|
// MAX + MAX overflow
|
||||||
|
// 0 + MIN MIN
|
||||||
|
// 0 + MAX MAX
|
||||||
|
// MIN + 0 MIN
|
||||||
|
// MAX + 0 MAX
|
||||||
|
// MIN + MAX -1
|
||||||
|
// MAX + MIN -1
|
||||||
|
try test__addoti4(0, 0);
|
||||||
|
try test__addoti4(min, min);
|
||||||
|
try test__addoti4(max, max);
|
||||||
|
try test__addoti4(0, min);
|
||||||
|
try test__addoti4(0, max);
|
||||||
|
try test__addoti4(min, 0);
|
||||||
|
try test__addoti4(max, 0);
|
||||||
|
try test__addoti4(min, max);
|
||||||
|
try test__addoti4(max, min);
|
||||||
|
|
||||||
|
// derived edge cases
|
||||||
|
// MIN+1 + MIN overflow
|
||||||
|
// MAX-1 + MAX overflow
|
||||||
|
// 1 + MIN = MIN+1
|
||||||
|
// -1 + MIN overflow
|
||||||
|
// -1 + MAX = MAX-1
|
||||||
|
// +1 + MAX overflow
|
||||||
|
// MIN + 1 = MIN+1
|
||||||
|
// MIN + -1 overflow
|
||||||
|
// MAX + 1 overflow
|
||||||
|
// MAX + -1 = MAX-1
|
||||||
|
try test__addoti4(min + 1, min);
|
||||||
|
try test__addoti4(max - 1, max);
|
||||||
|
try test__addoti4(1, min);
|
||||||
|
try test__addoti4(-1, min);
|
||||||
|
try test__addoti4(-1, max);
|
||||||
|
try test__addoti4(1, max);
|
||||||
|
try test__addoti4(min, 1);
|
||||||
|
try test__addoti4(min, -1);
|
||||||
|
try test__addoti4(max, -1);
|
||||||
|
try test__addoti4(max, 1);
|
||||||
|
}
|
||||||
20
lib/compiler_rt/addsf3.zig
Normal file
20
lib/compiler_rt/addsf3.zig
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
const common = @import("./common.zig");
|
||||||
|
const addf3 = @import("./addf3.zig").addf3;
|
||||||
|
|
||||||
|
pub const panic = common.panic;
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
if (common.want_aeabi) {
|
||||||
|
@export(__aeabi_fadd, .{ .name = "__aeabi_fadd", .linkage = common.linkage });
|
||||||
|
} else {
|
||||||
|
@export(__addsf3, .{ .name = "__addsf3", .linkage = common.linkage });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __addsf3(a: f32, b: f32) callconv(.C) f32 {
|
||||||
|
return addf3(f32, a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __aeabi_fadd(a: f32, b: f32) callconv(.AAPCS) f32 {
|
||||||
|
return addf3(f32, a, b);
|
||||||
|
}
|
||||||
26
lib/compiler_rt/addtf3.zig
Normal file
26
lib/compiler_rt/addtf3.zig
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
const common = @import("./common.zig");
|
||||||
|
const addf3 = @import("./addf3.zig").addf3;
|
||||||
|
|
||||||
|
pub const panic = common.panic;
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
if (common.want_ppc_abi) {
|
||||||
|
@export(__addkf3, .{ .name = "__addkf3", .linkage = common.linkage });
|
||||||
|
} else if (common.want_sparc_abi) {
|
||||||
|
@export(_Qp_add, .{ .name = "_Qp_add", .linkage = common.linkage });
|
||||||
|
} else {
|
||||||
|
@export(__addtf3, .{ .name = "__addtf3", .linkage = common.linkage });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __addtf3(a: f128, b: f128) callconv(.C) f128 {
|
||||||
|
return addf3(f128, a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __addkf3(a: f128, b: f128) callconv(.C) f128 {
|
||||||
|
return addf3(f128, a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _Qp_add(c: *f128, a: *f128, b: *f128) callconv(.C) void {
|
||||||
|
c.* = addf3(f128, a.*, b.*);
|
||||||
|
}
|
||||||
12
lib/compiler_rt/addxf3.zig
Normal file
12
lib/compiler_rt/addxf3.zig
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
const common = @import("./common.zig");
|
||||||
|
const addf3 = @import("./addf3.zig").addf3;
|
||||||
|
|
||||||
|
pub const panic = common.panic;
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
@export(__addxf3, .{ .name = "__addxf3", .linkage = common.linkage });
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __addxf3(a: f80, b: f80) callconv(.C) f80 {
|
||||||
|
return addf3(f80, a, b);
|
||||||
|
}
|
||||||
188
lib/compiler_rt/arm.zig
Normal file
188
lib/compiler_rt/arm.zig
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
// ARM specific builtins
|
||||||
|
const std = @import("std");
|
||||||
|
const builtin = @import("builtin");
|
||||||
|
const arch = builtin.cpu.arch;
|
||||||
|
const common = @import("common.zig");
|
||||||
|
|
||||||
|
pub const panic = common.panic;
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
if (!builtin.is_test) {
|
||||||
|
if (arch.isARM() or arch.isThumb()) {
|
||||||
|
@export(__aeabi_unwind_cpp_pr0, .{ .name = "__aeabi_unwind_cpp_pr0", .linkage = common.linkage });
|
||||||
|
@export(__aeabi_unwind_cpp_pr1, .{ .name = "__aeabi_unwind_cpp_pr1", .linkage = common.linkage });
|
||||||
|
@export(__aeabi_unwind_cpp_pr2, .{ .name = "__aeabi_unwind_cpp_pr2", .linkage = common.linkage });
|
||||||
|
|
||||||
|
@export(__aeabi_ldivmod, .{ .name = "__aeabi_ldivmod", .linkage = common.linkage });
|
||||||
|
@export(__aeabi_uldivmod, .{ .name = "__aeabi_uldivmod", .linkage = common.linkage });
|
||||||
|
|
||||||
|
@export(__aeabi_idivmod, .{ .name = "__aeabi_idivmod", .linkage = common.linkage });
|
||||||
|
@export(__aeabi_uidivmod, .{ .name = "__aeabi_uidivmod", .linkage = common.linkage });
|
||||||
|
|
||||||
|
@export(__aeabi_memcpy, .{ .name = "__aeabi_memcpy", .linkage = common.linkage });
|
||||||
|
@export(__aeabi_memcpy4, .{ .name = "__aeabi_memcpy4", .linkage = common.linkage });
|
||||||
|
@export(__aeabi_memcpy8, .{ .name = "__aeabi_memcpy8", .linkage = common.linkage });
|
||||||
|
|
||||||
|
@export(__aeabi_memmove, .{ .name = "__aeabi_memmove", .linkage = common.linkage });
|
||||||
|
@export(__aeabi_memmove4, .{ .name = "__aeabi_memmove4", .linkage = common.linkage });
|
||||||
|
@export(__aeabi_memmove8, .{ .name = "__aeabi_memmove8", .linkage = common.linkage });
|
||||||
|
|
||||||
|
@export(__aeabi_memset, .{ .name = "__aeabi_memset", .linkage = common.linkage });
|
||||||
|
@export(__aeabi_memset4, .{ .name = "__aeabi_memset4", .linkage = common.linkage });
|
||||||
|
@export(__aeabi_memset8, .{ .name = "__aeabi_memset8", .linkage = common.linkage });
|
||||||
|
|
||||||
|
@export(__aeabi_memclr, .{ .name = "__aeabi_memclr", .linkage = common.linkage });
|
||||||
|
@export(__aeabi_memclr4, .{ .name = "__aeabi_memclr4", .linkage = common.linkage });
|
||||||
|
@export(__aeabi_memclr8, .{ .name = "__aeabi_memclr8", .linkage = common.linkage });
|
||||||
|
|
||||||
|
if (builtin.os.tag == .linux) {
|
||||||
|
@export(__aeabi_read_tp, .{ .name = "__aeabi_read_tp", .linkage = common.linkage });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const __divmodsi4 = @import("int.zig").__divmodsi4;
|
||||||
|
const __udivmodsi4 = @import("int.zig").__udivmodsi4;
|
||||||
|
const __divmoddi4 = @import("int.zig").__divmoddi4;
|
||||||
|
const __udivmoddi4 = @import("int.zig").__udivmoddi4;
|
||||||
|
|
||||||
|
extern fn memset(dest: ?[*]u8, c: u8, n: usize) ?[*]u8;
|
||||||
|
extern fn memcpy(noalias dest: ?[*]u8, noalias src: ?[*]const u8, n: usize) ?[*]u8;
|
||||||
|
extern fn memmove(dest: ?[*]u8, src: ?[*]const u8, n: usize) ?[*]u8;
|
||||||
|
|
||||||
|
pub fn __aeabi_memcpy(dest: [*]u8, src: [*]u8, n: usize) callconv(.AAPCS) void {
|
||||||
|
@setRuntimeSafety(false);
|
||||||
|
_ = memcpy(dest, src, n);
|
||||||
|
}
|
||||||
|
pub fn __aeabi_memcpy4(dest: [*]u8, src: [*]u8, n: usize) callconv(.AAPCS) void {
|
||||||
|
@setRuntimeSafety(false);
|
||||||
|
_ = memcpy(dest, src, n);
|
||||||
|
}
|
||||||
|
pub fn __aeabi_memcpy8(dest: [*]u8, src: [*]u8, n: usize) callconv(.AAPCS) void {
|
||||||
|
@setRuntimeSafety(false);
|
||||||
|
_ = memcpy(dest, src, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __aeabi_memmove(dest: [*]u8, src: [*]u8, n: usize) callconv(.AAPCS) void {
|
||||||
|
@setRuntimeSafety(false);
|
||||||
|
_ = memmove(dest, src, n);
|
||||||
|
}
|
||||||
|
pub fn __aeabi_memmove4(dest: [*]u8, src: [*]u8, n: usize) callconv(.AAPCS) void {
|
||||||
|
@setRuntimeSafety(false);
|
||||||
|
_ = memmove(dest, src, n);
|
||||||
|
}
|
||||||
|
pub fn __aeabi_memmove8(dest: [*]u8, src: [*]u8, n: usize) callconv(.AAPCS) void {
|
||||||
|
@setRuntimeSafety(false);
|
||||||
|
_ = memmove(dest, src, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __aeabi_memset(dest: [*]u8, n: usize, c: u8) callconv(.AAPCS) void {
|
||||||
|
@setRuntimeSafety(false);
|
||||||
|
// This is dentical to the standard `memset` definition but with the last
|
||||||
|
// two arguments swapped
|
||||||
|
_ = memset(dest, c, n);
|
||||||
|
}
|
||||||
|
pub fn __aeabi_memset4(dest: [*]u8, n: usize, c: u8) callconv(.AAPCS) void {
|
||||||
|
@setRuntimeSafety(false);
|
||||||
|
_ = memset(dest, c, n);
|
||||||
|
}
|
||||||
|
pub fn __aeabi_memset8(dest: [*]u8, n: usize, c: u8) callconv(.AAPCS) void {
|
||||||
|
@setRuntimeSafety(false);
|
||||||
|
_ = memset(dest, c, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __aeabi_memclr(dest: [*]u8, n: usize) callconv(.AAPCS) void {
|
||||||
|
@setRuntimeSafety(false);
|
||||||
|
_ = memset(dest, 0, n);
|
||||||
|
}
|
||||||
|
pub fn __aeabi_memclr4(dest: [*]u8, n: usize) callconv(.AAPCS) void {
|
||||||
|
@setRuntimeSafety(false);
|
||||||
|
_ = memset(dest, 0, n);
|
||||||
|
}
|
||||||
|
pub fn __aeabi_memclr8(dest: [*]u8, n: usize) callconv(.AAPCS) void {
|
||||||
|
@setRuntimeSafety(false);
|
||||||
|
_ = memset(dest, 0, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dummy functions to avoid errors during the linking phase
|
||||||
|
pub fn __aeabi_unwind_cpp_pr0() callconv(.AAPCS) void {}
|
||||||
|
pub fn __aeabi_unwind_cpp_pr1() callconv(.AAPCS) void {}
|
||||||
|
pub fn __aeabi_unwind_cpp_pr2() callconv(.AAPCS) void {}
|
||||||
|
|
||||||
|
// This function can only clobber r0 according to the ABI
|
||||||
|
pub fn __aeabi_read_tp() callconv(.Naked) void {
|
||||||
|
@setRuntimeSafety(false);
|
||||||
|
asm volatile (
|
||||||
|
\\ mrc p15, 0, r0, c13, c0, 3
|
||||||
|
\\ bx lr
|
||||||
|
);
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The following functions are wrapped in an asm block to ensure the required
|
||||||
|
// calling convention is always respected
|
||||||
|
|
||||||
|
pub fn __aeabi_uidivmod() callconv(.Naked) void {
|
||||||
|
@setRuntimeSafety(false);
|
||||||
|
// Divide r0 by r1; the quotient goes in r0, the remainder in r1
|
||||||
|
asm volatile (
|
||||||
|
\\ push {lr}
|
||||||
|
\\ sub sp, #4
|
||||||
|
\\ mov r2, sp
|
||||||
|
\\ bl __udivmodsi4
|
||||||
|
\\ ldr r1, [sp]
|
||||||
|
\\ add sp, #4
|
||||||
|
\\ pop {pc}
|
||||||
|
::: "memory");
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __aeabi_uldivmod() callconv(.Naked) void {
|
||||||
|
@setRuntimeSafety(false);
|
||||||
|
// Divide r1:r0 by r3:r2; the quotient goes in r1:r0, the remainder in r3:r2
|
||||||
|
asm volatile (
|
||||||
|
\\ push {r4, lr}
|
||||||
|
\\ sub sp, #16
|
||||||
|
\\ add r4, sp, #8
|
||||||
|
\\ str r4, [sp]
|
||||||
|
\\ bl __udivmoddi4
|
||||||
|
\\ ldr r2, [sp, #8]
|
||||||
|
\\ ldr r3, [sp, #12]
|
||||||
|
\\ add sp, #16
|
||||||
|
\\ pop {r4, pc}
|
||||||
|
::: "memory");
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __aeabi_idivmod() callconv(.Naked) void {
|
||||||
|
@setRuntimeSafety(false);
|
||||||
|
// Divide r0 by r1; the quotient goes in r0, the remainder in r1
|
||||||
|
asm volatile (
|
||||||
|
\\ push {lr}
|
||||||
|
\\ sub sp, #4
|
||||||
|
\\ mov r2, sp
|
||||||
|
\\ bl __divmodsi4
|
||||||
|
\\ ldr r1, [sp]
|
||||||
|
\\ add sp, #4
|
||||||
|
\\ pop {pc}
|
||||||
|
::: "memory");
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __aeabi_ldivmod() callconv(.Naked) void {
|
||||||
|
@setRuntimeSafety(false);
|
||||||
|
// Divide r1:r0 by r3:r2; the quotient goes in r1:r0, the remainder in r3:r2
|
||||||
|
asm volatile (
|
||||||
|
\\ push {r4, lr}
|
||||||
|
\\ sub sp, #16
|
||||||
|
\\ add r4, sp, #8
|
||||||
|
\\ str r4, [sp]
|
||||||
|
\\ bl __divmoddi4
|
||||||
|
\\ ldr r2, [sp, #8]
|
||||||
|
\\ ldr r3, [sp, #12]
|
||||||
|
\\ add sp, #16
|
||||||
|
\\ pop {r4, pc}
|
||||||
|
::: "memory");
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
@ -1,8 +1,9 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
const arch = builtin.cpu.arch;
|
const cpu = builtin.cpu;
|
||||||
|
const arch = cpu.arch;
|
||||||
const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
|
const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
|
||||||
|
pub const panic = @import("common.zig").panic;
|
||||||
|
|
||||||
// This parameter is true iff the target architecture supports the bare minimum
|
// This parameter is true iff the target architecture supports the bare minimum
|
||||||
// to implement the atomic load/store intrinsics.
|
// to implement the atomic load/store intrinsics.
|
||||||
@ -24,6 +25,11 @@ const supports_atomic_ops = switch (arch) {
|
|||||||
// load/store atomically.
|
// load/store atomically.
|
||||||
// Objects bigger than this threshold require the use of a lock.
|
// Objects bigger than this threshold require the use of a lock.
|
||||||
const largest_atomic_size = switch (arch) {
|
const largest_atomic_size = switch (arch) {
|
||||||
|
// On SPARC systems that lacks CAS and/or swap instructions, the only
|
||||||
|
// available atomic operation is a test-and-set (`ldstub`), so we force
|
||||||
|
// every atomic memory access to go through the lock.
|
||||||
|
.sparc, .sparcel => if (cpu.features.featureSetHas(.hasleoncasa)) @sizeOf(usize) else 0,
|
||||||
|
|
||||||
// XXX: On x86/x86_64 we could check the presence of cmpxchg8b/cmpxchg16b
|
// XXX: On x86/x86_64 we could check the presence of cmpxchg8b/cmpxchg16b
|
||||||
// and set this parameter accordingly.
|
// and set this parameter accordingly.
|
||||||
else => @sizeOf(usize),
|
else => @sizeOf(usize),
|
||||||
@ -36,20 +42,44 @@ const SpinlockTable = struct {
|
|||||||
const max_spinlocks = 64;
|
const max_spinlocks = 64;
|
||||||
|
|
||||||
const Spinlock = struct {
|
const Spinlock = struct {
|
||||||
|
// SPARC ldstub instruction will write a 255 into the memory location.
|
||||||
|
// We'll use that as a sign that the lock is currently held.
|
||||||
|
// See also: Section B.7 in SPARCv8 spec & A.29 in SPARCv9 spec.
|
||||||
|
const sparc_lock: type = enum(u8) { Unlocked = 0, Locked = 255 };
|
||||||
|
const other_lock: type = enum(usize) { Unlocked = 0, Locked };
|
||||||
|
|
||||||
// Prevent false sharing by providing enough padding between two
|
// Prevent false sharing by providing enough padding between two
|
||||||
// consecutive spinlock elements
|
// consecutive spinlock elements
|
||||||
v: enum(usize) { Unlocked = 0, Locked } align(cache_line_size) = .Unlocked,
|
v: if (arch.isSPARC()) sparc_lock else other_lock align(cache_line_size) = .Unlocked,
|
||||||
|
|
||||||
fn acquire(self: *@This()) void {
|
fn acquire(self: *@This()) void {
|
||||||
while (true) {
|
while (true) {
|
||||||
switch (@atomicRmw(@TypeOf(self.v), &self.v, .Xchg, .Locked, .Acquire)) {
|
const flag = if (comptime arch.isSPARC()) flag: {
|
||||||
|
break :flag asm volatile ("ldstub [%[addr]], %[flag]"
|
||||||
|
: [flag] "=r" (-> @TypeOf(self.v)),
|
||||||
|
: [addr] "r" (&self.v),
|
||||||
|
: "memory"
|
||||||
|
);
|
||||||
|
} else flag: {
|
||||||
|
break :flag @atomicRmw(@TypeOf(self.v), &self.v, .Xchg, .Locked, .Acquire);
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (flag) {
|
||||||
.Unlocked => break,
|
.Unlocked => break,
|
||||||
.Locked => {},
|
.Locked => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn release(self: *@This()) void {
|
fn release(self: *@This()) void {
|
||||||
@atomicStore(@TypeOf(self.v), &self.v, .Unlocked, .Release);
|
if (comptime arch.isSPARC()) {
|
||||||
|
_ = asm volatile ("clrb [%[addr]]"
|
||||||
|
:
|
||||||
|
: [addr] "r" (&self.v),
|
||||||
|
: "memory"
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
@atomicStore(@TypeOf(self.v), &self.v, .Unlocked, .Release);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1,7 +1,20 @@
|
|||||||
|
const std = @import("std");
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
|
const arch = builtin.cpu.arch;
|
||||||
|
const abi = builtin.abi;
|
||||||
|
const common = @import("common.zig");
|
||||||
|
|
||||||
|
pub const panic = common.panic;
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
if (arch == .i386 and abi == .msvc) {
|
||||||
|
// Don't let LLVM apply the stdcall name mangling on those MSVC builtins
|
||||||
|
@export(_alldiv, .{ .name = "\x01__alldiv", .linkage = common.linkage });
|
||||||
|
@export(_aulldiv, .{ .name = "\x01__aulldiv", .linkage = common.linkage });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn _alldiv(a: i64, b: i64) callconv(.Stdcall) i64 {
|
pub fn _alldiv(a: i64, b: i64) callconv(.Stdcall) i64 {
|
||||||
@setRuntimeSafety(builtin.is_test);
|
|
||||||
const s_a = a >> (64 - 1);
|
const s_a = a >> (64 - 1);
|
||||||
const s_b = b >> (64 - 1);
|
const s_b = b >> (64 - 1);
|
||||||
|
|
||||||
@ -1,7 +1,20 @@
|
|||||||
|
const std = @import("std");
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
|
const arch = builtin.cpu.arch;
|
||||||
|
const abi = builtin.abi;
|
||||||
|
const common = @import("common.zig");
|
||||||
|
|
||||||
|
pub const panic = common.panic;
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
if (arch == .i386 and abi == .msvc) {
|
||||||
|
// Don't let LLVM apply the stdcall name mangling on those MSVC builtins
|
||||||
|
@export(_allrem, .{ .name = "\x01__allrem", .linkage = common.linkage });
|
||||||
|
@export(_aullrem, .{ .name = "\x01__aullrem", .linkage = common.linkage });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn _allrem(a: i64, b: i64) callconv(.Stdcall) i64 {
|
pub fn _allrem(a: i64, b: i64) callconv(.Stdcall) i64 {
|
||||||
@setRuntimeSafety(builtin.is_test);
|
|
||||||
const s_a = a >> (64 - 1);
|
const s_a = a >> (64 - 1);
|
||||||
const s_b = b >> (64 - 1);
|
const s_b = b >> (64 - 1);
|
||||||
|
|
||||||
@ -1,5 +1,14 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
|
const common = @import("common.zig");
|
||||||
|
|
||||||
|
pub const panic = common.panic;
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
@export(__bswapsi2, .{ .name = "__bswapsi2", .linkage = common.linkage });
|
||||||
|
@export(__bswapdi2, .{ .name = "__bswapdi2", .linkage = common.linkage });
|
||||||
|
@export(__bswapti2, .{ .name = "__bswapti2", .linkage = common.linkage });
|
||||||
|
}
|
||||||
|
|
||||||
// bswap - byteswap
|
// bswap - byteswap
|
||||||
// - bswapXi2 for unoptimized big and little endian
|
// - bswapXi2 for unoptimized big and little endian
|
||||||
@ -12,7 +21,6 @@ const builtin = @import("builtin");
|
|||||||
// 00 00 00 ff << 3*8 (rightmost byte)
|
// 00 00 00 ff << 3*8 (rightmost byte)
|
||||||
|
|
||||||
inline fn bswapXi2(comptime T: type, a: T) T {
|
inline fn bswapXi2(comptime T: type, a: T) T {
|
||||||
@setRuntimeSafety(builtin.is_test);
|
|
||||||
switch (@bitSizeOf(T)) {
|
switch (@bitSizeOf(T)) {
|
||||||
32 => {
|
32 => {
|
||||||
// zig fmt: off
|
// zig fmt: off
|
||||||
180
lib/compiler_rt/ceil.zig
Normal file
180
lib/compiler_rt/ceil.zig
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
//! Ported from musl, which is MIT licensed.
|
||||||
|
//! https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
|
||||||
|
//!
|
||||||
|
//! https://git.musl-libc.org/cgit/musl/tree/src/math/ceilf.c
|
||||||
|
//! https://git.musl-libc.org/cgit/musl/tree/src/math/ceil.c
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const builtin = @import("builtin");
|
||||||
|
const arch = builtin.cpu.arch;
|
||||||
|
const math = std.math;
|
||||||
|
const expect = std.testing.expect;
|
||||||
|
const common = @import("common.zig");
|
||||||
|
|
||||||
|
pub const panic = common.panic;
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
@export(__ceilh, .{ .name = "__ceilh", .linkage = common.linkage });
|
||||||
|
@export(ceilf, .{ .name = "ceilf", .linkage = common.linkage });
|
||||||
|
@export(ceil, .{ .name = "ceil", .linkage = common.linkage });
|
||||||
|
@export(__ceilx, .{ .name = "__ceilx", .linkage = common.linkage });
|
||||||
|
const ceilq_sym_name = if (common.want_ppc_abi) "ceilf128" else "ceilq";
|
||||||
|
@export(ceilq, .{ .name = ceilq_sym_name, .linkage = common.linkage });
|
||||||
|
@export(ceill, .{ .name = "ceill", .linkage = common.linkage });
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __ceilh(x: f16) callconv(.C) f16 {
|
||||||
|
// TODO: more efficient implementation
|
||||||
|
return @floatCast(f16, ceilf(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ceilf(x: f32) callconv(.C) f32 {
|
||||||
|
var u = @bitCast(u32, x);
|
||||||
|
var e = @intCast(i32, (u >> 23) & 0xFF) - 0x7F;
|
||||||
|
var m: u32 = undefined;
|
||||||
|
|
||||||
|
// TODO: Shouldn't need this explicit check.
|
||||||
|
if (x == 0.0) {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e >= 23) {
|
||||||
|
return x;
|
||||||
|
} else if (e >= 0) {
|
||||||
|
m = @as(u32, 0x007FFFFF) >> @intCast(u5, e);
|
||||||
|
if (u & m == 0) {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
math.doNotOptimizeAway(x + 0x1.0p120);
|
||||||
|
if (u >> 31 == 0) {
|
||||||
|
u += m;
|
||||||
|
}
|
||||||
|
u &= ~m;
|
||||||
|
return @bitCast(f32, u);
|
||||||
|
} else {
|
||||||
|
math.doNotOptimizeAway(x + 0x1.0p120);
|
||||||
|
if (u >> 31 != 0) {
|
||||||
|
return -0.0;
|
||||||
|
} else {
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ceil(x: f64) callconv(.C) f64 {
|
||||||
|
const f64_toint = 1.0 / math.floatEps(f64);
|
||||||
|
|
||||||
|
const u = @bitCast(u64, x);
|
||||||
|
const e = (u >> 52) & 0x7FF;
|
||||||
|
var y: f64 = undefined;
|
||||||
|
|
||||||
|
if (e >= 0x3FF + 52 or x == 0) {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (u >> 63 != 0) {
|
||||||
|
y = x - f64_toint + f64_toint - x;
|
||||||
|
} else {
|
||||||
|
y = x + f64_toint - f64_toint - x;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e <= 0x3FF - 1) {
|
||||||
|
math.doNotOptimizeAway(y);
|
||||||
|
if (u >> 63 != 0) {
|
||||||
|
return -0.0;
|
||||||
|
} else {
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
} else if (y < 0) {
|
||||||
|
return x + y + 1;
|
||||||
|
} else {
|
||||||
|
return x + y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __ceilx(x: f80) callconv(.C) f80 {
|
||||||
|
// TODO: more efficient implementation
|
||||||
|
return @floatCast(f80, ceilq(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ceilq(x: f128) callconv(.C) f128 {
|
||||||
|
const f128_toint = 1.0 / math.floatEps(f128);
|
||||||
|
|
||||||
|
const u = @bitCast(u128, x);
|
||||||
|
const e = (u >> 112) & 0x7FFF;
|
||||||
|
var y: f128 = undefined;
|
||||||
|
|
||||||
|
if (e >= 0x3FFF + 112 or x == 0) return x;
|
||||||
|
|
||||||
|
if (u >> 127 != 0) {
|
||||||
|
y = x - f128_toint + f128_toint - x;
|
||||||
|
} else {
|
||||||
|
y = x + f128_toint - f128_toint - x;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e <= 0x3FFF - 1) {
|
||||||
|
math.doNotOptimizeAway(y);
|
||||||
|
if (u >> 127 != 0) {
|
||||||
|
return -0.0;
|
||||||
|
} else {
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
} else if (y < 0) {
|
||||||
|
return x + y + 1;
|
||||||
|
} else {
|
||||||
|
return x + y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ceill(x: c_longdouble) callconv(.C) c_longdouble {
|
||||||
|
switch (@typeInfo(c_longdouble).Float.bits) {
|
||||||
|
16 => return __ceilh(x),
|
||||||
|
32 => return ceilf(x),
|
||||||
|
64 => return ceil(x),
|
||||||
|
80 => return __ceilx(x),
|
||||||
|
128 => return ceilq(x),
|
||||||
|
else => @compileError("unreachable"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "ceil32" {
|
||||||
|
try expect(ceilf(1.3) == 2.0);
|
||||||
|
try expect(ceilf(-1.3) == -1.0);
|
||||||
|
try expect(ceilf(0.2) == 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "ceil64" {
|
||||||
|
try expect(ceil(1.3) == 2.0);
|
||||||
|
try expect(ceil(-1.3) == -1.0);
|
||||||
|
try expect(ceil(0.2) == 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "ceil128" {
|
||||||
|
try expect(ceilq(1.3) == 2.0);
|
||||||
|
try expect(ceilq(-1.3) == -1.0);
|
||||||
|
try expect(ceilq(0.2) == 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "ceil32.special" {
|
||||||
|
try expect(ceilf(0.0) == 0.0);
|
||||||
|
try expect(ceilf(-0.0) == -0.0);
|
||||||
|
try expect(math.isPositiveInf(ceilf(math.inf(f32))));
|
||||||
|
try expect(math.isNegativeInf(ceilf(-math.inf(f32))));
|
||||||
|
try expect(math.isNan(ceilf(math.nan(f32))));
|
||||||
|
}
|
||||||
|
|
||||||
|
test "ceil64.special" {
|
||||||
|
try expect(ceil(0.0) == 0.0);
|
||||||
|
try expect(ceil(-0.0) == -0.0);
|
||||||
|
try expect(math.isPositiveInf(ceil(math.inf(f64))));
|
||||||
|
try expect(math.isNegativeInf(ceil(-math.inf(f64))));
|
||||||
|
try expect(math.isNan(ceil(math.nan(f64))));
|
||||||
|
}
|
||||||
|
|
||||||
|
test "ceil128.special" {
|
||||||
|
try expect(ceilq(0.0) == 0.0);
|
||||||
|
try expect(ceilq(-0.0) == -0.0);
|
||||||
|
try expect(math.isPositiveInf(ceilq(math.inf(f128))));
|
||||||
|
try expect(math.isNegativeInf(ceilq(-math.inf(f128))));
|
||||||
|
try expect(math.isNan(ceilq(math.nan(f128))));
|
||||||
|
}
|
||||||
@ -2,6 +2,7 @@ const std = @import("std");
|
|||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
const arch = builtin.cpu.arch;
|
const arch = builtin.cpu.arch;
|
||||||
const os = builtin.os.tag;
|
const os = builtin.os.tag;
|
||||||
|
pub const panic = @import("common.zig").panic;
|
||||||
|
|
||||||
// Ported from llvm-project d32170dbd5b0d54436537b6b75beaf44324e0c28
|
// Ported from llvm-project d32170dbd5b0d54436537b6b75beaf44324e0c28
|
||||||
|
|
||||||
@ -10,7 +11,13 @@ const os = builtin.os.tag;
|
|||||||
// It is expected to invalidate the instruction cache for the
|
// It is expected to invalidate the instruction cache for the
|
||||||
// specified range.
|
// specified range.
|
||||||
|
|
||||||
pub fn clear_cache(start: usize, end: usize) callconv(.C) void {
|
comptime {
|
||||||
|
if (builtin.zig_backend != .stage2_llvm) {
|
||||||
|
_ = clear_cache;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clear_cache(start: usize, end: usize) callconv(.C) void {
|
||||||
const x86 = switch (arch) {
|
const x86 = switch (arch) {
|
||||||
.i386, .x86_64 => true,
|
.i386, .x86_64 => true,
|
||||||
else => false,
|
else => false,
|
||||||
@ -36,7 +43,7 @@ pub fn clear_cache(start: usize, end: usize) callconv(.C) void {
|
|||||||
else => false,
|
else => false,
|
||||||
};
|
};
|
||||||
const sparc = switch (arch) {
|
const sparc = switch (arch) {
|
||||||
.sparc, .sparcv9, .sparcel => true,
|
.sparc, .sparc64, .sparcel => true,
|
||||||
else => false,
|
else => false,
|
||||||
};
|
};
|
||||||
const apple = switch (os) {
|
const apple = switch (os) {
|
||||||
@ -1,14 +1,26 @@
|
|||||||
|
const builtin = @import("builtin");
|
||||||
const clz = @import("count0bits.zig");
|
const clz = @import("count0bits.zig");
|
||||||
const testing = @import("std").testing;
|
const testing = @import("std").testing;
|
||||||
|
|
||||||
fn test__clzsi2(a: u32, expected: i32) !void {
|
fn test__clzsi2(a: u32, expected: i32) !void {
|
||||||
// XXX At high optimization levels this test may be horribly miscompiled if
|
// stage1 and stage2 diverge on function pointer semantics
|
||||||
// one of the naked implementations is selected.
|
switch (builtin.zig_backend) {
|
||||||
var nakedClzsi2 = clz.__clzsi2;
|
.stage1 => {
|
||||||
var actualClzsi2 = @ptrCast(fn (a: i32) callconv(.C) i32, nakedClzsi2);
|
// Use of `var` here is working around a stage1 bug.
|
||||||
var x = @bitCast(i32, a);
|
var nakedClzsi2 = clz.__clzsi2;
|
||||||
var result = actualClzsi2(x);
|
var actualClzsi2 = @ptrCast(fn (a: i32) callconv(.C) i32, nakedClzsi2);
|
||||||
try testing.expectEqual(expected, result);
|
var x = @bitCast(i32, a);
|
||||||
|
var result = actualClzsi2(x);
|
||||||
|
try testing.expectEqual(expected, result);
|
||||||
|
},
|
||||||
|
else => {
|
||||||
|
const nakedClzsi2 = clz.__clzsi2;
|
||||||
|
const actualClzsi2 = @ptrCast(*const fn (a: i32) callconv(.C) i32, &nakedClzsi2);
|
||||||
|
const x = @bitCast(i32, a);
|
||||||
|
const result = actualClzsi2(x);
|
||||||
|
try testing.expectEqual(expected, result);
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test "clzsi2" {
|
test "clzsi2" {
|
||||||
@ -1,5 +1,18 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
|
const is_test = builtin.is_test;
|
||||||
|
const common = @import("common.zig");
|
||||||
|
|
||||||
|
pub const panic = common.panic;
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
@export(__cmpsi2, .{ .name = "__cmpsi2", .linkage = common.linkage });
|
||||||
|
@export(__cmpdi2, .{ .name = "__cmpdi2", .linkage = common.linkage });
|
||||||
|
@export(__cmpti2, .{ .name = "__cmpti2", .linkage = common.linkage });
|
||||||
|
@export(__ucmpsi2, .{ .name = "__ucmpsi2", .linkage = common.linkage });
|
||||||
|
@export(__ucmpdi2, .{ .name = "__ucmpdi2", .linkage = common.linkage });
|
||||||
|
@export(__ucmpti2, .{ .name = "__ucmpti2", .linkage = common.linkage });
|
||||||
|
}
|
||||||
|
|
||||||
// cmp - signed compare
|
// cmp - signed compare
|
||||||
// - cmpXi2_generic for unoptimized little and big endian
|
// - cmpXi2_generic for unoptimized little and big endian
|
||||||
@ -12,7 +25,6 @@ const builtin = @import("builtin");
|
|||||||
// a > b => 2
|
// a > b => 2
|
||||||
|
|
||||||
inline fn XcmpXi2(comptime T: type, a: T, b: T) i32 {
|
inline fn XcmpXi2(comptime T: type, a: T, b: T) i32 {
|
||||||
@setRuntimeSafety(builtin.is_test);
|
|
||||||
var cmp1: i32 = 0;
|
var cmp1: i32 = 0;
|
||||||
var cmp2: i32 = 0;
|
var cmp2: i32 = 0;
|
||||||
if (a > b)
|
if (a > b)
|
||||||
68
lib/compiler_rt/cmpdf2.zig
Normal file
68
lib/compiler_rt/cmpdf2.zig
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
///! The quoted behavior definitions are from
|
||||||
|
///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines
|
||||||
|
const common = @import("./common.zig");
|
||||||
|
const comparef = @import("./comparef.zig");
|
||||||
|
|
||||||
|
pub const panic = common.panic;
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
if (common.want_aeabi) {
|
||||||
|
@export(__aeabi_dcmpeq, .{ .name = "__aeabi_dcmpeq", .linkage = common.linkage });
|
||||||
|
@export(__aeabi_dcmplt, .{ .name = "__aeabi_dcmplt", .linkage = common.linkage });
|
||||||
|
@export(__aeabi_dcmple, .{ .name = "__aeabi_dcmple", .linkage = common.linkage });
|
||||||
|
} else {
|
||||||
|
@export(__eqdf2, .{ .name = "__eqdf2", .linkage = common.linkage });
|
||||||
|
@export(__nedf2, .{ .name = "__nedf2", .linkage = common.linkage });
|
||||||
|
@export(__ledf2, .{ .name = "__ledf2", .linkage = common.linkage });
|
||||||
|
@export(__cmpdf2, .{ .name = "__cmpdf2", .linkage = common.linkage });
|
||||||
|
@export(__ltdf2, .{ .name = "__ltdf2", .linkage = common.linkage });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// "These functions calculate a <=> b. That is, if a is less than b, they return -1;
|
||||||
|
/// if a is greater than b, they return 1; and if a and b are equal they return 0.
|
||||||
|
/// If either argument is NaN they return 1..."
|
||||||
|
///
|
||||||
|
/// Note that this matches the definition of `__ledf2`, `__eqdf2`, `__nedf2`, `__cmpdf2`,
|
||||||
|
/// and `__ltdf2`.
|
||||||
|
fn __cmpdf2(a: f64, b: f64) callconv(.C) i32 {
|
||||||
|
return @enumToInt(comparef.cmpf2(f64, comparef.LE, a, b));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// "These functions return a value less than or equal to zero if neither argument is NaN,
|
||||||
|
/// and a is less than or equal to b."
|
||||||
|
pub fn __ledf2(a: f64, b: f64) callconv(.C) i32 {
|
||||||
|
return __cmpdf2(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// "These functions return zero if neither argument is NaN, and a and b are equal."
|
||||||
|
/// Note that due to some kind of historical accident, __eqdf2 and __nedf2 are defined
|
||||||
|
/// to have the same return value.
|
||||||
|
pub fn __eqdf2(a: f64, b: f64) callconv(.C) i32 {
|
||||||
|
return __cmpdf2(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal."
|
||||||
|
/// Note that due to some kind of historical accident, __eqdf2 and __nedf2 are defined
|
||||||
|
/// to have the same return value.
|
||||||
|
pub fn __nedf2(a: f64, b: f64) callconv(.C) i32 {
|
||||||
|
return __cmpdf2(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// "These functions return a value less than zero if neither argument is NaN, and a
|
||||||
|
/// is strictly less than b."
|
||||||
|
pub fn __ltdf2(a: f64, b: f64) callconv(.C) i32 {
|
||||||
|
return __cmpdf2(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __aeabi_dcmpeq(a: f64, b: f64) callconv(.AAPCS) i32 {
|
||||||
|
return @boolToInt(comparef.cmpf2(f64, comparef.LE, a, b) == .Equal);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __aeabi_dcmplt(a: f64, b: f64) callconv(.AAPCS) i32 {
|
||||||
|
return @boolToInt(comparef.cmpf2(f64, comparef.LE, a, b) == .Less);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __aeabi_dcmple(a: f64, b: f64) callconv(.AAPCS) i32 {
|
||||||
|
return @boolToInt(comparef.cmpf2(f64, comparef.LE, a, b) != .Greater);
|
||||||
|
}
|
||||||
68
lib/compiler_rt/cmpsf2.zig
Normal file
68
lib/compiler_rt/cmpsf2.zig
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
///! The quoted behavior definitions are from
|
||||||
|
///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines
|
||||||
|
const common = @import("./common.zig");
|
||||||
|
const comparef = @import("./comparef.zig");
|
||||||
|
|
||||||
|
pub const panic = common.panic;
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
if (common.want_aeabi) {
|
||||||
|
@export(__aeabi_fcmpeq, .{ .name = "__aeabi_fcmpeq", .linkage = common.linkage });
|
||||||
|
@export(__aeabi_fcmplt, .{ .name = "__aeabi_fcmplt", .linkage = common.linkage });
|
||||||
|
@export(__aeabi_fcmple, .{ .name = "__aeabi_fcmple", .linkage = common.linkage });
|
||||||
|
} else {
|
||||||
|
@export(__eqsf2, .{ .name = "__eqsf2", .linkage = common.linkage });
|
||||||
|
@export(__nesf2, .{ .name = "__nesf2", .linkage = common.linkage });
|
||||||
|
@export(__lesf2, .{ .name = "__lesf2", .linkage = common.linkage });
|
||||||
|
@export(__cmpsf2, .{ .name = "__cmpsf2", .linkage = common.linkage });
|
||||||
|
@export(__ltsf2, .{ .name = "__ltsf2", .linkage = common.linkage });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// "These functions calculate a <=> b. That is, if a is less than b, they return -1;
|
||||||
|
/// if a is greater than b, they return 1; and if a and b are equal they return 0.
|
||||||
|
/// If either argument is NaN they return 1..."
|
||||||
|
///
|
||||||
|
/// Note that this matches the definition of `__lesf2`, `__eqsf2`, `__nesf2`, `__cmpsf2`,
|
||||||
|
/// and `__ltsf2`.
|
||||||
|
fn __cmpsf2(a: f32, b: f32) callconv(.C) i32 {
|
||||||
|
return @enumToInt(comparef.cmpf2(f32, comparef.LE, a, b));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// "These functions return a value less than or equal to zero if neither argument is NaN,
|
||||||
|
/// and a is less than or equal to b."
|
||||||
|
pub fn __lesf2(a: f32, b: f32) callconv(.C) i32 {
|
||||||
|
return __cmpsf2(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// "These functions return zero if neither argument is NaN, and a and b are equal."
|
||||||
|
/// Note that due to some kind of historical accident, __eqsf2 and __nesf2 are defined
|
||||||
|
/// to have the same return value.
|
||||||
|
pub fn __eqsf2(a: f32, b: f32) callconv(.C) i32 {
|
||||||
|
return __cmpsf2(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal."
|
||||||
|
/// Note that due to some kind of historical accident, __eqsf2 and __nesf2 are defined
|
||||||
|
/// to have the same return value.
|
||||||
|
pub fn __nesf2(a: f32, b: f32) callconv(.C) i32 {
|
||||||
|
return __cmpsf2(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// "These functions return a value less than zero if neither argument is NaN, and a
|
||||||
|
/// is strictly less than b."
|
||||||
|
pub fn __ltsf2(a: f32, b: f32) callconv(.C) i32 {
|
||||||
|
return __cmpsf2(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __aeabi_fcmpeq(a: f32, b: f32) callconv(.AAPCS) i32 {
|
||||||
|
return @boolToInt(comparef.cmpf2(f32, comparef.LE, a, b) == .Equal);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __aeabi_fcmplt(a: f32, b: f32) callconv(.AAPCS) i32 {
|
||||||
|
return @boolToInt(comparef.cmpf2(f32, comparef.LE, a, b) == .Less);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __aeabi_fcmple(a: f32, b: f32) callconv(.AAPCS) i32 {
|
||||||
|
return @boolToInt(comparef.cmpf2(f32, comparef.LE, a, b) != .Greater);
|
||||||
|
}
|
||||||
122
lib/compiler_rt/cmptf2.zig
Normal file
122
lib/compiler_rt/cmptf2.zig
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
///! The quoted behavior definitions are from
|
||||||
|
///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines
|
||||||
|
const common = @import("./common.zig");
|
||||||
|
const comparef = @import("./comparef.zig");
|
||||||
|
|
||||||
|
pub const panic = common.panic;
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
if (common.want_ppc_abi) {
|
||||||
|
@export(__eqkf2, .{ .name = "__eqkf2", .linkage = common.linkage });
|
||||||
|
@export(__nekf2, .{ .name = "__nekf2", .linkage = common.linkage });
|
||||||
|
@export(__ltkf2, .{ .name = "__ltkf2", .linkage = common.linkage });
|
||||||
|
@export(__lekf2, .{ .name = "__lekf2", .linkage = common.linkage });
|
||||||
|
} else if (common.want_sparc_abi) {
|
||||||
|
@export(_Qp_cmp, .{ .name = "_Qp_cmp", .linkage = common.linkage });
|
||||||
|
@export(_Qp_feq, .{ .name = "_Qp_feq", .linkage = common.linkage });
|
||||||
|
@export(_Qp_fne, .{ .name = "_Qp_fne", .linkage = common.linkage });
|
||||||
|
@export(_Qp_flt, .{ .name = "_Qp_flt", .linkage = common.linkage });
|
||||||
|
@export(_Qp_fle, .{ .name = "_Qp_fle", .linkage = common.linkage });
|
||||||
|
@export(_Qp_fgt, .{ .name = "_Qp_fgt", .linkage = common.linkage });
|
||||||
|
@export(_Qp_fge, .{ .name = "_Qp_fge", .linkage = common.linkage });
|
||||||
|
} else {
|
||||||
|
@export(__eqtf2, .{ .name = "__eqtf2", .linkage = common.linkage });
|
||||||
|
@export(__netf2, .{ .name = "__netf2", .linkage = common.linkage });
|
||||||
|
@export(__letf2, .{ .name = "__letf2", .linkage = common.linkage });
|
||||||
|
@export(__cmptf2, .{ .name = "__cmptf2", .linkage = common.linkage });
|
||||||
|
@export(__lttf2, .{ .name = "__lttf2", .linkage = common.linkage });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// "These functions calculate a <=> b. That is, if a is less than b, they return -1;
|
||||||
|
/// if a is greater than b, they return 1; and if a and b are equal they return 0.
|
||||||
|
/// If either argument is NaN they return 1..."
|
||||||
|
///
|
||||||
|
/// Note that this matches the definition of `__letf2`, `__eqtf2`, `__netf2`, `__cmptf2`,
|
||||||
|
/// and `__lttf2`.
|
||||||
|
fn __cmptf2(a: f128, b: f128) callconv(.C) i32 {
|
||||||
|
return @enumToInt(comparef.cmpf2(f128, comparef.LE, a, b));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// "These functions return a value less than or equal to zero if neither argument is NaN,
|
||||||
|
/// and a is less than or equal to b."
|
||||||
|
fn __letf2(a: f128, b: f128) callconv(.C) i32 {
|
||||||
|
return __cmptf2(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// "These functions return zero if neither argument is NaN, and a and b are equal."
|
||||||
|
/// Note that due to some kind of historical accident, __eqtf2 and __netf2 are defined
|
||||||
|
/// to have the same return value.
|
||||||
|
fn __eqtf2(a: f128, b: f128) callconv(.C) i32 {
|
||||||
|
return __cmptf2(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal."
|
||||||
|
/// Note that due to some kind of historical accident, __eqtf2 and __netf2 are defined
|
||||||
|
/// to have the same return value.
|
||||||
|
fn __netf2(a: f128, b: f128) callconv(.C) i32 {
|
||||||
|
return __cmptf2(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// "These functions return a value less than zero if neither argument is NaN, and a
|
||||||
|
/// is strictly less than b."
|
||||||
|
fn __lttf2(a: f128, b: f128) callconv(.C) i32 {
|
||||||
|
return __cmptf2(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __eqkf2(a: f128, b: f128) callconv(.C) i32 {
|
||||||
|
return __cmptf2(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __nekf2(a: f128, b: f128) callconv(.C) i32 {
|
||||||
|
return __cmptf2(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __ltkf2(a: f128, b: f128) callconv(.C) i32 {
|
||||||
|
return __cmptf2(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __lekf2(a: f128, b: f128) callconv(.C) i32 {
|
||||||
|
return __cmptf2(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
const SparcFCMP = enum(i32) {
|
||||||
|
Equal = 0,
|
||||||
|
Less = 1,
|
||||||
|
Greater = 2,
|
||||||
|
Unordered = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn _Qp_cmp(a: *const f128, b: *const f128) callconv(.C) i32 {
|
||||||
|
return @enumToInt(comparef.cmpf2(f128, SparcFCMP, a.*, b.*));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _Qp_feq(a: *const f128, b: *const f128) callconv(.C) bool {
|
||||||
|
return @intToEnum(SparcFCMP, _Qp_cmp(a, b)) == .Equal;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _Qp_fne(a: *const f128, b: *const f128) callconv(.C) bool {
|
||||||
|
return @intToEnum(SparcFCMP, _Qp_cmp(a, b)) != .Equal;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _Qp_flt(a: *const f128, b: *const f128) callconv(.C) bool {
|
||||||
|
return @intToEnum(SparcFCMP, _Qp_cmp(a, b)) == .Less;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _Qp_fgt(a: *const f128, b: *const f128) callconv(.C) bool {
|
||||||
|
return @intToEnum(SparcFCMP, _Qp_cmp(a, b)) == .Greater;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _Qp_fge(a: *const f128, b: *const f128) callconv(.C) bool {
|
||||||
|
return switch (@intToEnum(SparcFCMP, _Qp_cmp(a, b))) {
|
||||||
|
.Equal, .Greater => true,
|
||||||
|
.Less, .Unordered => false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _Qp_fle(a: *const f128, b: *const f128) callconv(.C) bool {
|
||||||
|
return switch (@intToEnum(SparcFCMP, _Qp_cmp(a, b))) {
|
||||||
|
.Equal, .Less => true,
|
||||||
|
.Greater, .Unordered => false,
|
||||||
|
};
|
||||||
|
}
|
||||||
50
lib/compiler_rt/cmpxf2.zig
Normal file
50
lib/compiler_rt/cmpxf2.zig
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
///! The quoted behavior definitions are from
|
||||||
|
///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines
|
||||||
|
const common = @import("./common.zig");
|
||||||
|
const comparef = @import("./comparef.zig");
|
||||||
|
|
||||||
|
pub const panic = common.panic;
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
@export(__eqxf2, .{ .name = "__eqxf2", .linkage = common.linkage });
|
||||||
|
@export(__nexf2, .{ .name = "__nexf2", .linkage = common.linkage });
|
||||||
|
@export(__lexf2, .{ .name = "__lexf2", .linkage = common.linkage });
|
||||||
|
@export(__cmpxf2, .{ .name = "__cmpxf2", .linkage = common.linkage });
|
||||||
|
@export(__ltxf2, .{ .name = "__ltxf2", .linkage = common.linkage });
|
||||||
|
}
|
||||||
|
|
||||||
|
/// "These functions calculate a <=> b. That is, if a is less than b, they return -1;
|
||||||
|
/// if a is greater than b, they return 1; and if a and b are equal they return 0.
|
||||||
|
/// If either argument is NaN they return 1..."
|
||||||
|
///
|
||||||
|
/// Note that this matches the definition of `__lexf2`, `__eqxf2`, `__nexf2`, `__cmpxf2`,
|
||||||
|
/// and `__ltxf2`.
|
||||||
|
fn __cmpxf2(a: f80, b: f80) callconv(.C) i32 {
|
||||||
|
return @enumToInt(comparef.cmp_f80(comparef.LE, a, b));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// "These functions return a value less than or equal to zero if neither argument is NaN,
|
||||||
|
/// and a is less than or equal to b."
|
||||||
|
fn __lexf2(a: f80, b: f80) callconv(.C) i32 {
|
||||||
|
return __cmpxf2(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// "These functions return zero if neither argument is NaN, and a and b are equal."
|
||||||
|
/// Note that due to some kind of historical accident, __eqxf2 and __nexf2 are defined
|
||||||
|
/// to have the same return value.
|
||||||
|
fn __eqxf2(a: f80, b: f80) callconv(.C) i32 {
|
||||||
|
return __cmpxf2(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal."
|
||||||
|
/// Note that due to some kind of historical accident, __eqxf2 and __nexf2 are defined
|
||||||
|
/// to have the same return value.
|
||||||
|
fn __nexf2(a: f80, b: f80) callconv(.C) i32 {
|
||||||
|
return __cmpxf2(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// "These functions return a value less than zero if neither argument is NaN, and a
|
||||||
|
/// is strictly less than b."
|
||||||
|
fn __ltxf2(a: f80, b: f80) callconv(.C) i32 {
|
||||||
|
return __cmpxf2(a, b);
|
||||||
|
}
|
||||||
202
lib/compiler_rt/common.zig
Normal file
202
lib/compiler_rt/common.zig
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const builtin = @import("builtin");
|
||||||
|
|
||||||
|
pub const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak;
|
||||||
|
pub const want_aeabi = switch (builtin.abi) {
|
||||||
|
.eabi,
|
||||||
|
.eabihf,
|
||||||
|
.musleabi,
|
||||||
|
.musleabihf,
|
||||||
|
.gnueabi,
|
||||||
|
.gnueabihf,
|
||||||
|
=> switch (builtin.cpu.arch) {
|
||||||
|
.arm, .armeb, .thumb, .thumbeb => true,
|
||||||
|
else => false,
|
||||||
|
},
|
||||||
|
else => false,
|
||||||
|
};
|
||||||
|
pub const want_ppc_abi = builtin.cpu.arch.isPPC() or builtin.cpu.arch.isPPC64();
|
||||||
|
|
||||||
|
/// This governs whether to use these symbol names for f16/f32 conversions
|
||||||
|
/// rather than the standard names:
|
||||||
|
/// * __gnu_f2h_ieee
|
||||||
|
/// * __gnu_h2f_ieee
|
||||||
|
/// Known correct configurations:
|
||||||
|
/// x86_64-freestanding-none => true
|
||||||
|
/// x86_64-linux-none => true
|
||||||
|
/// x86_64-linux-gnu => true
|
||||||
|
/// x86_64-linux-musl => true
|
||||||
|
/// x86_64-linux-eabi => true
|
||||||
|
/// arm-linux-musleabihf => true
|
||||||
|
/// arm-linux-gnueabihf => true
|
||||||
|
/// arm-linux-eabihf => false
|
||||||
|
/// wasm32-wasi-musl => false
|
||||||
|
/// wasm32-freestanding-none => false
|
||||||
|
/// x86_64-windows-gnu => true
|
||||||
|
/// x86_64-windows-msvc => true
|
||||||
|
/// any-macos-any => false
|
||||||
|
pub const gnu_f16_abi = switch (builtin.cpu.arch) {
|
||||||
|
.wasm32, .wasm64 => false,
|
||||||
|
|
||||||
|
.arm, .armeb, .thumb, .thumbeb => switch (builtin.abi) {
|
||||||
|
.eabi, .eabihf => false,
|
||||||
|
else => true,
|
||||||
|
},
|
||||||
|
|
||||||
|
else => !builtin.os.tag.isDarwin(),
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const want_sparc_abi = builtin.cpu.arch.isSPARC();
|
||||||
|
|
||||||
|
// Avoid dragging in the runtime safety mechanisms into this .o file,
|
||||||
|
// unless we're trying to test compiler-rt.
|
||||||
|
pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace) noreturn {
|
||||||
|
_ = error_return_trace;
|
||||||
|
if (builtin.is_test) {
|
||||||
|
@setCold(true);
|
||||||
|
std.debug.panic("{s}", .{msg});
|
||||||
|
} else {
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// AArch64 is the only ABI (at the moment) to support f16 arguments without the
|
||||||
|
/// need for extending them to wider fp types.
|
||||||
|
/// TODO remove this; do this type selection in the language rather than
|
||||||
|
/// here in compiler-rt.
|
||||||
|
pub const F16T = if (builtin.cpu.arch.isAARCH64()) f16 else u16;
|
||||||
|
|
||||||
|
pub fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {
|
||||||
|
switch (Z) {
|
||||||
|
u16 => {
|
||||||
|
// 16x16 --> 32 bit multiply
|
||||||
|
const product = @as(u32, a) * @as(u32, b);
|
||||||
|
hi.* = @intCast(u16, product >> 16);
|
||||||
|
lo.* = @truncate(u16, product);
|
||||||
|
},
|
||||||
|
u32 => {
|
||||||
|
// 32x32 --> 64 bit multiply
|
||||||
|
const product = @as(u64, a) * @as(u64, b);
|
||||||
|
hi.* = @truncate(u32, product >> 32);
|
||||||
|
lo.* = @truncate(u32, product);
|
||||||
|
},
|
||||||
|
u64 => {
|
||||||
|
const S = struct {
|
||||||
|
fn loWord(x: u64) u64 {
|
||||||
|
return @truncate(u32, x);
|
||||||
|
}
|
||||||
|
fn hiWord(x: u64) u64 {
|
||||||
|
return @truncate(u32, x >> 32);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 64x64 -> 128 wide multiply for platforms that don't have such an operation;
|
||||||
|
// many 64-bit platforms have this operation, but they tend to have hardware
|
||||||
|
// floating-point, so we don't bother with a special case for them here.
|
||||||
|
// Each of the component 32x32 -> 64 products
|
||||||
|
const plolo: u64 = S.loWord(a) * S.loWord(b);
|
||||||
|
const plohi: u64 = S.loWord(a) * S.hiWord(b);
|
||||||
|
const philo: u64 = S.hiWord(a) * S.loWord(b);
|
||||||
|
const phihi: u64 = S.hiWord(a) * S.hiWord(b);
|
||||||
|
// Sum terms that contribute to lo in a way that allows us to get the carry
|
||||||
|
const r0: u64 = S.loWord(plolo);
|
||||||
|
const r1: u64 = S.hiWord(plolo) +% S.loWord(plohi) +% S.loWord(philo);
|
||||||
|
lo.* = r0 +% (r1 << 32);
|
||||||
|
// Sum terms contributing to hi with the carry from lo
|
||||||
|
hi.* = S.hiWord(plohi) +% S.hiWord(philo) +% S.hiWord(r1) +% phihi;
|
||||||
|
},
|
||||||
|
u128 => {
|
||||||
|
const Word_LoMask = @as(u64, 0x00000000ffffffff);
|
||||||
|
const Word_HiMask = @as(u64, 0xffffffff00000000);
|
||||||
|
const Word_FullMask = @as(u64, 0xffffffffffffffff);
|
||||||
|
const S = struct {
|
||||||
|
fn Word_1(x: u128) u64 {
|
||||||
|
return @truncate(u32, x >> 96);
|
||||||
|
}
|
||||||
|
fn Word_2(x: u128) u64 {
|
||||||
|
return @truncate(u32, x >> 64);
|
||||||
|
}
|
||||||
|
fn Word_3(x: u128) u64 {
|
||||||
|
return @truncate(u32, x >> 32);
|
||||||
|
}
|
||||||
|
fn Word_4(x: u128) u64 {
|
||||||
|
return @truncate(u32, x);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 128x128 -> 256 wide multiply for platforms that don't have such an operation;
|
||||||
|
// many 64-bit platforms have this operation, but they tend to have hardware
|
||||||
|
// floating-point, so we don't bother with a special case for them here.
|
||||||
|
|
||||||
|
const product11: u64 = S.Word_1(a) * S.Word_1(b);
|
||||||
|
const product12: u64 = S.Word_1(a) * S.Word_2(b);
|
||||||
|
const product13: u64 = S.Word_1(a) * S.Word_3(b);
|
||||||
|
const product14: u64 = S.Word_1(a) * S.Word_4(b);
|
||||||
|
const product21: u64 = S.Word_2(a) * S.Word_1(b);
|
||||||
|
const product22: u64 = S.Word_2(a) * S.Word_2(b);
|
||||||
|
const product23: u64 = S.Word_2(a) * S.Word_3(b);
|
||||||
|
const product24: u64 = S.Word_2(a) * S.Word_4(b);
|
||||||
|
const product31: u64 = S.Word_3(a) * S.Word_1(b);
|
||||||
|
const product32: u64 = S.Word_3(a) * S.Word_2(b);
|
||||||
|
const product33: u64 = S.Word_3(a) * S.Word_3(b);
|
||||||
|
const product34: u64 = S.Word_3(a) * S.Word_4(b);
|
||||||
|
const product41: u64 = S.Word_4(a) * S.Word_1(b);
|
||||||
|
const product42: u64 = S.Word_4(a) * S.Word_2(b);
|
||||||
|
const product43: u64 = S.Word_4(a) * S.Word_3(b);
|
||||||
|
const product44: u64 = S.Word_4(a) * S.Word_4(b);
|
||||||
|
|
||||||
|
const sum0: u128 = @as(u128, product44);
|
||||||
|
const sum1: u128 = @as(u128, product34) +%
|
||||||
|
@as(u128, product43);
|
||||||
|
const sum2: u128 = @as(u128, product24) +%
|
||||||
|
@as(u128, product33) +%
|
||||||
|
@as(u128, product42);
|
||||||
|
const sum3: u128 = @as(u128, product14) +%
|
||||||
|
@as(u128, product23) +%
|
||||||
|
@as(u128, product32) +%
|
||||||
|
@as(u128, product41);
|
||||||
|
const sum4: u128 = @as(u128, product13) +%
|
||||||
|
@as(u128, product22) +%
|
||||||
|
@as(u128, product31);
|
||||||
|
const sum5: u128 = @as(u128, product12) +%
|
||||||
|
@as(u128, product21);
|
||||||
|
const sum6: u128 = @as(u128, product11);
|
||||||
|
|
||||||
|
const r0: u128 = (sum0 & Word_FullMask) +%
|
||||||
|
((sum1 & Word_LoMask) << 32);
|
||||||
|
const r1: u128 = (sum0 >> 64) +%
|
||||||
|
((sum1 >> 32) & Word_FullMask) +%
|
||||||
|
(sum2 & Word_FullMask) +%
|
||||||
|
((sum3 << 32) & Word_HiMask);
|
||||||
|
|
||||||
|
lo.* = r0 +% (r1 << 64);
|
||||||
|
hi.* = (r1 >> 64) +%
|
||||||
|
(sum1 >> 96) +%
|
||||||
|
(sum2 >> 64) +%
|
||||||
|
(sum3 >> 32) +%
|
||||||
|
sum4 +%
|
||||||
|
(sum5 << 32) +%
|
||||||
|
(sum6 << 64);
|
||||||
|
},
|
||||||
|
else => @compileError("unsupported"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn normalize(comptime T: type, significand: *std.meta.Int(.unsigned, @typeInfo(T).Float.bits)) i32 {
|
||||||
|
const Z = std.meta.Int(.unsigned, @typeInfo(T).Float.bits);
|
||||||
|
const integerBit = @as(Z, 1) << std.math.floatFractionalBits(T);
|
||||||
|
|
||||||
|
const shift = @clz(Z, significand.*) - @clz(Z, integerBit);
|
||||||
|
significand.* <<= @intCast(std.math.Log2Int(Z), shift);
|
||||||
|
return @as(i32, 1) - shift;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn fneg(a: anytype) @TypeOf(a) {
|
||||||
|
const F = @TypeOf(a);
|
||||||
|
const bits = @typeInfo(F).Float.bits;
|
||||||
|
const U = @Type(.{ .Int = .{
|
||||||
|
.signedness = .unsigned,
|
||||||
|
.bits = bits,
|
||||||
|
} });
|
||||||
|
const sign_bit_mask = @as(U, 1) << (bits - 1);
|
||||||
|
const negated = @bitCast(U, a) ^ sign_bit_mask;
|
||||||
|
return @bitCast(F, negated);
|
||||||
|
}
|
||||||
@ -6,7 +6,15 @@ const std = @import("std");
|
|||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
const is_test = builtin.is_test;
|
const is_test = builtin.is_test;
|
||||||
|
|
||||||
const comparedf2 = @import("compareXf2.zig");
|
const __eqdf2 = @import("./cmpdf2.zig").__eqdf2;
|
||||||
|
const __ledf2 = @import("./cmpdf2.zig").__ledf2;
|
||||||
|
const __ltdf2 = @import("./cmpdf2.zig").__ltdf2;
|
||||||
|
const __nedf2 = @import("./cmpdf2.zig").__nedf2;
|
||||||
|
|
||||||
|
const __gedf2 = @import("./gedf2.zig").__gedf2;
|
||||||
|
const __gtdf2 = @import("./gedf2.zig").__gtdf2;
|
||||||
|
|
||||||
|
const __unorddf2 = @import("./unorddf2.zig").__unorddf2;
|
||||||
|
|
||||||
const TestVector = struct {
|
const TestVector = struct {
|
||||||
a: f64,
|
a: f64,
|
||||||
@ -21,25 +29,25 @@ const TestVector = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
fn test__cmpdf2(vector: TestVector) bool {
|
fn test__cmpdf2(vector: TestVector) bool {
|
||||||
if (comparedf2.__eqdf2(vector.a, vector.b) != vector.eqReference) {
|
if (__eqdf2(vector.a, vector.b) != vector.eqReference) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (comparedf2.__gedf2(vector.a, vector.b) != vector.geReference) {
|
if (__gedf2(vector.a, vector.b) != vector.geReference) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (comparedf2.__gtdf2(vector.a, vector.b) != vector.gtReference) {
|
if (__gtdf2(vector.a, vector.b) != vector.gtReference) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (comparedf2.__ledf2(vector.a, vector.b) != vector.leReference) {
|
if (__ledf2(vector.a, vector.b) != vector.leReference) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (comparedf2.__ltdf2(vector.a, vector.b) != vector.ltReference) {
|
if (__ltdf2(vector.a, vector.b) != vector.ltReference) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (comparedf2.__nedf2(vector.a, vector.b) != vector.neReference) {
|
if (__nedf2(vector.a, vector.b) != vector.neReference) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (comparedf2.__unorddf2(vector.a, vector.b) != vector.unReference) {
|
if (__unorddf2(vector.a, vector.b) != vector.unReference) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
118
lib/compiler_rt/comparef.zig
Normal file
118
lib/compiler_rt/comparef.zig
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
pub const LE = enum(i32) {
|
||||||
|
Less = -1,
|
||||||
|
Equal = 0,
|
||||||
|
Greater = 1,
|
||||||
|
|
||||||
|
const Unordered: LE = .Greater;
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const GE = enum(i32) {
|
||||||
|
Less = -1,
|
||||||
|
Equal = 0,
|
||||||
|
Greater = 1,
|
||||||
|
|
||||||
|
const Unordered: GE = .Less;
|
||||||
|
};
|
||||||
|
|
||||||
|
pub inline fn cmpf2(comptime T: type, comptime RT: type, a: T, b: T) RT {
|
||||||
|
const bits = @typeInfo(T).Float.bits;
|
||||||
|
const srep_t = std.meta.Int(.signed, bits);
|
||||||
|
const rep_t = std.meta.Int(.unsigned, bits);
|
||||||
|
|
||||||
|
const significandBits = std.math.floatMantissaBits(T);
|
||||||
|
const exponentBits = std.math.floatExponentBits(T);
|
||||||
|
const signBit = (@as(rep_t, 1) << (significandBits + exponentBits));
|
||||||
|
const absMask = signBit - 1;
|
||||||
|
const infT = comptime std.math.inf(T);
|
||||||
|
const infRep = @bitCast(rep_t, infT);
|
||||||
|
|
||||||
|
const aInt = @bitCast(srep_t, a);
|
||||||
|
const bInt = @bitCast(srep_t, b);
|
||||||
|
const aAbs = @bitCast(rep_t, aInt) & absMask;
|
||||||
|
const bAbs = @bitCast(rep_t, bInt) & absMask;
|
||||||
|
|
||||||
|
// If either a or b is NaN, they are unordered.
|
||||||
|
if (aAbs > infRep or bAbs > infRep) return RT.Unordered;
|
||||||
|
|
||||||
|
// If a and b are both zeros, they are equal.
|
||||||
|
if ((aAbs | bAbs) == 0) return .Equal;
|
||||||
|
|
||||||
|
// If at least one of a and b is positive, we get the same result comparing
|
||||||
|
// a and b as signed integers as we would with a floating-point compare.
|
||||||
|
if ((aInt & bInt) >= 0) {
|
||||||
|
if (aInt < bInt) {
|
||||||
|
return .Less;
|
||||||
|
} else if (aInt == bInt) {
|
||||||
|
return .Equal;
|
||||||
|
} else return .Greater;
|
||||||
|
} else {
|
||||||
|
// Otherwise, both are negative, so we need to flip the sense of the
|
||||||
|
// comparison to get the correct result. (This assumes a twos- or ones-
|
||||||
|
// complement integer representation; if integers are represented in a
|
||||||
|
// sign-magnitude representation, then this flip is incorrect).
|
||||||
|
if (aInt > bInt) {
|
||||||
|
return .Less;
|
||||||
|
} else if (aInt == bInt) {
|
||||||
|
return .Equal;
|
||||||
|
} else return .Greater;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn cmp_f80(comptime RT: type, a: f80, b: f80) RT {
|
||||||
|
const a_rep = std.math.break_f80(a);
|
||||||
|
const b_rep = std.math.break_f80(b);
|
||||||
|
const sig_bits = std.math.floatMantissaBits(f80);
|
||||||
|
const int_bit = 0x8000000000000000;
|
||||||
|
const sign_bit = 0x8000;
|
||||||
|
const special_exp = 0x7FFF;
|
||||||
|
|
||||||
|
// If either a or b is NaN, they are unordered.
|
||||||
|
if ((a_rep.exp & special_exp == special_exp and a_rep.fraction ^ int_bit != 0) or
|
||||||
|
(b_rep.exp & special_exp == special_exp and b_rep.fraction ^ int_bit != 0))
|
||||||
|
return RT.Unordered;
|
||||||
|
|
||||||
|
// If a and b are both zeros, they are equal.
|
||||||
|
if ((a_rep.fraction | b_rep.fraction) | ((a_rep.exp | b_rep.exp) & special_exp) == 0)
|
||||||
|
return .Equal;
|
||||||
|
|
||||||
|
if (@boolToInt(a_rep.exp == b_rep.exp) & @boolToInt(a_rep.fraction == b_rep.fraction) != 0) {
|
||||||
|
return .Equal;
|
||||||
|
} else if (a_rep.exp & sign_bit != b_rep.exp & sign_bit) {
|
||||||
|
// signs are different
|
||||||
|
if (@bitCast(i16, a_rep.exp) < @bitCast(i16, b_rep.exp)) {
|
||||||
|
return .Less;
|
||||||
|
} else {
|
||||||
|
return .Greater;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const a_fraction = a_rep.fraction | (@as(u80, a_rep.exp) << sig_bits);
|
||||||
|
const b_fraction = b_rep.fraction | (@as(u80, b_rep.exp) << sig_bits);
|
||||||
|
if (a_fraction < b_fraction) {
|
||||||
|
return .Less;
|
||||||
|
} else {
|
||||||
|
return .Greater;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn unordcmp(comptime T: type, a: T, b: T) i32 {
|
||||||
|
const rep_t = std.meta.Int(.unsigned, @typeInfo(T).Float.bits);
|
||||||
|
|
||||||
|
const significandBits = std.math.floatMantissaBits(T);
|
||||||
|
const exponentBits = std.math.floatExponentBits(T);
|
||||||
|
const signBit = (@as(rep_t, 1) << (significandBits + exponentBits));
|
||||||
|
const absMask = signBit - 1;
|
||||||
|
const infRep = @bitCast(rep_t, std.math.inf(T));
|
||||||
|
|
||||||
|
const aAbs: rep_t = @bitCast(rep_t, a) & absMask;
|
||||||
|
const bAbs: rep_t = @bitCast(rep_t, b) & absMask;
|
||||||
|
|
||||||
|
return @boolToInt(aAbs > infRep or bAbs > infRep);
|
||||||
|
}
|
||||||
|
|
||||||
|
test {
|
||||||
|
_ = @import("comparesf2_test.zig");
|
||||||
|
_ = @import("comparedf2_test.zig");
|
||||||
|
}
|
||||||
@ -6,7 +6,15 @@ const std = @import("std");
|
|||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
const is_test = builtin.is_test;
|
const is_test = builtin.is_test;
|
||||||
|
|
||||||
const comparesf2 = @import("compareXf2.zig");
|
const __eqsf2 = @import("./cmpsf2.zig").__eqsf2;
|
||||||
|
const __lesf2 = @import("./cmpsf2.zig").__lesf2;
|
||||||
|
const __ltsf2 = @import("./cmpsf2.zig").__ltsf2;
|
||||||
|
const __nesf2 = @import("./cmpsf2.zig").__nesf2;
|
||||||
|
|
||||||
|
const __gesf2 = @import("./gesf2.zig").__gesf2;
|
||||||
|
const __gtsf2 = @import("./gesf2.zig").__gtsf2;
|
||||||
|
|
||||||
|
const __unordsf2 = @import("./unordsf2.zig").__unordsf2;
|
||||||
|
|
||||||
const TestVector = struct {
|
const TestVector = struct {
|
||||||
a: f32,
|
a: f32,
|
||||||
@ -21,25 +29,25 @@ const TestVector = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
fn test__cmpsf2(vector: TestVector) bool {
|
fn test__cmpsf2(vector: TestVector) bool {
|
||||||
if (comparesf2.__eqsf2(vector.a, vector.b) != vector.eqReference) {
|
if (__eqsf2(vector.a, vector.b) != vector.eqReference) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (comparesf2.__gesf2(vector.a, vector.b) != vector.geReference) {
|
if (__gesf2(vector.a, vector.b) != vector.geReference) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (comparesf2.__gtsf2(vector.a, vector.b) != vector.gtReference) {
|
if (__gtsf2(vector.a, vector.b) != vector.gtReference) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (comparesf2.__lesf2(vector.a, vector.b) != vector.leReference) {
|
if (__lesf2(vector.a, vector.b) != vector.leReference) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (comparesf2.__ltsf2(vector.a, vector.b) != vector.ltReference) {
|
if (__ltsf2(vector.a, vector.b) != vector.ltReference) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (comparesf2.__nesf2(vector.a, vector.b) != vector.neReference) {
|
if (__nesf2(vector.a, vector.b) != vector.neReference) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (comparesf2.__unordsf2(vector.a, vector.b) != vector.unReference) {
|
if (__unordsf2(vector.a, vector.b) != vector.unReference) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
170
lib/compiler_rt/cos.zig
Normal file
170
lib/compiler_rt/cos.zig
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const builtin = @import("builtin");
|
||||||
|
const arch = builtin.cpu.arch;
|
||||||
|
const math = std.math;
|
||||||
|
const expect = std.testing.expect;
|
||||||
|
const common = @import("common.zig");
|
||||||
|
|
||||||
|
pub const panic = common.panic;
|
||||||
|
|
||||||
|
const trig = @import("trig.zig");
|
||||||
|
const rem_pio2 = @import("rem_pio2.zig").rem_pio2;
|
||||||
|
const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f;
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
@export(__cosh, .{ .name = "__cosh", .linkage = common.linkage });
|
||||||
|
@export(cosf, .{ .name = "cosf", .linkage = common.linkage });
|
||||||
|
@export(cos, .{ .name = "cos", .linkage = common.linkage });
|
||||||
|
@export(__cosx, .{ .name = "__cosx", .linkage = common.linkage });
|
||||||
|
const cosq_sym_name = if (common.want_ppc_abi) "cosf128" else "cosq";
|
||||||
|
@export(cosq, .{ .name = cosq_sym_name, .linkage = common.linkage });
|
||||||
|
@export(cosl, .{ .name = "cosl", .linkage = common.linkage });
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __cosh(a: f16) callconv(.C) f16 {
|
||||||
|
// TODO: more efficient implementation
|
||||||
|
return @floatCast(f16, cosf(a));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cosf(x: f32) callconv(.C) f32 {
|
||||||
|
// Small multiples of pi/2 rounded to double precision.
|
||||||
|
const c1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18
|
||||||
|
const c2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18
|
||||||
|
const c3pio2: f64 = 3.0 * math.pi / 2.0; // 0x4012D97C, 0x7F3321D2
|
||||||
|
const c4pio2: f64 = 4.0 * math.pi / 2.0; // 0x401921FB, 0x54442D18
|
||||||
|
|
||||||
|
var ix = @bitCast(u32, x);
|
||||||
|
const sign = ix >> 31 != 0;
|
||||||
|
ix &= 0x7fffffff;
|
||||||
|
|
||||||
|
if (ix <= 0x3f490fda) { // |x| ~<= pi/4
|
||||||
|
if (ix < 0x39800000) { // |x| < 2**-12
|
||||||
|
// raise inexact if x != 0
|
||||||
|
math.doNotOptimizeAway(x + 0x1p120);
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
return trig.__cosdf(x);
|
||||||
|
}
|
||||||
|
if (ix <= 0x407b53d1) { // |x| ~<= 5*pi/4
|
||||||
|
if (ix > 0x4016cbe3) { // |x| ~> 3*pi/4
|
||||||
|
return -trig.__cosdf(if (sign) x + c2pio2 else x - c2pio2);
|
||||||
|
} else {
|
||||||
|
if (sign) {
|
||||||
|
return trig.__sindf(x + c1pio2);
|
||||||
|
} else {
|
||||||
|
return trig.__sindf(c1pio2 - x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ix <= 0x40e231d5) { // |x| ~<= 9*pi/4
|
||||||
|
if (ix > 0x40afeddf) { // |x| ~> 7*pi/4
|
||||||
|
return trig.__cosdf(if (sign) x + c4pio2 else x - c4pio2);
|
||||||
|
} else {
|
||||||
|
if (sign) {
|
||||||
|
return trig.__sindf(-x - c3pio2);
|
||||||
|
} else {
|
||||||
|
return trig.__sindf(x - c3pio2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// cos(Inf or NaN) is NaN
|
||||||
|
if (ix >= 0x7f800000) {
|
||||||
|
return x - x;
|
||||||
|
}
|
||||||
|
|
||||||
|
var y: f64 = undefined;
|
||||||
|
const n = rem_pio2f(x, &y);
|
||||||
|
return switch (n & 3) {
|
||||||
|
0 => trig.__cosdf(y),
|
||||||
|
1 => trig.__sindf(-y),
|
||||||
|
2 => -trig.__cosdf(y),
|
||||||
|
else => trig.__sindf(y),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cos(x: f64) callconv(.C) f64 {
|
||||||
|
var ix = @bitCast(u64, x) >> 32;
|
||||||
|
ix &= 0x7fffffff;
|
||||||
|
|
||||||
|
// |x| ~< pi/4
|
||||||
|
if (ix <= 0x3fe921fb) {
|
||||||
|
if (ix < 0x3e46a09e) { // |x| < 2**-27 * sqrt(2)
|
||||||
|
// raise inexact if x!=0
|
||||||
|
math.doNotOptimizeAway(x + 0x1p120);
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
return trig.__cos(x, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// cos(Inf or NaN) is NaN
|
||||||
|
if (ix >= 0x7ff00000) {
|
||||||
|
return x - x;
|
||||||
|
}
|
||||||
|
|
||||||
|
var y: [2]f64 = undefined;
|
||||||
|
const n = rem_pio2(x, &y);
|
||||||
|
return switch (n & 3) {
|
||||||
|
0 => trig.__cos(y[0], y[1]),
|
||||||
|
1 => -trig.__sin(y[0], y[1], 1),
|
||||||
|
2 => -trig.__cos(y[0], y[1]),
|
||||||
|
else => trig.__sin(y[0], y[1], 1),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __cosx(a: f80) callconv(.C) f80 {
|
||||||
|
// TODO: more efficient implementation
|
||||||
|
return @floatCast(f80, cosq(a));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cosq(a: f128) callconv(.C) f128 {
|
||||||
|
// TODO: more correct implementation
|
||||||
|
return cos(@floatCast(f64, a));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cosl(x: c_longdouble) callconv(.C) c_longdouble {
|
||||||
|
switch (@typeInfo(c_longdouble).Float.bits) {
|
||||||
|
16 => return __cosh(x),
|
||||||
|
32 => return cosf(x),
|
||||||
|
64 => return cos(x),
|
||||||
|
80 => return __cosx(x),
|
||||||
|
128 => return cosq(x),
|
||||||
|
else => @compileError("unreachable"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "cos32" {
|
||||||
|
const epsilon = 0.00001;
|
||||||
|
|
||||||
|
try expect(math.approxEqAbs(f32, cosf(0.0), 1.0, epsilon));
|
||||||
|
try expect(math.approxEqAbs(f32, cosf(0.2), 0.980067, epsilon));
|
||||||
|
try expect(math.approxEqAbs(f32, cosf(0.8923), 0.627623, epsilon));
|
||||||
|
try expect(math.approxEqAbs(f32, cosf(1.5), 0.070737, epsilon));
|
||||||
|
try expect(math.approxEqAbs(f32, cosf(-1.5), 0.070737, epsilon));
|
||||||
|
try expect(math.approxEqAbs(f32, cosf(37.45), 0.969132, epsilon));
|
||||||
|
try expect(math.approxEqAbs(f32, cosf(89.123), 0.400798, epsilon));
|
||||||
|
}
|
||||||
|
|
||||||
|
test "cos64" {
|
||||||
|
const epsilon = 0.000001;
|
||||||
|
|
||||||
|
try expect(math.approxEqAbs(f64, cos(0.0), 1.0, epsilon));
|
||||||
|
try expect(math.approxEqAbs(f64, cos(0.2), 0.980067, epsilon));
|
||||||
|
try expect(math.approxEqAbs(f64, cos(0.8923), 0.627623, epsilon));
|
||||||
|
try expect(math.approxEqAbs(f64, cos(1.5), 0.070737, epsilon));
|
||||||
|
try expect(math.approxEqAbs(f64, cos(-1.5), 0.070737, epsilon));
|
||||||
|
try expect(math.approxEqAbs(f64, cos(37.45), 0.969132, epsilon));
|
||||||
|
try expect(math.approxEqAbs(f64, cos(89.123), 0.40080, epsilon));
|
||||||
|
}
|
||||||
|
|
||||||
|
test "cos32.special" {
|
||||||
|
try expect(math.isNan(cosf(math.inf(f32))));
|
||||||
|
try expect(math.isNan(cosf(-math.inf(f32))));
|
||||||
|
try expect(math.isNan(cosf(math.nan(f32))));
|
||||||
|
}
|
||||||
|
|
||||||
|
test "cos64.special" {
|
||||||
|
try expect(math.isNan(cos(math.inf(f64))));
|
||||||
|
try expect(math.isNan(cos(-math.inf(f64))));
|
||||||
|
try expect(math.isNan(cos(math.nan(f64))));
|
||||||
|
}
|
||||||
@ -1,5 +1,21 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
|
const is_test = builtin.is_test;
|
||||||
|
const common = @import("common.zig");
|
||||||
|
|
||||||
|
pub const panic = common.panic;
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
@export(__clzsi2, .{ .name = "__clzsi2", .linkage = common.linkage });
|
||||||
|
@export(__clzdi2, .{ .name = "__clzdi2", .linkage = common.linkage });
|
||||||
|
@export(__clzti2, .{ .name = "__clzti2", .linkage = common.linkage });
|
||||||
|
@export(__ctzsi2, .{ .name = "__ctzsi2", .linkage = common.linkage });
|
||||||
|
@export(__ctzdi2, .{ .name = "__ctzdi2", .linkage = common.linkage });
|
||||||
|
@export(__ctzti2, .{ .name = "__ctzti2", .linkage = common.linkage });
|
||||||
|
@export(__ffssi2, .{ .name = "__ffssi2", .linkage = common.linkage });
|
||||||
|
@export(__ffsdi2, .{ .name = "__ffsdi2", .linkage = common.linkage });
|
||||||
|
@export(__ffsti2, .{ .name = "__ffsti2", .linkage = common.linkage });
|
||||||
|
}
|
||||||
|
|
||||||
// clz - count leading zeroes
|
// clz - count leading zeroes
|
||||||
// - clzXi2 for unoptimized little and big endian
|
// - clzXi2 for unoptimized little and big endian
|
||||||
@ -15,8 +31,6 @@ const builtin = @import("builtin");
|
|||||||
// - ffsXi2 for unoptimized little and big endian
|
// - ffsXi2 for unoptimized little and big endian
|
||||||
|
|
||||||
inline fn clzXi2(comptime T: type, a: T) i32 {
|
inline fn clzXi2(comptime T: type, a: T) i32 {
|
||||||
@setRuntimeSafety(builtin.is_test);
|
|
||||||
|
|
||||||
var x = switch (@bitSizeOf(T)) {
|
var x = switch (@bitSizeOf(T)) {
|
||||||
32 => @bitCast(u32, a),
|
32 => @bitCast(u32, a),
|
||||||
64 => @bitCast(u64, a),
|
64 => @bitCast(u64, a),
|
||||||
@ -154,8 +168,6 @@ pub fn __clzti2(a: i128) callconv(.C) i32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline fn ctzXi2(comptime T: type, a: T) i32 {
|
inline fn ctzXi2(comptime T: type, a: T) i32 {
|
||||||
@setRuntimeSafety(builtin.is_test);
|
|
||||||
|
|
||||||
var x = switch (@bitSizeOf(T)) {
|
var x = switch (@bitSizeOf(T)) {
|
||||||
32 => @bitCast(u32, a),
|
32 => @bitCast(u32, a),
|
||||||
64 => @bitCast(u64, a),
|
64 => @bitCast(u64, a),
|
||||||
@ -191,8 +203,6 @@ pub fn __ctzti2(a: i128) callconv(.C) i32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline fn ffsXi2(comptime T: type, a: T) i32 {
|
inline fn ffsXi2(comptime T: type, a: T) i32 {
|
||||||
@setRuntimeSafety(builtin.is_test);
|
|
||||||
|
|
||||||
var x = switch (@bitSizeOf(T)) {
|
var x = switch (@bitSizeOf(T)) {
|
||||||
32 => @bitCast(u32, a),
|
32 => @bitCast(u32, a),
|
||||||
64 => @bitCast(u64, a),
|
64 => @bitCast(u64, a),
|
||||||
@ -1,12 +1,35 @@
|
|||||||
// Ported from:
|
//! Ported from:
|
||||||
//
|
//!
|
||||||
// https://github.com/llvm/llvm-project/commit/d674d96bc56c0f377879d01c9d8dfdaaa7859cdb/compiler-rt/lib/builtins/divdf3.c
|
//! https://github.com/llvm/llvm-project/commit/d674d96bc56c0f377879d01c9d8dfdaaa7859cdb/compiler-rt/lib/builtins/divdf3.c
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
|
const arch = builtin.cpu.arch;
|
||||||
|
const is_test = builtin.is_test;
|
||||||
|
const common = @import("common.zig");
|
||||||
|
|
||||||
|
const normalize = common.normalize;
|
||||||
|
const wideMultiply = common.wideMultiply;
|
||||||
|
|
||||||
|
pub const panic = common.panic;
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
if (common.want_aeabi) {
|
||||||
|
@export(__aeabi_ddiv, .{ .name = "__aeabi_ddiv", .linkage = common.linkage });
|
||||||
|
} else {
|
||||||
|
@export(__divdf3, .{ .name = "__divdf3", .linkage = common.linkage });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn __divdf3(a: f64, b: f64) callconv(.C) f64 {
|
pub fn __divdf3(a: f64, b: f64) callconv(.C) f64 {
|
||||||
@setRuntimeSafety(builtin.is_test);
|
return div(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __aeabi_ddiv(a: f64, b: f64) callconv(.AAPCS) f64 {
|
||||||
|
return div(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn div(a: f64, b: f64) f64 {
|
||||||
const Z = std.meta.Int(.unsigned, 64);
|
const Z = std.meta.Int(.unsigned, 64);
|
||||||
const SignedZ = std.meta.Int(.signed, 64);
|
const SignedZ = std.meta.Int(.signed, 64);
|
||||||
|
|
||||||
@ -202,131 +225,6 @@ pub fn __divdf3(a: f64, b: f64) callconv(.C) f64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {
|
|
||||||
@setRuntimeSafety(builtin.is_test);
|
|
||||||
switch (Z) {
|
|
||||||
u32 => {
|
|
||||||
// 32x32 --> 64 bit multiply
|
|
||||||
const product = @as(u64, a) * @as(u64, b);
|
|
||||||
hi.* = @truncate(u32, product >> 32);
|
|
||||||
lo.* = @truncate(u32, product);
|
|
||||||
},
|
|
||||||
u64 => {
|
|
||||||
const S = struct {
|
|
||||||
fn loWord(x: u64) u64 {
|
|
||||||
return @truncate(u32, x);
|
|
||||||
}
|
|
||||||
fn hiWord(x: u64) u64 {
|
|
||||||
return @truncate(u32, x >> 32);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// 64x64 -> 128 wide multiply for platforms that don't have such an operation;
|
|
||||||
// many 64-bit platforms have this operation, but they tend to have hardware
|
|
||||||
// floating-point, so we don't bother with a special case for them here.
|
|
||||||
// Each of the component 32x32 -> 64 products
|
|
||||||
const plolo: u64 = S.loWord(a) * S.loWord(b);
|
|
||||||
const plohi: u64 = S.loWord(a) * S.hiWord(b);
|
|
||||||
const philo: u64 = S.hiWord(a) * S.loWord(b);
|
|
||||||
const phihi: u64 = S.hiWord(a) * S.hiWord(b);
|
|
||||||
// Sum terms that contribute to lo in a way that allows us to get the carry
|
|
||||||
const r0: u64 = S.loWord(plolo);
|
|
||||||
const r1: u64 = S.hiWord(plolo) +% S.loWord(plohi) +% S.loWord(philo);
|
|
||||||
lo.* = r0 +% (r1 << 32);
|
|
||||||
// Sum terms contributing to hi with the carry from lo
|
|
||||||
hi.* = S.hiWord(plohi) +% S.hiWord(philo) +% S.hiWord(r1) +% phihi;
|
|
||||||
},
|
|
||||||
u128 => {
|
|
||||||
const Word_LoMask = @as(u64, 0x00000000ffffffff);
|
|
||||||
const Word_HiMask = @as(u64, 0xffffffff00000000);
|
|
||||||
const Word_FullMask = @as(u64, 0xffffffffffffffff);
|
|
||||||
const S = struct {
|
|
||||||
fn Word_1(x: u128) u64 {
|
|
||||||
return @truncate(u32, x >> 96);
|
|
||||||
}
|
|
||||||
fn Word_2(x: u128) u64 {
|
|
||||||
return @truncate(u32, x >> 64);
|
|
||||||
}
|
|
||||||
fn Word_3(x: u128) u64 {
|
|
||||||
return @truncate(u32, x >> 32);
|
|
||||||
}
|
|
||||||
fn Word_4(x: u128) u64 {
|
|
||||||
return @truncate(u32, x);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// 128x128 -> 256 wide multiply for platforms that don't have such an operation;
|
|
||||||
// many 64-bit platforms have this operation, but they tend to have hardware
|
|
||||||
// floating-point, so we don't bother with a special case for them here.
|
|
||||||
|
|
||||||
const product11: u64 = S.Word_1(a) * S.Word_1(b);
|
|
||||||
const product12: u64 = S.Word_1(a) * S.Word_2(b);
|
|
||||||
const product13: u64 = S.Word_1(a) * S.Word_3(b);
|
|
||||||
const product14: u64 = S.Word_1(a) * S.Word_4(b);
|
|
||||||
const product21: u64 = S.Word_2(a) * S.Word_1(b);
|
|
||||||
const product22: u64 = S.Word_2(a) * S.Word_2(b);
|
|
||||||
const product23: u64 = S.Word_2(a) * S.Word_3(b);
|
|
||||||
const product24: u64 = S.Word_2(a) * S.Word_4(b);
|
|
||||||
const product31: u64 = S.Word_3(a) * S.Word_1(b);
|
|
||||||
const product32: u64 = S.Word_3(a) * S.Word_2(b);
|
|
||||||
const product33: u64 = S.Word_3(a) * S.Word_3(b);
|
|
||||||
const product34: u64 = S.Word_3(a) * S.Word_4(b);
|
|
||||||
const product41: u64 = S.Word_4(a) * S.Word_1(b);
|
|
||||||
const product42: u64 = S.Word_4(a) * S.Word_2(b);
|
|
||||||
const product43: u64 = S.Word_4(a) * S.Word_3(b);
|
|
||||||
const product44: u64 = S.Word_4(a) * S.Word_4(b);
|
|
||||||
|
|
||||||
const sum0: u128 = @as(u128, product44);
|
|
||||||
const sum1: u128 = @as(u128, product34) +%
|
|
||||||
@as(u128, product43);
|
|
||||||
const sum2: u128 = @as(u128, product24) +%
|
|
||||||
@as(u128, product33) +%
|
|
||||||
@as(u128, product42);
|
|
||||||
const sum3: u128 = @as(u128, product14) +%
|
|
||||||
@as(u128, product23) +%
|
|
||||||
@as(u128, product32) +%
|
|
||||||
@as(u128, product41);
|
|
||||||
const sum4: u128 = @as(u128, product13) +%
|
|
||||||
@as(u128, product22) +%
|
|
||||||
@as(u128, product31);
|
|
||||||
const sum5: u128 = @as(u128, product12) +%
|
|
||||||
@as(u128, product21);
|
|
||||||
const sum6: u128 = @as(u128, product11);
|
|
||||||
|
|
||||||
const r0: u128 = (sum0 & Word_FullMask) +%
|
|
||||||
((sum1 & Word_LoMask) << 32);
|
|
||||||
const r1: u128 = (sum0 >> 64) +%
|
|
||||||
((sum1 >> 32) & Word_FullMask) +%
|
|
||||||
(sum2 & Word_FullMask) +%
|
|
||||||
((sum3 << 32) & Word_HiMask);
|
|
||||||
|
|
||||||
lo.* = r0 +% (r1 << 64);
|
|
||||||
hi.* = (r1 >> 64) +%
|
|
||||||
(sum1 >> 96) +%
|
|
||||||
(sum2 >> 64) +%
|
|
||||||
(sum3 >> 32) +%
|
|
||||||
sum4 +%
|
|
||||||
(sum5 << 32) +%
|
|
||||||
(sum6 << 64);
|
|
||||||
},
|
|
||||||
else => @compileError("unsupported"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn normalize(comptime T: type, significand: *std.meta.Int(.unsigned, @typeInfo(T).Float.bits)) i32 {
|
|
||||||
@setRuntimeSafety(builtin.is_test);
|
|
||||||
const Z = std.meta.Int(.unsigned, @typeInfo(T).Float.bits);
|
|
||||||
const significandBits = std.math.floatMantissaBits(T);
|
|
||||||
const implicitBit = @as(Z, 1) << significandBits;
|
|
||||||
|
|
||||||
const shift = @clz(Z, significand.*) - @clz(Z, implicitBit);
|
|
||||||
significand.* <<= @intCast(std.math.Log2Int(Z), shift);
|
|
||||||
return 1 - shift;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn __aeabi_ddiv(a: f64, b: f64) callconv(.AAPCS) f64 {
|
|
||||||
@setRuntimeSafety(false);
|
|
||||||
return @call(.{ .modifier = .always_inline }, __divdf3, .{ a, b });
|
|
||||||
}
|
|
||||||
|
|
||||||
test {
|
test {
|
||||||
_ = @import("divdf3_test.zig");
|
_ = @import("divdf3_test.zig");
|
||||||
}
|
}
|
||||||
@ -1,12 +1,33 @@
|
|||||||
// Ported from:
|
//! Ported from:
|
||||||
//
|
//!
|
||||||
// https://github.com/llvm/llvm-project/commit/d674d96bc56c0f377879d01c9d8dfdaaa7859cdb/compiler-rt/lib/builtins/divsf3.c
|
//! https://github.com/llvm/llvm-project/commit/d674d96bc56c0f377879d01c9d8dfdaaa7859cdb/compiler-rt/lib/builtins/divsf3.c
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
|
const arch = builtin.cpu.arch;
|
||||||
|
|
||||||
|
const common = @import("common.zig");
|
||||||
|
const normalize = common.normalize;
|
||||||
|
|
||||||
|
pub const panic = common.panic;
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
if (common.want_aeabi) {
|
||||||
|
@export(__aeabi_fdiv, .{ .name = "__aeabi_fdiv", .linkage = common.linkage });
|
||||||
|
} else {
|
||||||
|
@export(__divsf3, .{ .name = "__divsf3", .linkage = common.linkage });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn __divsf3(a: f32, b: f32) callconv(.C) f32 {
|
pub fn __divsf3(a: f32, b: f32) callconv(.C) f32 {
|
||||||
@setRuntimeSafety(builtin.is_test);
|
return div(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __aeabi_fdiv(a: f32, b: f32) callconv(.AAPCS) f32 {
|
||||||
|
return div(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn div(a: f32, b: f32) f32 {
|
||||||
const Z = std.meta.Int(.unsigned, 32);
|
const Z = std.meta.Int(.unsigned, 32);
|
||||||
|
|
||||||
const significandBits = std.math.floatMantissaBits(f32);
|
const significandBits = std.math.floatMantissaBits(f32);
|
||||||
@ -184,22 +205,6 @@ pub fn __divsf3(a: f32, b: f32) callconv(.C) f32 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn normalize(comptime T: type, significand: *std.meta.Int(.unsigned, @typeInfo(T).Float.bits)) i32 {
|
|
||||||
@setRuntimeSafety(builtin.is_test);
|
|
||||||
const Z = std.meta.Int(.unsigned, @typeInfo(T).Float.bits);
|
|
||||||
const significandBits = std.math.floatMantissaBits(T);
|
|
||||||
const implicitBit = @as(Z, 1) << significandBits;
|
|
||||||
|
|
||||||
const shift = @clz(Z, significand.*) - @clz(Z, implicitBit);
|
|
||||||
significand.* <<= @intCast(std.math.Log2Int(Z), shift);
|
|
||||||
return 1 - shift;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn __aeabi_fdiv(a: f32, b: f32) callconv(.AAPCS) f32 {
|
|
||||||
@setRuntimeSafety(false);
|
|
||||||
return @call(.{ .modifier = .always_inline }, __divsf3, .{ a, b });
|
|
||||||
}
|
|
||||||
|
|
||||||
test {
|
test {
|
||||||
_ = @import("divsf3_test.zig");
|
_ = @import("divsf3_test.zig");
|
||||||
}
|
}
|
||||||
@ -1,11 +1,35 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
|
|
||||||
const normalize = @import("divdf3.zig").normalize;
|
const common = @import("common.zig");
|
||||||
const wideMultiply = @import("divdf3.zig").wideMultiply;
|
const normalize = common.normalize;
|
||||||
|
const wideMultiply = common.wideMultiply;
|
||||||
|
|
||||||
|
pub const panic = common.panic;
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
if (common.want_ppc_abi) {
|
||||||
|
@export(__divkf3, .{ .name = "__divkf3", .linkage = common.linkage });
|
||||||
|
} else if (common.want_sparc_abi) {
|
||||||
|
@export(_Qp_div, .{ .name = "_Qp_div", .linkage = common.linkage });
|
||||||
|
} else {
|
||||||
|
@export(__divtf3, .{ .name = "__divtf3", .linkage = common.linkage });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn __divtf3(a: f128, b: f128) callconv(.C) f128 {
|
pub fn __divtf3(a: f128, b: f128) callconv(.C) f128 {
|
||||||
@setRuntimeSafety(builtin.is_test);
|
return div(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __divkf3(a: f128, b: f128) callconv(.C) f128 {
|
||||||
|
return div(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _Qp_div(c: *f128, a: *const f128, b: *const f128) callconv(.C) void {
|
||||||
|
c.* = div(a.*, b.*);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn div(a: f128, b: f128) f128 {
|
||||||
const Z = std.meta.Int(.unsigned, 128);
|
const Z = std.meta.Int(.unsigned, 128);
|
||||||
|
|
||||||
const significandBits = std.math.floatMantissaBits(f128);
|
const significandBits = std.math.floatMantissaBits(f128);
|
||||||
@ -34,8 +34,12 @@ test "divtf3" {
|
|||||||
try test__divtf3(math.qnan_f128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0);
|
try test__divtf3(math.qnan_f128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0);
|
||||||
// NaN / any = NaN
|
// NaN / any = NaN
|
||||||
try test__divtf3(math.nan_f128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0);
|
try test__divtf3(math.nan_f128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0);
|
||||||
// inf / any = inf
|
// inf / any(except inf and nan) = inf
|
||||||
try test__divtf3(math.inf_f128, 0x1.23456789abcdefp+5, 0x7fff000000000000, 0);
|
try test__divtf3(math.inf(f128), 0x1.23456789abcdefp+5, 0x7fff000000000000, 0);
|
||||||
|
// inf / inf = nan
|
||||||
|
try test__divtf3(math.inf(f128), math.inf(f128), 0x7fff800000000000, 0);
|
||||||
|
// inf / nan = nan
|
||||||
|
try test__divtf3(math.inf(f128), math.nan(f128), 0x7fff800000000000, 0);
|
||||||
|
|
||||||
try test__divtf3(0x1.a23b45362464523375893ab4cdefp+5, 0x1.eedcbaba3a94546558237654321fp-1, 0x4004b0b72924d407, 0x0717e84356c6eba2);
|
try test__divtf3(0x1.a23b45362464523375893ab4cdefp+5, 0x1.eedcbaba3a94546558237654321fp-1, 0x4004b0b72924d407, 0x0717e84356c6eba2);
|
||||||
try test__divtf3(0x1.a2b34c56d745382f9abf2c3dfeffp-50, 0x1.ed2c3ba15935332532287654321fp-9, 0x3fd5b2af3f828c9b, 0x40e51f64cde8b1f2);
|
try test__divtf3(0x1.a2b34c56d745382f9abf2c3dfeffp-50, 0x1.ed2c3ba15935332532287654321fp-9, 0x3fd5b2af3f828c9b, 0x40e51f64cde8b1f2);
|
||||||
54
lib/compiler_rt/divti3.zig
Normal file
54
lib/compiler_rt/divti3.zig
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const builtin = @import("builtin");
|
||||||
|
const udivmod = @import("udivmod.zig").udivmod;
|
||||||
|
const arch = builtin.cpu.arch;
|
||||||
|
const common = @import("common.zig");
|
||||||
|
|
||||||
|
pub const panic = common.panic;
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
if (builtin.os.tag == .windows) {
|
||||||
|
switch (arch) {
|
||||||
|
.i386 => {
|
||||||
|
@export(__divti3, .{ .name = "__divti3", .linkage = common.linkage });
|
||||||
|
},
|
||||||
|
.x86_64 => {
|
||||||
|
// The "ti" functions must use Vector(2, u64) parameter types to adhere to the ABI
|
||||||
|
// that LLVM expects compiler-rt to have.
|
||||||
|
@export(__divti3_windows_x86_64, .{ .name = "__divti3", .linkage = common.linkage });
|
||||||
|
},
|
||||||
|
else => {},
|
||||||
|
}
|
||||||
|
if (arch.isAARCH64()) {
|
||||||
|
@export(__divti3, .{ .name = "__divti3", .linkage = common.linkage });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
@export(__divti3, .{ .name = "__divti3", .linkage = common.linkage });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __divti3(a: i128, b: i128) callconv(.C) i128 {
|
||||||
|
return div(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
const v128 = @import("std").meta.Vector(2, u64);
|
||||||
|
|
||||||
|
fn __divti3_windows_x86_64(a: v128, b: v128) callconv(.C) v128 {
|
||||||
|
return @bitCast(v128, div(@bitCast(i128, a), @bitCast(i128, b)));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn div(a: i128, b: i128) i128 {
|
||||||
|
const s_a = a >> (128 - 1);
|
||||||
|
const s_b = b >> (128 - 1);
|
||||||
|
|
||||||
|
const an = (a ^ s_a) -% s_a;
|
||||||
|
const bn = (b ^ s_b) -% s_b;
|
||||||
|
|
||||||
|
const r = udivmod(u128, @bitCast(u128, an), @bitCast(u128, bn), null);
|
||||||
|
const s = s_a ^ s_b;
|
||||||
|
return (@bitCast(i128, r) ^ s) -% s;
|
||||||
|
}
|
||||||
|
|
||||||
|
test {
|
||||||
|
_ = @import("divti3_test.zig");
|
||||||
|
}
|
||||||
210
lib/compiler_rt/divxf3.zig
Normal file
210
lib/compiler_rt/divxf3.zig
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const builtin = @import("builtin");
|
||||||
|
const arch = builtin.cpu.arch;
|
||||||
|
|
||||||
|
const common = @import("common.zig");
|
||||||
|
const normalize = common.normalize;
|
||||||
|
const wideMultiply = common.wideMultiply;
|
||||||
|
|
||||||
|
pub const panic = common.panic;
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
@export(__divxf3, .{ .name = "__divxf3", .linkage = common.linkage });
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __divxf3(a: f80, b: f80) callconv(.C) f80 {
|
||||||
|
const T = f80;
|
||||||
|
const Z = std.meta.Int(.unsigned, @bitSizeOf(T));
|
||||||
|
|
||||||
|
const significandBits = std.math.floatMantissaBits(T);
|
||||||
|
const fractionalBits = std.math.floatFractionalBits(T);
|
||||||
|
const exponentBits = std.math.floatExponentBits(T);
|
||||||
|
|
||||||
|
const signBit = (@as(Z, 1) << (significandBits + exponentBits));
|
||||||
|
const maxExponent = ((1 << exponentBits) - 1);
|
||||||
|
const exponentBias = (maxExponent >> 1);
|
||||||
|
|
||||||
|
const integerBit = (@as(Z, 1) << fractionalBits);
|
||||||
|
const quietBit = integerBit >> 1;
|
||||||
|
const significandMask = (@as(Z, 1) << significandBits) - 1;
|
||||||
|
|
||||||
|
const absMask = signBit - 1;
|
||||||
|
const qnanRep = @bitCast(Z, std.math.nan(T)) | quietBit;
|
||||||
|
const infRep = @bitCast(Z, std.math.inf(T));
|
||||||
|
|
||||||
|
const aExponent = @truncate(u32, (@bitCast(Z, a) >> significandBits) & maxExponent);
|
||||||
|
const bExponent = @truncate(u32, (@bitCast(Z, b) >> significandBits) & maxExponent);
|
||||||
|
const quotientSign: Z = (@bitCast(Z, a) ^ @bitCast(Z, b)) & signBit;
|
||||||
|
|
||||||
|
var aSignificand: Z = @bitCast(Z, a) & significandMask;
|
||||||
|
var bSignificand: Z = @bitCast(Z, b) & significandMask;
|
||||||
|
var scale: i32 = 0;
|
||||||
|
|
||||||
|
// Detect if a or b is zero, denormal, infinity, or NaN.
|
||||||
|
if (aExponent -% 1 >= maxExponent - 1 or bExponent -% 1 >= maxExponent - 1) {
|
||||||
|
const aAbs: Z = @bitCast(Z, a) & absMask;
|
||||||
|
const bAbs: Z = @bitCast(Z, b) & absMask;
|
||||||
|
|
||||||
|
// NaN / anything = qNaN
|
||||||
|
if (aAbs > infRep) return @bitCast(T, @bitCast(Z, a) | quietBit);
|
||||||
|
// anything / NaN = qNaN
|
||||||
|
if (bAbs > infRep) return @bitCast(T, @bitCast(Z, b) | quietBit);
|
||||||
|
|
||||||
|
if (aAbs == infRep) {
|
||||||
|
// infinity / infinity = NaN
|
||||||
|
if (bAbs == infRep) {
|
||||||
|
return @bitCast(T, qnanRep);
|
||||||
|
}
|
||||||
|
// infinity / anything else = +/- infinity
|
||||||
|
else {
|
||||||
|
return @bitCast(T, aAbs | quotientSign);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// anything else / infinity = +/- 0
|
||||||
|
if (bAbs == infRep) return @bitCast(T, quotientSign);
|
||||||
|
|
||||||
|
if (aAbs == 0) {
|
||||||
|
// zero / zero = NaN
|
||||||
|
if (bAbs == 0) {
|
||||||
|
return @bitCast(T, qnanRep);
|
||||||
|
}
|
||||||
|
// zero / anything else = +/- zero
|
||||||
|
else {
|
||||||
|
return @bitCast(T, quotientSign);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// anything else / zero = +/- infinity
|
||||||
|
if (bAbs == 0) return @bitCast(T, infRep | quotientSign);
|
||||||
|
|
||||||
|
// one or both of a or b is denormal, the other (if applicable) is a
|
||||||
|
// normal number. Renormalize one or both of a and b, and set scale to
|
||||||
|
// include the necessary exponent adjustment.
|
||||||
|
if (aAbs < integerBit) scale +%= normalize(T, &aSignificand);
|
||||||
|
if (bAbs < integerBit) scale -%= normalize(T, &bSignificand);
|
||||||
|
}
|
||||||
|
var quotientExponent: i32 = @bitCast(i32, aExponent -% bExponent) +% scale;
|
||||||
|
|
||||||
|
// Align the significand of b as a Q63 fixed-point number in the range
|
||||||
|
// [1, 2.0) and get a Q64 approximate reciprocal using a small minimax
|
||||||
|
// polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2. This
|
||||||
|
// is accurate to about 3.5 binary digits.
|
||||||
|
const q63b = @intCast(u64, bSignificand);
|
||||||
|
var recip64 = @as(u64, 0x7504f333F9DE6484) -% q63b;
|
||||||
|
// 0x7504f333F9DE6484 / 2^64 + 1 = 3/4 + 1/sqrt(2)
|
||||||
|
|
||||||
|
// Now refine the reciprocal estimate using a Newton-Raphson iteration:
|
||||||
|
//
|
||||||
|
// x1 = x0 * (2 - x0 * b)
|
||||||
|
//
|
||||||
|
// This doubles the number of correct binary digits in the approximation
|
||||||
|
// with each iteration.
|
||||||
|
var correction64: u64 = undefined;
|
||||||
|
correction64 = @truncate(u64, ~(@as(u128, recip64) *% q63b >> 64) +% 1);
|
||||||
|
recip64 = @truncate(u64, @as(u128, recip64) *% correction64 >> 63);
|
||||||
|
correction64 = @truncate(u64, ~(@as(u128, recip64) *% q63b >> 64) +% 1);
|
||||||
|
recip64 = @truncate(u64, @as(u128, recip64) *% correction64 >> 63);
|
||||||
|
correction64 = @truncate(u64, ~(@as(u128, recip64) *% q63b >> 64) +% 1);
|
||||||
|
recip64 = @truncate(u64, @as(u128, recip64) *% correction64 >> 63);
|
||||||
|
correction64 = @truncate(u64, ~(@as(u128, recip64) *% q63b >> 64) +% 1);
|
||||||
|
recip64 = @truncate(u64, @as(u128, recip64) *% correction64 >> 63);
|
||||||
|
correction64 = @truncate(u64, ~(@as(u128, recip64) *% q63b >> 64) +% 1);
|
||||||
|
recip64 = @truncate(u64, @as(u128, recip64) *% correction64 >> 63);
|
||||||
|
|
||||||
|
// The reciprocal may have overflowed to zero if the upper half of b is
|
||||||
|
// exactly 1.0. This would sabatoge the full-width final stage of the
|
||||||
|
// computation that follows, so we adjust the reciprocal down by one bit.
|
||||||
|
recip64 -%= 1;
|
||||||
|
|
||||||
|
// We need to perform one more iteration to get us to 112 binary digits;
|
||||||
|
// The last iteration needs to happen with extra precision.
|
||||||
|
|
||||||
|
// NOTE: This operation is equivalent to __multi3, which is not implemented
|
||||||
|
// in some architechures
|
||||||
|
var reciprocal: u128 = undefined;
|
||||||
|
var correction: u128 = undefined;
|
||||||
|
var dummy: u128 = undefined;
|
||||||
|
wideMultiply(u128, recip64, q63b, &dummy, &correction);
|
||||||
|
|
||||||
|
correction = -%correction;
|
||||||
|
|
||||||
|
const cHi = @truncate(u64, correction >> 64);
|
||||||
|
const cLo = @truncate(u64, correction);
|
||||||
|
|
||||||
|
var r64cH: u128 = undefined;
|
||||||
|
var r64cL: u128 = undefined;
|
||||||
|
wideMultiply(u128, recip64, cHi, &dummy, &r64cH);
|
||||||
|
wideMultiply(u128, recip64, cLo, &dummy, &r64cL);
|
||||||
|
|
||||||
|
reciprocal = r64cH + (r64cL >> 64);
|
||||||
|
|
||||||
|
// Adjust the final 128-bit reciprocal estimate downward to ensure that it
|
||||||
|
// is strictly smaller than the infinitely precise exact reciprocal. Because
|
||||||
|
// the computation of the Newton-Raphson step is truncating at every step,
|
||||||
|
// this adjustment is small; most of the work is already done.
|
||||||
|
reciprocal -%= 2;
|
||||||
|
|
||||||
|
// The numerical reciprocal is accurate to within 2^-112, lies in the
|
||||||
|
// interval [0.5, 1.0), and is strictly smaller than the true reciprocal
|
||||||
|
// of b. Multiplying a by this reciprocal thus gives a numerical q = a/b
|
||||||
|
// in Q127 with the following properties:
|
||||||
|
//
|
||||||
|
// 1. q < a/b
|
||||||
|
// 2. q is in the interval [0.5, 2.0)
|
||||||
|
// 3. The error in q is bounded away from 2^-63 (actually, we have
|
||||||
|
// many bits to spare, but this is all we need).
|
||||||
|
|
||||||
|
// We need a 128 x 128 multiply high to compute q.
|
||||||
|
var quotient128: u128 = undefined;
|
||||||
|
var quotientLo: u128 = undefined;
|
||||||
|
wideMultiply(u128, aSignificand << 2, reciprocal, "ient128, "ientLo);
|
||||||
|
|
||||||
|
// Two cases: quotient is in [0.5, 1.0) or quotient is in [1.0, 2.0).
|
||||||
|
// Right shift the quotient if it falls in the [1,2) range and adjust the
|
||||||
|
// exponent accordingly.
|
||||||
|
var quotient: u64 = if (quotient128 < (integerBit << 1)) b: {
|
||||||
|
quotientExponent -= 1;
|
||||||
|
break :b @intCast(u64, quotient128);
|
||||||
|
} else @intCast(u64, quotient128 >> 1);
|
||||||
|
|
||||||
|
// We are going to compute a residual of the form
|
||||||
|
//
|
||||||
|
// r = a - q*b
|
||||||
|
//
|
||||||
|
// We know from the construction of q that r satisfies:
|
||||||
|
//
|
||||||
|
// 0 <= r < ulp(q)*b
|
||||||
|
//
|
||||||
|
// If r is greater than 1/2 ulp(q)*b, then q rounds up. Otherwise, we
|
||||||
|
// already have the correct result. The exact halfway case cannot occur.
|
||||||
|
var residual: u64 = -%(quotient *% q63b);
|
||||||
|
|
||||||
|
const writtenExponent = quotientExponent + exponentBias;
|
||||||
|
if (writtenExponent >= maxExponent) {
|
||||||
|
// If we have overflowed the exponent, return infinity.
|
||||||
|
return @bitCast(T, infRep | quotientSign);
|
||||||
|
} else if (writtenExponent < 1) {
|
||||||
|
if (writtenExponent == 0) {
|
||||||
|
// Check whether the rounded result is normal.
|
||||||
|
if (residual > (bSignificand >> 1)) { // round
|
||||||
|
if (quotient == (integerBit - 1)) // If the rounded result is normal, return it
|
||||||
|
return @bitCast(T, @bitCast(Z, std.math.floatMin(T)) | quotientSign);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Flush denormals to zero. In the future, it would be nice to add
|
||||||
|
// code to round them correctly.
|
||||||
|
return @bitCast(T, quotientSign);
|
||||||
|
} else {
|
||||||
|
const round = @boolToInt(residual > (bSignificand >> 1));
|
||||||
|
// Insert the exponent
|
||||||
|
var absResult = quotient | (@intCast(Z, writtenExponent) << significandBits);
|
||||||
|
// Round
|
||||||
|
absResult +%= round;
|
||||||
|
// Insert the sign and return
|
||||||
|
return @bitCast(T, absResult | quotientSign | integerBit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test {
|
||||||
|
_ = @import("divxf3_test.zig");
|
||||||
|
}
|
||||||
65
lib/compiler_rt/divxf3_test.zig
Normal file
65
lib/compiler_rt/divxf3_test.zig
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const math = std.math;
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
const __divxf3 = @import("divxf3.zig").__divxf3;
|
||||||
|
|
||||||
|
fn compareResult(result: f80, expected: u80) bool {
|
||||||
|
const rep = @bitCast(u80, result);
|
||||||
|
|
||||||
|
if (rep == expected) return true;
|
||||||
|
// test other possible NaN representations (signal NaN)
|
||||||
|
if (math.isNan(result) and math.isNan(@bitCast(f80, expected))) return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expect__divxf3_result(a: f80, b: f80, expected: u80) !void {
|
||||||
|
const x = __divxf3(a, b);
|
||||||
|
const ret = compareResult(x, expected);
|
||||||
|
try testing.expect(ret == true);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test__divxf3(a: f80, b: f80) !void {
|
||||||
|
const integerBit = 1 << math.floatFractionalBits(f80);
|
||||||
|
const x = __divxf3(a, b);
|
||||||
|
|
||||||
|
// Next float (assuming normal, non-zero result)
|
||||||
|
const x_plus_eps = @bitCast(f80, (@bitCast(u80, x) + 1) | integerBit);
|
||||||
|
// Prev float (assuming normal, non-zero result)
|
||||||
|
const x_minus_eps = @bitCast(f80, (@bitCast(u80, x) - 1) | integerBit);
|
||||||
|
|
||||||
|
// Make sure result is more accurate than the adjacent floats
|
||||||
|
const err_x = @fabs(@mulAdd(f80, x, b, -a));
|
||||||
|
const err_x_plus_eps = @fabs(@mulAdd(f80, x_plus_eps, b, -a));
|
||||||
|
const err_x_minus_eps = @fabs(@mulAdd(f80, x_minus_eps, b, -a));
|
||||||
|
|
||||||
|
try testing.expect(err_x_minus_eps > err_x);
|
||||||
|
try testing.expect(err_x_plus_eps > err_x);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "divxf3" {
|
||||||
|
// qNaN / any = qNaN
|
||||||
|
try expect__divxf3_result(math.qnan_f80, 0x1.23456789abcdefp+5, 0x7fffC000000000000000);
|
||||||
|
// NaN / any = NaN
|
||||||
|
try expect__divxf3_result(math.nan_f80, 0x1.23456789abcdefp+5, 0x7fffC000000000000000);
|
||||||
|
// inf / any(except inf and nan) = inf
|
||||||
|
try expect__divxf3_result(math.inf(f80), 0x1.23456789abcdefp+5, 0x7fff8000000000000000);
|
||||||
|
// inf / inf = nan
|
||||||
|
try expect__divxf3_result(math.inf(f80), math.inf(f80), 0x7fffC000000000000000);
|
||||||
|
// inf / nan = nan
|
||||||
|
try expect__divxf3_result(math.inf(f80), math.nan(f80), 0x7fffC000000000000000);
|
||||||
|
|
||||||
|
try test__divxf3(0x1.a23b45362464523375893ab4cdefp+5, 0x1.eedcbaba3a94546558237654321fp-1);
|
||||||
|
try test__divxf3(0x1.a2b34c56d745382f9abf2c3dfeffp-50, 0x1.ed2c3ba15935332532287654321fp-9);
|
||||||
|
try test__divxf3(0x1.2345f6aaaa786555f42432abcdefp+456, 0x1.edacbba9874f765463544dd3621fp+6400);
|
||||||
|
try test__divxf3(0x1.2d3456f789ba6322bc665544edefp-234, 0x1.eddcdba39f3c8b7a36564354321fp-4455);
|
||||||
|
try test__divxf3(0x1.2345f6b77b7a8953365433abcdefp+234, 0x1.edcba987d6bb3aa467754354321fp-4055);
|
||||||
|
try test__divxf3(0x1.a23b45362464523375893ab4cdefp+5, 0x1.a2b34c56d745382f9abf2c3dfeffp-50);
|
||||||
|
try test__divxf3(0x1.a23b45362464523375893ab4cdefp+5, 0x1.1234567890abcdef987654321123p0);
|
||||||
|
try test__divxf3(0x1.a23b45362464523375893ab4cdefp+5, 0x1.12394205810257120adae8929f23p+16);
|
||||||
|
try test__divxf3(0x1.a23b45362464523375893ab4cdefp+5, 0x1.febdcefa1231245f9abf2c3dfeffp-50);
|
||||||
|
|
||||||
|
// Result rounds down to zero
|
||||||
|
try expect__divxf3_result(6.72420628622418701252535563464350521E-4932, 2.0, 0x0);
|
||||||
|
}
|
||||||
@ -1,22 +1,26 @@
|
|||||||
// __emutls_get_address specific builtin
|
//! __emutls_get_address specific builtin
|
||||||
//
|
//!
|
||||||
// derived work from LLVM Compiler Infrastructure - release 8.0 (MIT)
|
//! derived work from LLVM Compiler Infrastructure - release 8.0 (MIT)
|
||||||
// https://github.com/llvm-mirror/compiler-rt/blob/release_80/lib/builtins/emutls.c
|
//! https://github.com/llvm-mirror/compiler-rt/blob/release_80/lib/builtins/emutls.c
|
||||||
//
|
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
|
const common = @import("common.zig");
|
||||||
|
|
||||||
const abort = std.os.abort;
|
const abort = std.os.abort;
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
const expect = std.testing.expect;
|
const expect = std.testing.expect;
|
||||||
|
|
||||||
// defined in C as:
|
/// defined in C as:
|
||||||
// typedef unsigned int gcc_word __attribute__((mode(word)));
|
/// typedef unsigned int gcc_word __attribute__((mode(word)));
|
||||||
const gcc_word = usize;
|
const gcc_word = usize;
|
||||||
|
|
||||||
|
pub const panic = common.panic;
|
||||||
|
|
||||||
comptime {
|
comptime {
|
||||||
assert(builtin.link_libc);
|
if (builtin.link_libc and builtin.os.tag == .openbsd) {
|
||||||
|
@export(__emutls_get_address, .{ .name = "__emutls_get_address", .linkage = common.linkage });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// public entrypoint for generated code using EmulatedTLS
|
/// public entrypoint for generated code using EmulatedTLS
|
||||||
@ -319,6 +323,8 @@ const emutls_control = extern struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
test "simple_allocator" {
|
test "simple_allocator" {
|
||||||
|
if (!builtin.link_libc or builtin.os.tag != .openbsd) return error.SkipZigTest;
|
||||||
|
|
||||||
var data1: *[64]u8 = simple_allocator.alloc([64]u8);
|
var data1: *[64]u8 = simple_allocator.alloc([64]u8);
|
||||||
defer simple_allocator.free(data1);
|
defer simple_allocator.free(data1);
|
||||||
for (data1) |*c| {
|
for (data1) |*c| {
|
||||||
@ -333,6 +339,8 @@ test "simple_allocator" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "__emutls_get_address zeroed" {
|
test "__emutls_get_address zeroed" {
|
||||||
|
if (!builtin.link_libc or builtin.os.tag != .openbsd) return error.SkipZigTest;
|
||||||
|
|
||||||
var ctl = emutls_control.init(usize, null);
|
var ctl = emutls_control.init(usize, null);
|
||||||
try expect(ctl.object.index == 0);
|
try expect(ctl.object.index == 0);
|
||||||
|
|
||||||
@ -352,6 +360,8 @@ test "__emutls_get_address zeroed" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "__emutls_get_address with default_value" {
|
test "__emutls_get_address with default_value" {
|
||||||
|
if (!builtin.link_libc or builtin.os.tag != .openbsd) return error.SkipZigTest;
|
||||||
|
|
||||||
var value: usize = 5678; // default value
|
var value: usize = 5678; // default value
|
||||||
var ctl = emutls_control.init(usize, &value);
|
var ctl = emutls_control.init(usize, &value);
|
||||||
try expect(ctl.object.index == 0);
|
try expect(ctl.object.index == 0);
|
||||||
@ -370,6 +380,8 @@ test "__emutls_get_address with default_value" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "test default_value with differents sizes" {
|
test "test default_value with differents sizes" {
|
||||||
|
if (!builtin.link_libc or builtin.os.tag != .openbsd) return error.SkipZigTest;
|
||||||
|
|
||||||
const testType = struct {
|
const testType = struct {
|
||||||
fn _testType(comptime T: type, value: T) !void {
|
fn _testType(comptime T: type, value: T) !void {
|
||||||
var def: T = value;
|
var def: T = value;
|
||||||
@ -4,25 +4,31 @@
|
|||||||
// https://git.musl-libc.org/cgit/musl/tree/src/math/expf.c
|
// https://git.musl-libc.org/cgit/musl/tree/src/math/expf.c
|
||||||
// https://git.musl-libc.org/cgit/musl/tree/src/math/exp.c
|
// https://git.musl-libc.org/cgit/musl/tree/src/math/exp.c
|
||||||
|
|
||||||
const std = @import("../std.zig");
|
const std = @import("std");
|
||||||
|
const builtin = @import("builtin");
|
||||||
|
const arch = builtin.cpu.arch;
|
||||||
const math = std.math;
|
const math = std.math;
|
||||||
const expect = std.testing.expect;
|
const expect = std.testing.expect;
|
||||||
|
const common = @import("common.zig");
|
||||||
|
|
||||||
/// Returns e raised to the power of x (e^x).
|
pub const panic = common.panic;
|
||||||
///
|
|
||||||
/// Special Cases:
|
comptime {
|
||||||
/// - exp(+inf) = +inf
|
@export(__exph, .{ .name = "__exph", .linkage = common.linkage });
|
||||||
/// - exp(nan) = nan
|
@export(expf, .{ .name = "expf", .linkage = common.linkage });
|
||||||
pub fn exp(x: anytype) @TypeOf(x) {
|
@export(exp, .{ .name = "exp", .linkage = common.linkage });
|
||||||
const T = @TypeOf(x);
|
@export(__expx, .{ .name = "__expx", .linkage = common.linkage });
|
||||||
return switch (T) {
|
const expq_sym_name = if (common.want_ppc_abi) "expf128" else "expq";
|
||||||
f32 => exp32(x),
|
@export(expq, .{ .name = expq_sym_name, .linkage = common.linkage });
|
||||||
f64 => exp64(x),
|
@export(expl, .{ .name = "expl", .linkage = common.linkage });
|
||||||
else => @compileError("exp not implemented for " ++ @typeName(T)),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exp32(x_: f32) f32 {
|
pub fn __exph(a: f16) callconv(.C) f16 {
|
||||||
|
// TODO: more efficient implementation
|
||||||
|
return @floatCast(f16, expf(a));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn expf(x_: f32) callconv(.C) f32 {
|
||||||
const half = [_]f32{ 0.5, -0.5 };
|
const half = [_]f32{ 0.5, -0.5 };
|
||||||
const ln2hi = 6.9314575195e-1;
|
const ln2hi = 6.9314575195e-1;
|
||||||
const ln2lo = 1.4286067653e-6;
|
const ln2lo = 1.4286067653e-6;
|
||||||
@ -97,7 +103,7 @@ fn exp32(x_: f32) f32 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exp64(x_: f64) f64 {
|
pub fn exp(x_: f64) callconv(.C) f64 {
|
||||||
const half = [_]f64{ 0.5, -0.5 };
|
const half = [_]f64{ 0.5, -0.5 };
|
||||||
const ln2hi: f64 = 6.93147180369123816490e-01;
|
const ln2hi: f64 = 6.93147180369123816490e-01;
|
||||||
const ln2lo: f64 = 1.90821492927058770002e-10;
|
const ln2lo: f64 = 1.90821492927058770002e-10;
|
||||||
@ -181,37 +187,53 @@ fn exp64(x_: f64) f64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test "math.exp" {
|
pub fn __expx(a: f80) callconv(.C) f80 {
|
||||||
try expect(exp(@as(f32, 0.0)) == exp32(0.0));
|
// TODO: more efficient implementation
|
||||||
try expect(exp(@as(f64, 0.0)) == exp64(0.0));
|
return @floatCast(f80, expq(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
test "math.exp32" {
|
pub fn expq(a: f128) callconv(.C) f128 {
|
||||||
|
// TODO: more correct implementation
|
||||||
|
return exp(@floatCast(f64, a));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn expl(x: c_longdouble) callconv(.C) c_longdouble {
|
||||||
|
switch (@typeInfo(c_longdouble).Float.bits) {
|
||||||
|
16 => return __exph(x),
|
||||||
|
32 => return expf(x),
|
||||||
|
64 => return exp(x),
|
||||||
|
80 => return __expx(x),
|
||||||
|
128 => return expq(x),
|
||||||
|
else => @compileError("unreachable"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "exp32" {
|
||||||
const epsilon = 0.000001;
|
const epsilon = 0.000001;
|
||||||
|
|
||||||
try expect(exp32(0.0) == 1.0);
|
try expect(expf(0.0) == 1.0);
|
||||||
try expect(math.approxEqAbs(f32, exp32(0.0), 1.0, epsilon));
|
try expect(math.approxEqAbs(f32, expf(0.0), 1.0, epsilon));
|
||||||
try expect(math.approxEqAbs(f32, exp32(0.2), 1.221403, epsilon));
|
try expect(math.approxEqAbs(f32, expf(0.2), 1.221403, epsilon));
|
||||||
try expect(math.approxEqAbs(f32, exp32(0.8923), 2.440737, epsilon));
|
try expect(math.approxEqAbs(f32, expf(0.8923), 2.440737, epsilon));
|
||||||
try expect(math.approxEqAbs(f32, exp32(1.5), 4.481689, epsilon));
|
try expect(math.approxEqAbs(f32, expf(1.5), 4.481689, epsilon));
|
||||||
}
|
}
|
||||||
|
|
||||||
test "math.exp64" {
|
test "exp64" {
|
||||||
const epsilon = 0.000001;
|
const epsilon = 0.000001;
|
||||||
|
|
||||||
try expect(exp64(0.0) == 1.0);
|
try expect(exp(0.0) == 1.0);
|
||||||
try expect(math.approxEqAbs(f64, exp64(0.0), 1.0, epsilon));
|
try expect(math.approxEqAbs(f64, exp(0.0), 1.0, epsilon));
|
||||||
try expect(math.approxEqAbs(f64, exp64(0.2), 1.221403, epsilon));
|
try expect(math.approxEqAbs(f64, exp(0.2), 1.221403, epsilon));
|
||||||
try expect(math.approxEqAbs(f64, exp64(0.8923), 2.440737, epsilon));
|
try expect(math.approxEqAbs(f64, exp(0.8923), 2.440737, epsilon));
|
||||||
try expect(math.approxEqAbs(f64, exp64(1.5), 4.481689, epsilon));
|
try expect(math.approxEqAbs(f64, exp(1.5), 4.481689, epsilon));
|
||||||
}
|
}
|
||||||
|
|
||||||
test "math.exp32.special" {
|
test "exp32.special" {
|
||||||
try expect(math.isPositiveInf(exp32(math.inf(f32))));
|
try expect(math.isPositiveInf(expf(math.inf(f32))));
|
||||||
try expect(math.isNan(exp32(math.nan(f32))));
|
try expect(math.isNan(expf(math.nan(f32))));
|
||||||
}
|
}
|
||||||
|
|
||||||
test "math.exp64.special" {
|
test "exp64.special" {
|
||||||
try expect(math.isPositiveInf(exp64(math.inf(f64))));
|
try expect(math.isPositiveInf(exp(math.inf(f64))));
|
||||||
try expect(math.isNan(exp64(math.nan(f64))));
|
try expect(math.isNan(exp(math.nan(f64))));
|
||||||
}
|
}
|
||||||
@ -4,44 +4,31 @@
|
|||||||
// https://git.musl-libc.org/cgit/musl/tree/src/math/exp2f.c
|
// https://git.musl-libc.org/cgit/musl/tree/src/math/exp2f.c
|
||||||
// https://git.musl-libc.org/cgit/musl/tree/src/math/exp2.c
|
// https://git.musl-libc.org/cgit/musl/tree/src/math/exp2.c
|
||||||
|
|
||||||
const std = @import("../std.zig");
|
const std = @import("std");
|
||||||
|
const builtin = @import("builtin");
|
||||||
|
const arch = builtin.cpu.arch;
|
||||||
const math = std.math;
|
const math = std.math;
|
||||||
const expect = std.testing.expect;
|
const expect = std.testing.expect;
|
||||||
|
const common = @import("common.zig");
|
||||||
|
|
||||||
/// Returns 2 raised to the power of x (2^x).
|
pub const panic = common.panic;
|
||||||
///
|
|
||||||
/// Special Cases:
|
comptime {
|
||||||
/// - exp2(+inf) = +inf
|
@export(__exp2h, .{ .name = "__exp2h", .linkage = common.linkage });
|
||||||
/// - exp2(nan) = nan
|
@export(exp2f, .{ .name = "exp2f", .linkage = common.linkage });
|
||||||
pub fn exp2(x: anytype) @TypeOf(x) {
|
@export(exp2, .{ .name = "exp2", .linkage = common.linkage });
|
||||||
const T = @TypeOf(x);
|
@export(__exp2x, .{ .name = "__exp2x", .linkage = common.linkage });
|
||||||
return switch (T) {
|
const exp2q_sym_name = if (common.want_ppc_abi) "exp2f128" else "exp2q";
|
||||||
f32 => exp2_32(x),
|
@export(exp2q, .{ .name = exp2q_sym_name, .linkage = common.linkage });
|
||||||
f64 => exp2_64(x),
|
@export(exp2l, .{ .name = "exp2l", .linkage = common.linkage });
|
||||||
else => @compileError("exp2 not implemented for " ++ @typeName(T)),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const exp2ft = [_]f64{
|
pub fn __exp2h(x: f16) callconv(.C) f16 {
|
||||||
0x1.6a09e667f3bcdp-1,
|
// TODO: more efficient implementation
|
||||||
0x1.7a11473eb0187p-1,
|
return @floatCast(f16, exp2f(x));
|
||||||
0x1.8ace5422aa0dbp-1,
|
}
|
||||||
0x1.9c49182a3f090p-1,
|
|
||||||
0x1.ae89f995ad3adp-1,
|
|
||||||
0x1.c199bdd85529cp-1,
|
|
||||||
0x1.d5818dcfba487p-1,
|
|
||||||
0x1.ea4afa2a490dap-1,
|
|
||||||
0x1.0000000000000p+0,
|
|
||||||
0x1.0b5586cf9890fp+0,
|
|
||||||
0x1.172b83c7d517bp+0,
|
|
||||||
0x1.2387a6e756238p+0,
|
|
||||||
0x1.306fe0a31b715p+0,
|
|
||||||
0x1.3dea64c123422p+0,
|
|
||||||
0x1.4bfdad5362a27p+0,
|
|
||||||
0x1.5ab07dd485429p+0,
|
|
||||||
};
|
|
||||||
|
|
||||||
fn exp2_32(x: f32) f32 {
|
pub fn exp2f(x: f32) callconv(.C) f32 {
|
||||||
const tblsiz = @intCast(u32, exp2ft.len);
|
const tblsiz = @intCast(u32, exp2ft.len);
|
||||||
const redux: f32 = 0x1.8p23 / @intToFloat(f32, tblsiz);
|
const redux: f32 = 0x1.8p23 / @intToFloat(f32, tblsiz);
|
||||||
const P1: f32 = 0x1.62e430p-1;
|
const P1: f32 = 0x1.62e430p-1;
|
||||||
@ -98,6 +85,115 @@ fn exp2_32(x: f32) f32 {
|
|||||||
return @floatCast(f32, r * uk);
|
return @floatCast(f32, r * uk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn exp2(x: f64) callconv(.C) f64 {
|
||||||
|
const tblsiz: u32 = @intCast(u32, exp2dt.len / 2);
|
||||||
|
const redux: f64 = 0x1.8p52 / @intToFloat(f64, tblsiz);
|
||||||
|
const P1: f64 = 0x1.62e42fefa39efp-1;
|
||||||
|
const P2: f64 = 0x1.ebfbdff82c575p-3;
|
||||||
|
const P3: f64 = 0x1.c6b08d704a0a6p-5;
|
||||||
|
const P4: f64 = 0x1.3b2ab88f70400p-7;
|
||||||
|
const P5: f64 = 0x1.5d88003875c74p-10;
|
||||||
|
|
||||||
|
const ux = @bitCast(u64, x);
|
||||||
|
const ix = @intCast(u32, ux >> 32) & 0x7FFFFFFF;
|
||||||
|
|
||||||
|
// TODO: This should be handled beneath.
|
||||||
|
if (math.isNan(x)) {
|
||||||
|
return math.nan(f64);
|
||||||
|
}
|
||||||
|
|
||||||
|
// |x| >= 1022 or nan
|
||||||
|
if (ix >= 0x408FF000) {
|
||||||
|
// x >= 1024 or nan
|
||||||
|
if (ix >= 0x40900000 and ux >> 63 == 0) {
|
||||||
|
math.raiseOverflow();
|
||||||
|
return math.inf(f64);
|
||||||
|
}
|
||||||
|
// -inf or -nan
|
||||||
|
if (ix >= 0x7FF00000) {
|
||||||
|
return -1 / x;
|
||||||
|
}
|
||||||
|
// x <= -1022
|
||||||
|
if (ux >> 63 != 0) {
|
||||||
|
// underflow
|
||||||
|
if (x <= -1075 or x - 0x1.0p52 + 0x1.0p52 != x) {
|
||||||
|
math.doNotOptimizeAway(@floatCast(f32, -0x1.0p-149 / x));
|
||||||
|
}
|
||||||
|
if (x <= -1075) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// |x| < 0x1p-54
|
||||||
|
else if (ix < 0x3C900000) {
|
||||||
|
return 1.0 + x;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: musl relies on unsafe behaviours which are replicated below
|
||||||
|
// (addition overflow, division truncation, casting). Appears that this
|
||||||
|
// produces the intended result but should confirm how GCC/Clang handle this
|
||||||
|
// to ensure.
|
||||||
|
|
||||||
|
// reduce x
|
||||||
|
var uf: f64 = x + redux;
|
||||||
|
// NOTE: musl performs an implicit 64-bit to 32-bit u32 truncation here
|
||||||
|
var i_0: u32 = @truncate(u32, @bitCast(u64, uf));
|
||||||
|
i_0 +%= tblsiz / 2;
|
||||||
|
|
||||||
|
const k: u32 = i_0 / tblsiz * tblsiz;
|
||||||
|
const ik: i32 = @divTrunc(@bitCast(i32, k), tblsiz);
|
||||||
|
i_0 %= tblsiz;
|
||||||
|
uf -= redux;
|
||||||
|
|
||||||
|
// r = exp2(y) = exp2t[i_0] * p(z - eps[i])
|
||||||
|
var z: f64 = x - uf;
|
||||||
|
const t: f64 = exp2dt[@intCast(usize, 2 * i_0)];
|
||||||
|
z -= exp2dt[@intCast(usize, 2 * i_0 + 1)];
|
||||||
|
const r: f64 = t + t * z * (P1 + z * (P2 + z * (P3 + z * (P4 + z * P5))));
|
||||||
|
|
||||||
|
return math.scalbn(r, ik);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __exp2x(x: f80) callconv(.C) f80 {
|
||||||
|
// TODO: more efficient implementation
|
||||||
|
return @floatCast(f80, exp2q(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn exp2q(x: f128) callconv(.C) f128 {
|
||||||
|
// TODO: more correct implementation
|
||||||
|
return exp2(@floatCast(f64, x));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn exp2l(x: c_longdouble) callconv(.C) c_longdouble {
|
||||||
|
switch (@typeInfo(c_longdouble).Float.bits) {
|
||||||
|
16 => return __exp2h(x),
|
||||||
|
32 => return exp2f(x),
|
||||||
|
64 => return exp2(x),
|
||||||
|
80 => return __exp2x(x),
|
||||||
|
128 => return exp2q(x),
|
||||||
|
else => @compileError("unreachable"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const exp2ft = [_]f64{
|
||||||
|
0x1.6a09e667f3bcdp-1,
|
||||||
|
0x1.7a11473eb0187p-1,
|
||||||
|
0x1.8ace5422aa0dbp-1,
|
||||||
|
0x1.9c49182a3f090p-1,
|
||||||
|
0x1.ae89f995ad3adp-1,
|
||||||
|
0x1.c199bdd85529cp-1,
|
||||||
|
0x1.d5818dcfba487p-1,
|
||||||
|
0x1.ea4afa2a490dap-1,
|
||||||
|
0x1.0000000000000p+0,
|
||||||
|
0x1.0b5586cf9890fp+0,
|
||||||
|
0x1.172b83c7d517bp+0,
|
||||||
|
0x1.2387a6e756238p+0,
|
||||||
|
0x1.306fe0a31b715p+0,
|
||||||
|
0x1.3dea64c123422p+0,
|
||||||
|
0x1.4bfdad5362a27p+0,
|
||||||
|
0x1.5ab07dd485429p+0,
|
||||||
|
};
|
||||||
|
|
||||||
const exp2dt = [_]f64{
|
const exp2dt = [_]f64{
|
||||||
// exp2(z + eps) eps
|
// exp2(z + eps) eps
|
||||||
0x1.6a09e667f3d5dp-1, 0x1.9880p-44,
|
0x1.6a09e667f3d5dp-1, 0x1.9880p-44,
|
||||||
@ -358,108 +454,34 @@ const exp2dt = [_]f64{
|
|||||||
0x1.690f4b19e9471p+0, -0x1.9780p-45,
|
0x1.690f4b19e9471p+0, -0x1.9780p-45,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn exp2_64(x: f64) f64 {
|
test "exp2_32" {
|
||||||
const tblsiz: u32 = @intCast(u32, exp2dt.len / 2);
|
|
||||||
const redux: f64 = 0x1.8p52 / @intToFloat(f64, tblsiz);
|
|
||||||
const P1: f64 = 0x1.62e42fefa39efp-1;
|
|
||||||
const P2: f64 = 0x1.ebfbdff82c575p-3;
|
|
||||||
const P3: f64 = 0x1.c6b08d704a0a6p-5;
|
|
||||||
const P4: f64 = 0x1.3b2ab88f70400p-7;
|
|
||||||
const P5: f64 = 0x1.5d88003875c74p-10;
|
|
||||||
|
|
||||||
const ux = @bitCast(u64, x);
|
|
||||||
const ix = @intCast(u32, ux >> 32) & 0x7FFFFFFF;
|
|
||||||
|
|
||||||
// TODO: This should be handled beneath.
|
|
||||||
if (math.isNan(x)) {
|
|
||||||
return math.nan(f64);
|
|
||||||
}
|
|
||||||
|
|
||||||
// |x| >= 1022 or nan
|
|
||||||
if (ix >= 0x408FF000) {
|
|
||||||
// x >= 1024 or nan
|
|
||||||
if (ix >= 0x40900000 and ux >> 63 == 0) {
|
|
||||||
math.raiseOverflow();
|
|
||||||
return math.inf(f64);
|
|
||||||
}
|
|
||||||
// -inf or -nan
|
|
||||||
if (ix >= 0x7FF00000) {
|
|
||||||
return -1 / x;
|
|
||||||
}
|
|
||||||
// x <= -1022
|
|
||||||
if (ux >> 63 != 0) {
|
|
||||||
// underflow
|
|
||||||
if (x <= -1075 or x - 0x1.0p52 + 0x1.0p52 != x) {
|
|
||||||
math.doNotOptimizeAway(@floatCast(f32, -0x1.0p-149 / x));
|
|
||||||
}
|
|
||||||
if (x <= -1075) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// |x| < 0x1p-54
|
|
||||||
else if (ix < 0x3C900000) {
|
|
||||||
return 1.0 + x;
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: musl relies on unsafe behaviours which are replicated below
|
|
||||||
// (addition overflow, division truncation, casting). Appears that this
|
|
||||||
// produces the intended result but should confirm how GCC/Clang handle this
|
|
||||||
// to ensure.
|
|
||||||
|
|
||||||
// reduce x
|
|
||||||
var uf: f64 = x + redux;
|
|
||||||
// NOTE: musl performs an implicit 64-bit to 32-bit u32 truncation here
|
|
||||||
var i_0: u32 = @truncate(u32, @bitCast(u64, uf));
|
|
||||||
i_0 +%= tblsiz / 2;
|
|
||||||
|
|
||||||
const k: u32 = i_0 / tblsiz * tblsiz;
|
|
||||||
const ik: i32 = @divTrunc(@bitCast(i32, k), tblsiz);
|
|
||||||
i_0 %= tblsiz;
|
|
||||||
uf -= redux;
|
|
||||||
|
|
||||||
// r = exp2(y) = exp2t[i_0] * p(z - eps[i])
|
|
||||||
var z: f64 = x - uf;
|
|
||||||
const t: f64 = exp2dt[@intCast(usize, 2 * i_0)];
|
|
||||||
z -= exp2dt[@intCast(usize, 2 * i_0 + 1)];
|
|
||||||
const r: f64 = t + t * z * (P1 + z * (P2 + z * (P3 + z * (P4 + z * P5))));
|
|
||||||
|
|
||||||
return math.scalbn(r, ik);
|
|
||||||
}
|
|
||||||
|
|
||||||
test "math.exp2" {
|
|
||||||
try expect(exp2(@as(f32, 0.8923)) == exp2_32(0.8923));
|
|
||||||
try expect(exp2(@as(f64, 0.8923)) == exp2_64(0.8923));
|
|
||||||
}
|
|
||||||
|
|
||||||
test "math.exp2_32" {
|
|
||||||
const epsilon = 0.000001;
|
const epsilon = 0.000001;
|
||||||
|
|
||||||
try expect(exp2_32(0.0) == 1.0);
|
try expect(exp2f(0.0) == 1.0);
|
||||||
try expect(math.approxEqAbs(f32, exp2_32(0.2), 1.148698, epsilon));
|
try expect(math.approxEqAbs(f32, exp2f(0.2), 1.148698, epsilon));
|
||||||
try expect(math.approxEqAbs(f32, exp2_32(0.8923), 1.856133, epsilon));
|
try expect(math.approxEqAbs(f32, exp2f(0.8923), 1.856133, epsilon));
|
||||||
try expect(math.approxEqAbs(f32, exp2_32(1.5), 2.828427, epsilon));
|
try expect(math.approxEqAbs(f32, exp2f(1.5), 2.828427, epsilon));
|
||||||
try expect(math.approxEqAbs(f32, exp2_32(37.45), 187747237888, epsilon));
|
try expect(math.approxEqAbs(f32, exp2f(37.45), 187747237888, epsilon));
|
||||||
try expect(math.approxEqAbs(f32, exp2_32(-1), 0.5, epsilon));
|
try expect(math.approxEqAbs(f32, exp2f(-1), 0.5, epsilon));
|
||||||
}
|
}
|
||||||
|
|
||||||
test "math.exp2_64" {
|
test "exp2_64" {
|
||||||
const epsilon = 0.000001;
|
const epsilon = 0.000001;
|
||||||
|
|
||||||
try expect(exp2_64(0.0) == 1.0);
|
try expect(exp2(0.0) == 1.0);
|
||||||
try expect(math.approxEqAbs(f64, exp2_64(0.2), 1.148698, epsilon));
|
try expect(math.approxEqAbs(f64, exp2(0.2), 1.148698, epsilon));
|
||||||
try expect(math.approxEqAbs(f64, exp2_64(0.8923), 1.856133, epsilon));
|
try expect(math.approxEqAbs(f64, exp2(0.8923), 1.856133, epsilon));
|
||||||
try expect(math.approxEqAbs(f64, exp2_64(1.5), 2.828427, epsilon));
|
try expect(math.approxEqAbs(f64, exp2(1.5), 2.828427, epsilon));
|
||||||
try expect(math.approxEqAbs(f64, exp2_64(-1), 0.5, epsilon));
|
try expect(math.approxEqAbs(f64, exp2(-1), 0.5, epsilon));
|
||||||
try expect(math.approxEqAbs(f64, exp2_64(-0x1.a05cc754481d1p-2), 0x1.824056efc687cp-1, epsilon));
|
try expect(math.approxEqAbs(f64, exp2(-0x1.a05cc754481d1p-2), 0x1.824056efc687cp-1, epsilon));
|
||||||
}
|
}
|
||||||
|
|
||||||
test "math.exp2_32.special" {
|
test "exp2_32.special" {
|
||||||
try expect(math.isPositiveInf(exp2_32(math.inf(f32))));
|
try expect(math.isPositiveInf(exp2f(math.inf(f32))));
|
||||||
try expect(math.isNan(exp2_32(math.nan(f32))));
|
try expect(math.isNan(exp2f(math.nan(f32))));
|
||||||
}
|
}
|
||||||
|
|
||||||
test "math.exp2_64.special" {
|
test "exp2_64.special" {
|
||||||
try expect(math.isPositiveInf(exp2_64(math.inf(f64))));
|
try expect(math.isPositiveInf(exp2(math.inf(f64))));
|
||||||
try expect(math.isNan(exp2_64(math.nan(f64))));
|
try expect(math.isNan(exp2(math.nan(f64))));
|
||||||
}
|
}
|
||||||
26
lib/compiler_rt/extenddftf2.zig
Normal file
26
lib/compiler_rt/extenddftf2.zig
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
const common = @import("./common.zig");
|
||||||
|
const extendf = @import("./extendf.zig").extendf;
|
||||||
|
|
||||||
|
pub const panic = common.panic;
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
if (common.want_ppc_abi) {
|
||||||
|
@export(__extenddfkf2, .{ .name = "__extenddfkf2", .linkage = common.linkage });
|
||||||
|
} else if (common.want_sparc_abi) {
|
||||||
|
@export(_Qp_dtoq, .{ .name = "_Qp_dtoq", .linkage = common.linkage });
|
||||||
|
} else {
|
||||||
|
@export(__extenddftf2, .{ .name = "__extenddftf2", .linkage = common.linkage });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __extenddftf2(a: f64) callconv(.C) f128 {
|
||||||
|
return extendf(f128, f64, @bitCast(u64, a));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __extenddfkf2(a: f64) callconv(.C) f128 {
|
||||||
|
return extendf(f128, f64, @bitCast(u64, a));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _Qp_dtoq(c: *f128, a: f64) callconv(.C) void {
|
||||||
|
c.* = extendf(f128, f64, @bitCast(u64, a));
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user