// Copyright 2013 the V8 project authors. All rights reserved.
|
// Use of this source code is governed by a BSD-style license that can be
|
// found in the LICENSE file.
|
|
#ifndef V8_COMPILER_MACHINE_OPERATOR_H_
|
#define V8_COMPILER_MACHINE_OPERATOR_H_
|
|
#include "src/base/compiler-specific.h"
|
#include "src/base/flags.h"
|
#include "src/globals.h"
|
#include "src/machine-type.h"
|
#include "src/utils.h"
|
#include "src/zone/zone.h"
|
|
namespace v8 {
|
namespace internal {
|
namespace compiler {
|
|
// Forward declarations.
|
struct MachineOperatorGlobalCache;
|
class Operator;
|
|
|
// For operators that are not supported on all platforms.
|
class OptionalOperator final {
|
public:
|
OptionalOperator(bool supported, const Operator* op)
|
: supported_(supported), op_(op) {}
|
|
bool IsSupported() const { return supported_; }
|
// Gets the operator only if it is supported.
|
const Operator* op() const {
|
DCHECK(supported_);
|
return op_;
|
}
|
// Always gets the operator, even for unsupported operators. This is useful to
|
// use the operator as a placeholder in a graph, for instance.
|
const Operator* placeholder() const { return op_; }
|
|
private:
|
bool supported_;
|
const Operator* const op_;
|
};
|
|
|
// A Load needs a MachineType.
|
typedef MachineType LoadRepresentation;
|
|
V8_EXPORT_PRIVATE LoadRepresentation LoadRepresentationOf(Operator const*)
|
V8_WARN_UNUSED_RESULT;
|
|
// A Store needs a MachineType and a WriteBarrierKind in order to emit the
|
// correct write barrier.
|
class StoreRepresentation final {
|
public:
|
StoreRepresentation(MachineRepresentation representation,
|
WriteBarrierKind write_barrier_kind)
|
: representation_(representation),
|
write_barrier_kind_(write_barrier_kind) {}
|
|
MachineRepresentation representation() const { return representation_; }
|
WriteBarrierKind write_barrier_kind() const { return write_barrier_kind_; }
|
|
private:
|
MachineRepresentation representation_;
|
WriteBarrierKind write_barrier_kind_;
|
};
|
|
V8_EXPORT_PRIVATE bool operator==(StoreRepresentation, StoreRepresentation);
|
bool operator!=(StoreRepresentation, StoreRepresentation);
|
|
size_t hash_value(StoreRepresentation);
|
|
V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, StoreRepresentation);
|
|
V8_EXPORT_PRIVATE StoreRepresentation const& StoreRepresentationOf(
|
Operator const*) V8_WARN_UNUSED_RESULT;
|
|
// An UnalignedStore needs a MachineType.
|
typedef MachineRepresentation UnalignedStoreRepresentation;
|
|
UnalignedStoreRepresentation const& UnalignedStoreRepresentationOf(
|
Operator const*) V8_WARN_UNUSED_RESULT;
|
|
class StackSlotRepresentation final {
|
public:
|
StackSlotRepresentation(int size, int alignment)
|
: size_(size), alignment_(alignment) {}
|
|
int size() const { return size_; }
|
int alignment() const { return alignment_; }
|
|
private:
|
int size_;
|
int alignment_;
|
};
|
|
V8_EXPORT_PRIVATE bool operator==(StackSlotRepresentation,
|
StackSlotRepresentation);
|
bool operator!=(StackSlotRepresentation, StackSlotRepresentation);
|
|
size_t hash_value(StackSlotRepresentation);
|
|
V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&,
|
StackSlotRepresentation);
|
|
V8_EXPORT_PRIVATE StackSlotRepresentation const& StackSlotRepresentationOf(
|
Operator const* op) V8_WARN_UNUSED_RESULT;
|
|
MachineRepresentation AtomicStoreRepresentationOf(Operator const* op)
|
V8_WARN_UNUSED_RESULT;
|
|
MachineType AtomicOpType(Operator const* op) V8_WARN_UNUSED_RESULT;
|
|
// Interface for building machine-level operators. These operators are
|
// machine-level but machine-independent and thus define a language suitable
|
// for generating code to run on architectures such as ia32, x64, arm, etc.
|
class V8_EXPORT_PRIVATE MachineOperatorBuilder final
|
: public NON_EXPORTED_BASE(ZoneObject) {
|
public:
|
// Flags that specify which operations are available. This is useful
|
// for operations that are unsupported by some back-ends.
|
enum Flag : unsigned {
|
kNoFlags = 0u,
|
kFloat32RoundDown = 1u << 0,
|
kFloat64RoundDown = 1u << 1,
|
kFloat32RoundUp = 1u << 2,
|
kFloat64RoundUp = 1u << 3,
|
kFloat32RoundTruncate = 1u << 4,
|
kFloat64RoundTruncate = 1u << 5,
|
kFloat32RoundTiesEven = 1u << 6,
|
kFloat64RoundTiesEven = 1u << 7,
|
kFloat64RoundTiesAway = 1u << 8,
|
kInt32DivIsSafe = 1u << 9,
|
kUint32DivIsSafe = 1u << 10,
|
kWord32ShiftIsSafe = 1u << 11,
|
kWord32Ctz = 1u << 12,
|
kWord64Ctz = 1u << 13,
|
kWord32Popcnt = 1u << 14,
|
kWord64Popcnt = 1u << 15,
|
kWord32ReverseBits = 1u << 16,
|
kWord64ReverseBits = 1u << 17,
|
kInt32AbsWithOverflow = 1u << 20,
|
kInt64AbsWithOverflow = 1u << 21,
|
kSpeculationFence = 1u << 22,
|
kAllOptionalOps =
|
kFloat32RoundDown | kFloat64RoundDown | kFloat32RoundUp |
|
kFloat64RoundUp | kFloat32RoundTruncate | kFloat64RoundTruncate |
|
kFloat64RoundTiesAway | kFloat32RoundTiesEven | kFloat64RoundTiesEven |
|
kWord32Ctz | kWord64Ctz | kWord32Popcnt | kWord64Popcnt |
|
kWord32ReverseBits | kWord64ReverseBits | kInt32AbsWithOverflow |
|
kInt64AbsWithOverflow | kSpeculationFence
|
};
|
typedef base::Flags<Flag, unsigned> Flags;
|
|
class AlignmentRequirements {
|
public:
|
enum UnalignedAccessSupport { kNoSupport, kSomeSupport, kFullSupport };
|
|
bool IsUnalignedLoadSupported(MachineRepresentation rep) const {
|
return IsUnalignedSupported(unalignedLoadUnsupportedTypes_, rep);
|
}
|
|
bool IsUnalignedStoreSupported(MachineRepresentation rep) const {
|
return IsUnalignedSupported(unalignedStoreUnsupportedTypes_, rep);
|
}
|
|
static AlignmentRequirements FullUnalignedAccessSupport() {
|
return AlignmentRequirements(kFullSupport);
|
}
|
static AlignmentRequirements NoUnalignedAccessSupport() {
|
return AlignmentRequirements(kNoSupport);
|
}
|
static AlignmentRequirements SomeUnalignedAccessUnsupported(
|
EnumSet<MachineRepresentation> unalignedLoadUnsupportedTypes,
|
EnumSet<MachineRepresentation> unalignedStoreUnsupportedTypes) {
|
return AlignmentRequirements(kSomeSupport, unalignedLoadUnsupportedTypes,
|
unalignedStoreUnsupportedTypes);
|
}
|
|
private:
|
explicit AlignmentRequirements(
|
AlignmentRequirements::UnalignedAccessSupport unalignedAccessSupport,
|
EnumSet<MachineRepresentation> unalignedLoadUnsupportedTypes =
|
EnumSet<MachineRepresentation>(),
|
EnumSet<MachineRepresentation> unalignedStoreUnsupportedTypes =
|
EnumSet<MachineRepresentation>())
|
: unalignedSupport_(unalignedAccessSupport),
|
unalignedLoadUnsupportedTypes_(unalignedLoadUnsupportedTypes),
|
unalignedStoreUnsupportedTypes_(unalignedStoreUnsupportedTypes) {}
|
|
bool IsUnalignedSupported(EnumSet<MachineRepresentation> unsupported,
|
MachineRepresentation rep) const {
|
// All accesses of bytes in memory are aligned.
|
DCHECK_NE(MachineRepresentation::kWord8, rep);
|
switch (unalignedSupport_) {
|
case kFullSupport:
|
return true;
|
case kNoSupport:
|
return false;
|
case kSomeSupport:
|
return !unsupported.Contains(rep);
|
}
|
UNREACHABLE();
|
}
|
|
const AlignmentRequirements::UnalignedAccessSupport unalignedSupport_;
|
const EnumSet<MachineRepresentation> unalignedLoadUnsupportedTypes_;
|
const EnumSet<MachineRepresentation> unalignedStoreUnsupportedTypes_;
|
};
|
|
explicit MachineOperatorBuilder(
|
Zone* zone,
|
MachineRepresentation word = MachineType::PointerRepresentation(),
|
Flags supportedOperators = kNoFlags,
|
AlignmentRequirements alignmentRequirements =
|
AlignmentRequirements::FullUnalignedAccessSupport());
|
|
const Operator* Comment(const char* msg);
|
const Operator* DebugAbort();
|
const Operator* DebugBreak();
|
const Operator* UnsafePointerAdd();
|
|
const Operator* Word32And();
|
const Operator* Word32Or();
|
const Operator* Word32Xor();
|
const Operator* Word32Shl();
|
const Operator* Word32Shr();
|
const Operator* Word32Sar();
|
const Operator* Word32Ror();
|
const Operator* Word32Equal();
|
const Operator* Word32Clz();
|
const OptionalOperator Word32Ctz();
|
const OptionalOperator Word32Popcnt();
|
const OptionalOperator Word64Popcnt();
|
const OptionalOperator Word32ReverseBits();
|
const OptionalOperator Word64ReverseBits();
|
const Operator* Word32ReverseBytes();
|
const Operator* Word64ReverseBytes();
|
const OptionalOperator Int32AbsWithOverflow();
|
const OptionalOperator Int64AbsWithOverflow();
|
|
// Return true if the target's Word32 shift implementation is directly
|
// compatible with JavaScript's specification. Otherwise, we have to manually
|
// generate a mask with 0x1f on the amount ahead of generating the shift.
|
bool Word32ShiftIsSafe() const { return flags_ & kWord32ShiftIsSafe; }
|
|
const Operator* Word64And();
|
const Operator* Word64Or();
|
const Operator* Word64Xor();
|
const Operator* Word64Shl();
|
const Operator* Word64Shr();
|
const Operator* Word64Sar();
|
const Operator* Word64Ror();
|
const Operator* Word64Clz();
|
const OptionalOperator Word64Ctz();
|
const Operator* Word64Equal();
|
|
const Operator* Int32PairAdd();
|
const Operator* Int32PairSub();
|
const Operator* Int32PairMul();
|
const Operator* Word32PairShl();
|
const Operator* Word32PairShr();
|
const Operator* Word32PairSar();
|
|
const Operator* Int32Add();
|
const Operator* Int32AddWithOverflow();
|
const Operator* Int32Sub();
|
const Operator* Int32SubWithOverflow();
|
const Operator* Int32Mul();
|
const Operator* Int32MulWithOverflow();
|
const Operator* Int32MulHigh();
|
const Operator* Int32Div();
|
const Operator* Int32Mod();
|
const Operator* Int32LessThan();
|
const Operator* Int32LessThanOrEqual();
|
const Operator* Uint32Div();
|
const Operator* Uint32LessThan();
|
const Operator* Uint32LessThanOrEqual();
|
const Operator* Uint32Mod();
|
const Operator* Uint32MulHigh();
|
bool Int32DivIsSafe() const { return flags_ & kInt32DivIsSafe; }
|
bool Uint32DivIsSafe() const { return flags_ & kUint32DivIsSafe; }
|
|
const Operator* Int64Add();
|
const Operator* Int64AddWithOverflow();
|
const Operator* Int64Sub();
|
const Operator* Int64SubWithOverflow();
|
const Operator* Int64Mul();
|
const Operator* Int64Div();
|
const Operator* Int64Mod();
|
const Operator* Int64LessThan();
|
const Operator* Int64LessThanOrEqual();
|
const Operator* Uint64Div();
|
const Operator* Uint64LessThan();
|
const Operator* Uint64LessThanOrEqual();
|
const Operator* Uint64Mod();
|
|
// This operator reinterprets the bits of a tagged pointer as word.
|
const Operator* BitcastTaggedToWord();
|
|
// This operator reinterprets the bits of a tagged MaybeObject pointer as
|
// word.
|
const Operator* BitcastMaybeObjectToWord();
|
|
// This operator reinterprets the bits of a word as tagged pointer.
|
const Operator* BitcastWordToTagged();
|
|
// This operator reinterprets the bits of a word as a Smi.
|
const Operator* BitcastWordToTaggedSigned();
|
|
// JavaScript float64 to int32/uint32 truncation.
|
const Operator* TruncateFloat64ToWord32();
|
|
// These operators change the representation of numbers while preserving the
|
// value of the number. Narrowing operators assume the input is representable
|
// in the target type and are *not* defined for other inputs.
|
// Use narrowing change operators only when there is a static guarantee that
|
// the input value is representable in the target value.
|
const Operator* ChangeFloat32ToFloat64();
|
const Operator* ChangeFloat64ToInt32(); // narrowing
|
const Operator* ChangeFloat64ToUint32(); // narrowing
|
const Operator* ChangeFloat64ToUint64();
|
const Operator* TruncateFloat64ToUint32();
|
const Operator* TruncateFloat32ToInt32();
|
const Operator* TruncateFloat32ToUint32();
|
const Operator* TryTruncateFloat32ToInt64();
|
const Operator* TryTruncateFloat64ToInt64();
|
const Operator* TryTruncateFloat32ToUint64();
|
const Operator* TryTruncateFloat64ToUint64();
|
const Operator* ChangeInt32ToFloat64();
|
const Operator* ChangeInt32ToInt64();
|
const Operator* ChangeUint32ToFloat64();
|
const Operator* ChangeUint32ToUint64();
|
|
// These operators truncate or round numbers, both changing the representation
|
// of the number and mapping multiple input values onto the same output value.
|
const Operator* TruncateFloat64ToFloat32();
|
const Operator* TruncateInt64ToInt32();
|
const Operator* RoundFloat64ToInt32();
|
const Operator* RoundInt32ToFloat32();
|
const Operator* RoundInt64ToFloat32();
|
const Operator* RoundInt64ToFloat64();
|
const Operator* RoundUint32ToFloat32();
|
const Operator* RoundUint64ToFloat32();
|
const Operator* RoundUint64ToFloat64();
|
|
// These operators reinterpret the bits of a floating point number as an
|
// integer and vice versa.
|
const Operator* BitcastFloat32ToInt32();
|
const Operator* BitcastFloat64ToInt64();
|
const Operator* BitcastInt32ToFloat32();
|
const Operator* BitcastInt64ToFloat64();
|
|
// These operators sign-extend to Int32/Int64
|
const Operator* SignExtendWord8ToInt32();
|
const Operator* SignExtendWord16ToInt32();
|
const Operator* SignExtendWord8ToInt64();
|
const Operator* SignExtendWord16ToInt64();
|
const Operator* SignExtendWord32ToInt64();
|
|
// Floating point operators always operate with IEEE 754 round-to-nearest
|
// (single-precision).
|
const Operator* Float32Add();
|
const Operator* Float32Sub();
|
const Operator* Float32Mul();
|
const Operator* Float32Div();
|
const Operator* Float32Sqrt();
|
|
// Floating point operators always operate with IEEE 754 round-to-nearest
|
// (double-precision).
|
const Operator* Float64Add();
|
const Operator* Float64Sub();
|
const Operator* Float64Mul();
|
const Operator* Float64Div();
|
const Operator* Float64Mod();
|
const Operator* Float64Sqrt();
|
|
// Floating point comparisons complying to IEEE 754 (single-precision).
|
const Operator* Float32Equal();
|
const Operator* Float32LessThan();
|
const Operator* Float32LessThanOrEqual();
|
|
// Floating point comparisons complying to IEEE 754 (double-precision).
|
const Operator* Float64Equal();
|
const Operator* Float64LessThan();
|
const Operator* Float64LessThanOrEqual();
|
|
// Floating point min/max complying to EcmaScript 6 (double-precision).
|
const Operator* Float64Max();
|
const Operator* Float64Min();
|
// Floating point min/max complying to WebAssembly (single-precision).
|
const Operator* Float32Max();
|
const Operator* Float32Min();
|
|
// Floating point abs complying to IEEE 754 (single-precision).
|
const Operator* Float32Abs();
|
|
// Floating point abs complying to IEEE 754 (double-precision).
|
const Operator* Float64Abs();
|
|
// Floating point rounding.
|
const OptionalOperator Float32RoundDown();
|
const OptionalOperator Float64RoundDown();
|
const OptionalOperator Float32RoundUp();
|
const OptionalOperator Float64RoundUp();
|
const OptionalOperator Float32RoundTruncate();
|
const OptionalOperator Float64RoundTruncate();
|
const OptionalOperator Float64RoundTiesAway();
|
const OptionalOperator Float32RoundTiesEven();
|
const OptionalOperator Float64RoundTiesEven();
|
|
// Floating point neg.
|
const Operator* Float32Neg();
|
const Operator* Float64Neg();
|
|
// Floating point trigonometric functions (double-precision).
|
const Operator* Float64Acos();
|
const Operator* Float64Acosh();
|
const Operator* Float64Asin();
|
const Operator* Float64Asinh();
|
const Operator* Float64Atan();
|
const Operator* Float64Atan2();
|
const Operator* Float64Atanh();
|
const Operator* Float64Cos();
|
const Operator* Float64Cosh();
|
const Operator* Float64Sin();
|
const Operator* Float64Sinh();
|
const Operator* Float64Tan();
|
const Operator* Float64Tanh();
|
|
// Floating point exponential functions (double-precision).
|
const Operator* Float64Exp();
|
const Operator* Float64Expm1();
|
const Operator* Float64Pow();
|
|
// Floating point logarithm (double-precision).
|
const Operator* Float64Log();
|
const Operator* Float64Log1p();
|
const Operator* Float64Log2();
|
const Operator* Float64Log10();
|
|
// Floating point cube root (double-precision).
|
const Operator* Float64Cbrt();
|
|
// Floating point bit representation.
|
const Operator* Float64ExtractLowWord32();
|
const Operator* Float64ExtractHighWord32();
|
const Operator* Float64InsertLowWord32();
|
const Operator* Float64InsertHighWord32();
|
|
// Change signalling NaN to quiet NaN.
|
// Identity for any input that is not signalling NaN.
|
const Operator* Float64SilenceNaN();
|
|
// SIMD operators.
|
const Operator* F32x4Splat();
|
const Operator* F32x4ExtractLane(int32_t);
|
const Operator* F32x4ReplaceLane(int32_t);
|
const Operator* F32x4SConvertI32x4();
|
const Operator* F32x4UConvertI32x4();
|
const Operator* F32x4Abs();
|
const Operator* F32x4Neg();
|
const Operator* F32x4RecipApprox();
|
const Operator* F32x4RecipSqrtApprox();
|
const Operator* F32x4Add();
|
const Operator* F32x4AddHoriz();
|
const Operator* F32x4Sub();
|
const Operator* F32x4Mul();
|
const Operator* F32x4Div();
|
const Operator* F32x4Min();
|
const Operator* F32x4Max();
|
const Operator* F32x4Eq();
|
const Operator* F32x4Ne();
|
const Operator* F32x4Lt();
|
const Operator* F32x4Le();
|
|
const Operator* I32x4Splat();
|
const Operator* I32x4ExtractLane(int32_t);
|
const Operator* I32x4ReplaceLane(int32_t);
|
const Operator* I32x4SConvertF32x4();
|
const Operator* I32x4SConvertI16x8Low();
|
const Operator* I32x4SConvertI16x8High();
|
const Operator* I32x4Neg();
|
const Operator* I32x4Shl(int32_t);
|
const Operator* I32x4ShrS(int32_t);
|
const Operator* I32x4Add();
|
const Operator* I32x4AddHoriz();
|
const Operator* I32x4Sub();
|
const Operator* I32x4Mul();
|
const Operator* I32x4MinS();
|
const Operator* I32x4MaxS();
|
const Operator* I32x4Eq();
|
const Operator* I32x4Ne();
|
const Operator* I32x4GtS();
|
const Operator* I32x4GeS();
|
|
const Operator* I32x4UConvertF32x4();
|
const Operator* I32x4UConvertI16x8Low();
|
const Operator* I32x4UConvertI16x8High();
|
const Operator* I32x4ShrU(int32_t);
|
const Operator* I32x4MinU();
|
const Operator* I32x4MaxU();
|
const Operator* I32x4GtU();
|
const Operator* I32x4GeU();
|
|
const Operator* I16x8Splat();
|
const Operator* I16x8ExtractLane(int32_t);
|
const Operator* I16x8ReplaceLane(int32_t);
|
const Operator* I16x8SConvertI8x16Low();
|
const Operator* I16x8SConvertI8x16High();
|
const Operator* I16x8Neg();
|
const Operator* I16x8Shl(int32_t);
|
const Operator* I16x8ShrS(int32_t);
|
const Operator* I16x8SConvertI32x4();
|
const Operator* I16x8Add();
|
const Operator* I16x8AddSaturateS();
|
const Operator* I16x8AddHoriz();
|
const Operator* I16x8Sub();
|
const Operator* I16x8SubSaturateS();
|
const Operator* I16x8Mul();
|
const Operator* I16x8MinS();
|
const Operator* I16x8MaxS();
|
const Operator* I16x8Eq();
|
const Operator* I16x8Ne();
|
const Operator* I16x8GtS();
|
const Operator* I16x8GeS();
|
|
const Operator* I16x8UConvertI8x16Low();
|
const Operator* I16x8UConvertI8x16High();
|
const Operator* I16x8ShrU(int32_t);
|
const Operator* I16x8UConvertI32x4();
|
const Operator* I16x8AddSaturateU();
|
const Operator* I16x8SubSaturateU();
|
const Operator* I16x8MinU();
|
const Operator* I16x8MaxU();
|
const Operator* I16x8GtU();
|
const Operator* I16x8GeU();
|
|
const Operator* I8x16Splat();
|
const Operator* I8x16ExtractLane(int32_t);
|
const Operator* I8x16ReplaceLane(int32_t);
|
const Operator* I8x16Neg();
|
const Operator* I8x16Shl(int32_t);
|
const Operator* I8x16ShrS(int32_t);
|
const Operator* I8x16SConvertI16x8();
|
const Operator* I8x16Add();
|
const Operator* I8x16AddSaturateS();
|
const Operator* I8x16Sub();
|
const Operator* I8x16SubSaturateS();
|
const Operator* I8x16Mul();
|
const Operator* I8x16MinS();
|
const Operator* I8x16MaxS();
|
const Operator* I8x16Eq();
|
const Operator* I8x16Ne();
|
const Operator* I8x16GtS();
|
const Operator* I8x16GeS();
|
|
const Operator* I8x16ShrU(int32_t);
|
const Operator* I8x16UConvertI16x8();
|
const Operator* I8x16AddSaturateU();
|
const Operator* I8x16SubSaturateU();
|
const Operator* I8x16MinU();
|
const Operator* I8x16MaxU();
|
const Operator* I8x16GtU();
|
const Operator* I8x16GeU();
|
|
const Operator* S128Load();
|
const Operator* S128Store();
|
|
const Operator* S128Zero();
|
const Operator* S128And();
|
const Operator* S128Or();
|
const Operator* S128Xor();
|
const Operator* S128Not();
|
const Operator* S128Select();
|
|
const Operator* S8x16Shuffle(const uint8_t shuffle[16]);
|
|
const Operator* S1x4AnyTrue();
|
const Operator* S1x4AllTrue();
|
const Operator* S1x8AnyTrue();
|
const Operator* S1x8AllTrue();
|
const Operator* S1x16AnyTrue();
|
const Operator* S1x16AllTrue();
|
|
// load [base + index]
|
const Operator* Load(LoadRepresentation rep);
|
const Operator* PoisonedLoad(LoadRepresentation rep);
|
const Operator* ProtectedLoad(LoadRepresentation rep);
|
|
// store [base + index], value
|
const Operator* Store(StoreRepresentation rep);
|
const Operator* ProtectedStore(MachineRepresentation rep);
|
|
// unaligned load [base + index]
|
const Operator* UnalignedLoad(LoadRepresentation rep);
|
|
// unaligned store [base + index], value
|
const Operator* UnalignedStore(UnalignedStoreRepresentation rep);
|
|
const Operator* StackSlot(int size, int alignment = 0);
|
const Operator* StackSlot(MachineRepresentation rep, int alignment = 0);
|
|
// Destroy value by masking when misspeculating.
|
const Operator* TaggedPoisonOnSpeculation();
|
const Operator* Word32PoisonOnSpeculation();
|
const Operator* Word64PoisonOnSpeculation();
|
|
// Access to the machine stack.
|
const Operator* LoadStackPointer();
|
const Operator* LoadFramePointer();
|
const Operator* LoadParentFramePointer();
|
|
// atomic-load [base + index]
|
const Operator* Word32AtomicLoad(LoadRepresentation rep);
|
// atomic-load [base + index]
|
const Operator* Word64AtomicLoad(LoadRepresentation rep);
|
// atomic-store [base + index], value
|
const Operator* Word32AtomicStore(MachineRepresentation rep);
|
// atomic-store [base + index], value
|
const Operator* Word64AtomicStore(MachineRepresentation rep);
|
// atomic-exchange [base + index], value
|
const Operator* Word32AtomicExchange(MachineType type);
|
// atomic-exchange [base + index], value
|
const Operator* Word64AtomicExchange(MachineType type);
|
// atomic-compare-exchange [base + index], old_value, new_value
|
const Operator* Word32AtomicCompareExchange(MachineType type);
|
// atomic-compare-exchange [base + index], old_value, new_value
|
const Operator* Word64AtomicCompareExchange(MachineType type);
|
// atomic-add [base + index], value
|
const Operator* Word32AtomicAdd(MachineType type);
|
// atomic-sub [base + index], value
|
const Operator* Word32AtomicSub(MachineType type);
|
// atomic-and [base + index], value
|
const Operator* Word32AtomicAnd(MachineType type);
|
// atomic-or [base + index], value
|
const Operator* Word32AtomicOr(MachineType type);
|
// atomic-xor [base + index], value
|
const Operator* Word32AtomicXor(MachineType rep);
|
// atomic-add [base + index], value
|
const Operator* Word64AtomicAdd(MachineType rep);
|
// atomic-sub [base + index], value
|
const Operator* Word64AtomicSub(MachineType type);
|
// atomic-and [base + index], value
|
const Operator* Word64AtomicAnd(MachineType type);
|
// atomic-or [base + index], value
|
const Operator* Word64AtomicOr(MachineType type);
|
// atomic-xor [base + index], value
|
const Operator* Word64AtomicXor(MachineType rep);
|
// atomic-narrow-add [base + index], value
|
const Operator* Word64AtomicNarrowAdd(MachineType type);
|
// atomic-narow-sub [base + index], value
|
const Operator* Word64AtomicNarrowSub(MachineType type);
|
// atomic-narrow-and [base + index], value
|
const Operator* Word64AtomicNarrowAnd(MachineType type);
|
// atomic-narrow-or [base + index], value
|
const Operator* Word64AtomicNarrowOr(MachineType type);
|
// atomic-narrow-xor [base + index], value
|
const Operator* Word64AtomicNarrowXor(MachineType type);
|
// atomic-narrow-exchange [base + index], value
|
const Operator* Word64AtomicNarrowExchange(MachineType type);
|
// atomic-narrow-compare-exchange [base + index], old_value, new_value
|
const Operator* Word64AtomicNarrowCompareExchange(MachineType type);
|
// atomic-pair-load [base + index]
|
const Operator* Word32AtomicPairLoad();
|
// atomic-pair-sub [base + index], value_high, value-low
|
const Operator* Word32AtomicPairStore();
|
// atomic-pair-add [base + index], value_high, value_low
|
const Operator* Word32AtomicPairAdd();
|
// atomic-pair-sub [base + index], value_high, value-low
|
const Operator* Word32AtomicPairSub();
|
// atomic-pair-and [base + index], value_high, value_low
|
const Operator* Word32AtomicPairAnd();
|
// atomic-pair-or [base + index], value_high, value_low
|
const Operator* Word32AtomicPairOr();
|
// atomic-pair-xor [base + index], value_high, value_low
|
const Operator* Word32AtomicPairXor();
|
// atomic-pair-exchange [base + index], value_high, value_low
|
const Operator* Word32AtomicPairExchange();
|
// atomic-pair-compare-exchange [base + index], old_value_high, old_value_low,
|
// new_value_high, new_value_low
|
const Operator* Word32AtomicPairCompareExchange();
|
|
const OptionalOperator SpeculationFence();
|
|
// Target machine word-size assumed by this builder.
|
bool Is32() const { return word() == MachineRepresentation::kWord32; }
|
bool Is64() const { return word() == MachineRepresentation::kWord64; }
|
MachineRepresentation word() const { return word_; }
|
|
bool UnalignedLoadSupported(MachineRepresentation rep) {
|
return alignment_requirements_.IsUnalignedLoadSupported(rep);
|
}
|
|
bool UnalignedStoreSupported(MachineRepresentation rep) {
|
return alignment_requirements_.IsUnalignedStoreSupported(rep);
|
}
|
|
// Pseudo operators that translate to 32/64-bit operators depending on the
|
// word-size of the target machine assumed by this builder.
|
#define PSEUDO_OP_LIST(V) \
|
V(Word, And) \
|
V(Word, Or) \
|
V(Word, Xor) \
|
V(Word, Shl) \
|
V(Word, Shr) \
|
V(Word, Sar) \
|
V(Word, Ror) \
|
V(Word, Clz) \
|
V(Word, Equal) \
|
V(Word, PoisonOnSpeculation) \
|
V(Int, Add) \
|
V(Int, Sub) \
|
V(Int, Mul) \
|
V(Int, Div) \
|
V(Int, Mod) \
|
V(Int, LessThan) \
|
V(Int, LessThanOrEqual) \
|
V(Uint, Div) \
|
V(Uint, LessThan) \
|
V(Uint, Mod)
|
#define PSEUDO_OP(Prefix, Suffix) \
|
const Operator* Prefix##Suffix() { \
|
return Is32() ? Prefix##32##Suffix() : Prefix##64##Suffix(); \
|
}
|
PSEUDO_OP_LIST(PSEUDO_OP)
|
#undef PSEUDO_OP
|
#undef PSEUDO_OP_LIST
|
|
private:
|
Zone* zone_;
|
MachineOperatorGlobalCache const& cache_;
|
MachineRepresentation const word_;
|
Flags const flags_;
|
AlignmentRequirements const alignment_requirements_;
|
|
DISALLOW_COPY_AND_ASSIGN(MachineOperatorBuilder);
|
};
|
|
|
DEFINE_OPERATORS_FOR_FLAGS(MachineOperatorBuilder::Flags)
|
|
} // namespace compiler
|
} // namespace internal
|
} // namespace v8
|
|
#endif // V8_COMPILER_MACHINE_OPERATOR_H_
|