Merge pull request #1879 from heiher/loong-simd-unified-types
loongarch: Use unified data types for SIMD intrinsics
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,33 +1,140 @@
|
||||
types! {
|
||||
#![unstable(feature = "stdarch_loongarch", issue = "117427")]
|
||||
|
||||
/// LOONGARCH-specific 256-bit wide vector of 32 packed `i8`.
|
||||
pub struct v32i8(32 x pub(crate) i8);
|
||||
/// 256-bit wide integer vector type, LoongArch-specific
|
||||
///
|
||||
/// This type is the same as the `__m256i` type defined in `lasxintrin.h`,
|
||||
/// representing a 256-bit SIMD register. Usage of this type typically
|
||||
/// occurs in conjunction with the `lasx` target features for LoongArch.
|
||||
///
|
||||
/// Internally this type may be viewed as:
|
||||
///
|
||||
/// * `i8x32` - thirty two `i8` values packed together
|
||||
/// * `i16x16` - sixteen `i16` values packed together
|
||||
/// * `i32x8` - eight `i32` values packed together
|
||||
/// * `i64x4` - four `i64` values packed together
|
||||
///
|
||||
/// (as well as unsigned versions). Each intrinsic may interpret the
|
||||
/// internal bits differently, check the documentation of the intrinsic
|
||||
/// to see how it's being used.
|
||||
///
|
||||
/// The in-memory representation of this type is the same as the one of an
|
||||
/// equivalent array (i.e. the in-memory order of elements is the same, and
|
||||
/// there is no padding); however, the alignment is different and equal to
|
||||
/// the size of the type. Note that the ABI for function calls may *not* be
|
||||
/// the same.
|
||||
///
|
||||
/// Note that this means that an instance of `m256i` typically just means
|
||||
/// a "bag of bits" which is left up to interpretation at the point of use.
|
||||
///
|
||||
/// Most intrinsics using `m256i` are prefixed with `lasx_` and the integer
|
||||
/// types tend to correspond to suffixes like "b", "h", "w" or "d".
|
||||
pub struct m256i(4 x i64);
|
||||
|
||||
/// LOONGARCH-specific 256-bit wide vector of 16 packed `i16`.
|
||||
pub struct v16i16(16 x pub(crate) i16);
|
||||
/// 256-bit wide set of eight `f32` values, LoongArch-specific
|
||||
///
|
||||
/// This type is the same as the `__m256` type defined in `lasxintrin.h`,
|
||||
/// representing a 256-bit SIMD register which internally consists of
|
||||
/// eight packed `f32` instances. Usage of this type typically occurs in
|
||||
/// conjunction with the `lasx` target features for LoongArch.
|
||||
///
|
||||
/// Note that unlike `m256i`, the integer version of the 256-bit registers,
|
||||
/// this `m256` type has *one* interpretation. Each instance of `m256`
|
||||
/// always corresponds to `f32x8`, or eight `f32` values packed together.
|
||||
///
|
||||
/// The in-memory representation of this type is the same as the one of an
|
||||
/// equivalent array (i.e. the in-memory order of elements is the same, and
|
||||
/// there is no padding between two consecutive elements); however, the
|
||||
/// alignment is different and equal to the size of the type. Note that the
|
||||
/// ABI for function calls may *not* be the same.
|
||||
///
|
||||
/// Most intrinsics using `m256` are prefixed with `lasx_` and are
|
||||
/// suffixed with "s".
|
||||
pub struct m256(8 x f32);
|
||||
|
||||
/// LOONGARCH-specific 256-bit wide vector of 8 packed `i32`.
|
||||
pub struct v8i32(8 x pub(crate) i32);
|
||||
/// 256-bit wide set of four `f64` values, LoongArch-specific
|
||||
///
|
||||
/// This type is the same as the `__m256d` type defined in `lasxintrin.h`,
|
||||
/// representing a 256-bit SIMD register which internally consists of
|
||||
/// four packed `f64` instances. Usage of this type typically occurs in
|
||||
/// conjunction with the `lasx` target features for LoongArch.
|
||||
///
|
||||
/// Note that unlike `m256i`, the integer version of the 256-bit registers,
|
||||
/// this `m256d` type has *one* interpretation. Each instance of `m256d`
|
||||
/// always corresponds to `f64x4`, or four `f64` values packed together.
|
||||
///
|
||||
/// The in-memory representation of this type is the same as the one of an
|
||||
/// equivalent array (i.e. the in-memory order of elements is the same, and
|
||||
/// there is no padding); however, the alignment is different and equal to
|
||||
/// the size of the type. Note that the ABI for function calls may *not* be
|
||||
/// the same.
|
||||
///
|
||||
/// Most intrinsics using `m256d` are prefixed with `lasx_` and are suffixed
|
||||
/// with "d". Not to be confused with "d" which is used for `m256i`.
|
||||
pub struct m256d(4 x f64);
|
||||
|
||||
/// LOONGARCH-specific 256-bit wide vector of 4 packed `i64`.
|
||||
pub struct v4i64(4 x pub(crate) i64);
|
||||
|
||||
/// LOONGARCH-specific 256-bit wide vector of 32 packed `u8`.
|
||||
pub struct v32u8(32 x pub(crate) u8);
|
||||
|
||||
/// LOONGARCH-specific 256-bit wide vector of 16 packed `u16`.
|
||||
pub struct v16u16(16 x pub(crate) u16);
|
||||
|
||||
/// LOONGARCH-specific 256-bit wide vector of 8 packed `u32`.
|
||||
pub struct v8u32(8 x pub(crate) u32);
|
||||
|
||||
/// LOONGARCH-specific 256-bit wide vector of 4 packed `u64`.
|
||||
pub struct v4u64(4 x pub(crate) u64);
|
||||
|
||||
/// LOONGARCH-specific 128-bit wide vector of 8 packed `f32`.
|
||||
pub struct v8f32(8 x pub(crate) f32);
|
||||
|
||||
/// LOONGARCH-specific 256-bit wide vector of 4 packed `f64`.
|
||||
pub struct v4f64(4 x pub(crate) f64);
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(simd)]
|
||||
pub(crate) struct __v32i8([i8; 32]);
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(simd)]
|
||||
pub(crate) struct __v16i16([i16; 16]);
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(simd)]
|
||||
pub(crate) struct __v8i32([i32; 8]);
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(simd)]
|
||||
pub(crate) struct __v4i64([i64; 4]);
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(simd)]
|
||||
pub(crate) struct __v32u8([u8; 32]);
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(simd)]
|
||||
pub(crate) struct __v16u16([u16; 16]);
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(simd)]
|
||||
pub(crate) struct __v8u32([u32; 8]);
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(simd)]
|
||||
pub(crate) struct __v4u64([u64; 4]);
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(simd)]
|
||||
pub(crate) struct __v8f32([f32; 8]);
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(simd)]
|
||||
pub(crate) struct __v4f64([f64; 4]);
|
||||
|
||||
// These type aliases are provided solely for transitional compatibility.
|
||||
// They are temporary and will be removed when appropriate.
|
||||
#[allow(non_camel_case_types)]
|
||||
#[unstable(feature = "stdarch_loongarch", issue = "117427")]
|
||||
pub type v32i8 = m256i;
|
||||
#[allow(non_camel_case_types)]
|
||||
#[unstable(feature = "stdarch_loongarch", issue = "117427")]
|
||||
pub type v16i16 = m256i;
|
||||
#[allow(non_camel_case_types)]
|
||||
#[unstable(feature = "stdarch_loongarch", issue = "117427")]
|
||||
pub type v8i32 = m256i;
|
||||
#[allow(non_camel_case_types)]
|
||||
#[unstable(feature = "stdarch_loongarch", issue = "117427")]
|
||||
pub type v4i64 = m256i;
|
||||
#[allow(non_camel_case_types)]
|
||||
#[unstable(feature = "stdarch_loongarch", issue = "117427")]
|
||||
pub type v32u8 = m256i;
|
||||
#[allow(non_camel_case_types)]
|
||||
#[unstable(feature = "stdarch_loongarch", issue = "117427")]
|
||||
pub type v16u16 = m256i;
|
||||
#[allow(non_camel_case_types)]
|
||||
#[unstable(feature = "stdarch_loongarch", issue = "117427")]
|
||||
pub type v8u32 = m256i;
|
||||
#[allow(non_camel_case_types)]
|
||||
#[unstable(feature = "stdarch_loongarch", issue = "117427")]
|
||||
pub type v4u64 = m256i;
|
||||
#[allow(non_camel_case_types)]
|
||||
#[unstable(feature = "stdarch_loongarch", issue = "117427")]
|
||||
pub type v8f32 = m256;
|
||||
#[allow(non_camel_case_types)]
|
||||
#[unstable(feature = "stdarch_loongarch", issue = "117427")]
|
||||
pub type v4f64 = m256d;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,33 +1,140 @@
|
||||
types! {
|
||||
#![unstable(feature = "stdarch_loongarch", issue = "117427")]
|
||||
|
||||
/// LOONGARCH-specific 128-bit wide vector of 16 packed `i8`.
|
||||
pub struct v16i8(16 x pub(crate) i8);
|
||||
/// 128-bit wide integer vector type, LoongArch-specific
|
||||
///
|
||||
/// This type is the same as the `__m128i` type defined in `lsxintrin.h`,
|
||||
/// representing a 128-bit SIMD register. Usage of this type typically
|
||||
/// occurs in conjunction with the `lsx` and higher target features for
|
||||
/// LoongArch.
|
||||
///
|
||||
/// Internally this type may be viewed as:
|
||||
///
|
||||
/// * `i8x16` - sixteen `i8` values packed together
|
||||
/// * `i16x8` - eight `i16` values packed together
|
||||
/// * `i32x4` - four `i32` values packed together
|
||||
/// * `i64x2` - two `i64` values packed together
|
||||
///
|
||||
/// (as well as unsigned versions). Each intrinsic may interpret the
|
||||
/// internal bits differently, check the documentation of the intrinsic
|
||||
/// to see how it's being used.
|
||||
///
|
||||
/// The in-memory representation of this type is the same as the one of an
|
||||
/// equivalent array (i.e. the in-memory order of elements is the same, and
|
||||
/// there is no padding); however, the alignment is different and equal to
|
||||
/// the size of the type. Note that the ABI for function calls may *not* be
|
||||
/// the same.
|
||||
///
|
||||
/// Note that this means that an instance of `m128i` typically just means
|
||||
/// a "bag of bits" which is left up to interpretation at the point of use.
|
||||
///
|
||||
/// Most intrinsics using `m128i` are prefixed with `lsx_` and the integer
|
||||
/// types tend to correspond to suffixes like "b", "h", "w" or "d".
|
||||
pub struct m128i(2 x i64);
|
||||
|
||||
/// LOONGARCH-specific 128-bit wide vector of 8 packed `i16`.
|
||||
pub struct v8i16(8 x pub(crate) i16);
|
||||
/// 128-bit wide set of four `f32` values, LoongArch-specific
|
||||
///
|
||||
/// This type is the same as the `__m128` type defined in `lsxintrin.h`,
|
||||
/// representing a 128-bit SIMD register which internally consists of
|
||||
/// four packed `f32` instances. Usage of this type typically occurs in
|
||||
/// conjunction with the `lsx` and higher target features for LoongArch.
|
||||
///
|
||||
/// Note that unlike `m128i`, the integer version of the 128-bit registers,
|
||||
/// this `m128` type has *one* interpretation. Each instance of `m128`
|
||||
/// corresponds to `f32x4`, or four `f32` values packed together.
|
||||
///
|
||||
/// The in-memory representation of this type is the same as the one of an
|
||||
/// equivalent array (i.e. the in-memory order of elements is the same, and
|
||||
/// there is no padding); however, the alignment is different and equal to
|
||||
/// the size of the type. Note that the ABI for function calls may *not* be
|
||||
/// the same.
|
||||
///
|
||||
/// Most intrinsics using `m128` are prefixed with `lsx_` and are suffixed
|
||||
/// with "s".
|
||||
pub struct m128(4 x f32);
|
||||
|
||||
/// LOONGARCH-specific 128-bit wide vector of 4 packed `i32`.
|
||||
pub struct v4i32(4 x pub(crate) i32);
|
||||
|
||||
/// LOONGARCH-specific 128-bit wide vector of 2 packed `i64`.
|
||||
pub struct v2i64(2 x pub(crate) i64);
|
||||
|
||||
/// LOONGARCH-specific 128-bit wide vector of 16 packed `u8`.
|
||||
pub struct v16u8(16 x pub(crate) u8);
|
||||
|
||||
/// LOONGARCH-specific 128-bit wide vector of 8 packed `u16`.
|
||||
pub struct v8u16(8 x pub(crate) u16);
|
||||
|
||||
/// LOONGARCH-specific 128-bit wide vector of 4 packed `u32`.
|
||||
pub struct v4u32(4 x pub(crate) u32);
|
||||
|
||||
/// LOONGARCH-specific 128-bit wide vector of 2 packed `u64`.
|
||||
pub struct v2u64(2 x pub(crate) u64);
|
||||
|
||||
/// LOONGARCH-specific 128-bit wide vector of 4 packed `f32`.
|
||||
pub struct v4f32(4 x pub(crate) f32);
|
||||
|
||||
/// LOONGARCH-specific 128-bit wide vector of 2 packed `f64`.
|
||||
pub struct v2f64(2 x pub(crate) f64);
|
||||
/// 128-bit wide set of two `f64` values, LoongArch-specific
|
||||
///
|
||||
/// This type is the same as the `__m128d` type defined in `lsxintrin.h`,
|
||||
/// representing a 128-bit SIMD register which internally consists of
|
||||
/// two packed `f64` instances. Usage of this type typically occurs in
|
||||
/// conjunction with the `lsx` and higher target features for LoongArch.
|
||||
///
|
||||
/// Note that unlike `m128i`, the integer version of the 128-bit registers,
|
||||
/// this `m128d` type has *one* interpretation. Each instance of `m128d`
|
||||
/// always corresponds to `f64x2`, or two `f64` values packed together.
|
||||
///
|
||||
/// The in-memory representation of this type is the same as the one of an
|
||||
/// equivalent array (i.e. the in-memory order of elements is the same, and
|
||||
/// there is no padding); however, the alignment is different and equal to
|
||||
/// the size of the type. Note that the ABI for function calls may *not* be
|
||||
/// the same.
|
||||
///
|
||||
/// Most intrinsics using `m128d` are prefixed with `lsx_` and are suffixed
|
||||
/// with "d". Not to be confused with "d" which is used for `m128i`.
|
||||
pub struct m128d(2 x f64);
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(simd)]
|
||||
pub(crate) struct __v16i8([i8; 16]);
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(simd)]
|
||||
pub(crate) struct __v8i16([i16; 8]);
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(simd)]
|
||||
pub(crate) struct __v4i32([i32; 4]);
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(simd)]
|
||||
pub(crate) struct __v2i64([i64; 2]);
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(simd)]
|
||||
pub(crate) struct __v16u8([u8; 16]);
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(simd)]
|
||||
pub(crate) struct __v8u16([u16; 8]);
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(simd)]
|
||||
pub(crate) struct __v4u32([u32; 4]);
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(simd)]
|
||||
pub(crate) struct __v2u64([u64; 2]);
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(simd)]
|
||||
pub(crate) struct __v4f32([f32; 4]);
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(simd)]
|
||||
pub(crate) struct __v2f64([f64; 2]);
|
||||
|
||||
// These type aliases are provided solely for transitional compatibility.
|
||||
// They are temporary and will be removed when appropriate.
|
||||
#[allow(non_camel_case_types)]
|
||||
#[unstable(feature = "stdarch_loongarch", issue = "117427")]
|
||||
pub type v16i8 = m128i;
|
||||
#[allow(non_camel_case_types)]
|
||||
#[unstable(feature = "stdarch_loongarch", issue = "117427")]
|
||||
pub type v8i16 = m128i;
|
||||
#[allow(non_camel_case_types)]
|
||||
#[unstable(feature = "stdarch_loongarch", issue = "117427")]
|
||||
pub type v4i32 = m128i;
|
||||
#[allow(non_camel_case_types)]
|
||||
#[unstable(feature = "stdarch_loongarch", issue = "117427")]
|
||||
pub type v2i64 = m128i;
|
||||
#[allow(non_camel_case_types)]
|
||||
#[unstable(feature = "stdarch_loongarch", issue = "117427")]
|
||||
pub type v16u8 = m128i;
|
||||
#[allow(non_camel_case_types)]
|
||||
#[unstable(feature = "stdarch_loongarch", issue = "117427")]
|
||||
pub type v8u16 = m128i;
|
||||
#[allow(non_camel_case_types)]
|
||||
#[unstable(feature = "stdarch_loongarch", issue = "117427")]
|
||||
pub type v4u32 = m128i;
|
||||
#[allow(non_camel_case_types)]
|
||||
#[unstable(feature = "stdarch_loongarch", issue = "117427")]
|
||||
pub type v2u64 = m128i;
|
||||
#[allow(non_camel_case_types)]
|
||||
#[unstable(feature = "stdarch_loongarch", issue = "117427")]
|
||||
pub type v4f32 = m128;
|
||||
#[allow(non_camel_case_types)]
|
||||
#[unstable(feature = "stdarch_loongarch", issue = "117427")]
|
||||
pub type v2f64 = m128d;
|
||||
|
||||
@@ -156,6 +156,7 @@ fn gen_bind(in_file: String, ext_name: &str) -> io::Result<()> {
|
||||
// OUT_DIR=`pwd`/crates/core_arch cargo run -p stdarch-gen-loongarch -- {in_file}
|
||||
// ```
|
||||
|
||||
use crate::mem::transmute;
|
||||
use super::types::*;
|
||||
"#
|
||||
));
|
||||
@@ -239,38 +240,63 @@ fn gen_bind_body(
|
||||
para_num: i32,
|
||||
target: TargetFeature,
|
||||
) -> (String, String) {
|
||||
let type_to_rst = |t: &str, s: bool| -> &str {
|
||||
match (t, s) {
|
||||
("V16QI", _) => "v16i8",
|
||||
("V32QI", _) => "v32i8",
|
||||
("V8HI", _) => "v8i16",
|
||||
("V16HI", _) => "v16i16",
|
||||
("V4SI", _) => "v4i32",
|
||||
("V8SI", _) => "v8i32",
|
||||
("V2DI", _) => "v2i64",
|
||||
("V4DI", _) => "v4i64",
|
||||
("UV16QI", _) => "v16u8",
|
||||
("UV32QI", _) => "v32u8",
|
||||
("UV8HI", _) => "v8u16",
|
||||
("UV16HI", _) => "v16u16",
|
||||
("UV4SI", _) => "v4u32",
|
||||
("UV8SI", _) => "v8u32",
|
||||
("UV2DI", _) => "v2u64",
|
||||
("UV4DI", _) => "v4u64",
|
||||
("SI", _) => "i32",
|
||||
("DI", _) => "i64",
|
||||
("USI", _) => "u32",
|
||||
("UDI", _) => "u64",
|
||||
("V4SF", _) => "v4f32",
|
||||
("V8SF", _) => "v8f32",
|
||||
("V2DF", _) => "v2f64",
|
||||
("V4DF", _) => "v4f64",
|
||||
("UQI", _) => "u32",
|
||||
("QI", _) => "i32",
|
||||
("CVPOINTER", false) => "*const i8",
|
||||
("CVPOINTER", true) => "*mut i8",
|
||||
("HI", _) => "i32",
|
||||
(_, _) => panic!("unknown type: {t}"),
|
||||
enum TypeKind {
|
||||
Vector,
|
||||
Intrinsic,
|
||||
}
|
||||
use TypeKind::*;
|
||||
let type_to_rst = |t: &str, s: bool, k: TypeKind| -> &str {
|
||||
match (t, s, k) {
|
||||
("V16QI", _, Vector) => "__v16i8",
|
||||
("V16QI", _, Intrinsic) => "m128i",
|
||||
("V32QI", _, Vector) => "__v32i8",
|
||||
("V32QI", _, Intrinsic) => "m256i",
|
||||
("V8HI", _, Vector) => "__v8i16",
|
||||
("V8HI", _, Intrinsic) => "m128i",
|
||||
("V16HI", _, Vector) => "__v16i16",
|
||||
("V16HI", _, Intrinsic) => "m256i",
|
||||
("V4SI", _, Vector) => "__v4i32",
|
||||
("V4SI", _, Intrinsic) => "m128i",
|
||||
("V8SI", _, Vector) => "__v8i32",
|
||||
("V8SI", _, Intrinsic) => "m256i",
|
||||
("V2DI", _, Vector) => "__v2i64",
|
||||
("V2DI", _, Intrinsic) => "m128i",
|
||||
("V4DI", _, Vector) => "__v4i64",
|
||||
("V4DI", _, Intrinsic) => "m256i",
|
||||
("UV16QI", _, Vector) => "__v16u8",
|
||||
("UV16QI", _, Intrinsic) => "m128i",
|
||||
("UV32QI", _, Vector) => "__v32u8",
|
||||
("UV32QI", _, Intrinsic) => "m256i",
|
||||
("UV8HI", _, Vector) => "__v8u16",
|
||||
("UV8HI", _, Intrinsic) => "m128i",
|
||||
("UV16HI", _, Vector) => "__v16u16",
|
||||
("UV16HI", _, Intrinsic) => "m256i",
|
||||
("UV4SI", _, Vector) => "__v4u32",
|
||||
("UV4SI", _, Intrinsic) => "m128i",
|
||||
("UV8SI", _, Vector) => "__v8u32",
|
||||
("UV8SI", _, Intrinsic) => "m256i",
|
||||
("UV2DI", _, Vector) => "__v2u64",
|
||||
("UV2DI", _, Intrinsic) => "m128i",
|
||||
("UV4DI", _, Vector) => "__v4u64",
|
||||
("UV4DI", _, Intrinsic) => "m256i",
|
||||
("SI", _, _) => "i32",
|
||||
("DI", _, _) => "i64",
|
||||
("USI", _, _) => "u32",
|
||||
("UDI", _, _) => "u64",
|
||||
("V4SF", _, Vector) => "__v4f32",
|
||||
("V4SF", _, Intrinsic) => "m128",
|
||||
("V8SF", _, Vector) => "__v8f32",
|
||||
("V8SF", _, Intrinsic) => "m256",
|
||||
("V2DF", _, Vector) => "__v2f64",
|
||||
("V2DF", _, Intrinsic) => "m128d",
|
||||
("V4DF", _, Vector) => "__v4f64",
|
||||
("V4DF", _, Intrinsic) => "m256d",
|
||||
("UQI", _, _) => "u32",
|
||||
("QI", _, _) => "i32",
|
||||
("CVPOINTER", false, _) => "*const i8",
|
||||
("CVPOINTER", true, _) => "*mut i8",
|
||||
("HI", _, _) => "i32",
|
||||
(_, _, _) => panic!("unknown type: {t}"),
|
||||
}
|
||||
};
|
||||
|
||||
@@ -281,27 +307,27 @@ fn gen_bind_body(
|
||||
let fn_output = if out_t.to_lowercase() == "void" {
|
||||
String::new()
|
||||
} else {
|
||||
format!(" -> {}", type_to_rst(out_t, is_store))
|
||||
format!(" -> {}", type_to_rst(out_t, is_store, Vector))
|
||||
};
|
||||
let fn_inputs = match para_num {
|
||||
1 => format!("(a: {})", type_to_rst(in_t[0], is_store)),
|
||||
1 => format!("(a: {})", type_to_rst(in_t[0], is_store, Vector)),
|
||||
2 => format!(
|
||||
"(a: {}, b: {})",
|
||||
type_to_rst(in_t[0], is_store),
|
||||
type_to_rst(in_t[1], is_store)
|
||||
type_to_rst(in_t[0], is_store, Vector),
|
||||
type_to_rst(in_t[1], is_store, Vector)
|
||||
),
|
||||
3 => format!(
|
||||
"(a: {}, b: {}, c: {})",
|
||||
type_to_rst(in_t[0], is_store),
|
||||
type_to_rst(in_t[1], is_store),
|
||||
type_to_rst(in_t[2], is_store)
|
||||
type_to_rst(in_t[0], is_store, Vector),
|
||||
type_to_rst(in_t[1], is_store, Vector),
|
||||
type_to_rst(in_t[2], is_store, Vector)
|
||||
),
|
||||
4 => format!(
|
||||
"(a: {}, b: {}, c: {}, d: {})",
|
||||
type_to_rst(in_t[0], is_store),
|
||||
type_to_rst(in_t[1], is_store),
|
||||
type_to_rst(in_t[2], is_store),
|
||||
type_to_rst(in_t[3], is_store)
|
||||
type_to_rst(in_t[0], is_store, Vector),
|
||||
type_to_rst(in_t[1], is_store, Vector),
|
||||
type_to_rst(in_t[2], is_store, Vector),
|
||||
type_to_rst(in_t[3], is_store, Vector)
|
||||
),
|
||||
_ => panic!("unsupported parameter number"),
|
||||
};
|
||||
@@ -330,34 +356,40 @@ fn gen_bind_body(
|
||||
let fn_output = if out_t.to_lowercase() == "void" {
|
||||
String::new()
|
||||
} else {
|
||||
format!("-> {} ", type_to_rst(out_t, is_store))
|
||||
format!("-> {} ", type_to_rst(out_t, is_store, Intrinsic))
|
||||
};
|
||||
let mut fn_inputs = match para_num {
|
||||
1 => format!("(a: {})", type_to_rst(in_t[0], is_store)),
|
||||
1 => format!("(a: {})", type_to_rst(in_t[0], is_store, Intrinsic)),
|
||||
2 => format!(
|
||||
"(a: {}, b: {})",
|
||||
type_to_rst(in_t[0], is_store),
|
||||
type_to_rst(in_t[1], is_store)
|
||||
type_to_rst(in_t[0], is_store, Intrinsic),
|
||||
type_to_rst(in_t[1], is_store, Intrinsic)
|
||||
),
|
||||
3 => format!(
|
||||
"(a: {}, b: {}, c: {})",
|
||||
type_to_rst(in_t[0], is_store),
|
||||
type_to_rst(in_t[1], is_store),
|
||||
type_to_rst(in_t[2], is_store)
|
||||
type_to_rst(in_t[0], is_store, Intrinsic),
|
||||
type_to_rst(in_t[1], is_store, Intrinsic),
|
||||
type_to_rst(in_t[2], is_store, Intrinsic)
|
||||
),
|
||||
4 => format!(
|
||||
"(a: {}, b: {}, c: {}, d: {})",
|
||||
type_to_rst(in_t[0], is_store),
|
||||
type_to_rst(in_t[1], is_store),
|
||||
type_to_rst(in_t[2], is_store),
|
||||
type_to_rst(in_t[3], is_store)
|
||||
type_to_rst(in_t[0], is_store, Intrinsic),
|
||||
type_to_rst(in_t[1], is_store, Intrinsic),
|
||||
type_to_rst(in_t[2], is_store, Intrinsic),
|
||||
type_to_rst(in_t[3], is_store, Intrinsic)
|
||||
),
|
||||
_ => panic!("unsupported parameter number"),
|
||||
};
|
||||
if para_num == 1 && in_t[0] == "HI" {
|
||||
fn_inputs = match asm_fmts[1].as_str() {
|
||||
"si13" | "i13" => format!("<const IMM_S13: {}>()", type_to_rst(in_t[0], is_store)),
|
||||
"si10" => format!("<const IMM_S10: {}>()", type_to_rst(in_t[0], is_store)),
|
||||
"si13" | "i13" => format!(
|
||||
"<const IMM_S13: {}>()",
|
||||
type_to_rst(in_t[0], is_store, Intrinsic)
|
||||
),
|
||||
"si10" => format!(
|
||||
"<const IMM_S10: {}>()",
|
||||
type_to_rst(in_t[0], is_store, Intrinsic)
|
||||
),
|
||||
_ => panic!("unsupported assembly format: {}", asm_fmts[1]),
|
||||
};
|
||||
rustc_legacy_const_generics = "rustc_legacy_const_generics(0)";
|
||||
@@ -365,8 +397,8 @@ fn gen_bind_body(
|
||||
fn_inputs = if asm_fmts[2].starts_with("ui") {
|
||||
format!(
|
||||
"<const IMM{2}: {1}>(a: {0})",
|
||||
type_to_rst(in_t[0], is_store),
|
||||
type_to_rst(in_t[1], is_store),
|
||||
type_to_rst(in_t[0], is_store, Intrinsic),
|
||||
type_to_rst(in_t[1], is_store, Intrinsic),
|
||||
asm_fmts[2].get(2..).unwrap()
|
||||
)
|
||||
} else {
|
||||
@@ -377,8 +409,8 @@ fn gen_bind_body(
|
||||
fn_inputs = if asm_fmts[2].starts_with("si") {
|
||||
format!(
|
||||
"<const IMM_S{2}: {1}>(a: {0})",
|
||||
type_to_rst(in_t[0], is_store),
|
||||
type_to_rst(in_t[1], is_store),
|
||||
type_to_rst(in_t[0], is_store, Intrinsic),
|
||||
type_to_rst(in_t[1], is_store, Intrinsic),
|
||||
asm_fmts[2].get(2..).unwrap()
|
||||
)
|
||||
} else {
|
||||
@@ -389,8 +421,8 @@ fn gen_bind_body(
|
||||
fn_inputs = if asm_fmts[2].starts_with("si") {
|
||||
format!(
|
||||
"<const IMM_S{2}: {1}>(mem_addr: {0})",
|
||||
type_to_rst(in_t[0], is_store),
|
||||
type_to_rst(in_t[1], is_store),
|
||||
type_to_rst(in_t[0], is_store, Intrinsic),
|
||||
type_to_rst(in_t[1], is_store, Intrinsic),
|
||||
asm_fmts[2].get(2..).unwrap()
|
||||
)
|
||||
} else {
|
||||
@@ -401,8 +433,8 @@ fn gen_bind_body(
|
||||
fn_inputs = match asm_fmts[2].as_str() {
|
||||
"rk" => format!(
|
||||
"(mem_addr: {}, b: {})",
|
||||
type_to_rst(in_t[0], is_store),
|
||||
type_to_rst(in_t[1], is_store)
|
||||
type_to_rst(in_t[0], is_store, Intrinsic),
|
||||
type_to_rst(in_t[1], is_store, Intrinsic)
|
||||
),
|
||||
_ => panic!("unsupported assembly format: {}", asm_fmts[2]),
|
||||
};
|
||||
@@ -410,9 +442,9 @@ fn gen_bind_body(
|
||||
fn_inputs = if asm_fmts[2].starts_with("ui") {
|
||||
format!(
|
||||
"<const IMM{3}: {2}>(a: {0}, b: {1})",
|
||||
type_to_rst(in_t[0], is_store),
|
||||
type_to_rst(in_t[1], is_store),
|
||||
type_to_rst(in_t[2], is_store),
|
||||
type_to_rst(in_t[0], is_store, Intrinsic),
|
||||
type_to_rst(in_t[1], is_store, Intrinsic),
|
||||
type_to_rst(in_t[2], is_store, Intrinsic),
|
||||
asm_fmts[2].get(2..).unwrap()
|
||||
)
|
||||
} else {
|
||||
@@ -423,9 +455,9 @@ fn gen_bind_body(
|
||||
fn_inputs = match asm_fmts[2].as_str() {
|
||||
"si12" => format!(
|
||||
"<const IMM_S12: {2}>(a: {0}, mem_addr: {1})",
|
||||
type_to_rst(in_t[0], is_store),
|
||||
type_to_rst(in_t[1], is_store),
|
||||
type_to_rst(in_t[2], is_store)
|
||||
type_to_rst(in_t[0], is_store, Intrinsic),
|
||||
type_to_rst(in_t[1], is_store, Intrinsic),
|
||||
type_to_rst(in_t[2], is_store, Intrinsic)
|
||||
),
|
||||
_ => panic!("unsupported assembly format: {}", asm_fmts[2]),
|
||||
};
|
||||
@@ -434,9 +466,9 @@ fn gen_bind_body(
|
||||
fn_inputs = match asm_fmts[2].as_str() {
|
||||
"rk" => format!(
|
||||
"(a: {}, mem_addr: {}, b: {})",
|
||||
type_to_rst(in_t[0], is_store),
|
||||
type_to_rst(in_t[1], is_store),
|
||||
type_to_rst(in_t[2], is_store)
|
||||
type_to_rst(in_t[0], is_store, Intrinsic),
|
||||
type_to_rst(in_t[1], is_store, Intrinsic),
|
||||
type_to_rst(in_t[2], is_store, Intrinsic)
|
||||
),
|
||||
_ => panic!("unsupported assembly format: {}", asm_fmts[2]),
|
||||
};
|
||||
@@ -444,10 +476,10 @@ fn gen_bind_body(
|
||||
fn_inputs = match (asm_fmts[2].as_str(), current_name.chars().last().unwrap()) {
|
||||
("si8", t) => format!(
|
||||
"<const IMM_S8: {2}, const IMM{4}: {3}>(a: {0}, mem_addr: {1})",
|
||||
type_to_rst(in_t[0], is_store),
|
||||
type_to_rst(in_t[1], is_store),
|
||||
type_to_rst(in_t[2], is_store),
|
||||
type_to_rst(in_t[3], is_store),
|
||||
type_to_rst(in_t[0], is_store, Intrinsic),
|
||||
type_to_rst(in_t[1], is_store, Intrinsic),
|
||||
type_to_rst(in_t[2], is_store, Intrinsic),
|
||||
type_to_rst(in_t[3], is_store, Intrinsic),
|
||||
type_to_imm(t),
|
||||
),
|
||||
(_, _) => panic!(
|
||||
@@ -466,10 +498,16 @@ fn gen_bind_body(
|
||||
let unsafe_end = if !is_mem { " }" } else { "" };
|
||||
let mut call_params = {
|
||||
match para_num {
|
||||
1 => format!("{unsafe_start}__{current_name}(a){unsafe_end}"),
|
||||
2 => format!("{unsafe_start}__{current_name}(a, b){unsafe_end}"),
|
||||
3 => format!("{unsafe_start}__{current_name}(a, b, c){unsafe_end}"),
|
||||
4 => format!("{unsafe_start}__{current_name}(a, b, c, d){unsafe_end}"),
|
||||
1 => format!("{unsafe_start}transmute(__{current_name}(transmute(a))){unsafe_end}"),
|
||||
2 => format!(
|
||||
"{unsafe_start}transmute(__{current_name}(transmute(a), transmute(b))){unsafe_end}"
|
||||
),
|
||||
3 => format!(
|
||||
"{unsafe_start}transmute(__{current_name}(transmute(a), transmute(b), transmute(c))){unsafe_end}"
|
||||
),
|
||||
4 => format!(
|
||||
"{unsafe_start}transmute(__{current_name}(transmute(a), transmute(b), transmute(c), transmute(d))){unsafe_end}"
|
||||
),
|
||||
_ => panic!("unsupported parameter number"),
|
||||
}
|
||||
};
|
||||
@@ -477,12 +515,12 @@ fn gen_bind_body(
|
||||
call_params = match asm_fmts[1].as_str() {
|
||||
"si10" => {
|
||||
format!(
|
||||
"static_assert_simm_bits!(IMM_S10, 10);\n {unsafe_start}__{current_name}(IMM_S10){unsafe_end}"
|
||||
"static_assert_simm_bits!(IMM_S10, 10);\n {unsafe_start}transmute(__{current_name}(IMM_S10)){unsafe_end}"
|
||||
)
|
||||
}
|
||||
"i13" => {
|
||||
format!(
|
||||
"static_assert_simm_bits!(IMM_S13, 13);\n {unsafe_start}__{current_name}(IMM_S13){unsafe_end}"
|
||||
"static_assert_simm_bits!(IMM_S13, 13);\n {unsafe_start}transmute(__{current_name}(IMM_S13)){unsafe_end}"
|
||||
)
|
||||
}
|
||||
_ => panic!("unsupported assembly format: {}", asm_fmts[2]),
|
||||
@@ -490,7 +528,7 @@ fn gen_bind_body(
|
||||
} else if para_num == 2 && (in_t[1] == "UQI" || in_t[1] == "USI") {
|
||||
call_params = if asm_fmts[2].starts_with("ui") {
|
||||
format!(
|
||||
"static_assert_uimm_bits!(IMM{0}, {0});\n {unsafe_start}__{current_name}(a, IMM{0}){unsafe_end}",
|
||||
"static_assert_uimm_bits!(IMM{0}, {0});\n {unsafe_start}transmute(__{current_name}(transmute(a), IMM{0})){unsafe_end}",
|
||||
asm_fmts[2].get(2..).unwrap()
|
||||
)
|
||||
} else {
|
||||
@@ -500,7 +538,7 @@ fn gen_bind_body(
|
||||
call_params = match asm_fmts[2].as_str() {
|
||||
"si5" => {
|
||||
format!(
|
||||
"static_assert_simm_bits!(IMM_S5, 5);\n {unsafe_start}__{current_name}(a, IMM_S5){unsafe_end}"
|
||||
"static_assert_simm_bits!(IMM_S5, 5);\n {unsafe_start}transmute(__{current_name}(transmute(a), IMM_S5)){unsafe_end}"
|
||||
)
|
||||
}
|
||||
_ => panic!("unsupported assembly format: {}", asm_fmts[2]),
|
||||
@@ -508,7 +546,7 @@ fn gen_bind_body(
|
||||
} else if para_num == 2 && in_t[0] == "CVPOINTER" && in_t[1] == "SI" {
|
||||
call_params = if asm_fmts[2].starts_with("si") {
|
||||
format!(
|
||||
"static_assert_simm_bits!(IMM_S{0}, {0});\n {unsafe_start}__{current_name}(mem_addr, IMM_S{0}){unsafe_end}",
|
||||
"static_assert_simm_bits!(IMM_S{0}, {0});\n {unsafe_start}transmute(__{current_name}(mem_addr, IMM_S{0})){unsafe_end}",
|
||||
asm_fmts[2].get(2..).unwrap()
|
||||
)
|
||||
} else {
|
||||
@@ -516,13 +554,15 @@ fn gen_bind_body(
|
||||
}
|
||||
} else if para_num == 2 && in_t[0] == "CVPOINTER" && in_t[1] == "DI" {
|
||||
call_params = match asm_fmts[2].as_str() {
|
||||
"rk" => format!("{unsafe_start}__{current_name}(mem_addr, b){unsafe_end}"),
|
||||
"rk" => format!(
|
||||
"{unsafe_start}transmute(__{current_name}(mem_addr, transmute(b))){unsafe_end}"
|
||||
),
|
||||
_ => panic!("unsupported assembly format: {}", asm_fmts[2]),
|
||||
};
|
||||
} else if para_num == 3 && (in_t[2] == "USI" || in_t[2] == "UQI") {
|
||||
call_params = if asm_fmts[2].starts_with("ui") {
|
||||
format!(
|
||||
"static_assert_uimm_bits!(IMM{0}, {0});\n {unsafe_start}__{current_name}(a, b, IMM{0}){unsafe_end}",
|
||||
"static_assert_uimm_bits!(IMM{0}, {0});\n {unsafe_start}transmute(__{current_name}(transmute(a), transmute(b), IMM{0})){unsafe_end}",
|
||||
asm_fmts[2].get(2..).unwrap()
|
||||
)
|
||||
} else {
|
||||
@@ -531,19 +571,21 @@ fn gen_bind_body(
|
||||
} else if para_num == 3 && in_t[1] == "CVPOINTER" && in_t[2] == "SI" {
|
||||
call_params = match asm_fmts[2].as_str() {
|
||||
"si12" => format!(
|
||||
"static_assert_simm_bits!(IMM_S12, 12);\n {unsafe_start}__{current_name}(a, mem_addr, IMM_S12){unsafe_end}"
|
||||
"static_assert_simm_bits!(IMM_S12, 12);\n {unsafe_start}transmute(__{current_name}(transmute(a), mem_addr, IMM_S12)){unsafe_end}"
|
||||
),
|
||||
_ => panic!("unsupported assembly format: {}", asm_fmts[2]),
|
||||
};
|
||||
} else if para_num == 3 && in_t[1] == "CVPOINTER" && in_t[2] == "DI" {
|
||||
call_params = match asm_fmts[2].as_str() {
|
||||
"rk" => format!("{unsafe_start}__{current_name}(a, mem_addr, b){unsafe_end}"),
|
||||
"rk" => format!(
|
||||
"{unsafe_start}transmute(__{current_name}(transmute(a), mem_addr, transmute(b))){unsafe_end}"
|
||||
),
|
||||
_ => panic!("unsupported assembly format: {}", asm_fmts[2]),
|
||||
};
|
||||
} else if para_num == 4 {
|
||||
call_params = match (asm_fmts[2].as_str(), current_name.chars().last().unwrap()) {
|
||||
("si8", t) => format!(
|
||||
"static_assert_simm_bits!(IMM_S8, 8);\n static_assert_uimm_bits!(IMM{0}, {0});\n {unsafe_start}__{current_name}(a, mem_addr, IMM_S8, IMM{0}){unsafe_end}",
|
||||
"static_assert_simm_bits!(IMM_S8, 8);\n static_assert_uimm_bits!(IMM{0}, {0});\n {unsafe_start}transmute(__{current_name}(transmute(a), mem_addr, IMM_S8, IMM{0})){unsafe_end}",
|
||||
type_to_imm(t)
|
||||
),
|
||||
(_, _) => panic!(
|
||||
|
||||
Reference in New Issue
Block a user