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