Merge pull request #2223 from cfallin/baldrdash-2020
Support for SpiderMonkey's "Wasm ABI 2020" in general and on AArch64.
This commit is contained in:
@@ -20,6 +20,11 @@ use std::convert::TryFrom;
|
||||
/// with 32-bit arithmetic: for now, 128 MB.
|
||||
static STACK_ARG_RET_SIZE_LIMIT: u64 = 128 * 1024 * 1024;
|
||||
|
||||
/// Offset in stack-arg area to callee-TLS slot in Baldrdash-2020 calling convention.
|
||||
static BALDRDASH_CALLEE_TLS_OFFSET: i64 = 0;
|
||||
/// Offset in stack-arg area to caller-TLS slot in Baldrdash-2020 calling convention.
|
||||
static BALDRDASH_CALLER_TLS_OFFSET: i64 = 8;
|
||||
|
||||
/// Try to fill a Baldrdash register, returning it if it was found.
|
||||
fn try_fill_baldrdash_reg(call_conv: CallConv, param: &ir::AbiParam) -> Option<ABIArg> {
|
||||
if call_conv.extends_baldrdash() {
|
||||
@@ -30,6 +35,7 @@ fn try_fill_baldrdash_reg(call_conv: CallConv, param: &ir::AbiParam) -> Option<A
|
||||
regs::r14().to_real_reg(),
|
||||
types::I64,
|
||||
param.extension,
|
||||
param.purpose,
|
||||
))
|
||||
}
|
||||
&ir::ArgumentPurpose::SignatureId => {
|
||||
@@ -38,6 +44,27 @@ fn try_fill_baldrdash_reg(call_conv: CallConv, param: &ir::AbiParam) -> Option<A
|
||||
regs::r10().to_real_reg(),
|
||||
types::I64,
|
||||
param.extension,
|
||||
param.purpose,
|
||||
))
|
||||
}
|
||||
&ir::ArgumentPurpose::CalleeTLS => {
|
||||
// This is SpiderMonkey's callee TLS slot in the extended frame of Wasm's ABI-2020.
|
||||
assert!(call_conv == isa::CallConv::Baldrdash2020);
|
||||
Some(ABIArg::Stack(
|
||||
BALDRDASH_CALLEE_TLS_OFFSET,
|
||||
ir::types::I64,
|
||||
ir::ArgumentExtension::None,
|
||||
param.purpose,
|
||||
))
|
||||
}
|
||||
&ir::ArgumentPurpose::CallerTLS => {
|
||||
// This is SpiderMonkey's caller TLS slot in the extended frame of Wasm's ABI-2020.
|
||||
assert!(call_conv == isa::CallConv::Baldrdash2020);
|
||||
Some(ABIArg::Stack(
|
||||
BALDRDASH_CALLER_TLS_OFFSET,
|
||||
ir::types::I64,
|
||||
ir::ArgumentExtension::None,
|
||||
param.purpose,
|
||||
))
|
||||
}
|
||||
_ => None,
|
||||
@@ -70,12 +97,19 @@ impl ABIMachineSpec for X64ABIMachineSpec {
|
||||
add_ret_area_ptr: bool,
|
||||
) -> CodegenResult<(Vec<ABIArg>, i64, Option<usize>)> {
|
||||
let is_baldrdash = call_conv.extends_baldrdash();
|
||||
let has_baldrdash_tls = call_conv == isa::CallConv::Baldrdash2020;
|
||||
|
||||
let mut next_gpr = 0;
|
||||
let mut next_vreg = 0;
|
||||
let mut next_stack: u64 = 0;
|
||||
let mut ret = vec![];
|
||||
|
||||
if args_or_rets == ArgsOrRets::Args && has_baldrdash_tls {
|
||||
// Baldrdash ABI-2020 always has two stack-arg slots reserved, for the callee and
|
||||
// caller TLS-register values, respectively.
|
||||
next_stack = 16;
|
||||
}
|
||||
|
||||
for i in 0..params.len() {
|
||||
// Process returns backward, according to the SpiderMonkey ABI (which we
|
||||
// adopt internally if `is_baldrdash` is set).
|
||||
@@ -90,7 +124,9 @@ impl ABIMachineSpec for X64ABIMachineSpec {
|
||||
&ir::ArgumentPurpose::VMContext
|
||||
| &ir::ArgumentPurpose::Normal
|
||||
| &ir::ArgumentPurpose::StackLimit
|
||||
| &ir::ArgumentPurpose::SignatureId => {}
|
||||
| &ir::ArgumentPurpose::SignatureId
|
||||
| &ir::ArgumentPurpose::CalleeTLS
|
||||
| &ir::ArgumentPurpose::CallerTLS => {}
|
||||
_ => panic!(
|
||||
"Unsupported argument purpose {:?} in signature: {:?}",
|
||||
param.purpose, params
|
||||
@@ -130,6 +166,7 @@ impl ABIMachineSpec for X64ABIMachineSpec {
|
||||
reg.to_real_reg(),
|
||||
param.value_type,
|
||||
param.extension,
|
||||
param.purpose,
|
||||
));
|
||||
*next_reg += 1;
|
||||
} else {
|
||||
@@ -144,6 +181,7 @@ impl ABIMachineSpec for X64ABIMachineSpec {
|
||||
next_stack as i64,
|
||||
param.value_type,
|
||||
param.extension,
|
||||
param.purpose,
|
||||
));
|
||||
next_stack += size;
|
||||
}
|
||||
@@ -160,12 +198,14 @@ impl ABIMachineSpec for X64ABIMachineSpec {
|
||||
reg.to_real_reg(),
|
||||
types::I64,
|
||||
ir::ArgumentExtension::None,
|
||||
ir::ArgumentPurpose::Normal,
|
||||
));
|
||||
} else {
|
||||
ret.push(ABIArg::Stack(
|
||||
next_stack as i64,
|
||||
types::I64,
|
||||
ir::ArgumentExtension::None,
|
||||
ir::ArgumentPurpose::Normal,
|
||||
));
|
||||
next_stack += 8;
|
||||
}
|
||||
@@ -347,6 +387,7 @@ impl ABIMachineSpec for X64ABIMachineSpec {
|
||||
|
||||
fn gen_clobber_save(
|
||||
call_conv: isa::CallConv,
|
||||
_: &settings::Flags,
|
||||
clobbers: &Set<Writable<RealReg>>,
|
||||
) -> (u64, SmallVec<[Self::I; 16]>) {
|
||||
let mut insts = SmallVec::new();
|
||||
@@ -392,6 +433,7 @@ impl ABIMachineSpec for X64ABIMachineSpec {
|
||||
|
||||
fn gen_clobber_restore(
|
||||
call_conv: isa::CallConv,
|
||||
flags: &settings::Flags,
|
||||
clobbers: &Set<Writable<RealReg>>,
|
||||
) -> SmallVec<[Self::I; 16]> {
|
||||
let mut insts = SmallVec::new();
|
||||
@@ -426,6 +468,18 @@ impl ABIMachineSpec for X64ABIMachineSpec {
|
||||
));
|
||||
}
|
||||
|
||||
// If this is Baldrdash-2020, restore the callee (i.e., our) TLS
|
||||
// register. We may have allocated it for something else and clobbered
|
||||
// it, but the ABI expects us to leave the TLS register unchanged.
|
||||
if call_conv == isa::CallConv::Baldrdash2020 {
|
||||
let off = BALDRDASH_CALLEE_TLS_OFFSET + Self::fp_to_arg_offset(call_conv, flags);
|
||||
insts.push(Inst::mov64_m_r(
|
||||
Amode::imm_reg(off as u32, regs::rbp()),
|
||||
Writable::from_reg(regs::r14()),
|
||||
None,
|
||||
));
|
||||
}
|
||||
|
||||
insts
|
||||
}
|
||||
|
||||
@@ -594,7 +648,11 @@ fn in_vec_reg(ty: types::Type) -> bool {
|
||||
|
||||
fn get_intreg_for_arg_systemv(call_conv: &CallConv, idx: usize) -> Option<Reg> {
|
||||
match call_conv {
|
||||
CallConv::Fast | CallConv::Cold | CallConv::SystemV | CallConv::BaldrdashSystemV => {}
|
||||
CallConv::Fast
|
||||
| CallConv::Cold
|
||||
| CallConv::SystemV
|
||||
| CallConv::BaldrdashSystemV
|
||||
| CallConv::Baldrdash2020 => {}
|
||||
_ => panic!("int args only supported for SysV calling convention"),
|
||||
};
|
||||
match idx {
|
||||
@@ -610,7 +668,11 @@ fn get_intreg_for_arg_systemv(call_conv: &CallConv, idx: usize) -> Option<Reg> {
|
||||
|
||||
fn get_fltreg_for_arg_systemv(call_conv: &CallConv, idx: usize) -> Option<Reg> {
|
||||
match call_conv {
|
||||
CallConv::Fast | CallConv::Cold | CallConv::SystemV | CallConv::BaldrdashSystemV => {}
|
||||
CallConv::Fast
|
||||
| CallConv::Cold
|
||||
| CallConv::SystemV
|
||||
| CallConv::BaldrdashSystemV
|
||||
| CallConv::Baldrdash2020 => {}
|
||||
_ => panic!("float args only supported for SysV calling convention"),
|
||||
};
|
||||
match idx {
|
||||
@@ -637,7 +699,7 @@ fn get_intreg_for_retval_systemv(
|
||||
1 => Some(regs::rdx()),
|
||||
_ => None,
|
||||
},
|
||||
CallConv::BaldrdashSystemV => {
|
||||
CallConv::BaldrdashSystemV | CallConv::Baldrdash2020 => {
|
||||
if intreg_idx == 0 && retval_idx == 0 {
|
||||
Some(regs::rax())
|
||||
} else {
|
||||
@@ -659,7 +721,7 @@ fn get_fltreg_for_retval_systemv(
|
||||
1 => Some(regs::xmm1()),
|
||||
_ => None,
|
||||
},
|
||||
CallConv::BaldrdashSystemV => {
|
||||
CallConv::BaldrdashSystemV | CallConv::Baldrdash2020 => {
|
||||
if fltreg_idx == 0 && retval_idx == 0 {
|
||||
Some(regs::xmm0())
|
||||
} else {
|
||||
@@ -701,7 +763,7 @@ fn is_callee_save_baldrdash(r: RealReg) -> bool {
|
||||
|
||||
fn get_callee_saves(call_conv: &CallConv, regs: &Set<Writable<RealReg>>) -> Vec<Writable<RealReg>> {
|
||||
let mut regs: Vec<Writable<RealReg>> = match call_conv {
|
||||
CallConv::BaldrdashSystemV => regs
|
||||
CallConv::BaldrdashSystemV | CallConv::Baldrdash2020 => regs
|
||||
.iter()
|
||||
.cloned()
|
||||
.filter(|r| is_callee_save_baldrdash(r.to_reg()))
|
||||
|
||||
Reference in New Issue
Block a user