forked from OSchip/llvm-project
[WebAssembly] Implementation of (most) table instructions
Implementation of instructions table.get, table.set, table.grow, table.size, table.fill, table.copy. Missing instructions are table.init and elem.drop as they deal with element sections which are not yet implemented. Added more tests to tables.s Differential Revision: https://reviews.llvm.org/D89797
This commit is contained in:
parent
e7d37742a2
commit
69e2797eae
|
@ -22,3 +22,4 @@ 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_NUMBER_LEB, 20)
|
||||
|
|
|
@ -194,6 +194,9 @@ def FlagVT : ValueType<0 , 158>; // Pre-RA sched glue
|
|||
def isVoid : ValueType<0 , 159>; // Produces no value
|
||||
def untyped: ValueType<8 , 160>; // Produces an untyped value
|
||||
def exnref : ValueType<0 , 161>; // WebAssembly's exnref type
|
||||
def funcref : ValueType<0 , 162>; // WebAssembly's funcref type
|
||||
def externref : ValueType<0 , 163>; // WebAssembly's externref type
|
||||
|
||||
|
||||
def token : ValueType<0 , 248>; // TokenTy
|
||||
def MetadataVT: ValueType<0, 249>; // Metadata
|
||||
|
|
|
@ -51,6 +51,8 @@ public:
|
|||
return Info.Kind == wasm::WASM_SYMBOL_TYPE_FUNCTION;
|
||||
}
|
||||
|
||||
bool isTypeTable() const { return Info.Kind == wasm::WASM_SYMBOL_TYPE_TABLE; }
|
||||
|
||||
bool isTypeData() const { return Info.Kind == wasm::WASM_SYMBOL_TYPE_DATA; }
|
||||
|
||||
bool isTypeGlobal() const {
|
||||
|
@ -222,6 +224,7 @@ private:
|
|||
bool isValidEventIndex(uint32_t Index) const;
|
||||
bool isDefinedEventIndex(uint32_t Index) const;
|
||||
bool isValidFunctionSymbol(uint32_t Index) const;
|
||||
bool isValidTableSymbol(uint32_t Index) const;
|
||||
bool isValidGlobalSymbol(uint32_t Index) const;
|
||||
bool isValidEventSymbol(uint32_t Index) const;
|
||||
bool isValidDataSymbol(uint32_t Index) const;
|
||||
|
|
|
@ -245,9 +245,11 @@ namespace llvm {
|
|||
// will be determined by the opcode.
|
||||
|
||||
exnref = 161, // WebAssembly's exnref type
|
||||
funcref = 162, // WebAssembly's funcref type
|
||||
externref = 163, // WebAssembly's externref type
|
||||
|
||||
FIRST_VALUETYPE = 1, // This is always the beginning of the list.
|
||||
LAST_VALUETYPE = 162, // This always remains at the end of the list.
|
||||
LAST_VALUETYPE = 164, // 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
|
||||
|
@ -973,7 +975,9 @@ namespace llvm {
|
|||
case v1024f32: return TypeSize::Fixed(32768);
|
||||
case v2048i32:
|
||||
case v2048f32: return TypeSize::Fixed(65536);
|
||||
case exnref: return TypeSize::Fixed(0); // opaque type
|
||||
case exnref:
|
||||
case funcref:
|
||||
case externref: return TypeSize::Fixed(0); // opaque type
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -158,15 +158,17 @@ std::string EVT::getEVTString() const {
|
|||
if (isFloatingPoint())
|
||||
return "f" + utostr(getSizeInBits());
|
||||
llvm_unreachable("Invalid EVT!");
|
||||
case MVT::bf16: return "bf16";
|
||||
case MVT::ppcf128: return "ppcf128";
|
||||
case MVT::isVoid: return "isVoid";
|
||||
case MVT::Other: return "ch";
|
||||
case MVT::Glue: return "glue";
|
||||
case MVT::x86mmx: return "x86mmx";
|
||||
case MVT::Metadata:return "Metadata";
|
||||
case MVT::Untyped: return "Untyped";
|
||||
case MVT::exnref : return "exnref";
|
||||
case MVT::bf16: return "bf16";
|
||||
case MVT::ppcf128: return "ppcf128";
|
||||
case MVT::isVoid: return "isVoid";
|
||||
case MVT::Other: return "ch";
|
||||
case MVT::Glue: return "glue";
|
||||
case MVT::x86mmx: return "x86mmx";
|
||||
case MVT::Metadata: return "Metadata";
|
||||
case MVT::Untyped: return "Untyped";
|
||||
case MVT::exnref: return "exnref";
|
||||
case MVT::funcref: return "funcref";
|
||||
case MVT::externref: return "externref";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -559,6 +559,7 @@ WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry,
|
|||
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_NUMBER_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];
|
||||
|
@ -663,6 +664,7 @@ void WasmObjectWriter::applyRelocations(
|
|||
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_NUMBER_LEB:
|
||||
writePatchableLEB<5>(Stream, Value, Offset);
|
||||
break;
|
||||
case wasm::R_WASM_MEMORY_ADDR_LEB64:
|
||||
|
|
|
@ -552,6 +552,7 @@ static bool supportsWasm32(uint64_t Type) {
|
|||
case wasm::R_WASM_SECTION_OFFSET_I32:
|
||||
case wasm::R_WASM_EVENT_INDEX_LEB:
|
||||
case wasm::R_WASM_GLOBAL_INDEX_I32:
|
||||
case wasm::R_WASM_TABLE_NUMBER_LEB:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
@ -585,6 +586,7 @@ static uint64_t resolveWasm32(RelocationRef R, uint64_t S, uint64_t A) {
|
|||
case wasm::R_WASM_SECTION_OFFSET_I32:
|
||||
case wasm::R_WASM_EVENT_INDEX_LEB:
|
||||
case wasm::R_WASM_GLOBAL_INDEX_I32:
|
||||
case wasm::R_WASM_TABLE_NUMBER_LEB:
|
||||
// For wasm section, its offset at 0 -- ignoring Value
|
||||
return A;
|
||||
default:
|
||||
|
|
|
@ -822,6 +822,11 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
|
|||
return make_error<GenericBinaryError>("Bad relocation function index",
|
||||
object_error::parse_failed);
|
||||
break;
|
||||
case wasm::R_WASM_TABLE_NUMBER_LEB:
|
||||
if (!isValidTableSymbol(Reloc.Index))
|
||||
return make_error<GenericBinaryError>("Bad relocation table index",
|
||||
object_error::parse_failed);
|
||||
break;
|
||||
case wasm::R_WASM_TYPE_INDEX_LEB:
|
||||
if (Reloc.Index >= Signatures.size())
|
||||
return make_error<GenericBinaryError>("Bad relocation type index",
|
||||
|
@ -1181,6 +1186,10 @@ bool WasmObjectFile::isValidFunctionSymbol(uint32_t Index) const {
|
|||
return Index < Symbols.size() && Symbols[Index].isTypeFunction();
|
||||
}
|
||||
|
||||
bool WasmObjectFile::isValidTableSymbol(uint32_t Index) const {
|
||||
return Index < Symbols.size() && Symbols[Index].isTypeTable();
|
||||
}
|
||||
|
||||
bool WasmObjectFile::isValidGlobalSymbol(uint32_t Index) const {
|
||||
return Index < Symbols.size() && Symbols[Index].isTypeGlobal();
|
||||
}
|
||||
|
|
|
@ -198,6 +198,7 @@ MCDisassembler::DecodeStatus WebAssemblyDisassembler::getInstruction(
|
|||
case WebAssembly::OPERAND_LOCAL:
|
||||
case WebAssembly::OPERAND_GLOBAL:
|
||||
case WebAssembly::OPERAND_FUNCTION32:
|
||||
case WebAssembly::OPERAND_TABLE:
|
||||
case WebAssembly::OPERAND_OFFSET32:
|
||||
case WebAssembly::OPERAND_OFFSET64:
|
||||
case WebAssembly::OPERAND_P2ALIGN:
|
||||
|
|
|
@ -151,6 +151,7 @@ void WebAssemblyMCCodeEmitter::encodeInstruction(
|
|||
PaddedSize = 10;
|
||||
break;
|
||||
case WebAssembly::OPERAND_FUNCTION32:
|
||||
case WebAssembly::OPERAND_TABLE:
|
||||
case WebAssembly::OPERAND_OFFSET32:
|
||||
case WebAssembly::OPERAND_SIGNATURE:
|
||||
case WebAssembly::OPERAND_TYPEINDEX:
|
||||
|
|
|
@ -76,6 +76,8 @@ enum OperandType {
|
|||
OPERAND_EVENT,
|
||||
/// A list of branch targets for br_list.
|
||||
OPERAND_BRLIST,
|
||||
/// 32-bit unsigned table number.
|
||||
OPERAND_TABLE,
|
||||
};
|
||||
} // end namespace WebAssembly
|
||||
|
||||
|
|
|
@ -102,6 +102,8 @@ unsigned WebAssemblyWasmObjectWriter::getRelocType(const MCValue &Target,
|
|||
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_NUMBER_LEB;
|
||||
return wasm::R_WASM_MEMORY_ADDR_LEB;
|
||||
case WebAssembly::fixup_uleb128_i64:
|
||||
assert(SymA.isData());
|
||||
|
|
|
@ -115,6 +115,10 @@ static unsigned getLocalGetOpcode(const TargetRegisterClass *RC) {
|
|||
return WebAssembly::LOCAL_GET_V128;
|
||||
if (RC == &WebAssembly::EXNREFRegClass)
|
||||
return WebAssembly::LOCAL_GET_EXNREF;
|
||||
if (RC == &WebAssembly::FUNCREFRegClass)
|
||||
return WebAssembly::LOCAL_GET_FUNCREF;
|
||||
if (RC == &WebAssembly::EXTERNREFRegClass)
|
||||
return WebAssembly::LOCAL_GET_EXTERNREF;
|
||||
llvm_unreachable("Unexpected register class");
|
||||
}
|
||||
|
||||
|
@ -132,6 +136,10 @@ static unsigned getLocalSetOpcode(const TargetRegisterClass *RC) {
|
|||
return WebAssembly::LOCAL_SET_V128;
|
||||
if (RC == &WebAssembly::EXNREFRegClass)
|
||||
return WebAssembly::LOCAL_SET_EXNREF;
|
||||
if (RC == &WebAssembly::FUNCREFRegClass)
|
||||
return WebAssembly::LOCAL_SET_FUNCREF;
|
||||
if (RC == &WebAssembly::EXTERNREFRegClass)
|
||||
return WebAssembly::LOCAL_SET_EXTERNREF;
|
||||
llvm_unreachable("Unexpected register class");
|
||||
}
|
||||
|
||||
|
@ -149,6 +157,10 @@ static unsigned getLocalTeeOpcode(const TargetRegisterClass *RC) {
|
|||
return WebAssembly::LOCAL_TEE_V128;
|
||||
if (RC == &WebAssembly::EXNREFRegClass)
|
||||
return WebAssembly::LOCAL_TEE_EXNREF;
|
||||
if (RC == &WebAssembly::FUNCREFRegClass)
|
||||
return WebAssembly::LOCAL_TEE_FUNCREF;
|
||||
if (RC == &WebAssembly::EXTERNREFRegClass)
|
||||
return WebAssembly::LOCAL_TEE_EXTERNREF;
|
||||
llvm_unreachable("Unexpected register class");
|
||||
}
|
||||
|
||||
|
@ -166,6 +178,10 @@ static MVT typeForRegClass(const TargetRegisterClass *RC) {
|
|||
return MVT::v16i8;
|
||||
if (RC == &WebAssembly::EXNREFRegClass)
|
||||
return MVT::exnref;
|
||||
if (RC == &WebAssembly::FUNCREFRegClass)
|
||||
return MVT::funcref;
|
||||
if (RC == &WebAssembly::EXTERNREFRegClass)
|
||||
return MVT::externref;
|
||||
llvm_unreachable("unrecognized register class");
|
||||
}
|
||||
|
||||
|
|
|
@ -129,6 +129,8 @@ private:
|
|||
case MVT::f32:
|
||||
case MVT::f64:
|
||||
case MVT::exnref:
|
||||
case MVT::funcref:
|
||||
case MVT::externref:
|
||||
return VT;
|
||||
case MVT::f16:
|
||||
return MVT::f32;
|
||||
|
@ -809,6 +811,12 @@ bool WebAssemblyFastISel::selectCall(const Instruction *I) {
|
|||
case MVT::exnref:
|
||||
ResultReg = createResultReg(&WebAssembly::EXNREFRegClass);
|
||||
break;
|
||||
case MVT::funcref:
|
||||
ResultReg = createResultReg(&WebAssembly::FUNCREFRegClass);
|
||||
break;
|
||||
case MVT::externref:
|
||||
ResultReg = createResultReg(&WebAssembly::EXTERNREFRegClass);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -163,6 +163,9 @@ def vec_i64imm_op : Operand<i64>;
|
|||
let OperandType = "OPERAND_FUNCTION32" in
|
||||
def function32_op : Operand<i32>;
|
||||
|
||||
let OperandType = "OPERAND_TABLE" in
|
||||
def table32_op : Operand<i32>;
|
||||
|
||||
let OperandType = "OPERAND_OFFSET32" in
|
||||
def offset32_op : Operand<i32>;
|
||||
|
||||
|
@ -237,6 +240,8 @@ defm "": ARGUMENT<I64, i64>;
|
|||
defm "": ARGUMENT<F32, f32>;
|
||||
defm "": ARGUMENT<F64, f64>;
|
||||
defm "": ARGUMENT<EXNREF, exnref>;
|
||||
defm "": ARGUMENT<FUNCREF, funcref>;
|
||||
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 +312,8 @@ defm "" : LOCAL<F32>;
|
|||
defm "" : LOCAL<F64>;
|
||||
defm "" : LOCAL<V128>, Requires<[HasSIMD128]>;
|
||||
defm "" : LOCAL<EXNREF>, Requires<[HasExceptionHandling]>;
|
||||
defm "" : LOCAL<FUNCREF>, Requires<[HasReferenceTypes]>;
|
||||
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 +372,4 @@ include "WebAssemblyInstrAtomics.td"
|
|||
include "WebAssemblyInstrSIMD.td"
|
||||
include "WebAssemblyInstrRef.td"
|
||||
include "WebAssemblyInstrBulkMemory.td"
|
||||
include "WebAssemblyInstrTable.td"
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
// WebAssemblyInstrTable.td - WebAssembly Table codegen support -*- tablegen -*-
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// WebAssembly Table operand code-gen constructs.
|
||||
/// Instructions that handle tables
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
multiclass TABLE<WebAssemblyRegClass rt> {
|
||||
defm TABLE_GET_#rt : I<(outs rt:$res), (ins table32_op:$table),
|
||||
(outs), (ins table32_op:$table),
|
||||
[],
|
||||
"table.get\t$res, $table",
|
||||
"table.get\t$table",
|
||||
0x25>;
|
||||
|
||||
defm TABLE_SET_#rt : I<(outs), (ins table32_op:$table, rt:$val, I32:$i),
|
||||
(outs), (ins table32_op:$table),
|
||||
[],
|
||||
"table.set\t$table, $val, $i",
|
||||
"table.set\t$table",
|
||||
0x26>;
|
||||
|
||||
defm TABLE_GROW_#rt : I<(outs I32:$sz), (ins table32_op:$table, I32:$n, rt:$val),
|
||||
(outs), (ins table32_op:$table),
|
||||
[],
|
||||
"table.grow\t$sz, $table, $n, $val",
|
||||
"table.grow\t$table",
|
||||
0xfc0f>;
|
||||
|
||||
defm TABLE_FILL_#rt : I<(outs), (ins table32_op:$table, I32:$n, rt:$val, I32:$i),
|
||||
(outs), (ins table32_op:$table),
|
||||
[],
|
||||
"table.fill\t$table, $n, $val, $i",
|
||||
"table.fill\t$table",
|
||||
0xfc11>;
|
||||
|
||||
}
|
||||
|
||||
defm "" : TABLE<FUNCREF>, Requires<[HasReferenceTypes]>;
|
||||
defm "" : TABLE<EXTERNREF>, Requires<[HasReferenceTypes]>;
|
||||
|
||||
defm TABLE_SIZE : I<(outs I32:$sz), (ins table32_op:$table),
|
||||
(outs), (ins table32_op:$table),
|
||||
[],
|
||||
"table.size\t$sz, $table",
|
||||
"table.size\t$table",
|
||||
0xfc10>,
|
||||
Requires<[HasReferenceTypes]>;
|
||||
|
||||
|
||||
defm TABLE_COPY : I<(outs), (ins table32_op:$table1, table32_op:$table2, I32:$n, I32:$s, I32:$d),
|
||||
(outs), (ins table32_op:$table1, table32_op:$table2),
|
||||
[],
|
||||
"table.copy\t$table1, $table2, $n, $s, $d",
|
||||
"table.copy\t$table1, $table2",
|
||||
0xfc0e>,
|
||||
Requires<[HasReferenceTypes]>;
|
|
@ -44,6 +44,8 @@ def F64_0 : WebAssemblyReg<"%f64.0">;
|
|||
def V128_0: WebAssemblyReg<"%v128">;
|
||||
|
||||
def EXNREF_0 : WebAssemblyReg<"%exnref.0">;
|
||||
def FUNCREF_0 : WebAssemblyReg<"%funcref.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 +67,5 @@ def F64 : WebAssemblyRegClass<[f64], 64, (add F64_0)>;
|
|||
def V128 : WebAssemblyRegClass<[v4f32, v2f64, v2i64, v4i32, v16i8, v8i16], 128,
|
||||
(add V128_0)>;
|
||||
def EXNREF : WebAssemblyRegClass<[exnref], 0, (add EXNREF_0)>;
|
||||
def FUNCREF : WebAssemblyRegClass<[funcref], 0, (add FUNCREF_0)>;
|
||||
def EXTERNREF : WebAssemblyRegClass<[externref], 0, (add EXTERNREF_0)>;
|
||||
|
|
|
@ -1,19 +1,123 @@
|
|||
# RUN: llvm-mc -triple=wasm32-unknown-unknown < %s | FileCheck %s
|
||||
# RUN: llvm-mc -triple=wasm32-unknown-unknown -filetype=obj < %s | obj2yaml | FileCheck -check-prefix=BIN %s
|
||||
# RUN: llvm-mc -triple=wasm32-unknown-unknown -mattr=+reference-types < %s | FileCheck %s
|
||||
# RUN: llvm-mc -show-encoding -triple=wasm32-unknown-unknown -mattr=+reference-types < %s | FileCheck -check-prefix=ENC %s
|
||||
# RUN: llvm-mc -triple=wasm32-unknown-unknown -mattr=+reference-types -filetype=obj < %s | obj2yaml | FileCheck -check-prefix=BIN %s
|
||||
|
||||
# Test creating several empty tables
|
||||
# Creating several empty tables
|
||||
|
||||
.tabletype foo, externref
|
||||
# CHECK: .tabletype foo, externref
|
||||
# CHECK: foo:
|
||||
.tabletype foo, externref
|
||||
foo:
|
||||
|
||||
bar:
|
||||
.tabletype bar, funcref
|
||||
|
||||
# CHECK: .tabletype foo, externref
|
||||
# CHECK: foo:
|
||||
|
||||
# CHECK: bar:
|
||||
# CHECK-NEXT: .tabletype bar, funcref
|
||||
# CHECK-NEXT: .tabletype bar, funcref
|
||||
bar:
|
||||
.tabletype bar, funcref
|
||||
|
||||
table1:
|
||||
.tabletype table1, funcref
|
||||
table2:
|
||||
.tabletype table2, funcref
|
||||
|
||||
# Table instructions
|
||||
|
||||
# CHECK: copy_tables:
|
||||
# CHECK-NEXT: .functype copy_tables (i32, i32) -> ()
|
||||
# CHECK-NEXT: local.get 0
|
||||
# CHECK-NEXT: local.get 1
|
||||
# CHECK: table.size table1
|
||||
# CHECK: table.copy table1, table2
|
||||
# CHECK-NEXT: end_function
|
||||
# CHECK-NEXT:.Ltmp0:
|
||||
# CHECK-NEXT: .size copy_tables, .Ltmp0-copy_tables
|
||||
copy_tables:
|
||||
.functype copy_tables (i32, i32) -> ()
|
||||
local.get 0
|
||||
local.get 1
|
||||
|
||||
# ENC: table.size table1 # encoding: [0xfc,0x10,0x80'A',0x80'A',0x80'A',0x80'A',A]
|
||||
table.size table1
|
||||
|
||||
# ENC: table.copy table1, table2 # encoding: [0xfc,0x0e,0x80'A',0x80'A',0x80'A',0x80'A',A,0x80'B',0x80'B',0x80'B',0x80'B',B]
|
||||
table.copy table1, table2
|
||||
end_function
|
||||
|
||||
# CHECK: table_get:
|
||||
# CHECK-NEXT: .functype table_get (i32) -> (externref)
|
||||
# CHECK-NEXT: local.get 0
|
||||
# CHECK: table.get foo
|
||||
# CHECK-NEXT: end_function
|
||||
# CHECK-NEXT: .Ltmp1:
|
||||
# CHECK-NEXT: .size table_get, .Ltmp1-table_get
|
||||
table_get:
|
||||
.functype table_get (i32) -> (externref)
|
||||
local.get 0
|
||||
|
||||
# ENC: table.get foo # encoding: [0x25,0x80'A',0x80'A',0x80'A',0x80'A',A]
|
||||
table.get foo
|
||||
end_function
|
||||
|
||||
# CHECK: table_set:
|
||||
# CHECK-NEXT: .functype table_set (i32, externref) -> ()
|
||||
# CHECK-NEXT: local.get 0
|
||||
# CHECK-NEXT: local.get 1
|
||||
# CHECK: table.set foo
|
||||
# CHECK-NEXT: end_function
|
||||
# CHECK-NEXT: .Ltmp2:
|
||||
# CHECK-NEXT: .size table_set, .Ltmp2-table_set
|
||||
table_set:
|
||||
.functype table_set (i32, externref) -> ()
|
||||
local.get 0
|
||||
local.get 1
|
||||
|
||||
# ENC: table.set foo # encoding: [0x26,0x80'A',0x80'A',0x80'A',0x80'A',A]
|
||||
table.set foo
|
||||
end_function
|
||||
|
||||
# CHECK: table_grow:
|
||||
# CHECK-NEXT: .functype table_grow (i32) -> (i32)
|
||||
# CHECK-NEXT: i32.const 0
|
||||
# CHECK-NEXT: table.get foo
|
||||
# CHECK-NEXT: local.get 0
|
||||
# CHECK: table.grow foo
|
||||
# CHECK-NEXT: local.get 0
|
||||
# CHECK-NEXT: i32.add
|
||||
# CHECK-NEXT: end_function
|
||||
# CHECK-NEXT: .Ltmp3:
|
||||
# CHECK-NEXT: .size table_grow, .Ltmp3-table_grow
|
||||
table_grow:
|
||||
.functype table_grow (i32) -> (i32)
|
||||
i32.const 0
|
||||
table.get foo
|
||||
local.get 0
|
||||
|
||||
# ENC: table.grow foo # encoding: [0xfc,0x0f,0x80'A',0x80'A',0x80'A',0x80'A',A]
|
||||
table.grow foo
|
||||
local.get 0
|
||||
i32.add
|
||||
end_function
|
||||
|
||||
# CHECK: table_fill:
|
||||
# CHECK-NEXT: .functype table_fill (i32, i32) -> ()
|
||||
# CHECK-NEXT: local.get 0
|
||||
# CHECK-NEXT: i32.const 0
|
||||
# CHECK-NEXT: table.get table1
|
||||
# CHECK-NEXT: local.get 1
|
||||
# CHECK: table.fill table1
|
||||
# CHECK-NEXT: end_function
|
||||
# CHECK-NEXT: .Ltmp4:
|
||||
# CHECK-NEXT: .size table_fill, .Ltmp4-table_fill
|
||||
table_fill:
|
||||
.functype table_fill (i32, i32) -> ()
|
||||
local.get 0
|
||||
i32.const 0
|
||||
table.get table1
|
||||
local.get 1
|
||||
|
||||
# ENC: table.fill table1 # encoding: [0xfc,0x11,0x80'A',0x80'A',0x80'A',0x80'A',A]
|
||||
table.fill table1
|
||||
end_function
|
||||
|
||||
# BIN: - Type: TABLE
|
||||
# BIN-NEXT: Tables:
|
||||
|
@ -26,6 +130,52 @@ bar:
|
|||
# BIN-NEXT: Limits:
|
||||
# BIN-NEXT: Initial: 0x00000000
|
||||
|
||||
# BIN: - Type: CODE
|
||||
# BIN-NEXT: Relocations:
|
||||
# BIN-NEXT: - Type: R_WASM_TABLE_NUMBER_LEB
|
||||
# BIN-NEXT: Index: 2
|
||||
# BIN-NEXT: Offset: 0x00000009
|
||||
# BIN-NEXT: - Type: R_WASM_TABLE_NUMBER_LEB
|
||||
# BIN-NEXT: Index: 2
|
||||
# BIN-NEXT: Offset: 0x00000010
|
||||
# BIN-NEXT: - Type: R_WASM_TABLE_NUMBER_LEB
|
||||
# BIN-NEXT: Index: 3
|
||||
# BIN-NEXT: Offset: 0x00000015
|
||||
# BIN-NEXT: - Type: R_WASM_TABLE_NUMBER_LEB
|
||||
# BIN-NEXT: Index: 0
|
||||
# BIN-NEXT: Offset: 0x00000020
|
||||
# BIN-NEXT: - Type: R_WASM_TABLE_NUMBER_LEB
|
||||
# BIN-NEXT: Index: 0
|
||||
# BIN-NEXT: Offset: 0x0000002D
|
||||
# BIN-NEXT: - Type: R_WASM_TABLE_NUMBER_LEB
|
||||
# BIN-NEXT: Index: 0
|
||||
# BIN-NEXT: Offset: 0x00000038
|
||||
# BIN-NEXT: - Type: R_WASM_TABLE_NUMBER_LEB
|
||||
# BIN-NEXT: Index: 0
|
||||
# BIN-NEXT: Offset: 0x00000041
|
||||
# BIN-NEXT: - Type: R_WASM_TABLE_NUMBER_LEB
|
||||
# BIN-NEXT: Index: 2
|
||||
# BIN-NEXT: Offset: 0x00000051
|
||||
# BIN-NEXT: - Type: R_WASM_TABLE_NUMBER_LEB
|
||||
# BIN-NEXT: Index: 2
|
||||
# BIN-NEXT: Offset: 0x0000005A
|
||||
# BIN-NEXT: Functions:
|
||||
# BIN-NEXT: - Index: 0
|
||||
# BIN-NEXT: Locals: []
|
||||
# BIN-NEXT: Body: 20002001FC108380808000FC0E838080800084808080000B
|
||||
# BIN-NEXT: - Index: 1
|
||||
# BIN-NEXT: Locals: []
|
||||
# BIN-NEXT: Body: 20002581808080000B
|
||||
# BIN-NEXT: - Index: 2
|
||||
# BIN-NEXT: Locals: []
|
||||
# BIN-NEXT: Body: 200020012681808080000B
|
||||
# BIN-NEXT: - Index: 3
|
||||
# BIN-NEXT: Locals: []
|
||||
# BIN-NEXT: Body: 41002581808080002000FC0F818080800020006A0B
|
||||
# BIN-NEXT: - Index: 4
|
||||
# BIN-NEXT: Locals: []
|
||||
# BIN-NEXT: Body: 200041002583808080002001FC1183808080000B
|
||||
|
||||
# BIN: - Type: CUSTOM
|
||||
# BIN-NEXT: Name: linking
|
||||
# BIN-NEXT: Version: 2
|
||||
|
|
|
@ -211,21 +211,23 @@ StringRef llvm::getEnumName(MVT::SimpleValueType T) {
|
|||
case MVT::nxv2bf16: return "MVT::nxv2bf16";
|
||||
case MVT::nxv4bf16: return "MVT::nxv4bf16";
|
||||
case MVT::nxv8bf16: return "MVT::nxv8bf16";
|
||||
case MVT::nxv1f32: return "MVT::nxv1f32";
|
||||
case MVT::nxv2f32: return "MVT::nxv2f32";
|
||||
case MVT::nxv4f32: return "MVT::nxv4f32";
|
||||
case MVT::nxv8f32: return "MVT::nxv8f32";
|
||||
case MVT::nxv16f32: return "MVT::nxv16f32";
|
||||
case MVT::nxv1f64: return "MVT::nxv1f64";
|
||||
case MVT::nxv2f64: return "MVT::nxv2f64";
|
||||
case MVT::nxv4f64: return "MVT::nxv4f64";
|
||||
case MVT::nxv8f64: return "MVT::nxv8f64";
|
||||
case MVT::token: return "MVT::token";
|
||||
case MVT::Metadata: return "MVT::Metadata";
|
||||
case MVT::iPTR: return "MVT::iPTR";
|
||||
case MVT::iPTRAny: return "MVT::iPTRAny";
|
||||
case MVT::Untyped: return "MVT::Untyped";
|
||||
case MVT::exnref: return "MVT::exnref";
|
||||
case MVT::nxv1f32: return "MVT::nxv1f32";
|
||||
case MVT::nxv2f32: return "MVT::nxv2f32";
|
||||
case MVT::nxv4f32: return "MVT::nxv4f32";
|
||||
case MVT::nxv8f32: return "MVT::nxv8f32";
|
||||
case MVT::nxv16f32: return "MVT::nxv16f32";
|
||||
case MVT::nxv1f64: return "MVT::nxv1f64";
|
||||
case MVT::nxv2f64: return "MVT::nxv2f64";
|
||||
case MVT::nxv4f64: return "MVT::nxv4f64";
|
||||
case MVT::nxv8f64: return "MVT::nxv8f64";
|
||||
case MVT::token: return "MVT::token";
|
||||
case MVT::Metadata: return "MVT::Metadata";
|
||||
case MVT::iPTR: return "MVT::iPTR";
|
||||
case MVT::iPTRAny: return "MVT::iPTRAny";
|
||||
case MVT::Untyped: return "MVT::Untyped";
|
||||
case MVT::exnref: return "MVT::exnref";
|
||||
case MVT::funcref: return "MVT::funcref";
|
||||
case MVT::externref: return "MVT::externref";
|
||||
default: llvm_unreachable("ILLEGAL VALUE TYPE!");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue