Repository navigation
Add an armhf ABI for 32-bit ARM hard-float. #22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4fa65af
92f7423
9335c29
72d4a12
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -158,7 +158,7 @@ file and does not run it. | |
| | `switch_x64_msvc.asm` | `rbx`, `rbp`, `rdi`, `rsi`, `r12`–`r15`, `xmm6`–`xmm15` | Those registers match the Windows x64 ABI. MXCSR[6:15] is non-volatile on Windows and is not spilled, so a changed rounding mode does not travel with the stack. The SysV file does save MXCSR. | | ||
| | `switch_x86_gcc.S` | `ebx`, `esi`, `edi`, `ebp` | Integer set is complete. There is no callee-saved XMM on i386 SysV. The x87 control word is callee-saved in that ABI and is not saved. | | ||
| | `switch_x86_msvc.asm` | `ebx`, `esi`, `edi`, `ebp`, plus the C wrapper saves `fs:[0]` | Integer set is complete for cdecl. Same x87 control-word gap. | | ||
| | `switch_arm_gcc.S` | `r4`–`r11`, `lr` | Complete for the soft-float `arm-linux-gnueabi` ABI this tree ships (`.arch armv5t`, `.fpu softvfp`). `d8`–`d15` are absent. The inline header clobbers them, so a hard-float or softfp build of this `.S` would drop callee-saved VFP state. `armhf` is not a configured ABI. The live frame pointer is not adjusted. | | ||
| | `switch_arm_gcc.S` | `r4`–`r11`, `lr` | Complete for the soft-float `arm-linux-gnueabi` ABI this tree ships (`.arch armv5t`, `.fpu softvfp`). `d8`–`d15` are absent. The inline header clobbers them, so a hard-float or softfp build of this `.S` would drop callee-saved VFP state. The live frame pointer is not adjusted. | | ||
| | `switch_arm_msvc.asm` | `r4`–`r11`, `lr`, `q4`–`q7` (`d8`–`d15`), `FPSCR` | The set matches 32-bit Windows ARM. Alignment does not. `push {r4-r10, fp, lr}` is 9 words, so `sp` is 4-byte aligned for `vpush {q4-q7}`. A doubleword `VPUSH` requires 8-byte alignment. `stackman_call` pushes 3 registers and then `blx`s with `sp` still 4 mod 8. The changelog records this ABI as dropped; the file is still wrong if it is built. | | ||
| | `switch_riscv64_gcc.S` | `ra`, `s0`–`s11`, `fs0`–`fs11` | `stackman_switch` is complete for LP64D. `gp` and `tp` are left alone. `fcsr` is thread `fenv` state, not a per-call spill. | | ||
|
|
||
|
|
@@ -186,6 +186,9 @@ file and does not run it. | |
| keep the callback or the new stack pointer in `r11` across that asm. | ||
| AArch64 still adjusts `x29`, which the prologue sets with | ||
| `mov x29, sp`. | ||
| - `__ARM_PCS_VFP` selects `armhf` (`switch_armhf_gcc.S`), which spills | ||
| `d8`–`d15`. `FPSCR` is still not spilled. The soft-float file was | ||
| left unchanged. | ||
| - Windows ARM32 was removed: `switch_arm_msvc.asm`, `switch_arm_msvc.h`, | ||
| the `_M_ARM` branch in `platform.h`, the Debug|ARM configurations in | ||
| vs2017, vs2019, and vs2022, and `lib/win_arm/stackman.lib`. The | ||
|
|
@@ -356,7 +359,8 @@ The shipped integer set (`r4`–`r11`, `lr`) needs no new stores. | |
| **Applied fix.** `__ARM_PCS_VFP` is a compile error, and `CP_REGISTERS` is | ||
| commented as inline-only. The optional `r11` adjustment was applied and | ||
| then removed. See the frame-pointer applied fix above. `d8`–`d15` were | ||
| not added. A separate hard-float port is on the roadmap. | ||
| not added to this file. `__ARM_PCS_VFP` selects `armhf` | ||
| (`switch_armhf_gcc.S` spills `d8`–`d15`; `FPSCR` is still not spilled). | ||
|
|
||
| ### Windows ARM32: delete it, or align `sp` before `vpush` | ||
|
|
||
|
|
@@ -393,20 +397,20 @@ alternative was not used. | |
|
|
||
| ## Roadmap | ||
|
|
||
| Two items from the audit are still open. | ||
| SME lazy save is still open. The ARM32 hard-float port is `armhf`. | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [suggestion] The roadmap now says the ARM32 hard-float port is Suggestion: Leave the original soft-float findings in place, and add a short applied-fix note that |
||
|
|
||
| ### ARM32 hard-float | ||
|
|
||
| The shipped `switch_arm_gcc.S` is soft-float (`arm-linux-gnueabi`, | ||
| The soft-float file `switch_arm_gcc.S` is unchanged (`arm-linux-gnueabi`, | ||
| `.arch armv5t`, `.fpu softvfp`) and does not spill `d8`–`d15`. | ||
| `__ARM_PCS_VFP` is a compile error, so a hard-float build cannot use that | ||
| file by mistake. | ||
|
|
||
| A hard-float port is a new assembly, alongside the soft-float file. It | ||
| spills `d8`–`d15` in `stackman_switch`, has its own ABI name, and is what | ||
| a `__ARM_PCS_VFP` build selects. The `#error` stays until that port | ||
| exists. Softfp is not that port: it does not define `__ARM_PCS_VFP`, and | ||
| the compiler can still use `d8`–`d15`. | ||
| `__ARM_PCS_VFP` is still a compile error in that header, so a hard-float | ||
| build cannot use that file by mistake. | ||
|
|
||
| `switch_armhf_gcc.h` is the hard-float port. `platform.h` selects it, | ||
| and the ABI name `armhf`, when `__ARM_PCS_VFP` is set. `stackman_switch` | ||
| spills `d8`–`d15`. `FPSCR` is not spilled. Softfp is not this port: it | ||
| does not define `__ARM_PCS_VFP`, and the compiler can still use | ||
| `d8`–`d15` while building `arm32`. | ||
|
|
||
| ### AArch64 SME lazy save | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| /* | ||
| * this file is provided for where inline assembly is not | ||
| * dependable, such as with clang, or if | ||
| * STACKMAN_INLINE_ASM is false | ||
| * The file is generated using | ||
| * "arm-linux-gnueabihf-gcc -S -marm gen_asm.c" and then copying the code | ||
| * from gen_asm.s into this file. | ||
| * | ||
| */ | ||
| .arch armv7-a | ||
| .fpu vfpv3-d16 | ||
| .eabi_attribute 28, 1 | ||
| .eabi_attribute 20, 1 | ||
| .eabi_attribute 21, 1 | ||
| .eabi_attribute 23, 3 | ||
| .eabi_attribute 24, 1 | ||
| .eabi_attribute 25, 1 | ||
| .eabi_attribute 26, 2 | ||
| .eabi_attribute 30, 6 | ||
| .eabi_attribute 34, 1 | ||
| .eabi_attribute 18, 4 | ||
| .file "gen_asm.c" | ||
| .text | ||
| .align 2 | ||
| .global stackman_switch | ||
| .syntax unified | ||
| .arm | ||
| .type stackman_switch, %function | ||
| stackman_switch: | ||
| @ args = 0, pretend = 0, frame = 0 | ||
| @ frame_needed = 0, uses_anonymous_args = 0 | ||
| push {r3, r4, r5, r6, r7, r8, r9, r10, fp, lr} | ||
| vpush.64 {d8, d9, d10, d11, d12, d13, d14, d15} | ||
| mov r3, r0 | ||
| mov r0, r1 | ||
| .syntax divided | ||
| @ 91 "../platforms/switch_armhf_gcc.h" 1 | ||
| mov r2, sp | ||
| @ 0 "" 2 | ||
| .arm | ||
| .syntax unified | ||
| mov r1, #0 | ||
| mov r5, r0 | ||
| mov r4, r3 | ||
| blx r3 | ||
| mov r2, r0 | ||
| .syntax divided | ||
| @ 95 "../platforms/switch_armhf_gcc.h" 1 | ||
| mov sp, r0 | ||
| @ 0 "" 2 | ||
| .arm | ||
| .syntax unified | ||
| mov r1, #1 | ||
| mov r0, r5 | ||
| blx r4 | ||
| vldm sp!, {d8-d15} | ||
| pop {r3, r4, r5, r6, r7, r8, r9, r10, fp, pc} | ||
| .size stackman_switch, .-stackman_switch | ||
| .align 2 | ||
| .global stackman_call | ||
| .syntax unified | ||
| .arm | ||
| .type stackman_call, %function | ||
| stackman_call: | ||
| @ args = 0, pretend = 0, frame = 0 | ||
| @ frame_needed = 1, uses_anonymous_args = 0 | ||
| push {r4, r5, fp, lr} | ||
| add fp, sp, #12 | ||
| mov r5, r0 | ||
| mov r0, r1 | ||
| mov r3, r2 | ||
| .syntax divided | ||
| @ 111 "../platforms/switch_armhf_gcc.h" 1 | ||
| mov r4, sp | ||
| @ 0 "" 2 | ||
| @ 112 "../platforms/switch_armhf_gcc.h" 1 | ||
| mov r2, sp | ||
| @ 0 "" 2 | ||
| .arm | ||
| .syntax unified | ||
| cmp r3, #0 | ||
| beq .L4 | ||
| .syntax divided | ||
| @ 116 "../platforms/switch_armhf_gcc.h" 1 | ||
| mov sp, r3 | ||
| @ 0 "" 2 | ||
| .arm | ||
| .syntax unified | ||
| .L4: | ||
| mov r1, #2 | ||
| blx r5 | ||
| .syntax divided | ||
| @ 120 "../platforms/switch_armhf_gcc.h" 1 | ||
| mov sp, r4 | ||
| @ 0 "" 2 | ||
| .arm | ||
| .syntax unified | ||
| pop {r4, r5, fp, pc} | ||
| .size stackman_call, .-stackman_call | ||
| .ident "GCC: (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0" | ||
| .section .note.GNU-stack,"",%progbits |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[suggestion] The banner now says 11 platforms and the ABI list adds
armhf, but two later sections of the same README were not updated. Line 192 still says pre-built libraries cover "9 ABIs total: 4 Linux, 2 macOS, 3 Windows" (actual set is 6 Linux + 2 macOS + 3 Windows). Line 222 still says CI builds "all 9 supported platforms" and lists Linux as AMD64, i386, ARM32, and ARM64, omitting botharmhfandriscv64.Suggestion: Update those two sentences to the same 11-ABI set the banner, the platform list, and
create-releasenow use, includingarmhfin the Linux CI list.