Index: include/llvm/BinaryFormat/Wasm.h =================================================================== --- include/llvm/BinaryFormat/Wasm.h +++ include/llvm/BinaryFormat/Wasm.h @@ -191,6 +191,7 @@ WASM_TYPE_I64 = 0x7E, WASM_TYPE_F32 = 0x7D, WASM_TYPE_F64 = 0x7C, + WASM_TYPE_V128 = 0x7B, WASM_TYPE_ANYFUNC = 0x70, WASM_TYPE_EXCEPT_REF = 0x68, WASM_TYPE_FUNC = 0x60, @@ -225,6 +226,7 @@ I64 = WASM_TYPE_I64, F32 = WASM_TYPE_F32, F64 = WASM_TYPE_F64, + V128 = WASM_TYPE_V128, EXCEPT_REF = WASM_TYPE_EXCEPT_REF, }; Index: lib/ObjectYAML/WasmYAML.cpp =================================================================== --- lib/ObjectYAML/WasmYAML.cpp +++ lib/ObjectYAML/WasmYAML.cpp @@ -452,6 +452,7 @@ ECase(I64); ECase(F32); ECase(F64); + ECase(V128); ECase(ANYFUNC); ECase(FUNC); ECase(NORESULT); Index: lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h =================================================================== --- lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h +++ lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h @@ -51,7 +51,6 @@ namespace WebAssembly { const char *TypeToString(MVT Ty); -const char *TypeToString(wasm::ValType Type); } // end namespace WebAssembly Index: lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp =================================================================== --- lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp +++ lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp @@ -258,19 +258,3 @@ llvm_unreachable("unsupported type"); } } - -const char *llvm::WebAssembly::TypeToString(wasm::ValType Type) { - switch (Type) { - case wasm::ValType::I32: - return "i32"; - case wasm::ValType::I64: - return "i64"; - case wasm::ValType::F32: - return "f32"; - case wasm::ValType::F64: - return "f64"; - case wasm::ValType::EXCEPT_REF: - return "except_ref"; - } - llvm_unreachable("unsupported type"); -} Index: lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp =================================================================== --- lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp +++ lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp @@ -133,6 +133,13 @@ return wasm::ValType::F32; case MVT::f64: return wasm::ValType::F64; + case MVT::v16i8: + case MVT::v8i16: + case MVT::v4i32: + case MVT::v2i64: + case MVT::v4f32: + case MVT::v2f64: + return wasm::ValType::V128; case MVT::ExceptRef: return wasm::ValType::EXCEPT_REF; default: Index: lib/Target/WebAssembly/WebAssemblyInstrCall.td =================================================================== --- lib/Target/WebAssembly/WebAssemblyInstrCall.td +++ lib/Target/WebAssembly/WebAssemblyInstrCall.td @@ -89,12 +89,12 @@ defm "" : CALL; defm "" : CALL; defm "" : CALL; - defm "" : SIMD_CALL; - defm "" : SIMD_CALL; - defm "" : SIMD_CALL; - defm "" : SIMD_CALL; - defm "" : SIMD_CALL; - defm "" : SIMD_CALL; + defm "" : SIMD_CALL; + defm "" : SIMD_CALL; + defm "" : SIMD_CALL; + defm "" : SIMD_CALL; + defm "" : SIMD_CALL; + defm "" : SIMD_CALL; defm CALL_VOID : I<(outs), (ins function32_op:$callee, variable_ops), (outs), (ins function32_op:$callee), Index: lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp =================================================================== --- lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp +++ lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp @@ -149,6 +149,8 @@ return wasm::ValType::F32; if (RC == &WebAssembly::F64RegClass) return wasm::ValType::F64; + if (RC == &WebAssembly::V128RegClass) + return wasm::ValType::V128; llvm_unreachable("Unexpected register class"); } Index: test/CodeGen/WebAssembly/call.ll =================================================================== --- test/CodeGen/WebAssembly/call.ll +++ test/CodeGen/WebAssembly/call.ll @@ -1,5 +1,5 @@ -; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-keep-registers -wasm-temporary-workarounds=false | FileCheck %s -; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-keep-registers -fast-isel -fast-isel-abort=1 -wasm-temporary-workarounds=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-keep-registers -wasm-temporary-workarounds=false -mattr=+sign-ext,+simd128 | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-keep-registers -fast-isel -fast-isel-abort=1 -wasm-temporary-workarounds=false -mattr=+sign-ext,+simd128 | FileCheck %s ; Test that basic call operations assemble as expected. @@ -12,6 +12,7 @@ declare i64 @i64_nullary() declare float @float_nullary() declare double @double_nullary() +declare <16 x i8> @v128_nullary() declare void @void_nullary() ; CHECK-LABEL: call_i32_nullary: @@ -50,6 +51,15 @@ ret double %r } +; CHECK-LABEL: call_v128_nullary: +; CHECK-NEXT: .result v128{{$}} +; CHECK-NEXT: {{^}} v128.call $push[[NUM:[0-9]+]]=, v128_nullary@FUNCTION{{$}} +; CHECK-NEXT: return $pop[[NUM]]{{$}} +define <16 x i8> @call_v128_nullary() { + %r = call <16 x i8> @v128_nullary() + ret <16 x i8> %r +} + ; CHECK-LABEL: call_void_nullary: ; CHECK-NEXT: {{^}} call void_nullary@FUNCTION{{$}} ; CHECK-NEXT: return{{$}} @@ -102,6 +112,17 @@ ret i32 %t } +; CHECK-LABEL: call_indirect_v128: +; CHECK-NEXT: .param i32{{$}} +; CHECK-NEXT: .result v128{{$}} +; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} +; CHECK-NEXT: {{^}} v128.call_indirect $push[[NUM:[0-9]+]]=, $pop[[L0]]{{$}} +; CHECK-NEXT: return $pop[[NUM]]{{$}} +define <16 x i8> @call_indirect_v128(<16 x i8> ()* %callee) { + %t = call <16 x i8> %callee() + ret <16 x i8> %t +} + ; CHECK-LABEL: call_indirect_arg: ; CHECK-NEXT: .param i32, i32{{$}} ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 1{{$}} Index: test/MC/WebAssembly/types.ll =================================================================== --- /dev/null +++ test/MC/WebAssembly/types.ll @@ -0,0 +1,52 @@ +; RUN: llc -wasm-enable-unimplemented-simd -mattr=+sign-ext,+simd128 -filetype=obj %s -o - | obj2yaml | FileCheck %s + +target triple = "wasm32-unknown-unknown" + +declare i32 @i32() +declare i64 @i64() +declare float @f32() +declare double @f64() +declare <16 x i8> @v16i8() +declare <8 x i16> @v8i16() +declare <4 x i32> @v4i32() +declare <2 x i64> @v2i64() +declare <4 x float> @v4f32() +declare <2 x double> @v2f64() + +define void @f1() { +entry: + %tmp1 = call i32 @i32() + %tmp2 = call i64 @i64() + %tmp3 = call float @f32() + %tmp4 = call double @f64() + %tmp5 = call <16 x i8> @v16i8() + %tmp6 = call <8 x i16> @v8i16() + %tmp7 = call <4 x i32> @v4i32() + %tmp8 = call <2 x i64> @v2i64() + %tmp9 = call <4 x float> @v4f32() + %tmp10 = call <2 x double> @v2f64() + ret void +} + +; CHECK-LABEL: - Type: TYPE +; CHECK-NEXT: Signatures: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: ReturnType: NORESULT +; CHECK-NEXT: ParamTypes: +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: ReturnType: I32 +; CHECK-NEXT: ParamTypes: +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: ReturnType: I64 +; CHECK-NEXT: ParamTypes: +; CHECK-NEXT: - Index: 3 +; CHECK-NEXT: ReturnType: F32 +; CHECK-NEXT: ParamTypes: +; CHECK-NEXT: - Index: 4 +; CHECK-NEXT: ReturnType: F64 +; CHECK-NEXT: ParamTypes: +; CHECK-NEXT: - Index: 5 +; CHECK-NEXT: ReturnType: V128 +; CHECK-NEXT: ParamTypes: +; should be no additional types +; CHECK-NOT: ReturnType