/*
 * Pin calls this function to set the value of an emulated register.
 */
static VOID SetReg(unsigned toolRegId, THREADID tid, CONTEXT *ctxt, const VOID *data, VOID *)
{
    PrintEmulated();

    switch (toolRegId)
    {
    case EMULATED_REG_RCX:
      {
        const ADDRINT *val = static_cast<const ADDRINT *>(data);
        PIN_SetContextReg(ctxt, REG_RCX, *val);
        break;
      }
    case EMULATED_REG_RSP:
      {
        const ADDRINT *val = static_cast<const ADDRINT *>(data);
        PIN_SetContextReg(ctxt, REG_RSP, *val);
        break;
      }
    case EMULATED_REG_FPSW:
      {
        const UINT32 *val = static_cast<const UINT32 *>(data);
        PIN_SetContextReg(ctxt, REG_FPSW, static_cast<ADDRINT>(*val));
        break;
      }
    case EMULATED_REG_ST0:
      {
        FPSTATE fpstate;
        PIN_GetContextFPState(ctxt, &fpstate);
        std::memcpy(&fpstate.fxsave_legacy._sts[0], data, 10);
        PIN_SetContextFPState(ctxt, &fpstate);
        break;
      }
    case EMULATED_REG_XMM0:
      {
        FPSTATE fpstate;
        PIN_GetContextFPState(ctxt, &fpstate);
        std::memcpy(&fpstate.fxsave_legacy._xmms[0], data, 16);
        PIN_SetContextFPState(ctxt, &fpstate);
        break;
      }
    default:
      {
        ASSERTX(0);
        break;
      }
    }
}
/*
 * Pin calls this function to get the value of an emulated register.
 */
static VOID GetReg(unsigned toolRegId, THREADID tid, CONTEXT *ctxt, VOID *data, VOID *)
{
    PrintEmulated();

    switch (toolRegId)
    {
    case EMULATED_REG_ECX:
      {
        ADDRINT *val = static_cast<ADDRINT *>(data);
        *val = PIN_GetContextReg(ctxt, REG_ECX);
        break;
      }
    case EMULATED_REG_ESP:
      {
        ADDRINT *val = static_cast<ADDRINT *>(data);
        *val = PIN_GetContextReg(ctxt, REG_ESP);
        break;
      }
    case EMULATED_REG_FPSW:
      {
        UINT32 *val = static_cast<UINT32 *>(data);
        *val = static_cast<UINT32>(PIN_GetContextReg(ctxt, REG_FPSW));
        break;
      }
    case EMULATED_REG_ST0:
      {
        FPSTATE fpstate;
        PIN_GetContextFPState(ctxt, &fpstate);
        std::memcpy(data, &fpstate.fxsave_legacy._sts[0], 10);
        break;
      }
    case EMULATED_REG_XMM0:
      {
        FPSTATE fpstate;
        PIN_GetContextFPState(ctxt, &fpstate);
        std::memcpy(data, &fpstate.fxsave_legacy._xmms[0], 16);
        break;
      }
    default:
      {
        ASSERTX(0);
        break;
      }
    }
}