summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/asmjit/src/asmjit/core/archcommons.h
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/asmjit/src/asmjit/core/archcommons.h')
-rw-r--r--3rdparty/asmjit/src/asmjit/core/archcommons.h261
1 files changed, 261 insertions, 0 deletions
diff --git a/3rdparty/asmjit/src/asmjit/core/archcommons.h b/3rdparty/asmjit/src/asmjit/core/archcommons.h
new file mode 100644
index 00000000000..2b47d17c1b4
--- /dev/null
+++ b/3rdparty/asmjit/src/asmjit/core/archcommons.h
@@ -0,0 +1,261 @@
+// This file is part of AsmJit project <https://asmjit.com>
+//
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+
+#ifndef ASMJIT_CORE_ARCHCOMMONS_H_INCLUDED
+#define ASMJIT_CORE_ARCHCOMMONS_H_INCLUDED
+
+// This file provides architecture-specific classes that are required in the core library. For example Imm operand
+// allows to be created from arm::Shift in a const-expr way, so the arm::Shift must be provided. So this header file
+// provides everything architecture-specific that is used by the Core API.
+
+#include "../core/globals.h"
+
+ASMJIT_BEGIN_SUB_NAMESPACE(arm)
+
+//! \addtogroup asmjit_arm
+//! \{
+
+//! Condition code (both AArch32 & AArch64).
+//!
+//! \note This enumeration doesn't match condition code that is used in AArch32/AArch64 opcodes. In general this
+//! condition code is encoded as `(cc - 2) & 0xF` so that `kAL` condition code is zero and encoded as 0xE in opcode.
+//! This makes it easier to use a condition code as an instruction modifier that defaults to 'al'.
+enum class CondCode : uint8_t {
+ kAL = 0x00u, //!< (no condition code) (always)
+ kNA = 0x01u, //!< (not available) (special)
+ kEQ = 0x02u, //!< Z==1 (any_sign ==)
+ kNE = 0x03u, //!< Z==0 (any_sign !=)
+ kCS = 0x04u, //!< C==1 (unsigned >=)
+ kHS = 0x04u, //!< C==1 (unsigned >=)
+ kLO = 0x05u, //!< C==0 (unsigned < )
+ kCC = 0x05u, //!< C==0 (unsigned < )
+ kMI = 0x06u, //!< N==1 (is negative)
+ kPL = 0x07u, //!< N==0 (is positive or zero)
+ kVS = 0x08u, //!< V==1 (is overflow)
+ kVC = 0x09u, //!< V==0 (no overflow)
+ kHI = 0x0Au, //!< C==1 & Z==0 (unsigned > )
+ kLS = 0x0Bu, //!< C==0 | Z==1 (unsigned <=)
+ kGE = 0x0Cu, //!< N==V (signed >=)
+ kLT = 0x0Du, //!< N!=V (signed < )
+ kGT = 0x0Eu, //!< Z==0 & N==V (signed > )
+ kLE = 0x0Fu, //!< Z==1 | N!=V (signed <=)
+
+ kZero = kEQ, //!< Zero flag (alias to equal).
+ kNotZero = kNE, //!< Not zero (alias to Not Equal).
+
+ kEqual = kEQ, //!< Equal `a == b`.
+ kNotEqual = kNE, //!< Not Equal `a != b`.
+
+ kCarry = kCS, //!< Carry flag.
+ kNotCarry = kCC, //!< Not carry.
+
+ kSign = kMI, //!< Sign flag.
+ kNotSign = kPL, //!< Not sign.
+
+ kNegative = kMI, //!< Negative.
+ kPositive = kPL, //!< Positive or zero.
+
+ kOverflow = kVS, //!< Signed overflow.
+ kNotOverflow = kVC, //!< Not signed overflow.
+
+ kSignedLT = kLT, //!< Signed `a < b`.
+ kSignedLE = kLE, //!< Signed `a <= b`.
+ kSignedGT = kGT, //!< Signed `a > b`.
+ kSignedGE = kGE, //!< Signed `a >= b`.
+
+ kUnsignedLT = kLO, //!< Unsigned `a < b`.
+ kUnsignedLE = kLS, //!< Unsigned `a <= b`.
+ kUnsignedGT = kHI, //!< Unsigned `a > b`.
+ kUnsignedGE = kHS, //!< Unsigned `a >= b`.
+
+ kBTZero = kZero, //!< Tested bit is zero.
+ kBTNotZero = kNotZero, //!< Tested bit is not zero.
+
+ kAlways = kAL, //!< No condition code (always).
+
+ kMaxValue = 0x0Fu //!< Maximum value of `CondCode`.
+};
+
+
+//! \cond
+static constexpr CondCode _reverseCondTable[] = {
+ CondCode::kAL, // AL <- AL
+ CondCode::kNA, // NA <- NA
+ CondCode::kEQ, // EQ <- EQ
+ CondCode::kNE, // NE <- NE
+ CondCode::kLS, // LS <- CS
+ CondCode::kHI, // HI <- LO
+ CondCode::kMI, // MI <- MI
+ CondCode::kPL, // PL <- PL
+ CondCode::kVS, // VS <- VS
+ CondCode::kVC, // VC <- VC
+ CondCode::kLO, // LO <- HI
+ CondCode::kCS, // CS <- LS
+ CondCode::kLE, // LE <- GE
+ CondCode::kGT, // GT <- LT
+ CondCode::kLT, // LT <- GT
+ CondCode::kGE // GE <- LE
+};
+//! \endcond
+
+//! Reverses a condition code (reverses the corresponding operands of a comparison).
+static ASMJIT_INLINE_NODEBUG constexpr CondCode reverseCond(CondCode cond) noexcept { return _reverseCondTable[uint8_t(cond)]; }
+//! Negates a condition code.
+static ASMJIT_INLINE_NODEBUG constexpr CondCode negateCond(CondCode cond) noexcept { return CondCode(uint8_t(cond) ^ uint8_t(1)); }
+
+//! Memory offset mode.
+//!
+//! Describes either fixed, pre-index, or post-index offset modes.
+enum class OffsetMode : uint32_t {
+ //! Fixed offset mode (either no index at all or a regular index without a write-back).
+ kFixed = 0u,
+ //! Pre-index "[BASE, #Offset {, <shift>}]!" with write-back.
+ kPreIndex = 1u,
+ //! Post-index "[BASE], #Offset {, <shift>}" with write-back.
+ kPostIndex = 2u
+};
+
+//! Shift operation predicate (ARM) describes either SHIFT or EXTEND operation.
+//!
+//! \note The constants are AsmJit specific. The first 5 values describe real constants on ARM32 and AArch64 hardware,
+//! however, the addition constants that describe extend modes are specific to AsmJit and would be translated to the
+//! AArch64 specific constants by the assembler.
+enum class ShiftOp : uint32_t {
+ //! Shift left logical operation (default).
+ //!
+ //! Available to all ARM architectures.
+ kLSL = 0x00u,
+
+ //! Shift right logical operation.
+ //!
+ //! Available to all ARM architectures.
+ kLSR = 0x01u,
+
+ //! Shift right arithmetic operation.
+ //!
+ //! Available to all ARM architectures.
+ kASR = 0x02u,
+
+ //! Rotate right operation (AArch32 only).
+ kROR = 0x03u,
+
+ //! Rotate right with carry operation (encoded as `ShiftOp::kROR` with zero) (AArch32 only).
+ kRRX = 0x04u,
+
+ //! Shift left by filling low order bits with ones.
+ kMSL = 0x05u,
+
+ //! UXTN extend register operation (AArch64 only).
+ kUXTB = 0x06u,
+ //! UXTH extend register operation (AArch64 only).
+ kUXTH = 0x07u,
+ //! UXTW extend register operation (AArch64 only).
+ kUXTW = 0x08u,
+ //! UXTX extend register operation (AArch64 only).
+ kUXTX = 0x09u,
+
+ //! SXTB extend register operation (AArch64 only).
+ kSXTB = 0x0Au,
+ //! SXTH extend register operation (AArch64 only).
+ kSXTH = 0x0Bu,
+ //! SXTW extend register operation (AArch64 only).
+ kSXTW = 0x0Cu,
+ //! SXTX extend register operation (AArch64 only).
+ kSXTX = 0x0Du
+
+ // NOTE: 0xE and 0xF are used by memory operand to specify POST|PRE offset mode.
+};
+
+//! Represents ARM immediate shift operation type and value.
+class Shift {
+public:
+ //! Shift operation.
+ ShiftOp _op;
+ //! Shift Value.
+ uint32_t _value;
+
+ //! Default constructed Shift is not initialized.
+ ASMJIT_INLINE_NODEBUG Shift() noexcept = default;
+
+ //! Copy constructor (default)
+ ASMJIT_INLINE_NODEBUG constexpr Shift(const Shift& other) noexcept = default;
+
+ //! Constructs Shift from operation `op` and shift `value`.
+ ASMJIT_INLINE_NODEBUG constexpr Shift(ShiftOp op, uint32_t value) noexcept
+ : _op(op),
+ _value(value) {}
+
+ //! Returns the shift operation.
+ ASMJIT_INLINE_NODEBUG constexpr ShiftOp op() const noexcept { return _op; }
+ //! Sets shift operation to `op`.
+ ASMJIT_INLINE_NODEBUG void setOp(ShiftOp op) noexcept { _op = op; }
+
+ //! Returns the shift amount.
+ ASMJIT_INLINE_NODEBUG constexpr uint32_t value() const noexcept { return _value; }
+ //! Sets shift amount to `value`.
+ ASMJIT_INLINE_NODEBUG void setValue(uint32_t value) noexcept { _value = value; }
+};
+
+//! \}
+
+ASMJIT_END_SUB_NAMESPACE
+
+ASMJIT_BEGIN_SUB_NAMESPACE(a32)
+
+using namespace arm;
+
+//! Data type that can be encoded with AArch32 instruction identifier.
+//!
+//! \note Data types are frequently used with AArch32 SIMD instructions. For example `VMAX` instruction can
+//! use almost all datatypes in a form `VMAX.F32`, `VMAX.S16`, `VMAX.U32`, etc... Emitter automatically adds
+//! the required data type at emit level.
+enum class DataType : uint32_t {
+ //! No data type specified (default for all general purpose instructions).
+ kNone = 0,
+ //! 8-bit signed integer, specified as `.s8` in assembly.
+ kS8 = 1,
+ //! 16-bit signed integer, specified as `.s16` in assembly.
+ kS16 = 2,
+ //! 32-bit signed integer, specified as `.s32` in assembly.
+ kS32 = 3,
+ //! 64-bit signed integer, specified as `.s64` in assembly.
+ kS64 = 4,
+ //! 8-bit unsigned integer, specified as `.u8` in assembly.
+ kU8 = 5,
+ //! 16-bit unsigned integer, specified as `.u16` in assembly.
+ kU16 = 6,
+ //! 32-bit unsigned integer, specified as `.u32` in assembly.
+ kU32 = 7,
+ //! 64-bit unsigned integer, specified as `.u64` in assembly.
+ kU64 = 8,
+ //! 16-bit floating point (half precision), specified as `.f16` in assembly.
+ kF16 = 10,
+ //! 32-bit floating point (single precision), specified as `.f32` in assembly.
+ kF32 = 11,
+ //! 64-bit floating point (double precision), specified as `.f64` in assembly.
+ kF64 = 12,
+ //! 8-bit polynomial.
+ kP8 = 13,
+ //! 16-bit BF16 floating point.
+ kBF16 = 14,
+ //! 64-bit polynomial.
+ kP64 = 15,
+
+ //! Maximum value of `DataType`.
+ kMaxValue = 15
+};
+
+static ASMJIT_INLINE_NODEBUG uint32_t dataTypeSize(DataType dt) noexcept {
+ static constexpr uint8_t table[] = { 0, 1, 2, 4, 8, 1, 2, 4, 8, 2, 4, 8, 1, 2, 8 };
+ return table[size_t(dt)];
+}
+
+ASMJIT_END_SUB_NAMESPACE
+
+ASMJIT_BEGIN_SUB_NAMESPACE(a64)
+using namespace arm;
+ASMJIT_END_SUB_NAMESPACE
+
+#endif // ASMJIT_CORE_ARCHCOMMONS_H_INCLUDED