mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-11 07:12:02 +00:00
506 lines
23 KiB
C++
506 lines
23 KiB
C++
// [AsmJit]
|
|
// Complete x86/x64 JIT and Remote Assembler for C++.
|
|
//
|
|
// [License]
|
|
// Zlib - See LICENSE.md file in the package.
|
|
|
|
// [Guard]
|
|
#ifndef _ASMJIT_X86_X86GLOBALS_H
|
|
#define _ASMJIT_X86_X86GLOBALS_H
|
|
|
|
// [Dependencies]
|
|
#include "../base/globals.h"
|
|
|
|
// [Api-Begin]
|
|
#include "../asmjit_apibegin.h"
|
|
|
|
namespace asmjit {
|
|
|
|
//! \addtogroup asmjit_x86
|
|
//! \{
|
|
|
|
// ============================================================================
|
|
// [asmjit::x86regs::]
|
|
// ============================================================================
|
|
|
|
//! X86 registers.
|
|
namespace x86regs {}
|
|
|
|
// ============================================================================
|
|
// [asmjit::x86defs::]
|
|
// ============================================================================
|
|
|
|
//! X86 definitions.
|
|
namespace x86defs {
|
|
|
|
// ============================================================================
|
|
// [asmjit::x86defs::SpecialRegs]
|
|
// ============================================================================
|
|
|
|
//! Flags describing special registers and/or their parts.
|
|
ASMJIT_ENUM(SpecialRegs) {
|
|
kSpecialReg_FLAGS_CF = 0x00000001U, //!< [R|E]FLAGS - Carry flag.
|
|
kSpecialReg_FLAGS_PF = 0x00000002U, //!< [R|E]FLAGS - Parity flag.
|
|
kSpecialReg_FLAGS_AF = 0x00000004U, //!< [R|E]FLAGS - Adjust flag.
|
|
kSpecialReg_FLAGS_ZF = 0x00000008U, //!< [R|E]FLAGS - Zero flag.
|
|
kSpecialReg_FLAGS_SF = 0x00000010U, //!< [R|E]FLAGS - Sign flag.
|
|
kSpecialReg_FLAGS_TF = 0x00000020U, //!< [R|E]FLAGS - Trap flag.
|
|
kSpecialReg_FLAGS_IF = 0x00000040U, //!< [R|E]FLAGS - Interrupt enable flag.
|
|
kSpecialReg_FLAGS_DF = 0x00000080U, //!< [R|E]FLAGS - Direction flag.
|
|
kSpecialReg_FLAGS_OF = 0x00000100U, //!< [R|E]FLAGS - Overflow flag.
|
|
kSpecialReg_FLAGS_AC = 0x00000200U, //!< [R|E]FLAGS - Alignment check.
|
|
kSpecialReg_FLAGS_SYS = 0x00000400U, //!< [R|E]FLAGS - System flags.
|
|
|
|
kSpecialReg_X87CW_EXC = 0x00000800U, //!< X87 Control Word - Exception control.
|
|
kSpecialReg_X87CW_PC = 0x00001000U, //!< X87 Control Word - Precision control.
|
|
kSpecialReg_X87CW_RC = 0x00002000U, //!< X87 Control Word - Rounding control.
|
|
|
|
kSpecialReg_X87SW_EXC = 0x00004000U, //!< X87 Status Word - Exception flags.
|
|
kSpecialReg_X87SW_C0 = 0x00008000U, //!< X87 Status Word - C0 flag.
|
|
kSpecialReg_X87SW_C1 = 0x00010000U, //!< X87 Status Word - C1 flag.
|
|
kSpecialReg_X87SW_C2 = 0x00020000U, //!< X87 Status Word - C2 flag.
|
|
kSpecialReg_X87SW_TOP = 0x00040000U, //!< X87 Status Word - Top of the FPU stack.
|
|
kSpecialReg_X87SW_C3 = 0x00080000U, //!< X87 Status Word - C3 flag.
|
|
|
|
kSpecialReg_MSR = 0x00100000U, //!< MSR register.
|
|
kSpecialReg_XCR = 0x00200000U //!< XCR register.
|
|
};
|
|
|
|
// ============================================================================
|
|
// [asmjit::x86defs::X87SW]
|
|
// ============================================================================
|
|
|
|
//! FPU status word.
|
|
ASMJIT_ENUM(X87SW) {
|
|
kX87SW_Invalid = 0x0001U,
|
|
kX87SW_Denormalized = 0x0002U,
|
|
kX87SW_DivByZero = 0x0004U,
|
|
kX87SW_Overflow = 0x0008U,
|
|
kX87SW_Underflow = 0x0010U,
|
|
kX87SW_Precision = 0x0020U,
|
|
kX87SW_StackFault = 0x0040U,
|
|
kX87SW_Interrupt = 0x0080U,
|
|
kX87SW_C0 = 0x0100U,
|
|
kX87SW_C1 = 0x0200U,
|
|
kX87SW_C2 = 0x0400U,
|
|
kX87SW_Top = 0x3800U,
|
|
kX87SW_C3 = 0x4000U,
|
|
kX87SW_Busy = 0x8000U
|
|
};
|
|
|
|
// ============================================================================
|
|
// [asmjit::x86defs::X87CW]
|
|
// ============================================================================
|
|
|
|
//! FPU control word.
|
|
ASMJIT_ENUM(X87CW) {
|
|
// Bits 0-5.
|
|
kX87CW_EM_Mask = 0x003FU,
|
|
kX87CW_EM_Invalid = 0x0001U,
|
|
kX87CW_EM_Denormal = 0x0002U,
|
|
kX87CW_EM_DivByZero = 0x0004U,
|
|
kX87CW_EM_Overflow = 0x0008U,
|
|
kX87CW_EM_Underflow = 0x0010U,
|
|
kX87CW_EM_Inexact = 0x0020U,
|
|
|
|
// Bits 8-9.
|
|
kX87CW_PC_Mask = 0x0300U,
|
|
kX87CW_PC_Float = 0x0000U,
|
|
kX87CW_PC_Reserved = 0x0100U,
|
|
kX87CW_PC_Double = 0x0200U,
|
|
kX87CW_PC_Extended = 0x0300U,
|
|
|
|
// Bits 10-11.
|
|
kX87CW_RC_Mask = 0x0C00U,
|
|
kX87CW_RC_Nearest = 0x0000U,
|
|
kX87CW_RC_Down = 0x0400U,
|
|
kX87CW_RC_Up = 0x0800U,
|
|
kX87CW_RC_Truncate = 0x0C00U,
|
|
|
|
// Bit 12.
|
|
kX87CW_IC_Mask = 0x1000U,
|
|
kX87CW_IC_Projective = 0x0000U,
|
|
kX87CW_IC_Affine = 0x1000U
|
|
};
|
|
|
|
// ============================================================================
|
|
// [asmjit::x86defs::Cond]
|
|
// ============================================================================
|
|
|
|
//! Condition codes.
|
|
ASMJIT_ENUM(Cond) {
|
|
kCondO = 0x00U, //!< OF==1
|
|
kCondNO = 0x01U, //!< OF==0
|
|
kCondB = 0x02U, //!< CF==1 (unsigned < )
|
|
kCondC = 0x02U, //!< CF==1
|
|
kCondNAE = 0x02U, //!< CF==1 (unsigned < )
|
|
kCondAE = 0x03U, //!< CF==0 (unsigned >=)
|
|
kCondNB = 0x03U, //!< CF==0 (unsigned >=)
|
|
kCondNC = 0x03U, //!< CF==0
|
|
kCondE = 0x04U, //!< ZF==1 (any_sign ==)
|
|
kCondZ = 0x04U, //!< ZF==1 (any_sign ==)
|
|
kCondNE = 0x05U, //!< ZF==0 (any_sign !=)
|
|
kCondNZ = 0x05U, //!< ZF==0 (any_sign !=)
|
|
kCondBE = 0x06U, //!< CF==1 | ZF==1 (unsigned <=)
|
|
kCondNA = 0x06U, //!< CF==1 | ZF==1 (unsigned <=)
|
|
kCondA = 0x07U, //!< CF==0 & ZF==0 (unsigned > )
|
|
kCondNBE = 0x07U, //!< CF==0 & ZF==0 (unsigned > )
|
|
kCondS = 0x08U, //!< SF==1 (is negative)
|
|
kCondNS = 0x09U, //!< SF==0 (is positive or zero)
|
|
kCondP = 0x0AU, //!< PF==1
|
|
kCondPE = 0x0AU, //!< PF==1
|
|
kCondPO = 0x0BU, //!< PF==0
|
|
kCondNP = 0x0BU, //!< PF==0
|
|
kCondL = 0x0CU, //!< SF!=OF (signed < )
|
|
kCondNGE = 0x0CU, //!< SF!=OF (signed < )
|
|
kCondGE = 0x0DU, //!< SF==OF (signed >=)
|
|
kCondNL = 0x0DU, //!< SF==OF (signed >=)
|
|
kCondLE = 0x0EU, //!< ZF==1 | SF!=OF (signed <=)
|
|
kCondNG = 0x0EU, //!< ZF==1 | SF!=OF (signed <=)
|
|
kCondG = 0x0FU, //!< ZF==0 & SF==OF (signed > )
|
|
kCondNLE = 0x0FU, //!< ZF==0 & SF==OF (signed > )
|
|
kCondCount = 0x10U,
|
|
|
|
// Simplified condition codes.
|
|
kCondSign = kCondS, //!< Sign.
|
|
kCondNotSign = kCondNS, //!< Not Sign.
|
|
|
|
kCondOverflow = kCondO, //!< Signed overflow.
|
|
kCondNotOverflow = kCondNO, //!< Not signed overflow.
|
|
|
|
kCondEqual = kCondE, //!< Equal `a == b`.
|
|
kCondNotEqual = kCondNE, //!< Not Equal `a != b`.
|
|
|
|
kCondSignedLT = kCondL, //!< Signed `a < b`.
|
|
kCondSignedLE = kCondLE, //!< Signed `a <= b`.
|
|
kCondSignedGT = kCondG, //!< Signed `a > b`.
|
|
kCondSignedGE = kCondGE, //!< Signed `a >= b`.
|
|
|
|
kCondUnsignedLT = kCondB, //!< Unsigned `a < b`.
|
|
kCondUnsignedLE = kCondBE, //!< Unsigned `a <= b`.
|
|
kCondUnsignedGT = kCondA, //!< Unsigned `a > b`.
|
|
kCondUnsignedGE = kCondAE, //!< Unsigned `a >= b`.
|
|
|
|
kCondZero = kCondZ,
|
|
kCondNotZero = kCondNZ,
|
|
|
|
kCondNegative = kCondS,
|
|
kCondPositive = kCondNS,
|
|
|
|
kCondParityEven = kCondP,
|
|
kCondParityOdd = kCondPO
|
|
};
|
|
|
|
// ============================================================================
|
|
// [asmjit::x86defs::CmpPredicate]
|
|
// ============================================================================
|
|
|
|
//! A predicate used by CMP[PD|PS|SD|SS] instructions.
|
|
ASMJIT_ENUM(CmpPredicate) {
|
|
kCmpEQ = 0x00U, //!< Equal (Quiet).
|
|
kCmpLT = 0x01U, //!< Less (Signaling).
|
|
kCmpLE = 0x02U, //!< Less/Equal (Signaling).
|
|
kCmpUNORD = 0x03U, //!< Unordered (Quiet).
|
|
kCmpNEQ = 0x04U, //!< Not Equal (Quiet).
|
|
kCmpNLT = 0x05U, //!< Not Less (Signaling).
|
|
kCmpNLE = 0x06U, //!< Not Less/Equal (Signaling).
|
|
kCmpORD = 0x07U //!< Ordered (Quiet).
|
|
};
|
|
|
|
// ============================================================================
|
|
// [asmjit::x86defs::VCmpPredicate]
|
|
// ============================================================================
|
|
|
|
//! A predicate used by VCMP[PD|PS|SD|SS] instructions.
|
|
//!
|
|
//! The first 8 values are compatible with \ref CmpPredicate.
|
|
ASMJIT_ENUM(VCmpPredicate) {
|
|
kVCmpEQ_OQ = 0x00U, //!< Equal (Quiet , Ordered).
|
|
kVCmpLT_OS = 0x01U, //!< Less (Signaling, Ordered).
|
|
kVCmpLE_OS = 0x02U, //!< Less/Equal (Signaling, Ordered).
|
|
kVCmpUNORD_Q = 0x03U, //!< Unordered (Quiet).
|
|
kVCmpNEQ_UQ = 0x04U, //!< Not Equal (Quiet , Unordered).
|
|
kVCmpNLT_US = 0x05U, //!< Not Less (Signaling, Unordered).
|
|
kVCmpNLE_US = 0x06U, //!< Not Less/Equal (Signaling, Unordered).
|
|
kVCmpORD_Q = 0x07U, //!< Ordered (Quiet).
|
|
kVCmpEQ_UQ = 0x08U, //!< Equal (Quiet , Unordered).
|
|
kVCmpNGE_US = 0x09U, //!< Not Greater/Equal (Signaling, Unordered).
|
|
kVCmpNGT_US = 0x0AU, //!< Not Greater (Signaling, Unordered).
|
|
kVCmpFALSE_OQ = 0x0BU, //!< False (Quiet , Ordered).
|
|
kVCmpNEQ_OQ = 0x0CU, //!< Not Equal (Quiet , Ordered).
|
|
kVCmpGE_OS = 0x0DU, //!< Greater/Equal (Signaling, Ordered).
|
|
kVCmpGT_OS = 0x0EU, //!< Greater (Signaling, Ordered).
|
|
kVCmpTRUE_UQ = 0x0FU, //!< True (Quiet , Unordered).
|
|
kVCmpEQ_OS = 0x10U, //!< Equal (Signaling, Ordered).
|
|
kVCmpLT_OQ = 0x11U, //!< Less (Quiet , Ordered).
|
|
kVCmpLE_OQ = 0x12U, //!< Less/Equal (Quiet , Ordered).
|
|
kVCmpUNORD_S = 0x13U, //!< Unordered (Signaling).
|
|
kVCmpNEQ_US = 0x14U, //!< Not Equal (Signaling, Unordered).
|
|
kVCmpNLT_UQ = 0x15U, //!< Not Less (Quiet , Unordered).
|
|
kVCmpNLE_UQ = 0x16U, //!< Not Less/Equal (Quiet , Unordered).
|
|
kVCmpORD_S = 0x17U, //!< Ordered (Signaling).
|
|
kVCmpEQ_US = 0x18U, //!< Equal (Signaling, Unordered).
|
|
kVCmpNGE_UQ = 0x19U, //!< Not Greater/Equal (Quiet , Unordered).
|
|
kVCmpNGT_UQ = 0x1AU, //!< Not Greater (Quiet , Unordered).
|
|
kVCmpFALSE_OS = 0x1BU, //!< False (Signaling, Ordered).
|
|
kVCmpNEQ_OS = 0x1CU, //!< Not Equal (Signaling, Ordered).
|
|
kVCmpGE_OQ = 0x1DU, //!< Greater/Equal (Quiet , Ordered).
|
|
kVCmpGT_OQ = 0x1EU, //!< Greater (Quiet , Ordered).
|
|
kVCmpTRUE_US = 0x1FU //!< True (Signaling, Unordered).
|
|
};
|
|
|
|
// ============================================================================
|
|
// [asmjit::x86defs::PCmpStrPredicate]
|
|
// ============================================================================
|
|
|
|
//! A predicate used by [V]PCMP[I|E]STR[I|M] instructions.
|
|
ASMJIT_ENUM(PCmpStrPredicate) {
|
|
// Source data format:
|
|
kPCmpStrUB = 0x00U << 0, //!< The source data format is unsigned bytes.
|
|
kPCmpStrUW = 0x01U << 0, //!< The source data format is unsigned words.
|
|
kPCmpStrSB = 0x02U << 0, //!< The source data format is signed bytes.
|
|
kPCmpStrSW = 0x03U << 0, //!< The source data format is signed words.
|
|
|
|
// Aggregation operation:
|
|
kPCmpStrEqualAny = 0x00U << 2, //!< The arithmetic comparison is "equal".
|
|
kPCmpStrRanges = 0x01U << 2, //!< The arithmetic comparison is “greater than or equal”
|
|
//!< between even indexed elements and “less than or equal”
|
|
//!< between odd indexed elements.
|
|
kPCmpStrEqualEach = 0x02U << 2, //!< The arithmetic comparison is "equal".
|
|
kPCmpStrEqualOrdered = 0x03U << 2, //!< The arithmetic comparison is "equal".
|
|
|
|
// Polarity:
|
|
kPCmpStrPosPolarity = 0x00U << 4, //!< IntRes2 = IntRes1.
|
|
kPCmpStrNegPolarity = 0x01U << 4, //!< IntRes2 = -1 XOR IntRes1.
|
|
kPCmpStrPosMasked = 0x02U << 4, //!< IntRes2 = IntRes1.
|
|
kPCmpStrNegMasked = 0x03U << 4, //!< IntRes2[i] = second[i] == invalid ? IntRes1[i] : ~IntRes1[i].
|
|
|
|
// Output selection (pcmpstri):
|
|
kPCmpStrOutputLSI = 0x00U << 6, //!< The index returned to ECX is of the least significant set bit in IntRes2.
|
|
kPCmpStrOutputMSI = 0x01U << 6, //!< The index returned to ECX is of the most significant set bit in IntRes2.
|
|
|
|
// Output selection (pcmpstrm):
|
|
kPCmpStrBitMask = 0x00U << 6, //!< IntRes2 is returned as the mask to the least significant bits of XMM0.
|
|
kPCmpStrIndexMask = 0x01U << 6 //!< IntRes2 is expanded into a byte/word mask and placed in XMM0.
|
|
};
|
|
|
|
// ============================================================================
|
|
// [asmjit::x86defs::VPCmpPredicate]
|
|
// ============================================================================
|
|
|
|
//! A predicate used by VPCMP[U][B|W|D|Q] instructions (AVX-512).
|
|
ASMJIT_ENUM(VPCmpPredicate) {
|
|
kVPCmpEQ = 0x00U, //!< Equal.
|
|
kVPCmpLT = 0x01U, //!< Less.
|
|
kVPCmpLE = 0x02U, //!< Less/Equal.
|
|
kVPCmpFALSE = 0x03U, //!< False.
|
|
kVPCmpNE = 0x04U, //!< Not Equal.
|
|
kVPCmpGE = 0x05U, //!< Greater/Equal.
|
|
kVPCmpGT = 0x06U, //!< Greater.
|
|
kVPCmpTRUE = 0x07U //!< True.
|
|
};
|
|
|
|
// ============================================================================
|
|
// [asmjit::x86defs::VPComPredicate]
|
|
// ============================================================================
|
|
|
|
//! A predicate used by VPCOM[U][B|W|D|Q] instructions (XOP).
|
|
ASMJIT_ENUM(VPComPredicate) {
|
|
kVPComLT = 0x00U, //!< Less.
|
|
kVPComLE = 0x01U, //!< Less/Equal
|
|
kVPComGT = 0x02U, //!< Greater.
|
|
kVPComGE = 0x03U, //!< Greater/Equal.
|
|
kVPComEQ = 0x04U, //!< Equal.
|
|
kVPComNE = 0x05U, //!< Not Equal.
|
|
kVPComFALSE = 0x06U, //!< False.
|
|
kVPComTRUE = 0x07U //!< True.
|
|
};
|
|
|
|
// ============================================================================
|
|
// [asmjit::x86defs::VFPClassPredicate]
|
|
// ============================================================================
|
|
|
|
//! A predicate used by VFPCLASS[PD|PS|SD|SS] instructions (AVX-512).
|
|
ASMJIT_ENUM(VFPClassPredicate) {
|
|
kVFPClassQNaN = 0x00U,
|
|
kVFPClassPZero = 0x01U,
|
|
kVFPClassNZero = 0x02U,
|
|
kVFPClassPInf = 0x03U,
|
|
kVFPClassNInf = 0x04U,
|
|
kVFPClassDenormal = 0x05U,
|
|
kVFPClassNegative = 0x06U,
|
|
kVFPClassSNaN = 0x07U
|
|
};
|
|
|
|
// ============================================================================
|
|
// [asmjit::x86defs::VFixupImmPredicate]
|
|
// ============================================================================
|
|
|
|
//! A predicate used by VFIXUPIMM[PD|PS|SD|SS] instructions (AVX-512).
|
|
ASMJIT_ENUM(VFixupImmPredicate) {
|
|
kVFixupImmZEOnZero = 0x01U,
|
|
kVFixupImmIEOnZero = 0x02U,
|
|
kVFixupImmZEOnOne = 0x04U,
|
|
kVFixupImmIEOnOne = 0x08U,
|
|
kVFixupImmIEOnSNaN = 0x10U,
|
|
kVFixupImmIEOnNInf = 0x20U,
|
|
kVFixupImmIEOnNegative= 0x40U,
|
|
kVFixupImmIEOnPInf = 0x80U
|
|
};
|
|
|
|
// ============================================================================
|
|
// [asmjit::x86defs::VGetMantPredicate]
|
|
// ============================================================================
|
|
|
|
//! A predicate used by VGETMANT[PD|PS|SD|SS] instructions (AVX-512).
|
|
ASMJIT_ENUM(VGetMantPredicate) {
|
|
kVGetMant1To2 = 0x00U,
|
|
kVGetMant1Div2To2 = 0x01U,
|
|
kVGetMant1Div2To1 = 0x02U,
|
|
kVGetMant3Div4To3Div2 = 0x03U,
|
|
kVGetMantNoSign = 0x04U,
|
|
kVGetMantQNaNIfSign = 0x08U
|
|
};
|
|
|
|
// ============================================================================
|
|
// [asmjit::x86defs::VRangePredicate]
|
|
// ============================================================================
|
|
|
|
//! A predicate used by VRANGE[PD|PS|SD|SS] instructions (AVX-512).
|
|
ASMJIT_ENUM(VRangePredicate) {
|
|
kVRangeSelectMin = 0x00U, //!< Select minimum value.
|
|
kVRangeSelectMax = 0x01U, //!< Select maximum value.
|
|
kVRangeSelectAbsMin = 0x02U, //!< Select minimum absolute value.
|
|
kVRangeSelectAbsMax = 0x03U, //!< Select maximum absolute value.
|
|
kVRangeSignSrc1 = 0x00U, //!< Select sign of SRC1.
|
|
kVRangeSignSrc2 = 0x04U, //!< Select sign of SRC2.
|
|
kVRangeSign0 = 0x08U, //!< Set sign to 0.
|
|
kVRangeSign1 = 0x0CU //!< Set sign to 1.
|
|
};
|
|
|
|
// ============================================================================
|
|
// [asmjit::x86defs::VReducePredicate]
|
|
// ============================================================================
|
|
|
|
//! A predicate used by VREDUCE[PD|PS|SD|SS] instructions (AVX-512).
|
|
ASMJIT_ENUM(VReducePredicate) {
|
|
kVReduceRoundCurrent = 0x00U, //!< Round to the current mode set.
|
|
kVReduceRoundEven = 0x04U, //!< Round to nearest even.
|
|
kVReduceRoundDown = 0x05U, //!< Round down.
|
|
kVReduceRoundUp = 0x06U, //!< Round up.
|
|
kVReduceRoundTrunc = 0x07U, //!< Truncate.
|
|
kVReduceSuppress = 0x08U //!< Suppress exceptions.
|
|
};
|
|
|
|
// ============================================================================
|
|
// [asmjit::x86defs::TLogPredicate]
|
|
// ============================================================================
|
|
|
|
//! A predicate that can be used to create an immediate for VTERNLOG[D|Q].
|
|
ASMJIT_ENUM(TLogPredicate) {
|
|
kTLog0 = 0x00U,
|
|
kTLog1 = 0xFFU,
|
|
kTLogA = 0xF0U,
|
|
kTLogB = 0xCCU,
|
|
kTLogC = 0xAAU,
|
|
kTLogNotA = kTLogA ^ 0xFFU,
|
|
kTLogNotB = kTLogB ^ 0xFFU,
|
|
kTLogNotC = kTLogC ^ 0xFFU,
|
|
|
|
kTLogAB = kTLogA & kTLogB,
|
|
kTLogAC = kTLogA & kTLogC,
|
|
kTLogBC = kTLogB & kTLogC,
|
|
kTLogNotAB = kTLogAB ^ 0xFFU,
|
|
kTLogNotAC = kTLogAC ^ 0xFFU,
|
|
kTLogNotBC = kTLogBC ^ 0xFFU,
|
|
|
|
kTLogABC = kTLogA & kTLogB & kTLogC,
|
|
kTLogNotABC = kTLogABC ^ 0xFFU
|
|
};
|
|
|
|
// ============================================================================
|
|
// [asmjit::x86defs::RoundPredicate]
|
|
// ============================================================================
|
|
|
|
//! A predicate used by ROUND[PD|PS|SD|SS] instructions.
|
|
ASMJIT_ENUM(RoundPredicate) {
|
|
kRoundNearest = 0x00U, //!< Round to nearest (even).
|
|
kRoundDown = 0x01U, //!< Round to down toward -INF (floor),
|
|
kRoundUp = 0x02U, //!< Round to up toward +INF (ceil).
|
|
kRoundTrunc = 0x03U, //!< Round toward zero (truncate).
|
|
kRoundCurrent = 0x04U, //!< Round to the current rounding mode set (ignores other RC bits).
|
|
kRoundInexact = 0x08U //!< Avoids inexact exception, if set.
|
|
};
|
|
|
|
} // x86defs namespace
|
|
|
|
// ============================================================================
|
|
// [asmjit::x86::]
|
|
// ============================================================================
|
|
|
|
//! X86 constants, registers, and utilities.
|
|
namespace x86 {
|
|
|
|
// Include all x86 specific namespaces here.
|
|
using namespace x86defs;
|
|
using namespace x86regs;
|
|
|
|
//! Pack a shuffle constant to be used by SSE/AVX/AVX-512 instructions (2 values).
|
|
//!
|
|
//! \param a Position of the first component [0, 1].
|
|
//! \param b Position of the second component [0, 1].
|
|
//!
|
|
//! Shuffle constants can be used to encode an immediate for these instructions:
|
|
//! - `shufpd`
|
|
static ASMJIT_INLINE int shufImm(uint32_t a, uint32_t b) noexcept {
|
|
ASMJIT_ASSERT(a <= 1 && b <= 1);
|
|
return static_cast<int>((a << 1) | b);
|
|
}
|
|
|
|
//! Pack a shuffle constant to be used by SSE/AVX/AVX-512 instructions (4 values).
|
|
//!
|
|
//! \param a Position of the first component [0, 3].
|
|
//! \param b Position of the second component [0, 3].
|
|
//! \param c Position of the third component [0, 3].
|
|
//! \param d Position of the fourth component [0, 3].
|
|
//!
|
|
//! Shuffle constants can be used to encode an immediate for these instructions:
|
|
//! - `pshufw()`
|
|
//! - `pshufd()`
|
|
//! - `pshuflw()`
|
|
//! - `pshufhw()`
|
|
//! - `shufps()`
|
|
static ASMJIT_INLINE int shufImm(uint32_t a, uint32_t b, uint32_t c, uint32_t d) noexcept {
|
|
ASMJIT_ASSERT(a <= 3 && b <= 3 && c <= 3 && d <= 3);
|
|
return static_cast<int>((a << 6) | (b << 4) | (c << 2) | d);
|
|
}
|
|
|
|
//! Create an immediate that can be used by VTERNLOG[D|Q] instructions.
|
|
static ASMJIT_INLINE int tlogImm(
|
|
uint32_t b000, uint32_t b001, uint32_t b010, uint32_t b011,
|
|
uint32_t b100, uint32_t b101, uint32_t b110, uint32_t b111) noexcept {
|
|
|
|
ASMJIT_ASSERT(b000 <= 1 && b001 <= 1 && b010 <= 1 && b011 <= 1 &&
|
|
b100 <= 1 && b101 <= 1 && b110 <= 1 && b111 <= 1);
|
|
return static_cast<int>((b000 << 0) | (b001 << 1) | (b010 << 2) | (b011 << 3) |
|
|
(b100 << 4) | (b101 << 5) | (b110 << 6) | (b111 << 7));
|
|
}
|
|
|
|
//! Create an immediate that can be used by VTERNLOG[D|Q] instructions.
|
|
static ASMJIT_INLINE int tlogVal(int x) noexcept { return x & 0xFF; }
|
|
//! Negate an immediate that can be used by VTERNLOG[D|Q] instructions.
|
|
static ASMJIT_INLINE int tlogNot(int x) noexcept { return x ^ 0xFF; }
|
|
//! Create an if/else logic that can be used by VTERNLOG[D|Q] instructions.
|
|
static ASMJIT_INLINE int tlogIf(int cond, int a, int b) noexcept { return (cond & a) | (tlogNot(cond) & b); }
|
|
|
|
} // x86 namespace
|
|
|
|
//! \}
|
|
|
|
} // asmjit namespace
|
|
|
|
// [Api-End]
|
|
#include "../asmjit_apiend.h"
|
|
|
|
// [Guard]
|
|
#endif // _ASMJIT_X86_X86GLOBALS_H
|