authorgravatar for jan.hafer@rwth-aachen.deJan Philipp Hafer <jan.hafer@rwth-aachen.de> 2022-02-15 14:56:49+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-23 16:38:51-05:00
log5d89955543d30b851777ff119160e480d04a6f0e
tree2bb1bcaa2c4676a4e627fd743cc1145ea4555318
parentecf56d85efa227acf1bd9cab9ad2d5af05f7efe5

compiler_rt: specify goals, organize README and compiler_rt.zig

* goals - zig as linker for object files generated by other compilers - zig-specific runtime features for eventual standardisation * changes - missing routines are marked with `missing` - structure inspired by libgcc docs, but improved order and wording - rename misspelled functions - reorder and rephrase compiler_rt.zig to reflect documentation - potential decimal float or fixed-point arithmetic support: * 'Decimal float library routines' ca. 120 functions * 'Fixed-point fractional library routines' ca. 300 functions thanks to @Vexu for multiple reviews and @scheibo for review

5 files changed, 305 insertions(+), 58 deletions(-)

lib/std/special/compiler_rt.zig+40-45
......@@ -41,8 +41,8 @@ comptime {
4141
4242 const __extendhfxf2 = @import("compiler_rt/extend_f80.zig").__extendhfxf2;
4343 @export(__extendhfxf2, .{ .name = "__extendhfxf2", .linkage = linkage });
44 const __extendffxf2 = @import("compiler_rt/extend_f80.zig").__extendffxf2;
45 @export(__extendffxf2, .{ .name = "__extendffxf2", .linkage = linkage });
44 const __extendsfxf2 = @import("compiler_rt/extend_f80.zig").__extendsfxf2;
45 @export(__extendsfxf2, .{ .name = "__extendsfxf2", .linkage = linkage });
4646 const __extenddfxf2 = @import("compiler_rt/extend_f80.zig").__extenddfxf2;
4747 @export(__extenddfxf2, .{ .name = "__extenddfxf2", .linkage = linkage });
4848 const __extendxftf2 = @import("compiler_rt/extend_f80.zig").__extendxftf2;
......@@ -105,26 +105,6 @@ comptime {
105105 @export(__extendhfsf2, .{ .name = "__gnu_h2f_ieee", .linkage = linkage });
106106 }
107107
108 // Integral arithmetic which returns if overflow
109 const __addosi4 = @import("compiler_rt/addo.zig").__addosi4;
110 @export(__addosi4, .{ .name = "__addosi4", .linkage = linkage });
111 const __addodi4 = @import("compiler_rt/addo.zig").__addodi4;
112 @export(__addodi4, .{ .name = "__addodi4", .linkage = linkage });
113 const __addoti4 = @import("compiler_rt/addo.zig").__addoti4;
114 @export(__addoti4, .{ .name = "__addoti4", .linkage = linkage });
115 const __subosi4 = @import("compiler_rt/subo.zig").__subosi4;
116 @export(__subosi4, .{ .name = "__subosi4", .linkage = linkage });
117 const __subodi4 = @import("compiler_rt/subo.zig").__subodi4;
118 @export(__subodi4, .{ .name = "__subodi4", .linkage = linkage });
119 const __suboti4 = @import("compiler_rt/subo.zig").__suboti4;
120 @export(__suboti4, .{ .name = "__suboti4", .linkage = linkage });
121 const __mulosi4 = @import("compiler_rt/mulo.zig").__mulosi4;
122 @export(__mulosi4, .{ .name = "__mulosi4", .linkage = linkage });
123 const __mulodi4 = @import("compiler_rt/mulo.zig").__mulodi4;
124 @export(__mulodi4, .{ .name = "__mulodi4", .linkage = linkage });
125 const __muloti4 = @import("compiler_rt/mulo.zig").__muloti4;
126 @export(__muloti4, .{ .name = "__muloti4", .linkage = linkage });
127
128108 if (builtin.os.tag == .windows) {
129109 // Default stack-probe functions emitted by LLVM
130110 if (is_mingw) {
......@@ -214,8 +194,8 @@ comptime {
214194
215195 const __truncxfhf2 = @import("compiler_rt/trunc_f80.zig").__truncxfhf2;
216196 @export(__truncxfhf2, .{ .name = "__truncxfhf2", .linkage = linkage });
217 const __truncxfff2 = @import("compiler_rt/trunc_f80.zig").__truncxfff2;
218 @export(__truncxfff2, .{ .name = "__truncxfff2", .linkage = linkage });
197 const __truncxfsf2 = @import("compiler_rt/trunc_f80.zig").__truncxfsf2;
198 @export(__truncxfsf2, .{ .name = "__truncxfsf2", .linkage = linkage });
219199 const __truncxfdf2 = @import("compiler_rt/trunc_f80.zig").__truncxfdf2;
220200 @export(__truncxfdf2, .{ .name = "__truncxfdf2", .linkage = linkage });
221201 const __trunctfxf2 = @import("compiler_rt/trunc_f80.zig").__trunctfxf2;
......@@ -274,20 +254,7 @@ comptime {
274254 const __divtf3 = @import("compiler_rt/divtf3.zig").__divtf3;
275255 @export(__divtf3, .{ .name = "__divtf3", .linkage = linkage });
276256
277 // Integral bit manipulation
278 const __ashldi3 = @import("compiler_rt/shift.zig").__ashldi3;
279 @export(__ashldi3, .{ .name = "__ashldi3", .linkage = linkage });
280 const __ashlti3 = @import("compiler_rt/shift.zig").__ashlti3;
281 @export(__ashlti3, .{ .name = "__ashlti3", .linkage = linkage });
282 const __ashrdi3 = @import("compiler_rt/shift.zig").__ashrdi3;
283 @export(__ashrdi3, .{ .name = "__ashrdi3", .linkage = linkage });
284 const __ashrti3 = @import("compiler_rt/shift.zig").__ashrti3;
285 @export(__ashrti3, .{ .name = "__ashrti3", .linkage = linkage });
286 const __lshrdi3 = @import("compiler_rt/shift.zig").__lshrdi3;
287 @export(__lshrdi3, .{ .name = "__lshrdi3", .linkage = linkage });
288 const __lshrti3 = @import("compiler_rt/shift.zig").__lshrti3;
289 @export(__lshrti3, .{ .name = "__lshrti3", .linkage = linkage });
290
257 // Integer Bit operations
291258 const __clzsi2 = @import("compiler_rt/count0bits.zig").__clzsi2;
292259 @export(__clzsi2, .{ .name = "__clzsi2", .linkage = linkage });
293260 const __clzdi2 = @import("compiler_rt/count0bits.zig").__clzdi2;
......@@ -306,21 +273,18 @@ comptime {
306273 @export(__ffsdi2, .{ .name = "__ffsdi2", .linkage = linkage });
307274 const __ffsti2 = @import("compiler_rt/count0bits.zig").__ffsti2;
308275 @export(__ffsti2, .{ .name = "__ffsti2", .linkage = linkage });
309
310276 const __paritysi2 = @import("compiler_rt/parity.zig").__paritysi2;
311277 @export(__paritysi2, .{ .name = "__paritysi2", .linkage = linkage });
312278 const __paritydi2 = @import("compiler_rt/parity.zig").__paritydi2;
313279 @export(__paritydi2, .{ .name = "__paritydi2", .linkage = linkage });
314280 const __parityti2 = @import("compiler_rt/parity.zig").__parityti2;
315281 @export(__parityti2, .{ .name = "__parityti2", .linkage = linkage });
316
317282 const __popcountsi2 = @import("compiler_rt/popcount.zig").__popcountsi2;
318283 @export(__popcountsi2, .{ .name = "__popcountsi2", .linkage = linkage });
319284 const __popcountdi2 = @import("compiler_rt/popcount.zig").__popcountdi2;
320285 @export(__popcountdi2, .{ .name = "__popcountdi2", .linkage = linkage });
321286 const __popcountti2 = @import("compiler_rt/popcount.zig").__popcountti2;
322287 @export(__popcountti2, .{ .name = "__popcountti2", .linkage = linkage });
323
324288 const __bswapsi2 = @import("compiler_rt/bswap.zig").__bswapsi2;
325289 @export(__bswapsi2, .{ .name = "__bswapsi2", .linkage = linkage });
326290 const __bswapdi2 = @import("compiler_rt/bswap.zig").__bswapdi2;
......@@ -429,13 +393,26 @@ comptime {
429393 @export(__isPlatformVersionAtLeast, .{ .name = "__isPlatformVersionAtLeast", .linkage = linkage });
430394 }
431395
432 // Integral arithmetic
396 // Integer Arithmetic
397 const __ashldi3 = @import("compiler_rt/shift.zig").__ashldi3;
398 @export(__ashldi3, .{ .name = "__ashldi3", .linkage = linkage });
399 const __ashlti3 = @import("compiler_rt/shift.zig").__ashlti3;
400 @export(__ashlti3, .{ .name = "__ashlti3", .linkage = linkage });
401 const __ashrdi3 = @import("compiler_rt/shift.zig").__ashrdi3;
402 @export(__ashrdi3, .{ .name = "__ashrdi3", .linkage = linkage });
403 const __ashrti3 = @import("compiler_rt/shift.zig").__ashrti3;
404 @export(__ashrti3, .{ .name = "__ashrti3", .linkage = linkage });
405 const __lshrdi3 = @import("compiler_rt/shift.zig").__lshrdi3;
406 @export(__lshrdi3, .{ .name = "__lshrdi3", .linkage = linkage });
407 const __lshrti3 = @import("compiler_rt/shift.zig").__lshrti3;
408 @export(__lshrti3, .{ .name = "__lshrti3", .linkage = linkage });
433409 const __negsi2 = @import("compiler_rt/negXi2.zig").__negsi2;
434410 @export(__negsi2, .{ .name = "__negsi2", .linkage = linkage });
435411 const __negdi2 = @import("compiler_rt/negXi2.zig").__negdi2;
436412 @export(__negdi2, .{ .name = "__negdi2", .linkage = linkage });
437413 const __negti2 = @import("compiler_rt/negXi2.zig").__negti2;
438414 @export(__negti2, .{ .name = "__negti2", .linkage = linkage });
415
439416 const __mulsi3 = @import("compiler_rt/int.zig").__mulsi3;
440417 @export(__mulsi3, .{ .name = "__mulsi3", .linkage = linkage });
441418 const __muldi3 = @import("compiler_rt/muldi3.zig").__muldi3;
......@@ -463,7 +440,7 @@ comptime {
463440 const __udivmodsi4 = @import("compiler_rt/int.zig").__udivmodsi4;
464441 @export(__udivmodsi4, .{ .name = "__udivmodsi4", .linkage = linkage });
465442
466 // Integral arithmetic with trapping overflow
443 // Integer Arithmetic with trapping overflow
467444 const __absvsi2 = @import("compiler_rt/absv.zig").__absvsi2;
468445 @export(__absvsi2, .{ .name = "__absvsi2", .linkage = linkage });
469446 const __absvdi2 = @import("compiler_rt/absv.zig").__absvdi2;
......@@ -477,9 +454,27 @@ comptime {
477454 const __negvti2 = @import("compiler_rt/negv.zig").__negvti2;
478455 @export(__negvti2, .{ .name = "__negvti2", .linkage = linkage });
479456
480 // missing: Integral arithmetic which returns if overflow
457 // Integer arithmetic which returns if overflow
458 const __addosi4 = @import("compiler_rt/addo.zig").__addosi4;
459 @export(__addosi4, .{ .name = "__addosi4", .linkage = linkage });
460 const __addodi4 = @import("compiler_rt/addo.zig").__addodi4;
461 @export(__addodi4, .{ .name = "__addodi4", .linkage = linkage });
462 const __addoti4 = @import("compiler_rt/addo.zig").__addoti4;
463 @export(__addoti4, .{ .name = "__addoti4", .linkage = linkage });
464 const __subosi4 = @import("compiler_rt/subo.zig").__subosi4;
465 @export(__subosi4, .{ .name = "__subosi4", .linkage = linkage });
466 const __subodi4 = @import("compiler_rt/subo.zig").__subodi4;
467 @export(__subodi4, .{ .name = "__subodi4", .linkage = linkage });
468 const __suboti4 = @import("compiler_rt/subo.zig").__suboti4;
469 @export(__suboti4, .{ .name = "__suboti4", .linkage = linkage });
470 const __mulosi4 = @import("compiler_rt/mulo.zig").__mulosi4;
471 @export(__mulosi4, .{ .name = "__mulosi4", .linkage = linkage });
472 const __mulodi4 = @import("compiler_rt/mulo.zig").__mulodi4;
473 @export(__mulodi4, .{ .name = "__mulodi4", .linkage = linkage });
474 const __muloti4 = @import("compiler_rt/mulo.zig").__muloti4;
475 @export(__muloti4, .{ .name = "__muloti4", .linkage = linkage });
481476
482 // Integral comparison
477 // Integer Comparison
483478 // (a < b) => 0
484479 // (a == b) => 1
485480 // (a > b) => 2
lib/std/special/compiler_rt/README.md+261-9
......@@ -1,15 +1,267 @@
1This compiler-rt library is ported from [LLVM](http://compiler-rt.llvm.org/).
1If hardware lacks basic or specialized functionality, compiler-rt adds such functionality
2for basic arithmetic(s).
3One such example is 64-bit integer multiplication on 32-bit x86.
24
3It's needed because LLVM emits library calls to compiler-rt when hardware lacks
4functionality, for example, 64-bit integer multiplication on 32-bit x86.
5Goals:
61. zig as linker for object files produced by other compilers
7 => `function compatibility` to compiler-rt and libgcc for same-named functions
8 * compatibility conflict between compiler-rt and libgcc: prefer compiler-rt
92. `symbol-level compatibility` low-priority compared to emitted calls by llvm
10 * symbol-level compatibility: libgcc even lower priority
113. add zig-specific language runtime features, see #7265
12 * example: arbitrary bit width integer arithmetic
13 * lower to call those functions for e.g. multiplying two i12345 numbers together
14 * proper naming + documention for standardizing (allow languages to follow our exmaple)
15
16Current status (tracking libgcc documentation):
17- Integer library routines => almost implemented
18- Soft float library routines => only f80 routines missing
19- Decimal float library routines => unimplemented (~120 functions)
20- Fixed-point fractional library routines => unimplemented (~300 functions)
21- Exception handling routines => unclear, if supported (~32+x undocumented functions)
22- Miscellaneous routines => unclear, if supported (cache control and stack function)
23- No zig-specific language runtime features in compiler-rt yet
524
625This library is automatically built as-needed for the compilation target and
726then statically linked and therefore is a transparent dependency for the
827programmer.
28For details see `../compiler_rt.zig`.
29
30The routines in this folder are listed below.
31Routines are annotated as `type source routine // description`, with `routine`
32being the name used in aforementioned `compiler_rt.zig`.
33`dev` means deviating from compiler_rt, `port` ported, `source` is the
34information source for the implementation, `none` means unimplemented.
35Some examples for the naming convention are:
36- dev source name_routine, name_routine2 various implementations for performance, simplicity etc
37- port llvm compiler-rt library routines from [LLVM](http://compiler-rt.llvm.org/)
38 * LLVM emits library calls to compiler-rt, if the hardware lacks functionality
39- port musl libc routines from [musl](https://musl.libc.org/)
40If the library or information source is uncommon, use the entry `other` for `source`.
41Please do not break the search by inserting entries in another format than `impl space source`.
42
43Bugs should be solved by trying to duplicate the bug upstream, if possible.
44 * If the bug exists upstream, get it fixed upstream and port the fix downstream to Zig.
45 * If the bug only exists in Zig, use the corresponding C code and debug
46 both implementations side by side to figure out what is wrong.
47
48## Integer library routines
49
50#### Integer Bit operations
51- dev HackersDelight __clzsi2 // count leading zeros
52- dev HackersDelight __clzdi2 // count leading zeros
53- dev HackersDelight __clzti2 // count leading zeros
54- dev HackersDelight __ctzsi2 // count trailing zeros
55- dev HackersDelight __ctzdi2 // count trailing zeros
56- dev HackersDelight __ctzti2 // count trailing zeros
57- dev __ctzsi2 __ffssi2 // find least significant 1 bit
58- dev __ctzsi2 __ffsdi2 // find least significant 1 bit
59- dev __ctzsi2 __ffsti2 // find least significant 1 bit
60- dev BitTwiddlingHacks __paritysi2 // bit parity
61- dev BitTwiddlingHacks __paritydi2 // bit parity
62- dev BitTwiddlingHacks __parityti2 // bit parity
63- dev TAOCP __popcountsi2 // bit population
64- dev TAOCP __popcountdi2 // bit population
65- dev TAOCP __popcountti2 // bit population
66- dev other __bswapsi2 // a byteswapped
67- dev other __bswapdi2 // a byteswapped
68- dev other __bswapti2 // a byteswapped
69
70#### Integer Comparison
71- port llvm __cmpsi2 // (a<b)=>output=0, (a==b)=>output=1, (a>b)=>output=2
72- port llvm __cmpdi2
73- port llvm __cmpti2
74- port llvm __ucmpsi2 // (a<b)=>output=0, (a==b)=>output=1, (a>b)=>output=2
75- port llvm __ucmpdi2
76- port llvm __ucmpti2
77
78#### Integer Arithmetic
79- none none __ashlsi3 // a << b unused in llvm, missing (e.g. used by rl78)
80- port llvm __ashldi3 // a << b
81- port llvm __ashlti3 // a << b
82- none none __ashrsi3 // a >> b arithmetic (sign fill) missing (e.g. used by rl78)
83- port llvm __ashrdi3 // a >> b arithmetic (sign fill)
84- port llvm __ashrti3 // a >> b arithmetic (sign fill)
85- none none __lshrsi3 // a >> b logical (zero fill) missing (e.g. used by rl78)
86- port llvm __lshrdi3 // a >> b logical (zero fill)
87- port llvm __lshrti3 // a >> b logical (zero fill)
88- port llvm __negdi2 // -a symbol-level compatibility: libgcc
89- port llvm __negti2 // -a unnecessary: unused in backends
90- port llvm __mulsi3 // a * b signed
91- port llvm __muldi3 // a * b signed
92- port llvm __multi3 // a * b signed
93- port llvm __divsi3 // a / b signed
94- port llvm __divdi3 // a / b signed
95- port llvm __divti3 // a / b signed
96- port llvm __udivsi3 // a / b unsigned
97- port llvm __udivdi3 // a / b unsigned
98- port llvm __udivti3 // a / b unsigned
99- port llvm __modsi3 // a % b signed
100- port llvm __moddi3 // a % b signed
101- port llvm __modti3 // a % b signed
102- port llvm __umodsi3 // a % b unsigned
103- port llvm __umoddi3 // a % b unsigned
104- port llvm __umodti3 // a % b unsigned
105- port llvm __udivmoddi4 // a / b, rem.* = a % b unsigned
106- port llvm __udivmodti4 // a / b, rem.* = a % b unsigned
107- port llvm __udivmodsi4 // a / b, rem.* = a % b unsigned
108- port llvm __divmodsi4 // a / b, rem.* = a % b signed, ARM
109
110#### Integer Arithmetic with trapping overflow
111- dev BitTwiddlingHacks __absvsi2 // abs(a)
112- dev BitTwiddlingHacks __absvdi2 // abs(a)
113- dev BitTwiddlingHacks __absvti2 // abs(a)
114- port llvm __negvsi2 // -a symbol-level compatibility: libgcc
115- port llvm __negvdi2 // -a unnecessary: unused in backends
116- port llvm __negvti2 // -a
117- TODO upstreaming __addvsi3..__mulvti3 after testing panics works
118- dev HackersDelight __addvsi3 // a + b
119- dev HackersDelight __addvdi3 // a + b
120- dev HackersDelight __addvti3 // a + b
121- dev HackersDelight __subvsi3 // a - b
122- dev HackersDelight __subvdi3 // a - b
123- dev HackersDelight __subvti3 // a - b
124- dev HackersDelight __mulvsi3 // a * b
125- dev HackersDelight __mulvdi3 // a * b
126- dev HackersDelight __mulvti3 // a * b
127
128#### Integer Arithmetic which returns if overflow (would be faster without pointer)
129- dev HackersDelight __addosi4 // a + b, overflow=>ov.*=1 else 0
130- dev HackersDelight __addodi4 // (completeness + performance, llvm does not use them)
131- dev HackersDelight __addoti4 //
132- dev HackersDelight __subosi4 // a - b, overflow=>ov.*=1 else 0
133- dev HackersDelight __subodi4 // (completeness + performance, llvm does not use them)
134- dev HackersDelight __suboti4 //
135- dev HackersDelight __mulosi4 // a * b, overflow=>ov.*=1 else 0
136- dev HackersDelight __mulodi4 // (required by llvm)
137- dev HackersDelight __muloti4 //
138
139## Float library routines
140
141#### Float Conversion
142- todo todo __extendsfdf2 // extend a f32 => f64
143- todo todo __extendsftf2 // extend a f32 => f128
144- dev llvm __extendsfxf2 // extend a f32 => f80
145- todo todo __extenddftf2 // extend a f64 => f128
146- dev llvm __extenddfxf2 // extend a f64 => f80
147- todo todo __truncdfsf2 // truncate a to narrower mode of return type, rounding towards zero
148- todo todo __trunctfdf2 //
149- todo todo __trunctfsf2 //
150- dev llvm __truncxfsf2 //
151- dev llvm __truncxfdf2 //
152- todo todo __fixsfsi // convert a to i32, rounding towards zero
153- todo todo __fixdfsi //
154- todo todo __fixtfsi //
155- none none __fixxfsi // missing
156- todo todo __fixsfdi // convert a to i64, rounding towards zero
157- todo todo __fixdfdi //
158- todo todo __fixtfdi //
159- none none __fixxfdi // missing
160- todo todo __fixsfti // convert a to i128, rounding towards zero
161- todo todo __fixdfti //
162- todo todo __fixtfdi //
163- none none __fixxfti // missing
164
165- __fixunssfsi // convert to u32, rounding towards zero. negative values become 0.
166- __fixunsdfsi //
167- __fixunstfsi //
168- __fixunsxfsi // missing
169- __fixunssfdi // convert to u64, rounding towards zero. negative values become 0.
170- __fixunsdfdi //
171- __fixunstfdi //
172- __fixunsxfdi // missing
173- __fixunssfti // convert to u128, rounding towards zero. negative values become 0.
174- __fixunsdfti //
175- __fixunstfdi //
176- __fixunsxfti // missing
177
178- __floatsisf // convert i32 to floating point
179- __floatsidf //
180- __floatsitf //
181- __floatsixf // missing
182- __floatdisf // convert i64 to floating point
183- __floatdidf //
184- __floatditf //
185- __floatdixf // missing
186- __floattisf // convert i128 to floating point
187- __floattidf //
188- __floattixf // missing
189
190- __floatunsisf // convert i32 to floating point
191- __floatunsidf //
192- __floatunsitf //
193- __floatunsixf // missing
194- __floatundisf // convert i64 to floating point
195- __floatundidf //
196- __floatunditf //
197- __floatundixf // missing
198- __floatuntisf // convert i128 to floating point
199- __floatuntidf //
200- __floatuntitf //
201- __floatuntixf // missing
202
203#### Float Comparison
204- __cmpsf2 // return (a<b)=>-1,(a==b)=>0,(a>b)=>1,Nan=>1 dont rely on this
205- __cmpdf2 // exported from __lesf2, __ledf2, __letf2 (below)
206- __cmptf2 //
207- __unordsf2 // (input==NaN) => out!=0 else out=0,
208- __unorddf2 // __only reliable for (input!=Nan)__
209- __unordtf2 //
210- __eqsf2 // (a!=NaN) and (b!=Nan) and (a==b) => output=0
211- __eqdf2 //
212- __eqtf2 //
213- __nesf2 // (a==NaN) or (b==Nan) or (a!=b) => output!=0
214- __nedf2 //
215- __netf2 //
216- __gesf2 // (a!=Nan) and (b!=Nan) and (a>=b) => output>=0
217- __gedf2 //
218- __getf2 //
219- __ltsf2 // (a!=Nan) and (b!=Nan) and (a<b) => output<0
220- __ltdf2 //
221- __lttf2 //
222- __lesf2 // (a!=Nan) and (b!=Nan) and (a<=b) => output<=0
223- __ledf2 //
224- __letf2 //
225- __gtsf2 // (a!=Nan) and (b!=Nan) and (a>b) => output>0
226- __gtdf2 //
227- __gttf2 //
228
229#### Float Arithmetic
230- __addsf3 // a + b f32
231- __adddf3 // a + b f64
232- __addtf3 // a + b f128
233- __addxf3 // a + b f80
234- __aeabi_fadd // a + b f64 ARM: AAPCS
235- __aeabi_dadd // a + b f64 ARM: AAPCS
236- __subsf3 // a - b
237- __subdf3 // a - b
238- __subtf3 // a - b
239- __subxf3 // a - b f80
240- __aeabi_fsub // a - b f64 ARM: AAPCS
241- __aeabi_dsub // a - b f64 ARM: AAPCS
242- __mulsf3 // a * b
243- __muldf3 // a * b
244- __multf3 // a * b
245- __mulxf3 // a * b missing
246- __divsf3 // a / b
247- __divdf3 // a / b
248- __divtf3 // a / b
249- __divxf3 // a / b missing
250- __negsf2 // -a symbol-level compatibility: libgcc uses this for the rl78
251- __negdf2 // -a unnecessary: can be lowered directly to a xor
252- __negtf2 // -a
253- __negxf2 // -a
9254
10Any bugs should be solved by trying to duplicate the bug upstream.
11 * If the bug exists upstream, get it fixed with the LLVM team and then port
12 the fix downstream to Zig.
13 * If the bug only exists in Zig, something went wrong porting the code,
14 and you can run the C code and Zig code side by side in a debugger
15 to figure out what's happening differently.
255#### Floating point raised to integer power
256- __powisf2 // unclear, if supported a ^ b
257- __powidf2 //
258- __powitf2 //
259- __powixf2 //
260- __mulsc3 // unsupported (a+ib) * (c+id)
261- __muldc3 //
262- __multc3 //
263- __mulxc3 //
264- __divsc3 // unsupported (a+ib) * / (c+id)
265- __divdc3 //
266- __divtc3 //
267- __divxc3 //
lib/std/special/compiler_rt/extend_f80.zig+1-1
......@@ -11,7 +11,7 @@ pub fn __extendhfxf2(a: F16T) callconv(.C) f80 {
1111 return extendF80(f16, @bitCast(u16, a));
1212}
1313
14pub fn __extendffxf2(a: f32) callconv(.C) f80 {
14pub fn __extendsfxf2(a: f32) callconv(.C) f80 {
1515 return extendF80(f32, @bitCast(u32, a));
1616}
1717
lib/std/special/compiler_rt/trunc_f80.zig+1-1
......@@ -10,7 +10,7 @@ pub fn __truncxfhf2(a: f80) callconv(.C) F16T {
1010 return @bitCast(F16T, trunc(f16, a));
1111}
1212
13pub fn __truncxfff2(a: f80) callconv(.C) f32 {
13pub fn __truncxfsf2(a: f80) callconv(.C) f32 {
1414 return trunc(f32, a);
1515}
1616
src/stage1/codegen.cpp+2-2
......@@ -1641,7 +1641,7 @@ static LLVMValueRef gen_soft_f80_widen_or_shorten(CodeGen *g, ZigType *actual_ty
16411641 break;
16421642 case 32:
16431643 return_type = g->builtin_types.entry_f32->llvm_type;
1644 func_name = "__truncxfff2";
1644 func_name = "__truncxfsf2";
16451645 break;
16461646 case 64:
16471647 return_type = g->builtin_types.entry_f64->llvm_type;
......@@ -1670,7 +1670,7 @@ static LLVMValueRef gen_soft_f80_widen_or_shorten(CodeGen *g, ZigType *actual_ty
16701670 break;
16711671 case 32:
16721672 param_type = g->builtin_types.entry_f32->llvm_type;
1673 func_name = "__extendffxf2";
1673 func_name = "__extendsfxf2";
16741674 break;
16751675 case 64:
16761676 param_type = g->builtin_types.entry_f64->llvm_type;