| author | |
| committer | |
| log | 3e72411db011dfdd35d8eb9b2f51ea5c55a61d1e |
| tree | eba97a3ba5f63b3441c034b001b50a96db29e02a |
| parent | 67fb4d13593fb6f940415fda2abd56c452c7a28e |
| signature |
* 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,6 +625,7 @@ set(ZIG_STD_FILES |
| 625 | "special/compiler_rt/floatuntitf.zig" | 625 | "special/compiler_rt/floatuntitf.zig" |
| 626 | "special/compiler_rt/index.zig" | 626 | "special/compiler_rt/index.zig" |
| 627 | "special/compiler_rt/muloti4.zig" | 627 | "special/compiler_rt/muloti4.zig" |
| 628 | "special/compiler_rt/multi3.zig" | ||
| 628 | "special/compiler_rt/truncXfYf2.zig" | 629 | "special/compiler_rt/truncXfYf2.zig" |
| 629 | "special/compiler_rt/udivmod.zig" | 630 | "special/compiler_rt/udivmod.zig" |
| 630 | "special/compiler_rt/udivmoddi4.zig" | 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,6 +1084,8 @@ bool want_first_arg_sret(CodeGen *g, FnTypeId *fn_type_id) { |
| 1084 | } | 1084 | } |
| 1085 | zig_panic("TODO implement C ABI for x86_64 return types. type '%s'\nSee https://github.com/ziglang/zig/issues/1481", | 1085 | zig_panic("TODO implement C ABI for x86_64 return types. type '%s'\nSee https://github.com/ziglang/zig/issues/1481", |
| 1086 | buf_ptr(&fn_type_id->return_type->name)); | 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 | zig_panic("TODO implement C ABI for this architecture. See https://github.com/ziglang/zig/issues/1481"); | 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,6 +80,7 @@ comptime { |
| 80 | @export("___chkstk_ms", ___chkstk_ms, linkage); | 80 | @export("___chkstk_ms", ___chkstk_ms, linkage); |
| 81 | } | 81 | } |
| 82 | @export("__divti3", @import("divti3.zig").__divti3_windows_x86_64, linkage); | 82 | @export("__divti3", @import("divti3.zig").__divti3_windows_x86_64, linkage); |
| 83 | @export("__multi3", @import("multi3.zig").__multi3_windows_x86_64, linkage); | ||
| 83 | @export("__muloti4", @import("muloti4.zig").__muloti4_windows_x86_64, linkage); | 84 | @export("__muloti4", @import("muloti4.zig").__muloti4_windows_x86_64, linkage); |
| 84 | @export("__udivti3", @import("udivti3.zig").__udivti3_windows_x86_64, linkage); | 85 | @export("__udivti3", @import("udivti3.zig").__udivti3_windows_x86_64, linkage); |
| 85 | @export("__udivmodti4", @import("udivmodti4.zig").__udivmodti4_windows_x86_64, linkage); | 86 | @export("__udivmodti4", @import("udivmodti4.zig").__udivmodti4_windows_x86_64, linkage); |
| ... | @@ -89,6 +90,7 @@ comptime { | ... | @@ -89,6 +90,7 @@ comptime { |
| 89 | } | 90 | } |
| 90 | } else { | 91 | } else { |
| 91 | @export("__divti3", @import("divti3.zig").__divti3, linkage); | 92 | @export("__divti3", @import("divti3.zig").__divti3, linkage); |
| 93 | @export("__multi3", @import("multi3.zig").__multi3, linkage); | ||
| 92 | @export("__muloti4", @import("muloti4.zig").__muloti4, linkage); | 94 | @export("__muloti4", @import("muloti4.zig").__muloti4, linkage); |
| 93 | @export("__udivti3", @import("udivti3.zig").__udivti3, linkage); | 95 | @export("__udivti3", @import("udivti3.zig").__udivti3, linkage); |
| 94 | @export("__udivmodti4", @import("udivmodti4.zig").__udivmodti4, linkage); | 96 | @export("__udivmodti4", @import("udivmodti4.zig").__udivmodti4, linkage); |
| ... | @@ -149,6 +151,7 @@ extern fn __aeabi_uldivmod(numerator: u64, denominator: u64) AeabiUlDivModResult | ... | @@ -149,6 +151,7 @@ extern fn __aeabi_uldivmod(numerator: u64, denominator: u64) AeabiUlDivModResult |
| 149 | 151 | ||
| 150 | fn isArmArch() bool { | 152 | fn isArmArch() bool { |
| 151 | return switch (builtin.arch) { | 153 | return switch (builtin.arch) { |
| 154 | builtin.Arch.armv8_3a, | ||
| 152 | builtin.Arch.armv8_2a, | 155 | builtin.Arch.armv8_2a, |
| 153 | builtin.Arch.armv8_1a, | 156 | builtin.Arch.armv8_1a, |
| 154 | builtin.Arch.armv8, | 157 | builtin.Arch.armv8, |
| ... | @@ -160,6 +163,7 @@ fn isArmArch() bool { | ... | @@ -160,6 +163,7 @@ fn isArmArch() bool { |
| 160 | builtin.Arch.armv7m, | 163 | builtin.Arch.armv7m, |
| 161 | builtin.Arch.armv7s, | 164 | builtin.Arch.armv7s, |
| 162 | builtin.Arch.armv7k, | 165 | builtin.Arch.armv7k, |
| 166 | builtin.Arch.armv7ve, | ||
| 163 | builtin.Arch.armv6, | 167 | builtin.Arch.armv6, |
| 164 | builtin.Arch.armv6m, | 168 | builtin.Arch.armv6m, |
| 165 | builtin.Arch.armv6k, | 169 | builtin.Arch.armv6k, |
| ... | @@ -167,6 +171,7 @@ fn isArmArch() bool { | ... | @@ -167,6 +171,7 @@ fn isArmArch() bool { |
| 167 | builtin.Arch.armv5, | 171 | builtin.Arch.armv5, |
| 168 | builtin.Arch.armv5te, | 172 | builtin.Arch.armv5te, |
| 169 | builtin.Arch.armv4t, | 173 | builtin.Arch.armv4t, |
| 174 | builtin.Arch.armebv8_3a, | ||
| 170 | builtin.Arch.armebv8_2a, | 175 | builtin.Arch.armebv8_2a, |
| 171 | builtin.Arch.armebv8_1a, | 176 | builtin.Arch.armebv8_1a, |
| 172 | builtin.Arch.armebv8, | 177 | builtin.Arch.armebv8, |
| ... | @@ -178,6 +183,7 @@ fn isArmArch() bool { | ... | @@ -178,6 +183,7 @@ fn isArmArch() bool { |
| 178 | builtin.Arch.armebv7m, | 183 | builtin.Arch.armebv7m, |
| 179 | builtin.Arch.armebv7s, | 184 | builtin.Arch.armebv7s, |
| 180 | builtin.Arch.armebv7k, | 185 | builtin.Arch.armebv7k, |
| 186 | builtin.Arch.armebv7ve, | ||
| 181 | builtin.Arch.armebv6, | 187 | builtin.Arch.armebv6, |
| 182 | builtin.Arch.armebv6m, | 188 | builtin.Arch.armebv6m, |
| 183 | builtin.Arch.armebv6k, | 189 | builtin.Arch.armebv6k, |
| ... | @@ -185,6 +191,22 @@ fn isArmArch() bool { | ... | @@ -185,6 +191,22 @@ fn isArmArch() bool { |
| 185 | builtin.Arch.armebv5, | 191 | builtin.Arch.armebv5, |
| 186 | builtin.Arch.armebv5te, | 192 | builtin.Arch.armebv5te, |
| 187 | builtin.Arch.armebv4t, | 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 | => true, | 210 | => true, |
| 189 | else => false, | 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 | } | ||