Bool OptIC4(CIntermediateCode *tmpi)
{
    I64                  i;
    CIntermediateCode   *tmpil1, *tmpil2;

    if (tmpi->ic_code < IC_IMM_I64)
        return FALSE;

    tmpil1 = tmpi;
    if (!(tmpil2 = OptLag1(tmpil1)))
        return FALSE;

    if (tmpil2->res.type & MDF_STACK && !(tmpil2->ic_flags & ICF_PUSH_RES))
    {
        if (tmpil1->ic_code == IC_ADD_CONST && tmpil1->arg1.type & MDF_STACK)
        {
            if ((tmpil2->ic_code == IC_REG || tmpil2->ic_code == IC_MOV) && tmpil2->arg1.type & MDF_REG)
            {
                i = tmpil1->ic_data;
                if (I32_MIN <= i <= I32_MAX && !Bt(&cmp.non_ptr_vars_mask, tmpil2->arg1.reg))
                {
                    tmpil1->ic_flags |= tmpil2->ic_flags & ICG_NO_CONVERT_MASK;
                    tmpil1->ic_code = IC_LEA;
                    tmpil1->arg1.type = MDF_DISP + tmpil1->arg1.type.raw_type;
                    tmpil1->arg1.reg = tmpil2->arg1.reg;
                    tmpil1->arg1.disp = i;
                    OptFree(tmpil2);
                    return TRUE;
                }
            }
            else if (tmpil2->ic_code == IC_SHL_CONST && tmpil2->arg1.type & MDF_REG)
            {
                i = tmpil1->ic_data;
                if (I32_MIN <= i <= I32_MAX && tmpil2->arg1.reg != REG_RSP && 1 <= tmpil2->ic_data <= 3)
                {
                    tmpil1->ic_flags |= tmpil2->ic_flags & ICG_NO_CONVERT_MASK;
                    tmpil1->ic_code = IC_LEA;
                    tmpil1->arg1.type = MDF_SIB + tmpil1->arg1.type.raw_type;
                    tmpil1->arg1.reg = tmpil2->arg1.reg << 8 + REG_NONE;
                    if (tmpil2->ic_data == 1)
                        tmpil1->arg1.reg |= 0x4000;
                    else if (tmpil2->ic_data == 2)
                        tmpil1->arg1.reg |= 0x8000;
                    else
                        tmpil1->arg1.reg |= 0xC000;
                    tmpil1->arg1.disp = i;
                    OptFree(tmpil2);
                    return TRUE;
                }
            }
        }
        if (tmpil2->ic_code == IC_MOV || tmpil2->ic_code == IC_REG)
        {
            if (tmpil1->arg2.type & MDF_STACK)
            {
                if (tmpil2->ic_flags & ICF_RES_TO_INT)
                {
                    if (tmpil2->arg1.type & MDF_IMM)
                        tmpil2->arg1.disp = tmpil2->arg1.disp(F64);
                    else
                        tmpil1->ic_flags |= ICF_ARG2_TO_INT;
                }
                else if (tmpil2->ic_flags & ICF_RES_TO_F64)
                {
                    if (tmpil2->arg1.type & MDF_IMM)
                        tmpil2->arg1.disp(F64) = tmpil2->arg1.disp;
                    else
                        tmpil1->ic_flags |= ICF_ARG2_TO_F64;
                }
                tmpil1->arg2.type=tmpil2->arg1.type & MDG_MASK +
                            MinI64(tmpil1->arg2.type.raw_type, MinI64(tmpil2->res.type.raw_type, tmpil2->arg1.type.raw_type));
                tmpil1->arg2.reg = tmpil2->arg1.reg;
                tmpil1->arg2.disp = tmpil2->arg1.disp;
                tmpil1->ic_flags |= tmpil2->ic_flags & ICG_NO_CONVERT_MASK;
                OptSetNOP2(tmpil2);
                return TRUE;
            }
            if (tmpil1->arg1.type & MDF_STACK)
            {
                if (tmpil2->ic_flags & ICF_RES_TO_INT)
                {
                    if (tmpil2->arg1.type & MDF_IMM)
                        tmpil2->arg1.disp = tmpil2->arg1.disp(F64);
                    else
                        tmpil1->ic_flags |= ICF_ARG1_TO_INT;
                }
                else if (tmpil2->ic_flags & ICF_RES_TO_F64)
                {
                    if (tmpil2->arg1.type & MDF_IMM)
                    {
                        if (tmpil2->arg1.type & RTF_UNSIGNED)
                            tmpil2->arg1.disp(F64) = tmpil2->arg1.disp(U64);
                        else
                            tmpil2->arg1.disp(F64) = tmpil2->arg1.disp(I64);
                    }
                    else
                        tmpil1->ic_flags |= ICF_ARG1_TO_F64;
                }
                tmpil1->arg1.type = tmpil2->arg1.type & MDG_MASK +
                            MinI64(tmpil1->arg1.type.raw_type, MinI64(tmpil2->res.type.raw_type, tmpil2->arg1.type.raw_type));
                CompMinTypePointed(tmpil1, tmpil2->arg1_type_pointed_to);
                tmpil1->arg1.reg = tmpil2->arg1.reg;
                tmpil1->arg1.disp = tmpil2->arg1.disp;
                tmpil1->ic_flags |= tmpil2->ic_flags & ICG_NO_CONVERT_MASK;
                OptSetNOP2(tmpil2);
                return TRUE;
            }
        }
        if (tmpil1->ic_code == IC_DEREF)
        {
            if (tmpil2->ic_code == IC_ADD_CONST && tmpil2->arg1.type & MDF_REG && tmpil1->arg1.type & MDF_STACK)
            {
                i = tmpil2->ic_data;
                if (I32_MIN <= i <= I32_MAX && !Bt(&cmp.non_ptr_vars_mask, tmpil2->arg1.reg))
                {
                    tmpil1->ic_flags |= tmpil2->ic_flags;
                    tmpil1->ic_code = IC_MOV;
                    tmpil1->arg1.type = MDF_DISP  +tmpil1->arg1_type_pointed_to;
                    tmpil1->arg1.reg = tmpil2->arg1.reg;
                    tmpil1->arg1.disp = i;
                    OptSetNOP2(tmpil2, -1);
                    return TRUE;
                }
            }
            if (tmpil2->ic_code == IC_LEA && tmpil1->arg1.type & MDF_STACK)
            {
                tmpil1->ic_flags |= tmpil2->ic_flags;
                tmpil1->ic_code = IC_MOV;
                tmpil1->arg1.type = tmpil2->arg1.type & MDG_MASK + tmpil1->arg1_type_pointed_to;
                tmpil1->arg1.reg = tmpil2->arg1.reg;
                tmpil1->arg1.disp = tmpil2->arg1.disp;
                OptFree(tmpil2);
                return TRUE;
            }
        }
    }
    if (tmpil1->ic_code == IC_DEREF)
    {
        if (tmpil1->arg1.type & MDF_REG)
        {
            tmpil1->arg1.type = MDF_DISP + tmpil1->arg1_type_pointed_to;
            tmpil1->arg1.disp = 0;
            tmpil1->ic_code = IC_MOV;
            return TRUE;
        }
    }

    return FALSE;
}

