(__i8x16)__b);
}
-static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_mul(v128_t __a,
- v128_t __b) {
- return (v128_t)((__u8x16)__a * (__u8x16)__b);
-}
-
static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_min(v128_t __a,
v128_t __b) {
return (v128_t)__builtin_wasm_min_s_i8x16((__i8x16)__a, (__i8x16)__b);
MVT::v2f64})
setOperationAction(Op, T, Custom);
- // There is no i64x2.mul instruction
- // TODO: Actually, there is now. Implement it.
- setOperationAction(ISD::MUL, MVT::v2i64, Expand);
+ // There is no i8x16.mul instruction
+ setOperationAction(ISD::MUL, MVT::v16i8, Expand);
// There are no vector select instructions
for (auto Op : {ISD::VSELECT, ISD::SELECT_CC, ISD::SELECT})
// Integer binary arithmetic
//===----------------------------------------------------------------------===//
+multiclass SIMDBinaryIntNoI8x16<SDNode node, string name, bits<32> baseInst> {
+ defm "" : SIMDBinary<v8i16, "i16x8", node, name, !add(baseInst, 32)>;
+ defm "" : SIMDBinary<v4i32, "i32x4", node, name, !add(baseInst, 64)>;
+ defm "" : SIMDBinary<v2i64, "i64x2", node, name, !add(baseInst, 96)>;
+}
+
multiclass SIMDBinaryIntSmall<SDNode node, string name, bits<32> baseInst> {
defm "" : SIMDBinary<v16i8, "i8x16", node, name, baseInst>;
defm "" : SIMDBinary<v8i16, "i16x8", node, name, !add(baseInst, 32)>;
// Integer multiplication: mul
let isCommutable = 1 in
-defm MUL : SIMDBinaryIntNoI64x2<mul, "mul", 117>;
+defm MUL : SIMDBinaryIntNoI8x16<mul, "mul", 117>;
// Integer min_s / min_u / max_s / max_u
let isCommutable = 1 in {
ret <16 x i8> %a
}
+; i8x16.mul is not in spec
; CHECK-LABEL: mul_v16i8:
; NO-SIMD128-NOT: i8x16
-; SIMD128-NEXT: .functype mul_v16i8 (v128, v128) -> (v128){{$}}
-; SIMD128-NEXT: i8x16.mul $push[[R:[0-9]+]]=, $0, $1{{$}}
-; SIMD128-NEXT: return $pop[[R]]{{$}}
+; SIMD128-NOT: i8x16.mul
+; SIMD128: i8x16.extract_lane_u
+; SIMD128: i32.mul
define <16 x i8> @mul_v16i8(<16 x i8> %x, <16 x i8> %y) {
%a = mul <16 x i8> %x, %y
ret <16 x i8> %a
ret <2 x i64> %a
}
-; v2i64.mul is not in spec
; CHECK-LABEL: mul_v2i64:
; NO-SIMD128-NOT: i64x2
-; SIMD128-NOT: i64x2.mul
-; SIMD128: i64x2.extract_lane
-; SIMD128: i64.mul
+; SIMD128-NEXT: .functype mul_v2i64 (v128, v128) -> (v128){{$}}
+; SIMD128: i64x2.mul $push[[R:[0-9]+]]=, $0, $1{{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
define <2 x i64> @mul_v2i64(<2 x i64> %x, <2 x i64> %y) {
%a = mul <2 x i64> %x, %y
ret <2 x i64> %a
}
; CHECK-LABEL: ctpop_v2i64:
-; CHECK: i64.popcnt
+; Note: expansion does not use i64.popcnt
+; CHECK: v128.and
declare <2 x i64> @llvm.ctpop.v2i64(<2 x i64>)
define <2 x i64> @ctpop_v2i64(<2 x i64> %x) {
%v = call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %x)
# CHECK: i8x16.sub_saturate_u # encoding: [0xfd,0x73]
i8x16.sub_saturate_u
- # CHECK: i8x16.mul # encoding: [0xfd,0x75]
- i8x16.mul
-
# CHECK: i8x16.min_s # encoding: [0xfd,0x76]
i8x16.min_s
# CHECK: i64x2.sub # encoding: [0xfd,0xd1,0x01]
i64x2.sub
+ # CHECK: i64x2.mul # encoding: [0xfd,0xd5,0x01]
+ i64x2.mul
+
# CHECK: f32x4.abs # encoding: [0xfd,0xe0,0x01]
f32x4.abs