Add tests for RISC-V C ABI
This commit is contained in:
parent
e590164175
commit
39633874ae
@ -168,6 +168,18 @@ struct floats {
|
||||
double c;
|
||||
};
|
||||
|
||||
struct char_char_double {
|
||||
uint8_t a;
|
||||
uint8_t b;
|
||||
double c;
|
||||
};
|
||||
|
||||
struct char_char_float {
|
||||
uint8_t a;
|
||||
uint8_t b;
|
||||
float c;
|
||||
};
|
||||
|
||||
struct quad
|
||||
rust_dbg_abi_1(struct quad q) {
|
||||
struct quad qq = { q.c + 1,
|
||||
@ -185,6 +197,23 @@ rust_dbg_abi_2(struct floats f) {
|
||||
return ff;
|
||||
}
|
||||
|
||||
struct char_char_double
|
||||
rust_dbg_abi_3(struct char_char_double a) {
|
||||
struct char_char_double ccd = { a.a + 1,
|
||||
a.b - 1,
|
||||
a.c + 1.0 };
|
||||
return ccd;
|
||||
}
|
||||
|
||||
struct char_char_float
|
||||
rust_dbg_abi_4(struct char_char_float a) {
|
||||
struct char_char_float ccd = { a.a + 1,
|
||||
a.b - 1,
|
||||
a.c + 1.0 };
|
||||
return ccd;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
rust_dbg_static_mut = 3;
|
||||
|
||||
|
181
src/test/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs
Normal file
181
src/test/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs
Normal file
@ -0,0 +1,181 @@
|
||||
// ignore-tidy-linelength
|
||||
// compile-flags: -C no-prepopulate-passes
|
||||
// only-riscv64
|
||||
// only-linux
|
||||
#![crate_type = "lib"]
|
||||
#![allow(improper_ctypes)]
|
||||
|
||||
// CHECK: define void @f_void()
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_void() {}
|
||||
|
||||
// CHECK: define zeroext i1 @f_scalar_0(i1 zeroext %a)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_scalar_0(a: bool) -> bool {
|
||||
a
|
||||
}
|
||||
|
||||
// CHECK: define signext i8 @f_scalar_1(i8 signext %x)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_scalar_1(x: i8) -> i8 {
|
||||
x
|
||||
}
|
||||
|
||||
// CHECK: define zeroext i8 @f_scalar_2(i8 zeroext %x)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_scalar_2(x: u8) -> u8 {
|
||||
x
|
||||
}
|
||||
|
||||
// CHECK: define signext i32 @f_scalar_3(i32 signext %x)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_scalar_3(x: i32) -> u32 {
|
||||
x as u32
|
||||
}
|
||||
|
||||
// CHECK: define i64 @f_scalar_4(i64 %x)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_scalar_4(x: i64) -> i64 {
|
||||
x
|
||||
}
|
||||
|
||||
// CHECK: define float @f_fp_scalar_1(float)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_fp_scalar_1(x: f32) -> f32 {
|
||||
x
|
||||
}
|
||||
// CHECK: define double @f_fp_scalar_2(double)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_fp_scalar_2(x: f64) -> f64 {
|
||||
x
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct Empty {}
|
||||
|
||||
// CHECK: define void @f_agg_empty_struct()
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_agg_empty_struct(e: Empty) -> Empty {
|
||||
e
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct Tiny {
|
||||
a: u16,
|
||||
b: u16,
|
||||
c: u16,
|
||||
d: u16,
|
||||
}
|
||||
|
||||
// CHECK: define void @f_agg_tiny(i64)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_agg_tiny(mut e: Tiny) {
|
||||
e.a += e.b;
|
||||
e.c += e.d;
|
||||
}
|
||||
|
||||
// CHECK: define i64 @f_agg_tiny_ret()
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_agg_tiny_ret() -> Tiny {
|
||||
Tiny { a: 1, b: 2, c: 3, d: 4 }
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct Small {
|
||||
a: i64,
|
||||
b: *mut i64,
|
||||
}
|
||||
|
||||
// CHECK: define void @f_agg_small([2 x i64])
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_agg_small(mut x: Small) {
|
||||
x.a += unsafe { *x.b };
|
||||
x.b = &mut x.a;
|
||||
}
|
||||
|
||||
// CHECK: define [2 x i64] @f_agg_small_ret()
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_agg_small_ret() -> Small {
|
||||
Small { a: 1, b: core::ptr::null_mut() }
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct SmallAligned {
|
||||
a: i128,
|
||||
}
|
||||
|
||||
// CHECK: define void @f_agg_small_aligned(i128)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_agg_small_aligned(mut x: SmallAligned) {
|
||||
x.a += x.a;
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct Large {
|
||||
a: i64,
|
||||
b: i64,
|
||||
c: i64,
|
||||
d: i64,
|
||||
}
|
||||
|
||||
// CHECK: define void @f_agg_large(%Large* {{.*}}%x)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_agg_large(mut x: Large) {
|
||||
x.a = x.b + x.c + x.d;
|
||||
}
|
||||
|
||||
// CHECK: define void @f_agg_large_ret(%Large* {{.*}}sret{{.*}}, i32 signext %i, i8 signext %j)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_agg_large_ret(i: i32, j: i8) -> Large {
|
||||
Large { a: 1, b: 2, c: 3, d: 4 }
|
||||
}
|
||||
|
||||
// CHECK: define void @f_scalar_stack_1(i64, [2 x i64], i128, %Large* {{.*}}%d, i8 zeroext %e, i8 signext %f, i8 %g, i8 %h)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_scalar_stack_1(
|
||||
a: Tiny,
|
||||
b: Small,
|
||||
c: SmallAligned,
|
||||
d: Large,
|
||||
e: u8,
|
||||
f: i8,
|
||||
g: u8,
|
||||
h: i8,
|
||||
) {
|
||||
}
|
||||
|
||||
// CHECK: define void @f_scalar_stack_2(%Large* {{.*}}sret{{.*}}, i64 %a, i128, i128, i64 %d, i8 zeroext %e, i8 %f, i8 %g)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_scalar_stack_2(
|
||||
a: u64,
|
||||
b: SmallAligned,
|
||||
c: SmallAligned,
|
||||
d: u64,
|
||||
e: u8,
|
||||
f: i8,
|
||||
g: u8,
|
||||
) -> Large {
|
||||
Large { a: a as i64, b: e as i64, c: f as i64, d: g as i64 }
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
fn f_va_callee(_: i32, ...) -> i32;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_va_caller() {
|
||||
// CHECK: call signext i32 (i32, ...) @f_va_callee(i32 signext 1, i32 signext 2, i64 3, double {{.*}}, double {{.*}}, i64 {{.*}}, [2 x i64] {{.*}}, i128 {{.*}}, %Large* {{.*}})
|
||||
f_va_callee(
|
||||
1,
|
||||
2i32,
|
||||
3i64,
|
||||
4.0f64,
|
||||
5.0f64,
|
||||
Tiny { a: 1, b: 2, c: 3, d: 4 },
|
||||
Small { a: 10, b: core::ptr::null_mut() },
|
||||
SmallAligned { a: 11 },
|
||||
Large { a: 12, b: 13, c: 14, d: 15 },
|
||||
);
|
||||
// CHECK: call signext i32 (i32, ...) @f_va_callee(i32 signext 1, i32 signext 2, i32 signext 3, i32 signext 4, i128 {{.*}}, i32 signext 6, i32 signext 7, i32 8, i32 9)
|
||||
f_va_callee(1, 2i32, 3i32, 4i32, SmallAligned { a: 5 }, 6i32, 7i32, 8i32, 9i32);
|
||||
}
|
293
src/test/codegen/riscv-abi/riscv64-lp64d-abi.rs
Normal file
293
src/test/codegen/riscv-abi/riscv64-lp64d-abi.rs
Normal file
@ -0,0 +1,293 @@
|
||||
// ignore-tidy-linelength
|
||||
// compile-flags: -C no-prepopulate-passes
|
||||
// only-riscv64
|
||||
// only-linux
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// CHECK: define void @f_fpr_tracking(double, double, double, double, double, double, double, double, i8 zeroext %i)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_fpr_tracking(
|
||||
a: f64,
|
||||
b: f64,
|
||||
c: f64,
|
||||
d: f64,
|
||||
e: f64,
|
||||
f: f64,
|
||||
g: f64,
|
||||
h: f64,
|
||||
i: u8,
|
||||
) {
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct Double {
|
||||
f: f64,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct DoubleDouble {
|
||||
f: f64,
|
||||
g: f64,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct DoubleFloat {
|
||||
f: f64,
|
||||
g: f32,
|
||||
}
|
||||
|
||||
// CHECK: define void @f_double_s_arg(double)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_double_s_arg(a: Double) {}
|
||||
|
||||
// CHECK: define double @f_ret_double_s()
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_ret_double_s() -> Double {
|
||||
Double { f: 1. }
|
||||
}
|
||||
|
||||
// CHECK: define void @f_double_double_s_arg({ double, double })
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_double_double_s_arg(a: DoubleDouble) {}
|
||||
|
||||
// CHECK: define { double, double } @f_ret_double_double_s()
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_ret_double_double_s() -> DoubleDouble {
|
||||
DoubleDouble { f: 1., g: 2. }
|
||||
}
|
||||
|
||||
// CHECK: define void @f_double_float_s_arg({ double, float })
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_double_float_s_arg(a: DoubleFloat) {}
|
||||
|
||||
// CHECK: define { double, float } @f_ret_double_float_s()
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_ret_double_float_s() -> DoubleFloat {
|
||||
DoubleFloat { f: 1., g: 2. }
|
||||
}
|
||||
|
||||
// CHECK: define void @f_double_double_s_arg_insufficient_fprs(double, double, double, double, double, double, double, [2 x i64])
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_double_double_s_arg_insufficient_fprs(
|
||||
a: f64,
|
||||
b: f64,
|
||||
c: f64,
|
||||
d: f64,
|
||||
e: f64,
|
||||
f: f64,
|
||||
g: f64,
|
||||
h: DoubleDouble,
|
||||
) {
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct DoubleInt8 {
|
||||
f: f64,
|
||||
i: i8,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct DoubleUInt8 {
|
||||
f: f64,
|
||||
i: u8,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct DoubleInt32 {
|
||||
f: f64,
|
||||
i: i32,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct DoubleInt64 {
|
||||
f: f64,
|
||||
i: i64,
|
||||
}
|
||||
|
||||
// CHECK: define void @f_double_int8_s_arg({ double, i8 })
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_double_int8_s_arg(a: DoubleInt8) {}
|
||||
|
||||
// CHECK: define { double, i8 } @f_ret_double_int8_s()
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_ret_double_int8_s() -> DoubleInt8 {
|
||||
DoubleInt8 { f: 1., i: 2 }
|
||||
}
|
||||
|
||||
// CHECK: define void @f_double_int32_s_arg({ double, i32 })
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_double_int32_s_arg(a: DoubleInt32) {}
|
||||
|
||||
// CHECK: define { double, i32 } @f_ret_double_int32_s()
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_ret_double_int32_s() -> DoubleInt32 {
|
||||
DoubleInt32 { f: 1., i: 2 }
|
||||
}
|
||||
|
||||
// CHECK: define void @f_double_uint8_s_arg({ double, i8 })
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_double_uint8_s_arg(a: DoubleUInt8) {}
|
||||
|
||||
// CHECK: define { double, i8 } @f_ret_double_uint8_s()
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_ret_double_uint8_s() -> DoubleUInt8 {
|
||||
DoubleUInt8 { f: 1., i: 2 }
|
||||
}
|
||||
|
||||
// CHECK: define void @f_double_int64_s_arg({ double, i64 })
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_double_int64_s_arg(a: DoubleInt64) {}
|
||||
|
||||
// CHECK: define { double, i64 } @f_ret_double_int64_s()
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_ret_double_int64_s() -> DoubleInt64 {
|
||||
DoubleInt64 { f: 1., i: 2 }
|
||||
}
|
||||
|
||||
// CHECK: define void @f_double_int8_s_arg_insufficient_gprs(i32 signext %a, i32 signext %b, i32 signext %c, i32 signext %d, i32 signext %e, i32 signext %f, i32 signext %g, i32 signext %h, [2 x i64])
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_double_int8_s_arg_insufficient_gprs(
|
||||
a: i32,
|
||||
b: i32,
|
||||
c: i32,
|
||||
d: i32,
|
||||
e: i32,
|
||||
f: i32,
|
||||
g: i32,
|
||||
h: i32,
|
||||
i: DoubleInt8,
|
||||
) {
|
||||
}
|
||||
|
||||
// CHECK: define void @f_struct_double_int8_insufficient_fprs(float, double, double, double, double, double, double, double, [2 x i64])
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_struct_double_int8_insufficient_fprs(
|
||||
a: f32,
|
||||
b: f64,
|
||||
c: f64,
|
||||
d: f64,
|
||||
e: f64,
|
||||
f: f64,
|
||||
g: f64,
|
||||
h: f64,
|
||||
i: DoubleInt8,
|
||||
) {
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct DoubleArr1 {
|
||||
a: [f64; 1],
|
||||
}
|
||||
|
||||
// CHECK: define void @f_doublearr1_s_arg(double)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_doublearr1_s_arg(a: DoubleArr1) {}
|
||||
|
||||
// CHECK: define double @f_ret_doublearr1_s()
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_ret_doublearr1_s() -> DoubleArr1 {
|
||||
DoubleArr1 { a: [1.] }
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct DoubleArr2 {
|
||||
a: [f64; 2],
|
||||
}
|
||||
|
||||
// CHECK: define void @f_doublearr2_s_arg({ double, double })
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_doublearr2_s_arg(a: DoubleArr2) {}
|
||||
|
||||
// CHECK: define { double, double } @f_ret_doublearr2_s()
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_ret_doublearr2_s() -> DoubleArr2 {
|
||||
DoubleArr2 { a: [1., 2.] }
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct Tricky1 {
|
||||
f: [f64; 1],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct DoubleArr2Tricky1 {
|
||||
g: [Tricky1; 2],
|
||||
}
|
||||
|
||||
// CHECK: define void @f_doublearr2_tricky1_s_arg({ double, double })
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_doublearr2_tricky1_s_arg(a: DoubleArr2Tricky1) {}
|
||||
|
||||
// CHECK: define { double, double } @f_ret_doublearr2_tricky1_s()
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_ret_doublearr2_tricky1_s() -> DoubleArr2Tricky1 {
|
||||
DoubleArr2Tricky1 { g: [Tricky1 { f: [1.] }, Tricky1 { f: [2.] }] }
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct EmptyStruct {}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct DoubleArr2Tricky2 {
|
||||
s: EmptyStruct,
|
||||
g: [Tricky1; 2],
|
||||
}
|
||||
|
||||
// CHECK: define void @f_doublearr2_tricky2_s_arg({ double, double })
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_doublearr2_tricky2_s_arg(a: DoubleArr2Tricky2) {}
|
||||
|
||||
// CHECK: define { double, double } @f_ret_doublearr2_tricky2_s()
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_ret_doublearr2_tricky2_s() -> DoubleArr2Tricky2 {
|
||||
DoubleArr2Tricky2 { s: EmptyStruct {}, g: [Tricky1 { f: [1.] }, Tricky1 { f: [2.] }] }
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct IntDoubleInt {
|
||||
a: i32,
|
||||
b: f64,
|
||||
c: i32,
|
||||
}
|
||||
|
||||
// CHECK: define void @f_int_double_int_s_arg(%IntDoubleInt* {{.*}}%a)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_int_double_int_s_arg(a: IntDoubleInt) {}
|
||||
|
||||
// CHECK: define void @f_ret_int_double_int_s(%IntDoubleInt* {{.*}}sret
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_ret_int_double_int_s() -> IntDoubleInt {
|
||||
IntDoubleInt { a: 1, b: 2., c: 3 }
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct CharCharDouble {
|
||||
a: u8,
|
||||
b: u8,
|
||||
c: f64,
|
||||
}
|
||||
|
||||
// CHECK: define void @f_char_char_double_s_arg([2 x i64])
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_char_char_double_s_arg(a: CharCharDouble) {}
|
||||
|
||||
// CHECK: define [2 x i64] @f_ret_char_char_double_s()
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_ret_char_char_double_s() -> CharCharDouble {
|
||||
CharCharDouble { a: 1, b: 2, c: 3. }
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub union DoubleU {
|
||||
a: f64,
|
||||
}
|
||||
|
||||
// CHECK: define void @f_double_u_arg(i64)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_double_u_arg(a: DoubleU) {}
|
||||
|
||||
// CHECK: define i64 @f_ret_double_u()
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_ret_double_u() -> DoubleU {
|
||||
unsafe { DoubleU { a: 1. } }
|
||||
}
|
277
src/test/codegen/riscv-abi/riscv64-lp64f-lp64d-abi.rs
Normal file
277
src/test/codegen/riscv-abi/riscv64-lp64f-lp64d-abi.rs
Normal file
@ -0,0 +1,277 @@
|
||||
// ignore-tidy-linelength
|
||||
// compile-flags: -C no-prepopulate-passes
|
||||
// only-riscv64
|
||||
// only-linux
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// CHECK: define void @f_fpr_tracking(float, float, float, float, float, float, float, float, i8 zeroext %i)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_fpr_tracking(
|
||||
a: f32,
|
||||
b: f32,
|
||||
c: f32,
|
||||
d: f32,
|
||||
e: f32,
|
||||
f: f32,
|
||||
g: f32,
|
||||
h: f32,
|
||||
i: u8,
|
||||
) {
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct Float {
|
||||
f: f32,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct FloatFloat {
|
||||
f: f32,
|
||||
g: f32,
|
||||
}
|
||||
|
||||
// CHECK: define void @f_float_s_arg(float)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_float_s_arg(a: Float) {}
|
||||
|
||||
// CHECK: define float @f_ret_float_s()
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_ret_float_s() -> Float {
|
||||
Float { f: 1. }
|
||||
}
|
||||
|
||||
// CHECK: define void @f_float_float_s_arg({ float, float })
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_float_float_s_arg(a: FloatFloat) {}
|
||||
|
||||
// CHECK: define { float, float } @f_ret_float_float_s()
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_ret_float_float_s() -> FloatFloat {
|
||||
FloatFloat { f: 1., g: 2. }
|
||||
}
|
||||
|
||||
// CHECK: define void @f_float_float_s_arg_insufficient_fprs(float, float, float, float, float, float, float, i64)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_float_float_s_arg_insufficient_fprs(
|
||||
a: f32,
|
||||
b: f32,
|
||||
c: f32,
|
||||
d: f32,
|
||||
e: f32,
|
||||
f: f32,
|
||||
g: f32,
|
||||
h: FloatFloat,
|
||||
) {
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct FloatInt8 {
|
||||
f: f32,
|
||||
i: i8,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct FloatUInt8 {
|
||||
f: f32,
|
||||
i: u8,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct FloatInt32 {
|
||||
f: f32,
|
||||
i: i32,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct FloatInt64 {
|
||||
f: f32,
|
||||
i: i64,
|
||||
}
|
||||
|
||||
// CHECK: define void @f_float_int8_s_arg({ float, i8 })
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_float_int8_s_arg(a: FloatInt8) {}
|
||||
|
||||
// CHECK: define { float, i8 } @f_ret_float_int8_s()
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_ret_float_int8_s() -> FloatInt8 {
|
||||
FloatInt8 { f: 1., i: 2 }
|
||||
}
|
||||
|
||||
// CHECK: define void @f_float_int32_s_arg({ float, i32 })
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_float_int32_s_arg(a: FloatInt32) {}
|
||||
|
||||
// CHECK: define { float, i32 } @f_ret_float_int32_s()
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_ret_float_int32_s() -> FloatInt32 {
|
||||
FloatInt32 { f: 1., i: 2 }
|
||||
}
|
||||
|
||||
// CHECK: define void @f_float_uint8_s_arg({ float, i8 })
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_float_uint8_s_arg(a: FloatUInt8) {}
|
||||
|
||||
// CHECK: define { float, i8 } @f_ret_float_uint8_s()
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_ret_float_uint8_s() -> FloatUInt8 {
|
||||
FloatUInt8 { f: 1., i: 2 }
|
||||
}
|
||||
|
||||
// CHECK: define void @f_float_int64_s_arg({ float, i64 })
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_float_int64_s_arg(a: FloatInt64) {}
|
||||
|
||||
// CHECK: define { float, i64 } @f_ret_float_int64_s()
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_ret_float_int64_s() -> FloatInt64 {
|
||||
FloatInt64 { f: 1., i: 2 }
|
||||
}
|
||||
|
||||
// CHECK: define void @f_float_int8_s_arg_insufficient_gprs(i32 signext %a, i32 signext %b, i32 signext %c, i32 signext %d, i32 signext %e, i32 signext %f, i32 signext %g, i32 signext %h, i64)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_float_int8_s_arg_insufficient_gprs(
|
||||
a: i32,
|
||||
b: i32,
|
||||
c: i32,
|
||||
d: i32,
|
||||
e: i32,
|
||||
f: i32,
|
||||
g: i32,
|
||||
h: i32,
|
||||
i: FloatInt8,
|
||||
) {
|
||||
}
|
||||
|
||||
// CHECK: define void @f_struct_float_int8_insufficient_fprs(float, float, float, float, float, float, float, float, i64)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_struct_float_int8_insufficient_fprs(
|
||||
a: f32,
|
||||
b: f32,
|
||||
c: f32,
|
||||
d: f32,
|
||||
e: f32,
|
||||
f: f32,
|
||||
g: f32,
|
||||
h: f32,
|
||||
i: FloatInt8,
|
||||
) {
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct FloatArr1 {
|
||||
a: [f32; 1],
|
||||
}
|
||||
|
||||
// CHECK: define void @f_floatarr1_s_arg(float)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_floatarr1_s_arg(a: FloatArr1) {}
|
||||
|
||||
// CHECK: define float @f_ret_floatarr1_s()
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_ret_floatarr1_s() -> FloatArr1 {
|
||||
FloatArr1 { a: [1.] }
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct FloatArr2 {
|
||||
a: [f32; 2],
|
||||
}
|
||||
|
||||
// CHECK: define void @f_floatarr2_s_arg({ float, float })
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_floatarr2_s_arg(a: FloatArr2) {}
|
||||
|
||||
// CHECK: define { float, float } @f_ret_floatarr2_s()
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_ret_floatarr2_s() -> FloatArr2 {
|
||||
FloatArr2 { a: [1., 2.] }
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct Tricky1 {
|
||||
f: [f32; 1],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct FloatArr2Tricky1 {
|
||||
g: [Tricky1; 2],
|
||||
}
|
||||
|
||||
// CHECK: define void @f_floatarr2_tricky1_s_arg({ float, float })
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_floatarr2_tricky1_s_arg(a: FloatArr2Tricky1) {}
|
||||
|
||||
// CHECK: define { float, float } @f_ret_floatarr2_tricky1_s()
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_ret_floatarr2_tricky1_s() -> FloatArr2Tricky1 {
|
||||
FloatArr2Tricky1 { g: [Tricky1 { f: [1.] }, Tricky1 { f: [2.] }] }
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct EmptyStruct {}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct FloatArr2Tricky2 {
|
||||
s: EmptyStruct,
|
||||
g: [Tricky1; 2],
|
||||
}
|
||||
|
||||
// CHECK: define void @f_floatarr2_tricky2_s_arg({ float, float })
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_floatarr2_tricky2_s_arg(a: FloatArr2Tricky2) {}
|
||||
|
||||
// CHECK: define { float, float } @f_ret_floatarr2_tricky2_s()
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_ret_floatarr2_tricky2_s() -> FloatArr2Tricky2 {
|
||||
FloatArr2Tricky2 { s: EmptyStruct {}, g: [Tricky1 { f: [1.] }, Tricky1 { f: [2.] }] }
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct IntFloatInt {
|
||||
a: i32,
|
||||
b: f32,
|
||||
c: i32,
|
||||
}
|
||||
|
||||
// CHECK: define void @f_int_float_int_s_arg([2 x i64])
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_int_float_int_s_arg(a: IntFloatInt) {}
|
||||
|
||||
// CHECK: define [2 x i64] @f_ret_int_float_int_s()
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_ret_int_float_int_s() -> IntFloatInt {
|
||||
IntFloatInt { a: 1, b: 2., c: 3 }
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct CharCharFloat {
|
||||
a: u8,
|
||||
b: u8,
|
||||
c: f32,
|
||||
}
|
||||
|
||||
// CHECK: define void @f_char_char_float_s_arg(i64)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_char_char_float_s_arg(a: CharCharFloat) {}
|
||||
|
||||
// CHECK: define i64 @f_ret_char_char_float_s()
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_ret_char_char_float_s() -> CharCharFloat {
|
||||
CharCharFloat { a: 1, b: 2, c: 3. }
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub union FloatU {
|
||||
a: f32,
|
||||
}
|
||||
|
||||
// CHECK: define void @f_float_u_arg(i64)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_float_u_arg(a: FloatU) {}
|
||||
|
||||
// CHECK: define i64 @f_ret_float_u()
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_ret_float_u() -> FloatU {
|
||||
unsafe { FloatU { a: 1. } }
|
||||
}
|
@ -10,13 +10,23 @@ pub struct Quad { a: u64, b: u64, c: u64, d: u64 }
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Floats { a: f64, b: u8, c: f64 }
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct CharCharDouble { a: u8, b: u8, c: f64 }
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct CharCharFloat { a: u8, b: u8, c: f32 }
|
||||
|
||||
mod rustrt {
|
||||
use super::{Floats, Quad};
|
||||
use super::{Floats, Quad, CharCharDouble, CharCharFloat};
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_abi_1(q: Quad) -> Quad;
|
||||
pub fn rust_dbg_abi_2(f: Floats) -> Floats;
|
||||
pub fn rust_dbg_abi_3(a: CharCharDouble) -> CharCharDouble;
|
||||
pub fn rust_dbg_abi_4(a: CharCharFloat) -> CharCharFloat;
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,7 +68,47 @@ fn test2() {
|
||||
fn test2() {
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
fn test3() {
|
||||
unsafe {
|
||||
let a = CharCharDouble {
|
||||
a: 1,
|
||||
b: 2,
|
||||
c: 3.,
|
||||
};
|
||||
let b = rustrt::rust_dbg_abi_3(a);
|
||||
println!("a: {}", b.a);
|
||||
println!("b: {}", b.b);
|
||||
println!("c: {}", b.c);
|
||||
assert_eq!(b.a, a.a + 1);
|
||||
assert_eq!(b.b, a.b - 1);
|
||||
assert_eq!(b.c, a.c + 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
fn test3() {}
|
||||
|
||||
fn test4() {
|
||||
unsafe {
|
||||
let a = CharCharFloat {
|
||||
a: 1,
|
||||
b: 2,
|
||||
c: 3.,
|
||||
};
|
||||
let b = rustrt::rust_dbg_abi_4(a);
|
||||
println!("a: {}", b.a);
|
||||
println!("b: {}", b.b);
|
||||
println!("c: {}", b.c);
|
||||
assert_eq!(b.a, a.a + 1);
|
||||
assert_eq!(b.b, a.b - 1);
|
||||
assert_eq!(b.c, a.c + 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
test1();
|
||||
test2();
|
||||
test3();
|
||||
test4();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user