Implement a Windows Baldrdash calling convention;

This commit is contained in:
Benjamin Bouvier
2019-08-14 10:39:18 +02:00
parent d8d3602257
commit 2ee35b7ea1
21 changed files with 92 additions and 55 deletions

View File

@@ -112,7 +112,8 @@ pub fn define() -> SettingGroup {
"cold", "cold",
"system_v", "system_v",
"windows_fastcall", "windows_fastcall",
"baldrdash", "baldrdash_system_v",
"baldrdash_windows",
"probestack", "probestack",
], ],
); );

View File

@@ -373,7 +373,8 @@ mod tests {
CallConv::Cold, CallConv::Cold,
CallConv::SystemV, CallConv::SystemV,
CallConv::WindowsFastcall, CallConv::WindowsFastcall,
CallConv::Baldrdash, CallConv::BaldrdashSystemV,
CallConv::BaldrdashWindows,
] { ] {
assert_eq!(Ok(cc), cc.to_string().parse()) assert_eq!(Ok(cc), cc.to_string().parse())
} }
@@ -381,16 +382,19 @@ mod tests {
#[test] #[test]
fn signatures() { fn signatures() {
let mut sig = Signature::new(CallConv::Baldrdash); let mut sig = Signature::new(CallConv::BaldrdashSystemV);
assert_eq!(sig.to_string(), "() baldrdash"); assert_eq!(sig.to_string(), "() baldrdash_system_v");
sig.params.push(AbiParam::new(I32)); sig.params.push(AbiParam::new(I32));
assert_eq!(sig.to_string(), "(i32) baldrdash"); assert_eq!(sig.to_string(), "(i32) baldrdash_system_v");
sig.returns.push(AbiParam::new(F32)); sig.returns.push(AbiParam::new(F32));
assert_eq!(sig.to_string(), "(i32) -> f32 baldrdash"); assert_eq!(sig.to_string(), "(i32) -> f32 baldrdash_system_v");
sig.params.push(AbiParam::new(I32.by(4).unwrap())); sig.params.push(AbiParam::new(I32.by(4).unwrap()));
assert_eq!(sig.to_string(), "(i32, i32x4) -> f32 baldrdash"); assert_eq!(sig.to_string(), "(i32, i32x4) -> f32 baldrdash_system_v");
sig.returns.push(AbiParam::new(B8)); sig.returns.push(AbiParam::new(B8));
assert_eq!(sig.to_string(), "(i32, i32x4) -> f32, b8 baldrdash"); assert_eq!(
sig.to_string(),
"(i32, i32x4) -> f32, b8 baldrdash_system_v"
);
// Order does not matter. // Order does not matter.
sig.params[0].location = ArgumentLoc::Stack(24); sig.params[0].location = ArgumentLoc::Stack(24);
@@ -399,7 +403,7 @@ mod tests {
// Writing ABI-annotated signatures. // Writing ABI-annotated signatures.
assert_eq!( assert_eq!(
sig.to_string(), sig.to_string(),
"(i32 [24], i32x4 [8]) -> f32, b8 baldrdash" "(i32 [24], i32x4 [8]) -> f32, b8 baldrdash_system_v"
); );
} }
} }

View File

