1//===- WebAssemblyMCTypeUtilities.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 "WebAssemblyMCTypeUtilities.h"
15#include "WebAssemblyMCTargetDesc.h"
16#include "llvm/ADT/StringSwitch.h"
17
18using namespace llvm;
19
20std::optional<wasm::ValType> WebAssembly::parseType(StringRef Type) {
21  // FIXME: can't use StringSwitch because wasm::ValType doesn't have a
22  // "invalid" value.
23  if (Type == "i32")
24    return wasm::ValType::I32;
25  if (Type == "i64")
26    return wasm::ValType::I64;
27  if (Type == "f32")
28    return wasm::ValType::F32;
29  if (Type == "f64")
30    return wasm::ValType::F64;
31  if (Type == "v128" || Type == "i8x16" || Type == "i16x8" || Type == "i32x4" ||
32      Type == "i64x2" || Type == "f32x4" || Type == "f64x2")
33    return wasm::ValType::V128;
34  if (Type == "funcref")
35    return wasm::ValType::FUNCREF;
36  if (Type == "externref")
37    return wasm::ValType::EXTERNREF;
38  return std::nullopt;
39}
40
41WebAssembly::BlockType WebAssembly::parseBlockType(StringRef Type) {
42  // Multivalue block types are handled separately in parseSignature
43  return StringSwitch<WebAssembly::BlockType>(Type)
44      .Case("i32", WebAssembly::BlockType::I32)
45      .Case("i64", WebAssembly::BlockType::I64)
46      .Case("f32", WebAssembly::BlockType::F32)
47      .Case("f64", WebAssembly::BlockType::F64)
48      .Case("v128", WebAssembly::BlockType::V128)
49      .Case("funcref", WebAssembly::BlockType::Funcref)
50      .Case("externref", WebAssembly::BlockType::Externref)
51      .Case("void", WebAssembly::BlockType::Void)
52      .Default(WebAssembly::BlockType::Invalid);
53}
54
55// We have various enums representing a subset of these types, use this
56// function to convert any of them to text.
57const char *WebAssembly::anyTypeToString(unsigned Type) {
58  switch (Type) {
59  case wasm::WASM_TYPE_I32:
60    return "i32";
61  case wasm::WASM_TYPE_I64:
62    return "i64";
63  case wasm::WASM_TYPE_F32:
64    return "f32";
65  case wasm::WASM_TYPE_F64:
66    return "f64";
67  case wasm::WASM_TYPE_V128:
68    return "v128";
69  case wasm::WASM_TYPE_FUNCREF:
70    return "funcref";
71  case wasm::WASM_TYPE_EXTERNREF:
72    return "externref";
73  case wasm::WASM_TYPE_FUNC:
74    return "func";
75  case wasm::WASM_TYPE_NORESULT:
76    return "void";
77  default:
78    return "invalid_type";
79  }
80}
81
82const char *WebAssembly::typeToString(wasm::ValType Type) {
83  return anyTypeToString(static_cast<unsigned>(Type));
84}
85
86std::string WebAssembly::typeListToString(ArrayRef<wasm::ValType> List) {
87  std::string S;
88  for (const auto &Type : List) {
89    if (&Type != &List[0])
90      S += ", ";
91    S += WebAssembly::typeToString(Type);
92  }
93  return S;
94}
95
96std::string WebAssembly::signatureToString(const wasm::WasmSignature *Sig) {
97  std::string S("(");
98  S += typeListToString(Sig->Params);
99  S += ") -> (";
100  S += typeListToString(Sig->Returns);
101  S += ")";
102  return S;
103}
104
105wasm::ValType WebAssembly::regClassToValType(unsigned RC) {
106  switch (RC) {
107  case WebAssembly::I32RegClassID:
108    return wasm::ValType::I32;
109  case WebAssembly::I64RegClassID:
110    return wasm::ValType::I64;
111  case WebAssembly::F32RegClassID:
112    return wasm::ValType::F32;
113  case WebAssembly::F64RegClassID:
114    return wasm::ValType::F64;
115  case WebAssembly::V128RegClassID:
116    return wasm::ValType::V128;
117  case WebAssembly::FUNCREFRegClassID:
118    return wasm::ValType::FUNCREF;
119  case WebAssembly::EXTERNREFRegClassID:
120    return wasm::ValType::EXTERNREF;
121  default:
122    llvm_unreachable("unexpected type");
123  }
124}
125