U0 OptPass4(CCompCtrl *cc, COptReg *reg_offsets, I64 *_type)
{
    CHashClass          *tmpc, *tmpc1, *tmpc2;
    CIntermediateCode   *tmpi, *tmpi1, *tmpi2, *tmpil1, *tmpil2, *tmpil3, *tmpi_next;
    I64                  code, i;
    Bool                 dead_code = FALSE;
    CCodeMisc           *lb;
    CParseStack         *ps = cc->ps;

    ps->ptr = 0;
    ps->ptr2 = 0;

    if (_type)
        *_type = RT_I64;

    tmpi = cc->coc.coc_head.next;
    while (code = tmpi->ic_code)
    {
        tmpi_next = tmpi->next;
        if (dead_code && code != IC_LABEL)
        {
            if (code == IC_JMP || code == IC_SUB_CALL)
            {
                lb = OptLabelFwd(tmpi->ic_data);
                if (lb->use_count > 0)
                    lb->use_count--;
            }
            tmpi = OptFree(tmpi);
        }
        else
        {
            tmpc = tmpi->ic_class;
            tmpi1 = tmpi2 = &cmp.ic_nop;
            if (tmpil1 = OptLag2(tmpi))
            {
                if (tmpil2 = OptLag2(tmpil1))
                {
                    if (!(tmpil3 = OptLag2(tmpil2)))
                        tmpil3 = &cmp.ic_nop;
                }
                else
                    tmpil2 = tmpil3 = &cmp.ic_nop;
            }
            else
                tmpil1 = tmpil2 = tmpil3 = &cmp.ic_nop;
            switch [intermediate_code_table[code].arg_count]
            {
                case IS_V_ARG:
                    ps->ptr -= tmpi->ic_data >> 3;
                    break;

                case IS_2_ARG:
                    tmpi2 = ParsePop(ps);
                    tmpc2 = tmpi2->ic_class;
                case IS_1_ARG:
                    tmpi1 = ParsePop(ps);
                    tmpc1 = tmpi1->ic_class;
                    break;

                case IS_0_ARG: //nobound switch
                    break;
            }
            switch [code]
            {
                case IC_IMM_I64:
                case IC_TYPE:
                    tmpi->arg1.type = MDF_IMM + RT_I64;
                    tmpi->arg1.disp = tmpi->ic_data;
                    tmpi->ic_code = IC_MOV;
                    break;

                case IC_IMM_F64:
                    tmpi->arg1.type = MDF_IMM + RT_I64;
                    tmpi->arg1.disp = tmpi->ic_data;
                    tmpi->arg1_type_pointed_to = RT_F64;
                    tmpi->ic_code = IC_MOV;
                    break;

                case IC_MOV:
                    if (tmpi->arg1.type & MDF_DISP && tmpi->arg1.reg == REG_RBP)
                    {
                        i = CompOffset2Reg(tmpi->arg1.disp, reg_offsets);
                        if (i >= 0)
                        {
                            tmpi->arg1.type = MDF_REG + tmpi->arg1.type.raw_type;
                            tmpi->arg1.reg = i;
                            tmpi->arg1.disp = 0;
                        }
                    }
                    break;

                case IC_DEREF:
                    if (tmpi1->ic_code == IC_LEA)
                    {
                        if (tmpi1->arg1.type & MDF_DISP && tmpi1->arg1.reg == REG_RBP)
                        {
                            i = CompOffset2Reg(tmpi1->arg1.disp, reg_offsets);
                            if (i >= 0)
                            {
                                tmpi->ic_flags |= tmpi1->ic_flags;
                                tmpi->ic_code = IC_REG;
                                tmpi->arg1.type = MDF_REG + tmpi->arg1.type.raw_type;
                                tmpi->arg1.reg = i;
                                tmpi->arg1.disp = 0;
                                OptFree(tmpi1);
                            }
                        }
                    }
                    else if ((tmpi1->ic_code == IC_ABS_ADDR || tmpi1->ic_code == IC_MOV &&
                            tmpi1->arg1.type == MDF_IMM + RT_I64 &&
                            0 <= tmpi1->arg1.disp <= I32_MAX) && !(tmpi1->ic_flags & ICF_NO_RIP))
                    {
                        if (tmpi1->ic_code == IC_ABS_ADDR)
                            tmpi->arg1.disp = tmpi1->ic_data;
                        else
                            tmpi->arg1.disp = tmpi1->arg1.disp;
                        tmpi->ic_flags |= tmpi1->ic_flags;
                        tmpi->ic_code = IC_MOV;
                        tmpi->arg1.type = MDF_RIP_DISP32 + tmpi->arg1_type_pointed_to;
                        tmpi->arg1.reg = REG_RIP;
                        OptFree(tmpi1);
                    }
                    break;

                case IC_BR_MM_ZERO:
                case IC_BR_MM_NOT_ZERO:
//(branch ++ to zero is unlikely)
                case IC_DEREF_PP:
                case IC_DEREF_MM:
                case IC__PP:
                case IC__MM:
                case IC_PP_:
                case IC_MM_:
                    if (tmpi1->ic_code == IC_LEA)
                    {
                        if (tmpi1->arg1.type & MDF_DISP && tmpi1->arg1.reg == REG_RBP)
                        {
                            i = CompOffset2Reg(tmpi1->arg1.disp, reg_offsets);
                            if (i >= 0)
                            {
                                tmpi->ic_flags |= tmpi1->ic_flags;
                                tmpi->arg1.type = MDF_REG + tmpi->arg1.type.raw_type;
                                tmpi->arg1.reg = i;
                                tmpi->arg1.disp = 0;
                                tmpi->ic_flags |= ICF_BY_VAL;
                                OptSetNOP2(tmpi1);
                            }
                            else
                                goto p4_lea_gone;
                        }
                        else
                        {
p4_lea_gone:
                            tmpi->ic_flags |= tmpi1->ic_flags;
                            tmpi->arg1.type = tmpi1->arg1.type;
                            tmpi->arg1.reg = tmpi1->arg1.reg;
                            tmpi->arg1.disp = tmpi1->arg1.disp;
                            tmpi->ic_flags |= ICF_BY_VAL;
                            OptSetNOP2(tmpi1);
                        }
                    }
                    else if ((tmpi1->ic_code == IC_ABS_ADDR || tmpi1->ic_code == IC_MOV &&
                            tmpi1->arg1.type==MDF_IMM + RT_I64 &&
                            0 <= tmpi1->arg1.disp <= I32_MAX)&& !(tmpi1->ic_flags & ICF_NO_RIP))
                    {
                        tmpi->ic_flags |= tmpi1->ic_flags;
                        if (tmpi1->ic_code == IC_ABS_ADDR)
                            tmpi->arg1.disp = tmpi1->ic_data;
                        else
                            tmpi->arg1.disp = tmpi1->arg1.disp;
                        tmpi->arg1.type = MDF_RIP_DISP32 + tmpi->arg1_type_pointed_to;
                        tmpi->arg1.reg = REG_RIP;
                        tmpi->ic_flags |= ICF_BY_VAL;
                        OptFree(tmpi1);
                    }
                    break;

                case IC_ADD:
                    if (tmpi1->ic_code == IC_MOV && tmpi1->arg1.type == MDF_REG + RT_I64 || tmpi1->ic_code == IC_REG)
                    {
                        if (tmpi2->ic_code == IC_MOV && tmpi2->arg1.type == MDF_REG + RT_I64 || tmpi2->ic_code == IC_REG)
                        {
                            if (tmpi2->arg1.reg != REG_RSP)
                            {
                                tmpi->arg1.disp = 0;
                                tmpi->arg1.reg = tmpi1->arg1.reg + tmpi2->arg1.reg << 8;
                                goto p4_sib;
                            }
                            else if (tmpi1->arg1.reg != REG_RSP)
                            {
                                tmpi->arg1.disp = 0;
                                tmpi->arg1.reg = tmpi2->arg1.reg + tmpi1->arg1.reg << 8;
p4_sib:
                                tmpi->ic_flags |= (tmpi1->ic_flags | tmpi2->ic_flags) & ICG_NO_CONVERT_MASK;
                                OptSetNOP2(tmpi1);
                                OptFree(tmpi2);

                                tmpi->ic_code = IC_LEA;
                                tmpi->arg1.type = MDF_SIB+RT_I64;
                                tmpi->arg1_type_pointed_to = RT_I64;

                                tmpi->arg2.type = MDF_NULL + tmpi->arg2.type.raw_type;
                            }
                        }
                        else if (tmpi2->ic_code == IC_SHL_CONST &&
                                tmpi2->arg1.type == MDF_REG + RT_I64 && tmpi2->ic_data <= 3)
                        {
                            if (tmpi2->arg1.reg != REG_RSP)
                            {
                                tmpi->arg1.disp = 0;
                                tmpi->arg1.reg = tmpi1->arg1.reg + tmpi2->arg1.reg << 8;
                                if (tmpi2->ic_data == 1)
                                    tmpi->arg1.reg |= 0x4000;
                                else if (tmpi2->ic_data == 2)
                                    tmpi->arg1.reg |= 0x8000;
                                else
                                    tmpi->arg1.reg |= 0xC000;
                                goto p4_sib;
                            }
                        }
                    }
                    else if (tmpi1->ic_code == IC_LEA && tmpi1->arg1.type & MDF_DISP)
                    {
                        if (tmpi1->arg1.reg == REG_RBP && CompOffset2Reg(tmpi1->arg1.disp, reg_offsets) >= 0)
                            break;
                        if (tmpi2->ic_code == IC_MOV && tmpi2->arg1.type == MDF_REG + RT_I64 || tmpi2->ic_code == IC_REG)
                        {
                            if (tmpi2->arg1.reg != REG_RSP)
                            {
                                tmpi->arg1.disp = tmpi1->arg1.disp;
                                tmpi->arg1.reg = tmpi1->arg1.reg + tmpi2->arg1.reg << 8;
                                goto p4_sib;
                            }
                            else if (tmpi1->arg1.reg != REG_RSP)
                            {
                                tmpi->arg1.disp = tmpi1->arg1.disp;
                                tmpi->arg1.reg = tmpi2->arg1.reg + tmpi1->arg1.reg << 8;
                                goto p4_sib;
                            }
                        }
                        else if (tmpi2->ic_code == IC_SHL_CONST &&
                                tmpi2->arg1.type == MDF_REG + RT_I64 && tmpi2->ic_data <= 3)
                        {
                            if (tmpi2->arg1.reg != REG_RSP)
                            {
                                tmpi->arg1.disp = tmpi1->arg1.disp;
                                tmpi->arg1.reg = tmpi1->arg1.reg + tmpi2->arg1.reg << 8;
                                if (tmpi2->ic_data == 1)
                                    tmpi->arg1.reg |= 0x4000;
                                else if (tmpi2->ic_data == 2)
                                    tmpi->arg1.reg |= 0x8000;
                                else
                                    tmpi->arg1.reg |= 0xC000;
                                goto p4_sib;
                            }
                        }
                    }
                    break;

                case IC_ASSIGN_PP:
                case IC_ASSIGN_MM:
//this value was stashed during pass012 for pointer arithmetic
                    tmpi->ic_class2 = tmpi->t.class2; //See ic_class2
                case IC_ASSIGN:
                case IC_SHL_EQU:
                case IC_SHR_EQU:
                case IC_MUL_EQU:
                case IC_DIV_EQU:
                case IC_MOD_EQU:
                case IC_AND_EQU:
                case IC_OR_EQU:
                case IC_XOR_EQU:
                case IC_ADD_EQU:
                case IC_SUB_EQU:
                    if (tmpi1->ic_code == IC_LEA)
                    {
                        if (tmpi1->arg1.type & (MDF_DISP | MDF_SIB))
                        {
                            tmpi2 = tmpi->next;
                            if (tmpi1->arg1.type & MDF_DISP && tmpi1->arg1.reg == REG_RBP)
                            {
                                i = CompOffset2Reg(tmpi1->arg1.disp, reg_offsets);
                                if (i >= 0)
                                {
                                    tmpi->ic_flags |= tmpi1->ic_flags;
                                    tmpi->arg1.type = MDF_REG + tmpi->arg1.type.raw_type;
                                    tmpi->arg1.reg = i;
                                    tmpi->arg1.disp = 0;
                                    OptSetNOP2(tmpi1);
                                }
                                else
                                {
                                    tmpi->ic_flags |= tmpi1->ic_flags;
                                    tmpi->arg1.type = MDF_DISP + tmpi->arg1.type.raw_type;
                                    tmpi->arg1.reg = REG_RBP;
                                    tmpi->arg1.disp = tmpi1->arg1.disp;
                                    OptSetNOP2(tmpi1);
                                }
                            }
                            else
                            {
                                tmpi->ic_flags |= tmpi1->ic_flags;
                                tmpi->arg1.type = tmpi1->arg1.type & MDG_MASK + tmpi->arg1.type.raw_type;
                                tmpi->arg1.reg = tmpi1->arg1.reg;
                                tmpi->arg1.disp = tmpi1->arg1.disp;
                                OptSetNOP2(tmpi1);
                            }
                            if (tmpi->res.type & MDF_STACK && tmpi2->arg2.type & MDF_STACK &&
                                code != IC_ASSIGN_PP && code != IC_ASSIGN_MM)
                            {
                                tmpi->res.type = tmpi->arg1.type;
                                tmpi->res.reg = tmpi->arg1.reg;
                                tmpi->res.disp = tmpi->arg1.disp;
                                tmpi2->arg2.type = tmpi->arg1.type;
                                tmpi2->arg2.reg = tmpi->arg1.reg;
                                tmpi2->arg2.disp = tmpi->arg1.disp;
                                CompMinTypePointed(tmpi2, tmpi->arg1_type_pointed_to);
                            }
                            tmpi->ic_flags |= ICF_BY_VAL;
                        }
                    }
                    else if ((tmpi1->ic_code == IC_ABS_ADDR || tmpi1->ic_code == IC_MOV &&
                            tmpi1->arg1.type == MDF_IMM + RT_I64 &&
                            0 <= tmpi1->arg1.disp <= I32_MAX) && !(tmpi1->ic_flags & ICF_NO_RIP))
                    {
                        tmpi->ic_flags |= tmpi1->ic_flags;
                        if (tmpi1->ic_code == IC_ABS_ADDR)
                            tmpi->arg1.disp = tmpi1->ic_data;
                        else
                            tmpi->arg1.disp = tmpi1->arg1.disp;
                        tmpi->arg1.type = MDF_RIP_DISP32 + tmpi->arg1.type.raw_type;
                        tmpi->arg1.reg = REG_RIP;
                        tmpi->ic_flags |= ICF_BY_VAL;
                        OptSetNOP2(tmpi1);
                    }
                    break;

                case IC_RETURN_VAL:
                case IC_RETURN_VAL2:
                    if (!tmpi->ic_class)
                    {
                        if (_type)
                        {
                            tmpil1 = tmpi;
                            while (tmpil1 = OptLag1(tmpil1))
                                if (tmpil1->ic_class)
                                {
                                    if (tmpil1->ic_flags & ICF_RES_TO_F64)
                                        *_type = RT_F64;
                                    else if (tmpil1->ic_flags & ICF_RES_TO_INT)
                                        *_type = RT_I64;
                                    else
                                        *_type = tmpil1->ic_class->raw_type;
                                    break;
                                }
                        }
                        tmpi->ic_class = cmp.internal_types[RT_I64];
                    }
                    else if (_type)
                        *_type = tmpi->ic_class->raw_type;
                    break;

                case IC_NOP1:
                    tmpi = OptFree(tmpi);
                    break;

                case IC_BR_BT:
                case IC_BR_BTS:
                case IC_BR_BTR:
                case IC_BR_BTC:
                case IC_BR_NOT_BT:
                case IC_BR_NOT_BTS:
                case IC_BR_NOT_BTR:
                case IC_BR_NOT_BTC:
                case IC_BT:
                case IC_BTS:
                case IC_BTR:
                case IC_BTC:
                case IC_LBTS:
                case IC_LBTR:
                case IC_LBTC:
                    if (!(tmpi->ic_flags & ICF_BY_VAL))
                    {
                        if (tmpi2->ic_code == IC_ADDR)
                        {
                            if (tmpi2->arg1.type & MDF_STACK && tmpi2->res.type & MDF_STACK)
                            {
                                if (tmpil2 = OptLag1(tmpi2))
                                {
                                    if (tmpil2->ic_code == IC_LEA)
                                    {
                                        if (tmpil2->arg1.type & (MDF_IMM | MDG_REG_DISP_SIB_RIP))
                                        {
                                            if (tmpi2)
                                            {
                                                tmpi->ic_flags |= tmpi2->ic_flags;
                                                OptFree(tmpi2);
                                            }
                                            tmpi->ic_flags |= tmpil2->ic_flags | ICF_BY_VAL;
                                            tmpi->arg2.type = tmpil2->arg1.type;
                                            tmpi->arg2.reg  = tmpil2->arg1.reg;
                                            tmpi->arg2.disp = tmpil2->arg1.disp;
                                            OptFree(tmpil2);
                                        }
                                        break;
                                    }
                                    else if (tmpil2->ic_code != IC_ABS_ADDR && !(tmpil2->ic_code == IC_MOV &&
                                            tmpil2->arg1.type == MDF_IMM + RT_I64 && 0 <= tmpil2->arg1.disp <= I32_MAX) ||
                                            tmpil2->ic_flags & ICF_NO_RIP)
                                        tmpil2 = NULL;
                                    else
                                    {
                                        if (tmpil2->ic_code == IC_ABS_ADDR)
                                            tmpi->arg2.disp = tmpil2->ic_data;
                                        else
                                            tmpi->arg2.disp = tmpil2->arg1.disp;
                                    }
                                }
                            }
                            else
                            {
                                if (tmpi2->arg1.type == MDF_IMM + RT_I64 && 0 <= tmpi2->arg1.disp <= I32_MAX &&
                                    !(tmpi2->ic_flags & ICF_NO_RIP))
                                {
                                    tmpil2 = tmpi2;
                                    tmpi2 = NULL;
                                    tmpi->arg2.disp = tmpil2->arg1.disp;
                                }
                                else
                                    tmpil2 = NULL;
                            }
                            if (tmpil2)
                            {
                                if (tmpi2)
                                {
                                    tmpi->ic_flags |= tmpi2->ic_flags;
                                    OptFree(tmpi2);
                                }
                                tmpi->ic_flags |= tmpil2->ic_flags | ICF_BY_VAL;
                                tmpi->arg2.type = MDF_RIP_DISP32 + tmpi->arg2.type.raw_type;
                                tmpi->arg2.reg = REG_RIP;
                                OptFree(tmpil2);
                            }
                        }
                        else if (tmpi2->ic_code == IC_MOV && tmpi2->res.type & MDF_STACK &&
                                tmpi2->arg1.type == MDF_IMM + RT_I64 && 0 <= tmpi2->arg1.disp <= I32_MAX &&
                                    !(tmpi2->ic_flags & ICF_NO_RIP))
                        {
                            tmpi->arg2.disp = tmpi2->arg1.disp;
                            tmpi->ic_flags |= tmpi2->ic_flags | ICF_BY_VAL;
                            tmpi->arg2.type = MDF_RIP_DISP32 + tmpi->arg2.type.raw_type;
                            tmpi->arg2.reg  = REG_RIP;
                            OptFree(tmpi2);
                        }
                    }
                    break;

                case IC_BR_EQU_EQU ...IC_BR_LESS_EQU:
                case IC_BR_EQU_EQU2...IC_BR_LESS_EQU2:
                case IC_BR_CARRY:
                case IC_BR_NOT_CARRY:
                case IC_BR_ZERO:
                case IC_BR_NOT_ZERO:
                    lb = tmpi->ic_data;
                    if (tmpi->ic_flags & ICF_PUSH_CMP)
                    {
                        lb->flags |= CMF_POP_CMP;
                        lb->forward = NULL;
                    }
                    break;

                case IC_LABEL:
                    lb = tmpi->ic_data;
                    if (lb->use_count)
                        dead_code = FALSE;
                    break;

                case IC_JMP:
                case IC_RET:
                    dead_code = TRUE;
                    break;

                case IC_NOP2:
                    ps->ptr += tmpi->ic_data;
                    break;

                case IC_CALL_END:
                case IC_END_EXP:
                    if (!(tmpil1->ic_flags & ICF_PUSH_RES))
                    {
                        if (tmpi->ic_flags & ICF_RES_NOT_USED)
                        {
                            tmpil1->ic_flags |= ICF_RES_NOT_USED;
                            tmpil1->res.type = MDF_NULL + tmpil1->res.type.raw_type;
                        }
                        else if (tmpi->arg1.type & MDF_STACK && tmpil1->res.type & MDF_STACK)
                        {
                            tmpi->arg1.type = MDF_REG + tmpi->arg1.type.raw_type;
                            tmpi->arg1.disp = 0;
                            tmpil1->res.type = MDF_REG + tmpil1->res.type.raw_type;
                            tmpil1->res.disp = 0;
                            if (intermediate_code_table[tmpi->ic_code].arg_count == IS_2_ARG)
                            {
                                tmpi->arg1.reg = REG_R8;
                                tmpil1->res.reg = REG_R8;
                            }
                            else
                            {
                                tmpi->arg1.reg = REG_RAX;
                                tmpil1->res.reg = REG_RAX;
                            }
                        }
                    }
                    break;

                case IC_STR_CONST:
                case IC_FS:
                case IC_GS:
                case IC_MOV_FS:
                case IC_MOV_GS:
                case IC_RIP:
                case IC_RBP:
                case IC_REG:
                case IC_COM:
                case IC_POSTFIX_TYPECAST:
                case IC_NOT:
                case IC_UNARY_MINUS:
                case IC_PUSH_CMP:
                case IC_ADD_CONST:
                case IC_SUB_CONST:
                case IC_ENTER:
                case IC_ADD_RSP:
                case IC_ADD_RSP1:
                case IC_CALL:
                case IC_CALL_INDIRECT:
                case IC_CALL_INDIRECT2:
                case IC_CALL_EXTERN:
                case IC_CALL_IMPORT:
                case IC_PUSH:
                case IC_POP:
                case IC_INVLPG:
                case IC_CLFLUSH:
                case IC_RFLAGS_GET:
                case IC_CARRY:
                case IC_RDTSC:
                case IC_RFLAGS_SET:
                case IC_RBP_GET:
                case IC_RBP_SET:
                case IC_RSP_GET:
                case IC_RAX_GET:
                case IC_RSP_SET:
                case IC_RAX_SET:
                case IC_SHL_CONST:
                case IC_LEA:
                case IC_SHR_CONST:
                case IC_POWER:
                case IC_SHL:
                case IC_SHR:
                case IC_MUL:
                case IC_DIV:
                case IC_MOD:
                case IC_AND:
                case IC_OR:
                case IC_XOR:
                case IC_SUB:
                case IC_EQU_EQU...IC_LESS_EQU:
                case IC_AND_AND:
                case IC_OR_OR:
                case IC_XOR_XOR:
                case IC_GET_LABEL:
                case IC_ABS_ADDR:
                case IC_HEAP_GLOBAL:
                case IC_ADDR_IMPORT:
                case IC_BSF:
                case IC_BSR:
                case IC_POPCNT:
                case IC_SIGN_I64:
                case IC_TOUPPER:
                case IC_TO_I64:
                case IC_TO_F64:
                case IC_TO_BOOL:
                case IC_SQR:
                case IC_ABS:
                case IC_SQRT:
                case IC_SIN:
                case IC_COS:
                case IC_TAN:
                case IC_ATAN:
                case IC_ABS_I64:
                case IC_MIN_I64:
                case IC_MAX_I64:
                case IC_MIN_U64:
                case IC_MAX_U64:
                case IC_MOD_U64:
                case IC_SQR_I64:
                case IC_SQR_U64:
                case IC_SWAP_U8:
                case IC_SWAP_U16:
                case IC_SWAP_U32:
                case IC_SWAP_I64:
                case IC_QUEUE_INIT:
                case IC_QUEUE_INSERT:
                case IC_QUEUE_INSERT_REV:
                case IC_QUEUE_REMOVE:
                case IC_IN_U32:
                case IC_IN_U16:
                case IC_IN_U8:
                case IC_STRLEN:
                case IC_OUT_U32:
                case IC_OUT_U16:
                case IC_OUT_U8:
                case IC_NOBOUND_SWITCH:
                case IC_SWITCH:
                case IC_END:
                case IC_ADDR:
                case IC_CALL_START:
                case IC_LEAVE:
                case IC_PUSH_REGS:
                case IC_POP_REGS:
                case IC_ASM:
                case IC_BR_AND_NOT_ZERO:
                case IC_BR_AND_ZERO:
                case IC_SUB_CALL:
                case IC_CALL_END2:
                    break;

                default:
                    "Pass:%d Missing IC handler\n", cc->pass;
                    ICPut(cc, tmpi);
                    LexExcept(cc, "Compiler Optimization Error at ");
            }
            if (tmpi)
            {
                while (OptIC4(tmpi));
                code = tmpi->ic_code;
                if (intermediate_code_table[code].res_count)
                    ParsePush(ps, tmpi);
            }
        }
        tmpi = tmpi_next;
    }
    if (ps->ptr > 2)
    {
        "Pass:%d Stack:%08X\n", cc->pass, ps->ptr;
        LexExcept(cc, "Compiler Optimization Error at ");
    }
}