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 #include "llvm/CodeGen/TargetRegisterInfo.h"
17 
18 // Get register classes enum.
19 #define GET_REGINFO_ENUM
20 #include "WebAssemblyGenRegisterInfo.inc"
21 
22 using namespace llvm;
23 
24 MVT WebAssembly::parseMVT(StringRef Type) {
25   return StringSwitch<MVT>(Type)
26       .Case("i32", MVT::i32)
27       .Case("i64", MVT::i64)
28       .Case("f32", MVT::f32)
29       .Case("f64", MVT::f64)
30       .Case("i64", MVT::i64)
31       .Case("v16i8", MVT::v16i8)
32       .Case("v8i16", MVT::v8i16)
33       .Case("v4i32", MVT::v4i32)
34       .Case("v2i64", MVT::v2i64)
35       .Case("funcref", MVT::funcref)
36       .Case("externref", MVT::externref)
37       .Default(MVT::INVALID_SIMPLE_VALUE_TYPE);
38 }
39 
40 wasm::ValType WebAssembly::toValType(MVT Type) {
41   switch (Type.SimpleTy) {
42   case MVT::i32:
43     return wasm::ValType::I32;
44   case MVT::i64:
45     return wasm::ValType::I64;
46   case MVT::f32:
47     return wasm::ValType::F32;
48   case MVT::f64:
49     return wasm::ValType::F64;
50   case MVT::v16i8:
51   case MVT::v8i16:
52   case MVT::v4i32:
53   case MVT::v2i64:
54   case MVT::v4f32:
55   case MVT::v2f64:
56     return wasm::ValType::V128;
57   case MVT::funcref:
58     return wasm::ValType::FUNCREF;
59   case MVT::externref:
60     return wasm::ValType::EXTERNREF;
61   default:
62     llvm_unreachable("unexpected type");
63   }
64 }
65 
66 wasm::ValType WebAssembly::regClassToValType(const TargetRegisterClass *RC) {
67   assert(RC != nullptr);
68   return regClassToValType(RC->getID());
69 }
70 
71 void WebAssembly::wasmSymbolSetType(MCSymbolWasm *Sym, const Type *GlobalVT,
72                                     const ArrayRef<MVT> &VTs) {
73   assert(!Sym->getType());
74 
75   // Tables are represented as Arrays in LLVM IR therefore
76   // they reach this point as aggregate Array types with an element type
77   // that is a reference type.
78   wasm::ValType ValTy;
79   bool IsTable = false;
80   if (GlobalVT->isArrayTy() && WebAssembly::isWebAssemblyReferenceType(
81                                    GlobalVT->getArrayElementType())) {
82     IsTable = true;
83     const Type *ElTy = GlobalVT->getArrayElementType();
84     if (WebAssembly::isWebAssemblyExternrefType(ElTy))
85       ValTy = wasm::ValType::EXTERNREF;
86     else if (WebAssembly::isWebAssemblyFuncrefType(ElTy))
87       ValTy = wasm::ValType::FUNCREF;
88     else
89       report_fatal_error("unhandled reference type");
90   } else if (VTs.size() == 1) {
91     ValTy = WebAssembly::toValType(VTs[0]);
92   } else
93     report_fatal_error("Aggregate globals not yet implemented");
94 
95   if (IsTable) {
96     Sym->setType(wasm::WASM_SYMBOL_TYPE_TABLE);
97     Sym->setTableType(ValTy);
98   } else {
99     Sym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
100     Sym->setGlobalType(wasm::WasmGlobalType{uint8_t(ValTy), /*Mutable=*/true});
101   }
102 }
103