Skip to content

Commit e5b2865

Browse files
committed
Refactor call ABI.
1 parent fd67b79 commit e5b2865

File tree

1 file changed

+37
-48
lines changed

1 file changed

+37
-48
lines changed

src/librustc_target/abi/call/xtensa.rs

Lines changed: 37 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,27 @@ const MAX_RET_IN_REGS_SIZE: u64 = 2 * 32;
99

1010
fn classify_ret_ty<Ty>(arg: &mut ArgAbi<'_, Ty>, xlen: u64) {
1111
// The rules for return and argument types are the same, so defer to
12-
// classifyArgumentType.
13-
classify_arg_ty(arg, xlen, &mut 2); // two as max return size
12+
// classify_arg_ty.
13+
let mut remaining_gpr = 2;
14+
let fixed = true;
15+
classify_arg_ty(arg, xlen, fixed, &mut remaining_gpr);
1416
}
1517

16-
fn classify_arg_ty<Ty>(arg: &mut ArgAbi<'_, Ty>, xlen: u64, remaining_gpr: &mut u64) {
17-
// Determine the number of GPRs needed to pass the current argument
18-
// according to the ABI. 2*XLen-aligned varargs are passed in "aligned"
19-
// register pairs, so may consume 3 registers.
18+
fn classify_arg_ty<Ty>(arg: &mut ArgAbi<'_, Ty>, xlen: u64, fixed: bool, remaining_gpr: &mut u64) {
19+
assert!(*remaining_gpr <= NUM_ARG_GPR, "Arg GPR tracking underflow");
2020

2121
let arg_size = arg.layout.size;
22-
if arg_size.bits() > MAX_ARG_IN_REGS_SIZE {
23-
arg.make_indirect();
24-
return;
25-
}
22+
let alignment = arg.layout.details.align.abi;
2623

27-
let alignment = arg.layout.align.abi;
28-
let mut required_gpr = 1u64; // at least one per arg
24+
// Determine the number of GPRs needed to pass the current argument
25+
// according to the ABI. 2*XLen-aligned varargs are passed in "aligned"
26+
// register pairs, so may consume 3 registers.
27+
let mut required_gpr = 1u64;
2928

30-
if alignment.bits() == 2 * xlen {
29+
if !fixed && alignment.bits() == 2 * xlen {
3130
required_gpr = 2 + (*remaining_gpr % 2);
3231
} else if arg_size.bits() > xlen && arg_size.bits() <= MAX_ARG_IN_REGS_SIZE {
33-
required_gpr = (arg_size.bits() + (xlen - 1)) / xlen;
32+
required_gpr = (arg_size.bits() + xlen - 1) / xlen;
3433
}
3534

3635
let mut stack_required = false;
@@ -40,63 +39,53 @@ fn classify_arg_ty<Ty>(arg: &mut ArgAbi<'_, Ty>, xlen: u64, remaining_gpr: &mut
4039
}
4140
*remaining_gpr -= required_gpr;
4241

43-
// if a value can fit in a reg and the
44-
// stack is not required, extend
4542
if !arg.layout.is_aggregate() {
46-
// non-aggregate types
43+
// All integral types are promoted to XLen width, unless passed on the
44+
// stack.
4745
if arg_size.bits() < xlen && !stack_required {
4846
arg.extend_integer_width_to(xlen);
47+
return;
4948
}
50-
} else if arg_size.bits() as u64 <= MAX_ARG_IN_REGS_SIZE {
51-
// aggregate types
52-
// Aggregates which are <= 4*32 will be passed in registers if possible,
53-
// so coerce to integers.
5449

50+
return;
51+
}
52+
53+
// Aggregates which are <= 4 * 32 will be passed in registers if possible,
54+
// so coerce to integers.
55+
if size.bits() as u64 <= MAX_ARG_IN_REGS_SIZE {
5556
// Use a single XLen int if possible, 2*XLen if 2*XLen alignment is
5657
// required, and a 2-element XLen array if only XLen alignment is
5758
// required.
58-
// if alignment == 2 * xlen {
59-
// arg.extend_integer_width_to(xlen * 2);
60-
// } else {
61-
// arg.extend_integer_width_to(arg_size + (xlen - 1) / xlen);
62-
// }
63-
if alignment.bits() == 2 * xlen {
59+
if arg_size.bits() <= xlen {
60+
arg.cast_to(Uniform { unit: Reg::i32(), total: arg_size });
61+
return;
62+
} else if alignment.bits() == 2 * xlen {
6463
arg.cast_to(Uniform { unit: Reg::i64(), total: arg_size });
64+
return;
6565
} else {
66-
//FIXME array type - this should be a homogenous array type
67-
// arg.extend_integer_width_to(arg_size + (xlen - 1) / xlen);
66+
arg.extend_integer_width_to((arg_size.bits() + xlen - 1) / xlen);
67+
return;
6868
}
69-
} else {
70-
// if we get here the stack is required
71-
assert!(stack_required);
72-
arg.make_indirect();
7369
}
7470

75-
// if arg_size as u64 <= MAX_ARG_IN_REGS_SIZE {
76-
// let align = arg.layout.align.abi.bytes();
77-
// let total = arg.layout.size;
78-
// arg.cast_to(Uniform {
79-
// unit: if align <= 4 { Reg::i32() } else { Reg::i64() },
80-
// total
81-
// });
82-
// return;
83-
// }
71+
arg.make_indirect();
8472
}
8573

86-
pub fn compute_abi_info<Ty>(fabi: &mut FnAbi<'_, Ty>, xlen: u64) {
87-
if !fabi.ret.is_ignore() {
88-
classify_ret_ty(&mut fabi.ret, xlen);
74+
pub fn compute_abi_info<Ty>(fty: &mut FnAbi<'_, Ty>, xlen: u64) {
75+
if !fty.ret.is_ignore() {
76+
classify_ret_ty(&mut fty.ret, xlen);
8977
}
9078

9179
let return_indirect =
92-
fabi.ret.layout.size.bits() > MAX_RET_IN_REGS_SIZE || fabi.ret.is_indirect();
80+
fty.ret.is_indirect() || fty.ret.layout.size.bits() > MAX_RET_IN_REGS_SIZE;
9381

9482
let mut remaining_gpr = if return_indirect { NUM_ARG_GPR - 1 } else { NUM_ARG_GPR };
9583

96-
for arg in &mut fabi.args {
84+
for arg in &mut fty.args {
9785
if arg.is_ignore() {
9886
continue;
9987
}
100-
classify_arg_ty(arg, xlen, &mut remaining_gpr);
88+
let fixed = true;
89+
classify_arg_ty(arg, xlen, fixed, &mut remaining_gpr);
10190
}
10291
}

0 commit comments

Comments
 (0)