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