#define SHIFT(size, size2, res_store, immediate)                         \
        if ((fetchdat & 0xc0) == 0xc0)                                          \
        {                                                                       \
                reg = LOAD_REG_ ## size(fetchdat & 7);                          \
                if (immediate) count = (fetchdat >> 8) & 0x1f;                  \
        }                                                                       \
        else                                                                    \
        {                                                                       \
                target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);                                            \
                STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);                                                       \
                SAVE_EA();                                                                                                      \
                MEM_CHECK_WRITE_ ## size(target_seg);                                                                                              \
                reg = MEM_LOAD_ADDR_EA_ ## size ## _NO_ABRT(target_seg);                                                               \
                if (immediate) count = fastreadb(cs + op_pc + 1) & 0x1f;        \
        }                                                                       \
        STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, count);                          \
                                                                                \
        res_store((uintptr_t)&cpu_state.flags_op1, reg);                                   \
                                                                                \
        switch (fetchdat & 0x38)                                                \
        {                                                                       \
                case 0x20: case 0x30: /*SHL*/                                   \
                SHL_ ## size ## _IMM(reg, count);                               \
                STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SHL ## size2);      \
                break;                                                          \
                                                                                \
                case 0x28: /*SHR*/                                              \
                SHR_ ## size ## _IMM(reg, count);                               \
                STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SHR ## size2);      \
                break;                                                          \
                                                                                \
                case 0x38: /*SAR*/                                              \
                SAR_ ## size ## _IMM(reg, count);                               \
                STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SAR ## size2);      \
                break;                                                          \
        }                                                                       \
                                                                                \
        res_store((uintptr_t)&cpu_state.flags_res, reg);                                   \
        if ((fetchdat & 0xc0) == 0xc0)                                          \
                STORE_REG_ ## size ## _RELEASE(reg);                            \
        else                                                                    \
        {                                                                       \
                LOAD_EA();                                                      \
                MEM_STORE_ADDR_EA_ ## size ## _NO_ABRT(target_seg, reg);        \
        }

static uint32_t ropC0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
        x86seg *target_seg = NULL;
        int count;
        int reg;

        if ((fetchdat & 0x38) < 0x20)
                return 0;

        SHIFT(B, 8, STORE_HOST_REG_ADDR_BL, 1);

        return op_pc + 2;
}
static uint32_t ropC1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
        x86seg *target_seg = NULL;
        int count;
        int reg;

        if ((fetchdat & 0x38) < 0x20)
                return 0;

        SHIFT(W, 16, STORE_HOST_REG_ADDR_WL, 1);

        return op_pc + 2;
}
static uint32_t ropC1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
        x86seg *target_seg = NULL;
        int count;
        int reg;

        if ((fetchdat & 0x38) < 0x20)
                return 0;

        SHIFT(L, 32, STORE_HOST_REG_ADDR, 1);

        return op_pc + 2;
}

static uint32_t ropD0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
        x86seg *target_seg = NULL;
        int count = 1;
        int reg;

        if ((fetchdat & 0x38) < 0x20)
                return 0;

        SHIFT(B, 8, STORE_HOST_REG_ADDR_BL, 0);

        return op_pc + 1;
}
static uint32_t ropD1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
        x86seg *target_seg = NULL;
        int count = 1;
        int reg;

        if ((fetchdat & 0x38) < 0x20)
                return 0;

        SHIFT(W, 16, STORE_HOST_REG_ADDR_WL, 0);

        return op_pc + 1;
}
static uint32_t ropD1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
        x86seg *target_seg = NULL;
        int count = 1;
        int reg;

        if ((fetchdat & 0x38) < 0x20)
                return 0;

        SHIFT(L, 32, STORE_HOST_REG_ADDR, 0);

        return op_pc + 1;
}
