diff --git a/lib/cretonne/src/isa/intel/abi.rs b/lib/cretonne/src/isa/intel/abi.rs index 707d42b8d9..7a051905d4 100644 --- a/lib/cretonne/src/isa/intel/abi.rs +++ b/lib/cretonne/src/isa/intel/abi.rs @@ -6,7 +6,7 @@ use regalloc::AllocatableSet; use settings as shared_settings; use super::registers::{GPR, FPR, RU}; use abi::{ArgAction, ValueConversion, ArgAssigner, legalize_args}; -use ir::{ArgumentType, ArgumentLoc, ArgumentExtension}; +use ir::{ArgumentType, ArgumentPurpose, ArgumentLoc, ArgumentExtension}; /// Argument registers for x86-64 static ARG_GPRS: [RU; 6] = [RU::rdi, RU::rsi, RU::rdx, RU::rcx, RU::r8, RU::r9]; @@ -64,6 +64,24 @@ impl ArgAssigner for Args { } } + // Handle special-purpose arguments. + // TODO: The registers below are for `spiderwasm`. Should we check the calling convention? + if ty.is_int() { + match arg.purpose { + // This is SpiderMonkey's `WasmTlsReg`. + ArgumentPurpose::VMContext => { + return ArgumentLoc::Reg(if self.pointer_bits == 64 { + RU::r14 + } else { + RU::rsi + } as RegUnit).into() + } + // This is SpiderMonkey's `WasmTableCallSigReg`. + ArgumentPurpose::SignatureId => return ArgumentLoc::Reg(RU::rbx as RegUnit).into(), + _ => {} + } + } + // Try to use a GPR. if !ty.is_float() && self.gpr_used < self.gpr.len() { let reg = self.gpr[self.gpr_used] as RegUnit;