You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1703 lines
58 KiB

//Groups: @ingroup\s+(API_REF|KNOBS|IMG_BASIC_API|INS_BASIC_API|INS_INST_API|INS_BASIC_API_GEN_IA32|INS_BASIC_API_IA32|INS_MOD_API_GEN_IA32|SEC_BASIC_API|RTN_BASIC_API|REG_BASIC_API|REG_CPU_GENERIC|REG_CPU_IA32|TRACE_BASIC_API|BBL_BASIC_API|SYM_BASIC_API|MISC_PRINT|MISC_PARSE|KNOB_API|KNOB_BASIC|KNOB_PRINT|LOCK|PIN_CONTROL|TRACE_VERSION_API|BUFFER_API|PROTO_API|PIN_PROCESS_API|PIN_THREAD_API|PIN_SYSCALL_API|WINDOWS_SYSCALL_API_UNDOC|DEBUG_API|ERROR_FILE_BASIC|TYPE_BASE|INSTLIB|ALARM|CHILD_PROCESS_API|UTILS|MISC|CONTEXT_API|PHYSICAL_CONTEXT_API|PIN_CALLBACKS|EXCEPTION_API|APPDEBUG_API|STOPPED_THREAD_API|BUFFER_API|PROTO|INST_ARGS|DEPRECATED_PIN_API|INTERNAL_EXCEPTION_PRIVATE_UNDOCUMENTED|PIN_THREAD_PRIVATE|CHILD_PROCESS_INTERNAL|BBL_BASIC|ROGUE_BASIC_API|MESSAGE_TYPE|MESSAGE_BASIC|ERRFILE|MISC_BASIC|ITC_INST_API|CONTEXT_API_UNDOC|EXCEPTION_API_UNDOC|UNDOCUMENTED_PIN_API|OPIN|TRACE_VERSIONS
/* PIN API */
/* THIS FILE IS AUTOMAGICALLY GENERATED - DO NOT CHANGE DIRECTLY*/
typedef enum
{
REG_INVALID_ = 0,
/// @cond INTERNAL_DOXYGEN
REG_NONE = 1,
REG_FIRST = 2,
// base for all kinds of registers (application, machine, pin)
REG_RBASE,
// Machine registers are individual real registers on the machine
REG_MACHINE_BASE = REG_RBASE,
// Application registers are registers used in the application binary
// Application registers include all machine registers. In addition,
// they include some aggregrate registers that can be accessed by
// the application in a single instruction
// Essentially, application registers = individual machine registers + aggregrate registers
REG_APPLICATION_BASE = REG_RBASE,
/* !@ todo: should save scratch mmx and fp registers */
// The machine registers that form a context. These are the registers
// that need to be saved in a context switch.
REG_PHYSICAL_INTEGER_BASE = REG_RBASE,
REG_TO_SPILL_BASE = REG_RBASE,
/// @endcond
REG_GR_BASE = REG_RBASE,
# if defined(TARGET_IA32E)
// Context registers in the Intel(R) 64 architecture
REG_RDI = REG_GR_BASE, ///< rdi
REG_GDI = REG_RDI, ///< edi on a 32 bit machine, rdi on 64
REG_RSI, ///< rsi
REG_GSI = REG_RSI, ///< esi on a 32 bit machine, rsi on 64
REG_RBP, ///< rbp
REG_GBP = REG_RBP, ///< ebp on a 32 bit machine, rbp on 64
REG_RSP, ///< rsp
REG_STACK_PTR = REG_RSP,///< esp on a 32 bit machine, rsp on 64
REG_RBX, ///< rbx
REG_GBX = REG_RBX, ///< ebx on a 32 bit machine, rbx on 64
REG_RDX, ///< rdx
REG_GDX = REG_RDX, ///< edx on a 32 bit machine, rdx on 64
REG_RCX, ///< rcx
REG_GCX = REG_RCX, ///< ecx on a 32 bit machine, rcx on 64
REG_RAX, ///< rax
REG_GAX = REG_RAX, ///< eax on a 32 bit machine, rax on 64
REG_R8,
REG_R9,
REG_R10,
REG_R11,
REG_R12,
REG_R13,
REG_R14,
REG_R15,
REG_GR_LAST = REG_R15,
REG_SEG_BASE,
REG_SEG_CS = REG_SEG_BASE,
REG_SEG_SS,
REG_SEG_DS,
REG_SEG_ES,
REG_SEG_FS,
REG_SEG_GS,
REG_SEG_LAST = REG_SEG_GS,
REG_RFLAGS,
REG_GFLAGS=REG_RFLAGS,
REG_RIP,
REG_INST_PTR = REG_RIP,
# else // not defined(TARGET_IA32E)
// Context registers in the IA-32 architecture
REG_EDI = REG_GR_BASE,
REG_GDI = REG_EDI,
REG_ESI,
REG_GSI = REG_ESI,
REG_EBP,
REG_GBP = REG_EBP,
REG_ESP,
REG_STACK_PTR = REG_ESP,
REG_EBX,
REG_GBX = REG_EBX,
REG_EDX,
REG_GDX = REG_EDX,
REG_ECX,
REG_GCX = REG_ECX,
REG_EAX,
REG_GAX = REG_EAX,
REG_GR_LAST = REG_EAX,
REG_SEG_BASE,
REG_SEG_CS = REG_SEG_BASE,
REG_SEG_SS,
REG_SEG_DS,
REG_SEG_ES,
REG_SEG_FS,
REG_SEG_GS,
REG_SEG_LAST = REG_SEG_GS,
REG_EFLAGS,
REG_GFLAGS=REG_EFLAGS,
REG_EIP,
REG_INST_PTR = REG_EIP,
# endif // not defined(TARGET_IA32E)
/// @cond INTERNAL_DOXYGEN
REG_PHYSICAL_INTEGER_END = REG_INST_PTR,
/// @endcond
// partial registers common to both the IA-32 and Intel(R) 64 architectures.
REG_AL,
REG_AH,
REG_AX,
REG_CL,
REG_CH,
REG_CX,
REG_DL,
REG_DH,
REG_DX,
REG_BL,
REG_BH,
REG_BX,
REG_BP,
REG_SI,
REG_DI,
REG_SP,
REG_FLAGS,
REG_IP,
# if defined(TARGET_IA32E)
// partial registers in the Intel(R) 64 architecture
REG_EDI,
REG_DIL,
REG_ESI,
REG_SIL,
REG_EBP,
REG_BPL,
REG_ESP,
REG_SPL,
REG_EBX,
REG_EDX,
REG_ECX,
REG_EAX,
REG_EFLAGS,
REG_EIP,
REG_R8B,
REG_R8W,
REG_R8D,
REG_R9B,
REG_R9W,
REG_R9D,
REG_R10B,
REG_R10W,
REG_R10D,
REG_R11B,
REG_R11W,
REG_R11D,
REG_R12B,
REG_R12W,
REG_R12D,
REG_R13B,
REG_R13W,
REG_R13D,
REG_R14B,
REG_R14W,
REG_R14D,
REG_R15B,
REG_R15W,
REG_R15D,
# endif // not defined(TARGET_IA32E)
REG_MM_BASE,
REG_MM0 = REG_MM_BASE,
REG_MM1,
REG_MM2,
REG_MM3,
REG_MM4,
REG_MM5,
REG_MM6,
REG_MM7,
REG_MM_LAST = REG_MM7,
REG_XMM_BASE,
REG_FIRST_FP_REG = REG_XMM_BASE,
REG_XMM0 = REG_XMM_BASE,
REG_XMM1,
REG_XMM2,
REG_XMM3,
REG_XMM4,
REG_XMM5,
REG_XMM6,
REG_XMM7,
# if defined(TARGET_IA32E)
// additional xmm registers in the Intel(R) 64 architecture
REG_XMM8,
REG_XMM9,
REG_XMM10,
REG_XMM11,
REG_XMM12,
REG_XMM13,
REG_XMM14,
REG_XMM15,
REG_XMM_SSE_LAST = REG_XMM15,
REG_XMM_AVX_LAST = REG_XMM_SSE_LAST,
REG_XMM_AVX512_HI16_FIRST,
REG_XMM16 = REG_XMM_AVX512_HI16_FIRST,
REG_XMM17,
REG_XMM18,
REG_XMM19,
REG_XMM20,
REG_XMM21,
REG_XMM22,
REG_XMM23,
REG_XMM24,
REG_XMM25,
REG_XMM26,
REG_XMM27,
REG_XMM28,
REG_XMM29,
REG_XMM30,
REG_XMM31,
REG_XMM_AVX512_HI16_LAST = REG_XMM31,
REG_XMM_AVX512_LAST = REG_XMM_AVX512_HI16_LAST,
REG_XMM_LAST = REG_XMM_AVX512_LAST,
# else // not TARGET_IA32E
REG_XMM_SSE_LAST = REG_XMM7,
REG_XMM_AVX_LAST = REG_XMM_SSE_LAST,
REG_XMM_AVX512_LAST = REG_XMM_AVX_LAST,
REG_XMM_LAST = REG_XMM_AVX512_LAST,
# endif // not TARGET_IA32E
REG_YMM_BASE,
REG_YMM0 = REG_YMM_BASE,
REG_YMM1,
REG_YMM2,
REG_YMM3,
REG_YMM4,
REG_YMM5,
REG_YMM6,
REG_YMM7,
# if defined(TARGET_IA32E)
// additional ymm registers in the Intel(R) 64 architecture
REG_YMM8,
REG_YMM9,
REG_YMM10,
REG_YMM11,
REG_YMM12,
REG_YMM13,
REG_YMM14,
REG_YMM15,
REG_YMM_AVX_LAST = REG_YMM15,
REG_YMM_AVX512_HI16_FIRST,
REG_YMM16 = REG_YMM_AVX512_HI16_FIRST,
REG_YMM17,
REG_YMM18,
REG_YMM19,
REG_YMM20,
REG_YMM21,
REG_YMM22,
REG_YMM23,
REG_YMM24,
REG_YMM25,
REG_YMM26,
REG_YMM27,
REG_YMM28,
REG_YMM29,
REG_YMM30,
REG_YMM31,
REG_YMM_AVX512_HI16_LAST = REG_YMM31,
REG_YMM_AVX512_LAST = REG_YMM_AVX512_HI16_LAST,
REG_YMM_LAST = REG_YMM_AVX512_LAST,
# else // not TARGET_IA32E
REG_YMM_AVX_LAST = REG_YMM7,
REG_YMM_AVX512_LAST = REG_YMM_AVX_LAST,
REG_YMM_LAST = REG_YMM_AVX512_LAST,
# endif // not TARGET_IA32E
REG_ZMM_BASE,
REG_ZMM0 = REG_ZMM_BASE,
REG_ZMM1,
REG_ZMM2,
REG_ZMM3,
REG_ZMM4,
REG_ZMM5,
REG_ZMM6,
REG_ZMM7,
# if defined(TARGET_IA32E)
REG_ZMM8,
REG_ZMM9,
REG_ZMM10,
REG_ZMM11,
REG_ZMM12,
REG_ZMM13,
REG_ZMM14,
REG_ZMM15,
REG_ZMM_AVX512_SPLIT_LAST = REG_ZMM15,
REG_ZMM_AVX512_HI16_FIRST,
REG_ZMM16 = REG_ZMM_AVX512_HI16_FIRST,
REG_ZMM17,
REG_ZMM18,
REG_ZMM19,
REG_ZMM20,
REG_ZMM21,
REG_ZMM22,
REG_ZMM23,
REG_ZMM24,
REG_ZMM25,
REG_ZMM26,
REG_ZMM27,
REG_ZMM28,
REG_ZMM29,
REG_ZMM30,
REG_ZMM31,
REG_ZMM_AVX512_HI16_LAST = REG_ZMM31,
REG_ZMM_AVX512_LAST = REG_ZMM_AVX512_HI16_LAST,
REG_ZMM_LAST = REG_ZMM_AVX512_LAST,
# else // not defined(TARGET_IA32E)
REG_ZMM_AVX512_SPLIT_LAST = REG_ZMM7,
REG_ZMM_AVX512_LAST = REG_ZMM_AVX512_SPLIT_LAST,
REG_ZMM_LAST = REG_ZMM_AVX512_LAST,
# endif // not defined(TARGET_IA32E)
REG_K_BASE,
REG_K0 = REG_K_BASE,
// The K0 opmask register cannot be used as the write mask operand of an AVX512 instruction.
// However the encoding of K0 as the write mask operand is legal and is used as an implicit full mask.
REG_IMPLICIT_FULL_MASK = REG_K0,
REG_K1,
REG_K2,
REG_K3,
REG_K4,
REG_K5,
REG_K6,
REG_K7,
REG_K_LAST = REG_K7,
REG_MXCSR,
REG_MXCSRMASK,
// This corresponds to the "orig_eax" register that is visible
// to some debuggers.
# if defined(TARGET_IA32E)
REG_ORIG_RAX,
REG_ORIG_GAX = REG_ORIG_RAX,
# else // not defined(TARGET_IA32E)
REG_ORIG_EAX,
REG_ORIG_GAX = REG_ORIG_EAX,
# endif // not defined(TARGET_IA32E)
REG_FPST_BASE,
REG_FPSTATUS_BASE = REG_FPST_BASE,
REG_FPCW = REG_FPSTATUS_BASE,
REG_FPSW,
REG_FPTAG, ///< Abridged 8-bit version of x87 tag register.
REG_FPIP_OFF,
REG_FPIP_SEL,
REG_FPOPCODE,
REG_FPDP_OFF,
REG_FPDP_SEL,
REG_FPSTATUS_LAST = REG_FPDP_SEL,
REG_FPTAG_FULL, ///< Full 16-bit version of x87 tag register.
REG_ST_BASE,
REG_ST0 = REG_ST_BASE,
REG_ST1,
REG_ST2,
REG_ST3,
REG_ST4,
REG_ST5,
REG_ST6,
REG_ST7,
REG_ST_LAST = REG_ST7,
REG_FPST_LAST = REG_ST_LAST,
REG_DR_BASE,
REG_DR0 = REG_DR_BASE,
REG_DR1,
REG_DR2,
REG_DR3,
REG_DR4,
REG_DR5,
REG_DR6,
REG_DR7,
REG_DR_LAST = REG_DR7,
REG_CR_BASE,
REG_CR0 = REG_CR_BASE,
REG_CR1,
REG_CR2,
REG_CR3,
REG_CR4,
REG_CR_LAST = REG_CR4,
REG_TSSR,
REG_LDTR,
REG_TR_BASE,
REG_TR = REG_TR_BASE,
REG_TR3,
REG_TR4,
REG_TR5,
REG_TR6,
REG_TR7,
REG_TR_LAST = REG_TR7,
/// @cond INTERNAL_DOXYGEN
REG_MACHINE_LAST = REG_TR_LAST, /* last machine register */
/* these are the two registers implementing the eflags in pin
REG_STATUS_FLAGS represents the OF, SF, ZF, AF, PF and CF flags.
REG_DF_FLAG represents the DF flag.
flag splitting is done because the DF flag spilling and filling is rather expensive,
and the DF flag is not read/written by most instructions - therefore it is
not necessary to spill/fill it on most instructions that read/write the flags.
(prior to flag splitting, whenever any of the flags needed to be spilled/filled
both the DF and all the above status flags were spilled/filled).
NOTE - this flag splitting is not done if the pushf/popf sequence is being used
rather than the sahf/lahf sequence (some early Intel64 processors do not
support sahf/lahf instructions). Also the KnobRegFlagsSplit can be used
to disable the flags splitting when the sahf/lahf sequence is being used
Flags splitting is not done at the INS operand level - it is done when building
the vreglist for register allocation. So tools see the architectural flags registers
in INSs. See the functions MakeRegisterList and REG_InsertReadRegToVreglist to see
how the split flags are inserted into the vreglist.
See jit_flags_spillfill_ia32.cpp file comments to learn how they are spilled/filled
*/
REG_STATUS_FLAGS,
REG_DF_FLAG,
// NOTE: although REG_X87 is outside REG_APPLICATION_LAST scope it is part of app registers
// therefore any traversal of all application regs need to have special handling for REG_X87
REG_APPLICATION_LAST = REG_DF_FLAG, /* last register name used by the application */
/* Pin's virtual register names */
REG_TOOL_BASE,
/// @endcond
/**
* *** Segment registers (FS/GS) handling in Pin ***
*
* Background about segment virtualization support in Pin:
* Segment virtualization was introduced in Pin in the past in order to support Pin on OS's which didn't contain old
* (without segment usage) libc in a standard installation.
* Application and Pin were using 2 different TLS's, however access to them was done through segment registers
* (Also known as thread-self-pointer registers)
* (actually through their matching segment descriptor which contain the segment base address).
* Segment register (selector) can have one value at a time. Changing segment register value back and forth (from application
* to Pin and the other way around) is very costly performance wise (involve system calls).
* Also there may have been other limitations.
* Therefore it was decided to emulate application instructions which use segments registers.
* This is done by saving segment selector value and segment base address in the spill area (i.e REG_PIN_SEG_GS_VAL
* and REG_SEG_GS_BASE ) for each thread and performing all segment related instruction (of the application) using their
* values (by emulating instructions that set these registers and translate instructions that are accessing the memory using
* fs or gs prefix - we call this virtualizing segment).
* (This also help when passing effective address of memory operands to analysis routines)
* In Linux 32 bit the segment base address changes every time we write to a segment register (every time we load GS/FS,
* the hidden part is also loaded with the segment base address - it's kind of a cache for optimization, to save bus cycles)
* In order to support this beside emulating these in instructions we also tracked GDT/LDT tables (We store these tables
* inside Pin and update them every time needed).
*
* Today we have PinCRT which doesn't use segment registers, therefore we don't have to virtualize application segment usage
* and just let application execute these instructions in their original form (without modifying them or without emulating
* them).
*
* Linux
* In Linux we no longer virtualize application handling of segments: application instructions which uses segments or
* segments prefix now runs in their original form.
* In Linux 64 bits we now only track segment base address virtual register by emulating the system call which changes the
* segment base address (track application segment base address inside a virtual register in addition to updating the
* application one).
* In Linux 32 bits it's more complicated: It's hard to track the segment address without fully emulating all writes to
* segment registers + tracking the GDT/LDT which is a lot of work.
* Instead we're using GsBaseAddress()/FsBaseAddress() where needed including in PrecomputeSegBaseAddressIfNeeded() which
* is called from SetupArgumentEa() when needing to compute REG_SEG_FS_BASE/REG_SEG_GS_BASE value (holds the segment base
* address)
*
* macOS
* In macOS, PIN still use (at least) the system loader which uses the GS segment register, therefore segment virtualization
* is still used.
*
* Windows
* In Windows we compute segment base address at the beginning (assume it doens't change) and use its value when needed.
* REG_PIN_SEG_GS_VAL and REG_PIN_SEG_FS_VAL are unused in this platform
*
*/
// Virtual registers reg holding memory addresses pointed by GS/FS registers
// These registers are visible for tool writers
REG_SEG_GS_BASE = REG_TOOL_BASE, ///< Base address for GS segment
REG_SEG_FS_BASE, ///< Base address for FS segment
// ISA-independent Pin virtual regs needed for instrumentation
// These are pin registers visible to the pintool writers.
REG_INST_BASE,
REG_INST_SCRATCH_BASE = REG_INST_BASE, ///< First available scratch register
REG_INST_G0 = REG_INST_SCRATCH_BASE, ///< Scratch register used in pintools
REG_INST_G1, ///< Scratch register used in pintools
REG_INST_G2, ///< Scratch register used in pintools
REG_INST_G3, ///< Scratch register used in pintools
REG_INST_G4, ///< Scratch register used in pintools
REG_INST_G5, ///< Scratch register used in pintools
REG_INST_G6, ///< Scratch register used in pintools
REG_INST_G7, ///< Scratch register used in pintools
REG_INST_G8, ///< Scratch register used in pintools
REG_INST_G9, ///< Scratch register used in pintools
REG_INST_G10, ///< Scratch register used in pintools
REG_INST_G11, ///< Scratch register used in pintools
REG_INST_G12, ///< Scratch register used in pintools
REG_INST_G13, ///< Scratch register used in pintools
REG_INST_G14, ///< Scratch register used in pintools
REG_INST_G15, ///< Scratch register used in pintools
REG_INST_G16, ///< Scratch register used in pintools
REG_INST_G17, ///< Scratch register used in pintools
REG_INST_G18, ///< Scratch register used in pintools
REG_INST_G19, ///< Scratch register used in pintools
REG_INST_G20, ///< Scratch register used in pintools
REG_INST_G21, ///< Scratch register used in pintools
REG_INST_G22, ///< Scratch register used in pintools
REG_INST_G23, ///< Scratch register used in pintools
REG_INST_G24, ///< Scratch register used in pintools
REG_INST_G25, ///< Scratch register used in pintools
REG_INST_G26, ///< Scratch register used in pintools
REG_INST_G27, ///< Scratch register used in pintools
REG_INST_G28, ///< Scratch register used in pintools
REG_INST_G29, ///< Scratch register used in pintools
REG_INST_TOOL_FIRST = REG_INST_G0,
REG_INST_TOOL_LAST = REG_INST_G29,
REG_BUF_BASE0,
REG_BUF_BASE1,
REG_BUF_BASE2,
REG_BUF_BASE3,
REG_BUF_BASE4,
REG_BUF_BASE5,
REG_BUF_BASE6,
REG_BUF_BASE7,
REG_BUF_BASE8,
REG_BUF_BASE9,
REG_BUF_BASE_LAST = REG_BUF_BASE9,
REG_BUF_END0,
REG_BUF_END1,
REG_BUF_END2,
REG_BUF_END3,
REG_BUF_END4,
REG_BUF_END5,
REG_BUF_END6,
REG_BUF_END7,
REG_BUF_END8,
REG_BUF_END9,
REG_BUF_ENDLAST = REG_BUF_END9,
REG_BUF_LAST = REG_BUF_ENDLAST,
REG_INST_SCRATCH_LAST = REG_BUF_LAST,
# if defined(TARGET_IA32E)
// DWORD versions of the above G0-G29 scratch regs
REG_INST_G0D, ///< Scratch register used in pintools
REG_INST_G1D, ///< Scratch register used in pintools
REG_INST_G2D, ///< Scratch register used in pintools
REG_INST_G3D, ///< Scratch register used in pintools
REG_INST_G4D, ///< Scratch register used in pintools
REG_INST_G5D, ///< Scratch register used in pintools
REG_INST_G6D, ///< Scratch register used in pintools
REG_INST_G7D, ///< Scratch register used in pintools
REG_INST_G8D, ///< Scratch register used in pintools
REG_INST_G9D, ///< Scratch register used in pintools
REG_INST_G10D, ///< Scratch register used in pintools
REG_INST_G11D, ///< Scratch register used in pintools
REG_INST_G12D, ///< Scratch register used in pintools
REG_INST_G13D, ///< Scratch register used in pintools
REG_INST_G14D, ///< Scratch register used in pintools
REG_INST_G15D, ///< Scratch register used in pintools
REG_INST_G16D, ///< Scratch register used in pintools
REG_INST_G17D, ///< Scratch register used in pintools
REG_INST_G18D, ///< Scratch register used in pintools
REG_INST_G19D, ///< Scratch register used in pintools
REG_INST_G20D, ///< Scratch register used in pintools
REG_INST_G21D, ///< Scratch register used in pintools
REG_INST_G22D, ///< Scratch register used in pintools
REG_INST_G23D, ///< Scratch register used in pintools
REG_INST_G24D, ///< Scratch register used in pintools
REG_INST_G25D, ///< Scratch register used in pintools
REG_INST_G26D, ///< Scratch register used in pintools
REG_INST_G27D, ///< Scratch register used in pintools
REG_INST_G28D, ///< Scratch register used in pintools
REG_INST_G29D, ///< Scratch register used in pintools
REG_TOOL_LAST = REG_INST_G29D,
# else // end of defined(TARGET_IA32E)
REG_TOOL_LAST = REG_BUF_LAST,
# endif // end of !(defined(TARGET_IA32E))
/// @cond INTERNAL_DOXYGEN
REG_SPECIAL_BASE,
// REG_X87 is a representative of the X87 fp state - it is NOT available for explicit use in ANY
// of the Pin APIs.
// This register is set/get internally using xsave/xrstor or fxsave/fxrstor.
// In order to allow proper work of xsave/xrstor, the size of this register includes all the legacy xfeatures
// and the extended header. see @ref REG_X87_SIZE.
REG_X87 = REG_SPECIAL_BASE,
REG_SPECIAL_LAST = REG_X87,
REG_PIN_BASE,
REG_PIN_SEG_GS_VAL = REG_PIN_BASE, // virtual reg holding actual value of GS (also known as segment selector which is the
// visible part of the segment register). Only used when KnobVirtualSegments is on.
REG_PIN_SEG_FS_VAL, // virtual reg holding actual value of FS (also known as segment selector which is the
// visible part of the segment register). Only used when KnobVirtualSegments is on.
REG_LAST_CONTEXT_REG = REG_PIN_SEG_FS_VAL, // Last register in the canonical SPILL AREA Based CONTEXT
REG_PIN_GR_BASE,
// ia32-specific Pin gr regs
REG_PIN_EDI = REG_PIN_GR_BASE,
# if defined(TARGET_IA32)
REG_PIN_GDI = REG_PIN_EDI, // PIN_GDI == PIN_EDI on 32 bit, PIN_RDI on 64 bit.
# endif // defined(TARGET_IA32)
REG_PIN_ESI,
# if defined(TARGET_IA32)
REG_PIN_GSI = REG_PIN_ESI,
# endif // defined(TARGET_IA32)
REG_PIN_EBP,
# if defined(TARGET_IA32)
REG_PIN_GBP = REG_PIN_EBP,
# endif // defined(TARGET_IA32)
REG_PIN_ESP,
# if defined (TARGET_IA32)
REG_PIN_STACK_PTR = REG_PIN_ESP,
# endif // defined(TARGET_IA32)
REG_PIN_EBX,
# if defined(TARGET_IA32)
REG_PIN_GBX = REG_PIN_EBX,
# endif // defined(TARGET_IA32)
REG_PIN_EDX,
# if defined(TARGET_IA32)
REG_PIN_GDX = REG_PIN_EDX,
# endif // defined(TARGET_IA32)
REG_PIN_ECX,
# if defined(TARGET_IA32)
REG_PIN_GCX = REG_PIN_ECX, // PIN_GCX == PIN_ECX on 32 bit, PIN_RCX on 64 bit.
# endif // defined(TARGET_IA32)
REG_PIN_EAX,
# if defined(TARGET_IA32)
REG_PIN_GAX = REG_PIN_EAX, // PIN_GAX == PIN_EAX on 32 bit, PIN_RAX on 64 bit.
# endif // defined(TARGET_IA32)
REG_PIN_AL,
REG_PIN_AH,
REG_PIN_AX,
REG_PIN_CL,
REG_PIN_CH,
REG_PIN_CX,
REG_PIN_DL,
REG_PIN_DH,
REG_PIN_DX,
REG_PIN_BL,
REG_PIN_BH,
REG_PIN_BX,
REG_PIN_BP,
REG_PIN_SI,
REG_PIN_DI,
REG_PIN_SP,
# if defined(TARGET_IA32E)
// Intel(R) 64 architecture specific pin gr regs
REG_PIN_RDI,
REG_PIN_GDI = REG_PIN_RDI,
REG_PIN_RSI,
REG_PIN_GSI = REG_PIN_RSI,
REG_PIN_RBP,
REG_PIN_GBP = REG_PIN_RBP,
REG_PIN_RSP,
REG_PIN_STACK_PTR = REG_PIN_RSP,
REG_PIN_RBX,
REG_PIN_GBX = REG_PIN_RBX,
REG_PIN_RDX,
REG_PIN_GDX = REG_PIN_RDX,
REG_PIN_RCX,
REG_PIN_GCX = REG_PIN_RCX,
REG_PIN_RAX,
REG_PIN_GAX = REG_PIN_RAX,
REG_PIN_R8,
REG_PIN_R9,
REG_PIN_R10,
REG_PIN_R11,
REG_PIN_R12,
REG_PIN_R13,
REG_PIN_R14,
REG_PIN_R15,
REG_PIN_DIL,
REG_PIN_SIL,
REG_PIN_BPL,
REG_PIN_SPL,
REG_PIN_R8B,
REG_PIN_R8W,
REG_PIN_R8D,
REG_PIN_R9B,
REG_PIN_R9W,
REG_PIN_R9D,
REG_PIN_R10B,
REG_PIN_R10W,
REG_PIN_R10D,
REG_PIN_R11B,
REG_PIN_R11W,
REG_PIN_R11D,
REG_PIN_R12B,
REG_PIN_R12W,
REG_PIN_R12D,
REG_PIN_R13B,
REG_PIN_R13W,
REG_PIN_R13D,
REG_PIN_R14B,
REG_PIN_R14W,
REG_PIN_R14D,
REG_PIN_R15B,
REG_PIN_R15W,
REG_PIN_R15D,
# endif // defined(TARGET_IA32E)
// Every thread is assigned an index so we can implement tls
REG_PIN_THREAD_ID,
// ISA-independent gr regs
REG_PIN_INDIRREG, // virtual reg holding indirect jmp target value
REG_PIN_IPRELADDR, // virtual reg holding ip-rel address value
REG_PIN_SYSENTER_RESUMEADDR, // virtual reg holding the resume address from sysenter
REG_PIN_SYSCALL_NEXT_PC, // virtual reg holding the next PC when Pin emulates a system call
REG_PIN_VMENTER, // virtual reg holding the address of VmEnter
// actually it is the spill slot of this register that holds
// the address
// ISA-independent gr regs holding temporary values
REG_PIN_T_BASE,
#ifdef TARGET_IA32E
REG_PIN_T0 = REG_PIN_T_BASE,
REG_PIN_T1,
REG_PIN_T2,
REG_PIN_T3,
REG_PIN_T0D, // lower 32 bits of temporary register
REG_PIN_T1D,
REG_PIN_T2D,
REG_PIN_T3D,
#else // not TARGET_IA32E
REG_PIN_T0 = REG_PIN_T_BASE,
REG_PIN_T0D = REG_PIN_T0,
REG_PIN_T1,
REG_PIN_T1D = REG_PIN_T1,
REG_PIN_T2,
REG_PIN_T2D = REG_PIN_T2,
REG_PIN_T3,
REG_PIN_T3D = REG_PIN_T3,
#endif // not TARGET_IA32E
REG_PIN_T0W, // lower 16 bits of temporary register
REG_PIN_T1W,
REG_PIN_T2W,
REG_PIN_T3W,
REG_PIN_T0L, // lower 8 bits of temporary register
REG_PIN_T1L,
REG_PIN_T2L,
REG_PIN_T3L,
REG_PIN_T_LAST = REG_PIN_T3L,
REG_PIN_THREAD_IDD, // REG_PIN_THREAD_ID 32 half part
REG_TO_SPILL_LAST = REG_PIN_THREAD_IDD,
REG_PIN_INST_COND, // for conditional instrumentation.
// Used for memory rewriting, these are not live outside the region
// but cannot use general purpose scratch registers, because they're
// used during instrumentation generation, rather than region generation.
#ifdef TARGET_IA32E
REG_PIN_INST_T0,
REG_PIN_INST_T1,
REG_PIN_INST_T2,
REG_PIN_INST_T3,
REG_PIN_INST_T0D, // lower 32 bits of temporary register
REG_PIN_INST_T1D,
REG_PIN_INST_T2D,
REG_PIN_INST_T3D,
#else // not TARGET_IA32E
REG_PIN_INST_T0,
REG_PIN_INST_T0D = REG_PIN_INST_T0,
REG_PIN_INST_T1,
REG_PIN_INST_T1D = REG_PIN_INST_T1,
REG_PIN_INST_T2,
REG_PIN_INST_T2D = REG_PIN_INST_T2,
REG_PIN_INST_T3,
REG_PIN_INST_T3D = REG_PIN_INST_T3,
#endif // not TARGET_IA32E
REG_PIN_INST_T0W, // lower 16 bits of temporary register
REG_PIN_INST_T1W,
REG_PIN_INST_T2W,
REG_PIN_INST_T3W,
REG_PIN_INST_T0L, // lower 8 bits of temporary register
REG_PIN_INST_T1L,
REG_PIN_INST_T2L,
REG_PIN_INST_T3L,
// Used to preserve the predicate value around repped string ops
REG_PIN_INST_PRESERVED_PREDICATE,
// Used when the AC flag needs to be cleared before analysis routine
REG_PIN_FLAGS_BEFORE_AC_CLEARING,
// Virtual regs used by Pin inside instrumentation bridges.
// Unlike REG_INST_BASE to REG_INST_LAST, these registers are
// NOT visible to Pin clients.
REG_PIN_BRIDGE_ORIG_SP, // hold the stack ptr value before the bridge
REG_PIN_BRIDGE_APP_IP, // hold the application (not code cache) IP to resume
REG_PIN_BRIDGE_SP_BEFORE_ALIGN, // hold the stack ptr value before the stack alignment
REG_PIN_BRIDGE_SP_BEFORE_CALL, // hold the stack ptr value before call to replaced function in probe mode
REG_PIN_BRIDGE_SP_BEFORE_MARSHALLING_FRAME, // hold the stack ptr value before allocating the marshalling frame
REG_PIN_BRIDGE_MARSHALLING_FRAME, // hold the address of the marshalled reference registers
REG_PIN_BRIDGE_ON_STACK_CONTEXT_FRAME, // hold the address of the on stack context frame
REG_PIN_BRIDGE_ON_STACK_CONTEXT_SP, // hold the sp at which the on stack context was pushed
REG_PIN_BRIDGE_MULTI_MEMORYACCESS_FRAME, // hold the address of the on stack PIN_MULTI_MEM_ACCESS_INFO frame
REG_PIN_BRIDGE_MULTI_MEMORYACCESS_SP, // hold the sp at which the PIN_MULTI_MEM_ACCESS_INFO was pushed
// hold the address of the on stack MULTI_MEM_ACCESS_AND_REWRITE_EMULATION_INFO frame
REG_PIN_MULTI_MEM_ACCESS_AND_REWRITE_EMULATION_INFO_FRAME,
REG_PIN_BRIDGE_TRANS_MEMORY_CALLBACK_FRAME, // hold the address of the on stack PIN_MEM_TRANS_INFO frame
REG_PIN_BRIDGE_TRANS_MEMORY_CALLBACK_SP, // hold the sp at which the PIN_MEM_TRANS_INFO was pushed
REG_PIN_TRANS_MEMORY_CALLBACK_READ_ADDR, // hold the result of read memory address calculation
REG_PIN_TRANS_MEMORY_CALLBACK_READ2_ADDR, // hold the result of read2 memory address calculation
REG_PIN_TRANS_MEMORY_CALLBACK_WRITE_ADDR, // hold the result of write memory address calculation
REG_PIN_BRIDGE_SPILL_AREA_CONTEXT_FRAME, // hold the address of the spill area context frame
REG_PIN_BRIDGE_SPILL_AREA_CONTEXT_SP, // hold the sp at which the spill area context was pushed
REG_PIN_AVX_IN_USE, // holds the value of EDX resulting from an XGETBV instruction,
// if both the CPU and the OS support AVX state and AVX is in use, 0 otherwise.
// XGETBV with ECX=1 returns the logical AND of XCR0
// and the current value of the XINUSE state-component bitmap
REG_PIN_SPILLPTR, // ptr to the pin spill area
REG_PIN_GR_LAST = REG_PIN_SPILLPTR,
REG_PIN_X87,
REG_PIN_MXCSR,
// REG_PIN_FLAGS is x86-specific, but since it is not a gr, we put it out of
// REG_PIN_GR_BASE and REG_PIN_GR_LAST
/* these are the two registers implementing the PIN flags in pin
REG_PIN_STATUS_FLAGS represents the OF, SF, ZF, AF, PF and CF flags.
REG_PIN_DF_FLAG represents the DF flag.
*/
REG_PIN_STATUS_FLAGS,
REG_PIN_DF_FLAG,
/* REG_PIN_FLAGS is used only in the case when the pushf/popf sequence is used
for flags spill/fill rather than the sahf/lahf sequence.
*/
REG_PIN_FLAGS,
REG_PIN_XMM_BASE,
REG_PIN_XMM0 = REG_PIN_XMM_BASE,
REG_PIN_XMM1,
REG_PIN_XMM2,
REG_PIN_XMM3,
REG_PIN_XMM4,
REG_PIN_XMM5,
REG_PIN_XMM6,
REG_PIN_XMM7,
# if defined(TARGET_IA32E)
// additional xmm registers in the Intel(R) 64 architecture
REG_PIN_XMM8,
REG_PIN_XMM9,
REG_PIN_XMM10,
REG_PIN_XMM11,
REG_PIN_XMM12,
REG_PIN_XMM13,
REG_PIN_XMM14,
REG_PIN_XMM15,
REG_PIN_XMM_SSE_LAST = REG_PIN_XMM15,
REG_PIN_XMM_AVX_LAST = REG_PIN_XMM_SSE_LAST,
REG_PIN_XMM_AVX512_HI16_FIRST,
REG_PIN_XMM16 = REG_PIN_XMM_AVX512_HI16_FIRST,
REG_PIN_XMM17,
REG_PIN_XMM18,
REG_PIN_XMM19,
REG_PIN_XMM20,
REG_PIN_XMM21,
REG_PIN_XMM22,
REG_PIN_XMM23,
REG_PIN_XMM24,
REG_PIN_XMM25,
REG_PIN_XMM26,
REG_PIN_XMM27,
REG_PIN_XMM28,
REG_PIN_XMM29,
REG_PIN_XMM30,
REG_PIN_XMM31,
REG_PIN_XMM_AVX512_HI16_LAST = REG_PIN_XMM31,
REG_PIN_XMM_AVX512_LAST = REG_PIN_XMM_AVX512_HI16_LAST,
REG_PIN_XMM_LAST = REG_PIN_XMM_AVX512_LAST,
# else // not TARGET_IA32E
REG_PIN_XMM_SSE_LAST = REG_PIN_XMM7,
REG_PIN_XMM_AVX_LAST = REG_PIN_XMM_SSE_LAST,
REG_PIN_XMM_AVX512_LAST = REG_PIN_XMM_AVX_LAST,
REG_PIN_XMM_LAST = REG_PIN_XMM_AVX512_LAST,
# endif // TARGET_IA32E
REG_PIN_YMM_BASE,
REG_PIN_YMM0 = REG_PIN_YMM_BASE,
REG_PIN_YMM1,
REG_PIN_YMM2,
REG_PIN_YMM3,
REG_PIN_YMM4,
REG_PIN_YMM5,
REG_PIN_YMM6,
REG_PIN_YMM7,
# if defined(TARGET_IA32E)
// additional ymm registers in the Intel(R) 64 architecture
REG_PIN_YMM8,
REG_PIN_YMM9,
REG_PIN_YMM10,
REG_PIN_YMM11,
REG_PIN_YMM12,
REG_PIN_YMM13,
REG_PIN_YMM14,
REG_PIN_YMM15,
REG_PIN_YMM_AVX_LAST = REG_PIN_YMM15,
REG_PIN_YMM_AVX512_HI16_FIRST,
REG_PIN_YMM16 = REG_PIN_YMM_AVX512_HI16_FIRST,
REG_PIN_YMM17,
REG_PIN_YMM18,
REG_PIN_YMM19,
REG_PIN_YMM20,
REG_PIN_YMM21,
REG_PIN_YMM22,
REG_PIN_YMM23,
REG_PIN_YMM24,
REG_PIN_YMM25,
REG_PIN_YMM26,
REG_PIN_YMM27,
REG_PIN_YMM28,
REG_PIN_YMM29,
REG_PIN_YMM30,
REG_PIN_YMM31,
REG_PIN_YMM_AVX512_HI16_LAST = REG_PIN_YMM31,
REG_PIN_YMM_AVX512_LAST = REG_PIN_YMM_AVX512_HI16_LAST,
REG_PIN_YMM_LAST = REG_PIN_YMM_AVX512_LAST,
# else // not TARGET_IA32E
REG_PIN_YMM_AVX_LAST = REG_PIN_YMM7,
REG_PIN_YMM_AVX512_LAST = REG_PIN_YMM_AVX_LAST,
REG_PIN_YMM_LAST = REG_PIN_YMM_AVX512_LAST,
# endif // not TARGET_IA32E
REG_PIN_ZMM_BASE,
REG_PIN_ZMM0 = REG_PIN_ZMM_BASE,
REG_PIN_ZMM1,
REG_PIN_ZMM2,
REG_PIN_ZMM3,
REG_PIN_ZMM4,
REG_PIN_ZMM5,
REG_PIN_ZMM6,
REG_PIN_ZMM7,
# ifndef TARGET_IA32
REG_PIN_ZMM8,
REG_PIN_ZMM9,
REG_PIN_ZMM10,
REG_PIN_ZMM11,
REG_PIN_ZMM12,
REG_PIN_ZMM13,
REG_PIN_ZMM14,
REG_PIN_ZMM15,
REG_PIN_ZMM_AVX512_SPLIT_LAST = REG_PIN_ZMM15,
REG_PIN_ZMM_AVX512_HI16_FIRST,
REG_PIN_ZMM16 = REG_PIN_ZMM_AVX512_HI16_FIRST,
REG_PIN_ZMM17,
REG_PIN_ZMM18,
REG_PIN_ZMM19,
REG_PIN_ZMM20,
REG_PIN_ZMM21,
REG_PIN_ZMM22,
REG_PIN_ZMM23,
REG_PIN_ZMM24,
REG_PIN_ZMM25,
REG_PIN_ZMM26,
REG_PIN_ZMM27,
REG_PIN_ZMM28,
REG_PIN_ZMM29,
REG_PIN_ZMM30,
REG_PIN_ZMM31,
REG_PIN_ZMM_AVX512_HI16_LAST = REG_PIN_ZMM31,
REG_PIN_ZMM_AVX512_LAST = REG_PIN_ZMM_AVX512_HI16_LAST,
REG_PIN_ZMM_LAST = REG_PIN_ZMM_AVX512_LAST,
# else // TARGET_IA32
REG_PIN_ZMM_AVX512_SPLIT_LAST = REG_PIN_ZMM7,
REG_PIN_ZMM_AVX512_LAST = REG_PIN_ZMM_AVX512_SPLIT_LAST,
REG_PIN_ZMM_LAST = REG_PIN_ZMM_AVX512_LAST,
# endif // TARGET_IA32
REG_PIN_K_BASE,
REG_PIN_K0 = REG_PIN_K_BASE,
REG_PIN_K1,
REG_PIN_K2,
REG_PIN_K3,
REG_PIN_K4,
REG_PIN_K5,
REG_PIN_K6,
REG_PIN_K7,
REG_PIN_K_LAST = REG_PIN_K7,
REG_PIN_LAST = REG_PIN_K_LAST,
/// @endcond
REG_LAST
} REG;
/* DO NOT EDIT */
typedef enum {
REG_ACCESS_READ,
REG_ACCESS_WRITE, // this implies partial write so previous value is needed
REG_ACCESS_OVERWRITE // this implies full overwrite so previous value is not needed
} REG_ACCESS;
/* DO NOT EDIT */
const ADDRINT NUM_PHYSICAL_REGS = REG_PHYSICAL_INTEGER_END - REG_PHYSICAL_INTEGER_BASE + 1;
/* DO NOT EDIT */
const ADDRINT NUM_SCRATCH_REGS = REG_INST_SCRATCH_LAST - REG_INST_SCRATCH_BASE + 1;
/* DO NOT EDIT */
const ADDRINT NUM_SPECIAL_REGS = 2 + NUM_SCRATCH_REGS;
/* DO NOT EDIT */
const ADDRINT NUM_CONTEXT_INT_REGS = NUM_PHYSICAL_REGS + NUM_SPECIAL_REGS;
/* DO NOT EDIT */
const ADDRINT NUM_CONTEXT_REGS = REG_LAST_CONTEXT_REG + 1;
/* DO NOT EDIT */
const ADDRINT ARCH_STATE_SIZE = (NUM_PHYSICAL_REGS + NUM_SPECIAL_REGS)*sizeof(ADDRINT) +
(FPSTATE_SIZE // because CONTEXT size must
// be at least as big as
// CONTEXT_CANONICAL size,
// and CONTEXT_CANONICAL._fpstate is used
+ FPSTATE_ALIGNMENT);
/* DO NOT EDIT */
struct REGDEF_ENTRY {
REG reg; // The REG enum of this register, used only to verify that this _regDefTable
// entry is indeed for the REG whose enum is equal to the index of this entry.
UINT32 regSpillSize; // The size of this register's spill slot in the spill area
REGWIDTH regWidth; // The width of this register
UINT64 regClassBitMap; // The REG_CLASS of this register as a bitmap
UINT64 regSubClassBitMap; // The REG_SUBCLASS of this register as a bitmap
REG_ALLOC_TYPE regAllocType; // Specified the type of physical register that must be allocated to this reg
REG regFullName; // The REG enum of the full register this register is part of
REG regMachineName; // The REG that this register must be allocated into when the register mapping is
// identity
REG regPinName; // sort of the inverse of regMachineName - for app regs, the corresponding Pin reg
};
/* DO NOT EDIT */
extern const REGDEF_ENTRY _regDefTable[] ;
/* DO NOT EDIT */
extern UINT64 _regClassBitMapTable[REG_LAST];
/* DO NOT EDIT */
extern UINT64 _regSubClassBitMapTable[REG_LAST];
/* DO NOT EDIT */
extern UINT32 _regSpillSizeTable[REG_LAST];
/* DO NOT EDIT */
extern REGWIDTH _regWidthTable[REG_LAST];
/* DO NOT EDIT */
extern REG_ALLOC_TYPE _regAllocTypeTable[REG_LAST];
/* DO NOT EDIT */
extern REG _regFullNameTable[REG_LAST];
/* DO NOT EDIT */
extern REG _regMachineNameTable[REG_LAST];
/* DO NOT EDIT */
extern REG _regPinNameTable[REG_LAST];
/* DO NOT EDIT */
extern INT32 _regWidthToBitWidth[];
/* DO NOT EDIT */
inline VOID InitRegTables()
{
for (UINT32 i=0; i<(int)REG_LAST; i++)
{
ASSERTXSLOW((REG)(i)==_regDefTable[i].reg);
_regClassBitMapTable[i] = _regDefTable[i].regClassBitMap;
_regSubClassBitMapTable[i] = _regDefTable[i].regSubClassBitMap;
_regSpillSizeTable[i] = _regDefTable[i].regSpillSize;
_regWidthTable[i] = _regDefTable[i].regWidth;
_regAllocTypeTable[i] = _regDefTable[i].regAllocType;
_regFullNameTable[i] = _regDefTable[i].regFullName;
_regMachineNameTable[i] = _regDefTable[i].regMachineName;
_regPinNameTable[i] = _regDefTable[i].regPinName;
}
}
/* DO NOT EDIT */
inline BOOL REG_is_reg(REG reg){ return (reg >= REG_RBASE) && (reg < REG_LAST);}
/* DO NOT EDIT */
inline BOOL REG_is_pseudo(REG reg){ return (reg == REG_ORIG_GAX);}
/* DO NOT EDIT */
inline BOOL REG_is_gr(REG reg)
{
return ((_regClassBitMapTable[reg]) == (_REGCBIT(REG_CLASS_GR)));
}
/* DO NOT EDIT */
inline BOOL REG_is_fr(REG reg)
{
const REG_CLASS_BITS frClassMask =
(_REGCBIT(REG_CLASS_XMM)) |
(_REGCBIT(REG_CLASS_YMM)) |
(_REGCBIT(REG_CLASS_ZMM)) |
(_REGCBIT(REG_CLASS_K)) |
(_REGCBIT(REG_CLASS_FPST)) |
(_REGCBIT(REG_CLASS_ST)) |
(_REGCBIT(REG_CLASS_MXCSR)) |
(_REGCBIT(REG_CLASS_MXCSRMASK));
return (((_regClassBitMapTable[reg]) & frClassMask) != 0);
}
/* DO NOT EDIT */
inline BOOL REG_is_br(REG reg) { return FALSE; }
/* DO NOT EDIT */
inline BOOL REG_is_gr64(REG reg)
{
#if defined(TARGET_IA32E)
// all gr on Intel(R) 64 architectures are 64-bits
return REG_is_gr(reg);
#else
// no 64-bit gr on x86
return FALSE;
#endif
}
/* DO NOT EDIT */
inline BOOL REG_is_gr32(REG reg)
{
#if defined(TARGET_IA32E)
return (_regClassBitMapTable[reg] == _REGCBIT(REG_CLASS_GRH32));
#else
return (_regClassBitMapTable[reg] == _REGCBIT(REG_CLASS_GR));
#endif
}
/* DO NOT EDIT */
inline BOOL REG_is_pin_gr32(REG reg)
{
#if defined(TARGET_IA32E)
return (_regClassBitMapTable[reg] == _REGCBIT(REG_CLASS_PIN_GRH32));
#else
return (_regClassBitMapTable[reg] == _REGCBIT(REG_CLASS_PIN_GR));
#endif
}
/* DO NOT EDIT */
inline BOOL REG_is_gr16(REG reg)
{
return (_regClassBitMapTable[reg] == _REGCBIT(REG_CLASS_GRH16));
}
/* DO NOT EDIT */
inline BOOL REG_is_gr8(REG reg)
{
const REG_CLASS_BITS gr8classMask = (_REGCBIT(REG_CLASS_GRU8)) | (_REGCBIT(REG_CLASS_GRL8));
return ((_regClassBitMapTable[reg] & gr8classMask) != 0);
}
/* DO NOT EDIT */
inline BOOL REG_is_seg(REG reg)
{
return (_regClassBitMapTable[reg] == (_REGCBIT(REG_CLASS_SEG)));
}
/* DO NOT EDIT */
inline BOOL REG_is_fr_for_get_context(REG reg)
{
const REG_CLASS_BITS frClassMask =
(_REGCBIT(REG_CLASS_FPST) ) |
(_REGCBIT(REG_CLASS_MXCSR)) |
(_REGCBIT(REG_CLASS_MXCSRMASK));
return ((_regClassBitMapTable[reg] & frClassMask) != 0);
}
/* DO NOT EDIT */
inline BOOL REG_is_mxcsr(REG reg) { return (REG_MXCSR == reg); }
/* DO NOT EDIT */
inline BOOL REG_is_any_mxcsr(REG reg) { return (REG_MXCSR == reg || REG_PIN_MXCSR == reg); }
/* DO NOT EDIT */
inline BOOL REG_is_mm(REG reg)
{
return (_regClassBitMapTable[reg] == (_REGCBIT(REG_CLASS_MM)));
}
/* DO NOT EDIT */
inline BOOL REG_is_xmm(REG reg)
{
return (_regClassBitMapTable[reg] == (_REGCBIT(REG_CLASS_XMM)));
}
/* DO NOT EDIT */
inline BOOL REG_is_ymm(REG reg)
{
return (_regClassBitMapTable[reg] == (_REGCBIT(REG_CLASS_YMM)));
}
/* DO NOT EDIT */
inline BOOL REG_is_zmm(REG reg)
{
return (_regClassBitMapTable[reg] == (_REGCBIT(REG_CLASS_ZMM)));
}
/* DO NOT EDIT */
inline BOOL REG_is_xmm_ymm_zmm(REG reg)
{
const REG_CLASS_BITS xmm_ymm_zmmClassMask = (_REGCBIT(REG_CLASS_XMM)) | (_REGCBIT(REG_CLASS_YMM)) | (_REGCBIT(REG_CLASS_ZMM));
return ((_regClassBitMapTable[reg] & xmm_ymm_zmmClassMask) != 0);
}
/* DO NOT EDIT */
inline BOOL REG_is_any_vector_reg(REG reg)
{
const REG_CLASS_BITS vectorClassMask =
_REGCBIT(REG_CLASS_XMM) | _REGCBIT(REG_CLASS_YMM) | _REGCBIT(REG_CLASS_ZMM) |
_REGCBIT(REG_CLASS_PIN_XMM) | _REGCBIT(REG_CLASS_PIN_YMM) | _REGCBIT(REG_CLASS_PIN_ZMM);
return ((_regClassBitMapTable[reg] & vectorClassMask) != 0);
}
/* DO NOT EDIT */
inline BOOL REG_is_k_mask(REG reg)
{
return (_regClassBitMapTable[reg] == (_REGCBIT(REG_CLASS_K)));
}
/* DO NOT EDIT */
inline BOOL REG_is_any_mask(REG reg)
{
return ((_regClassBitMapTable[reg] & (_REGCBIT(REG_CLASS_K) | _REGCBIT(REG_CLASS_PIN_K))) != 0);
}
/* DO NOT EDIT */
inline REG REG_corresponding_ymm_reg(REG reg) { return static_cast<REG>(reg-REG_XMM_BASE+REG_YMM_BASE); }
/* DO NOT EDIT */
inline REG REG_corresponding_zmm_reg(REG reg) { return static_cast<REG>(reg-REG_XMM_BASE+REG_ZMM_BASE); }
/* DO NOT EDIT */
inline BOOL REG_is_st(REG reg)
{
return (_regClassBitMapTable[reg] == (_REGCBIT(REG_CLASS_ST)));
}
/* DO NOT EDIT */
inline BOOL REG_is_machine(REG reg)
{
return ((reg >= REG_MACHINE_BASE) && (reg <= REG_MACHINE_LAST));
}
/* DO NOT EDIT */
inline BOOL REG_is_application(REG reg)
{
return ((_regClassBitMapTable[reg] & REGCBIT_APP_ALL) != 0);
}
/* DO NOT EDIT */
inline BOOL REG_is_pin(REG reg)
{
return ((_regClassBitMapTable[reg] & REGCBIT_PIN_ALL) != 0);
}
/* DO NOT EDIT */
inline BOOL REG_is_subclass_none(REG reg)
{
return ((_regSubClassBitMapTable[reg] & (REG_SUBCLASS_BITS(1) << (REG_SUBCLASS_NONE))) != 0);
}
/* DO NOT EDIT */
inline BOOL REG_is_pin_gpr(REG reg)
{
return REG_is_pin(reg) && REG_is_subclass_none(reg);
}
/* DO NOT EDIT */
inline BOOL REG_is_seg_base(REG reg)
{
return (reg == REG_SEG_GS_BASE)||(reg == REG_SEG_FS_BASE);
}
/* DO NOT EDIT */
inline BOOL REG_is_gs_or_fs(REG reg)
{
return (reg == REG_SEG_GS || reg == REG_SEG_FS);
}
/* DO NOT EDIT */
inline BOOL REG_valid_for_iarg_reg_value(REG reg)
{
const REG_CLASS_BITS allowedClassMask = ((_REGCBIT(REG_CLASS_GR)) | (_REGCBIT(REG_CLASS_PIN_GR)) | (_REGCBIT(REG_CLASS_SEG))
| REGCBIT_PARTIAL | REGCBIT_APP_FLAGS | REGCBIT_PIN_FLAGS);
const REG_CLASS_BITS disallowedPartialRegs = ((_REGCBIT(REG_CLASS_FLAGS16)) | (_REGCBIT(REG_CLASS_FLAGS32))
| (_REGCBIT(REG_CLASS_IP16)) | (_REGCBIT(REG_CLASS_IP32))
| (_REGCBIT(REG_CLASS_DFLAG)) | (_REGCBIT(REG_CLASS_STATUS_FLAGS)));
// Allow base GS, and base FS - there is explicit code that handles these registers
if (REG_is_seg_base(reg))
return TRUE;
// Disallow registers that are not legal
if (reg < REG_FIRST || reg > REG_LAST)
return FALSE;
// Disallow some registers that are smaller to fit into ADDRINT and don't have
// special implementation that allow PIN to get their value
if ((_regClassBitMapTable[reg] & disallowedPartialRegs) != 0)
return FALSE;
// We don't allow PIN internal register which correspond to an architectural register
// e.g. REG_PIN_EBX
if (REG_is_pin_gpr(reg))
return FALSE;
// If we passed all of the filters above, allow only those registers that are in the
// appropriate classes
return ((_regClassBitMapTable[reg] & allowedClassMask) != 0);
}
/* DO NOT EDIT */
inline BOOL REG_is_pin_gr(REG reg)
{
return (_regClassBitMapTable[reg] == (_REGCBIT(REG_CLASS_PIN_GR)));
}
/* DO NOT EDIT */
inline BOOL REG_is_pin_gr_half32(REG reg)
{
return (_regClassBitMapTable[reg] == (_REGCBIT(REG_CLASS_PIN_GRH32)));
}
/* DO NOT EDIT */
inline BOOL REG_is_pin_xmm(REG reg)
{
return (_regClassBitMapTable[reg] == (_REGCBIT(REG_CLASS_PIN_XMM)));
}
/* DO NOT EDIT */
inline BOOL REG_is_pin_ymm(REG reg)
{
return (_regClassBitMapTable[reg] == (_REGCBIT(REG_CLASS_PIN_YMM)));
}
/* DO NOT EDIT */
inline BOOL REG_is_pin_zmm(REG reg)
{
return (_regClassBitMapTable[reg] == (_REGCBIT(REG_CLASS_PIN_ZMM)));
}
/* DO NOT EDIT */
inline BOOL REG_is_pin_xmm_ymm_zmm(REG reg)
{
const REG_CLASS_BITS pin_xmm_ymm_zmmClassMask =
(_REGCBIT(REG_CLASS_PIN_XMM)) | (_REGCBIT(REG_CLASS_PIN_YMM)) | (_REGCBIT(REG_CLASS_PIN_ZMM));
return ((_regClassBitMapTable[reg] & pin_xmm_ymm_zmmClassMask) != 0);
}
/* DO NOT EDIT */
inline BOOL REG_is_pin_k_mask(REG reg)
{
return (_regClassBitMapTable[reg] == (_REGCBIT(REG_CLASS_PIN_K)));
}
/* DO NOT EDIT */
inline BOOL REG_is_avx512_hi16_xmm(const REG xmm)
{
#ifdef TARGET_IA32
return FALSE;
#else // not TARGET_IA32
if (REG_is_xmm(xmm))
{
return (xmm <= REG_XMM_AVX512_HI16_LAST && xmm >= REG_XMM_AVX512_HI16_FIRST);
}
else if (REG_is_pin_xmm(xmm))
{
return (xmm <= REG_PIN_XMM_AVX512_HI16_LAST && xmm >= REG_PIN_XMM_AVX512_HI16_FIRST);
}
else
{
return FALSE;
}
#endif // not TARGET_IA32
}
/* DO NOT EDIT */
inline BOOL REG_is_avx512_hi16_ymm(const REG ymm)
{
#ifdef TARGET_IA32
return FALSE;
#else // not TARGET_IA32
if (REG_is_ymm(ymm))
{
return (ymm <= REG_YMM_AVX512_HI16_LAST && ymm >= REG_YMM_AVX512_HI16_FIRST);
}
else if (REG_is_pin_ymm(ymm))
{
return (ymm <= REG_PIN_YMM_AVX512_HI16_LAST && ymm >= REG_PIN_YMM_AVX512_HI16_FIRST);
}
else
{
return FALSE;
}
#endif // not TARGET_IA32
}
/* DO NOT EDIT */
inline BOOL REG_is_gr_type(REG reg)
{
const REG_CLASS_BITS grclassMask = (_REGCBIT(REG_CLASS_GR)) | (_REGCBIT(REG_CLASS_PIN_GR));
return ((_regClassBitMapTable[reg] & grclassMask) != 0);
}
/* DO NOT EDIT */
inline REG REG_AppFlags() {return REG_GFLAGS;}
/* DO NOT EDIT */
inline BOOL REG_is_flags(REG reg) {return reg == REG_GFLAGS;}
/* DO NOT EDIT */
inline BOOL REG_is_pin_flags(REG reg) {return reg == REG_PIN_FLAGS;}
/* DO NOT EDIT */
inline BOOL REG_is_status_flags(REG reg) {return reg == REG_STATUS_FLAGS;}
/* DO NOT EDIT */
inline BOOL REG_is_pin_status_flags(REG reg) {return reg == REG_PIN_STATUS_FLAGS;}
/* DO NOT EDIT */
inline BOOL REG_is_df_flag(REG reg) {return reg == REG_DF_FLAG;}
/* DO NOT EDIT */
inline BOOL REG_is_pin_df_flag(REG reg) {return reg == REG_PIN_DF_FLAG;}
/* DO NOT EDIT */
inline BOOL REG_is_flags_type(REG reg)
{
const REG_CLASS_BITS flagsClassMask = ((_REGCBIT(REG_CLASS_FLAGS)) | (_REGCBIT(REG_CLASS_PIN_FLAGS)));
return ((_regClassBitMapTable[reg] & flagsClassMask) != 0);
}
/* DO NOT EDIT */
inline BOOL REG_is_flags_any_size_type(REG reg)
{
const REG_CLASS_BITS flagsClassMask
= ((_REGCBIT(REG_CLASS_FLAGS)) | (_REGCBIT(REG_CLASS_PIN_FLAGS))
| (_REGCBIT(REG_CLASS_FLAGS32)) | (_REGCBIT(REG_CLASS_FLAGS16)));
return ((_regClassBitMapTable[reg] & flagsClassMask) != 0);
}
/* DO NOT EDIT */
inline BOOL REG_is_status_flags_type(REG reg)
{
const REG_CLASS_BITS flagsStatusClassMask = ((_REGCBIT(REG_CLASS_STATUS_FLAGS)) | (_REGCBIT(REG_CLASS_PIN_STATUS_FLAGS)));
return ((_regClassBitMapTable[reg] & flagsStatusClassMask) != 0);
}
/* DO NOT EDIT */
inline BOOL REG_is_app_status_flags_type(REG reg)
{
return ((_regClassBitMapTable[reg] & _REGCBIT(REG_CLASS_STATUS_FLAGS)) != 0);
}
/* DO NOT EDIT */
inline BOOL REG_is_df_flag_type(REG reg)
{
const REG_CLASS_BITS dfClassMask = ((_REGCBIT(REG_CLASS_DFLAG)) | (_REGCBIT(REG_CLASS_PIN_DFLAG)));
return ((_regClassBitMapTable[reg] & dfClassMask) != 0);
}
/* DO NOT EDIT */
inline BOOL REG_is_app_df_flag_type(REG reg)
{
return ((_regClassBitMapTable[reg] & _REGCBIT(REG_CLASS_DFLAG)) != 0);
}
/* DO NOT EDIT */
inline BOOL REG_is_any_flags_type(REG reg)
{
return ((_regClassBitMapTable[reg] & (REGCBIT_APP_FLAGS | REGCBIT_PIN_FLAGS)) != 0);
}
/* DO NOT EDIT */
inline BOOL REG_is_any_pin_flags(REG reg)
{
return ((_regClassBitMapTable[reg] & REGCBIT_PIN_FLAGS) != 0);
}
/* DO NOT EDIT */
inline BOOL REG_is_any_app_flags(REG reg)
{
return ((_regClassBitMapTable[reg] & REGCBIT_APP_FLAGS) != 0);
}
/* DO NOT EDIT */
inline REG REG_get_status_flags_reg_of_type(REG reg)
{
if (REG_is_flags(reg))
{
return (REG_STATUS_FLAGS);
}
else
{
ASSERTX (REG_is_pin_flags(reg));
return (REG_PIN_STATUS_FLAGS);
}
}
/* DO NOT EDIT */
inline REG REG_get_df_flag_reg_of_type(REG reg)
{
if (REG_is_flags(reg))
{
return (REG_DF_FLAG);
}
else
{
ASSERTX (REG_is_pin_flags(reg));
return (REG_PIN_DF_FLAG);
}
}
/* DO NOT EDIT */
inline REG REG_get_full_flags_reg_of_type(REG reg)
{
if (REG_is_any_app_flags(reg))
{
return (REG_GFLAGS);
}
else
{
ASSERTX (REG_is_any_pin_flags(reg));
return (REG_PIN_FLAGS);
}
}
/* DO NOT EDIT */
inline BOOL REG_is_stackptr_type(REG reg)
{
return ((_regSubClassBitMapTable[reg] & REGSBIT_STACKPTR_ALL) != 0);
}
/* DO NOT EDIT */
inline BOOL REG_is_representative_reg(REG reg)
{
// The REG_X87 represents the FPST registers only
const REG_CLASS_BITS representativeClassMask = ((_REGCBIT(REG_CLASS_X87)) | (_REGCBIT(REG_CLASS_PIN_X87)));
return ((_regClassBitMapTable[reg] & representativeClassMask) != 0);
}
/* DO NOT EDIT */
inline BOOL REG_is_pin_inst(REG reg)
{
return ((_regSubClassBitMapTable[reg] & REGSBIT_PIN_INST_ALL) != 0);
}
/* DO NOT EDIT */
inline BOOL REG_is_buffer(REG reg)
{
return ((_regSubClassBitMapTable[reg] & (REG_SUBCLASS_BITS(1) << (REG_SUBCLASS_PIN_INST_BUF))) != 0);
}
/* DO NOT EDIT */
inline BOOL REG_is_inst_scratch(REG reg)
{
return ((_regSubClassBitMapTable[reg] & REGSBIT_PIN_SCRATCH_ALL) != 0);
}
/* DO NOT EDIT */
inline ADDRINT REG_regSubClassBitMapTable()
{
return ((ADDRINT)(_regSubClassBitMapTable));
}
/* DO NOT EDIT */
inline ADDRINT REG_regDefTable()
{
return ((ADDRINT)(_regDefTable));
}
/* DO NOT EDIT */
inline BOOL REG_is_pin_tmp(REG reg)
{
return ((_regSubClassBitMapTable[reg] & (REG_SUBCLASS_BITS(1) << (REG_SUBCLASS_PIN_TMP))) != 0);
}
/* DO NOT EDIT */
typedef enum
{
REGNAME_LAST
}REGNAME;
/* DO NOT EDIT */
inline REG REG_INVALID() {return REG_INVALID_;}
/* DO NOT EDIT */
inline BOOL REG_valid(REG reg){ return reg != REG_INVALID();}
/* DO NOT EDIT */
inline BOOL REG_is_pin64(REG reg)
{
#if defined(TARGET_IA32)
// Nothing is 64 bit on a 32 bit machine
return FALSE;
#endif
return REG_is_pin_gr(reg); // all FULL WIDTH pin gr registers are 64-bits
}
/* DO NOT EDIT */
extern REG REG_LastSupportedXmm();
/* DO NOT EDIT */
extern REG REG_LastSupportedYmm();
/* DO NOT EDIT */
extern REG REG_LastSupportedZmm();
/* DO NOT EDIT */
extern UINT32 REG_Size(REG reg);
/* DO NOT EDIT */
extern REG REG_FullRegName(const REG reg);
/* DO NOT EDIT */
extern std::string REG_StringShort(REG reg);
/* DO NOT EDIT */
extern REG REG_IdentityCopy(const REG reg);
/* DO NOT EDIT */