@@ -179,7 +179,7 @@ fn make_funcref_for_inst(
sig.returns.push(AbiParam::new(func.dfg.value_type(v))); sig.returns.push(AbiParam::new(func.dfg.value_type(v)));
} }
if call_conv == CallConv::Baldrdash { if call_conv.extends_baldrdash() {
// Adds the special VMContext parameter to the signature. // Adds the special VMContext parameter to the signature.
sig.params.push(AbiParam::special( sig.params.push(AbiParam::special(
isa.pointer_type(), isa.pointer_type(),

View File

@@ -15,8 +15,10 @@ pub enum CallConv {
SystemV, SystemV,
/// Windows "fastcall" convention, also used for x64 and ARM /// Windows "fastcall" convention, also used for x64 and ARM
WindowsFastcall, WindowsFastcall,
/// SpiderMonkey WebAssembly convention /// SpiderMonkey WebAssembly convention on systems using natively SystemV
Baldrdash, BaldrdashSystemV,
/// SpiderMonkey WebAssembly convention on Windows
BaldrdashWindows,
/// Specialized convention for the probestack function /// Specialized convention for the probestack function
Probestack, Probestack,
} }
@@ -40,10 +42,27 @@ impl CallConv {
LibcallCallConv::Cold => CallConv::Cold, LibcallCallConv::Cold => CallConv::Cold,
LibcallCallConv::SystemV => CallConv::SystemV, LibcallCallConv::SystemV => CallConv::SystemV,
LibcallCallConv::WindowsFastcall => CallConv::WindowsFastcall, LibcallCallConv::WindowsFastcall => CallConv::WindowsFastcall,
LibcallCallConv::Baldrdash => CallConv::Baldrdash, LibcallCallConv::BaldrdashSystemV => CallConv::BaldrdashSystemV,
LibcallCallConv::BaldrdashWindows => CallConv::BaldrdashWindows,
LibcallCallConv::Probestack => CallConv::Probestack, LibcallCallConv::Probestack => CallConv::Probestack,
} }
} }
/// Is the calling convention extending the Windows Fastcall ABI?
pub fn extends_windows_fastcall(&self) -> bool {
match self {
CallConv::WindowsFastcall | CallConv::BaldrdashWindows => true,
_ => false,
}
}
/// Is the calling convention extending the Baldrdash ABI?
pub fn extends_baldrdash(&self) -> bool {
match self {
CallConv::BaldrdashSystemV | CallConv::BaldrdashWindows => true,
_ => false,
}
}
} }
impl fmt::Display for CallConv { impl fmt::Display for CallConv {
@@ -53,7 +72,8 @@ impl fmt::Display for CallConv {
CallConv::Cold => "cold", CallConv::Cold => "cold",
CallConv::SystemV => "system_v", CallConv::SystemV => "system_v",
CallConv::WindowsFastcall => "windows_fastcall", CallConv::WindowsFastcall => "windows_fastcall",
CallConv::Baldrdash => "baldrdash", CallConv::BaldrdashSystemV => "baldrdash_system_v",
CallConv::BaldrdashWindows => "baldrdash_windows",
CallConv::Probestack => "probestack", CallConv::Probestack => "probestack",
}) })
} }
@@ -67,7 +87,8 @@ impl str::FromStr for CallConv {
"cold" => Ok(CallConv::Cold), "cold" => Ok(CallConv::Cold),
"system_v" => Ok(CallConv::SystemV), "system_v" => Ok(CallConv::SystemV),
"windows_fastcall" => Ok(CallConv::WindowsFastcall), "windows_fastcall" => Ok(CallConv::WindowsFastcall),
"baldrdash" => Ok(CallConv::Baldrdash), "baldrdash_system_v" => Ok(CallConv::BaldrdashSystemV),
"baldrdash_windows" => Ok(CallConv::BaldrdashWindows),
"probestack" => Ok(CallConv::Probestack), "probestack" => Ok(CallConv::Probestack),
_ => Err(()), _ => Err(()),
} }

View File

