blob: e52c999c14bc4e3b4a29bdac64fb6414ef9065f1 [file] [log] [blame]
/*
* Copyright 2019 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 wasm_features_h
#define wasm_features_h
#include <stdint.h>
#include <string>
#include "compiler-support.h"
#include "support/utilities.h"
struct FeatureSet {
enum Feature : uint32_t {
MVP = 0,
Atomics = 1 << 0,
MutableGlobals = 1 << 1,
TruncSat = 1 << 2,
SIMD = 1 << 3,
BulkMemory = 1 << 4,
SignExt = 1 << 5,
ExceptionHandling = 1 << 6,
TailCall = 1 << 7,
ReferenceTypes = 1 << 8,
All = (1 << 9) - 1
};
static std::string toString(Feature f) {
switch (f) {
case Atomics:
return "threads";
case MutableGlobals:
return "mutable-globals";
case TruncSat:
return "nontrapping-float-to-int";
case SIMD:
return "simd";
case BulkMemory:
return "bulk-memory";
case SignExt:
return "sign-ext";
case ExceptionHandling:
return "exception-handling";
case TailCall:
return "tail-call";
case ReferenceTypes:
return "reference-types";
default:
WASM_UNREACHABLE("unexpected feature");
}
}
FeatureSet() : features(MVP) {}
FeatureSet(uint32_t features) : features(features) {}
constexpr operator uint32_t() const { return features; }
bool isMVP() const { return features == MVP; }
bool has(FeatureSet f) { return (features & f) == f; }
bool hasAtomics() const { return (features & Atomics) != 0; }
bool hasMutableGlobals() const { return (features & MutableGlobals) != 0; }
bool hasTruncSat() const { return (features & TruncSat) != 0; }
bool hasSIMD() const { return (features & SIMD) != 0; }
bool hasBulkMemory() const { return (features & BulkMemory) != 0; }
bool hasSignExt() const { return (features & SignExt) != 0; }
bool hasExceptionHandling() const {
return (features & ExceptionHandling) != 0;
}
bool hasTailCall() const { return (features & TailCall) != 0; }
bool hasReferenceTypes() const { return (features & ReferenceTypes) != 0; }
bool hasAll() const { return (features & All) != 0; }
void makeMVP() { features = MVP; }
void set(FeatureSet f, bool v = true) {
features = v ? (features | f) : (features & ~f);
}
void setAtomics(bool v = true) { set(Atomics, v); }
void setMutableGlobals(bool v = true) { set(MutableGlobals, v); }
void setTruncSat(bool v = true) { set(TruncSat, v); }
void setSIMD(bool v = true) { set(SIMD, v); }
void setBulkMemory(bool v = true) { set(BulkMemory, v); }
void setSignExt(bool v = true) { set(SignExt, v); }
void setExceptionHandling(bool v = true) { set(ExceptionHandling, v); }
void setTailCall(bool v = true) { set(TailCall, v); }
void setReferenceTypes(bool v = true) { set(ReferenceTypes, v); }
void setAll(bool v = true) { features = v ? All : MVP; }
void enable(const FeatureSet& other) { features |= other.features; }
void disable(const FeatureSet& other) {
features = features & ~other.features & All;
}
template<typename F> void iterFeatures(F f) {
if (hasAtomics()) {
f(Atomics);
}
if (hasBulkMemory()) {
f(BulkMemory);
}
if (hasExceptionHandling()) {
f(ExceptionHandling);
}
if (hasMutableGlobals()) {
f(MutableGlobals);
}
if (hasTruncSat()) {
f(TruncSat);
}
if (hasSignExt()) {
f(SignExt);
}
if (hasSIMD()) {
f(SIMD);
}
if (hasTailCall()) {
f(TailCall);
}
if (hasReferenceTypes()) {
f(ReferenceTypes);
}
}
bool operator<=(const FeatureSet& other) const {
return !(features & ~other.features);
}
bool operator==(const FeatureSet& other) const {
return *this <= other && other <= *this;
}
bool operator!=(const FeatureSet& other) const { return !(*this == other); }
FeatureSet& operator|=(const FeatureSet& other) {
features |= other.features;
return *this;
}
uint32_t features;
};
#endif // wasm_features_h