<commit_before>//! \file
/*
**  Copyright (C) - Triton
**
**  This program is under the terms of the LGPLv3 License.
*/

#include <cstring>

#include <architecture.hpp>
#include <coreUtils.hpp>
#include <cpuSize.hpp>
#include <externalLibs.hpp>
#include <immediateOperand.hpp>
#include <x86Cpu.hpp>
#include <x86Specifications.hpp>

#ifdef TRITON_PYTHON_BINDINGS
  #include <pythonBindings.hpp>
#endif



namespace triton {
  namespace arch {
    namespace x86 {

    x86Cpu::x86Cpu() {
      this->clear();
    }


    x86Cpu::x86Cpu(const x86Cpu& other) {
      this->copy(other);
    }


    x86Cpu::~x86Cpu() {
      triton::arch::x86::x86_reg_eax    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_ax     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_ah     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_al     = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_ebx    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_bx     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_bh     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_bl     = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_ecx    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cx     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_ch     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cl     = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_edx    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_dx     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_dh     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_dl     = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_edi    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_di     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_dil    = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_esi    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_si     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_sil    = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_esp    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_sp     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_spl    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_stack  = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_ebp    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_bp     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_bpl    = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_eip    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_ip     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_pc     = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_eflags = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_mm0    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_mm1    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_mm2    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_mm3    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_mm4    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_mm5    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_mm6    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_mm7    = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_xmm0   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_xmm1   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_xmm2   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_xmm3   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_xmm4   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_xmm5   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_xmm6   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_xmm7   = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_ymm0   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_ymm1   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_ymm2   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_ymm3   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_ymm4   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_ymm5   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_ymm6   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_ymm7   = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_mxcsr  = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_cr0    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cr1    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cr2    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cr3    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cr4    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cr5    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cr6    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cr7    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cr8    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cr9    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cr10   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cr11   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cr12   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cr13   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cr14   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cr15   = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_ie     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_de     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_ze     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_oe     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_ue     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_pe     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_daz    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_im     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_dm     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_zm     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_om     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_um     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_pm     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_rl     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_rh     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_fz     = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_af     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cf     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_df     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_if     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_of     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_pf     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_sf     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_tf     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_zf     = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_cs     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_ds     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_es     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_fs     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_gs     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_ss     = triton::arch::RegisterOperand();
    }


    void x86Cpu::copy(const x86Cpu& other) {
      this->memory = other.memory;
      memcpy(this->eax,     other.eax,    sizeof(this->eax));
      memcpy(this->ebx,     other.ebx,    sizeof(this->ebx));
      memcpy(this->ecx,     other.ecx,    sizeof(this->ecx));
      memcpy(this->edx,     other.edx,    sizeof(this->edx));
      memcpy(this->edi,     other.edi,    sizeof(this->edi));
      memcpy(this->esi,     other.esi,    sizeof(this->esi));
      memcpy(this->esp,     other.esp,    sizeof(this->esp));
      memcpy(this->ebp,     other.ebp,    sizeof(this->ebp));
      memcpy(this->eip,     other.eip,    sizeof(this->eip));
      memcpy(this->eflags,  other.eflags, sizeof(this->eflags));
      memcpy(this->mm0,     other.mm0,    sizeof(this->mm0));
      memcpy(this->mm1,     other.mm1,    sizeof(this->mm1));
      memcpy(this->mm2,     other.mm2,    sizeof(this->mm2));
      memcpy(this->mm3,     other.mm3,    sizeof(this->mm3));
      memcpy(this->mm4,     other.mm4,    sizeof(this->mm4));
      memcpy(this->mm5,     other.mm5,    sizeof(this->mm5));
      memcpy(this->mm6,     other.mm6,    sizeof(this->mm6));
      memcpy(this->mm7,     other.mm7,    sizeof(this->mm7));
      memcpy(this->xmm0,    other.xmm0,   sizeof(this->xmm0));
      memcpy(this->xmm1,    other.xmm1,   sizeof(this->xmm1));
      memcpy(this->xmm2,    other.xmm2,   sizeof(this->xmm2));
      memcpy(this->xmm3,    other.xmm3,   sizeof(this->xmm3));
      memcpy(this->xmm4,    other.xmm4,   sizeof(this->xmm4));
      memcpy(this->xmm5,    other.xmm5,   sizeof(this->xmm5));
      memcpy(this->xmm6,    other.xmm6,   sizeof(this->xmm6));
      memcpy(this->xmm7,    other.xmm7,   sizeof(this->xmm7));
      memcpy(this->ymm0,    other.ymm0,   sizeof(this->ymm0));
      memcpy(this->ymm1,    other.ymm1,   sizeof(this->ymm1));
      memcpy(this->ymm2,    other.ymm2,   sizeof(this->ymm2));
      memcpy(this->ymm3,    other.ymm3,   sizeof(this->ymm3));
      memcpy(this->ymm4,    other.ymm4,   sizeof(this->ymm4));
      memcpy(this->ymm5,    other.ymm5,   sizeof(this->ymm5));
      memcpy(this->ymm6,    other.ymm6,   sizeof(this->ymm6));
      memcpy(this->ymm7,    other.ymm7,   sizeof(this->ymm7));
      memcpy(this->mxcsr,   other.mxcsr,  sizeof(this->mxcsr));
      memcpy(this->cr0,     other.cr0,    sizeof(this->cr0));
      memcpy(this->cr1,     other.cr1,    sizeof(this->cr1));
      memcpy(this->cr2,     other.cr2,    sizeof(this->cr2));
      memcpy(this->cr3,     other.cr3,    sizeof(this->cr3));
      memcpy(this->cr4,     other.cr4,    sizeof(this->cr4));
      memcpy(this->cr5,     other.cr5,    sizeof(this->cr5));
      memcpy(this->cr6,     other.cr6,    sizeof(this->cr6));
      memcpy(this->cr7,     other.cr7,    sizeof(this->cr7));
      memcpy(this->cr8,     other.cr8,    sizeof(this->cr8));
      memcpy(this->cr9,     other.cr9,    sizeof(this->cr9));
      memcpy(this->cr10,    other.cr10,   sizeof(this->cr10));
      memcpy(this->cr11,    other.cr11,   sizeof(this->cr11));
      memcpy(this->cr12,    other.cr12,   sizeof(this->cr12));
      memcpy(this->cr13,    other.cr13,   sizeof(this->cr13));
      memcpy(this->cr14,    other.cr14,   sizeof(this->cr14));
      memcpy(this->cr15,    other.cr15,   sizeof(this->cr15));
      memcpy(this->cs,      other.cs,     sizeof(this->cs));
      memcpy(this->ds,      other.ds,     sizeof(this->ds));
      memcpy(this->es,      other.es,     sizeof(this->es));
      memcpy(this->fs,      other.fs,     sizeof(this->fs));
      memcpy(this->gs,      other.gs,     sizeof(this->gs));
      memcpy(this->ss,      other.ss,     sizeof(this->ss));
    }