@@ -343,7 +343,7 @@ pub trait TargetIsa: fmt::Display + Sync {
let word_size = StackSize::from(self.pointer_bytes()); let word_size = StackSize::from(self.pointer_bytes());
// Account for the SpiderMonkey standard prologue pushes. // Account for the SpiderMonkey standard prologue pushes.
if func.signature.call_conv == CallConv::Baldrdash { if func.signature.call_conv.extends_baldrdash() {
let bytes = StackSize::from(self.flags().baldrdash_prologue_words()) * word_size; let bytes = StackSize::from(self.flags().baldrdash_prologue_words()) * word_size;
let mut ss = ir::StackSlotData::new(ir::StackSlotKind::IncomingArg, bytes); let mut ss = ir::StackSlotData::new(ir::StackSlotKind::IncomingArg, bytes);
ss.offset = Some(-(bytes as StackOffset)); ss.offset = Some(-(bytes as StackOffset));

View File

@@ -55,7 +55,7 @@ impl Args {
shared_flags: &shared_settings::Flags, shared_flags: &shared_settings::Flags,
isa_flags: &isa_settings::Flags, isa_flags: &isa_settings::Flags,
) -> Self { ) -> Self {
let offset = if let CallConv::WindowsFastcall = call_conv { let offset = if call_conv.extends_windows_fastcall() {
// [1] "The caller is responsible for allocating space for parameters to the callee, // [1] "The caller is responsible for allocating space for parameters to the callee,
// and must always allocate sufficient space to store four register parameters" // and must always allocate sufficient space to store four register parameters"
32 32
@@ -109,7 +109,7 @@ impl ArgAssigner for Args {
} }
// Handle special-purpose arguments. // Handle special-purpose arguments.
if ty.is_int() && self.call_conv == CallConv::Baldrdash { if ty.is_int() && self.call_conv.extends_baldrdash() {
match arg.purpose { match arg.purpose {
// This is SpiderMonkey's `WasmTlsReg`. // This is SpiderMonkey's `WasmTlsReg`.
ArgumentPurpose::VMContext => { ArgumentPurpose::VMContext => {
@@ -134,7 +134,7 @@ impl ArgAssigner for Args {
} }
// Try to use an FPR. // Try to use an FPR.
let fpr_offset = if self.call_conv == CallConv::WindowsFastcall { let fpr_offset = if self.call_conv.extends_windows_fastcall() {
// Float and general registers on windows share the same parameter index. // Float and general registers on windows share the same parameter index.
// The used register depends entirely on the parameter index: Even if XMM0 // The used register depends entirely on the parameter index: Even if XMM0
// is not used for the first parameter, it cannot be used for the second parameter. // is not used for the first parameter, it cannot be used for the second parameter.
@@ -143,6 +143,7 @@ impl ArgAssigner for Args {
} else { } else {
&mut self.fpr_used &mut self.fpr_used
}; };
if ty.is_float() && *fpr_offset < self.fpr_limit { if ty.is_float() && *fpr_offset < self.fpr_limit {
let reg = FPR.unit(*fpr_offset); let reg = FPR.unit(*fpr_offset);
*fpr_offset += 1; *fpr_offset += 1;
@@ -176,7 +177,7 @@ pub fn legalize_signature(
} }
PointerWidth::U64 => { PointerWidth::U64 => {
bits = 64; bits = 64;
args = if sig.call_conv == CallConv::WindowsFastcall { args = if sig.call_conv.extends_windows_fastcall() {
Args::new( Args::new(
bits, bits,
&ARG_GPRS_WIN_FASTCALL_X64[..], &ARG_GPRS_WIN_FASTCALL_X64[..],
@@ -200,7 +201,7 @@ pub fn legalize_signature(
legalize_args(&mut sig.params, &mut args); legalize_args(&mut sig.params, &mut args);
let (regs, fpr_limit) = if sig.call_conv == CallConv::WindowsFastcall { let (regs, fpr_limit) = if sig.call_conv.extends_windows_fastcall() {
// windows-x64 calling convention only uses XMM0 or RAX for return values // windows-x64 calling convention only uses XMM0 or RAX for return values
(&RET_GPRS_WIN_FASTCALL_X64[..], 1) (&RET_GPRS_WIN_FASTCALL_X64[..], 1)
} else { } else {
@@ -250,7 +251,7 @@ fn callee_saved_gprs(isa: &dyn TargetIsa, call_conv: CallConv) -> &'static [RU]
PointerWidth::U16 => panic!(), PointerWidth::U16 => panic!(),
PointerWidth::U32 => &[RU::rbx, RU::rsi, RU::rdi], PointerWidth::U32 => &[RU::rbx, RU::rsi, RU::rdi],
PointerWidth::U64 => { PointerWidth::U64 => {
if call_conv == CallConv::WindowsFastcall { if call_conv.extends_windows_fastcall() {
// "registers RBX, RBP, RDI, RSI, RSP, R12, R13, R14, R15 are considered nonvolatile // "registers RBX, RBP, RDI, RSI, RSP, R12, R13, R14, R15 are considered nonvolatile
// and must be saved and restored by a function that uses them." // and must be saved and restored by a function that uses them."
// as per https://msdn.microsoft.com/en-us/library/6t169e9c.aspx // as per https://msdn.microsoft.com/en-us/library/6t169e9c.aspx
@@ -322,7 +323,9 @@ pub fn prologue_epilogue(func: &mut ir::Function, isa: &dyn TargetIsa) -> Codege
system_v_prologue_epilogue(func, isa) system_v_prologue_epilogue(func, isa)
} }
CallConv::WindowsFastcall => fastcall_prologue_epilogue(func, isa), CallConv::WindowsFastcall => fastcall_prologue_epilogue(func, isa),
CallConv::Baldrdash => baldrdash_prologue_epilogue(func, isa), CallConv::BaldrdashSystemV | CallConv::BaldrdashWindows => {
baldrdash_prologue_epilogue(func, isa)
}
CallConv::Probestack => unimplemented!("probestack calling convention"), CallConv::Probestack => unimplemented!("probestack calling convention"),
} }
} }
@@ -336,7 +339,14 @@ fn baldrdash_prologue_epilogue(func: &mut ir::Function, isa: &dyn TargetIsa) ->
// Baldrdash on 32-bit x86 always aligns its stack pointer to 16 bytes. // Baldrdash on 32-bit x86 always aligns its stack pointer to 16 bytes.
let stack_align = 16; let stack_align = 16;
let word_size = StackSize::from(isa.pointer_bytes()); let word_size = StackSize::from(isa.pointer_bytes());
let bytes = StackSize::from(isa.flags().baldrdash_prologue_words()) * word_size; let shadow_store_size = if func.signature.call_conv.extends_windows_fastcall() {
32
} else {
0
};
let bytes =
StackSize::from(isa.flags().baldrdash_prologue_words()) * word_size + shadow_store_size;
let mut ss = ir::StackSlotData::new(ir::StackSlotKind::IncomingArg, bytes); let mut ss = ir::StackSlotData::new(ir::StackSlotKind::IncomingArg, bytes);
ss.offset = Some(-(bytes as StackOffset)); ss.offset = Some(-(bytes as StackOffset));

View File

@@ -20,7 +20,7 @@ pub fn expand_as_libcall(inst: ir::Inst, func: &mut ir::Function, isa: &dyn Targ
args.extend_from_slice(func.dfg.inst_args(inst)); args.extend_from_slice(func.dfg.inst_args(inst));
let call_conv = CallConv::for_libcall(isa); let call_conv = CallConv::for_libcall(isa);
if call_conv == CallConv::Baldrdash { if call_conv.extends_baldrdash() {
let vmctx = func let vmctx = func
.special_param(ir::ArgumentPurpose::VMContext) .special_param(ir::ArgumentPurpose::VMContext)
.expect("Missing vmctx parameter for baldrdash libcall"); .expect("Missing vmctx parameter for baldrdash libcall");

View File

@@ -1,6 +1,6 @@
test verifier test verifier
function %add_members(i32, i64 vmctx) -> f32 baldrdash { function %add_members(i32, i64 vmctx) -> f32 baldrdash_system_v {
gv0 = vmctx gv0 = vmctx
gv1 = load.i64 notrap aligned gv0+64 gv1 = load.i64 notrap aligned gv0+64
gv2 = load.i32 notrap aligned gv0+72 gv2 = load.i32 notrap aligned gv0+72

View File

@@ -1,6 +1,6 @@
test verifier test verifier
function %add_members(i32, i32 vmctx) -> f32 baldrdash { function %add_members(i32, i32 vmctx) -> f32 baldrdash_system_v {
gv0 = vmctx gv0 = vmctx
gv1 = load.i32 notrap aligned gv0+64 gv1 = load.i32 notrap aligned gv0+64
heap0 = static gv1, min 0x1000, bound 0x10_0000, offset_guard 0x1000 heap0 = static gv1, min 0x1000, bound 0x10_0000, offset_guard 0x1000

View File

@@ -1,6 +1,6 @@
test verifier test verifier
function %add_members(i32, i64 vmctx) -> f32 baldrdash { function %add_members(i32, i64 vmctx) -> f32 baldrdash_system_v {
gv0 = vmctx gv0 = vmctx
gv1 = load.i64 notrap aligned gv0+64 gv1 = load.i64 notrap aligned gv0+64
heap0 = static gv1, min 0x1000, bound 0x1_0000_0000, offset_guard 0x8000_0000 heap0 = static gv1, min 0x1000, bound 0x1_0000_0000, offset_guard 0x8000_0000

View File

@@ -375,7 +375,7 @@ convention:
param : type [paramext] [paramspecial] param : type [paramext] [paramspecial]
paramext : "uext" | "sext" paramext : "uext" | "sext"
paramspecial : "sret" | "link" | "fp" | "csr" | "vmctx" | "sigid" | "stack_limit" paramspecial : "sret" | "link" | "fp" | "csr" | "vmctx" | "sigid" | "stack_limit"
callconv : "fast" | "cold" | "system_v" | "fastcall" | "baldrdash" callconv : "fast" | "cold" | "system_v" | "fastcall" | "baldrdash_system_v" | "baldrdash_windows"
A function's calling convention determines exactly how arguments and return A function's calling convention determines exactly how arguments and return
values are passed, and how stack frames are managed. Since all of these details values are passed, and how stack frames are managed. Since all of these details
@@ -402,7 +402,8 @@ fast not-ABI-stable convention for best performance
cold not-ABI-stable convention for infrequently executed code cold not-ABI-stable convention for infrequently executed code
system_v System V-style convention used on many platforms system_v System V-style convention used on many platforms
fastcall Windows "fastcall" convention, also used for x64 and ARM fastcall Windows "fastcall" convention, also used for x64 and ARM
baldrdash SpiderMonkey WebAssembly convention baldrdash_system_v SpiderMonkey WebAssembly convention on platforms natively using SystemV.
baldrdash_windows SpiderMonkey WebAssembly convention on platforms natively using Windows.
========== =========================================== ========== ===========================================
The "not-ABI-stable" conventions do not follow an external specification and The "not-ABI-stable" conventions do not follow an external specification and

View File

@@ -18,8 +18,8 @@ ebb0:
return return
} }
function %pass_stack_int64(i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 vmctx) baldrdash { function %pass_stack_int64(i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 vmctx) baldrdash_system_v {
sig0 = (i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 vmctx) baldrdash sig0 = (i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 vmctx) baldrdash_system_v
fn0 = u0:0 sig0 fn0 = u0:0 sig0
ebb0(v0: i64, v1: i64, v2: i64, v3: i64, v4: i64, v5: i64, v6: i64, v7: i64, v8: i64, v9: i64, v10: i64, v11: i64, v12: i64, v13: i64, v14: i64, v15: i64, v16: i64, v17: i64, v18: i64, v19: i64, v20: i64): ebb0(v0: i64, v1: i64, v2: i64, v3: i64, v4: i64, v5: i64, v6: i64, v7: i64, v8: i64, v9: i64, v10: i64, v11: i64, v12: i64, v13: i64, v14: i64, v15: i64, v16: i64, v17: i64, v18: i64, v19: i64, v20: i64):

View File

@@ -44,7 +44,7 @@ ebb1:
; SpiderMonkey VM-style static 4+2 GB heap. ; SpiderMonkey VM-style static 4+2 GB heap.
; This eliminates bounds checks completely for offsets < 2GB. ; This eliminates bounds checks completely for offsets < 2GB.
function %staticheap_sm64(i32, i64 vmctx) -> f32 baldrdash { function %staticheap_sm64(i32, i64 vmctx) -> f32 baldrdash_system_v {
gv0 = vmctx gv0 = vmctx
gv1 = iadd_imm.i64 gv0, 64 gv1 = iadd_imm.i64 gv0, 64
heap0 = static gv1, min 0x1000, bound 0x1_0000_0000, offset_guard 0x8000_0000 heap0 = static gv1, min 0x1000, bound 0x1_0000_0000, offset_guard 0x8000_0000
@@ -65,7 +65,7 @@ ebb0(v0: i32, v999: i64):
return v4 return v4
} }
function %staticheap_static_oob_sm64(i32, i64 vmctx) -> f32 baldrdash { function %staticheap_static_oob_sm64(i32, i64 vmctx) -> f32 baldrdash_system_v {
gv0 = vmctx gv0 = vmctx
gv1 = iadd_imm.i64 gv0, 64 gv1 = iadd_imm.i64 gv0, 64
heap0 = static gv1, min 0x1000, bound 0x1000_0000, offset_guard 0x8000_0000 heap0 = static gv1, min 0x1000, bound 0x1000_0000, offset_guard 0x8000_0000
@@ -89,7 +89,7 @@ ebb0(v0: i32, v999: i64):
; SpiderMonkey VM-style static 4+2 GB heap. ; SpiderMonkey VM-style static 4+2 GB heap.
; Offsets >= 2 GB do require a boundscheck. ; Offsets >= 2 GB do require a boundscheck.
function %staticheap_sm64(i32, i64 vmctx) -> f32 baldrdash { function %staticheap_sm64(i32, i64 vmctx) -> f32 baldrdash_system_v {
gv0 = vmctx gv0 = vmctx
gv1 = iadd_imm.i64 gv0, 64 gv1 = iadd_imm.i64 gv0, 64
heap0 = static gv1, min 0x1000, bound 0x1_0000_0000, offset_guard 0x8000_0000 heap0 = static gv1, min 0x1000, bound 0x1_0000_0000, offset_guard 0x8000_0000

View File

@@ -3,15 +3,15 @@ set enable_simd=true
set probestack_enabled=false set probestack_enabled=false
target x86_64 haswell target x86_64 haswell
; use baldrdash calling convention here for simplicity (avoids prologue, epilogue) ; use baldrdash_system_v calling convention here for simplicity (avoids prologue, epilogue)
function %test_splat_i32() -> i32x4 baldrdash { function %test_splat_i32() -> i32x4 baldrdash_system_v {
ebb0: ebb0:
v0 = iconst.i32 42 v0 = iconst.i32 42
v1 = splat.i32x4 v0 v1 = splat.i32x4 v0
return v1 return v1
} }
; sameln: function %test_splat_i32() -> i32x4 [%xmm0] baldrdash { ; sameln: function %test_splat_i32() -> i32x4 [%xmm0] baldrdash_system_v {
; nextln: ss0 = incoming_arg 0, offset 0 ; nextln: ss0 = incoming_arg 0, offset 0
; nextln: ; nextln:
; nextln: ebb0: ; nextln: ebb0:
@@ -23,7 +23,7 @@ ebb0:
function %test_splat_i64() -> i64x2 baldrdash { function %test_splat_i64() -> i64x2 baldrdash_system_v {
ebb0: ebb0:
v0 = iconst.i64 42 v0 = iconst.i64 42
v1 = splat.i64x2 v0 v1 = splat.i64x2 v0
@@ -38,7 +38,7 @@ ebb0:
function %test_splat_b16() -> b16x8 baldrdash { function %test_splat_b16() -> b16x8 baldrdash_system_v {
ebb0: ebb0:
v0 = bconst.b16 true v0 = bconst.b16 true
v1 = splat.b16x8 v0 v1 = splat.b16x8 v0
@@ -56,7 +56,7 @@ ebb0:
function %test_splat_i8() -> i8x16 baldrdash { function %test_splat_i8() -> i8x16 baldrdash_system_v {
ebb0: ebb0:
v0 = iconst.i8 42 v0 = iconst.i8 42
v1 = splat.i8x16 v0 v1 = splat.i8x16 v0

View File

@@ -10,7 +10,7 @@ target x86_64 haswell
; particular, the first block has to be non-empty but its encoding size must be ; particular, the first block has to be non-empty but its encoding size must be
; zero (i.e. not generate any code). See also issue #666 for more details. ; zero (i.e. not generate any code). See also issue #666 for more details.
function u0:2691(i32 [%rdi], i32 [%rsi], i64 vmctx [%r14]) -> i64 uext [%rax] baldrdash { function u0:2691(i32 [%rdi], i32 [%rsi], i64 vmctx [%r14]) -> i64 uext [%rax] baldrdash_system_v {
ss0 = incoming_arg 24, offset -24 ss0 = incoming_arg 24, offset -24
gv0 = vmctx gv0 = vmctx
gv1 = iadd_imm.i64 gv0, 48 gv1 = iadd_imm.i64 gv0, 48

View File

@@ -7,7 +7,7 @@ target x86_64
; regex: V=v\d+ ; regex: V=v\d+
; regex: EBB=ebb\d+ ; regex: EBB=ebb\d+
function u0:0(i64 vmctx) baldrdash { function u0:0(i64 vmctx) baldrdash_system_v {
gv0 = vmctx gv0 = vmctx
gv1 = iadd_imm.i64 gv0, 48 gv1 = iadd_imm.i64 gv0, 48
jt0 = jump_table [ebb2, ebb2, ebb7] jt0 = jump_table [ebb2, ebb2, ebb7]

View File

@@ -10,13 +10,13 @@ ebb1:
; nextln: return ; nextln: return
; nextln: } ; nextln: }
function %r1() -> i32, f32 baldrdash { function %r1() -> i32, f32 baldrdash_system_v {
ebb1: ebb1:
v1 = iconst.i32 3 v1 = iconst.i32 3
v2 = f32const 0.0 v2 = f32const 0.0
return v1, v2 return v1, v2
} }
; sameln: function %r1() -> i32, f32 baldrdash { ; sameln: function %r1() -> i32, f32 baldrdash_system_v {
; nextln: ebb1: ; nextln: ebb1:
; nextln: v1 = iconst.i32 3 ; nextln: v1 = iconst.i32 3
; nextln: v2 = f32const 0.0 ; nextln: v2 = f32const 0.0
@@ -25,13 +25,13 @@ ebb1:
function %signatures() { function %signatures() {
sig10 = () sig10 = ()
sig11 = (i32, f64) -> i32, b1 baldrdash sig11 = (i32, f64) -> i32, b1 baldrdash_system_v
fn5 = %foo sig11 fn5 = %foo sig11
fn8 = %bar(i32) -> b1 fn8 = %bar(i32) -> b1
} }
; sameln: function %signatures() fast { ; sameln: function %signatures() fast {
; check: sig10 = () fast ; check: sig10 = () fast
; check: sig11 = (i32, f64) -> i32, b1 baldrdash ; check: sig11 = (i32, f64) -> i32, b1 baldrdash_system_v
; check: sig12 = (i32) -> b1 fast ; check: sig12 = (i32) -> b1 fast
; not: fn0 ; not: fn0
; check: fn5 = %foo sig11 ; check: fn5 = %foo sig11

View File

@@ -1,7 +1,7 @@
test regalloc test regalloc
target x86_64 haswell target x86_64 haswell
function %value_aliases(i32, f32, i64 vmctx) baldrdash { function %value_aliases(i32, f32, i64 vmctx) baldrdash_system_v {
gv0 = vmctx gv0 = vmctx
heap0 = static gv0, min 0x0001_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000 heap0 = static gv0, min 0x0001_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000

View File

@@ -1,7 +1,7 @@
test regalloc test regalloc
target x86_64 haswell target x86_64 haswell
function u0:9(i64 [%rdi], f32 [%xmm0], f64 [%xmm1], i32 [%rsi], i32 [%rdx], i64 vmctx [%r14]) -> i64 [%rax] baldrdash { function u0:9(i64 [%rdi], f32 [%xmm0], f64 [%xmm1], i32 [%rsi], i32 [%rdx], i64 vmctx [%r14]) -> i64 [%rax] baldrdash_system_v {
ebb0(v0: i64, v1: f32, v2: f64, v3: i32, v4: i32, v5: i64): ebb0(v0: i64, v1: f32, v2: f64, v3: i32, v4: i32, v5: i64):
v32 = iconst.i32 0 v32 = iconst.i32 0
v6 = bitcast.f32 v32 v6 = bitcast.f32 v32
@@ -121,10 +121,10 @@ ebb1(v31: i64):
return v31 return v31
} }
function u0:26(i64 vmctx [%r14]) -> i64 [%rax] baldrdash { function u0:26(i64 vmctx [%r14]) -> i64 [%rax] baldrdash_system_v {
gv1 = vmctx gv1 = vmctx
gv0 = iadd_imm.i64 gv1, 48 gv0 = iadd_imm.i64 gv1, 48
sig0 = (i32 [%rdi], i64 [%rsi], i64 vmctx [%r14], i64 sigid [%rbx]) -> i64 [%rax] baldrdash sig0 = (i32 [%rdi], i64 [%rsi], i64 vmctx [%r14], i64 sigid [%rbx]) -> i64 [%rax] baldrdash_system_v
ebb0(v0: i64): ebb0(v0: i64):
v1 = iconst.i32 32 v1 = iconst.i32 32

View File

@@ -6,7 +6,7 @@ target x86_64 haswell
; This function contains unreachable blocks which trip up the register ; This function contains unreachable blocks which trip up the register
; allocator if they don't get cleared out. ; allocator if they don't get cleared out.
function %unreachable_blocks(i64 vmctx) -> i32 baldrdash { function %unreachable_blocks(i64 vmctx) -> i32 baldrdash_system_v {
ebb0(v0: i64): ebb0(v0: i64):
v1 = iconst.i32 0 v1 = iconst.i32 0
v2 = iconst.i32 0 v2 = iconst.i32 0

View File

@@ -2630,14 +2630,14 @@ mod tests {
assert_eq!(sig.returns.len(), 0); assert_eq!(sig.returns.len(), 0);
assert_eq!(sig.call_conv, CallConv::SystemV); assert_eq!(sig.call_conv, CallConv::SystemV);
let sig2 = Parser::new("(i8 uext, f32, f64, i32 sret) -> i32 sext, f64 baldrdash") let sig2 = Parser::new("(i8 uext, f32, f64, i32 sret) -> i32 sext, f64 baldrdash_system_v")
.parse_signature(None) .parse_signature(None)
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
sig2.to_string(), sig2.to_string(),
"(i8 uext, f32, f64, i32 sret) -> i32 sext, f64 baldrdash" "(i8 uext, f32, f64, i32 sret) -> i32 sext, f64 baldrdash_system_v"
); );
assert_eq!(sig2.call_conv, CallConv::Baldrdash); assert_eq!(sig2.call_conv, CallConv::BaldrdashSystemV);
// Old-style signature without a calling convention. // Old-style signature without a calling convention.
assert_eq!( assert_eq!(