mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-22 19:24:13 +00:00
[WebAssembly] Use functions instead of macros for const SIMD intrinsics
To improve hygiene, consistency, and usability, it would be good to replace all the macro intrinsics in wasm_simd128.h with functions. The reason for using macros in the first place was to enforce the use of constants for some arguments using `_Static_assert` with `__builtin_constant_p`. This commit switches to using functions and uses the `__diagnose_if__` attribute rather than `_Static_assert` to enforce constantness. The remaining macro intrinsics cannot be made into functions until the builtin functions they are implemented with can be replaced with normal code patterns because the builtin functions themselves require that their arguments are constants. This commit also fixes a bug with the const_splat intrinsics in which the f32x4 and f64x2 variants were incorrectly producing integer vectors. Differential Revision: https://reviews.llvm.org/D102018
This commit is contained in:
parent
724604901a
commit
1e9c39a3f9
@ -48,8 +48,9 @@ typedef unsigned int __u32x2
|
||||
__attribute__((__always_inline__, __nodebug__, __target__("simd128"), \
|
||||
__min_vector_width__(128)))
|
||||
|
||||
#define __REQUIRE_CONSTANT(e) \
|
||||
_Static_assert(__builtin_constant_p(e), "Expected constant")
|
||||
#define __REQUIRE_CONSTANT(c) \
|
||||
__attribute__((__diagnose_if__(!__builtin_constant_p(c), \
|
||||
#c " must be constant", "error")))
|
||||
|
||||
static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_v128_load(const void *__mem) {
|
||||
// UB-free unaligned access copied from xmmintrin.h
|
||||
@ -246,88 +247,90 @@ static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_make(double __c0,
|
||||
return (v128_t)(__f64x2){__c0, __c1};
|
||||
}
|
||||
|
||||
#define wasm_i8x16_const(__c0, __c1, __c2, __c3, __c4, __c5, __c6, __c7, __c8, \
|
||||
__c9, __c10, __c11, __c12, __c13, __c14, __c15) \
|
||||
__extension__({ \
|
||||
__REQUIRE_CONSTANT(__c0); \
|
||||
__REQUIRE_CONSTANT(__c1); \
|
||||
__REQUIRE_CONSTANT(__c2); \
|
||||
__REQUIRE_CONSTANT(__c3); \
|
||||
__REQUIRE_CONSTANT(__c4); \
|
||||
__REQUIRE_CONSTANT(__c5); \
|
||||
__REQUIRE_CONSTANT(__c6); \
|
||||
__REQUIRE_CONSTANT(__c7); \
|
||||
__REQUIRE_CONSTANT(__c8); \
|
||||
__REQUIRE_CONSTANT(__c9); \
|
||||
__REQUIRE_CONSTANT(__c10); \
|
||||
__REQUIRE_CONSTANT(__c11); \
|
||||
__REQUIRE_CONSTANT(__c12); \
|
||||
__REQUIRE_CONSTANT(__c13); \
|
||||
__REQUIRE_CONSTANT(__c14); \
|
||||
__REQUIRE_CONSTANT(__c15); \
|
||||
(v128_t)(__i8x16){__c0, __c1, __c2, __c3, __c4, __c5, __c6, __c7, \
|
||||
__c8, __c9, __c10, __c11, __c12, __c13, __c14, __c15}; \
|
||||
})
|
||||
static __inline__ v128_t __DEFAULT_FN_ATTRS
|
||||
wasm_i8x16_const(int8_t __c0, int8_t __c1, int8_t __c2, int8_t __c3,
|
||||
int8_t __c4, int8_t __c5, int8_t __c6, int8_t __c7,
|
||||
int8_t __c8, int8_t __c9, int8_t __c10, int8_t __c11,
|
||||
int8_t __c12, int8_t __c13, int8_t __c14, int8_t __c15)
|
||||
__REQUIRE_CONSTANT(__c0) __REQUIRE_CONSTANT(__c1) __REQUIRE_CONSTANT(__c2)
|
||||
__REQUIRE_CONSTANT(__c3) __REQUIRE_CONSTANT(__c4)
|
||||
__REQUIRE_CONSTANT(__c5) __REQUIRE_CONSTANT(__c6)
|
||||
__REQUIRE_CONSTANT(__c7) __REQUIRE_CONSTANT(__c8)
|
||||
__REQUIRE_CONSTANT(__c9) __REQUIRE_CONSTANT(__c10)
|
||||
__REQUIRE_CONSTANT(__c11) __REQUIRE_CONSTANT(__c12)
|
||||
__REQUIRE_CONSTANT(__c13) __REQUIRE_CONSTANT(__c14)
|
||||
__REQUIRE_CONSTANT(__c15) {
|
||||
return (v128_t)(__i8x16){__c0, __c1, __c2, __c3, __c4, __c5,
|
||||
__c6, __c7, __c8, __c9, __c10, __c11,
|
||||
__c12, __c13, __c14, __c15};
|
||||
}
|
||||
|
||||
#define wasm_i16x8_const(__c0, __c1, __c2, __c3, __c4, __c5, __c6, __c7) \
|
||||
__extension__({ \
|
||||
__REQUIRE_CONSTANT(__c0); \
|
||||
__REQUIRE_CONSTANT(__c1); \
|
||||
__REQUIRE_CONSTANT(__c2); \
|
||||
__REQUIRE_CONSTANT(__c3); \
|
||||
__REQUIRE_CONSTANT(__c4); \
|
||||
__REQUIRE_CONSTANT(__c5); \
|
||||
__REQUIRE_CONSTANT(__c6); \
|
||||
__REQUIRE_CONSTANT(__c7); \
|
||||
(v128_t)(__i16x8){__c0, __c1, __c2, __c3, __c4, __c5, __c6, __c7}; \
|
||||
})
|
||||
static __inline__ v128_t __DEFAULT_FN_ATTRS
|
||||
wasm_i16x8_const(int16_t __c0, int16_t __c1, int16_t __c2, int16_t __c3,
|
||||
int16_t __c4, int16_t __c5, int16_t __c6, int16_t __c7)
|
||||
__REQUIRE_CONSTANT(__c0) __REQUIRE_CONSTANT(__c1) __REQUIRE_CONSTANT(__c2)
|
||||
__REQUIRE_CONSTANT(__c3) __REQUIRE_CONSTANT(__c4)
|
||||
__REQUIRE_CONSTANT(__c5) __REQUIRE_CONSTANT(__c6)
|
||||
__REQUIRE_CONSTANT(__c7) {
|
||||
return (v128_t)(__i16x8){__c0, __c1, __c2, __c3, __c4, __c5, __c6, __c7};
|
||||
}
|
||||
|
||||
#define wasm_i32x4_const(__c0, __c1, __c2, __c3) \
|
||||
__extension__({ \
|
||||
__REQUIRE_CONSTANT(__c0); \
|
||||
__REQUIRE_CONSTANT(__c1); \
|
||||
__REQUIRE_CONSTANT(__c2); \
|
||||
__REQUIRE_CONSTANT(__c3); \
|
||||
(v128_t)(__i32x4){__c0, __c1, __c2, __c3}; \
|
||||
})
|
||||
static __inline__ v128_t __DEFAULT_FN_ATTRS
|
||||
wasm_i32x4_const(int32_t __c0, int32_t __c1, int32_t __c2, int32_t __c3)
|
||||
__REQUIRE_CONSTANT(__c0) __REQUIRE_CONSTANT(__c1) __REQUIRE_CONSTANT(__c2)
|
||||
__REQUIRE_CONSTANT(__c3) {
|
||||
return (v128_t)(__i32x4){__c0, __c1, __c2, __c3};
|
||||
}
|
||||
|
||||
#define wasm_i64x2_const(__c0, __c1) \
|
||||
__extension__({ \
|
||||
__REQUIRE_CONSTANT(__c0); \
|
||||
__REQUIRE_CONSTANT(__c1); \
|
||||
(v128_t)(__i64x2){__c0, __c1}; \
|
||||
})
|
||||
static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i64x2_const(int64_t __c0,
|
||||
int64_t __c1)
|
||||
__REQUIRE_CONSTANT(__c0) __REQUIRE_CONSTANT(__c1) {
|
||||
return (v128_t)(__i64x2){__c0, __c1};
|
||||
}
|
||||
|
||||
#define wasm_f32x4_const(__c0, __c1, __c2, __c3) \
|
||||
__extension__({ \
|
||||
__REQUIRE_CONSTANT(__c0); \
|
||||
__REQUIRE_CONSTANT(__c1); \
|
||||
__REQUIRE_CONSTANT(__c2); \
|
||||
__REQUIRE_CONSTANT(__c3); \
|
||||
(v128_t)(__f32x4){__c0, __c1, __c2, __c3}; \
|
||||
})
|
||||
static __inline__ v128_t __DEFAULT_FN_ATTRS
|
||||
wasm_f32x4_const(float __c0, float __c1, float __c2, float __c3)
|
||||
__REQUIRE_CONSTANT(__c0) __REQUIRE_CONSTANT(__c1) __REQUIRE_CONSTANT(__c2)
|
||||
__REQUIRE_CONSTANT(__c3) {
|
||||
return (v128_t)(__f32x4){__c0, __c1, __c2, __c3};
|
||||
}
|
||||
|
||||
#define wasm_f64x2_const(__c0, __c1) \
|
||||
__extension__({ \
|
||||
__REQUIRE_CONSTANT(__c0); \
|
||||
__REQUIRE_CONSTANT(__c1); \
|
||||
(v128_t)(__f64x2){__c0, __c1}; \
|
||||
})
|
||||
static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_const(double __c0,
|
||||
double __c1)
|
||||
__REQUIRE_CONSTANT(__c0) __REQUIRE_CONSTANT(__c1) {
|
||||
return (v128_t)(__f64x2){__c0, __c1};
|
||||
}
|
||||
|
||||
#define wasm_i8x16_const_splat(__c) \
|
||||
wasm_i8x16_const(__c, __c, __c, __c, __c, __c, __c, __c, __c, __c, __c, __c, \
|
||||
__c, __c, __c, __c)
|
||||
static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_const_splat(int8_t __c)
|
||||
__REQUIRE_CONSTANT(__c) {
|
||||
return (v128_t)(__i8x16){__c, __c, __c, __c, __c, __c, __c, __c,
|
||||
__c, __c, __c, __c, __c, __c, __c, __c};
|
||||
}
|
||||
|
||||
#define wasm_i16x8_const_splat(__c) \
|
||||
wasm_i16x8_const(__c, __c, __c, __c, __c, __c, __c, __c)
|
||||
static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_const_splat(int16_t __c)
|
||||
__REQUIRE_CONSTANT(__c) {
|
||||
return (v128_t)(__i16x8){__c, __c, __c, __c, __c, __c, __c, __c};
|
||||
}
|
||||
|
||||
#define wasm_i32x4_const_splat(__c) wasm_i32x4_const(__c, __c, __c, __c)
|
||||
static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_const_splat(int32_t __c)
|
||||
__REQUIRE_CONSTANT(__c) {
|
||||
return (v128_t)(__i32x4){__c, __c, __c, __c};
|
||||
}
|
||||
|
||||
#define wasm_i64x2_const_splat(__c) wasm_i64x2_const(__c, __c)
|
||||
static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i64x2_const_splat(int64_t __c)
|
||||
__REQUIRE_CONSTANT(__c) {
|
||||
return (v128_t)(__i64x2){__c, __c};
|
||||
}
|
||||
|
||||
#define wasm_f32x4_const_splat(__c) wasm_i32x4_const(__c, __c, __c, __c)
|
||||
static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f32x4_const_splat(float __c)
|
||||
__REQUIRE_CONSTANT(__c) {
|
||||
return (v128_t)(__f32x4){__c, __c, __c, __c};
|
||||
}
|
||||
|
||||
#define wasm_f64x2_const_splat(__c) wasm_i64x2_const(__c, __c)
|
||||
static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_const_splat(double __c)
|
||||
__REQUIRE_CONSTANT(__c) {
|
||||
return (v128_t)(__f64x2){__c, __c};
|
||||
}
|
||||
|
||||
static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_splat(int8_t __a) {
|
||||
return (v128_t)(__i8x16){__a, __a, __a, __a, __a, __a, __a, __a,
|
||||
|
@ -420,7 +420,7 @@ v128_t test_i64x2_const_splat() {
|
||||
|
||||
// CHECK-LABEL: @test_f32x4_const_splat(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: ret <4 x i32> <i32 42, i32 42, i32 42, i32 42>
|
||||
// CHECK-NEXT: ret <4 x i32> <i32 1109917696, i32 1109917696, i32 1109917696, i32 1109917696>
|
||||
//
|
||||
v128_t test_f32x4_const_splat() {
|
||||
return wasm_f32x4_const_splat(42);
|
||||
@ -428,7 +428,7 @@ v128_t test_f32x4_const_splat() {
|
||||
|
||||
// CHECK-LABEL: @test_f64x2_const_splat(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: ret <4 x i32> <i32 42, i32 0, i32 42, i32 0>
|
||||
// CHECK-NEXT: ret <4 x i32> <i32 0, i32 1078263808, i32 0, i32 1078263808>
|
||||
//
|
||||
v128_t test_f64x2_const_splat() {
|
||||
return wasm_f64x2_const_splat(42);
|
||||
|
Loading…
x
Reference in New Issue
Block a user