//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_XMM_BASE+REG_YMM_BASE); } /* DO NOT EDIT */ inline REG REG_corresponding_zmm_reg(REG reg) { return static_cast(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 */