| author | |
| committer | |
| log | 3e72411db011dfdd35d8eb9b2f51ea5c55a61d1e |
| tree | eba97a3ba5f63b3441c034b001b50a96db29e02a |
| parent | 67fb4d13593fb6f940415fda2abd56c452c7a28e |
| signature | Commit is signed but in an unrecognized format. |
* add __multi3 compiler rt function. See #1290
* compiler rt includes ARM functions for thumb and aarch64 and
other sub-arches left out. See #1526
* support C ABI for returning structs on ARM. see #14815 files changed, 135 insertions(+), 0 deletions(-)
CMakeLists.txt+1| ... | ... | @@ -625,6 +625,7 @@ set(ZIG_STD_FILES |
| 625 | 625 | "special/compiler_rt/floatuntitf.zig" |
| 626 | 626 | "special/compiler_rt/index.zig" |
| 627 | 627 | "special/compiler_rt/muloti4.zig" |
| 628 | "special/compiler_rt/multi3.zig" | |
| 628 | 629 | "special/compiler_rt/truncXfYf2.zig" |
| 629 | 630 | "special/compiler_rt/udivmod.zig" |
| 630 | 631 | "special/compiler_rt/udivmoddi4.zig" |
src/analyze.cpp+2| ... | ... | @@ -1084,6 +1084,8 @@ bool want_first_arg_sret(CodeGen *g, FnTypeId *fn_type_id) { |
| 1084 | 1084 | } |
| 1085 | 1085 | zig_panic("TODO implement C ABI for x86_64 return types. type '%s'\nSee https://github.com/ziglang/zig/issues/1481", |
| 1086 | 1086 | buf_ptr(&fn_type_id->return_type->name)); |
| 1087 | } else if (g->zig_target.arch.arch == ZigLLVM_arm || g->zig_target.arch.arch == ZigLLVM_armeb) { | |
| 1088 | return type_size(g, fn_type_id->return_type) > 16; | |
| 1087 | 1089 | } |
| 1088 | 1090 | zig_panic("TODO implement C ABI for this architecture. See https://github.com/ziglang/zig/issues/1481"); |
| 1089 | 1091 | } |
std/special/compiler_rt/index.zig+22| ... | ... | @@ -80,6 +80,7 @@ comptime { |
| 80 | 80 | @export("___chkstk_ms", ___chkstk_ms, linkage); |
| 81 | 81 | } |
| 82 | 82 | @export("__divti3", @import("divti3.zig").__divti3_windows_x86_64, linkage); |
| 83 | @export("__multi3", @import("multi3.zig").__multi3_windows_x86_64, linkage); | |
| 83 | 84 | @export("__muloti4", @import("muloti4.zig").__muloti4_windows_x86_64, linkage); |
| 84 | 85 | @export("__udivti3", @import("udivti3.zig").__udivti3_windows_x86_64, linkage); |
| 85 | 86 | @export("__udivmodti4", @import("udivmodti4.zig").__udivmodti4_windows_x86_64, linkage); |
| ... | ... | @@ -89,6 +90,7 @@ comptime { |
| 89 | 90 | } |
| 90 | 91 | } else { |
| 91 | 92 | @export("__divti3", @import("divti3.zig").__divti3, linkage); |
| 93 | @export("__multi3", @import("multi3.zig").__multi3, linkage); | |
| 92 | 94 | @export("__muloti4", @import("muloti4.zig").__muloti4, linkage); |
| 93 | 95 | @export("__udivti3", @import("udivti3.zig").__udivti3, linkage); |
| 94 | 96 | @export("__udivmodti4", @import("udivmodti4.zig").__udivmodti4, linkage); |
| ... | ... | @@ -149,6 +151,7 @@ extern fn __aeabi_uldivmod(numerator: u64, denominator: u64) AeabiUlDivModResult |
| 149 | 151 | |
| 150 | 152 | fn isArmArch() bool { |
| 151 | 153 | return switch (builtin.arch) { |
| 154 | builtin.Arch.armv8_3a, | |
| 152 | 155 | builtin.Arch.armv8_2a, |
| 153 | 156 | builtin.Arch.armv8_1a, |
| 154 | 157 | builtin.Arch.armv8, |
| ... | ... | @@ -160,6 +163,7 @@ fn isArmArch() bool { |
| 160 | 163 | builtin.Arch.armv7m, |
| 161 | 164 | builtin.Arch.armv7s, |
| 162 | 165 | builtin.Arch.armv7k, |
| 166 | builtin.Arch.armv7ve, | |
| 163 | 167 | builtin.Arch.armv6, |
| 164 | 168 | builtin.Arch.armv6m, |
| 165 | 169 | builtin.Arch.armv6k, |
| ... | ... | @@ -167,6 +171,7 @@ fn isArmArch() bool { |
| 167 | 171 | builtin.Arch.armv5, |
| 168 | 172 | builtin.Arch.armv5te, |
| 169 | 173 | builtin.Arch.armv4t, |
| 174 | builtin.Arch.armebv8_3a, | |
| 170 | 175 | builtin.Arch.armebv8_2a, |
| 171 | 176 | builtin.Arch.armebv8_1a, |
| 172 | 177 | builtin.Arch.armebv8, |
| ... | ... | @@ -178,6 +183,7 @@ fn isArmArch() bool { |
| 178 | 183 | builtin.Arch.armebv7m, |
| 179 | 184 | builtin.Arch.armebv7s, |
| 180 | 185 | builtin.Arch.armebv7k, |
| 186 | builtin.Arch.armebv7ve, | |
| 181 | 187 | builtin.Arch.armebv6, |
| 182 | 188 | builtin.Arch.armebv6m, |
| 183 | 189 | builtin.Arch.armebv6k, |
| ... | ... | @@ -185,6 +191,22 @@ fn isArmArch() bool { |
| 185 | 191 | builtin.Arch.armebv5, |
| 186 | 192 | builtin.Arch.armebv5te, |
| 187 | 193 | builtin.Arch.armebv4t, |
| 194 | builtin.Arch.aarch64v8_3a, | |
| 195 | builtin.Arch.aarch64v8_2a, | |
| 196 | builtin.Arch.aarch64v8_1a, | |
| 197 | builtin.Arch.aarch64v8, | |
| 198 | builtin.Arch.aarch64v8r, | |
| 199 | builtin.Arch.aarch64v8m_baseline, | |
| 200 | builtin.Arch.aarch64v8m_mainline, | |
| 201 | builtin.Arch.aarch64_bev8_3a, | |
| 202 | builtin.Arch.aarch64_bev8_2a, | |
| 203 | builtin.Arch.aarch64_bev8_1a, | |
| 204 | builtin.Arch.aarch64_bev8, | |
| 205 | builtin.Arch.aarch64_bev8r, | |
| 206 | builtin.Arch.aarch64_bev8m_baseline, | |
| 207 | builtin.Arch.aarch64_bev8m_mainline, | |
| 208 | builtin.Arch.thumb, | |
| 209 | builtin.Arch.thumbeb, | |
| 188 | 210 | => true, |
| 189 | 211 | else => false, |
| 190 | 212 | }; |
std/special/compiler_rt/multi3.zig created+56| ... | ... | @@ -0,0 +1,56 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const compiler_rt = @import("index.zig"); | |
| 3 | ||
| 4 | // Ported from git@github.com:llvm-project/llvm-project-20170507.git | |
| 5 | // ae684fad6d34858c014c94da69c15e7774a633c3 | |
| 6 | // 2018-08-13 | |
| 7 | ||
| 8 | pub extern fn __multi3(a: i128, b: i128) i128 { | |
| 9 | @setRuntimeSafety(builtin.is_test); | |
| 10 | const x = twords{.all = a}; | |
| 11 | const y = twords{.all = b}; | |
| 12 | var r = twords{.all = __mulddi3(x.s.low, y.s.low)}; | |
| 13 | r.s.high +%= x.s.high *% y.s.low +% x.s.low *% y.s.high; | |
| 14 | return r.all; | |
| 15 | } | |
| 16 | ||
| 17 | pub extern fn __multi3_windows_x86_64(a: *const i128, b: *const i128) void { | |
| 18 | @setRuntimeSafety(builtin.is_test); | |
| 19 | compiler_rt.setXmm0(i128, __multi3(a.*, b.*)); | |
| 20 | } | |
| 21 | ||
| 22 | fn __mulddi3(a: u64, b: u64) i128 { | |
| 23 | const bits_in_dword_2 = (@sizeOf(i64) * 8) / 2; | |
| 24 | const lower_mask = ~u64(0) >> bits_in_dword_2; | |
| 25 | var r: twords = undefined; | |
| 26 | r.s.low = (a & lower_mask) *% (b & lower_mask); | |
| 27 | var t: u64 = r.s.low >> bits_in_dword_2; | |
| 28 | r.s.low &= lower_mask; | |
| 29 | t +%= (a >> bits_in_dword_2) *% (b & lower_mask); | |
| 30 | r.s.low +%= (t & lower_mask) << bits_in_dword_2; | |
| 31 | r.s.high = t >> bits_in_dword_2; | |
| 32 | t = r.s.low >> bits_in_dword_2; | |
| 33 | r.s.low &= lower_mask; | |
| 34 | t +%= (b >> bits_in_dword_2) *% (a & lower_mask); | |
| 35 | r.s.low +%= (t & lower_mask) << bits_in_dword_2; | |
| 36 | r.s.high +%= t >> bits_in_dword_2; | |
| 37 | r.s.high +%= (a >> bits_in_dword_2) *% (b >> bits_in_dword_2); | |
| 38 | return r.all; | |
| 39 | } | |
| 40 | ||
| 41 | const twords = extern union { | |
| 42 | all: i128, | |
| 43 | s: S, | |
| 44 | ||
| 45 | const S = if (builtin.endian == builtin.Endian.Little) struct { | |
| 46 | low: u64, | |
| 47 | high: u64, | |
| 48 | } else struct { | |
| 49 | high: u64, | |
| 50 | low: u64, | |
| 51 | }; | |
| 52 | }; | |
| 53 | ||
| 54 | test "import multi3" { | |
| 55 | _ = @import("multi3_test.zig"); | |
| 56 | } |
std/special/compiler_rt/multi3_test.zig created+54| ... | ... | @@ -0,0 +1,54 @@ |
| 1 | const __multi3 = @import("multi3.zig").__multi3; | |
| 2 | const assert = @import("std").debug.assert; | |
| 3 | ||
| 4 | fn test__multi3(a: i128, b: i128, expected: i128) void { | |
| 5 | const x = __multi3(a, b); | |
| 6 | assert(x == expected); | |
| 7 | } | |
| 8 | ||
| 9 | test "multi3" { | |
| 10 | test__multi3(0, 0, 0); | |
| 11 | test__multi3(0, 1, 0); | |
| 12 | test__multi3(1, 0, 0); | |
| 13 | test__multi3(0, 10, 0); | |
| 14 | test__multi3(10, 0, 0); | |
| 15 | test__multi3(0, 81985529216486895, 0); | |
| 16 | test__multi3(81985529216486895, 0, 0); | |
| 17 | ||
| 18 | test__multi3(0, -1, 0); | |
| 19 | test__multi3(-1, 0, 0); | |
| 20 | test__multi3(0, -10, 0); | |
| 21 | test__multi3(-10, 0, 0); | |
| 22 | test__multi3(0, -81985529216486895, 0); | |
| 23 | test__multi3(-81985529216486895, 0, 0); | |
| 24 | ||
| 25 | test__multi3(1, 1, 1); | |
| 26 | test__multi3(1, 10, 10); | |
| 27 | test__multi3(10, 1, 10); | |
| 28 | test__multi3(1, 81985529216486895, 81985529216486895); | |
| 29 | test__multi3(81985529216486895, 1, 81985529216486895); | |
| 30 | ||
| 31 | test__multi3(1, -1, -1); | |
| 32 | test__multi3(1, -10, -10); | |
| 33 | test__multi3(-10, 1, -10); | |
| 34 | test__multi3(1, -81985529216486895, -81985529216486895); | |
| 35 | test__multi3(-81985529216486895, 1, -81985529216486895); | |
| 36 | ||
| 37 | test__multi3(3037000499, 3037000499, 9223372030926249001); | |
| 38 | test__multi3(-3037000499, 3037000499, -9223372030926249001); | |
| 39 | test__multi3(3037000499, -3037000499, -9223372030926249001); | |
| 40 | test__multi3(-3037000499, -3037000499, 9223372030926249001); | |
| 41 | ||
| 42 | test__multi3(4398046511103, 2097152, 9223372036852678656); | |
| 43 | test__multi3(-4398046511103, 2097152, -9223372036852678656); | |
| 44 | test__multi3(4398046511103, -2097152, -9223372036852678656); | |
| 45 | test__multi3(-4398046511103, -2097152, 9223372036852678656); | |
| 46 | ||
| 47 | test__multi3(2097152, 4398046511103, 9223372036852678656); | |
| 48 | test__multi3(-2097152, 4398046511103, -9223372036852678656); | |
| 49 | test__multi3(2097152, -4398046511103, -9223372036852678656); | |
| 50 | test__multi3(-2097152, -4398046511103, 9223372036852678656); | |
| 51 | ||
| 52 | test__multi3(0x00000000000000B504F333F9DE5BE000, 0x000000000000000000B504F333F9DE5B, | |
| 53 | 0x7FFFFFFFFFFFF328DF915DA296E8A000); | |
| 54 | } |