From f618398b24acdc3317e6fd81f486d49176ffcef9 Mon Sep 17 00:00:00 2001 From: Jan Philipp Hafer Date: Wed, 26 Apr 2023 01:42:13 +0200 Subject: [PATCH] compiler_rt: document ARM status This commit documents the status of Run-time ABI 2022Q3 for ARM excluding C++ helper functions. --- lib/compiler_rt/README.md | 86 +++++++++++++++++++++++++++++++++++++-- lib/compiler_rt/arm.zig | 11 ++++- 2 files changed, 93 insertions(+), 4 deletions(-) diff --git a/lib/compiler_rt/README.md b/lib/compiler_rt/README.md index 468821bee4d1..47c0e7978abf 100644 --- a/lib/compiler_rt/README.md +++ b/lib/compiler_rt/README.md @@ -72,9 +72,11 @@ Integer and Float Operations | | | | | | **Integer Comparison** | | ✓ | __cmpsi2 | i32 | i32 | i32 | `(a 0, (a==b) -> 1, (a>b) -> 2` | | ✓ | __cmpdi2 | i64 | i64 | i32 | .. | +| ✗ | __aeabi_lcmp | i64 | i64 | i32 | .. ARM | | ✓ | __cmpti2 | i128 | i128 | i32 | .. | | ✓ | __ucmpsi2 | u32 | u32 | i32 | `(a 0, (a==b) -> 1, (a>b) -> 2` | | ✓ | __ucmpdi2 | u64 | u64 | i32 | .. | +| ✗ | __aeabi_ulcmp | u64 | u64 | i32 | .. ARM | | ✓ | __ucmpti2 | u128 | u128 | i32 | .. | | | | | | | **Integer Arithmetic** | | ✓ | __ashlsi3 | i32 | i32 | i32 | `a << b` [^unused_rl78] | @@ -94,6 +96,7 @@ Integer and Float Operations | ✓ | __negti2 | i128 | i128 | i128 | .. | | ✓ | __mulsi3 | i32 | i32 | i32 | `a * b` | | ✓ | __muldi3 | i64 | i64 | i64 | .. | +| ✓ | __aeabi_lmul | i64 | i64 | i64 | .. ARM | | ✓ | __multi3 | i128 | i128 | i128 | .. | | ✓ | __divsi3 | i32 | i32 | i32 | `a / b` | | ✓ | __divdi3 | i64 | i64 | i64 | .. | @@ -110,10 +113,14 @@ Integer and Float Operations | ✓ | __umoddi3 | u64 | u64 | u64 | .. | | ✓ | __umodti3 | u128 | u128 | u128 | .. | | ✓ | __udivmodsi4 | u32 | u32 | u32 | `a / b, rem.* = a % b` | +| ✓ | __aeabi_uidivmod | u32 | u32 | u32 | .. ARM | | ✓ | __udivmoddi4 | u64 | u64 | u64 | .. | +| ✓ | __aeabi_uldivmod | u64 | u64 | u64 | .. ARM | | ✓ | __udivmodti4 | u128 | u128 | u128 | .. | | ✓ | __divmodsi4 | i32 | i32 | i32 | `a / b, rem.* = a % b` | +| ✓ | __aeabi_idivmod | i32 | i32 | i32 | .. ARM | | ✓ | __divmoddi4 | i64 | i64 | i64 | .. | +| ✓ | __aeabi_ldivmod | i64 | i64 | i64 | .. ARM | | ✓ | __divmodti4 | i128 | i128 | i128 | .. [^libgcc_compat] | | | | | | | **Integer Arithmetic with Trapping Overflow**| | ✓ | __absvsi2 | i32 | i32 | i32 | abs(a) | @@ -142,11 +149,16 @@ Integer and Float Operations | ✓ | __mulodi4 | i64 | i64 | i64 | .. | | ✓ | __muloti4 | i128 | i128 | i128 | .. | | | | | | | **Float Conversion** | +| ✓ | __extendhfdf2 | f16 | ∅ | f32 | .. | | ✓ | __extendsfdf2 | f32 | ∅ | f64 | .. | +| ✓ | __aeabi_f2d | f32 | ∅ | f64 | .. | | ✓ | __extendsftf2 | f32 | ∅ | f128 | .. | | ✓ | __extendsfxf2 | f32 | ∅ | f80 | .. | | ✓ | __extenddftf2 | f64 | ∅ | f128 | .. | | ✓ | __extenddfxf2 | f64 | ∅ | f80 | .. | +| ✗ | __aeabi_h2f | f16 | ∅ | f32 | .. ARM | +| ✗ | __aeabi_h2f_alt | f16 | ∅ | f32 | .. ARM alternate [^VFPv3alt] | +| ✓ | __gnu_h2f_ieee | f16 | ∅ | f32 | .. GNU naming convention | | ✓ | __truncsfhf2 | f32 | ∅ | f16 | rounding towards zero | | ✓ | __truncdfhf2 | f64 | ∅ | f16 | .. | | ✓ | __truncdfsf2 | f64 | ∅ | f32 | .. | @@ -157,9 +169,11 @@ Integer and Float Operations | ✓ | __truncxfhf2 | f80 | ∅ | f16 | .. | | ✓ | __truncxfsf2 | f80 | ∅ | f32 | .. | | ✓ | __truncxfdf2 | f80 | ∅ | f64 | .. | -| ✓ | __aeabi_f2h | f32 | ∅ | f16 | .. ARM | -| ✓ | __gnu_f2h_ieee | f32 | ∅ | f16 | ..GNU naming convention | +| ✗ | __aeabi_f2h | f32 | ∅ | f16 | .. ARM | +| ✗ | __aeabi_f2h_alt | f32 | ∅ | f16 | .. ARM alternate [^VFPv3alt] | +| ✓ | __gnu_f2h_ieee | f32 | ∅ | f16 | .. GNU naming convention | | ✓ | __aeabi_d2h | f64 | ∅ | f16 | .. ARM | +| ✗ | __aeabi_d2h_alt | f64 | ∅ | f16 | .. ARM alternate [^VFPv3alt] | | ✓ | __aeabi_d2f | f64 | ∅ | f32 | .. ARM | | ✓ | __trunckfsf2 | f128 | ∅ | f32 | .. PPC | | ✓ | _Qp_qtos |*f128 | ∅ | f32 | .. SPARC | @@ -167,12 +181,16 @@ Integer and Float Operations | ✓ | _Qp_qtod |*f128 | ∅ | f64 | .. SPARC | | ✓ | __fixhfsi | f16 | ∅ | i32 | float to int, rounding towards zero | | ✓ | __fixsfsi | f32 | ∅ | i32 | .. | +| ✓ | __aeabi_f2iz | f32 | ∅ | i32 | .. ARM | | ✓ | __fixdfsi | f64 | ∅ | i32 | .. | +| ✓ | __aeabi_d2iz | f64 | ∅ | i32 | .. ARM | | ✓ | __fixtfsi | f128 | ∅ | i32 | .. | | ✓ | __fixxfsi | f80 | ∅ | i32 | .. | | ✓ | __fixhfdi | f16 | ∅ | i64 | .. | | ✓ | __fixsfdi | f32 | ∅ | i64 | .. | +| ✓ | __aeabi_f2lz | f32 | ∅ | i64 | .. ARM | | ✓ | __fixdfdi | f64 | ∅ | i64 | .. | +| ✓ | __aeabi_d2lz | f64 | ∅ | i64 | .. ARM | | ✓ | __fixtfdi | f128 | ∅ | i64 | .. | | ✓ | __fixxfdi | f80 | ∅ | i64 | .. | | ✓ | __fixhfti | f16 | ∅ | i128 | .. | @@ -182,12 +200,16 @@ Integer and Float Operations | ✓ | __fixxfti | f80 | ∅ | i128 | .. | | ✓ | __fixunshfsi | f16 | ∅ | u32 | float to uint, rounding towards zero. negative values become 0. | | ✓ | __fixunssfsi | f32 | ∅ | u32 | .. | +| ✓ | __aeabi_f2uiz | f32 | ∅ | u32 | .. ARM | | ✓ | __fixunsdfsi | f64 | ∅ | u32 | .. | +| ✓ | __aeabi_d2uiz | f64 | ∅ | u32 | .. ARM | | ✓ | __fixunstfsi | f128 | ∅ | u32 | .. | | ✓ | __fixunsxfsi | f80 | ∅ | u32 | .. | | ✓ | __fixunshfdi | f16 | ∅ | u64 | .. | | ✓ | __fixunssfdi | f32 | ∅ | u64 | .. | +| ✓ | __aeabi_f2ulz | f32 | ∅ | u64 | .. ARM | | ✓ | __fixunsdfdi | f64 | ∅ | u64 | .. | +| ✓ | __aeabi_d2ulz | f64 | ∅ | u64 | .. ARM | | ✓ | __fixunstfdi | f128 | ∅ | u64 | .. | | ✓ | __fixunsxfdi | f80 | ∅ | u64 | .. | | ✓ | __fixunshfti | f16 | ∅ | u128 | .. | @@ -197,11 +219,15 @@ Integer and Float Operations | ✓ | __fixunsxfti | f80 | ∅ | u128 | .. | | ✓ | __floatsihf | i32 | ∅ | f16 | int to float | | ✓ | __floatsisf | i32 | ∅ | f32 | .. | +| ✓ | __aeabi_i2f | i32 | ∅ | f32 | .. ARM | | ✓ | __floatsidf | i32 | ∅ | f64 | .. | +| ✓ | __aeabi_i2d | i32 | ∅ | f64 | .. ARM | | ✓ | __floatsitf | i32 | ∅ | f128 | .. | | ✓ | __floatsixf | i32 | ∅ | f80 | .. | | ✓ | __floatdisf | i64 | ∅ | f32 | .. | +| ✓ | __aeabi_l2f | i64 | ∅ | f32 | .. ARM | | ✓ | __floatdidf | i64 | ∅ | f64 | .. | +| ✓ | __aeabi_l2d | i64 | ∅ | f64 | .. ARM | | ✓ | __floatditf | i64 | ∅ | f128 | .. | | ✓ | __floatdixf | i64 | ∅ | f80 | .. | | ✓ | __floattihf | i128 | ∅ | f16 | .. | @@ -211,12 +237,16 @@ Integer and Float Operations | ✓ | __floattixf | i128 | ∅ | f80 | .. | | ✓ | __floatunsihf | u32 | ∅ | f16 | uint to float | | ✓ | __floatunsisf | u32 | ∅ | f32 | .. | +| ✓ | __aeabi_ui2f | u32 | ∅ | f32 | .. ARM | | ✓ | __floatunsidf | u32 | ∅ | f64 | .. | +| ✓ | __aeabi_ui2d | u32 | ∅ | f64 | .. ARM | | ✓ | __floatunsitf | u32 | ∅ | f128 | .. | | ✓ | __floatunsixf | u32 | ∅ | f80 | .. | | ✓ | __floatundihf | u64 | ∅ | f16 | .. | | ✓ | __floatundisf | u64 | ∅ | f32 | .. | +| ✓ | __aeabi_ul2f | u64 | ∅ | f32 | .. ARM | | ✓ | __floatundidf | u64 | ∅ | f64 | .. | +| ✓ | __aeabi_ul2d | u64 | ∅ | f64 | .. ARM | | ✓ | __floatunditf | u64 | ∅ | f128 | .. | | ✓ | __floatundixf | u64 | ∅ | f80 | .. | | ✓ | __floatuntihf | u128 | ∅ | f16 | .. | @@ -353,6 +383,7 @@ Integer and Float Operations [^noptr_faster]: Operations without pointer and without C struct semantics lead to better optimizations. [^perf_addition]: Has better performance than standard method due to 2s complement semantics. Not provided by LLVM and libgcc. +[^VFPv3alt]: Converts IEEE-format to VFPv3 alternative-format. Decimal float library routines @@ -712,8 +743,57 @@ TODO brief description | | | | | | | |**BigInt Arithmetic which Return on Overflow**[^noptr_faster]| Further content (conditionally) exported with C abi: + +ARM-only routines + +| Done | Name | a | b | Out | Comment | +| ---- | -------- | --- | --- | -----| ----------------------| +| | | | | | **Float Comparison** | +|✗|__aeabi_cfcmpeq | f32 | f32 | void | `a == b` result in PSR ZC flags[^PSRZC] | +|✗|__aeabi_cfcmple | f32 | f32 | void | `a <= b` result .. | +|✗|__aeabi_cfrcmple| f32 | f32 | void | `b <= a` .. | +|✗|__aeabi_cdcmpeq | f64 | f64 | void | `a == b` .. | +|✗|__aeabi_cdcmple | f64 | f64 | void | `a <= b` .. | +|✗|__aeabi_cdrcmple| f64 | f64 | void | `b <= a` .. | +| | | | | | **Float Arithmetic** | +|✗|__aeabi_frsub | f64 | f64 | f64 | `b - a` | +|✗|__aeabi_drsub | f64 | f64 | f64 | .. | +| | | | | | **Special** | +|✓|__aeabi_read_tp | ∅ | ∅ | *u8 | ret tls pointer | +|✗|__aeabi_idiv0 | i32 | ∅ | i32 | div by 0 modifier | +|✗|__aeabi_ldiv0 | i64 | ∅ | i64 | div by 0 modifier | +| | | | | | **Unaligned memory access** | +|✗|__aeabi_uread4 |[*]u8| ∅ | i32 | ret value read | +|✗|__aeabi_uwrite4 | i32 |[*]u8| i32 | ret value written | +|✗|__aeabi_uread8 |[*]u8| ∅ | i64 | .. | +|✗|__aeabi_uwrite8 | i64 |[*]u8| i64 | .. | + + +| Done | Name | a | b | c | Comment | +| ---- | -------- | --- | --- | -----| ----------------------| +| | | | | | **Memory copy, move and set** | +|✓|__aeabi_memcpy8 |[*]u8|[*]u8| usize| *dest, *src, size | +|✓|__aeabi_memcpy4 |[*]u8|[*]u8| usize| .. | +|✓|__aeabi_memcpy |[*]u8|[*]u8| usize| .. | +|✓|__aeabi_memmove8|[*]u8|[*]u8| usize| *dest, *src, size | +|✓|__aeabi_memmove4|[*]u8|[*]u8| usize| .. | +|✓|__aeabi_memmove |[*]u8|[*]u8| usize| .. | +|✓|__aeabi_memset8 |[*]u8|usize| i32 | *dest, size, char | +|✓|__aeabi_memset4 |[*]u8|usize| i32 | .. | +|✓|__aeabi_memset |[*]u8|usize| i32 | .. | +|✓|__aeabi_memclr8 |[*]u8| u32 | usize| *dest, size | +|✓|__aeabi_memclr4 |[*]u8| u32 | usize| .. | +|✓|__aeabi_memclr |[*]u8| u32 | usize| .. | +|✓|__aeabi_uwrite8 | i64 |[*]u8| i64 | .. | + +- __aeabi_read_tp + +[^PSRZC]: return result in the CPSR Z and C flag. C is clear only if the +operands are ordered and the first operand is less than the second. +Z is set only when the operands are ordered and equal. +Preserves all core registers except ip, lr, and the CPSR. + - aarch64 outline atomics -- arm routines (memory routines + memclr [setting to 0], divmod routines and stubs for unwind_cpp) - atomics - bcmp - clear cache diff --git a/lib/compiler_rt/arm.zig b/lib/compiler_rt/arm.zig index 27667d3b6095..94cd4feb8c40 100644 --- a/lib/compiler_rt/arm.zig +++ b/lib/compiler_rt/arm.zig @@ -1,4 +1,5 @@ -// ARM specific builtins +//! Implementation of ARM specific builtins for Run-time ABI +//! This file includes all ARM-only functions. const std = @import("std"); const builtin = @import("builtin"); const arch = builtin.cpu.arch; @@ -38,6 +39,9 @@ comptime { if (builtin.os.tag == .linux) { @export(__aeabi_read_tp, .{ .name = "__aeabi_read_tp", .linkage = common.linkage, .visibility = common.visibility }); } + + // floating-point helper functions (double-precision reverse subtraction, y – x), see subdf3.zig + @export(__aeabi_drsub, .{ .name = "__aeabi_drsub", .linkage = common.linkage, .visibility = common.visibility }); } } } @@ -186,3 +190,8 @@ pub fn __aeabi_ldivmod() callconv(.Naked) void { ::: "memory"); unreachable; } + +pub fn __aeabi_drsub(a: f64, b: f64) callconv(.AAPCS) f64 { + const neg_a = @bitCast(f64, @bitCast(u64, a) ^ (@as(u64, 1) << 63)); + return b + neg_a; +}