Implement a Windows Baldrdash calling convention;
This commit is contained in:
@@ -112,7 +112,8 @@ pub fn define() -> SettingGroup {
|
||||
"cold",
|
||||
"system_v",
|
||||
"windows_fastcall",
|
||||
"baldrdash",
|
||||
"baldrdash_system_v",
|
||||
"baldrdash_windows",
|
||||
"probestack",
|
||||
],
|
||||
);
|
||||
|
||||
@@ -373,7 +373,8 @@ mod tests {
|
||||
CallConv::Cold,
|
||||
CallConv::SystemV,
|
||||
CallConv::WindowsFastcall,
|
||||
CallConv::Baldrdash,
|
||||
CallConv::BaldrdashSystemV,
|
||||
CallConv::BaldrdashWindows,
|
||||
] {
|
||||
assert_eq!(Ok(cc), cc.to_string().parse())
|
||||
}
|
||||
@@ -381,16 +382,19 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn signatures() {
|
||||
let mut sig = Signature::new(CallConv::Baldrdash);
|
||||
assert_eq!(sig.to_string(), "() baldrdash");
|
||||
let mut sig = Signature::new(CallConv::BaldrdashSystemV);
|
||||
assert_eq!(sig.to_string(), "() baldrdash_system_v");
|
||||
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));
|
||||
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()));
|
||||
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));
|
||||
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.
|
||||
sig.params[0].location = ArgumentLoc::Stack(24);
|
||||
@@ -399,7 +403,7 @@ mod tests {
|
||||
// Writing ABI-annotated signatures.
|
||||
assert_eq!(
|
||||
sig.to_string(),
|
||||
"(i32 [24], i32x4 [8]) -> f32, b8 baldrdash"
|
||||
"(i32 [24], i32x4 [8]) -> f32, b8 baldrdash_system_v"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ fn make_funcref_for_inst(
|
||||
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.
|
||||
sig.params.push(AbiParam::special(
|
||||
isa.pointer_type(),
|
||||
|
||||
@@ -15,8 +15,10 @@ pub enum CallConv {
|
||||
SystemV,
|
||||
/// Windows "fastcall" convention, also used for x64 and ARM
|
||||
WindowsFastcall,
|
||||
/// SpiderMonkey WebAssembly convention
|
||||
Baldrdash,
|
||||
/// SpiderMonkey WebAssembly convention on systems using natively SystemV
|
||||
BaldrdashSystemV,
|
||||
/// SpiderMonkey WebAssembly convention on Windows
|
||||
BaldrdashWindows,
|
||||
/// Specialized convention for the probestack function
|
||||
Probestack,
|
||||
}
|
||||
@@ -40,10 +42,27 @@ impl CallConv {
|
||||
LibcallCallConv::Cold => CallConv::Cold,
|
||||
LibcallCallConv::SystemV => CallConv::SystemV,
|
||||
LibcallCallConv::WindowsFastcall => CallConv::WindowsFastcall,
|
||||
LibcallCallConv::Baldrdash => CallConv::Baldrdash,
|
||||
LibcallCallConv::BaldrdashSystemV => CallConv::BaldrdashSystemV,
|
||||
LibcallCallConv::BaldrdashWindows => CallConv::BaldrdashWindows,
|
||||
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 {
|
||||
@@ -53,7 +72,8 @@ impl fmt::Display for CallConv {
|
||||
CallConv::Cold => "cold",
|
||||
CallConv::SystemV => "system_v",
|
||||
CallConv::WindowsFastcall => "windows_fastcall",
|
||||
CallConv::Baldrdash => "baldrdash",
|
||||
CallConv::BaldrdashSystemV => "baldrdash_system_v",
|
||||
CallConv::BaldrdashWindows => "baldrdash_windows",
|
||||
CallConv::Probestack => "probestack",
|
||||
})
|
||||
}
|
||||
@@ -67,7 +87,8 @@ impl str::FromStr for CallConv {
|
||||
"cold" => Ok(CallConv::Cold),
|
||||
"system_v" => Ok(CallConv::SystemV),
|
||||
"windows_fastcall" => Ok(CallConv::WindowsFastcall),
|
||||
"baldrdash" => Ok(CallConv::Baldrdash),
|
||||
"baldrdash_system_v" => Ok(CallConv::BaldrdashSystemV),
|
||||
"baldrdash_windows" => Ok(CallConv::BaldrdashWindows),
|
||||
"probestack" => Ok(CallConv::Probestack),
|
||||
_ => Err(()),
|
||||
}
|
||||
|
||||
@@ -343,7 +343,7 @@ pub trait TargetIsa: fmt::Display + Sync {
|
||||
let word_size = StackSize::from(self.pointer_bytes());
|
||||
|
||||
// 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 mut ss = ir::StackSlotData::new(ir::StackSlotKind::IncomingArg, bytes);
|
||||
ss.offset = Some(-(bytes as StackOffset));
|
||||
|
||||
@@ -55,7 +55,7 @@ impl Args {
|
||||
shared_flags: &shared_settings::Flags,
|
||||
isa_flags: &isa_settings::Flags,
|
||||
) -> 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,
|
||||
// and must always allocate sufficient space to store four register parameters"
|
||||
32
|
||||
@@ -109,7 +109,7 @@ impl ArgAssigner for Args {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
// This is SpiderMonkey's `WasmTlsReg`.
|
||||
ArgumentPurpose::VMContext => {
|
||||
@@ -134,7 +134,7 @@ impl ArgAssigner for Args {
|
||||
}
|
||||
|
||||
// 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.
|
||||
// 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.
|
||||
@@ -143,6 +143,7 @@ impl ArgAssigner for Args {
|
||||
} else {
|
||||
&mut self.fpr_used
|
||||
};
|
||||
|
||||
if ty.is_float() && *fpr_offset < self.fpr_limit {
|
||||
let reg = FPR.unit(*fpr_offset);
|
||||
*fpr_offset += 1;
|
||||
@@ -176,7 +177,7 @@ pub fn legalize_signature(
|
||||
}
|
||||
PointerWidth::U64 => {
|
||||
bits = 64;
|
||||
args = if sig.call_conv == CallConv::WindowsFastcall {
|
||||
args = if sig.call_conv.extends_windows_fastcall() {
|
||||
Args::new(
|
||||
bits,
|
||||
&ARG_GPRS_WIN_FASTCALL_X64[..],
|
||||
@@ -200,7 +201,7 @@ pub fn legalize_signature(
|
||||
|
||||
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
|
||||
(&RET_GPRS_WIN_FASTCALL_X64[..], 1)
|
||||
} else {
|
||||
@@ -250,7 +251,7 @@ fn callee_saved_gprs(isa: &dyn TargetIsa, call_conv: CallConv) -> &'static [RU]
|
||||
PointerWidth::U16 => panic!(),
|
||||
PointerWidth::U32 => &[RU::rbx, RU::rsi, RU::rdi],
|
||||
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
|
||||
// and must be saved and restored by a function that uses them."
|
||||
// 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)
|
||||
}
|
||||
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"),
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
let stack_align = 16;
|
||||
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);
|
||||
ss.offset = Some(-(bytes as StackOffset));
|
||||
|
||||
@@ -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));
|
||||
|
||||
let call_conv = CallConv::for_libcall(isa);
|
||||
if call_conv == CallConv::Baldrdash {
|
||||
if call_conv.extends_baldrdash() {
|
||||
let vmctx = func
|
||||
.special_param(ir::ArgumentPurpose::VMContext)
|
||||
.expect("Missing vmctx parameter for baldrdash libcall");
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
test verifier
|
||||
|
||||
function %add_members(i32, i64 vmctx) -> f32 baldrdash {
|
||||
function %add_members(i32, i64 vmctx) -> f32 baldrdash_system_v {
|
||||
gv0 = vmctx
|
||||
gv1 = load.i64 notrap aligned gv0+64
|
||||
gv2 = load.i32 notrap aligned gv0+72
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
test verifier
|
||||
|
||||
function %add_members(i32, i32 vmctx) -> f32 baldrdash {
|
||||
function %add_members(i32, i32 vmctx) -> f32 baldrdash_system_v {
|
||||
gv0 = vmctx
|
||||
gv1 = load.i32 notrap aligned gv0+64
|
||||
heap0 = static gv1, min 0x1000, bound 0x10_0000, offset_guard 0x1000
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
test verifier
|
||||
|
||||
function %add_members(i32, i64 vmctx) -> f32 baldrdash {
|
||||
function %add_members(i32, i64 vmctx) -> f32 baldrdash_system_v {
|
||||
gv0 = vmctx
|
||||
gv1 = load.i64 notrap aligned gv0+64
|
||||
heap0 = static gv1, min 0x1000, bound 0x1_0000_0000, offset_guard 0x8000_0000
|
||||
|
||||
@@ -375,7 +375,7 @@ convention:
|
||||
param : type [paramext] [paramspecial]
|
||||
paramext : "uext" | "sext"
|
||||
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
|
||||
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
|
||||
system_v System V-style convention used on many platforms
|
||||
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
|
||||
|
||||
@@ -18,8 +18,8 @@ ebb0:
|
||||
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 {
|
||||
sig0 = (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_system_v
|
||||
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):
|
||||
|
||||
@@ -44,7 +44,7 @@ ebb1:
|
||||
|
||||
; SpiderMonkey VM-style static 4+2 GB heap.
|
||||
; 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
|
||||
gv1 = iadd_imm.i64 gv0, 64
|
||||
heap0 = static gv1, min 0x1000, bound 0x1_0000_0000, offset_guard 0x8000_0000
|
||||
@@ -65,7 +65,7 @@ ebb0(v0: i32, v999: i64):
|
||||
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
|
||||
gv1 = iadd_imm.i64 gv0, 64
|
||||
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.
|
||||
; 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
|
||||
gv1 = iadd_imm.i64 gv0, 64
|
||||
heap0 = static gv1, min 0x1000, bound 0x1_0000_0000, offset_guard 0x8000_0000
|
||||
|
||||
@@ -3,15 +3,15 @@ set enable_simd=true
|
||||
set probestack_enabled=false
|
||||
target x86_64 haswell
|
||||
|
||||
; use baldrdash calling convention here for simplicity (avoids prologue, epilogue)
|
||||
function %test_splat_i32() -> i32x4 baldrdash {
|
||||
; use baldrdash_system_v calling convention here for simplicity (avoids prologue, epilogue)
|
||||
function %test_splat_i32() -> i32x4 baldrdash_system_v {
|
||||
ebb0:
|
||||
v0 = iconst.i32 42
|
||||
v1 = splat.i32x4 v0
|
||||
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:
|
||||
; nextln: ebb0:
|
||||
@@ -23,7 +23,7 @@ ebb0:
|
||||
|
||||
|
||||
|
||||
function %test_splat_i64() -> i64x2 baldrdash {
|
||||
function %test_splat_i64() -> i64x2 baldrdash_system_v {
|
||||
ebb0:
|
||||
v0 = iconst.i64 42
|
||||
v1 = splat.i64x2 v0
|
||||
@@ -38,7 +38,7 @@ ebb0:
|
||||
|
||||
|
||||
|
||||
function %test_splat_b16() -> b16x8 baldrdash {
|
||||
function %test_splat_b16() -> b16x8 baldrdash_system_v {
|
||||
ebb0:
|
||||
v0 = bconst.b16 true
|
||||
v1 = splat.b16x8 v0
|
||||
@@ -56,7 +56,7 @@ ebb0:
|
||||
|
||||
|
||||
|
||||
function %test_splat_i8() -> i8x16 baldrdash {
|
||||
function %test_splat_i8() -> i8x16 baldrdash_system_v {
|
||||
ebb0:
|
||||
v0 = iconst.i8 42
|
||||
v1 = splat.i8x16 v0
|
||||
|
||||
@@ -10,7 +10,7 @@ target x86_64 haswell
|
||||
; 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.
|
||||
|
||||
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
|
||||
gv0 = vmctx
|
||||
gv1 = iadd_imm.i64 gv0, 48
|
||||
|
||||
@@ -7,7 +7,7 @@ target x86_64
|
||||
; regex: V=v\d+
|
||||
; regex: EBB=ebb\d+
|
||||
|
||||
function u0:0(i64 vmctx) baldrdash {
|
||||
function u0:0(i64 vmctx) baldrdash_system_v {
|
||||
gv0 = vmctx
|
||||
gv1 = iadd_imm.i64 gv0, 48
|
||||
jt0 = jump_table [ebb2, ebb2, ebb7]
|
||||
|
||||
@@ -10,13 +10,13 @@ ebb1:
|
||||
; nextln: return
|
||||
; nextln: }
|
||||
|
||||
function %r1() -> i32, f32 baldrdash {
|
||||
function %r1() -> i32, f32 baldrdash_system_v {
|
||||
ebb1:
|
||||
v1 = iconst.i32 3
|
||||
v2 = f32const 0.0
|
||||
return v1, v2
|
||||
}
|
||||
; sameln: function %r1() -> i32, f32 baldrdash {
|
||||
; sameln: function %r1() -> i32, f32 baldrdash_system_v {
|
||||
; nextln: ebb1:
|
||||
; nextln: v1 = iconst.i32 3
|
||||
; nextln: v2 = f32const 0.0
|
||||
@@ -25,13 +25,13 @@ ebb1:
|
||||
|
||||
function %signatures() {
|
||||
sig10 = ()
|
||||
sig11 = (i32, f64) -> i32, b1 baldrdash
|
||||
sig11 = (i32, f64) -> i32, b1 baldrdash_system_v
|
||||
fn5 = %foo sig11
|
||||
fn8 = %bar(i32) -> b1
|
||||
}
|
||||
; sameln: function %signatures() 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
|
||||
; not: fn0
|
||||
; check: fn5 = %foo sig11
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
test regalloc
|
||||
target x86_64 haswell
|
||||
|
||||
function %value_aliases(i32, f32, i64 vmctx) baldrdash {
|
||||
function %value_aliases(i32, f32, i64 vmctx) baldrdash_system_v {
|
||||
gv0 = vmctx
|
||||
heap0 = static gv0, min 0x0001_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
test regalloc
|
||||
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):
|
||||
v32 = iconst.i32 0
|
||||
v6 = bitcast.f32 v32
|
||||
@@ -121,10 +121,10 @@ ebb1(v31: i64):
|
||||
return v31
|
||||
}
|
||||
|
||||
function u0:26(i64 vmctx [%r14]) -> i64 [%rax] baldrdash {
|
||||
function u0:26(i64 vmctx [%r14]) -> i64 [%rax] baldrdash_system_v {
|
||||
gv1 = vmctx
|
||||
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):
|
||||
v1 = iconst.i32 32
|
||||
|
||||
@@ -6,7 +6,7 @@ target x86_64 haswell
|
||||
|
||||
; This function contains unreachable blocks which trip up the register
|
||||
; 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):
|
||||
v1 = iconst.i32 0
|
||||
v2 = iconst.i32 0
|
||||
|
||||
@@ -2630,14 +2630,14 @@ mod tests {
|
||||
assert_eq!(sig.returns.len(), 0);
|
||||
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)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
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.
|
||||
assert_eq!(
|
||||
|
||||
Reference in New Issue
Block a user