Skip to content

Commit 4583076

Browse files
authored
[compiler-rt][RISC-V] ILP32E/LP64E Save/Restore Grouping (llvm#95398)
This changes the save/restore procedures to save/restore registers one by one - to match the stack alignment for the ILP32E/LP64E ABIs, rather than the larger batches of the conventional ABIs. The implementations of the save routines are not tail-shared, to reduce the number of instructions. I think this also helps code size but I need to check this again. I would expect (but haven't measured) that the majority of functions compiled for the ILP32E/LP64E ABIs will in fact use both callee-saved registers, and therefore there are still savings to be had, but I think those can come later, with more data (especially if those changes are just to the instruction sequences we use to save the registers, rather than the number and alignment of how this is done). This is a potential break for all of the ILP32E/LP64E ABI - we may instead have to teach the compiler to emit the CFI information correctly for the grouping we already have implemented (because that grouping matches GCC). It depends on how intentional we think the grouping is in the original ILP32E/LP64E save/restore implementation was, and whether we think we can fix that now.
1 parent 58ea538 commit 4583076

File tree

2 files changed

+61
-28
lines changed

2 files changed

+61
-28
lines changed

compiler-rt/lib/builtins/riscv/restore.S

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,12 @@
1414
// them falling through into each other and don't want the linker to
1515
// accidentally split them up, garbage collect, or reorder them.
1616
//
17-
// The entry points are grouped up into 2s for rv64 and 4s for rv32 since this
18-
// is the minimum grouping which will maintain the required 16-byte stack
19-
// alignment.
17+
// For the conventional ABIs, entry points are grouped up into 2s for rv64 and
18+
// 4s for rv32 since this is the minimum grouping which will maintain the
19+
// required 16-byte stack alignment.
20+
//
21+
// For the ilp32e/lp64e abis, entry points are grouped into 1s, since this is
22+
// the minimum grouping which will maintain the required 4-byte stack alignment.
2023

2124
.text
2225

@@ -92,17 +95,23 @@ __riscv_restore_0:
9295

9396
.globl __riscv_restore_2
9497
.type __riscv_restore_2,@function
98+
__riscv_restore_2:
99+
lw s1, 0(sp)
100+
addi sp, sp, 4
101+
// fallthrough into __riscv_restore_1/0
102+
95103
.globl __riscv_restore_1
96104
.type __riscv_restore_1,@function
105+
__riscv_restore_1:
106+
lw s0, 0(sp)
107+
addi sp, sp, 4
108+
// fallthrough into __riscv_restore_0
109+
97110
.globl __riscv_restore_0
98111
.type __riscv_restore_0,@function
99-
__riscv_restore_2:
100-
__riscv_restore_1:
101112
__riscv_restore_0:
102-
lw s1, 0(sp)
103-
lw s0, 4(sp)
104-
lw ra, 8(sp)
105-
addi sp, sp, 12
113+
lw ra, 0(sp)
114+
addi sp, sp, 4
106115
ret
107116

108117
#endif
@@ -188,17 +197,23 @@ __riscv_restore_0:
188197

189198
.globl __riscv_restore_2
190199
.type __riscv_restore_2,@function
200+
__riscv_restore_2:
201+
ld s1, 0(sp)
202+
addi sp, sp, 8
203+
// fallthrough into __riscv_restore_1/0
204+
191205
.globl __riscv_restore_1
192206
.type __riscv_restore_1,@function
207+
__riscv_restore_1:
208+
ld s0, 0(sp)
209+
addi sp, sp, 8
210+
// fallthrough into __riscv_restore_0
211+
193212
.globl __riscv_restore_0
194213
.type __riscv_restore_0,@function
195-
__riscv_restore_2:
196-
__riscv_restore_1:
197214
__riscv_restore_0:
198-
ld s1, 0(sp)
199-
ld s0, 8(sp)
200-
ld ra, 16(sp)
201-
addi sp, sp, 24
215+
ld ra, 0(sp)
216+
addi sp, sp, 8
202217
ret
203218

204219
#endif

compiler-rt/lib/builtins/riscv/save.S

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -98,19 +98,28 @@ __riscv_save_0:
9898

9999
.globl __riscv_save_2
100100
.type __riscv_save_2,@function
101-
.globl __riscv_save_1
102-
.type __riscv_save_1,@function
103-
.globl __riscv_save_0
104-
.type __riscv_save_0,@function
105101
__riscv_save_2:
106-
__riscv_save_1:
107-
__riscv_save_0:
108102
addi sp, sp, -12
109103
sw s1, 0(sp)
110104
sw s0, 4(sp)
111105
sw ra, 8(sp)
112106
jr t0
113107

108+
.globl __riscv_save_1
109+
.type __riscv_save_1,@function
110+
__riscv_save_1:
111+
addi sp, sp, -8
112+
sw s0, 0(sp)
113+
sw ra, 4(sp)
114+
jr t0
115+
116+
.globl __riscv_save_0
117+
.type __riscv_save_0,@function
118+
__riscv_save_0:
119+
addi sp, sp, -4
120+
sw ra, 0(sp)
121+
jr t0
122+
114123
#endif
115124

116125
#elif __riscv_xlen == 64
@@ -208,18 +217,27 @@ __riscv_save_0:
208217

209218
.globl __riscv_save_2
210219
.type __riscv_save_2,@function
220+
__riscv_save_2:
221+
addi sp, sp, -24
222+
sw s1, 0(sp)
223+
sw s0, 8(sp)
224+
sw ra, 16(sp)
225+
jr t0
226+
211227
.globl __riscv_save_1
212228
.type __riscv_save_1,@function
229+
__riscv_save_1:
230+
addi sp, sp, -16
231+
sw s0, 0(sp)
232+
sw ra, 8(sp)
233+
jr t0
234+
213235
.globl __riscv_save_0
214236
.type __riscv_save_0,@function
215-
__riscv_save_2:
216-
__riscv_save_1:
217237
__riscv_save_0:
218-
addi sp, sp, -24
219-
sd s1, 0(sp)
220-
sd s0, 8(sp)
221-
sd ra, 16(sp)
222-
jr t0
238+
addi sp, sp, -8
239+
sw ra, 0(sp)
240+
jr t0
223241

224242
#endif
225243

0 commit comments

Comments
 (0)