pmatos updated this revision to Diff 282194.
pmatos added a comment.
Update externref patch
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D66035/new/
https://reviews.llvm.org/D66035
Files:
clang/lib/Basic/Targets/WebAssembly.cpp
lld/wasm/WriterUtils.cpp
llvm/include/llvm/BinaryFormat/Wasm.h
llvm/include/llvm/BinaryFormat/WasmRelocs.def
llvm/include/llvm/CodeGen/TargetLowering.h
llvm/include/llvm/CodeGen/ValueTypes.td
llvm/include/llvm/MC/MCExpr.h
llvm/include/llvm/MC/MCSymbolWasm.h
llvm/include/llvm/Object/Wasm.h
llvm/include/llvm/Support/MachineValueType.h
llvm/lib/BinaryFormat/Wasm.cpp
llvm/lib/CodeGen/CodeGenPrepare.cpp
llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
llvm/lib/CodeGen/ValueTypes.cpp
llvm/lib/MC/MCExpr.cpp
llvm/lib/MC/WasmObjectWriter.cpp
llvm/lib/Object/WasmObjectFile.cpp
llvm/lib/ObjectYAML/WasmEmitter.cpp
llvm/lib/ObjectYAML/WasmYAML.cpp
llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp
llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp
llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp
llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp
llvm/lib/Target/WebAssembly/WebAssembly.h
llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp
llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp
llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td
llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp
llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.td
llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
llvm/test/CodeGen/WebAssembly/externref.ll
llvm/test/CodeGen/WebAssembly/reg-argument.mir
llvm/test/CodeGen/WebAssembly/reg-copy.mir
llvm/utils/TableGen/CodeGenTarget.cpp
Index: llvm/utils/TableGen/CodeGenTarget.cpp
===================================================================
--- llvm/utils/TableGen/CodeGenTarget.cpp
+++ llvm/utils/TableGen/CodeGenTarget.cpp
@@ -219,6 +219,7 @@
case MVT::iPTRAny: return "MVT::iPTRAny";
case MVT::Untyped: return "MVT::Untyped";
case MVT::exnref: return "MVT::exnref";
+ case MVT::externref: return "MVT::externref";
default: llvm_unreachable("ILLEGAL VALUE TYPE!");
}
}
Index: llvm/test/CodeGen/WebAssembly/reg-copy.mir
===================================================================
--- llvm/test/CodeGen/WebAssembly/reg-copy.mir
+++ llvm/test/CodeGen/WebAssembly/reg-copy.mir
@@ -66,3 +66,14 @@
%0:exnref = COPY %1:exnref
RETURN implicit-def $arguments
...
+---
+name: copy_externref
+# CHECK-LABEL: copy_externref
+body: |
+ ; CHECK-LABEL: bb.0
+ ; CHECK-NEXT: %0:externref = COPY_EXTERNREF %1:externref
+ ; CHECK-NEXT: RETURN
+ bb.0:
+ %0:externref = COPY %1:externref
+ RETURN implicit-def $arguments
+...
Index: llvm/test/CodeGen/WebAssembly/reg-argument.mir
===================================================================
--- llvm/test/CodeGen/WebAssembly/reg-argument.mir
+++ llvm/test/CodeGen/WebAssembly/reg-argument.mir
@@ -57,3 +57,14 @@
%1:exnref = ARGUMENT_exnref 0, implicit $arguments
RETURN implicit-def $arguments
...
+---
+name: argument_externref
+# CHECK-LABEL: argument_externref
+body: |
+ ; CHECK-LABEL: bb.0:
+ ; CHECK-NEXT: %1:externref = ARGUMENT_externref 0
+ bb.0:
+ %0:i32 = CONST_I32 0, implicit-def $arguments
+ %1:externref = ARGUMENT_externref 0, implicit $arguments
+ RETURN implicit-def $arguments
+...
Index: llvm/test/CodeGen/WebAssembly/externref.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/externref.ll
@@ -0,0 +1,29 @@
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+reference-types | FileCheck %s
+
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128-ni:256"
+target triple = "wasm32-unknown-unknown"
+
+declare i8 addrspace(256)* @test(i8 addrspace(256)*)
+
+
+; CHECK-LABEL: call_test:
+; CHECK: .functype call_test (externref) -> (externref)
+define i8 addrspace(256)* @call_test(i8 addrspace(256)*) {
+; CHECK: call $push0=, test, $0
+ %a = call i8 addrspace(256)* @test(i8 addrspace(256)* %0)
+ ret i8 addrspace(256)* %a
+}
+
+; TODO: nullref?
+; define i8 addrspace(256)* @null_test() {
+; ret i8 addrspace(256)* null
+; }
+
+; TODO: Loading a externref from a pointer
+; @glob = external global i8 addrspace(256)*, align 4
+; define i8 addrspace(256)* @global_test() {
+; %a = load i8 addrspace(256)*, i8 addrspace(256)** @glob
+; ret i8 addrspace(256)* %a
+; }
+
+; CHECK: .functype test (externref) -> (externref)
Index: llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
@@ -112,15 +112,45 @@
return *RM;
}
+static bool HasReferenceTypes(StringRef FS) {
+ bool ReferenceTypes = false;
+ SmallVector<StringRef, 3> Features;
+
+ FS.split(Features, ',', -1, false /* KeepEmpty */);
+ for (auto &Feature : Features) {
+ if (Feature == "reference-types" || Feature == "+reference-types")
+ ReferenceTypes = true;
+ if (Feature == "-reference-types")
+ ReferenceTypes = false;
+ }
+
+ return ReferenceTypes;
+}
+
+static std::string computeDataLayout(const Triple &TT, StringRef FS) {
+ std::string Ret = "e-m:e"; // little endian, mangling elf
+
+ if (TT.isArch64Bit()) {
+ Ret += "-p:64:64";
+ } else {
+ Ret += "-p:32:32";
+ }
+
+ Ret += "-i64:64-n32:64-S128";
+
+ if (HasReferenceTypes(FS)) {
+ Ret += "-ni:256"; // externref
+ }
+ return Ret;
+}
+
/// Create an WebAssembly architecture model.
///
WebAssemblyTargetMachine::WebAssemblyTargetMachine(
const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
const TargetOptions &Options, Optional<Reloc::Model> RM,
Optional<CodeModel::Model> CM, CodeGenOpt::Level OL, bool JIT)
- : LLVMTargetMachine(T,
- TT.isArch64Bit() ? "e-m:e-p:64:64-i64:64-n32:64-S128"
- : "e-m:e-p:32:32-i64:64-n32:64-S128",
+ : LLVMTargetMachine(T, computeDataLayout(TT, FS),
TT, CPU, FS, Options, getEffectiveRelocModel(RM, TT),
getEffectiveCodeModel(CM, CodeModel::Large), OL),
TLOF(new WebAssemblyTargetObjectFile()) {
Index: llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.td
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.td
+++ llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.td
@@ -44,6 +44,7 @@
def V128_0: WebAssemblyReg<"%v128">;
def EXNREF_0 : WebAssemblyReg<"%exnref.0">;
+def EXTERNREF_0 : WebAssemblyReg<"%externref.0">;
// The value stack "register". This is an opaque entity which serves to order
// uses and defs that must remain in LIFO order.
@@ -65,3 +66,4 @@
def V128 : WebAssemblyRegClass<[v4f32, v2f64, v2i64, v4i32, v16i8, v8i16], 128,
(add V128_0)>;
def EXNREF : WebAssemblyRegClass<[exnref], 0, (add EXNREF_0)>;
+def EXTERNREF : WebAssemblyRegClass<[externref], 0, (add EXTERNREF_0)>;
Index: llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp
@@ -114,6 +114,9 @@
case WebAssembly::EXNREFRegClassID:
CopyLocalOpc = WebAssembly::COPY_EXNREF;
break;
+ case WebAssembly::EXTERNREFRegClassID:
+ CopyLocalOpc = WebAssembly::COPY_EXTERNREF;
+ break;
default:
llvm_unreachable("Unexpected register class for return operand");
}
Index: llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
@@ -61,6 +61,11 @@
WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
}
+ unsigned TargetFlags = MO.getTargetFlags();
+ if (TargetFlags == WebAssemblyII::MO_TABLE_INDEX) {
+ WasmSym->setType(wasm::WASM_SYMBOL_TYPE_TABLE);
+ }
+
return WasmSym;
}
@@ -88,6 +93,12 @@
return WasmSym;
}
+ unsigned TargetFlags = MO.getTargetFlags();
+ if (TargetFlags == WebAssemblyII::MO_TABLE_INDEX) {
+ WasmSym->setType(wasm::WASM_SYMBOL_TYPE_TABLE);
+ return WasmSym;
+ }
+
SmallVector<wasm::ValType, 4> Returns;
SmallVector<wasm::ValType, 4> Params;
if (strcmp(Name, "__cpp_exception") == 0) {
@@ -128,6 +139,9 @@
switch (TargetFlags) {
case WebAssemblyII::MO_NO_FLAG:
break;
+ case WebAssemblyII::MO_TABLE_INDEX:
+ Kind = MCSymbolRefExpr::VK_WASM_TABLEINDEX;
+ break;
case WebAssemblyII::MO_GOT:
Kind = MCSymbolRefExpr::VK_GOT;
break;
Index: llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td
===================================================================
--- /dev/null
+++ llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td
@@ -0,0 +1,12 @@
+multiclass WebAssemblyTableGet<WebAssemblyRegClass rc, string Name, int Opcode> {
+ let mayLoad = 1, UseNamedOperandTable = 1 in
+ defm "": I<(outs rc:$dst),
+ (ins table_op: $table, I32:$offset),
+ (outs), (ins table_op: $table),
+ [], !strconcat(Name, "\t$dst, ${offset}(${table})"),
+ !strconcat(Name, "\t${table}"), Opcode>;
+}
+
+defm TABLE_GET : WebAssemblyTableGet<EXTERNREF, "table.get", 0x25>;
+
+def : Pat<(externref (load (WebAssemblywrapper externref:$addr))), (TABLE_GET externref:$addr, (CONST_I32 0))>;
Index: llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
+++ llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
@@ -136,6 +136,9 @@
let OperandType = "OPERAND_GLOBAL" in
def global_op : Operand<i32>;
+let OperandType = "OPERAND_TABLE" in
+def table_op : Operand<externref>;
+
let OperandType = "OPERAND_I32IMM" in
def i32imm_op : Operand<i32>;
@@ -237,6 +240,7 @@
defm "": ARGUMENT<F32, f32>;
defm "": ARGUMENT<F64, f64>;
defm "": ARGUMENT<EXNREF, exnref>;
+defm "": ARGUMENT<EXTERNREF, externref>;
// local.get and local.set are not generated by instruction selection; they
// are implied by virtual register uses and defs.
@@ -307,6 +311,7 @@
defm "" : LOCAL<F64>;
defm "" : LOCAL<V128>, Requires<[HasSIMD128]>;
defm "" : LOCAL<EXNREF>, Requires<[HasExceptionHandling]>;
+defm "" : LOCAL<EXTERNREF>, Requires<[HasReferenceTypes]>;
let isMoveImm = 1, isAsCheapAsAMove = 1, isReMaterializable = 1 in {
defm CONST_I32 : I<(outs I32:$res), (ins i32imm_op:$imm),
@@ -365,3 +370,4 @@
include "WebAssemblyInstrSIMD.td"
include "WebAssemblyInstrRef.td"
include "WebAssemblyInstrBulkMemory.td"
+include "WebAssemblyInstrTable.td"
Index: llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp
@@ -78,6 +78,8 @@
CopyOpcode = WebAssembly::COPY_V128;
else if (RC == &WebAssembly::EXNREFRegClass)
CopyOpcode = WebAssembly::COPY_EXNREF;
+ else if (RC == &WebAssembly::EXTERNREFRegClass)
+ CopyOpcode = WebAssembly::COPY_EXTERNREF;
else
llvm_unreachable("Unexpected register class");
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
@@ -15,6 +15,7 @@
#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYISELLOWERING_H
#define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYISELLOWERING_H
+#include "WebAssembly.h"
#include "llvm/CodeGen/TargetLowering.h"
namespace llvm {
@@ -50,6 +51,18 @@
/// right decision when generating code for different targets.
const WebAssemblySubtarget *Subtarget;
+ MVT getPointerTy(const DataLayout &DL, uint32_t AS = 0) const override {
+ return AS == WebAssemblyAS::EXTERNREF_ADDRESS
+ ? MVT::externref
+ : MVT::getIntegerVT(DL.getPointerSizeInBits(AS));
+ }
+
+ MVT getPointerMemTy(const DataLayout &DL, uint32_t AS = 0) const override {
+ return AS == WebAssemblyAS::EXTERNREF_ADDRESS
+ ? MVT::externref
+ : MVT::getIntegerVT(DL.getPointerSizeInBits(AS));
+ }
+
AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *) const override;
FastISel *createFastISel(FunctionLoweringInfo &FuncInfo,
const TargetLibraryInfo *LibInfo) const override;
@@ -95,6 +108,7 @@
void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
SelectionDAG &DAG) const override;
+ bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const override;
const char *getClearCacheBuiltinName() const override {
report_fatal_error("llvm.clear_cache is not supported on wasm");
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -13,6 +13,7 @@
#include "WebAssemblyISelLowering.h"
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
+#include "WebAssembly.h"
#include "WebAssemblyMachineFunctionInfo.h"
#include "WebAssemblySubtarget.h"
#include "WebAssemblyTargetMachine.h"
@@ -64,6 +65,10 @@
addRegisterClass(MVT::v2i64, &WebAssembly::V128RegClass);
addRegisterClass(MVT::v2f64, &WebAssembly::V128RegClass);
}
+ if (Subtarget->hasReferenceTypes()) {
+ addRegisterClass(MVT::externref, &WebAssembly::EXTERNREFRegClass);
+ setOperationAction(ISD::GlobalAddress, MVT::externref, Custom);
+ }
// Compute derived properties from the register classes.
computeRegisterProperties(Subtarget->getRegisterInfo());
@@ -1080,6 +1085,14 @@
return Chain;
}
+bool WebAssemblyTargetLowering::isNoopAddrSpaceCast(unsigned SrcAS,
+ unsigned DestAS) const {
+ assert(SrcAS != DestAS && "Expected different address spaces!");
+
+ return SrcAS <= WebAssemblyAS::MAX_CUSTOM_ADDRESS &&
+ DestAS <= WebAssemblyAS::MAX_CUSTOM_ADDRESS;
+}
+
void WebAssemblyTargetLowering::ReplaceNodeResults(
SDNode *N, SmallVectorImpl<SDValue> &Results, SelectionDAG &DAG) const {
switch (N->getOpcode()) {
@@ -1225,8 +1238,9 @@
EVT VT = Op.getValueType();
assert(GA->getTargetFlags() == 0 &&
"Unexpected target flags on generic GlobalAddressSDNode");
- if (GA->getAddressSpace() != 0)
- fail(DL, DAG, "WebAssembly only expects the 0 address space");
+ if (GA->getAddressSpace() != 0 &&
+ GA->getAddressSpace() != WebAssemblyAS::EXTERNREF_ADDRESS)
+ fail(DL, DAG, "WebAssembly only expects the 0 or 256 (externref) address space");
unsigned OperandFlags = 0;
if (isPositionIndependent()) {
@@ -1258,6 +1272,10 @@
}
}
+ if (GA->getAddressSpace() == WebAssemblyAS::EXTERNREF_ADDRESS) {
+ OperandFlags = WebAssemblyII::MO_TABLE_INDEX;
+ }
+
return DAG.getNode(WebAssemblyISD::Wrapper, DL, VT,
DAG.getTargetGlobalAddress(GA->getGlobal(), DL, VT,
GA->getOffset(), OperandFlags));
Index: llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
@@ -130,6 +130,7 @@
case MVT::f32:
case MVT::f64:
case MVT::exnref:
+ case MVT::externref:
return VT;
case MVT::f16:
return MVT::f32;
@@ -709,6 +710,10 @@
Opc = WebAssembly::ARGUMENT_exnref;
RC = &WebAssembly::EXNREFRegClass;
break;
+ case MVT::externref:
+ Opc = WebAssembly::ARGUMENT_externref;
+ RC = &WebAssembly::EXTERNREFRegClass;
+ break;
default:
return false;
}
@@ -810,6 +815,9 @@
case MVT::exnref:
ResultReg = createResultReg(&WebAssembly::EXNREFRegClass);
break;
+ case MVT::externref:
+ ResultReg = createResultReg(&WebAssembly::EXTERNREFRegClass);
+ break;
default:
return false;
}
@@ -1323,6 +1331,7 @@
case MVT::v4f32:
case MVT::v2f64:
case MVT::exnref:
+ case MVT::externref:
break;
default:
return false;
Index: llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp
@@ -98,6 +98,8 @@
return WebAssembly::DROP_V128;
if (RC == &WebAssembly::EXNREFRegClass)
return WebAssembly::DROP_EXNREF;
+ if (RC == &WebAssembly::EXTERNREFRegClass)
+ return WebAssembly::DROP_EXTERNREF;
llvm_unreachable("Unexpected register class");
}
@@ -115,6 +117,8 @@
return WebAssembly::LOCAL_GET_V128;
if (RC == &WebAssembly::EXNREFRegClass)
return WebAssembly::LOCAL_GET_EXNREF;
+ if (RC == &WebAssembly::EXTERNREFRegClass)
+ return WebAssembly::LOCAL_GET_EXTERNREF;
llvm_unreachable("Unexpected register class");
}
@@ -132,6 +136,8 @@
return WebAssembly::LOCAL_SET_V128;
if (RC == &WebAssembly::EXNREFRegClass)
return WebAssembly::LOCAL_SET_EXNREF;
+ if (RC == &WebAssembly::EXNREFRegClass)
+ return WebAssembly::LOCAL_SET_EXTERNREF;
llvm_unreachable("Unexpected register class");
}
@@ -149,6 +155,8 @@
return WebAssembly::LOCAL_TEE_V128;
if (RC == &WebAssembly::EXNREFRegClass)
return WebAssembly::LOCAL_TEE_EXNREF;
+ if (RC == &WebAssembly::EXTERNREFRegClass)
+ return WebAssembly::LOCAL_TEE_EXTERNREF;
llvm_unreachable("Unexpected register class");
}
@@ -166,6 +174,8 @@
return MVT::v16i8;
if (RC == &WebAssembly::EXNREFRegClass)
return MVT::exnref;
+ if (RC == &WebAssembly::EXTERNREFRegClass)
+ return MVT::externref;
llvm_unreachable("unrecognized register class");
}
Index: llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
@@ -346,6 +346,7 @@
case WebAssembly::ARGUMENT_v4f32_S:
case WebAssembly::ARGUMENT_v2f64:
case WebAssembly::ARGUMENT_v2f64_S:
+ case WebAssembly::ARGUMENT_externref:
// These represent values which are live into the function entry, so there's
// no instruction to emit.
break;
Index: llvm/lib/Target/WebAssembly/WebAssembly.h
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssembly.h
+++ llvm/lib/Target/WebAssembly/WebAssembly.h
@@ -96,4 +96,12 @@
} // end namespace llvm
+namespace WebAssemblyAS {
+enum : unsigned {
+ // The maxium value for custom address-spaces.
+ MAX_CUSTOM_ADDRESS = 255,
+ EXTERNREF_ADDRESS = 256, // Address space for externref
+};
+}
+
#endif
Index: llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp
+++ llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp
@@ -73,6 +73,8 @@
switch (Modifier) {
case MCSymbolRefExpr::VK_GOT:
return wasm::R_WASM_GLOBAL_INDEX_LEB;
+ case MCSymbolRefExpr::VK_WASM_TABLEINDEX:
+ return wasm::R_WASM_TABLE_INDEX_LEB;
case MCSymbolRefExpr::VK_WASM_TBREL:
assert(SymA.isFunction());
return wasm::R_WASM_TABLE_INDEX_REL_SLEB;
@@ -102,6 +104,8 @@
return wasm::R_WASM_FUNCTION_INDEX_LEB;
if (SymA.isEvent())
return wasm::R_WASM_EVENT_INDEX_LEB;
+ if (SymA.isTable())
+ return wasm::R_WASM_TABLE_INDEX_LEB;
return wasm::R_WASM_MEMORY_ADDR_LEB;
case WebAssembly::fixup_uleb128_i64:
assert(SymA.isData());
Index: llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
===================================================================
--- llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
+++ llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
@@ -44,6 +44,8 @@
OPERAND_LOCAL,
/// Global index.
OPERAND_GLOBAL,
+ /// Table index.
+ OPERAND_TABLE,
/// 32-bit integer immediates.
OPERAND_I32IMM,
/// 64-bit integer immediates.
@@ -100,6 +102,9 @@
// address relative the __table_base wasm global.
// Only applicable to function symbols.
MO_TABLE_BASE_REL,
+
+ // On a symbol operand this indicates that this operand is a table index.
+ MO_TABLE_INDEX,
};
} // end namespace WebAssemblyII
@@ -130,6 +135,7 @@
F64 = unsigned(wasm::ValType::F64),
V128 = unsigned(wasm::ValType::V128),
Exnref = unsigned(wasm::ValType::EXNREF),
+ Externref = unsigned(wasm::ValType::EXTERNREF),
// Multivalue blocks (and other non-void blocks) are only emitted when the
// blocks will never be exited and are at the ends of functions (see
// WebAssemblyCFGStackify::fixEndsAtEndOfFunction). They also are never made
@@ -296,6 +302,8 @@
case WebAssembly::ARGUMENT_v2f64_S:
case WebAssembly::ARGUMENT_exnref:
case WebAssembly::ARGUMENT_exnref_S:
+ case WebAssembly::ARGUMENT_externref:
+ case WebAssembly::ARGUMENT_externref_S:
return true;
default:
return false;
@@ -316,6 +324,8 @@
case WebAssembly::COPY_V128_S:
case WebAssembly::COPY_EXNREF:
case WebAssembly::COPY_EXNREF_S:
+ case WebAssembly::COPY_EXTERNREF:
+ case WebAssembly::COPY_EXTERNREF_S:
return true;
default:
return false;
@@ -336,6 +346,8 @@
case WebAssembly::TEE_V128_S:
case WebAssembly::TEE_EXNREF:
case WebAssembly::TEE_EXNREF_S:
+ case WebAssembly::TEE_EXTERNREF:
+ case WebAssembly::TEE_EXTERNREF_S:
return true;
default:
return false;
Index: llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp
+++ llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp
@@ -149,6 +149,8 @@
return wasm::ValType::V128;
case MVT::exnref:
return wasm::ValType::EXNREF;
+ case MVT::externref:
+ return wasm::ValType::EXTERNREF;
default:
llvm_unreachable("unexpected type");
}
Index: llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp
+++ llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp
@@ -155,6 +155,7 @@
case WebAssembly::OPERAND_SIGNATURE:
case WebAssembly::OPERAND_TYPEINDEX:
case WebAssembly::OPERAND_GLOBAL:
+ case WebAssembly::OPERAND_TABLE:
case WebAssembly::OPERAND_EVENT:
FixupKind = MCFixupKind(WebAssembly::fixup_uleb128_i32);
break;
Index: llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
+++ llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
@@ -318,6 +318,8 @@
return "v128";
case wasm::WASM_TYPE_FUNCREF:
return "funcref";
+ case wasm::WASM_TYPE_EXTERNREF:
+ return "externref";
case wasm::WASM_TYPE_FUNC:
return "func";
case wasm::WASM_TYPE_EXNREF:
Index: llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp
+++ llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp
@@ -197,6 +197,7 @@
case WebAssembly::OPERAND_BASIC_BLOCK:
case WebAssembly::OPERAND_LOCAL:
case WebAssembly::OPERAND_GLOBAL:
+ case WebAssembly::OPERAND_TABLE:
case WebAssembly::OPERAND_FUNCTION32:
case WebAssembly::OPERAND_OFFSET32:
case WebAssembly::OPERAND_OFFSET64:
Index: llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
+++ llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
@@ -336,6 +336,7 @@
.Case("f64", WebAssembly::BlockType::F64)
.Case("v128", WebAssembly::BlockType::V128)
.Case("exnref", WebAssembly::BlockType::Exnref)
+ .Case("externref", WebAssembly::BlockType::Externref)
.Case("void", WebAssembly::BlockType::Void)
.Default(WebAssembly::BlockType::Invalid);
}
Index: llvm/lib/ObjectYAML/WasmYAML.cpp
===================================================================
--- llvm/lib/ObjectYAML/WasmYAML.cpp
+++ llvm/lib/ObjectYAML/WasmYAML.cpp
@@ -498,6 +498,8 @@
IO.mapRequired("Global", Info.ElementIndex);
} else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_EVENT) {
IO.mapRequired("Event", Info.ElementIndex);
+ } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_TABLE) {
+ IO.mapRequired("Table", Info.ElementIndex);
} else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_DATA) {
if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) {
IO.mapRequired("Segment", Info.DataRef.Segment);
@@ -553,6 +555,7 @@
ECase(GLOBAL);
ECase(SECTION);
ECase(EVENT);
+ ECase(TABLE);
#undef ECase
}
@@ -599,6 +602,7 @@
IO &IO, WasmYAML::TableType &Type) {
#define ECase(X) IO.enumCase(Type, #X, wasm::WASM_TYPE_##X);
ECase(FUNCREF);
+ ECase(EXTERNREF);
#undef ECase
}
Index: llvm/lib/ObjectYAML/WasmEmitter.cpp
===================================================================
--- llvm/lib/ObjectYAML/WasmEmitter.cpp
+++ llvm/lib/ObjectYAML/WasmEmitter.cpp
@@ -188,6 +188,7 @@
case wasm::WASM_SYMBOL_TYPE_FUNCTION:
case wasm::WASM_SYMBOL_TYPE_GLOBAL:
case wasm::WASM_SYMBOL_TYPE_EVENT:
+ case wasm::WASM_SYMBOL_TYPE_TABLE:
encodeULEB128(Info.ElementIndex, SubSection.getStream());
if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0 ||
(Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0)
Index: llvm/lib/Object/WasmObjectFile.cpp
===================================================================
--- llvm/lib/Object/WasmObjectFile.cpp
+++ llvm/lib/Object/WasmObjectFile.cpp
@@ -483,9 +483,11 @@
std::vector<wasm::WasmImport *> ImportedGlobals;
std::vector<wasm::WasmImport *> ImportedFunctions;
std::vector<wasm::WasmImport *> ImportedEvents;
+ std::vector<wasm::WasmImport *> ImportedTables;
ImportedGlobals.reserve(Imports.size());
ImportedFunctions.reserve(Imports.size());
ImportedEvents.reserve(Imports.size());
+ ImportedTables.reserve(Imports.size());
for (auto &I : Imports) {
if (I.Kind == wasm::WASM_EXTERNAL_FUNCTION)
ImportedFunctions.emplace_back(&I);
@@ -493,6 +495,8 @@
ImportedGlobals.emplace_back(&I);
else if (I.Kind == wasm::WASM_EXTERNAL_EVENT)
ImportedEvents.emplace_back(&I);
+ else if (I.Kind == wasm::WASM_EXTERNAL_TABLE)
+ ImportedTables.emplace_back(&I);
}
while (Count--) {
@@ -632,6 +636,27 @@
break;
}
+ case wasm::WASM_SYMBOL_TYPE_TABLE: {
+ Info.ElementIndex = readVaruint32(Ctx);
+ if (!isValidTableIndex(Info.ElementIndex) ||
+ IsDefined != isDefinedTableIndex(Info.ElementIndex))
+ return make_error<GenericBinaryError>("invalid table symbol index",
+ object_error::parse_failed);
+ if (IsDefined) {
+ Info.Name = readString(Ctx);
+ unsigned TableIndex = Info.ElementIndex - NumImportedTables;
+ } else {
+ wasm::WasmImport &Import = *ImportedTables[Info.ElementIndex];
+ if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0)
+ Info.Name = readString(Ctx);
+ else
+ Info.Name = Import.Field;
+ Info.ImportName = Import.Field;
+ Info.ImportModule = Import.Module;
+ }
+ break;
+ }
+
default:
return make_error<GenericBinaryError>("Invalid symbol type",
object_error::parse_failed);
@@ -823,6 +848,11 @@
return make_error<GenericBinaryError>("Bad relocation event index",
object_error::parse_failed);
break;
+ case wasm::R_WASM_TABLE_INDEX_LEB:
+ if (!isValidTableSymbol(Reloc.Index))
+ return make_error<GenericBinaryError>("Bad relocation table index",
+ object_error::parse_failed);
+ break;
case wasm::R_WASM_MEMORY_ADDR_LEB:
case wasm::R_WASM_MEMORY_ADDR_SLEB:
case wasm::R_WASM_MEMORY_ADDR_I32:
@@ -964,8 +994,10 @@
HasMemory64 = true;
break;
case wasm::WASM_EXTERNAL_TABLE:
+ NumImportedTables++;
Im.Table = readTable(Ctx);
- if (Im.Table.ElemType != wasm::WASM_TYPE_FUNCREF)
+ if (Im.Table.ElemType != wasm::WASM_TYPE_FUNCREF &&
+ Im.Table.ElemType != wasm::WASM_TYPE_EXTERNREF)
return make_error<GenericBinaryError>("Invalid table element type",
object_error::parse_failed);
break;
@@ -1009,7 +1041,9 @@
Tables.reserve(Count);
while (Count--) {
Tables.push_back(readTable(Ctx));
- if (Tables.back().ElemType != wasm::WASM_TYPE_FUNCREF) {
+ if (Tables.back().ElemType != wasm::WASM_TYPE_FUNCREF &&
+ // TODO: Only allow externref here when reference-types is enabled?
+ Tables.back().ElemType != wasm::WASM_TYPE_EXTERNREF) {
return make_error<GenericBinaryError>("Invalid table element type",
object_error::parse_failed);
}
@@ -1137,6 +1171,14 @@
return Index >= NumImportedEvents && isValidEventIndex(Index);
}
+bool WasmObjectFile::isValidTableIndex(uint32_t Index) const {
+ return Index < NumImportedTables + Tables.size();
+}
+
+bool WasmObjectFile::isDefinedTableIndex(uint32_t Index) const {
+ return Index >= NumImportedTables && isValidTableIndex(Index);
+}
+
bool WasmObjectFile::isValidFunctionSymbol(uint32_t Index) const {
return Index < Symbols.size() && Symbols[Index].isTypeFunction();
}
@@ -1149,6 +1191,10 @@
return Index < Symbols.size() && Symbols[Index].isTypeEvent();
}
+bool WasmObjectFile::isValidTableSymbol(uint32_t Index) const {
+ return Index < Symbols.size() && Symbols[Index].isTypeTable();
+}
+
bool WasmObjectFile::isValidDataSymbol(uint32_t Index) const {
return Index < Symbols.size() && Symbols[Index].isTypeData();
}
Index: llvm/lib/MC/WasmObjectWriter.cpp
===================================================================
--- llvm/lib/MC/WasmObjectWriter.cpp
+++ llvm/lib/MC/WasmObjectWriter.cpp
@@ -258,6 +258,7 @@
unsigned NumFunctionImports = 0;
unsigned NumGlobalImports = 0;
unsigned NumEventImports = 0;
+ unsigned NumTableImports = 0;
uint32_t SectionCount = 0;
// TargetObjectWriter wrappers.
@@ -575,6 +576,7 @@
case wasm::R_WASM_GLOBAL_INDEX_LEB:
case wasm::R_WASM_GLOBAL_INDEX_I32:
case wasm::R_WASM_EVENT_INDEX_LEB:
+ case wasm::R_WASM_TABLE_INDEX_LEB:
// Provisional value is function/global/event Wasm index
assert(WasmIndices.count(RelEntry.Symbol) > 0 && "symbol not found in wasm index space");
return WasmIndices[RelEntry.Symbol];
@@ -678,6 +680,7 @@
case wasm::R_WASM_GLOBAL_INDEX_LEB:
case wasm::R_WASM_MEMORY_ADDR_LEB:
case wasm::R_WASM_EVENT_INDEX_LEB:
+ case wasm::R_WASM_TABLE_INDEX_LEB:
writePatchableLEB<5>(Stream, Value, Offset);
break;
case wasm::R_WASM_MEMORY_ADDR_LEB64:
@@ -1023,6 +1026,7 @@
case wasm::WASM_SYMBOL_TYPE_FUNCTION:
case wasm::WASM_SYMBOL_TYPE_GLOBAL:
case wasm::WASM_SYMBOL_TYPE_EVENT:
+ case wasm::WASM_SYMBOL_TYPE_TABLE:
encodeULEB128(Sym.ElementIndex, W.OS);
if ((Sym.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0 ||
(Sym.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0)
@@ -1215,6 +1219,7 @@
TableImport.Kind = wasm::WASM_EXTERNAL_TABLE;
TableImport.Table.ElemType = wasm::WASM_TYPE_FUNCREF;
Imports.push_back(TableImport);
+ NumTableImports++;
// Populate SignatureIndices, and Imports and WasmIndices for undefined
// symbols. This must be done before populating WasmIndices for defined
@@ -1271,6 +1276,15 @@
Imports.push_back(Import);
assert(WasmIndices.count(&WS) == 0);
WasmIndices[&WS] = NumEventImports++;
+ } else if (WS.isTable()) {
+ wasm::WasmImport Import;
+ Import.Module = WS.getImportModule();
+ Import.Field = WS.getImportName();
+ Import.Kind = wasm::WASM_EXTERNAL_TABLE;
+ Import.Table.ElemType = wasm::WASM_TYPE_EXTERNREF;
+ Imports.push_back(Import);
+ assert(WasmIndices.count(&WS) == 0);
+ WasmIndices[&WS] = NumTableImports++;
}
}
}
@@ -1500,7 +1514,15 @@
}
LLVM_DEBUG(dbgs() << " -> event index: " << WasmIndices.find(&WS)->second
<< "\n");
-
+ } else if (WS.isTable()) {
+ if (WS.isDefined()) {
+ report_fatal_error("Defined tables are not supported yet");
+ } else {
+ // An import; the index was assigned above.
+ assert(WasmIndices.count(&WS) > 0);
+ }
+ LLVM_DEBUG(dbgs() << " -> table index: " << WasmIndices.find(&WS)->second
+ << "\n");
} else {
assert(WS.isSection());
}
Index: llvm/lib/MC/MCExpr.cpp
===================================================================
--- llvm/lib/MC/MCExpr.cpp
+++ llvm/lib/MC/MCExpr.cpp
@@ -337,6 +337,7 @@
case VK_Hexagon_IE: return "IE";
case VK_Hexagon_IE_GOT: return "IEGOT";
case VK_WASM_TYPEINDEX: return "TYPEINDEX";
+ case VK_WASM_TABLEINDEX: return "TABLEINDEX";
case VK_WASM_MBREL: return "MBREL";
case VK_WASM_TBREL: return "TBREL";
case VK_AMDGPU_GOTPCREL32_LO: return "gotpcrel32@lo";
@@ -472,6 +473,7 @@
.Case("hi8", VK_AVR_HI8)
.Case("hlo8", VK_AVR_HLO8)
.Case("typeindex", VK_WASM_TYPEINDEX)
+ .Case("tableindex", VK_WASM_TABLEINDEX)
.Case("tbrel", VK_WASM_TBREL)
.Case("mbrel", VK_WASM_MBREL)
.Case("gotpcrel32@lo", VK_AMDGPU_GOTPCREL32_LO)
Index: llvm/lib/CodeGen/ValueTypes.cpp
===================================================================
--- llvm/lib/CodeGen/ValueTypes.cpp
+++ llvm/lib/CodeGen/ValueTypes.cpp
@@ -168,6 +168,7 @@
case MVT::Metadata:return "Metadata";
case MVT::Untyped: return "Untyped";
case MVT::exnref : return "exnref";
+ case MVT::externref : return "externref";
}
}
@@ -467,6 +468,9 @@
case MVT::nxv8f64:
return ScalableVectorType::get(Type::getDoubleTy(Context), 8);
case MVT::Metadata: return Type::getMetadataTy(Context);
+ case MVT::externref:
+ return PointerType::get(Type::getInt8Ty(Context),
+ 256); // TODO: Fix AS for Webassembly
}
}
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===================================================================
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -4035,10 +4035,12 @@
Root = Chain;
ChainI = 0;
}
- SDValue A = DAG.getNode(ISD::ADD, dl,
- PtrVT, Ptr,
- DAG.getConstant(Offsets[i], dl, PtrVT),
- Flags);
+ SDValue A = Ptr;
+ if (Offsets[i] != 0)
+ A = DAG.getNode(ISD::ADD, dl,
+ PtrVT, Ptr,
+ DAG.getConstant(Offsets[i], dl, PtrVT),
+ Flags);
SDValue L = DAG.getLoad(MemVTs[i], dl, Root, A,
MachinePointerInfo(SV, Offsets[i]), Alignment,
Index: llvm/lib/CodeGen/CodeGenPrepare.cpp
===================================================================
--- llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -6232,6 +6232,9 @@
EVT LoadResultVT = TLI->getValueType(*DL, Load->getType());
unsigned BitWidth = LoadResultVT.getSizeInBits();
+ if (!BitWidth)
+ return false;
+
APInt DemandBits(BitWidth, 0);
APInt WidestAndBits(BitWidth, 0);
Index: llvm/lib/BinaryFormat/Wasm.cpp
===================================================================
--- llvm/lib/BinaryFormat/Wasm.cpp
+++ llvm/lib/BinaryFormat/Wasm.cpp
@@ -20,6 +20,8 @@
return "WASM_SYMBOL_TYPE_SECTION";
case wasm::WASM_SYMBOL_TYPE_EVENT:
return "WASM_SYMBOL_TYPE_EVENT";
+ case wasm::WASM_SYMBOL_TYPE_TABLE:
+ return "WASM_SYMBOL_TYPE_TABLE";
}
llvm_unreachable("unknown symbol type");
}
Index: llvm/include/llvm/Support/MachineValueType.h
===================================================================
--- llvm/include/llvm/Support/MachineValueType.h
+++ llvm/include/llvm/Support/MachineValueType.h
@@ -238,10 +238,11 @@
// unspecified type. The register class
// will be determined by the opcode.
- exnref = 155, // WebAssembly's exnref type
+ exnref = 155, // WebAssembly's exnref type
+ externref = 156, // WebAssembly's externref type
- FIRST_VALUETYPE = 1, // This is always the beginning of the list.
- LAST_VALUETYPE = 156, // This always remains at the end of the list.
+ FIRST_VALUETYPE = 1, // This is always the beginning of the list.
+ LAST_VALUETYPE = 157, // This always remains at the end of the list.
// This is the current maximum for LAST_VALUETYPE.
// MVT::MAX_ALLOWED_VALUETYPE is used for asserts and to size bit vectors
@@ -919,6 +920,7 @@
case v1024f32: return TypeSize::Fixed(32768);
case v2048i32:
case v2048f32: return TypeSize::Fixed(65536);
+ case externref:
case exnref: return TypeSize::Fixed(0); // opaque type
}
}
Index: llvm/include/llvm/Object/Wasm.h
===================================================================
--- llvm/include/llvm/Object/Wasm.h
+++ llvm/include/llvm/Object/Wasm.h
@@ -62,6 +62,8 @@
bool isTypeEvent() const { return Info.Kind == wasm::WASM_SYMBOL_TYPE_EVENT; }
+ bool isTypeTable() const { return Info.Kind == wasm::WASM_SYMBOL_TYPE_TABLE; }
+
bool isDefined() const { return !isUndefined(); }
bool isUndefined() const {
@@ -217,9 +219,12 @@
bool isDefinedGlobalIndex(uint32_t Index) const;
bool isValidEventIndex(uint32_t Index) const;
bool isDefinedEventIndex(uint32_t Index) const;
+ bool isValidTableIndex(uint32_t Index) const;
+ bool isDefinedTableIndex(uint32_t Index) const;
bool isValidFunctionSymbol(uint32_t Index) const;
bool isValidGlobalSymbol(uint32_t Index) const;
bool isValidEventSymbol(uint32_t Index) const;
+ bool isValidTableSymbol(uint32_t Index) const;
bool isValidDataSymbol(uint32_t Index) const;
bool isValidSectionSymbol(uint32_t Index) const;
wasm::WasmFunction &getDefinedFunction(uint32_t Index);
@@ -287,6 +292,7 @@
uint32_t NumImportedGlobals = 0;
uint32_t NumImportedFunctions = 0;
uint32_t NumImportedEvents = 0;
+ uint32_t NumImportedTables = 0;
uint32_t CodeSection = 0;
uint32_t DataSection = 0;
uint32_t EventSection = 0;
Index: llvm/include/llvm/MC/MCSymbolWasm.h
===================================================================
--- llvm/include/llvm/MC/MCSymbolWasm.h
+++ llvm/include/llvm/MC/MCSymbolWasm.h
@@ -44,6 +44,7 @@
bool isGlobal() const { return Type == wasm::WASM_SYMBOL_TYPE_GLOBAL; }
bool isSection() const { return Type == wasm::WASM_SYMBOL_TYPE_SECTION; }
bool isEvent() const { return Type == wasm::WASM_SYMBOL_TYPE_EVENT; }
+ bool isTable() const { return Type == wasm::WASM_SYMBOL_TYPE_TABLE; }
wasm::WasmSymbolType getType() const { return Type; }
void setType(wasm::WasmSymbolType type) { Type = type; }
Index: llvm/include/llvm/MC/MCExpr.h
===================================================================
--- llvm/include/llvm/MC/MCExpr.h
+++ llvm/include/llvm/MC/MCExpr.h
@@ -316,9 +316,10 @@
VK_Hexagon_IE,
VK_Hexagon_IE_GOT,
- VK_WASM_TYPEINDEX, // Reference to a symbol's type (signature)
- VK_WASM_MBREL, // Memory address relative to memory base
- VK_WASM_TBREL, // Table index relative to table bare
+ VK_WASM_TYPEINDEX, // Reference to a symbol's type (signature)
+ VK_WASM_TABLEINDEX, // Reference to a table
+ VK_WASM_MBREL, // Memory address relative to memory base
+ VK_WASM_TBREL, // Table index relative to table bare
VK_AMDGPU_GOTPCREL32_LO, // symbol@gotpcrel32@lo
VK_AMDGPU_GOTPCREL32_HI, // symbol@gotpcrel32@hi
Index: llvm/include/llvm/CodeGen/ValueTypes.td
===================================================================
--- llvm/include/llvm/CodeGen/ValueTypes.td
+++ llvm/include/llvm/CodeGen/ValueTypes.td
@@ -188,6 +188,7 @@
def isVoid : ValueType<0 , 153>; // Produces no value
def untyped: ValueType<8 , 154>; // Produces an untyped value
def exnref : ValueType<0 , 155>; // WebAssembly's exnref type
+def externref: ValueType<0, 156>; // WebAssembly's externref type
def token : ValueType<0 , 248>; // TokenTy
def MetadataVT: ValueType<0, 249>; // Metadata
Index: llvm/include/llvm/CodeGen/TargetLowering.h
===================================================================
--- llvm/include/llvm/CodeGen/TargetLowering.h
+++ llvm/include/llvm/CodeGen/TargetLowering.h
@@ -346,7 +346,7 @@
/// Return the in-memory pointer type for the given address space, defaults to
/// the pointer type from the data layout. FIXME: The default needs to be
/// removed once all the code is updated.
- MVT getPointerMemTy(const DataLayout &DL, uint32_t AS = 0) const {
+ virtual MVT getPointerMemTy(const DataLayout &DL, uint32_t AS = 0) const {
return MVT::getIntegerVT(DL.getPointerSizeInBits(AS));
}
Index: llvm/include/llvm/BinaryFormat/WasmRelocs.def
===================================================================
--- llvm/include/llvm/BinaryFormat/WasmRelocs.def
+++ llvm/include/llvm/BinaryFormat/WasmRelocs.def
@@ -15,10 +15,11 @@
WASM_RELOC(R_WASM_EVENT_INDEX_LEB, 10)
WASM_RELOC(R_WASM_MEMORY_ADDR_REL_SLEB, 11)
WASM_RELOC(R_WASM_TABLE_INDEX_REL_SLEB, 12)
-WASM_RELOC(R_WASM_GLOBAL_INDEX_I32, 13)
-WASM_RELOC(R_WASM_MEMORY_ADDR_LEB64, 14)
-WASM_RELOC(R_WASM_MEMORY_ADDR_SLEB64, 15)
-WASM_RELOC(R_WASM_MEMORY_ADDR_I64, 16)
-WASM_RELOC(R_WASM_MEMORY_ADDR_REL_SLEB64, 17)
-WASM_RELOC(R_WASM_TABLE_INDEX_SLEB64, 18)
-WASM_RELOC(R_WASM_TABLE_INDEX_I64, 19)
+WASM_RELOC(R_WASM_TABLE_INDEX_LEB, 13)
+WASM_RELOC(R_WASM_GLOBAL_INDEX_I32, 14)
+WASM_RELOC(R_WASM_MEMORY_ADDR_LEB64, 15)
+WASM_RELOC(R_WASM_MEMORY_ADDR_SLEB64, 16)
+WASM_RELOC(R_WASM_MEMORY_ADDR_I64, 17)
+WASM_RELOC(R_WASM_MEMORY_ADDR_REL_SLEB64, 18)
+WASM_RELOC(R_WASM_TABLE_INDEX_SLEB64, 19)
+WASM_RELOC(R_WASM_TABLE_INDEX_I64, 20)
Index: llvm/include/llvm/BinaryFormat/Wasm.h
===================================================================
--- llvm/include/llvm/BinaryFormat/Wasm.h
+++ llvm/include/llvm/BinaryFormat/Wasm.h
@@ -325,6 +325,7 @@
WASM_SYMBOL_TYPE_GLOBAL = 0x2,
WASM_SYMBOL_TYPE_SECTION = 0x3,
WASM_SYMBOL_TYPE_EVENT = 0x4,
+ WASM_SYMBOL_TYPE_TABLE = 0x5,
};
// Kinds of event attributes.
@@ -360,8 +361,9 @@
F32 = WASM_TYPE_F32,
F64 = WASM_TYPE_F64,
V128 = WASM_TYPE_V128,
- EXNREF = WASM_TYPE_EXNREF,
+ FUNCREF = WASM_TYPE_FUNCREF,
EXTERNREF = WASM_TYPE_EXTERNREF,
+ EXNREF = WASM_TYPE_EXNREF,
};
struct WasmSignature {
Index: lld/wasm/WriterUtils.cpp
===================================================================
--- lld/wasm/WriterUtils.cpp
+++ lld/wasm/WriterUtils.cpp
@@ -30,10 +30,12 @@
return "f64";
case ValType::V128:
return "v128";
- case ValType::EXNREF:
- return "exnref";
+ case ValType::FUNCREF:
+ return "funcref";
case ValType::EXTERNREF:
return "externref";
+ case ValType::EXNREF:
+ return "exnref";
}
llvm_unreachable("Invalid wasm::ValType");
}
Index: clang/lib/Basic/Targets/WebAssembly.cpp
===================================================================
--- clang/lib/Basic/Targets/WebAssembly.cpp
+++ clang/lib/Basic/Targets/WebAssembly.cpp
@@ -232,6 +232,7 @@
}
if (Feature == "+reference-types") {
HasReferenceTypes = true;
+ resetDataLayout("e-m:e-p:32:32-i64:64-n32:64-S128-ni:256");
continue;
}
if (Feature == "-reference-types") {
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits