Skip to content

Commit 5204d6b

Browse files
elliotttjameysharp
andcommitted
Enable callee saves with the tail calling convention on x64
Co-authored-by: Jamey Sharp <jsharp@fastly.com>
1 parent f766d21 commit 5204d6b

6 files changed

Lines changed: 856 additions & 733 deletions

File tree

cranelift/codegen/src/isa/x64/abi.rs

Lines changed: 8 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -595,14 +595,10 @@ impl ABIMachineSpec for X64ABIMachineSpec {
595595
}
596596

597597
fn gen_clobber_save(
598-
call_conv: isa::CallConv,
598+
_call_conv: isa::CallConv,
599599
flags: &settings::Flags,
600600
frame_layout: &FrameLayout,
601601
) -> SmallVec<[Self::I; 16]> {
602-
if call_conv == isa::CallConv::Tail {
603-
assert!(frame_layout.clobbered_callee_saves.is_empty());
604-
}
605-
606602
let mut insts = SmallVec::new();
607603

608604
if flags.unwind_info() && frame_layout.setup_area_size > 0 {
@@ -857,7 +853,6 @@ impl ABIMachineSpec for X64ABIMachineSpec {
857853

858854
fn get_regs_clobbered_by_call(call_conv_of_callee: isa::CallConv) -> PRegSet {
859855
match call_conv_of_callee {
860-
isa::CallConv::Tail => ALL_CLOBBERS,
861856
isa::CallConv::Winch => ALL_CLOBBERS,
862857
_ if call_conv_of_callee.extends_windows_fastcall() => WINDOWS_CLOBBERS,
863858
_ => SYSV_CLOBBERS,
@@ -882,13 +877,10 @@ impl ABIMachineSpec for X64ABIMachineSpec {
882877
outgoing_args_size: u32,
883878
) -> FrameLayout {
884879
let mut regs: Vec<Writable<RealReg>> = match call_conv {
885-
// The `tail` calling convention doesn't have any callee-save
886-
// registers.
887-
CallConv::Tail => vec![],
888880
// The `winch` calling convention doesn't have any callee-save
889881
// registers.
890882
CallConv::Winch => vec![],
891-
CallConv::Fast | CallConv::Cold | CallConv::SystemV => regs
883+
CallConv::Fast | CallConv::Cold | CallConv::SystemV | CallConv::Tail => regs
892884
.iter()
893885
.cloned()
894886
.filter(|r| is_callee_save_systemv(r.to_reg(), flags.enable_pinned_reg()))
@@ -1020,25 +1012,6 @@ impl From<StackAMode> for SyntheticAmode {
10201012
fn get_intreg_for_arg(call_conv: &CallConv, idx: usize, arg_idx: usize) -> Option<Reg> {
10211013
let is_fastcall = call_conv.extends_windows_fastcall();
10221014

1023-
if *call_conv == isa::CallConv::Tail {
1024-
return match idx {
1025-
0 => Some(regs::rax()),
1026-
1 => Some(regs::rcx()),
1027-
2 => Some(regs::rdx()),
1028-
3 => Some(regs::rbx()),
1029-
4 => Some(regs::rsi()),
1030-
5 => Some(regs::rdi()),
1031-
6 => Some(regs::r8()),
1032-
7 => Some(regs::r9()),
1033-
8 => Some(regs::r10()),
1034-
9 => Some(regs::r11()),
1035-
// NB: `r12`, `r13`, `r14` and `r15` are reserved for indirect
1036-
// callee addresses and temporaries required for our tail call
1037-
// sequence (fp, ret_addr, tmp).
1038-
_ => None,
1039-
};
1040-
}
1041-
10421015
// Fastcall counts by absolute argument number; SysV counts by argument of
10431016
// this (integer) class.
10441017
let i = if is_fastcall { arg_idx } else { idx };
@@ -1091,16 +1064,12 @@ fn get_intreg_for_retval(
10911064
0 => Some(regs::rax()),
10921065
1 => Some(regs::rcx()),
10931066
2 => Some(regs::rdx()),
1094-
3 => Some(regs::rbx()),
1095-
4 => Some(regs::rsi()),
1096-
5 => Some(regs::rdi()),
1097-
6 => Some(regs::r8()),
1098-
7 => Some(regs::r9()),
1099-
8 => Some(regs::r10()),
1100-
9 => Some(regs::r11()),
1101-
10 => Some(regs::r12()),
1102-
11 => Some(regs::r13()),
1103-
12 => Some(regs::r14()),
1067+
3 => Some(regs::rsi()),
1068+
4 => Some(regs::rdi()),
1069+
5 => Some(regs::r8()),
1070+
6 => Some(regs::r9()),
1071+
7 => Some(regs::r10()),
1072+
8 => Some(regs::r11()),
11041073
// NB: `r15` is reserved as a scratch register.
11051074
_ => None,
11061075
},

cranelift/filetests/filetests/isa/x64/fuzzbug-60035.clif

Lines changed: 9 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,14 @@ block0:
1515
; VCode:
1616
; pushq %rbp
1717
; movq %rsp, %rbp
18-
; subq %rsp, $64, %rsp
19-
; movq %rbx, 16(%rsp)
20-
; movq %r12, 24(%rsp)
21-
; movq %r13, 32(%rsp)
22-
; movq %r14, 40(%rsp)
23-
; movq %r15, 48(%rsp)
18+
; subq %rsp, $16, %rsp
19+
; movq %r15, 0(%rsp)
2420
; block0:
2521
; load_ext_name userextname0+0, %r15
26-
; movq %r15, rsp(0 + virtual offset)
27-
; movq rsp(0 + virtual offset), %r15
2822
; call *%r15
29-
; movq rsp(0 + virtual offset), %r15
3023
; call *%r15
31-
; movq 16(%rsp), %rbx
32-
; movq 24(%rsp), %r12
33-
; movq 32(%rsp), %r13
34-
; movq 40(%rsp), %r14
35-
; movq 48(%rsp), %r15
36-
; addq %rsp, $64, %rsp
24+
; movq 0(%rsp), %r15
25+
; addq %rsp, $16, %rsp
3726
; movq %rbp, %rsp
3827
; popq %rbp
3928
; ret
@@ -42,25 +31,14 @@ block0:
4231
; block0: ; offset 0x0
4332
; pushq %rbp
4433
; movq %rsp, %rbp
45-
; subq $0x40, %rsp
46-
; movq %rbx, 0x10(%rsp)
47-
; movq %r12, 0x18(%rsp)
48-
; movq %r13, 0x20(%rsp)
49-
; movq %r14, 0x28(%rsp)
50-
; movq %r15, 0x30(%rsp)
51-
; block1: ; offset 0x21
52-
; movabsq $0, %r15 ; reloc_external Abs8 u1:7 0
34+
; subq $0x10, %rsp
5335
; movq %r15, (%rsp)
54-
; movq (%rsp), %r15
36+
; block1: ; offset 0xc
37+
; movabsq $0, %r15 ; reloc_external Abs8 u1:7 0
5538
; callq *%r15
56-
; movq (%rsp), %r15
5739
; callq *%r15
58-
; movq 0x10(%rsp), %rbx
59-
; movq 0x18(%rsp), %r12
60-
; movq 0x20(%rsp), %r13
61-
; movq 0x28(%rsp), %r14
62-
; movq 0x30(%rsp), %r15
63-
; addq $0x40, %rsp
40+
; movq (%rsp), %r15
41+
; addq $0x10, %rsp
6442
; movq %rbp, %rsp
6543
; popq %rbp
6644
; retq

cranelift/filetests/filetests/isa/x64/return-call-indirect.clif

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ block0(v0: i64):
1414
; pushq %rbp
1515
; movq %rsp, %rbp
1616
; block0:
17-
; lea 10(%rax), %rax
17+
; lea 10(%rdi), %rax
1818
; movq %rbp, %rsp
1919
; popq %rbp
2020
; ret
@@ -24,7 +24,7 @@ block0(v0: i64):
2424
; pushq %rbp
2525
; movq %rsp, %rbp
2626
; block1: ; offset 0x4
27-
; addq $0xa, %rax
27+
; leaq 0xa(%rdi), %rax
2828
; movq %rbp, %rsp
2929
; popq %rbp
3030
; retq
@@ -42,18 +42,18 @@ block0(v0: i64):
4242
; pushq %rbp
4343
; movq %rsp, %rbp
4444
; block0:
45-
; load_ext_name %callee_i64+0, %rcx
46-
; return_call_unknown %rcx %rax=%rax
45+
; load_ext_name %callee_i64+0, %rax
46+
; return_call_unknown %rax %rdi=%rdi
4747
;
4848
; Disassembled:
4949
; block0: ; offset 0x0
5050
; pushq %rbp
5151
; movq %rsp, %rbp
5252
; block1: ; offset 0x4
53-
; movabsq $0, %rcx ; reloc_external Abs8 %callee_i64 0
53+
; movabsq $0, %rax ; reloc_external Abs8 %callee_i64 0
5454
; movq %rbp, %rsp
5555
; popq %rbp
56-
; jmpq *%rcx
56+
; jmpq *%rax
5757

5858
;;;; Test colocated tail calls ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5959

@@ -70,18 +70,18 @@ block0(v0: i64):
7070
; pushq %rbp
7171
; movq %rsp, %rbp
7272
; block0:
73-
; load_ext_name %callee_i64+0, %rcx
74-
; return_call_unknown %rcx %rax=%rax
73+
; load_ext_name %callee_i64+0, %rax
74+
; return_call_unknown %rax %rdi=%rdi
7575
;
7676
; Disassembled:
7777
; block0: ; offset 0x0
7878
; pushq %rbp
7979
; movq %rsp, %rbp
8080
; block1: ; offset 0x4
81-
; leaq (%rip), %rcx ; reloc_external CallPCRel4 %callee_i64 -4
81+
; leaq (%rip), %rax ; reloc_external CallPCRel4 %callee_i64 -4
8282
; movq %rbp, %rsp
8383
; popq %rbp
84-
; jmpq *%rcx
84+
; jmpq *%rax
8585

8686
;;;; Test passing `f64`s ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8787

@@ -165,7 +165,7 @@ block0(v0: i8):
165165
; pushq %rbp
166166
; movq %rsp, %rbp
167167
; block0:
168-
; testb %al, %al
168+
; testb %dil, %dil
169169
; setz %al
170170
; movq %rbp, %rsp
171171
; popq %rbp
@@ -176,7 +176,7 @@ block0(v0: i8):
176176
; pushq %rbp
177177
; movq %rsp, %rbp
178178
; block1: ; offset 0x4
179-
; testb %al, %al
179+
; testb %dil, %dil
180180
; sete %al
181181
; movq %rbp, %rsp
182182
; popq %rbp
@@ -195,16 +195,16 @@ block0(v0: i8):
195195
; pushq %rbp
196196
; movq %rsp, %rbp
197197
; block0:
198-
; load_ext_name %callee_i8+0, %rcx
199-
; return_call_unknown %rcx %rax=%rax
198+
; load_ext_name %callee_i8+0, %rax
199+
; return_call_unknown %rax %rdi=%rdi
200200
;
201201
; Disassembled:
202202
; block0: ; offset 0x0
203203
; pushq %rbp
204204
; movq %rsp, %rbp
205205
; block1: ; offset 0x4
206-
; movabsq $0, %rcx ; reloc_external Abs8 %callee_i8 0
206+
; movabsq $0, %rax ; reloc_external Abs8 %callee_i8 0
207207
; movq %rbp, %rsp
208208
; popq %rbp
209-
; jmpq *%rcx
209+
; jmpq *%rax
210210

0 commit comments

Comments
 (0)