1 //===-- WebAssemblyTypeUtilities.cpp - WebAssembly Type Utility Functions -===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// This file implements several utility functions for WebAssembly type parsing.
11 ///
12 //===----------------------------------------------------------------------===//
13
14 #include "WebAssemblyTypeUtilities.h"
15 #include "llvm/ADT/StringSwitch.h"
16
17 // Get register classes enum.
18 #define GET_REGINFO_ENUM
19 #include "WebAssemblyGenRegisterInfo.inc"
20
21 using namespace llvm;
22
parseType(StringRef Type)23 Optional<wasm::ValType> WebAssembly::parseType(StringRef Type) {
24 // FIXME: can't use StringSwitch because wasm::ValType doesn't have a
25 // "invalid" value.
26 if (Type == "i32")
27 return wasm::ValType::I32;
28 if (Type == "i64")
29 return wasm::ValType::I64;
30 if (Type == "f32")
31 return wasm::ValType::F32;
32 if (Type == "f64")
33 return wasm::ValType::F64;
34 if (Type == "v128" || Type == "i8x16" || Type == "i16x8" || Type == "i32x4" ||
35 Type == "i64x2" || Type == "f32x4" || Type == "f64x2")
36 return wasm::ValType::V128;
37 if (Type == "funcref")
38 return wasm::ValType::FUNCREF;
39 if (Type == "externref")
40 return wasm::ValType::EXTERNREF;
41 return Optional<wasm::ValType>();
42 }
43
parseHeapType(StringRef Type)44 WebAssembly::HeapType WebAssembly::parseHeapType(StringRef Type) {
45 return StringSwitch<WebAssembly::HeapType>(Type)
46 .Case("extern", WebAssembly::HeapType::Externref)
47 .Case("func", WebAssembly::HeapType::Funcref)
48 .Default(WebAssembly::HeapType::Invalid);
49 }
50
parseBlockType(StringRef Type)51 WebAssembly::BlockType WebAssembly::parseBlockType(StringRef Type) {
52 // Multivalue block types are handled separately in parseSignature
53 return StringSwitch<WebAssembly::BlockType>(Type)
54 .Case("i32", WebAssembly::BlockType::I32)
55 .Case("i64", WebAssembly::BlockType::I64)
56 .Case("f32", WebAssembly::BlockType::F32)
57 .Case("f64", WebAssembly::BlockType::F64)
58 .Case("v128", WebAssembly::BlockType::V128)
59 .Case("funcref", WebAssembly::BlockType::Funcref)
60 .Case("externref", WebAssembly::BlockType::Externref)
61 .Case("void", WebAssembly::BlockType::Void)
62 .Default(WebAssembly::BlockType::Invalid);
63 }
64
parseMVT(StringRef Type)65 MVT WebAssembly::parseMVT(StringRef Type) {
66 return StringSwitch<MVT>(Type)
67 .Case("i32", MVT::i32)
68 .Case("i64", MVT::i64)
69 .Case("f32", MVT::f32)
70 .Case("f64", MVT::f64)
71 .Case("i64", MVT::i64)
72 .Case("v16i8", MVT::v16i8)
73 .Case("v8i16", MVT::v8i16)
74 .Case("v4i32", MVT::v4i32)
75 .Case("v2i64", MVT::v2i64)
76 .Case("funcref", MVT::funcref)
77 .Case("externref", MVT::externref)
78 .Default(MVT::INVALID_SIMPLE_VALUE_TYPE);
79 }
80
81 // We have various enums representing a subset of these types, use this
82 // function to convert any of them to text.
anyTypeToString(unsigned Type)83 const char *WebAssembly::anyTypeToString(unsigned Type) {
84 switch (Type) {
85 case wasm::WASM_TYPE_I32:
86 return "i32";
87 case wasm::WASM_TYPE_I64:
88 return "i64";
89 case wasm::WASM_TYPE_F32:
90 return "f32";
91 case wasm::WASM_TYPE_F64:
92 return "f64";
93 case wasm::WASM_TYPE_V128:
94 return "v128";
95 case wasm::WASM_TYPE_FUNCREF:
96 return "funcref";
97 case wasm::WASM_TYPE_EXTERNREF:
98 return "externref";
99 case wasm::WASM_TYPE_FUNC:
100 return "func";
101 case wasm::WASM_TYPE_NORESULT:
102 return "void";
103 default:
104 return "invalid_type";
105 }
106 }
107
typeToString(wasm::ValType Type)108 const char *WebAssembly::typeToString(wasm::ValType Type) {
109 return anyTypeToString(static_cast<unsigned>(Type));
110 }
111
typeListToString(ArrayRef<wasm::ValType> List)112 std::string WebAssembly::typeListToString(ArrayRef<wasm::ValType> List) {
113 std::string S;
114 for (const auto &Type : List) {
115 if (&Type != &List[0])
116 S += ", ";
117 S += WebAssembly::typeToString(Type);
118 }
119 return S;
120 }
121
signatureToString(const wasm::WasmSignature * Sig)122 std::string WebAssembly::signatureToString(const wasm::WasmSignature *Sig) {
123 std::string S("(");
124 S += typeListToString(Sig->Params);
125 S += ") -> (";
126 S += typeListToString(Sig->Returns);
127 S += ")";
128 return S;
129 }
130
toValType(MVT Type)131 wasm::ValType WebAssembly::toValType(MVT Type) {
132 switch (Type.SimpleTy) {
133 case MVT::i32:
134 return wasm::ValType::I32;
135 case MVT::i64:
136 return wasm::ValType::I64;
137 case MVT::f32:
138 return wasm::ValType::F32;
139 case MVT::f64:
140 return wasm::ValType::F64;
141 case MVT::v16i8:
142 case MVT::v8i16:
143 case MVT::v4i32:
144 case MVT::v2i64:
145 case MVT::v4f32:
146 case MVT::v2f64:
147 return wasm::ValType::V128;
148 case MVT::funcref:
149 return wasm::ValType::FUNCREF;
150 case MVT::externref:
151 return wasm::ValType::EXTERNREF;
152 default:
153 llvm_unreachable("unexpected type");
154 }
155 }
156
regClassToValType(unsigned RC)157 wasm::ValType WebAssembly::regClassToValType(unsigned RC) {
158 switch (RC) {
159 case WebAssembly::I32RegClassID:
160 return wasm::ValType::I32;
161 case WebAssembly::I64RegClassID:
162 return wasm::ValType::I64;
163 case WebAssembly::F32RegClassID:
164 return wasm::ValType::F32;
165 case WebAssembly::F64RegClassID:
166 return wasm::ValType::F64;
167 case WebAssembly::V128RegClassID:
168 return wasm::ValType::V128;
169 case WebAssembly::FUNCREFRegClassID:
170 return wasm::ValType::FUNCREF;
171 case WebAssembly::EXTERNREFRegClassID:
172 return wasm::ValType::EXTERNREF;
173 default:
174 llvm_unreachable("unexpected type");
175 }
176 }
177