    void x86Cpu::init(void) {
      /* Define registers ========================================================= */
      triton::arch::x86::x86_reg_eax    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_EAX);
      triton::arch::x86::x86_reg_ax     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_AX);
      triton::arch::x86::x86_reg_ah     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_AH);
      triton::arch::x86::x86_reg_al     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_AL);

      triton::arch::x86::x86_reg_ebx    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_EBX);
      triton::arch::x86::x86_reg_bx     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_BX);
      triton::arch::x86::x86_reg_bh     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_BH);
      triton::arch::x86::x86_reg_bl     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_BL);

      triton::arch::x86::x86_reg_ecx    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_ECX);
      triton::arch::x86::x86_reg_cx     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CX);
      triton::arch::x86::x86_reg_ch     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CH);
      triton::arch::x86::x86_reg_cl     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CL);

      triton::arch::x86::x86_reg_edx    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_EDX);
      triton::arch::x86::x86_reg_dx     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_DX);
      triton::arch::x86::x86_reg_dh     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_DH);
      triton::arch::x86::x86_reg_dl     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_DL);

      triton::arch::x86::x86_reg_edi    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_EDI);
      triton::arch::x86::x86_reg_di     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_DI);
      triton::arch::x86::x86_reg_dil    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_DIL);

      triton::arch::x86::x86_reg_esi    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_ESI);
      triton::arch::x86::x86_reg_si     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_SI);
      triton::arch::x86::x86_reg_sil    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_SIL);

      triton::arch::x86::x86_reg_esp    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_ESP);
      triton::arch::x86::x86_reg_sp     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_SP);
      triton::arch::x86::x86_reg_spl    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_SPL);
      triton::arch::x86::x86_reg_stack  = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_ESP);

      triton::arch::x86::x86_reg_ebp    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_EBP);
      triton::arch::x86::x86_reg_bp     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_BP);
      triton::arch::x86::x86_reg_bpl    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_BPL);

      triton::arch::x86::x86_reg_eip    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_EIP);
      triton::arch::x86::x86_reg_ip     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_IP);
      triton::arch::x86::x86_reg_pc     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_EIP);

      triton::arch::x86::x86_reg_eflags = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_EFLAGS);

      triton::arch::x86::x86_reg_mm0    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_MM0);
      triton::arch::x86::x86_reg_mm1    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_MM1);
      triton::arch::x86::x86_reg_mm2    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_MM2);
      triton::arch::x86::x86_reg_mm3    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_MM3);
      triton::arch::x86::x86_reg_mm4    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_MM4);
      triton::arch::x86::x86_reg_mm5    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_MM5);
      triton::arch::x86::x86_reg_mm6    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_MM6);
      triton::arch::x86::x86_reg_mm7    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_MM7);

      triton::arch::x86::x86_reg_xmm0   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_XMM0);
      triton::arch::x86::x86_reg_xmm1   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_XMM1);
      triton::arch::x86::x86_reg_xmm2   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_XMM2);
      triton::arch::x86::x86_reg_xmm3   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_XMM3);
      triton::arch::x86::x86_reg_xmm4   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_XMM4);
      triton::arch::x86::x86_reg_xmm5   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_XMM5);
      triton::arch::x86::x86_reg_xmm6   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_XMM6);
      triton::arch::x86::x86_reg_xmm7   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_XMM7);

      triton::arch::x86::x86_reg_ymm0   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_YMM0);
      triton::arch::x86::x86_reg_ymm1   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_YMM1);
      triton::arch::x86::x86_reg_ymm2   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_YMM2);
      triton::arch::x86::x86_reg_ymm3   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_YMM3);
      triton::arch::x86::x86_reg_ymm4   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_YMM4);
      triton::arch::x86::x86_reg_ymm5   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_YMM5);
      triton::arch::x86::x86_reg_ymm6   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_YMM6);
      triton::arch::x86::x86_reg_ymm7   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_YMM7);

      triton::arch::x86::x86_reg_mxcsr  = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_MXCSR);

      triton::arch::x86::x86_reg_cr0    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CR0);
      triton::arch::x86::x86_reg_cr1    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CR1);
      triton::arch::x86::x86_reg_cr2    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CR2);
      triton::arch::x86::x86_reg_cr3    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CR3);
      triton::arch::x86::x86_reg_cr4    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CR4);
      triton::arch::x86::x86_reg_cr5    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CR5);
      triton::arch::x86::x86_reg_cr6    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CR6);
      triton::arch::x86::x86_reg_cr7    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CR7);
      triton::arch::x86::x86_reg_cr8    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CR8);
      triton::arch::x86::x86_reg_cr9    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CR9);
      triton::arch::x86::x86_reg_cr10   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CR10);
      triton::arch::x86::x86_reg_cr11   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CR11);
      triton::arch::x86::x86_reg_cr12   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CR12);
      triton::arch::x86::x86_reg_cr13   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CR13);
      triton::arch::x86::x86_reg_cr14   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CR14);
      triton::arch::x86::x86_reg_cr15   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CR15);

      triton::arch::x86::x86_reg_ie     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_IE);
      triton::arch::x86::x86_reg_de     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_DE);
      triton::arch::x86::x86_reg_ze     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_ZE);
      triton::arch::x86::x86_reg_oe     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_OE);
      triton::arch::x86::x86_reg_ue     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_UE);
      triton::arch::x86::x86_reg_pe     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_PE);
      triton::arch::x86::x86_reg_daz    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_DAZ);
      triton::arch::x86::x86_reg_im     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_IM);
      triton::arch::x86::x86_reg_dm     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_DM);
      triton::arch::x86::x86_reg_zm     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_ZM);
      triton::arch::x86::x86_reg_om     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_OM);
      triton::arch::x86::x86_reg_um     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_UM);
      triton::arch::x86::x86_reg_pm     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_PM);
      triton::arch::x86::x86_reg_rl     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_RL);
      triton::arch::x86::x86_reg_rh     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_RH);
      triton::arch::x86::x86_reg_fz     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_FZ);

      triton::arch::x86::x86_reg_af     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_AF);
      triton::arch::x86::x86_reg_cf     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CF);
      triton::arch::x86::x86_reg_df     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_DF);
      triton::arch::x86::x86_reg_if     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_IF);
      triton::arch::x86::x86_reg_of     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_OF);
      triton::arch::x86::x86_reg_pf     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_PF);
      triton::arch::x86::x86_reg_sf     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_SF);
      triton::arch::x86::x86_reg_tf     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_TF);
      triton::arch::x86::x86_reg_zf     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_ZF);

      triton::arch::x86::x86_reg_cs     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CS);
      triton::arch::x86::x86_reg_ds     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_DS);
      triton::arch::x86::x86_reg_es     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_ES);
      triton::arch::x86::x86_reg_fs     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_FS);
      triton::arch::x86::x86_reg_gs     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_GS);
      triton::arch::x86::x86_reg_ss     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_SS);


      /* Update python env ======================================================== */
      #ifdef TRITON_PYTHON_BINDINGS
        triton::bindings::python::initRegNamespace();
        triton::bindings::python::initCpuSizeNamespace();
        triton::bindings::python::initX86OpcodesNamespace();
        triton::bindings::python::initX86PrefixesNamespace();
        #if defined(__unix__) || defined(__APPLE__)
          triton::bindings::python::initSyscallNamespace();
        #endif
      #endif
    }


    void x86Cpu::clear(void) {
      /* Clear memory */
      this->memory.clear();

      /* Clear registers */
      memset(this->eax,     0x00, sizeof(this->eax));
      memset(this->ebx,     0x00, sizeof(this->ebx));
      memset(this->ecx,     0x00, sizeof(this->ecx));
      memset(this->edx,     0x00, sizeof(this->edx));
      memset(this->edi,     0x00, sizeof(this->edi));
      memset(this->esi,     0x00, sizeof(this->esi));
      memset(this->esp,     0x00, sizeof(this->esp));
      memset(this->ebp,     0x00, sizeof(this->ebp));
      memset(this->eip,     0x00, sizeof(this->eip));
      memset(this->eflags,  0x00, sizeof(this->eflags));
      memset(this->mm0,     0x00, sizeof(this->mm0));
      memset(this->mm1,     0x00, sizeof(this->mm1));
      memset(this->mm2,     0x00, sizeof(this->mm2));
      memset(this->mm3,     0x00, sizeof(this->mm3));
      memset(this->mm4,     0x00, sizeof(this->mm4));
      memset(this->mm5,     0x00, sizeof(this->mm5));
      memset(this->mm6,     0x00, sizeof(this->mm6));
      memset(this->mm7,     0x00, sizeof(this->mm7));
      memset(this->xmm0,    0x00, sizeof(this->xmm0));
      memset(this->xmm1,    0x00, sizeof(this->xmm1));
      memset(this->xmm2,    0x00, sizeof(this->xmm2));
      memset(this->xmm3,    0x00, sizeof(this->xmm3));
      memset(this->xmm4,    0x00, sizeof(this->xmm4));
      memset(this->xmm5,    0x00, sizeof(this->xmm5));
      memset(this->xmm6,    0x00, sizeof(this->xmm6));
      memset(this->xmm7,    0x00, sizeof(this->xmm7));
      memset(this->ymm0,    0x00, sizeof(this->ymm0));
      memset(this->ymm1,    0x00, sizeof(this->ymm1));
      memset(this->ymm2,    0x00, sizeof(this->ymm2));
      memset(this->ymm3,    0x00, sizeof(this->ymm3));
      memset(this->ymm4,    0x00, sizeof(this->ymm4));
      memset(this->ymm5,    0x00, sizeof(this->ymm5));
      memset(this->ymm6,    0x00, sizeof(this->ymm6));
      memset(this->ymm7,    0x00, sizeof(this->ymm7));
      memset(this->mxcsr,   0x00, sizeof(this->mxcsr));
      memset(this->cr0,     0x00, sizeof(this->cr0));
      memset(this->cr1,     0x00, sizeof(this->cr1));
      memset(this->cr2,     0x00, sizeof(this->cr2));
      memset(this->cr3,     0x00, sizeof(this->cr3));
      memset(this->cr4,     0x00, sizeof(this->cr4));
      memset(this->cr5,     0x00, sizeof(this->cr5));
      memset(this->cr6,     0x00, sizeof(this->cr6));
      memset(this->cr7,     0x00, sizeof(this->cr7));
      memset(this->cr8,     0x00, sizeof(this->cr8));
      memset(this->cr9,     0x00, sizeof(this->cr9));
      memset(this->cr10,    0x00, sizeof(this->cr10));
      memset(this->cr11,    0x00, sizeof(this->cr11));
      memset(this->cr12,    0x00, sizeof(this->cr12));
      memset(this->cr13,    0x00, sizeof(this->cr13));
      memset(this->cr14,    0x00, sizeof(this->cr14));
      memset(this->cr15,    0x00, sizeof(this->cr15));
      memset(this->cs,      0x00, sizeof(this->cs));
      memset(this->ds,      0x00, sizeof(this->ds));
      memset(this->es,      0x00, sizeof(this->es));
      memset(this->fs,      0x00, sizeof(this->fs));
      memset(this->gs,      0x00, sizeof(this->gs));
      memset(this->ss,      0x00, sizeof(this->ss));
    }


    void x86Cpu::operator=(const x86Cpu& other) {
      this->copy(other);
    }


    bool x86Cpu::isFlag(triton::uint32 regId) {
      return ((regId >= triton::arch::x86::ID_REG_AF && regId <= triton::arch::x86::ID_REG_FZ) ? true : false);
    }


    bool x86Cpu::isRegister(triton::uint32 regId) {
      return (this->isGPR(regId) || this->isMMX(regId) || this->isSSE(regId) || this->isAVX256(regId) || this->isControl(regId) || this->isSegment(regId));
    }


    bool x86Cpu::isRegisterValid(triton::uint32 regId) {
      return (this->isFlag(regId) || this->isRegister(regId));
    }


    bool x86Cpu::isGPR(triton::uint32 regId) {
      return ((regId >= triton::arch::x86::ID_REG_EAX && regId <= triton::arch::x86::ID_REG_EFLAGS) ? true : false);
    }


    bool x86Cpu::isMMX(triton::uint32 regId) {
      return ((regId >= triton::arch::x86::ID_REG_MM0 && regId <= triton::arch::x86::ID_REG_MM7) ? true : false);
    }


    bool x86Cpu::isSSE(triton::uint32 regId) {
      return ((regId >= triton::arch::x86::ID_REG_MXCSR && regId <= triton::arch::x86::ID_REG_XMM7) ? true : false);
    }


    bool x86Cpu::isAVX256(triton::uint32 regId) {
      return ((regId >= triton::arch::x86::ID_REG_YMM0 && regId <= triton::arch::x86::ID_REG_YMM7) ? true : false);
    }


    bool x86Cpu::isControl(triton::uint32 regId) {
      return ((regId >= triton::arch::x86::ID_REG_CR0 && regId <= triton::arch::x86::ID_REG_CR15) ? true : false);
    }


    bool x86Cpu::isSegment(triton::uint32 regId) {
      return ((regId >= triton::arch::x86::ID_REG_CS && regId <= triton::arch::x86::ID_REG_SS) ? true : false);
    }


    triton::uint32 x86Cpu::invalidRegister(void) {
      return triton::arch::x86::ID_REG_INVALID;
    }


    triton::uint32 x86Cpu::numberOfRegisters(void) {
      return triton::arch::x86::ID_REG_LAST_ITEM;
    }


    triton::uint32 x86Cpu::registerSize(void) {
      return DWORD_SIZE;
    }


    triton::uint32 x86Cpu::registerBitSize(void) {
      return DWORD_SIZE_BIT;
    }


    std::tuple<std::string, triton::uint32, triton::uint32, triton::uint32> x86Cpu::getRegisterInformation(triton::uint32 reg) {
      return triton::arch::x86::registerIdToRegisterInformation(reg);
    }


    std::set<triton::arch::RegisterOperand*> x86Cpu::getAllRegisters(void) {
      std::set<triton::arch::RegisterOperand*> ret;

      for (triton::uint32 index = 0; index < triton::arch::x86::ID_REG_LAST_ITEM; index++) {
        if (this->isRegisterValid(triton::arch::x86::x86_regs[index]->getId()))
          ret.insert(triton::arch::x86::x86_regs[index]);
      }

      return ret;
    }


    std::set<triton::arch::RegisterOperand*> x86Cpu::getParentRegisters(void) {
      std::set<triton::arch::RegisterOperand*> ret;

      for (triton::uint32 index = 0; index < triton::arch::x86::ID_REG_LAST_ITEM; index++) {
        /* Add GPR */
        if (triton::arch::x86::x86_regs[index]->getSize() == this->registerSize())
          ret.insert(triton::arch::x86::x86_regs[index]);

        /* Add Flags */
        else if (this->isFlag(triton::arch::x86::x86_regs[index]->getId()))
          ret.insert(triton::arch::x86::x86_regs[index]);

        /* Add MMX */
        else if (this->isMMX(triton::arch::x86::x86_regs[index]->getId()))
          ret.insert(triton::arch::x86::x86_regs[index]);

        /* Add SSE */
        else if (this->isSSE(triton::arch::x86::x86_regs[index]->getId()))
          ret.insert(triton::arch::x86::x86_regs[index]);

        /* Add AVX-256 */
        else if (this->isAVX256(triton::arch::x86::x86_regs[index]->getId()))
          ret.insert(triton::arch::x86::x86_regs[index]);

        /* Add Control */
        else if (this->isControl(triton::arch::x86::x86_regs[index]->getId()))
          ret.insert(triton::arch::x86::x86_regs[index]);
      }

      return ret;
    }


    void x86Cpu::disassembly(triton::arch::Instruction &inst) {
      triton::extlibs::capstone::csh       handle;
      triton::extlibs::capstone::cs_insn*  insn;
      size_t                               count = 0;

      /* Check if the opcodes and opcodes' size are defined */
      if (inst.getOpcodes() == nullptr || inst.getSize() == 0)
        throw std::runtime_error("x86Cpu::disassembly(): Opcodes and opcodesSize must be definied.");

      /* Open capstone */
      if (triton::extlibs::capstone::cs_open(triton::extlibs::capstone::CS_ARCH_X86, triton::extlibs::capstone::CS_MODE_32, &handle) != triton::extlibs::capstone::CS_ERR_OK)
        throw std::runtime_error("x86Cpu::disassembly(): Cannot open capstone.");

      /* Init capstone's options */
      triton::extlibs::capstone::cs_option(handle, triton::extlibs::capstone::CS_OPT_DETAIL, triton::extlibs::capstone::CS_OPT_ON);
      triton::extlibs::capstone::cs_option(handle, triton::extlibs::capstone::CS_OPT_SYNTAX, triton::extlibs::capstone::CS_OPT_SYNTAX_INTEL);

      /* Let's disass and build our operands */
      count = triton::extlibs::capstone::cs_disasm(handle, inst.getOpcodes(), inst.getSize(), inst.getAddress(), 0, &insn);
      if (count > 0) {
        triton::extlibs::capstone::cs_detail* detail = insn->detail;
        for (triton::uint32 j = 0; j < 1; j++) {

          /* Init the disassembly */
          std::stringstream str;
          str << insn[j].mnemonic << " " <<  insn[j].op_str;
          inst.setDisassembly(str.str());

          /* Refine the size */
          inst.setSize(insn[j].size);

          /* Init the instruction's type */
          inst.setType(capstoneInstructionToTritonInstruction(insn[j].id));

          /* Init the instruction's prefix */
          inst.setPrefix(capstonePrefixToTritonPrefix(detail->x86.prefix[0]));

          /* Init operands */
          for (triton::uint32 n = 0; n < detail->x86.op_count; n++) {
            triton::extlibs::capstone::cs_x86_op* op = &(detail->x86.operands[n]);
            switch(op->type) {

              case triton::extlibs::capstone::X86_OP_IMM:
                inst.operands.push_back(triton::arch::OperandWrapper(triton::arch::ImmediateOperand(op->imm, op->size)));
                break;

              case triton::extlibs::capstone::X86_OP_MEM: {
                triton::arch::MemoryOperand mem = inst.popMemoryAccess();

                /* Set the size if the memory is not valid */
                if (!mem.isValid())
                  mem.setPair(std::make_pair(((op->size * BYTE_SIZE_BIT) - 1), 0));

                /* LEA if exists */
                triton::arch::RegisterOperand segment(triton::arch::x86::capstoneRegisterToTritonRegister(op->mem.segment));
                triton::arch::RegisterOperand base(triton::arch::x86::capstoneRegisterToTritonRegister(op->mem.base));
                triton::arch::RegisterOperand index(triton::arch::x86::capstoneRegisterToTritonRegister(op->mem.index));
                triton::arch::ImmediateOperand disp(op->mem.disp, op->size);
                triton::arch::ImmediateOperand scale(op->mem.scale, op->size);

                mem.setSegmentRegister(segment);
                mem.setBaseRegister(base);
                mem.setIndexRegister(index);<commit_msg>x86::32 lea pc relative<commit_after>//! \file
/*
**  Copyright (C) - Triton
**
**  This program is under the terms of the LGPLv3 License.
*/

#include <cstring>

#include <architecture.hpp>
#include <coreUtils.hpp>
#include <cpuSize.hpp>
#include <externalLibs.hpp>
#include <immediateOperand.hpp>
#include <x86Cpu.hpp>
#include <x86Specifications.hpp>

#ifdef TRITON_PYTHON_BINDINGS
  #include <pythonBindings.hpp>
#endif



namespace triton {
  namespace arch {
    namespace x86 {

    x86Cpu::x86Cpu() {
      this->clear();
    }


    x86Cpu::x86Cpu(const x86Cpu& other) {
      this->copy(other);
    }


    x86Cpu::~x86Cpu() {
      triton::arch::x86::x86_reg_eax    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_ax     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_ah     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_al     = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_ebx    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_bx     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_bh     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_bl     = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_ecx    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cx     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_ch     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cl     = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_edx    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_dx     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_dh     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_dl     = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_edi    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_di     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_dil    = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_esi    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_si     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_sil    = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_esp    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_sp     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_spl    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_stack  = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_ebp    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_bp     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_bpl    = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_eip    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_ip     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_pc     = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_eflags = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_mm0    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_mm1    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_mm2    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_mm3    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_mm4    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_mm5    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_mm6    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_mm7    = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_xmm0   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_xmm1   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_xmm2   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_xmm3   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_xmm4   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_xmm5   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_xmm6   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_xmm7   = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_ymm0   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_ymm1   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_ymm2   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_ymm3   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_ymm4   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_ymm5   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_ymm6   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_ymm7   = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_mxcsr  = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_cr0    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cr1    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cr2    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cr3    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cr4    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cr5    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cr6    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cr7    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cr8    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cr9    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cr10   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cr11   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cr12   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cr13   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cr14   = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cr15   = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_ie     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_de     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_ze     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_oe     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_ue     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_pe     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_daz    = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_im     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_dm     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_zm     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_om     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_um     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_pm     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_rl     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_rh     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_fz     = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_af     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_cf     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_df     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_if     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_of     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_pf     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_sf     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_tf     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_zf     = triton::arch::RegisterOperand();

      triton::arch::x86::x86_reg_cs     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_ds     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_es     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_fs     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_gs     = triton::arch::RegisterOperand();
      triton::arch::x86::x86_reg_ss     = triton::arch::RegisterOperand();
    }


    void x86Cpu::copy(const x86Cpu& other) {
      this->memory = other.memory;
      memcpy(this->eax,     other.eax,    sizeof(this->eax));
      memcpy(this->ebx,     other.ebx,    sizeof(this->ebx));
      memcpy(this->ecx,     other.ecx,    sizeof(this->ecx));
      memcpy(this->edx,     other.edx,    sizeof(this->edx));
      memcpy(this->edi,     other.edi,    sizeof(this->edi));
      memcpy(this->esi,     other.esi,    sizeof(this->esi));
      memcpy(this->esp,     other.esp,    sizeof(this->esp));
      memcpy(this->ebp,     other.ebp,    sizeof(this->ebp));
      memcpy(this->eip,     other.eip,    sizeof(this->eip));
      memcpy(this->eflags,  other.eflags, sizeof(this->eflags));
      memcpy(this->mm0,     other.mm0,    sizeof(this->mm0));
      memcpy(this->mm1,     other.mm1,    sizeof(this->mm1));
      memcpy(this->mm2,     other.mm2,    sizeof(this->mm2));
      memcpy(this->mm3,     other.mm3,    sizeof(this->mm3));
      memcpy(this->mm4,     other.mm4,    sizeof(this->mm4));
      memcpy(this->mm5,     other.mm5,    sizeof(this->mm5));
      memcpy(this->mm6,     other.mm6,    sizeof(this->mm6));
      memcpy(this->mm7,     other.mm7,    sizeof(this->mm7));
      memcpy(this->xmm0,    other.xmm0,   sizeof(this->xmm0));
      memcpy(this->xmm1,    other.xmm1,   sizeof(this->xmm1));
      memcpy(this->xmm2,    other.xmm2,   sizeof(this->xmm2));
      memcpy(this->xmm3,    other.xmm3,   sizeof(this->xmm3));
      memcpy(this->xmm4,    other.xmm4,   sizeof(this->xmm4));
      memcpy(this->xmm5,    other.xmm5,   sizeof(this->xmm5));
      memcpy(this->xmm6,    other.xmm6,   sizeof(this->xmm6));
      memcpy(this->xmm7,    other.xmm7,   sizeof(this->xmm7));
      memcpy(this->ymm0,    other.ymm0,   sizeof(this->ymm0));
      memcpy(this->ymm1,    other.ymm1,   sizeof(this->ymm1));
      memcpy(this->ymm2,    other.ymm2,   sizeof(this->ymm2));
      memcpy(this->ymm3,    other.ymm3,   sizeof(this->ymm3));
      memcpy(this->ymm4,    other.ymm4,   sizeof(this->ymm4));
      memcpy(this->ymm5,    other.ymm5,   sizeof(this->ymm5));
      memcpy(this->ymm6,    other.ymm6,   sizeof(this->ymm6));
      memcpy(this->ymm7,    other.ymm7,   sizeof(this->ymm7));
      memcpy(this->mxcsr,   other.mxcsr,  sizeof(this->mxcsr));
      memcpy(this->cr0,     other.cr0,    sizeof(this->cr0));
      memcpy(this->cr1,     other.cr1,    sizeof(this->cr1));
      memcpy(this->cr2,     other.cr2,    sizeof(this->cr2));
      memcpy(this->cr3,     other.cr3,    sizeof(this->cr3));
      memcpy(this->cr4,     other.cr4,    sizeof(this->cr4));
      memcpy(this->cr5,     other.cr5,    sizeof(this->cr5));
      memcpy(this->cr6,     other.cr6,    sizeof(this->cr6));
      memcpy(this->cr7,     other.cr7,    sizeof(this->cr7));
      memcpy(this->cr8,     other.cr8,    sizeof(this->cr8));
      memcpy(this->cr9,     other.cr9,    sizeof(this->cr9));
      memcpy(this->cr10,    other.cr10,   sizeof(this->cr10));
      memcpy(this->cr11,    other.cr11,   sizeof(this->cr11));
      memcpy(this->cr12,    other.cr12,   sizeof(this->cr12));
      memcpy(this->cr13,    other.cr13,   sizeof(this->cr13));
      memcpy(this->cr14,    other.cr14,   sizeof(this->cr14));
      memcpy(this->cr15,    other.cr15,   sizeof(this->cr15));
      memcpy(this->cs,      other.cs,     sizeof(this->cs));
      memcpy(this->ds,      other.ds,     sizeof(this->ds));
      memcpy(this->es,      other.es,     sizeof(this->es));
      memcpy(this->fs,      other.fs,     sizeof(this->fs));
      memcpy(this->gs,      other.gs,     sizeof(this->gs));
      memcpy(this->ss,      other.ss,     sizeof(this->ss));
    }


    void x86Cpu::init(void) {
      /* Define registers ========================================================= */
      triton::arch::x86::x86_reg_eax    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_EAX);
      triton::arch::x86::x86_reg_ax     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_AX);
      triton::arch::x86::x86_reg_ah     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_AH);
      triton::arch::x86::x86_reg_al     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_AL);

      triton::arch::x86::x86_reg_ebx    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_EBX);
      triton::arch::x86::x86_reg_bx     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_BX);
      triton::arch::x86::x86_reg_bh     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_BH);
      triton::arch::x86::x86_reg_bl     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_BL);

      triton::arch::x86::x86_reg_ecx    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_ECX);
      triton::arch::x86::x86_reg_cx     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CX);
      triton::arch::x86::x86_reg_ch     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CH);
      triton::arch::x86::x86_reg_cl     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CL);

      triton::arch::x86::x86_reg_edx    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_EDX);
      triton::arch::x86::x86_reg_dx     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_DX);
      triton::arch::x86::x86_reg_dh     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_DH);
      triton::arch::x86::x86_reg_dl     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_DL);

      triton::arch::x86::x86_reg_edi    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_EDI);
      triton::arch::x86::x86_reg_di     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_DI);
      triton::arch::x86::x86_reg_dil    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_DIL);

      triton::arch::x86::x86_reg_esi    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_ESI);
      triton::arch::x86::x86_reg_si     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_SI);
      triton::arch::x86::x86_reg_sil    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_SIL);

      triton::arch::x86::x86_reg_esp    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_ESP);
      triton::arch::x86::x86_reg_sp     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_SP);
      triton::arch::x86::x86_reg_spl    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_SPL);
      triton::arch::x86::x86_reg_stack  = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_ESP);

      triton::arch::x86::x86_reg_ebp    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_EBP);
      triton::arch::x86::x86_reg_bp     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_BP);
      triton::arch::x86::x86_reg_bpl    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_BPL);

      triton::arch::x86::x86_reg_eip    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_EIP);
      triton::arch::x86::x86_reg_ip     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_IP);
      triton::arch::x86::x86_reg_pc     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_EIP);

      triton::arch::x86::x86_reg_eflags = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_EFLAGS);

      triton::arch::x86::x86_reg_mm0    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_MM0);
      triton::arch::x86::x86_reg_mm1    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_MM1);
      triton::arch::x86::x86_reg_mm2    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_MM2);
      triton::arch::x86::x86_reg_mm3    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_MM3);
      triton::arch::x86::x86_reg_mm4    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_MM4);
      triton::arch::x86::x86_reg_mm5    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_MM5);
      triton::arch::x86::x86_reg_mm6    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_MM6);
      triton::arch::x86::x86_reg_mm7    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_MM7);

      triton::arch::x86::x86_reg_xmm0   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_XMM0);
      triton::arch::x86::x86_reg_xmm1   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_XMM1);
      triton::arch::x86::x86_reg_xmm2   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_XMM2);
      triton::arch::x86::x86_reg_xmm3   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_XMM3);
      triton::arch::x86::x86_reg_xmm4   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_XMM4);
      triton::arch::x86::x86_reg_xmm5   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_XMM5);
      triton::arch::x86::x86_reg_xmm6   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_XMM6);
      triton::arch::x86::x86_reg_xmm7   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_XMM7);

      triton::arch::x86::x86_reg_ymm0   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_YMM0);
      triton::arch::x86::x86_reg_ymm1   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_YMM1);
      triton::arch::x86::x86_reg_ymm2   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_YMM2);
      triton::arch::x86::x86_reg_ymm3   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_YMM3);
      triton::arch::x86::x86_reg_ymm4   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_YMM4);
      triton::arch::x86::x86_reg_ymm5   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_YMM5);
      triton::arch::x86::x86_reg_ymm6   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_YMM6);
      triton::arch::x86::x86_reg_ymm7   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_YMM7);

      triton::arch::x86::x86_reg_mxcsr  = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_MXCSR);

      triton::arch::x86::x86_reg_cr0    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CR0);
      triton::arch::x86::x86_reg_cr1    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CR1);
      triton::arch::x86::x86_reg_cr2    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CR2);
      triton::arch::x86::x86_reg_cr3    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CR3);
      triton::arch::x86::x86_reg_cr4    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CR4);
      triton::arch::x86::x86_reg_cr5    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CR5);
      triton::arch::x86::x86_reg_cr6    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CR6);
      triton::arch::x86::x86_reg_cr7    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CR7);
      triton::arch::x86::x86_reg_cr8    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CR8);
      triton::arch::x86::x86_reg_cr9    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CR9);
      triton::arch::x86::x86_reg_cr10   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CR10);
      triton::arch::x86::x86_reg_cr11   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CR11);
      triton::arch::x86::x86_reg_cr12   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CR12);
      triton::arch::x86::x86_reg_cr13   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CR13);
      triton::arch::x86::x86_reg_cr14   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CR14);
      triton::arch::x86::x86_reg_cr15   = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CR15);

      triton::arch::x86::x86_reg_ie     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_IE);
      triton::arch::x86::x86_reg_de     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_DE);
      triton::arch::x86::x86_reg_ze     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_ZE);
      triton::arch::x86::x86_reg_oe     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_OE);
      triton::arch::x86::x86_reg_ue     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_UE);
      triton::arch::x86::x86_reg_pe     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_PE);
      triton::arch::x86::x86_reg_daz    = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_DAZ);
      triton::arch::x86::x86_reg_im     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_IM);
      triton::arch::x86::x86_reg_dm     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_DM);
      triton::arch::x86::x86_reg_zm     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_ZM);
      triton::arch::x86::x86_reg_om     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_OM);
      triton::arch::x86::x86_reg_um     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_UM);
      triton::arch::x86::x86_reg_pm     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_PM);
      triton::arch::x86::x86_reg_rl     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_RL);
      triton::arch::x86::x86_reg_rh     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_RH);
      triton::arch::x86::x86_reg_fz     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_FZ);

      triton::arch::x86::x86_reg_af     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_AF);
      triton::arch::x86::x86_reg_cf     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CF);
      triton::arch::x86::x86_reg_df     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_DF);
      triton::arch::x86::x86_reg_if     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_IF);
      triton::arch::x86::x86_reg_of     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_OF);
      triton::arch::x86::x86_reg_pf     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_PF);
      triton::arch::x86::x86_reg_sf     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_SF);
      triton::arch::x86::x86_reg_tf     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_TF);
      triton::arch::x86::x86_reg_zf     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_ZF);

      triton::arch::x86::x86_reg_cs     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_CS);
      triton::arch::x86::x86_reg_ds     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_DS);
      triton::arch::x86::x86_reg_es     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_ES);
      triton::arch::x86::x86_reg_fs     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_FS);
      triton::arch::x86::x86_reg_gs     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_GS);
      triton::arch::x86::x86_reg_ss     = triton::arch::RegisterOperand(triton::arch::x86::ID_REG_SS);


      /* Update python env ======================================================== */
      #ifdef TRITON_PYTHON_BINDINGS
        triton::bindings::python::initRegNamespace();
        triton::bindings::python::initCpuSizeNamespace();
        triton::bindings::python::initX86OpcodesNamespace();
        triton::bindings::python::initX86PrefixesNamespace();
        #if defined(__unix__) || defined(__APPLE__)
          triton::bindings::python::initSyscallNamespace();
        #endif
      #endif
    }


    void x86Cpu::clear(void) {
      /* Clear memory */
      this->memory.clear();

      /* Clear registers */
      memset(this->eax,     0x00, sizeof(this->eax));
      memset(this->ebx,     0x00, sizeof(this->ebx));
      memset(this->ecx,     0x00, sizeof(this->ecx));
      memset(this->edx,     0x00, sizeof(this->edx));
      memset(this->edi,     0x00, sizeof(this->edi));
      memset(this->esi,     0x00, sizeof(this->esi));
      memset(this->esp,     0x00, sizeof(this->esp));
      memset(this->ebp,     0x00, sizeof(this->ebp));
      memset(this->eip,     0x00, sizeof(this->eip));
      memset(this->eflags,  0x00, sizeof(this->eflags));
      memset(this->mm0,     0x00, sizeof(this->mm0));
      memset(this->mm1,     0x00, sizeof(this->mm1));
      memset(this->mm2,     0x00, sizeof(this->mm2));
      memset(this->mm3,     0x00, sizeof(this->mm3));
      memset(this->mm4,     0x00, sizeof(this->mm4));
      memset(this->mm5,     0x00, sizeof(this->mm5));
      memset(this->mm6,     0x00, sizeof(this->mm6));
      memset(this->mm7,     0x00, sizeof(this->mm7));
      memset(this->xmm0,    0x00, sizeof(this->xmm0));
      memset(this->xmm1,    0x00, sizeof(this->xmm1));
      memset(this->xmm2,    0x00, sizeof(this->xmm2));
      memset(this->xmm3,    0x00, sizeof(this->xmm3));
      memset(this->xmm4,    0x00, sizeof(this->xmm4));
      memset(this->xmm5,    0x00, sizeof(this->xmm5));
      memset(this->xmm6,    0x00, sizeof(this->xmm6));
      memset(this->xmm7,    0x00, sizeof(this->xmm7));
      memset(this->ymm0,    0x00, sizeof(this->ymm0));
      memset(this->ymm1,    0x00, sizeof(this->ymm1));
      memset(this->ymm2,    0x00, sizeof(this->ymm2));
      memset(this->ymm3,    0x00, sizeof(this->ymm3));
      memset(this->ymm4,    0x00, sizeof(this->ymm4));
      memset(this->ymm5,    0x00, sizeof(this->ymm5));
      memset(this->ymm6,    0x00, sizeof(this->ymm6));
      memset(this->ymm7,    0x00, sizeof(this->ymm7));
      memset(this->mxcsr,   0x00, sizeof(this->mxcsr));
      memset(this->cr0,     0x00, sizeof(this->cr0));
      memset(this->cr1,     0x00, sizeof(this->cr1));
      memset(this->cr2,     0x00, sizeof(this->cr2));
      memset(this->cr3,     0x00, sizeof(this->cr3));
      memset(this->cr4,     0x00, sizeof(this->cr4));
      memset(this->cr5,     0x00, sizeof(this->cr5));
      memset(this->cr6,     0x00, sizeof(this->cr6));
      memset(this->cr7,     0x00, sizeof(this->cr7));
      memset(this->cr8,     0x00, sizeof(this->cr8));
      memset(this->cr9,     0x00, sizeof(this->cr9));
      memset(this->cr10,    0x00, sizeof(this->cr10));
      memset(this->cr11,    0x00, sizeof(this->cr11));
      memset(this->cr12,    0x00, sizeof(this->cr12));
      memset(this->cr13,    0x00, sizeof(this->cr13));
      memset(this->cr14,    0x00, sizeof(this->cr14));
      memset(this->cr15,    0x00, sizeof(this->cr15));
      memset(this->cs,      0x00, sizeof(this->cs));
      memset(this->ds,      0x00, sizeof(this->ds));
      memset(this->es,      0x00, sizeof(this->es));
      memset(this->fs,      0x00, sizeof(this->fs));
      memset(this->gs,      0x00, sizeof(this->gs));
      memset(this->ss,      0x00, sizeof(this->ss));
    }


    void x86Cpu::operator=(const x86Cpu& other) {
      this->copy(other);
    }


    bool x86Cpu::isFlag(triton::uint32 regId) {
      return ((regId >= triton::arch::x86::ID_REG_AF && regId <= triton::arch::x86::ID_REG_FZ) ? true : false);
    }


    bool x86Cpu::isRegister(triton::uint32 regId) {
      return (this->isGPR(regId) || this->isMMX(regId) || this->isSSE(regId) || this->isAVX256(regId) || this->isControl(regId) || this->isSegment(regId));
    }


    bool x86Cpu::isRegisterValid(triton::uint32 regId) {
      return (this->isFlag(regId) || this->isRegister(regId));
    }


    bool x86Cpu::isGPR(triton::uint32 regId) {
      return ((regId >= triton::arch::x86::ID_REG_EAX && regId <= triton::arch::x86::ID_REG_EFLAGS) ? true : false);
    }


    bool x86Cpu::isMMX(triton::uint32 regId) {
      return ((regId >= triton::arch::x86::ID_REG_MM0 && regId <= triton::arch::x86::ID_REG_MM7) ? true : false);
    }


    bool x86Cpu::isSSE(triton::uint32 regId) {
      return ((regId >= triton::arch::x86::ID_REG_MXCSR && regId <= triton::arch::x86::ID_REG_XMM7) ? true : false);
    }


    bool x86Cpu::isAVX256(triton::uint32 regId) {
      return ((regId >= triton::arch::x86::ID_REG_YMM0 && regId <= triton::arch::x86::ID_REG_YMM7) ? true : false);
    }


    bool x86Cpu::isControl(triton::uint32 regId) {
      return ((regId >= triton::arch::x86::ID_REG_CR0 && regId <= triton::arch::x86::ID_REG_CR15) ? true : false);
    }


    bool x86Cpu::isSegment(triton::uint32 regId) {
      return ((regId >= triton::arch::x86::ID_REG_CS && regId <= triton::arch::x86::ID_REG_SS) ? true : false);
    }


    triton::uint32 x86Cpu::invalidRegister(void) {
      return triton::arch::x86::ID_REG_INVALID;
    }


    triton::uint32 x86Cpu::numberOfRegisters(void) {
      return triton::arch::x86::ID_REG_LAST_ITEM;
    }


    triton::uint32 x86Cpu::registerSize(void) {
      return DWORD_SIZE;
    }


    triton::uint32 x86Cpu::registerBitSize(void) {
      return DWORD_SIZE_BIT;
    }


    std::tuple<std::string, triton::uint32, triton::uint32, triton::uint32> x86Cpu::getRegisterInformation(triton::uint32 reg) {
      return triton::arch::x86::registerIdToRegisterInformation(reg);
    }


    std::set<triton::arch::RegisterOperand*> x86Cpu::getAllRegisters(void) {
      std::set<triton::arch::RegisterOperand*> ret;

      for (triton::uint32 index = 0; index < triton::arch::x86::ID_REG_LAST_ITEM; index++) {
        if (this->isRegisterValid(triton::arch::x86::x86_regs[index]->getId()))
          ret.insert(triton::arch::x86::x86_regs[index]);
      }

      return ret;
    }


    std::set<triton::arch::RegisterOperand*> x86Cpu::getParentRegisters(void) {
      std::set<triton::arch::RegisterOperand*> ret;

      for (triton::uint32 index = 0; index < triton::arch::x86::ID_REG_LAST_ITEM; index++) {
        /* Add GPR */
        if (triton::arch::x86::x86_regs[index]->getSize() == this->registerSize())
          ret.insert(triton::arch::x86::x86_regs[index]);

        /* Add Flags */
        else if (this->isFlag(triton::arch::x86::x86_regs[index]->getId()))
          ret.insert(triton::arch::x86::x86_regs[index]);

        /* Add MMX */
        else if (this->isMMX(triton::arch::x86::x86_regs[index]->getId()))
          ret.insert(triton::arch::x86::x86_regs[index]);

        /* Add SSE */
        else if (this->isSSE(triton::arch::x86::x86_regs[index]->getId()))
          ret.insert(triton::arch::x86::x86_regs[index]);

        /* Add AVX-256 */
        else if (this->isAVX256(triton::arch::x86::x86_regs[index]->getId()))
          ret.insert(triton::arch::x86::x86_regs[index]);

        /* Add Control */
        else if (this->isControl(triton::arch::x86::x86_regs[index]->getId()))
          ret.insert(triton::arch::x86::x86_regs[index]);
      }

      return ret;
    }


    void x86Cpu::disassembly(triton::arch::Instruction &inst) {
      triton::extlibs::capstone::csh       handle;
      triton::extlibs::capstone::cs_insn*  insn;
      size_t                               count = 0;

      /* Check if the opcodes and opcodes' size are defined */
      if (inst.getOpcodes() == nullptr || inst.getSize() == 0)
        throw std::runtime_error("x86Cpu::disassembly(): Opcodes and opcodesSize must be definied.");

      /* Open capstone */
      if (triton::extlibs::capstone::cs_open(triton::extlibs::capstone::CS_ARCH_X86, triton::extlibs::capstone::CS_MODE_32, &handle) != triton::extlibs::capstone::CS_ERR_OK)
        throw std::runtime_error("x86Cpu::disassembly(): Cannot open capstone.");

      /* Init capstone's options */
      triton::extlibs::capstone::cs_option(handle, triton::extlibs::capstone::CS_OPT_DETAIL, triton::extlibs::capstone::CS_OPT_ON);
      triton::extlibs::capstone::cs_option(handle, triton::extlibs::capstone::CS_OPT_SYNTAX, triton::extlibs::capstone::CS_OPT_SYNTAX_INTEL);

      /* Let's disass and build our operands */
      count = triton::extlibs::capstone::cs_disasm(handle, inst.getOpcodes(), inst.getSize(), inst.getAddress(), 0, &insn);
      if (count > 0) {
        triton::extlibs::capstone::cs_detail* detail = insn->detail;
        for (triton::uint32 j = 0; j < 1; j++) {

          /* Init the disassembly */
          std::stringstream str;
          str << insn[j].mnemonic << " " <<  insn[j].op_str;
          inst.setDisassembly(str.str());

          /* Refine the size */
          inst.setSize(insn[j].size);

          /* Init the instruction's type */
          inst.setType(capstoneInstructionToTritonInstruction(insn[j].id));

          /* Init the instruction's prefix */
          inst.setPrefix(capstonePrefixToTritonPrefix(detail->x86.prefix[0]));

          /* Init operands */
          for (triton::uint32 n = 0; n < detail->x86.op_count; n++) {
            triton::extlibs::capstone::cs_x86_op* op = &(detail->x86.operands[n]);
            switch(op->type) {

              case triton::extlibs::capstone::X86_OP_IMM:
                inst.operands.push_back(triton::arch::OperandWrapper(triton::arch::ImmediateOperand(op->imm, op->size)));
                break;

              case triton::extlibs::capstone::X86_OP_MEM: {
                triton::arch::MemoryOperand mem = inst.popMemoryAccess();

                /* Set the size if the memory is not valid */
                if (!mem.isValid())
                  mem.setPair(std::make_pair(((op->size * BYTE_SIZE_BIT) - 1), 0));

                /* LEA if exists */
                triton::arch::RegisterOperand segment(triton::arch::x86::capstoneRegisterToTritonRegister(op->mem.segment));
                triton::arch::RegisterOperand base(triton::arch::x86::capstoneRegisterToTritonRegister(op->mem.base));
                triton::arch::RegisterOperand index(triton::arch::x86::capstoneRegisterToTritonRegister(op->mem.index));
                triton::arch::ImmediateOperand disp(op->mem.disp, op->size);
                triton::arch::ImmediateOperand scale(op->mem.scale, op->size);

                /* Specify that LEA contains a PC relative */
                if (base == TRITON_X86_REG_PC)
                  mem.setPcRelative(inst.getNextAddress());

                mem.setSegmentRegister(segment);
                mem.setBaseRegister(base);
                mem.setIndexRegister(index);
{'fraction_non_alphanumeric': 0.18762448740480375, 'fraction_numerical': 0.05439367311072056, 'mean_word_length': 4.2439136779049225, 'pattern_counts': {'":': 0, '<': 65, '<?xml version=': 0, '>': 587, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5266211', 'n_tokens_mistral': 28398, 'n_tokens_neox': 25616, 'n_words': 2377}