Skip to content

Commit 562d0a8

Browse files
committed
Show the save of clobbered registers
1 parent f883418 commit 562d0a8

File tree

3 files changed

+284
-2
lines changed

3 files changed

+284
-2
lines changed

llvm/docs/LangRef.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ added in the future:
413413
- On AArch64 the callee preserves all general purpose registers, except
414414
X0-X8 and X16-X18. Not allowed with ``nest``.
415415

416-
- On RISC-V the callee preserve x5-x31 registers.
416+
- On RISC-V the callee preserve x5-x31 except x6, x7 and x28 registers.
417417

418418
The idea behind this convention is to support calls to runtime functions
419419
that have a hot path and a cold path. The hot path is usually a small piece

llvm/lib/Target/RISCV/RISCVCallingConv.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,6 @@ def CSR_XLEN_F32_V_Interrupt_RVE: CalleeSavedRegs<(sub CSR_XLEN_F32_V_Interrupt,
9696
def CSR_XLEN_F64_V_Interrupt_RVE: CalleeSavedRegs<(sub CSR_XLEN_F64_V_Interrupt,
9797
(sequence "X%u", 16, 31))>;
9898

99-
def CSR_RT_MostRegs : CalleeSavedRegs<(sub CSR_Interrupt, X6, X7, X28)>;
99+
def CSR_RT_MostRegs : CalleeSavedRegs<(sub (sequence "X%u", 5, 31), X6, X7, X28)>;
100100
def CSR_RT_MostRegs_RVE : CalleeSavedRegs<(sub CSR_RT_MostRegs,
101101
(sequence "X%u", 16, 31))>;

llvm/test/CodeGen/RISCV/calling-conv-preserve-most.ll

Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,3 +165,285 @@ define preserve_mostcc void @preserve_mostcc2() nounwind {
165165
call preserve_mostcc void @preserve_mostcc_func()
166166
ret void
167167
}
168+
169+
; X6, X7 and X28 will be saved to registers.
170+
define void @preserve_mostcc3() nounwind {
171+
; RV32I-LABEL: preserve_mostcc3:
172+
; RV32I: # %bb.0:
173+
; RV32I-NEXT: addi sp, sp, -16
174+
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
175+
; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
176+
; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
177+
; RV32I-NEXT: #APP
178+
; RV32I-NEXT: #NO_APP
179+
; RV32I-NEXT: mv a0, t1
180+
; RV32I-NEXT: #APP
181+
; RV32I-NEXT: #NO_APP
182+
; RV32I-NEXT: mv a1, t2
183+
; RV32I-NEXT: #APP
184+
; RV32I-NEXT: #NO_APP
185+
; RV32I-NEXT: #APP
186+
; RV32I-NEXT: #NO_APP
187+
; RV32I-NEXT: #APP
188+
; RV32I-NEXT: #NO_APP
189+
; RV32I-NEXT: mv a2, t3
190+
; RV32I-NEXT: call preserve_mostcc_func
191+
; RV32I-NEXT: mv t1, a0
192+
; RV32I-NEXT: mv t2, a1
193+
; RV32I-NEXT: mv t3, a2
194+
; RV32I-NEXT: #APP
195+
; RV32I-NEXT: #NO_APP
196+
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
197+
; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
198+
; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
199+
; RV32I-NEXT: addi sp, sp, 16
200+
; RV32I-NEXT: ret
201+
;
202+
; RV64I-LABEL: preserve_mostcc3:
203+
; RV64I: # %bb.0:
204+
; RV64I-NEXT: addi sp, sp, -32
205+
; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
206+
; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
207+
; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
208+
; RV64I-NEXT: #APP
209+
; RV64I-NEXT: #NO_APP
210+
; RV64I-NEXT: mv a0, t1
211+
; RV64I-NEXT: #APP
212+
; RV64I-NEXT: #NO_APP
213+
; RV64I-NEXT: mv a1, t2
214+
; RV64I-NEXT: #APP
215+
; RV64I-NEXT: #NO_APP
216+
; RV64I-NEXT: #APP
217+
; RV64I-NEXT: #NO_APP
218+
; RV64I-NEXT: #APP
219+
; RV64I-NEXT: #NO_APP
220+
; RV64I-NEXT: mv a2, t3
221+
; RV64I-NEXT: call preserve_mostcc_func
222+
; RV64I-NEXT: mv t1, a0
223+
; RV64I-NEXT: mv t2, a1
224+
; RV64I-NEXT: mv t3, a2
225+
; RV64I-NEXT: #APP
226+
; RV64I-NEXT: #NO_APP
227+
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
228+
; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
229+
; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
230+
; RV64I-NEXT: addi sp, sp, 32
231+
; RV64I-NEXT: ret
232+
;
233+
; RV32E-LABEL: preserve_mostcc3:
234+
; RV32E: # %bb.0:
235+
; RV32E-NEXT: addi sp, sp, -12
236+
; RV32E-NEXT: sw ra, 8(sp) # 4-byte Folded Spill
237+
; RV32E-NEXT: sw s0, 4(sp) # 4-byte Folded Spill
238+
; RV32E-NEXT: sw s1, 0(sp) # 4-byte Folded Spill
239+
; RV32E-NEXT: #APP
240+
; RV32E-NEXT: #NO_APP
241+
; RV32E-NEXT: mv a0, t1
242+
; RV32E-NEXT: #APP
243+
; RV32E-NEXT: #NO_APP
244+
; RV32E-NEXT: mv a1, t2
245+
; RV32E-NEXT: #APP
246+
; RV32E-NEXT: #NO_APP
247+
; RV32E-NEXT: #APP
248+
; RV32E-NEXT: #NO_APP
249+
; RV32E-NEXT: #APP
250+
; RV32E-NEXT: #NO_APP
251+
; RV32E-NEXT: mv a2, t3
252+
; RV32E-NEXT: call preserve_mostcc_func
253+
; RV32E-NEXT: mv t1, a0
254+
; RV32E-NEXT: mv t2, a1
255+
; RV32E-NEXT: mv t3, a2
256+
; RV32E-NEXT: #APP
257+
; RV32E-NEXT: #NO_APP
258+
; RV32E-NEXT: lw ra, 8(sp) # 4-byte Folded Reload
259+
; RV32E-NEXT: lw s0, 4(sp) # 4-byte Folded Reload
260+
; RV32E-NEXT: lw s1, 0(sp) # 4-byte Folded Reload
261+
; RV32E-NEXT: addi sp, sp, 12
262+
; RV32E-NEXT: ret
263+
;
264+
; RV64E-LABEL: preserve_mostcc3:
265+
; RV64E: # %bb.0:
266+
; RV64E-NEXT: addi sp, sp, -24
267+
; RV64E-NEXT: sd ra, 16(sp) # 8-byte Folded Spill
268+
; RV64E-NEXT: sd s0, 8(sp) # 8-byte Folded Spill
269+
; RV64E-NEXT: sd s1, 0(sp) # 8-byte Folded Spill
270+
; RV64E-NEXT: #APP
271+
; RV64E-NEXT: #NO_APP
272+
; RV64E-NEXT: mv a0, t1
273+
; RV64E-NEXT: #APP
274+
; RV64E-NEXT: #NO_APP
275+
; RV64E-NEXT: mv a1, t2
276+
; RV64E-NEXT: #APP
277+
; RV64E-NEXT: #NO_APP
278+
; RV64E-NEXT: #APP
279+
; RV64E-NEXT: #NO_APP
280+
; RV64E-NEXT: #APP
281+
; RV64E-NEXT: #NO_APP
282+
; RV64E-NEXT: mv a2, t3
283+
; RV64E-NEXT: call preserve_mostcc_func
284+
; RV64E-NEXT: mv t1, a0
285+
; RV64E-NEXT: mv t2, a1
286+
; RV64E-NEXT: mv t3, a2
287+
; RV64E-NEXT: #APP
288+
; RV64E-NEXT: #NO_APP
289+
; RV64E-NEXT: ld ra, 16(sp) # 8-byte Folded Reload
290+
; RV64E-NEXT: ld s0, 8(sp) # 8-byte Folded Reload
291+
; RV64E-NEXT: ld s1, 0(sp) # 8-byte Folded Reload
292+
; RV64E-NEXT: addi sp, sp, 24
293+
; RV64E-NEXT: ret
294+
%1 = call i32 asm sideeffect "", "={x6}"() nounwind
295+
%2 = call i32 asm sideeffect "", "={x7}"() nounwind
296+
%3 = call i32 asm sideeffect "", "={x8}"() nounwind
297+
%4 = call i32 asm sideeffect "", "={x9}"() nounwind
298+
%5 = call i32 asm sideeffect "", "={x28}"() nounwind
299+
call preserve_mostcc void @preserve_mostcc_func()
300+
call void asm sideeffect "", "{x6},{x7},{x8},{x9},{x28}"(i32 %1, i32 %2, i32 %3, i32 %4, i32 %5)
301+
ret void
302+
}
303+
304+
; X6, X7 and X28 will be saved to the stack.
305+
define void @preserve_mostcc4() nounwind {
306+
; RV32I-LABEL: preserve_mostcc4:
307+
; RV32I: # %bb.0:
308+
; RV32I-NEXT: addi sp, sp, -32
309+
; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
310+
; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
311+
; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
312+
; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
313+
; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill
314+
; RV32I-NEXT: sw s4, 8(sp) # 4-byte Folded Spill
315+
; RV32I-NEXT: #APP
316+
; RV32I-NEXT: #NO_APP
317+
; RV32I-NEXT: mv s2, t1
318+
; RV32I-NEXT: #APP
319+
; RV32I-NEXT: #NO_APP
320+
; RV32I-NEXT: mv s3, t2
321+
; RV32I-NEXT: #APP
322+
; RV32I-NEXT: #NO_APP
323+
; RV32I-NEXT: #APP
324+
; RV32I-NEXT: #NO_APP
325+
; RV32I-NEXT: #APP
326+
; RV32I-NEXT: #NO_APP
327+
; RV32I-NEXT: mv s4, t3
328+
; RV32I-NEXT: call standard_cc_func
329+
; RV32I-NEXT: mv t1, s2
330+
; RV32I-NEXT: mv t2, s3
331+
; RV32I-NEXT: mv t3, s4
332+
; RV32I-NEXT: #APP
333+
; RV32I-NEXT: #NO_APP
334+
; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
335+
; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
336+
; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
337+
; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
338+
; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
339+
; RV32I-NEXT: lw s4, 8(sp) # 4-byte Folded Reload
340+
; RV32I-NEXT: addi sp, sp, 32
341+
; RV32I-NEXT: ret
342+
;
343+
; RV64I-LABEL: preserve_mostcc4:
344+
; RV64I: # %bb.0:
345+
; RV64I-NEXT: addi sp, sp, -48
346+
; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
347+
; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill
348+
; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill
349+
; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill
350+
; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill
351+
; RV64I-NEXT: sd s4, 0(sp) # 8-byte Folded Spill
352+
; RV64I-NEXT: #APP
353+
; RV64I-NEXT: #NO_APP
354+
; RV64I-NEXT: mv s2, t1
355+
; RV64I-NEXT: #APP
356+
; RV64I-NEXT: #NO_APP
357+
; RV64I-NEXT: mv s3, t2
358+
; RV64I-NEXT: #APP
359+
; RV64I-NEXT: #NO_APP
360+
; RV64I-NEXT: #APP
361+
; RV64I-NEXT: #NO_APP
362+
; RV64I-NEXT: #APP
363+
; RV64I-NEXT: #NO_APP
364+
; RV64I-NEXT: mv s4, t3
365+
; RV64I-NEXT: call standard_cc_func
366+
; RV64I-NEXT: mv t1, s2
367+
; RV64I-NEXT: mv t2, s3
368+
; RV64I-NEXT: mv t3, s4
369+
; RV64I-NEXT: #APP
370+
; RV64I-NEXT: #NO_APP
371+
; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
372+
; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
373+
; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
374+
; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
375+
; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload
376+
; RV64I-NEXT: ld s4, 0(sp) # 8-byte Folded Reload
377+
; RV64I-NEXT: addi sp, sp, 48
378+
; RV64I-NEXT: ret
379+
;
380+
; RV32E-LABEL: preserve_mostcc4:
381+
; RV32E: # %bb.0:
382+
; RV32E-NEXT: addi sp, sp, -24
383+
; RV32E-NEXT: sw ra, 20(sp) # 4-byte Folded Spill
384+
; RV32E-NEXT: sw s0, 16(sp) # 4-byte Folded Spill
385+
; RV32E-NEXT: sw s1, 12(sp) # 4-byte Folded Spill
386+
; RV32E-NEXT: #APP
387+
; RV32E-NEXT: #NO_APP
388+
; RV32E-NEXT: sw t1, 8(sp) # 4-byte Folded Spill
389+
; RV32E-NEXT: #APP
390+
; RV32E-NEXT: #NO_APP
391+
; RV32E-NEXT: sw t2, 4(sp) # 4-byte Folded Spill
392+
; RV32E-NEXT: #APP
393+
; RV32E-NEXT: #NO_APP
394+
; RV32E-NEXT: #APP
395+
; RV32E-NEXT: #NO_APP
396+
; RV32E-NEXT: #APP
397+
; RV32E-NEXT: #NO_APP
398+
; RV32E-NEXT: sw t3, 0(sp) # 4-byte Folded Spill
399+
; RV32E-NEXT: call standard_cc_func
400+
; RV32E-NEXT: lw t1, 8(sp) # 4-byte Folded Reload
401+
; RV32E-NEXT: lw t2, 4(sp) # 4-byte Folded Reload
402+
; RV32E-NEXT: lw t3, 0(sp) # 4-byte Folded Reload
403+
; RV32E-NEXT: #APP
404+
; RV32E-NEXT: #NO_APP
405+
; RV32E-NEXT: lw ra, 20(sp) # 4-byte Folded Reload
406+
; RV32E-NEXT: lw s0, 16(sp) # 4-byte Folded Reload
407+
; RV32E-NEXT: lw s1, 12(sp) # 4-byte Folded Reload
408+
; RV32E-NEXT: addi sp, sp, 24
409+
; RV32E-NEXT: ret
410+
;
411+
; RV64E-LABEL: preserve_mostcc4:
412+
; RV64E: # %bb.0:
413+
; RV64E-NEXT: addi sp, sp, -48
414+
; RV64E-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
415+
; RV64E-NEXT: sd s0, 32(sp) # 8-byte Folded Spill
416+
; RV64E-NEXT: sd s1, 24(sp) # 8-byte Folded Spill
417+
; RV64E-NEXT: #APP
418+
; RV64E-NEXT: #NO_APP
419+
; RV64E-NEXT: sd t1, 16(sp) # 8-byte Folded Spill
420+
; RV64E-NEXT: #APP
421+
; RV64E-NEXT: #NO_APP
422+
; RV64E-NEXT: sd t2, 8(sp) # 8-byte Folded Spill
423+
; RV64E-NEXT: #APP
424+
; RV64E-NEXT: #NO_APP
425+
; RV64E-NEXT: #APP
426+
; RV64E-NEXT: #NO_APP
427+
; RV64E-NEXT: #APP
428+
; RV64E-NEXT: #NO_APP
429+
; RV64E-NEXT: sd t3, 0(sp) # 8-byte Folded Spill
430+
; RV64E-NEXT: call standard_cc_func
431+
; RV64E-NEXT: ld t1, 16(sp) # 8-byte Folded Reload
432+
; RV64E-NEXT: ld t2, 8(sp) # 8-byte Folded Reload
433+
; RV64E-NEXT: ld t3, 0(sp) # 8-byte Folded Reload
434+
; RV64E-NEXT: #APP
435+
; RV64E-NEXT: #NO_APP
436+
; RV64E-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
437+
; RV64E-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
438+
; RV64E-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
439+
; RV64E-NEXT: addi sp, sp, 48
440+
; RV64E-NEXT: ret
441+
%1 = call i32 asm sideeffect "", "={x6}"() nounwind
442+
%2 = call i32 asm sideeffect "", "={x7}"() nounwind
443+
%3 = call i32 asm sideeffect "", "={x8}"() nounwind
444+
%4 = call i32 asm sideeffect "", "={x9}"() nounwind
445+
%5 = call i32 asm sideeffect "", "={x28}"() nounwind
446+
call void @standard_cc_func()
447+
call void asm sideeffect "", "{x6},{x7},{x8},{x9},{x28}"(i32 %1, i32 %2, i32 %3, i32 %4, i32 %5)
448+
ret void
449+
}

0 commit comments

Comments
 (0)