mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
Auto merge of #99476 - dpaoliello:rawdylibvectorcall, r=michaelwoerister
Add tests for raw-dylib with vectorcall, and fix vectorcall code generation * Adds tests for using `raw-dylib` (#58713) with `vectorcall`. * Fixed code generation for `vectorcall` (parameters have to be marked with `InReg`, just like `fastcall`). * Enabled running the `raw-dylib` `fastcall` tests when using MSVC (since I had to add support in the test for running MSVC-only tests since GCC doesn't support `vectorcall`).
This commit is contained in:
commit
fe3342816a
@ -472,7 +472,9 @@ impl<'tcx> Collector<'tcx> {
|
||||
Abi::Fastcall { .. } => {
|
||||
DllCallingConvention::Fastcall(self.i686_arg_list_size(item))
|
||||
}
|
||||
// Vectorcall is intentionally not supported at this time.
|
||||
Abi::Vectorcall { .. } => {
|
||||
DllCallingConvention::Vectorcall(self.i686_arg_list_size(item))
|
||||
}
|
||||
_ => {
|
||||
self.tcx.sess.span_fatal(
|
||||
item.span,
|
||||
|
@ -669,8 +669,10 @@ impl<'a, Ty> FnAbi<'a, Ty> {
|
||||
|
||||
match &cx.target_spec().arch[..] {
|
||||
"x86" => {
|
||||
let flavor = if let spec::abi::Abi::Fastcall { .. } = abi {
|
||||
x86::Flavor::Fastcall
|
||||
let flavor = if let spec::abi::Abi::Fastcall { .. }
|
||||
| spec::abi::Abi::Vectorcall { .. } = abi
|
||||
{
|
||||
x86::Flavor::FastcallOrVectorcall
|
||||
} else {
|
||||
x86::Flavor::General
|
||||
};
|
||||
|
@ -5,7 +5,7 @@ use crate::spec::HasTargetSpec;
|
||||
#[derive(PartialEq)]
|
||||
pub enum Flavor {
|
||||
General,
|
||||
Fastcall,
|
||||
FastcallOrVectorcall,
|
||||
}
|
||||
|
||||
pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>, flavor: Flavor)
|
||||
@ -60,9 +60,9 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
if flavor == Flavor::Fastcall {
|
||||
if flavor == Flavor::FastcallOrVectorcall {
|
||||
// Mark arguments as InReg like clang does it,
|
||||
// so our fastcall is compatible with C/C++ fastcall.
|
||||
// so our fastcall/vectorcall is compatible with C/C++ fastcall/vectorcall.
|
||||
|
||||
// Clang reference: lib/CodeGen/TargetInfo.cpp
|
||||
// See X86_32ABIInfo::shouldPrimitiveUseInReg(), X86_32ABIInfo::updateFreeRegs()
|
||||
|
@ -14,10 +14,19 @@ ifdef IS_MSVC
|
||||
else
|
||||
$(CC) "$(TMPDIR)"/extern.obj -shared -o "$(TMPDIR)"/extern.dll
|
||||
endif
|
||||
"$(TMPDIR)"/driver > "$(TMPDIR)"/output.txt
|
||||
|
||||
"$(TMPDIR)"/driver > "$(TMPDIR)"/output.txt
|
||||
ifdef RUSTC_BLESS_TEST
|
||||
cp "$(TMPDIR)"/output.txt output.txt
|
||||
else
|
||||
$(DIFF) output.txt "$(TMPDIR)"/output.txt
|
||||
endif
|
||||
|
||||
ifdef IS_MSVC
|
||||
"$(TMPDIR)"/driver true > "$(TMPDIR)"/output.msvc.txt
|
||||
ifdef RUSTC_BLESS_TEST
|
||||
cp "$(TMPDIR)"/output.msvc.txt output.msvc.txt
|
||||
else
|
||||
$(DIFF) output.msvc.txt "$(TMPDIR)"/output.msvc.txt
|
||||
endif
|
||||
endif
|
||||
|
@ -1,5 +1,8 @@
|
||||
extern crate raw_dylib_alt_calling_convention_test;
|
||||
|
||||
fn main() {
|
||||
raw_dylib_alt_calling_convention_test::library_function();
|
||||
raw_dylib_alt_calling_convention_test::library_function(
|
||||
std::env::args().skip(1).next().map_or(
|
||||
false,
|
||||
|s| std::str::FromStr::from_str(&s).unwrap()));
|
||||
}
|
||||
|
@ -121,3 +121,58 @@ __declspec(dllexport) void __fastcall fastcall_fn_9(uint8_t x, double y) {
|
||||
printf("fastcall_fn_9(%d, %.1f)\n", x, y);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
// GCC doesn't support vectorcall: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89485
|
||||
#ifdef _MSC_VER
|
||||
__declspec(dllexport) void __vectorcall vectorcall_fn_1(int i) {
|
||||
printf("vectorcall_fn_1(%d)\n", i);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
__declspec(dllexport) void __vectorcall vectorcall_fn_2(uint8_t i, float f) {
|
||||
printf("vectorcall_fn_2(%d, %.1f)\n", i, f);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
__declspec(dllexport) void __vectorcall vectorcall_fn_3(double d) {
|
||||
printf("vectorcall_fn_3(%.1f)\n", d);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
__declspec(dllexport) void __vectorcall vectorcall_fn_4(uint8_t i, uint8_t j, float f) {
|
||||
printf("vectorcall_fn_4(%d, %d, %.1f)\n", i, j, f);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
__declspec(dllexport) void __vectorcall vectorcall_fn_5(struct S s, int i) {
|
||||
printf("vectorcall_fn_5(S { x: %d, y: %d }, %d)\n", s.x, s.y, i);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
__declspec(dllexport) void __vectorcall vectorcall_fn_6(struct S* s) {
|
||||
if (s) {
|
||||
printf("vectorcall_fn_6(S { x: %d, y: %d })\n", s->x, s->y);
|
||||
} else {
|
||||
printf("vectorcall_fn_6(null)\n");
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
__declspec(dllexport) void __vectorcall vectorcall_fn_7(struct S2 s, int i) {
|
||||
printf("vectorcall_fn_7(S2 { x: %d, y: %d }, %d)\n", s.x, s.y, i);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
__declspec(dllexport) void __vectorcall vectorcall_fn_8(struct S3 s, struct S3 t) {
|
||||
printf("vectorcall_fn_8(S3 { x: [%d, %d, %d, %d, %d] }, S3 { x: [%d, %d, %d, %d, %d] })\n",
|
||||
s.x[0], s.x[1], s.x[2], s.x[3], s.x[4],
|
||||
t.x[0], t.x[1], t.x[2], t.x[3], t.x[4]
|
||||
);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
__declspec(dllexport) void __vectorcall vectorcall_fn_9(uint8_t x, double y) {
|
||||
printf("vectorcall_fn_9(%d, %.1f)\n", x, y);
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif
|
||||
|
@ -1,4 +1,5 @@
|
||||
#![feature(raw_dylib)]
|
||||
#![feature(abi_vectorcall)]
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone)]
|
||||
@ -46,29 +47,60 @@ extern "fastcall" {
|
||||
fn fastcall_fn_9(x: u8, y: f64);
|
||||
}
|
||||
|
||||
pub fn library_function() {
|
||||
unsafe {
|
||||
stdcall_fn_1(14);
|
||||
stdcall_fn_2(16, 3.5);
|
||||
stdcall_fn_3(3.5);
|
||||
stdcall_fn_4(1, 2, 3.0);
|
||||
stdcall_fn_5(S { x: 1, y: 2 }, 16);
|
||||
stdcall_fn_6(Some(&S { x: 10, y: 12 }));
|
||||
stdcall_fn_7(S2 { x: 15, y: 16 }, 3);
|
||||
stdcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] });
|
||||
stdcall_fn_9(1, 3.0);
|
||||
#[cfg(target_env = "msvc")]
|
||||
#[link(name = "extern", kind = "raw-dylib")]
|
||||
extern "vectorcall" {
|
||||
fn vectorcall_fn_1(i: i32);
|
||||
fn vectorcall_fn_2(c: u8, f: f32);
|
||||
fn vectorcall_fn_3(d: f64);
|
||||
fn vectorcall_fn_4(i: u8, j: u8, f: f32);
|
||||
fn vectorcall_fn_5(a: S, b: i32);
|
||||
fn vectorcall_fn_6(a: Option<&S>);
|
||||
fn vectorcall_fn_7(a: S2, b: i32);
|
||||
fn vectorcall_fn_8(a: S3, b: S3);
|
||||
fn vectorcall_fn_9(x: u8, y: f64);
|
||||
}
|
||||
|
||||
fastcall_fn_1(14);
|
||||
fastcall_fn_2(16, 3.5);
|
||||
fastcall_fn_3(3.5);
|
||||
fastcall_fn_4(1, 2, 3.0);
|
||||
// FIXME: 91167
|
||||
// rustc generates incorrect code for the calls to fastcall_fn_5 and fastcall_fn_7
|
||||
// on i686-pc-windows-gnu; commenting these out until the indicated issue is fixed.
|
||||
//fastcall_fn_5(S { x: 1, y: 2 }, 16);
|
||||
fastcall_fn_6(Some(&S { x: 10, y: 12 }));
|
||||
//fastcall_fn_7(S2 { x: 15, y: 16 }, 3);
|
||||
fastcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] });
|
||||
fastcall_fn_9(1, 3.0);
|
||||
pub fn library_function(run_msvc_only: bool) {
|
||||
unsafe {
|
||||
if !run_msvc_only {
|
||||
stdcall_fn_1(14);
|
||||
stdcall_fn_2(16, 3.5);
|
||||
stdcall_fn_3(3.5);
|
||||
stdcall_fn_4(1, 2, 3.0);
|
||||
stdcall_fn_5(S { x: 1, y: 2 }, 16);
|
||||
stdcall_fn_6(Some(&S { x: 10, y: 12 }));
|
||||
stdcall_fn_7(S2 { x: 15, y: 16 }, 3);
|
||||
stdcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] });
|
||||
stdcall_fn_9(1, 3.0);
|
||||
|
||||
fastcall_fn_1(14);
|
||||
fastcall_fn_2(16, 3.5);
|
||||
fastcall_fn_3(3.5);
|
||||
fastcall_fn_4(1, 2, 3.0);
|
||||
fastcall_fn_6(Some(&S { x: 10, y: 12 }));
|
||||
fastcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] });
|
||||
fastcall_fn_9(1, 3.0);
|
||||
} else {
|
||||
// FIXME: 91167
|
||||
// rustc generates incorrect code for the calls to fastcall_fn_5 and fastcall_fn_7
|
||||
// on i686-pc-windows-gnu; disabling these until the indicated issue is fixed.
|
||||
fastcall_fn_5(S { x: 1, y: 2 }, 16);
|
||||
fastcall_fn_7(S2 { x: 15, y: 16 }, 3);
|
||||
|
||||
// GCC doesn't support vectorcall: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89485
|
||||
#[cfg(target_env = "msvc")]
|
||||
{
|
||||
vectorcall_fn_1(14);
|
||||
vectorcall_fn_2(16, 3.5);
|
||||
vectorcall_fn_3(3.5);
|
||||
vectorcall_fn_4(1, 2, 3.0);
|
||||
vectorcall_fn_5(S { x: 1, y: 2 }, 16);
|
||||
vectorcall_fn_6(Some(&S { x: 10, y: 12 }));
|
||||
vectorcall_fn_7(S2 { x: 15, y: 16 }, 3);
|
||||
vectorcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] });
|
||||
vectorcall_fn_9(1, 3.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,11 @@
|
||||
fastcall_fn_5(S { x: 1, y: 2 }, 16)
|
||||
fastcall_fn_7(S2 { x: 15, y: 16 }, 3)
|
||||
vectorcall_fn_1(14)
|
||||
vectorcall_fn_2(16, 3.5)
|
||||
vectorcall_fn_3(3.5)
|
||||
vectorcall_fn_4(1, 2, 3.0)
|
||||
vectorcall_fn_5(S { x: 1, y: 2 }, 16)
|
||||
vectorcall_fn_6(S { x: 10, y: 12 })
|
||||
vectorcall_fn_7(S2 { x: 15, y: 16 }, 3)
|
||||
vectorcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] })
|
||||
vectorcall_fn_9(1, 3.0)
|
Loading…
Reference in New Issue
Block a user