From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- third_party/wasm2c/include/wabt/opcode.h | 172 +++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 third_party/wasm2c/include/wabt/opcode.h (limited to 'third_party/wasm2c/include/wabt/opcode.h') diff --git a/third_party/wasm2c/include/wabt/opcode.h b/third_party/wasm2c/include/wabt/opcode.h new file mode 100644 index 0000000000..a7c7b2495a --- /dev/null +++ b/third_party/wasm2c/include/wabt/opcode.h @@ -0,0 +1,172 @@ +/* + * Copyright 2017 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_OPCODE_H_ +#define WABT_OPCODE_H_ + +#include + +#include "wabt/common.h" +#include "wabt/leb128.h" +#include "wabt/opcode-code-table.h" + +namespace wabt { + +class Features; + +struct Opcode { + // Opcode enumerations. + // + // NOTE: this enum does not match the binary encoding. + // + enum Enum : uint32_t { +#define WABT_OPCODE(rtype, type1, type2, type3, mem_size, prefix, code, Name, \ + text, decomp) \ + Name, +#include "wabt/opcode.def" +#undef WABT_OPCODE + Invalid, + }; + +// Static opcode objects. +#define WABT_OPCODE(rtype, type1, type2, type3, mem_size, prefix, code, Name, \ + text, decomp) \ + static Opcode Name##_Opcode; +#include "wabt/opcode.def" +#undef WABT_OPCODE + + Opcode() = default; // Provided so Opcode can be member of a union. + Opcode(Enum e) : enum_(e) {} + operator Enum() const { return enum_; } + + static Opcode FromCode(uint32_t); + static Opcode FromCode(uint8_t prefix, uint32_t code); + bool HasPrefix() const { return GetInfo().prefix != 0; } + uint8_t GetPrefix() const { return GetInfo().prefix; } + uint32_t GetCode() const { return GetInfo().code; } + size_t GetLength() const { return GetBytes().size(); } + const char* GetName() const { return GetInfo().name; } + const char* GetDecomp() const { + return *GetInfo().decomp ? GetInfo().decomp : GetInfo().name; + } + Type GetResultType() const { return GetInfo().result_type; } + Type GetParamType1() const { return GetInfo().param_types[0]; } + Type GetParamType2() const { return GetInfo().param_types[1]; } + Type GetParamType3() const { return GetInfo().param_types[2]; } + Type GetParamType(int n) const { return GetInfo().param_types[n - 1]; } + Address GetMemorySize() const { return GetInfo().memory_size; } + + // Get the byte sequence for this opcode, including prefix. + std::vector GetBytes() const; + + // Get the lane count of an extract/replace simd op. + uint32_t GetSimdLaneCount() const; + + // Return 1 if |alignment| matches the alignment of |opcode|, or if + // |alignment| is WABT_USE_NATURAL_ALIGNMENT. + bool IsNaturallyAligned(Address alignment) const; + + // If |alignment| is WABT_USE_NATURAL_ALIGNMENT, return the alignment of + // |opcode|, else return |alignment|. + Address GetAlignment(Address alignment) const; + + static bool IsPrefixByte(uint8_t byte) { + return byte == kMathPrefix || byte == kThreadsPrefix || byte == kSimdPrefix; + } + + bool IsEnabled(const Features& features) const; + bool IsInvalid() const { return enum_ >= Invalid; } + + private: + static constexpr uint32_t kMathPrefix = 0xfc; + static constexpr uint32_t kThreadsPrefix = 0xfe; + static constexpr uint32_t kSimdPrefix = 0xfd; + + struct Info { + const char* name; + const char* decomp; + Type result_type; + Type param_types[3]; + Address memory_size; + uint8_t prefix; + uint32_t code; + uint32_t prefix_code; // See PrefixCode below. Used for fast lookup. + }; + + static uint32_t PrefixCode(uint8_t prefix, uint32_t code) { + if (code >= (1 << MAX_OPCODE_BITS)) { + // Clamp to (2^bits - 1), since we know that it is an invalid code. + code = (1 << MAX_OPCODE_BITS) - 1; + } + return (prefix << MAX_OPCODE_BITS) | code; + } + + // The Opcode struct only stores an enumeration (Opcode::Enum) of all valid + // opcodes, densely packed. We want to be able to store invalid opcodes as + // well, for display to the user. To encode these, we use PrefixCode() to + // generate a uint32_t of the prefix/code pair, then negate the value so it + // doesn't overlap with the valid enum values. The negation is done using + // `~code + 1` since prefix_code is unsigned, and MSVC warns if you use - on + // an unsigned value. + // + // | 0 | Opcode::Invalid | INT32_MAX+1 UINT32_MAX | + // |---------------|-------------------------|---------------------------| + // | valid opcodes | unused space | invalid opcodes | + // + static Enum EncodeInvalidOpcode(uint32_t prefix_code) { + Enum result = static_cast(~prefix_code + 1); + assert(result >= Invalid); + return result; + } + + static void DecodeInvalidOpcode(Enum e, + uint8_t* out_prefix, + uint32_t* out_code) { + uint32_t prefix_code = ~static_cast(e) + 1; + *out_prefix = prefix_code >> MAX_OPCODE_BITS; + *out_code = prefix_code & 0xff; + } + + Info GetInfo() const; + static Info infos_[]; + + Enum enum_; +}; + +// static +inline Opcode Opcode::FromCode(uint32_t code) { + return FromCode(0, code); +} + +// static +inline Opcode Opcode::FromCode(uint8_t prefix, uint32_t code) { + uint32_t prefix_code = PrefixCode(prefix, code); + + if (WABT_LIKELY(prefix_code < WABT_ARRAY_SIZE(WabtOpcodeCodeTable))) { + uint32_t value = WabtOpcodeCodeTable[prefix_code]; + // The default value in the table is 0. That's a valid value, but only if + // the code is 0 (for nop). + if (WABT_LIKELY(value != 0 || code == 0)) { + return Opcode(static_cast(value)); + } + } + + return Opcode(EncodeInvalidOpcode(prefix_code)); +} + +} // namespace wabt + +#endif // WABT_OPCODE_H_ -- cgit v1.2.3