diff options
9 files changed, 229 insertions, 19 deletions
diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp index 2d92b93ca70..0d591c04535 100644 --- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp +++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp @@ -46,7 +46,9 @@ static unsigned MVTToWasmReg(MVT::SimpleValueType Type) { case MVT::v16i8: return WebAssembly::V128_0; case MVT::v8i16: return WebAssembly::V128_0; case MVT::v4i32: return WebAssembly::V128_0; + case MVT::v2i64: return WebAssembly::V128_0; case MVT::v4f32: return WebAssembly::V128_0; + case MVT::v2f64: return WebAssembly::V128_0; default: return MVT::INVALID_SIMPLE_VALUE_TYPE; } } @@ -194,6 +196,7 @@ public: const MCInstrInfo &mii, const MCTargetOptions &Options) : MCTargetAsmParser(Options, sti, mii), Parser(Parser), Lexer(Parser.getLexer()), LastLabel(nullptr) { + setAvailableFeatures(ComputeAvailableFeatures(sti.getFeatureBits())); } #define GET_ASSEMBLER_HEADER @@ -232,7 +235,13 @@ public: .Case("i8x16", MVT::v16i8) .Case("i16x8", MVT::v8i16) .Case("i32x4", MVT::v4i32) + .Case("i64x2", MVT::v2i64) .Case("f32x4", MVT::v4f32) + .Case("f64x2", MVT::v2f64) + // arbitrarily chosen vector type to associate with "v128" + // FIXME: should these be EVTs to avoid this arbitrary hack? Do we want + // to accept more specific SIMD register types? + .Case("v128", MVT::v16i8) .Default(MVT::INVALID_SIMPLE_VALUE_TYPE); } diff --git a/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp b/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp index 2f0960271e3..9f6797da3a2 100644 --- a/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp +++ b/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp @@ -92,14 +92,18 @@ static bool parseLEBImmediate(MCInst &MI, uint64_t &Size, } template <typename T> -bool parseFPImmediate(MCInst &MI, uint64_t &Size, ArrayRef<uint8_t> Bytes) { +bool parseImmediate(MCInst &MI, uint64_t &Size, ArrayRef<uint8_t> Bytes) { if (Size + sizeof(T) > Bytes.size()) return false; T Val; memcpy(&Val, Bytes.data() + Size, sizeof(T)); support::endian::byte_swap<T, support::endianness::little>(Val); Size += sizeof(T); - MI.addOperand(MCOperand::createFPImm(static_cast<double>(Val))); + if (std::is_floating_point<T>::value) { + MI.addOperand(MCOperand::createFPImm(static_cast<double>(Val))); + } else { + MI.addOperand(MCOperand::createImm(static_cast<int64_t>(Val))); + } return true; } @@ -160,12 +164,33 @@ MCDisassembler::DecodeStatus WebAssemblyDisassembler::getInstruction( } // FP operands. case WebAssembly::OPERAND_F32IMM: { - if (!parseFPImmediate<float>(MI, Size, Bytes)) + if (!parseImmediate<float>(MI, Size, Bytes)) return MCDisassembler::Fail; break; } case WebAssembly::OPERAND_F64IMM: { - if (!parseFPImmediate<double>(MI, Size, Bytes)) + if (!parseImmediate<double>(MI, Size, Bytes)) + return MCDisassembler::Fail; + break; + } + // Vector lane operands (not LEB encoded). + case WebAssembly::OPERAND_VEC_I8IMM: { + if (!parseImmediate<uint8_t>(MI, Size, Bytes)) + return MCDisassembler::Fail; + break; + } + case WebAssembly::OPERAND_VEC_I16IMM: { + if (!parseImmediate<uint16_t>(MI, Size, Bytes)) + return MCDisassembler::Fail; + break; + } + case WebAssembly::OPERAND_VEC_I32IMM: { + if (!parseImmediate<uint32_t>(MI, Size, Bytes)) + return MCDisassembler::Fail; + break; + } + case WebAssembly::OPERAND_VEC_I64IMM: { + if (!parseImmediate<uint64_t>(MI, Size, Bytes)) return MCDisassembler::Fail; break; } diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp index 417912604e0..bff074d987c 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp @@ -90,17 +90,34 @@ void WebAssemblyMCCodeEmitter::encodeInstruction( const MCOperandInfo &Info = Desc.OpInfo[i]; LLVM_DEBUG(dbgs() << "Encoding immediate: type=" << int(Info.OperandType) << "\n"); - if (Info.OperandType == WebAssembly::OPERAND_I32IMM) { + switch (Info.OperandType) { + case WebAssembly::OPERAND_I32IMM: encodeSLEB128(int32_t(MO.getImm()), OS); - } else if (Info.OperandType == WebAssembly::OPERAND_OFFSET32) { + break; + case WebAssembly::OPERAND_OFFSET32: encodeULEB128(uint32_t(MO.getImm()), OS); - } else if (Info.OperandType == WebAssembly::OPERAND_I64IMM) { + break; + case WebAssembly::OPERAND_I64IMM: encodeSLEB128(int64_t(MO.getImm()), OS); - } else if (Info.OperandType == WebAssembly::OPERAND_GLOBAL) { - llvm_unreachable("wasm globals should only be accessed symbolicly"); - } else if (Info.OperandType == WebAssembly::OPERAND_SIGNATURE) { + break; + case WebAssembly::OPERAND_SIGNATURE: OS << uint8_t(MO.getImm()); - } else { + break; + case WebAssembly::OPERAND_VEC_I8IMM: + support::endian::write<uint8_t>(OS, MO.getImm(), support::little); + break; + case WebAssembly::OPERAND_VEC_I16IMM: + support::endian::write<uint16_t>(OS, MO.getImm(), support::little); + break; + case WebAssembly::OPERAND_VEC_I32IMM: + support::endian::write<uint32_t>(OS, MO.getImm(), support::little); + break; + case WebAssembly::OPERAND_VEC_I64IMM: + support::endian::write<uint64_t>(OS, MO.getImm(), support::little); + break; + case WebAssembly::OPERAND_GLOBAL: + llvm_unreachable("wasm globals should only be accessed symbolicly"); + default: encodeULEB128(uint64_t(MO.getImm()), OS); } } else { diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h index b4639b4afdc..4ca921481dc 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h @@ -59,6 +59,14 @@ enum OperandType { OPERAND_F32IMM, /// 64-bit floating-point immediates. OPERAND_F64IMM, + /// 8-bit vector lane immediate + OPERAND_VEC_I8IMM, + /// 16-bit vector lane immediate + OPERAND_VEC_I16IMM, + /// 32-bit vector lane immediate + OPERAND_VEC_I32IMM, + /// 64-bit vector lane immediate + OPERAND_VEC_I64IMM, /// 32-bit unsigned function indices. OPERAND_FUNCTION32, /// 32-bit unsigned memory offsets. diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td index 3f97ef5f7b7..d9e87e017a6 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td @@ -118,6 +118,18 @@ def f32imm_op : Operand<f32>; let OperandType = "OPERAND_F64IMM" in def f64imm_op : Operand<f64>; +let OperandType = "OPERAND_VEC_I8IMM" in +def vec_i8imm_op : Operand<i32>; + +let OperandType = "OPERAND_VEC_I16IMM" in +def vec_i16imm_op : Operand<i32>; + +let OperandType = "OPERAND_VEC_I32IMM" in +def vec_i32imm_op : Operand<i32>; + +let OperandType = "OPERAND_VEC_I64IMM" in +def vec_i64imm_op : Operand<i64>; + let OperandType = "OPERAND_FUNCTION32" in def function32_op : Operand<i32>; diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td index 2a4505173fb..08b925aeee9 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td @@ -12,18 +12,71 @@ /// //===----------------------------------------------------------------------===// -// immediate argument types -def ImmByte : ImmLeaf<i32, [{ return 0 <= Imm && Imm < 256; }]>; +// constrained immediate argument types +foreach SIZE = [8, 16] in +def ImmI#SIZE : ImmLeaf<i32, "return (Imm & ((1UL << "#SIZE#") - 1)) == Imm;">; foreach SIZE = [2, 4, 8, 16, 32] in def LaneIdx#SIZE : ImmLeaf<i32, "return 0 <= Imm && Imm < "#SIZE#";">; +// const vectors +multiclass ConstVec<ValueType vec_t, dag ops, dag pat, string args> { + defm CONST_V128_#vec_t : SIMD_I<(outs V128:$dst), ops, (outs), ops, + [(set V128:$dst, (vec_t pat))], + "v128.const\t$dst, "#args, + "v128.const\t"#args, 0>; +} +defm "" : ConstVec<v16i8, + (ins vec_i8imm_op:$i0, vec_i8imm_op:$i1, + vec_i8imm_op:$i2, vec_i8imm_op:$i3, + vec_i8imm_op:$i4, vec_i8imm_op:$i5, + vec_i8imm_op:$i6, vec_i8imm_op:$i7, + vec_i8imm_op:$i8, vec_i8imm_op:$i9, + vec_i8imm_op:$iA, vec_i8imm_op:$iB, + vec_i8imm_op:$iC, vec_i8imm_op:$iD, + vec_i8imm_op:$iE, vec_i8imm_op:$iF), + (build_vector ImmI8:$i0, ImmI8:$i1, ImmI8:$i2, ImmI8:$i3, + ImmI8:$i4, ImmI8:$i5, ImmI8:$i6, ImmI8:$i7, + ImmI8:$i8, ImmI8:$i9, ImmI8:$iA, ImmI8:$iB, + ImmI8:$iC, ImmI8:$iD, ImmI8:$iE, ImmI8:$iF), + !strconcat("$i0, $i1, $i2, $i3, $i4, $i5, $i6, $i7, ", + "$i8, $i9, $iA, $iB, $iC, $iD, $iE, $iF")>; +defm "" : ConstVec<v8i16, + (ins vec_i16imm_op:$i0, vec_i16imm_op:$i1, + vec_i16imm_op:$i2, vec_i16imm_op:$i3, + vec_i16imm_op:$i4, vec_i16imm_op:$i5, + vec_i16imm_op:$i6, vec_i16imm_op:$i7), + (build_vector + ImmI16:$i0, ImmI16:$i1, ImmI16:$i2, ImmI16:$i3, + ImmI16:$i4, ImmI16:$i5, ImmI16:$i6, ImmI16:$i7), + "$i0, $i1, $i2, $i3, $i4, $i5, $i6, $i7">; +defm "" : ConstVec<v4i32, + (ins vec_i32imm_op:$i0, vec_i32imm_op:$i1, + vec_i32imm_op:$i2, vec_i32imm_op:$i3), + (build_vector (i32 imm:$i0), (i32 imm:$i1), + (i32 imm:$i2), (i32 imm:$i3)), + "$i0, $i1, $i2, $i3">; +defm "" : ConstVec<v2i64, + (ins vec_i64imm_op:$i0, vec_i64imm_op:$i1), + (build_vector (i64 imm:$i0), (i64 imm:$i1)), + "$i0, $i1">; +defm "" : ConstVec<v4f32, + (ins f32imm_op:$i0, f32imm_op:$i1, + f32imm_op:$i2, f32imm_op:$i3), + (build_vector (f32 fpimm:$i0), (f32 fpimm:$i1), + (f32 fpimm:$i2), (f32 fpimm:$i3)), + "$i0, $i1, $i2, $i3">; +defm "" : ConstVec<v2f64, + (ins f64imm_op:$i0, f64imm_op:$i1), + (build_vector (f64 fpimm:$i0), (f64 fpimm:$i1)), + "$i0, $i1">; + // lane extraction multiclass ExtractLane<ValueType vec_t, string vec, ImmLeaf imm_t, WebAssemblyRegClass reg_t, bits<32> simdop, string suffix = "", SDNode extract = vector_extract> { defm EXTRACT_LANE_#vec_t#suffix : - SIMD_I<(outs reg_t:$dst), (ins V128:$vec, I32:$idx), - (outs), (ins I32:$idx), + SIMD_I<(outs reg_t:$dst), (ins V128:$vec, i32imm_op:$idx), + (outs), (ins i32imm_op:$idx), [(set reg_t:$dst, (extract (vec_t V128:$vec), (i32 imm_t:$idx)))], vec#".extract_lane"#suffix#"\t$dst, $vec, $idx", vec#".extract_lane"#suffix#"\t$idx", simdop>; @@ -73,8 +126,8 @@ def : Pat<(i32 (vector_extract (v8i16 V128:$vec), (i32 LaneIdx8:$idx))), multiclass ReplaceLane<ValueType vec_t, string vec, WebAssemblyRegClass reg_t, ValueType lane_t, ImmLeaf imm_t, bits<32> simdop> { defm REPLACE_LANE_#vec_t : - SIMD_I<(outs V128:$dst), (ins V128:$vec, I32:$idx, reg_t:$x), - (outs), (ins I32:$idx), + SIMD_I<(outs V128:$dst), (ins V128:$vec, i32imm_op:$idx, reg_t:$x), + (outs), (ins i32imm_op:$idx), [(set V128:$dst, (vector_insert (vec_t V128:$vec), (lane_t reg_t:$x), (i32 imm_t:$idx)))], vec#".replace_lane\t$dst, $vec, $idx, $x", diff --git a/llvm/test/CodeGen/WebAssembly/simd.ll b/llvm/test/CodeGen/WebAssembly/simd.ll index 414c5b31356..064df0bf9fd 100644 --- a/llvm/test/CodeGen/WebAssembly/simd.ll +++ b/llvm/test/CodeGen/WebAssembly/simd.ll @@ -10,6 +10,19 @@ target triple = "wasm32-unknown-unknown" ; ============================================================================== ; 16 x i8 ; ============================================================================== +; CHECK-LABEL: const_v16i8: +; NO-SIMD128-NOT: i8x16 +; SIMD128: .result v128{{$}} +; SIMD128: v128.const $push0=, +; SIMD128-SAME: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 +; SIMD128-SAME: # encoding: [0xfd,0x00, +; SIMD128-SAME: 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, +; SIMD128-SAME: 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f]{{$}} +define <16 x i8> @const_v16i8() { + ret <16 x i8> <i8 00, i8 01, i8 02, i8 03, i8 04, i8 05, i8 06, i8 07, + i8 08, i8 09, i8 10, i8 11, i8 12, i8 13, i8 14, i8 15> +} + ; CHECK-LABEL: splat_v16i8: ; NO-SIMD128-NOT: i8x16 ; SIMD128: .param i32{{$}} @@ -73,6 +86,18 @@ define <16 x i8> @replace_v16i8(<16 x i8> %v, i8 %x) { ; ============================================================================== ; 8 x i16 ; ============================================================================== +; CHECK-LABEL: const_v8i16: +; NO-SIMD128-NOT: i16x8 +; SIMD128: .result v128{{$}} +; SIMD128: v128.const $push0=, 256, 770, 1284, 1798, 2312, 2826, 3340, 3854 +; SIMD128-SAME: # encoding: [0xfd,0x00, +; SIMD128-SAME: 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, +; SIMD128-SAME: 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f]{{$}} +define <8 x i16> @const_v8i16() { + ret <8 x i16> <i16 256, i16 770, i16 1284, i16 1798, + i16 2312, i16 2826, i16 3340, i16 3854> +} + ; CHECK-LABEL: splat_v8i16: ; NO-SIMD128-NOT: i16x8 ; SIMD128: .param i32{{$}} @@ -135,6 +160,17 @@ define <8 x i16> @replace_v8i16(<8 x i16> %v, i16 %x) { ; ============================================================================== ; 4 x i32 ; ============================================================================== +; CHECK-LABEL: const_v4i32: +; NO-SIMD128-NOT: i32x4 +; SIMD128: .result v128{{$}} +; SIMD128: v128.const $push0=, 50462976, 117835012, 185207048, 252579084 +; SIMD128-SAME: # encoding: [0xfd,0x00, +; SIMD128-SAME: 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, +; SIMD128-SAME: 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f]{{$}} +define <4 x i32> @const_v4i32() { + ret <4 x i32> <i32 50462976, i32 117835012, i32 185207048, i32 252579084> +} + ; CHECK-LABEL: splat_v4i32: ; NO-SIMD128-NOT: i32x4 ; SIMD128: .param i32{{$}} @@ -173,6 +209,18 @@ define <4 x i32> @replace_v4i32(<4 x i32> %v, i32 %x) { ; ============================================================================== ; 2 x i64 ; ============================================================================== +; CHECK-LABEL: const_v2i64: +; NO-SIMD128-NOT: i64x2 +; SIMD128-VM-NOT: i64x2 +; SIMD128: .result v128{{$}} +; SIMD128: v128.const $push0=, 506097522914230528, 1084818905618843912 +; SIMD128-SAME: # encoding: [0xfd,0x00, +; SIMD128-SAME: 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, +; SIMD128-SAME: 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f]{{$}} +define <2 x i64> @const_v2i64() { + ret <2 x i64> <i64 506097522914230528, i64 1084818905618843912> +} + ; CHECK-LABEL: splat_v2i64: ; NO-SIMD128-NOT: i64x2 ; SIMD128-VM-NOT: i64x2 @@ -213,6 +261,19 @@ define <2 x i64> @replace_v2i64(<2 x i64> %v, i64 %x) { ; ============================================================================== ; 4 x f32 ; ============================================================================== +; CHECK-LABEL: const_v4f32: +; NO-SIMD128-NOT: f32x4 +; SIMD128: .result v128{{$}} +; SIMD128: v128.const $push0=, +; SIMD128-SAME: 0x1.0402p-121, 0x1.0c0a08p-113, 0x1.14121p-105, 0x1.1c1a18p-97 +; SIMD128-SAME: # encoding: [0xfd,0x00, +; SIMD128-SAME: 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, +; SIMD128-SAME: 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f]{{$}} +define <4 x float> @const_v4f32() { + ret <4 x float> <float 0x3860402000000000, float 0x38e0c0a080000000, + float 0x3961412100000000, float 0x39e1c1a180000000> +} + ; CHECK-LABEL: splat_v4f32: ; NO-SIMD128-NOT: f32x4 ; SIMD128: .param f32{{$}} @@ -251,6 +312,17 @@ define <4 x float> @replace_v4f32(<4 x float> %v, float %x) { ; ============================================================================== ; 2 x f64 ; ============================================================================== +; CHECK-LABEL: const_v2f64: +; NO-SIMD128-NOT: f64x2 +; SIMD128: .result v128{{$}} +; SIMD128: v128.const $push0=, 0x1.60504030201p-911, 0x1.e0d0c0b0a0908p-783 +; SIMD128-SAME: # encoding: [0xfd,0x00, +; SIMD128-SAME: 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, +; SIMD128-SAME: 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f]{{$}} +define <2 x double> @const_v2f64() { + ret <2 x double> <double 0x0706050403020100, double 0x0F0E0D0C0B0A0908> +} + ; CHECK-LABEL: splat_v2f64: ; NO-SIMD128-NOT: f64x2 ; SIMD128-VM-NOT: f64x2 diff --git a/llvm/test/MC/Disassembler/WebAssembly/wasm.txt b/llvm/test/MC/Disassembler/WebAssembly/wasm.txt index 63c9bb183c8..aefd9a914a9 100644 --- a/llvm/test/MC/Disassembler/WebAssembly/wasm.txt +++ b/llvm/test/MC/Disassembler/WebAssembly/wasm.txt @@ -31,3 +31,7 @@ # Prefix byte example: # CHECK: i64.trunc_u:sat/f64 0xFC 0x07 + +# v128.const is arbitrarily disassembled as v2f64 +# CHECK: v128.const 0x1.60504030201p-911, 0x1.e0d0c0b0a0908p-783 +0xFD 0x00 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F diff --git a/llvm/test/MC/WebAssembly/basic-assembly.s b/llvm/test/MC/WebAssembly/basic-assembly.s index dbfd921ad78..dd9bd3ca999 100644 --- a/llvm/test/MC/WebAssembly/basic-assembly.s +++ b/llvm/test/MC/WebAssembly/basic-assembly.s @@ -1,17 +1,19 @@ -# RUN: llvm-mc -triple=wasm32-unknown-unknown < %s | FileCheck %s +# RUN: llvm-mc -triple=wasm32-unknown-unknown -mattr=+sign_ext,+simd128 < %s | FileCheck %s .text .type test0,@function test0: # Test all types: .param i32, i64 - .local f32, f64 #, i8x16, i16x8, i32x4, f32x4 + .local f32, f64, v128, v128 # Explicit getlocal/setlocal: get_local $push0=, 2 set_local 2, $pop0= # Implicit locals & immediates: i32.const $0=, -1 f64.const $3=, 0x1.999999999999ap1 + v128.const $4=, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 + v128.const $5=, 0, 1, 2, 3, 4, 5, 6, 7 # Indirect addressing: get_local $push1=, 0 f64.store 0($pop1), $3 @@ -37,6 +39,9 @@ test0: .LBB0_2: end_loop end_block # label0: + get_local $push12=, 4 + get_local $push13=, 5 + f32x4.add $4=, $pop12, $pop13 end_function @@ -48,6 +53,8 @@ test0: # CHECK-NEXT: set_local 2, $pop0 # CHECK-NEXT: i32.const $0=, -1 # CHECK-NEXT: f64.const $3=, 0x1.999999999999ap1 +# CHECK-NEXT: v128.const $4=, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 +# CHECK-NEXT: v128.const $5=, 0, 1, 2, 3, 4, 5, 6, 7 # CHECK-NEXT: get_local $push1=, 0 # CHECK-NEXT: f64.store 0($pop1):p2align=0, $3 # CHECK-NEXT: block @@ -71,4 +78,7 @@ test0: # CHECK-NEXT: .LBB0_2: # CHECK-NEXT: end_loop # CHECK-NEXT: end_block # label0: +# CHECK-NEXT: get_local $push12=, 4 +# CHECK-NEXT: get_local $push13=, 5 +# CHECK-NEXT: f32x4.add $4=, $pop12, $pop13 # CHECK-NEXT: end_function |