Annotation of qemu/target-cris/op.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *  CRIS emulation micro-operations for qemu.
                      3:  *
                      4:  *  Copyright (c) 2007 Edgar E. Iglesias, Axis Communications AB.
                      5:  *
                      6:  * This library is free software; you can redistribute it and/or
                      7:  * modify it under the terms of the GNU Lesser General Public
                      8:  * License as published by the Free Software Foundation; either
                      9:  * version 2 of the License, or (at your option) any later version.
                     10:  *
                     11:  * This library is distributed in the hope that it will be useful,
                     12:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     14:  * Lesser General Public License for more details.
                     15:  *
                     16:  * You should have received a copy of the GNU Lesser General Public
                     17:  * License along with this library; if not, write to the Free Software
                     18:  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     19:  */
                     20: #include "exec.h"
                     21: #include "host-utils.h"
                     22: 
                     23: #define REGNAME r0
                     24: #define REG (env->regs[0])
                     25: #include "op_template.h"
                     26: 
                     27: #define REGNAME r1
                     28: #define REG (env->regs[1])
                     29: #include "op_template.h"
                     30: 
                     31: #define REGNAME r2
                     32: #define REG (env->regs[2])
                     33: #include "op_template.h"
                     34: 
                     35: #define REGNAME r3
                     36: #define REG (env->regs[3])
                     37: #include "op_template.h"
                     38: 
                     39: #define REGNAME r4
                     40: #define REG (env->regs[4])
                     41: #include "op_template.h"
                     42: 
                     43: #define REGNAME r5
                     44: #define REG (env->regs[5])
                     45: #include "op_template.h"
                     46: 
                     47: #define REGNAME r6
                     48: #define REG (env->regs[6])
                     49: #include "op_template.h"
                     50: 
                     51: #define REGNAME r7
                     52: #define REG (env->regs[7])
                     53: #include "op_template.h"
                     54: 
                     55: #define REGNAME r8
                     56: #define REG (env->regs[8])
                     57: #include "op_template.h"
                     58: 
                     59: #define REGNAME r9
                     60: #define REG (env->regs[9])
                     61: #include "op_template.h"
                     62: 
                     63: #define REGNAME r10
                     64: #define REG (env->regs[10])
                     65: #include "op_template.h"
                     66: 
                     67: #define REGNAME r11
                     68: #define REG (env->regs[11])
                     69: #include "op_template.h"
                     70: 
                     71: #define REGNAME r12
                     72: #define REG (env->regs[12])
                     73: #include "op_template.h"
                     74: 
                     75: #define REGNAME r13
                     76: #define REG (env->regs[13])
                     77: #include "op_template.h"
                     78: 
                     79: #define REGNAME r14
                     80: #define REG (env->regs[14])
                     81: #include "op_template.h"
                     82: 
                     83: #define REGNAME r15
                     84: #define REG (env->regs[15])
                     85: #include "op_template.h"
                     86: 
                     87: 
                     88: #define REGNAME p0
                     89: #define REG (env->pregs[0])
                     90: #include "op_template.h"
                     91: 
                     92: #define REGNAME p1
                     93: #define REG (env->pregs[1])
                     94: #include "op_template.h"
                     95: 
                     96: #define REGNAME p2
                     97: #define REG (env->pregs[2])
                     98: #include "op_template.h"
                     99: 
                    100: #define REGNAME p3
                    101: #define REG (env->pregs[3])
                    102: #include "op_template.h"
                    103: 
                    104: #define REGNAME p4
                    105: #define REG (env->pregs[4])
                    106: #include "op_template.h"
                    107: 
                    108: #define REGNAME p5
                    109: #define REG (env->pregs[5])
                    110: #include "op_template.h"
                    111: 
                    112: #define REGNAME p6
                    113: #define REG (env->pregs[6])
                    114: #include "op_template.h"
                    115: 
                    116: #define REGNAME p7
                    117: #define REG (env->pregs[7])
                    118: #include "op_template.h"
                    119: 
                    120: #define REGNAME p8
                    121: #define REG (env->pregs[8])
                    122: #include "op_template.h"
                    123: 
                    124: #define REGNAME p9
                    125: #define REG (env->pregs[9])
                    126: #include "op_template.h"
                    127: 
                    128: #define REGNAME p10
                    129: #define REG (env->pregs[10])
                    130: #include "op_template.h"
                    131: 
                    132: #define REGNAME p11
                    133: #define REG (env->pregs[11])
                    134: #include "op_template.h"
                    135: 
                    136: #define REGNAME p12
                    137: #define REG (env->pregs[12])
                    138: #include "op_template.h"
                    139: 
                    140: #define REGNAME p13
                    141: #define REG (env->pregs[13])
                    142: #include "op_template.h"
                    143: 
                    144: #define REGNAME p14
                    145: #define REG (env->pregs[14])
                    146: #include "op_template.h"
                    147: 
                    148: #define REGNAME p15
                    149: #define REG (env->pregs[15])
                    150: #include "op_template.h"
                    151: 
                    152: /* Microcode.  */
                    153: 
                    154: void OPPROTO op_exit_tb (void)
                    155: {
                    156:        EXIT_TB();
                    157: }
                    158: 
                    159: void OPPROTO op_goto_tb0 (void)
                    160: {
                    161:        GOTO_TB(op_goto_tb0, PARAM1, 0);
                    162:        RETURN();
                    163: }
                    164: 
                    165: void OPPROTO op_goto_tb1 (void)
                    166: {
                    167:        GOTO_TB(op_goto_tb1, PARAM1, 1);
                    168:        RETURN();
                    169: }
                    170: 
                    171: void OPPROTO op_break_im(void)
                    172: {
                    173:        env->trapnr = PARAM1;
                    174:        env->exception_index = EXCP_BREAK;
                    175:        cpu_loop_exit();
                    176: }
                    177: 
                    178: void OPPROTO op_debug(void)
                    179: {
                    180:        env->exception_index = EXCP_DEBUG;
                    181:        cpu_loop_exit();
                    182: }
                    183: 
                    184: void OPPROTO op_exec_insn(void)
                    185: {
                    186:        env->stats.exec_insns++;
                    187:        RETURN();
                    188: }
                    189: void OPPROTO op_exec_load(void)
                    190: {
                    191:        env->stats.exec_loads++;
                    192:        RETURN();
                    193: }
                    194: void OPPROTO op_exec_store(void)
                    195: {
                    196:        env->stats.exec_stores++;
                    197:        RETURN();
                    198: }
                    199: 
                    200: void OPPROTO op_ccs_lshift (void)
                    201: {
                    202:        uint32_t ccs;
                    203: 
                    204:        /* Apply the ccs shift.  */
                    205:        ccs = env->pregs[SR_CCS];
                    206:        ccs = (ccs & 0xc0000000) | ((ccs << 12) >> 2);
                    207:        env->pregs[SR_CCS] = ccs;
                    208: }
                    209: void OPPROTO op_ccs_rshift (void)
                    210: {
                    211:        uint32_t ccs;
                    212: 
                    213:        /* Apply the ccs shift.  */
                    214:        ccs = env->pregs[SR_CCS];
                    215:        ccs = (ccs & 0xc0000000) | (ccs >> 10);
                    216:        env->pregs[SR_CCS] = ccs;
                    217: }
                    218: 
                    219: void OPPROTO op_setf (void)
                    220: {
                    221:        env->pregs[SR_CCS] |= PARAM1;
                    222:        RETURN();
                    223: }
                    224: 
                    225: void OPPROTO op_clrf (void)
                    226: {
                    227:        env->pregs[SR_CCS] &= ~PARAM1;
                    228:        RETURN();
                    229: }
                    230: 
                    231: void OPPROTO op_movl_debug1_T0 (void)
                    232: {
                    233:        env->debug1 = T0;
                    234:        RETURN();
                    235: }
                    236: 
                    237: void OPPROTO op_movl_debug2_T0 (void)
                    238: {
                    239:        env->debug2 = T0;
                    240:        RETURN();
                    241: }
                    242: 
                    243: void OPPROTO op_movl_debug3_T0 (void)
                    244: {
                    245:        env->debug3 = T0;
                    246:        RETURN();
                    247: }
                    248: void OPPROTO op_movl_debug1_T1 (void)
                    249: {
                    250:        env->debug1 = T1;
                    251:        RETURN();
                    252: }
                    253: 
                    254: void OPPROTO op_movl_debug2_T1 (void)
                    255: {
                    256:        env->debug2 = T1;
                    257:        RETURN();
                    258: }
                    259: 
                    260: void OPPROTO op_movl_debug3_T1 (void)
                    261: {
                    262:        env->debug3 = T1;
                    263:        RETURN();
                    264: }
                    265: void OPPROTO op_movl_debug3_im (void)
                    266: {
                    267:        env->debug3 = PARAM1;
                    268:        RETURN();
                    269: }
                    270: void OPPROTO op_movl_T0_flags (void)
                    271: {
                    272:        T0 = env->pregs[SR_CCS];
                    273:        RETURN();
                    274: }
                    275: void OPPROTO op_movl_flags_T0 (void)
                    276: {
                    277:        env->pregs[SR_CCS] = T0;
                    278:        RETURN();
                    279: }
                    280: 
                    281: void OPPROTO op_movl_sreg_T0 (void)
                    282: {
                    283:        env->sregs[env->pregs[SR_SRS]][PARAM1] = T0;
                    284:        RETURN();
                    285: }
                    286: 
                    287: void OPPROTO op_movl_tlb_lo_T0 (void)
                    288: {
                    289:        int srs;
                    290:        srs = env->pregs[SR_SRS];
                    291:        if (srs == 1 || srs == 2)
                    292:        {
                    293:                int set;
                    294:                int idx;
                    295:                uint32_t lo, hi;
                    296: 
                    297:                idx = set = env->sregs[SFR_RW_MM_TLB_SEL];
                    298:                set >>= 4;
                    299:                set &= 3;
                    300: 
                    301:                idx &= 31;
                    302:                /* We've just made a write to tlb_lo.  */
                    303:                lo = env->sregs[SFR_RW_MM_TLB_LO];
                    304:                hi = env->sregs[SFR_RW_MM_TLB_HI];
                    305:                env->tlbsets[srs - 1][set][idx].lo = lo;
                    306:                env->tlbsets[srs - 1][set][idx].hi = hi;
                    307:        }
                    308: 
                    309:        RETURN();
                    310: }
                    311: 
                    312: void OPPROTO op_movl_T0_sreg (void)
                    313: {
                    314:        T0 = env->sregs[env->pregs[SR_SRS]][PARAM1];
                    315:        RETURN();
                    316: }
                    317: 
                    318: void OPPROTO op_update_cc (void)
                    319: {
                    320:        env->cc_op = PARAM1;
                    321:        env->cc_dest = PARAM2;
                    322:        env->cc_src = PARAM3;
                    323:        RETURN();
                    324: }
                    325: 
                    326: void OPPROTO op_update_cc_op (void)
                    327: {
                    328:        env->cc_op = PARAM1;
                    329:        RETURN();
                    330: }
                    331: 
                    332: void OPPROTO op_update_cc_mask (void)
                    333: {
                    334:        env->cc_mask = PARAM1;
                    335:        RETURN();
                    336: }
                    337: 
                    338: void OPPROTO op_update_cc_dest_T0 (void)
                    339: {
                    340:        env->cc_dest = T0;
                    341:        RETURN();
                    342: }
                    343: 
                    344: void OPPROTO op_update_cc_result_T0 (void)
                    345: {
                    346:        env->cc_result = T0;
                    347:        RETURN();
                    348: }
                    349: 
                    350: void OPPROTO op_update_cc_size_im (void)
                    351: {
                    352:        env->cc_size = PARAM1;
                    353:        RETURN();
                    354: }
                    355: 
                    356: void OPPROTO op_update_cc_src_T1 (void)
                    357: {
                    358:        env->cc_src = T1;
                    359:        RETURN();
                    360: }
                    361: void OPPROTO op_update_cc_x (void)
                    362: {
                    363:        env->cc_x_live = PARAM1;
                    364:        env->cc_x = PARAM2;
                    365:        RETURN();
                    366: }
                    367: 
                    368: /* FIXME: is this allowed?  */
                    369: extern inline void evaluate_flags_writeback(uint32_t flags)
                    370: {
                    371:        int x;
                    372: 
                    373:        /* Extended arithmetics, leave the z flag alone.  */
                    374:        env->debug3 = env->pregs[SR_CCS];
                    375: 
                    376:        if (env->cc_x_live)
                    377:                x = env->cc_x;
                    378:        else
                    379:                x = env->pregs[SR_CCS] & X_FLAG;
                    380: 
                    381:        if ((x || env->cc_op == CC_OP_ADDC)
                    382:            && flags & Z_FLAG)
                    383:                env->cc_mask &= ~Z_FLAG;
                    384: 
                    385:        /* all insn clear the x-flag except setf or clrf.  */
                    386:        env->pregs[SR_CCS] &= ~(env->cc_mask | X_FLAG);
                    387:        flags &= env->cc_mask;
                    388:        env->pregs[SR_CCS] |= flags;
                    389:        RETURN();
                    390: }
                    391: 
                    392: void OPPROTO op_evaluate_flags_muls(void)
                    393: {
                    394:        uint32_t src;
                    395:        uint32_t dst;
                    396:        uint32_t res;
                    397:        uint32_t flags = 0;
                    398:        /* were gonna have to redo the muls.  */
                    399:        int64_t tmp, t0 ,t1;
                    400:        int32_t mof;
                    401:        int dneg;
                    402: 
                    403:        src = env->cc_src;
                    404:        dst = env->cc_dest;
                    405:        res = env->cc_result;
                    406: 
                    407: 
                    408:        /* cast into signed values to make GCC sign extend.  */
                    409:        t0 = (int32_t)src;
                    410:        t1 = (int32_t)dst;
                    411:        dneg = ((int32_t)res) < 0;
                    412: 
                    413:        tmp = t0 * t1;
                    414:        mof = tmp >> 32;
                    415:        if (tmp == 0)
                    416:                flags |= Z_FLAG;
                    417:        else if (tmp < 0)
                    418:                flags |= N_FLAG;
                    419:        if ((dneg && mof != -1)
                    420:            || (!dneg && mof != 0))
                    421:                flags |= V_FLAG;
                    422:        evaluate_flags_writeback(flags);
                    423:        RETURN();
                    424: }
                    425: 
                    426: void OPPROTO op_evaluate_flags_mulu(void)
                    427: {
                    428:        uint32_t src;
                    429:        uint32_t dst;
                    430:        uint32_t res;
                    431:        uint32_t flags = 0;
                    432:        /* were gonna have to redo the muls.  */
                    433:        uint64_t tmp, t0 ,t1;
                    434:        uint32_t mof;
                    435: 
                    436:        src = env->cc_src;
                    437:        dst = env->cc_dest;
                    438:        res = env->cc_result;
                    439: 
                    440: 
                    441:        /* cast into signed values to make GCC sign extend.  */
                    442:        t0 = src;
                    443:        t1 = dst;
                    444: 
                    445:        tmp = t0 * t1;
                    446:        mof = tmp >> 32;
                    447:        if (tmp == 0)
                    448:                flags |= Z_FLAG;
                    449:        else if (tmp >> 63)
                    450:                flags |= N_FLAG;
                    451:        if (mof)
                    452:                flags |= V_FLAG;
                    453: 
                    454:        evaluate_flags_writeback(flags);
                    455:        RETURN();
                    456: }
                    457: 
                    458: void OPPROTO op_evaluate_flags_mcp(void)
                    459: {
                    460:        uint32_t src;
                    461:        uint32_t dst;
                    462:        uint32_t res;
                    463:        uint32_t flags = 0;
                    464: 
                    465:        src = env->cc_src;
                    466:        dst = env->cc_dest;
                    467:        res = env->cc_result;
                    468: 
                    469:        if ((res & 0x80000000L) != 0L)
                    470:        {
                    471:                flags |= N_FLAG;
                    472:                if (((src & 0x80000000L) == 0L)
                    473:                    && ((dst & 0x80000000L) == 0L))
                    474:                {
                    475:                        flags |= V_FLAG;
                    476:                }
                    477:                else if (((src & 0x80000000L) != 0L) &&
                    478:                         ((dst & 0x80000000L) != 0L))
                    479:                {
                    480:                        flags |= R_FLAG;
                    481:                }
                    482:        }
                    483:        else
                    484:        {
                    485:                if (res == 0L)
                    486:                        flags |= Z_FLAG;
                    487:                if (((src & 0x80000000L) != 0L)
                    488:                    && ((dst & 0x80000000L) != 0L))
                    489:                        flags |= V_FLAG;
                    490:                if ((dst & 0x80000000L) != 0L
                    491:                    || (src & 0x80000000L) != 0L)
                    492:                        flags |= R_FLAG;
                    493:        }
                    494: 
                    495:        evaluate_flags_writeback(flags);
                    496:        RETURN();
                    497: }
                    498: 
                    499: void OPPROTO op_evaluate_flags_alu_4(void)
                    500: {
                    501:        uint32_t src;
                    502:        uint32_t dst;
                    503:        uint32_t res;
                    504:        uint32_t flags = 0;
                    505: 
                    506:        src = env->cc_src;
                    507:        dst = env->cc_dest;
                    508:        res = env->cc_result;
                    509: 
                    510:        if ((res & 0x80000000L) != 0L)
                    511:        {
                    512:                flags |= N_FLAG;
                    513:                if (((src & 0x80000000L) == 0L)
                    514:                    && ((dst & 0x80000000L) == 0L))
                    515:                {
                    516:                        flags |= V_FLAG;
                    517:                }
                    518:                else if (((src & 0x80000000L) != 0L) &&
                    519:                         ((dst & 0x80000000L) != 0L))
                    520:                {
                    521:                        flags |= C_FLAG;
                    522:                }
                    523:        }
                    524:        else
                    525:        {
                    526:                if (res == 0L)
                    527:                        flags |= Z_FLAG;
                    528:                if (((src & 0x80000000L) != 0L)
                    529:                    && ((dst & 0x80000000L) != 0L))
                    530:                        flags |= V_FLAG;
                    531:                if ((dst & 0x80000000L) != 0L
                    532:                    || (src & 0x80000000L) != 0L)
                    533:                        flags |= C_FLAG;
                    534:        }
                    535: 
                    536:        if (env->cc_op == CC_OP_SUB
                    537:            || env->cc_op == CC_OP_CMP) {
                    538:                flags ^= C_FLAG;
                    539:        }
                    540:        evaluate_flags_writeback(flags);
                    541:        RETURN();
                    542: }
                    543: 
                    544: void OPPROTO op_evaluate_flags_move_4 (void)
                    545: {
                    546:        uint32_t src;
                    547:        uint32_t res;
                    548:        uint32_t flags = 0;
                    549: 
                    550:        src = env->cc_src;
                    551:        res = env->cc_result;
                    552: 
                    553:        if ((int32_t)res < 0)
                    554:                flags |= N_FLAG;
                    555:        else if (res == 0L)
                    556:                flags |= Z_FLAG;
                    557: 
                    558:        evaluate_flags_writeback(flags);
                    559:        RETURN();
                    560: }
                    561: void OPPROTO op_evaluate_flags_move_2 (void)
                    562: {
                    563:        uint32_t src;
                    564:        uint32_t flags = 0;
                    565:        uint16_t res;
                    566: 
                    567:        src = env->cc_src;
                    568:        res = env->cc_result;
                    569: 
                    570:        if ((int16_t)res < 0L)
                    571:                flags |= N_FLAG;
                    572:        else if (res == 0)
                    573:                flags |= Z_FLAG;
                    574: 
                    575:        evaluate_flags_writeback(flags);
                    576:        RETURN();
                    577: }
                    578: 
                    579: /* TODO: This is expensive. We could split things up and only evaluate part of
                    580:    CCR on a need to know basis. For now, we simply re-evaluate everything.  */
                    581: void OPPROTO op_evaluate_flags (void)
                    582: {
                    583:        uint32_t src;
                    584:        uint32_t dst;
                    585:        uint32_t res;
                    586:        uint32_t flags = 0;
                    587: 
                    588:        src = env->cc_src;
                    589:        dst = env->cc_dest;
                    590:        res = env->cc_result;
                    591: 
                    592: 
                    593:        /* Now, evaluate the flags. This stuff is based on
                    594:           Per Zander's CRISv10 simulator.  */
                    595:        switch (env->cc_size)
                    596:        {
                    597:                case 1:
                    598:                        if ((res & 0x80L) != 0L)
                    599:                        {
                    600:                                flags |= N_FLAG;
                    601:                                if (((src & 0x80L) == 0L)
                    602:                                    && ((dst & 0x80L) == 0L))
                    603:                                {
                    604:                                        flags |= V_FLAG;
                    605:                                }
                    606:                                else if (((src & 0x80L) != 0L)
                    607:                                         && ((dst & 0x80L) != 0L))
                    608:                                {
                    609:                                        flags |= C_FLAG;
                    610:                                }
                    611:                        }
                    612:                        else
                    613:                        {
                    614:                                if ((res & 0xFFL) == 0L)
                    615:                                {
                    616:                                        flags |= Z_FLAG;
                    617:                                }
                    618:                                if (((src & 0x80L) != 0L)
                    619:                                    && ((dst & 0x80L) != 0L))
                    620:                                {
                    621:                                        flags |= V_FLAG;
                    622:                                }
                    623:                                if ((dst & 0x80L) != 0L
                    624:                                    || (src & 0x80L) != 0L)
                    625:                                {
                    626:                                        flags |= C_FLAG;
                    627:                                }
                    628:                        }
                    629:                        break;
                    630:                case 2:
                    631:                        if ((res & 0x8000L) != 0L)
                    632:                        {
                    633:                                flags |= N_FLAG;
                    634:                                if (((src & 0x8000L) == 0L)
                    635:                                    && ((dst & 0x8000L) == 0L))
                    636:                                {
                    637:                                        flags |= V_FLAG;
                    638:                                }
                    639:                                else if (((src & 0x8000L) != 0L)
                    640:                                         && ((dst & 0x8000L) != 0L))
                    641:                                {
                    642:                                        flags |= C_FLAG;
                    643:                                }
                    644:                        }
                    645:                        else
                    646:                        {
                    647:                                if ((res & 0xFFFFL) == 0L)
                    648:                                {
                    649:                                        flags |= Z_FLAG;
                    650:                                }
                    651:                                if (((src & 0x8000L) != 0L)
                    652:                                    && ((dst & 0x8000L) != 0L))
                    653:                                {
                    654:                                        flags |= V_FLAG;
                    655:                                }
                    656:                                if ((dst & 0x8000L) != 0L
                    657:                                    || (src & 0x8000L) != 0L)
                    658:                                {
                    659:                                        flags |= C_FLAG;
                    660:                                }
                    661:                        }
                    662:                        break;
                    663:                case 4:
                    664:                        if ((res & 0x80000000L) != 0L)
                    665:                        {
                    666:                                flags |= N_FLAG;
                    667:                                if (((src & 0x80000000L) == 0L)
                    668:                                    && ((dst & 0x80000000L) == 0L))
                    669:                                {
                    670:                                        flags |= V_FLAG;
                    671:                                }
                    672:                                else if (((src & 0x80000000L) != 0L) &&
                    673:                                         ((dst & 0x80000000L) != 0L))
                    674:                                {
                    675:                                        flags |= C_FLAG;
                    676:                                }
                    677:                        }
                    678:                        else
                    679:                        {
                    680:                                if (res == 0L)
                    681:                                        flags |= Z_FLAG;
                    682:                                if (((src & 0x80000000L) != 0L)
                    683:                                    && ((dst & 0x80000000L) != 0L))
                    684:                                        flags |= V_FLAG;
                    685:                                if ((dst & 0x80000000L) != 0L
                    686:                                    || (src & 0x80000000L) != 0L)
                    687:                                        flags |= C_FLAG;
                    688:                        }
                    689:                        break;
                    690:                default:
                    691:                        break;
                    692:        }
                    693: 
                    694:        if (env->cc_op == CC_OP_SUB
                    695:            || env->cc_op == CC_OP_CMP) {
                    696:                flags ^= C_FLAG;
                    697:        }
                    698:        evaluate_flags_writeback(flags);
                    699:        RETURN();
                    700: }
                    701: 
                    702: void OPPROTO op_extb_T0_T0 (void)
                    703: {
                    704:        T0 = ((int8_t)T0);
                    705:        RETURN();
                    706: }
                    707: void OPPROTO op_extb_T1_T0 (void)
                    708: {
                    709:        T1 = ((int8_t)T0);
                    710:        RETURN();
                    711: }
                    712: void OPPROTO op_extb_T1_T1 (void)
                    713: {
                    714:        T1 = ((int8_t)T1);
                    715:        RETURN();
                    716: }
                    717: void OPPROTO op_zextb_T0_T0 (void)
                    718: {
                    719:        T0 = ((uint8_t)T0);
                    720:        RETURN();
                    721: }
                    722: void OPPROTO op_zextb_T1_T0 (void)
                    723: {
                    724:        T1 = ((uint8_t)T0);
                    725:        RETURN();
                    726: }
                    727: void OPPROTO op_zextb_T1_T1 (void)
                    728: {
                    729:        T1 = ((uint8_t)T1);
                    730:        RETURN();
                    731: }
                    732: void OPPROTO op_extw_T0_T0 (void)
                    733: {
                    734:        T0 = ((int16_t)T0);
                    735:        RETURN();
                    736: }
                    737: void OPPROTO op_extw_T1_T0 (void)
                    738: {
                    739:        T1 = ((int16_t)T0);
                    740:        RETURN();
                    741: }
                    742: void OPPROTO op_extw_T1_T1 (void)
                    743: {
                    744:        T1 = ((int16_t)T1);
                    745:        RETURN();
                    746: }
                    747: 
                    748: void OPPROTO op_zextw_T0_T0 (void)
                    749: {
                    750:        T0 = ((uint16_t)T0);
                    751:        RETURN();
                    752: }
                    753: void OPPROTO op_zextw_T1_T0 (void)
                    754: {
                    755:        T1 = ((uint16_t)T0);
                    756:        RETURN();
                    757: }
                    758: 
                    759: void OPPROTO op_zextw_T1_T1 (void)
                    760: {
                    761:        T1 = ((uint16_t)T1);
                    762:        RETURN();
                    763: }
                    764: 
                    765: void OPPROTO op_movl_T0_im (void)
                    766: {
                    767:        T0 = PARAM1;
                    768:        RETURN();
                    769: }
                    770: void OPPROTO op_movl_T1_im (void)
                    771: {
                    772:        T1 = PARAM1;
                    773:        RETURN();
                    774: }
                    775: 
                    776: void OPPROTO op_addl_T0_im (void)
                    777: {
                    778:        T0 += PARAM1;
                    779:        RETURN();
                    780: }
                    781: 
                    782: void OPPROTO op_addl_T1_im (void)
                    783: {
                    784:        T1 += PARAM1;
                    785:        RETURN();
                    786: 
                    787: }
                    788: void OPPROTO op_subl_T0_im (void)
                    789: {
                    790:        T0 -= PARAM1;
                    791:        RETURN();
                    792: }
                    793: 
                    794: void OPPROTO op_addxl_T0_C (void)
                    795: {
                    796:        if (env->pregs[SR_CCS] & X_FLAG)
                    797:                T0 += !!(env->pregs[SR_CCS] & C_FLAG);
                    798:        RETURN();
                    799: }
                    800: void OPPROTO op_subxl_T0_C (void)
                    801: {
                    802:        if (env->pregs[SR_CCS] & X_FLAG)
                    803:                T0 -= !!(env->pregs[SR_CCS] & C_FLAG);
                    804:        RETURN();
                    805: }
                    806: void OPPROTO op_addl_T0_C (void)
                    807: {
                    808:        T0 += !!(env->pregs[SR_CCS] & C_FLAG);
                    809:        RETURN();
                    810: }
                    811: void OPPROTO op_addl_T0_R (void)
                    812: {
                    813:        T0 += !!(env->pregs[SR_CCS] & R_FLAG);
                    814:        RETURN();
                    815: }
                    816: 
                    817: void OPPROTO op_clr_R (void)
                    818: {
                    819:        env->pregs[SR_CCS] &= ~R_FLAG;
                    820:        RETURN();
                    821: }
                    822: 
                    823: 
                    824: void OPPROTO op_andl_T0_im (void)
                    825: {
                    826:        T0 &= PARAM1;
                    827:        RETURN();
                    828: }
                    829: 
                    830: void OPPROTO op_andl_T1_im (void)
                    831: {
                    832:        T1 &= PARAM1;
                    833:        RETURN();
                    834: }
                    835: 
                    836: void OPPROTO op_movl_T0_T1 (void)
                    837: {
                    838:        T0 = T1;
                    839:        RETURN();
                    840: }
                    841: 
                    842: void OPPROTO op_swp_T0_T1 (void)
                    843: {
                    844:        T0 ^= T1;
                    845:        T1 ^= T0;
                    846:        T0 ^= T1;
                    847:        RETURN();
                    848: }
                    849: 
                    850: void OPPROTO op_movl_T1_T0 (void)
                    851: {
                    852:        T1 = T0;
                    853:        RETURN();
                    854: }
                    855: 
                    856: void OPPROTO op_movl_pc_T0 (void)
                    857: {
                    858:        env->pc = T0;
                    859:        RETURN();
                    860: }
                    861: 
                    862: void OPPROTO op_movl_T0_0 (void)
                    863: {
                    864:        T0 = 0;
                    865:        RETURN();
                    866: }
                    867: 
                    868: void OPPROTO op_addl_T0_T1 (void)
                    869: {
                    870:        T0 += T1;
                    871:        RETURN();
                    872: }
                    873: 
                    874: void OPPROTO op_subl_T0_T1 (void)
                    875: {
                    876:        T0 -= T1;
                    877:        RETURN();
                    878: }
                    879: 
                    880: void OPPROTO op_absl_T1_T1 (void)
                    881: {
                    882:        int32_t st = T1;
                    883: 
                    884:        T1 = st < 0 ? -st : st;
                    885:        RETURN();
                    886: }
                    887: 
                    888: void OPPROTO op_muls_T0_T1 (void)
                    889: {
                    890:        int64_t tmp, t0 ,t1;
                    891: 
                    892:        /* cast into signed values to make GCC sign extend these babies.  */
                    893:        t0 = (int32_t)T0;
                    894:        t1 = (int32_t)T1;
                    895: 
                    896:        tmp = t0 * t1;
                    897:        T0 = tmp & 0xffffffff;
                    898:        env->pregs[REG_MOF] = tmp >> 32;
                    899:        RETURN();
                    900: }
                    901: 
                    902: void OPPROTO op_mulu_T0_T1 (void)
                    903: {
                    904:        uint64_t tmp, t0 ,t1;
                    905:        t0 = T0;
                    906:        t1 = T1;
                    907: 
                    908:        tmp = t0 * t1;
                    909:        T0 = tmp & 0xffffffff;
                    910:        env->pregs[REG_MOF] = tmp >> 32;
                    911:        RETURN();
                    912: }
                    913: 
                    914: void OPPROTO op_dstep_T0_T1 (void)
                    915: {
                    916:        T0 <<= 1;
                    917:        if (T0 >= T1)
                    918:                T0 -= T1;
                    919:        RETURN();
                    920: }
                    921: 
                    922: void OPPROTO op_orl_T0_T1 (void)
                    923: {
                    924:        T0 |= T1;
                    925:        RETURN();
                    926: }
                    927: 
                    928: void OPPROTO op_andl_T0_T1 (void)
                    929: {
                    930:        T0 &= T1;
                    931:        RETURN();
                    932: }
                    933: 
                    934: void OPPROTO op_xorl_T0_T1 (void)
                    935: {
                    936:        T0 ^= T1;
                    937:        RETURN();
                    938: }
                    939: 
                    940: void OPPROTO op_lsll_T0_T1 (void)
                    941: {
                    942:        int s = T1;
                    943:        if (s > 31)
                    944:                T0 = 0;
                    945:        else
                    946:                T0 <<= s;
                    947:        RETURN();
                    948: }
                    949: 
                    950: void OPPROTO op_lsll_T0_im (void)
                    951: {
                    952:        T0 <<= PARAM1;
                    953:        RETURN();
                    954: }
                    955: 
                    956: void OPPROTO op_lsrl_T0_T1 (void)
                    957: {
                    958:        int s = T1;
                    959:        if (s > 31)
                    960:                T0 = 0;
                    961:        else
                    962:                T0 >>= s;
                    963:        RETURN();
                    964: }
                    965: 
                    966: /* Rely on GCC emitting an arithmetic shift for signed right shifts.  */
                    967: void OPPROTO op_asrl_T0_T1 (void)
                    968: {
                    969:        int s = T1;
                    970:        if (s > 31)
                    971:                T0 = T0 & 0x80000000 ? -1 : 0;
                    972:        else
                    973:                T0 = (int32_t)T0 >> s;
                    974:        RETURN();
                    975: }
                    976: 
                    977: void OPPROTO op_btst_T0_T1 (void)
                    978: {
                    979:        /* FIXME: clean this up.  */
                    980: 
                    981:        /* des ref:
                    982:           The N flag is set according to the selected bit in the dest reg.
                    983:           The Z flag is set if the selected bit and all bits to the right are
                    984:           zero.
                    985:           The destination reg is not affected.*/
                    986:        unsigned int fz, sbit, bset, mask, masked_t0;
                    987: 
                    988:        sbit = T1 & 31;
                    989:         bset = !!(T0 & (1 << sbit));
                    990:        mask = sbit == 31 ? -1 : (1 << (sbit + 1)) - 1;
                    991:        masked_t0 = T0 & mask;
                    992:        fz = !(masked_t0 | bset);
                    993:        /* Set the N and Z flags accordingly.  */
                    994:        T0 = (bset << 3) | (fz << 2);
                    995:        RETURN();
                    996: }
                    997: 
                    998: void OPPROTO op_bound_T0_T1 (void)
                    999: {
                   1000:        if (T0 > T1)
                   1001:                T0 = T1;
                   1002:        RETURN();
                   1003: }
                   1004: 
                   1005: void OPPROTO op_lz_T0_T1 (void)
                   1006: {
                   1007:        T0 = clz32(T1);
                   1008:        RETURN();
                   1009: }
                   1010: 
                   1011: void OPPROTO op_negl_T0_T1 (void)
                   1012: {
                   1013:        T0 = -T1;
                   1014:        RETURN();
                   1015: }
                   1016: 
                   1017: void OPPROTO op_negl_T1_T1 (void)
                   1018: {
                   1019:        T1 = -T1;
                   1020:        RETURN();
                   1021: }
                   1022: 
                   1023: void OPPROTO op_not_T0_T0 (void)
                   1024: {
                   1025:        T0 = ~(T0);
                   1026:        RETURN();
                   1027: }
                   1028: void OPPROTO op_not_T1_T1 (void)
                   1029: {
                   1030:        T1 = ~(T1);
                   1031:        RETURN();
                   1032: }
                   1033: 
                   1034: void OPPROTO op_swapw_T0_T0 (void)
                   1035: {
                   1036:        T0 = (T0 << 16) | ((T0 >> 16));
                   1037:        RETURN();
                   1038: }
                   1039: 
                   1040: void OPPROTO op_swapb_T0_T0 (void)
                   1041: {
                   1042:        T0 = ((T0 << 8) & 0xff00ff00) | ((T0 >> 8) & 0x00ff00ff);
                   1043:        RETURN();
                   1044: }
                   1045: 
                   1046: void OPPROTO op_swapr_T0_T0 (void)
                   1047: {
                   1048:        T0 = (((T0 << 7) & 0x80808080) |
                   1049:              ((T0 << 5) & 0x40404040) |
                   1050:              ((T0 << 3) & 0x20202020) |
                   1051:              ((T0 << 1) & 0x10101010) |
                   1052:              ((T0 >> 1) & 0x08080808) |
                   1053:              ((T0 >> 3) & 0x04040404) |
                   1054:              ((T0 >> 5) & 0x02020202) |
                   1055:              ((T0 >> 7) & 0x01010101));
                   1056:        RETURN();
                   1057: }
                   1058: 
                   1059: void OPPROTO op_tst_cc_eq (void) {
                   1060:        uint32_t flags = env->pregs[SR_CCS];
                   1061:        int z_set;
                   1062: 
                   1063:        z_set = !!(flags & Z_FLAG);
                   1064:        T0 = z_set;
                   1065:        RETURN();
                   1066: }
                   1067: 
                   1068: void OPPROTO op_tst_cc_eq_fast (void) {
                   1069:        T0 = !(env->cc_result);
                   1070:        RETURN();
                   1071: }
                   1072: 
                   1073: void OPPROTO op_tst_cc_ne (void) {
                   1074:        uint32_t flags = env->pregs[SR_CCS];
                   1075:        int z_set;
                   1076: 
                   1077:        z_set = !!(flags & Z_FLAG);
                   1078:        T0 = !z_set;
                   1079:        RETURN();
                   1080: }
                   1081: void OPPROTO op_tst_cc_ne_fast (void) {
                   1082:        T0 = !!(env->cc_result);
                   1083:        RETURN();
                   1084: }
                   1085: 
                   1086: void OPPROTO op_tst_cc_cc (void) {
                   1087:        uint32_t flags = env->pregs[SR_CCS];
                   1088:        int c_set;
                   1089: 
                   1090:        c_set = !!(flags & C_FLAG);
                   1091:        T0 = !c_set;
                   1092:        RETURN();
                   1093: }
                   1094: void OPPROTO op_tst_cc_cs (void) {
                   1095:        uint32_t flags = env->pregs[SR_CCS];
                   1096:        int c_set;
                   1097: 
                   1098:        c_set = !!(flags & C_FLAG);
                   1099:        T0 = c_set;
                   1100:        RETURN();
                   1101: }
                   1102: 
                   1103: void OPPROTO op_tst_cc_vc (void) {
                   1104:        uint32_t flags = env->pregs[SR_CCS];
                   1105:        int v_set;
                   1106: 
                   1107:        v_set = !!(flags & V_FLAG);
                   1108:        T0 = !v_set;
                   1109:        RETURN();
                   1110: }
                   1111: void OPPROTO op_tst_cc_vs (void) {
                   1112:        uint32_t flags = env->pregs[SR_CCS];
                   1113:        int v_set;
                   1114: 
                   1115:        v_set = !!(flags & V_FLAG);
                   1116:        T0 = v_set;
                   1117:        RETURN();
                   1118: }
                   1119: void OPPROTO op_tst_cc_pl (void) {
                   1120:        uint32_t flags = env->pregs[SR_CCS];
                   1121:        int n_set;
                   1122: 
                   1123:        n_set = !!(flags & N_FLAG);
                   1124:        T0 = !n_set;
                   1125:        RETURN();
                   1126: }
                   1127: void OPPROTO op_tst_cc_pl_fast (void) {
                   1128:        T0 = ((int32_t)env->cc_result) >= 0;
                   1129:        RETURN();
                   1130: }
                   1131: 
                   1132: void OPPROTO op_tst_cc_mi (void) {
                   1133:        uint32_t flags = env->pregs[SR_CCS];
                   1134:        int n_set;
                   1135: 
                   1136:        n_set = !!(flags & N_FLAG);
                   1137:        T0 = n_set;
                   1138:        RETURN();
                   1139: }
                   1140: void OPPROTO op_tst_cc_mi_fast (void) {
                   1141:        T0 = ((int32_t)env->cc_result) < 0;
                   1142:        RETURN();
                   1143: }
                   1144: 
                   1145: void OPPROTO op_tst_cc_ls (void) {
                   1146:        uint32_t flags = env->pregs[SR_CCS];
                   1147:        int c_set;
                   1148:        int z_set;
                   1149: 
                   1150:        c_set = !!(flags & C_FLAG);
                   1151:        z_set = !!(flags & Z_FLAG);
                   1152:        T0 = c_set || z_set;
                   1153:        RETURN();
                   1154: }
                   1155: void OPPROTO op_tst_cc_hi (void) {
                   1156:        uint32_t flags = env->pregs[SR_CCS];
                   1157:        int z_set;
                   1158:        int c_set;
                   1159: 
                   1160:        z_set = !!(flags & Z_FLAG);
                   1161:        c_set = !!(flags & C_FLAG);
                   1162:        T0 = !c_set && !z_set;
                   1163:        RETURN();
                   1164: 
                   1165: }
                   1166: 
                   1167: void OPPROTO op_tst_cc_ge (void) {
                   1168:        uint32_t flags = env->pregs[SR_CCS];
                   1169:        int n_set;
                   1170:        int v_set;
                   1171: 
                   1172:        n_set = !!(flags & N_FLAG);
                   1173:        v_set = !!(flags & V_FLAG);
                   1174:        T0 = (n_set && v_set) || (!n_set && !v_set);
                   1175:        RETURN();
                   1176: }
                   1177: 
                   1178: void OPPROTO op_tst_cc_ge_fast (void) {
                   1179:        T0 = ((int32_t)env->cc_src < (int32_t)env->cc_dest);
                   1180:        RETURN();
                   1181: }
                   1182: 
                   1183: void OPPROTO op_tst_cc_lt (void) {
                   1184:        uint32_t flags = env->pregs[SR_CCS];
                   1185:        int n_set;
                   1186:        int v_set;
                   1187: 
                   1188:        n_set = !!(flags & N_FLAG);
                   1189:        v_set = !!(flags & V_FLAG);
                   1190:        T0 = (n_set && !v_set) || (!n_set && v_set);
                   1191:        RETURN();
                   1192: }
                   1193: 
                   1194: void OPPROTO op_tst_cc_gt (void) {
                   1195:        uint32_t flags = env->pregs[SR_CCS];
                   1196:        int n_set;
                   1197:        int v_set;
                   1198:        int z_set;
                   1199: 
                   1200:        n_set = !!(flags & N_FLAG);
                   1201:        v_set = !!(flags & V_FLAG);
                   1202:        z_set = !!(flags & Z_FLAG);
                   1203:        T0 = (n_set && v_set && !z_set)
                   1204:                || (!n_set && !v_set && !z_set);
                   1205:        RETURN();
                   1206: }
                   1207: 
                   1208: void OPPROTO op_tst_cc_le (void) {
                   1209:        uint32_t flags = env->pregs[SR_CCS];
                   1210:        int n_set;
                   1211:        int v_set;
                   1212:        int z_set;
                   1213: 
                   1214:        n_set = !!(flags & N_FLAG);
                   1215:        v_set = !!(flags & V_FLAG);
                   1216:        z_set = !!(flags & Z_FLAG);
                   1217:        T0 = z_set || (n_set && !v_set) || (!n_set && v_set);
                   1218:        RETURN();
                   1219: }
                   1220: 
                   1221: void OPPROTO op_tst_cc_p (void) {
                   1222:        uint32_t flags = env->pregs[SR_CCS];
                   1223:        int p_set;
                   1224: 
                   1225:        p_set = !!(flags & P_FLAG);
                   1226:        T0 = p_set;
                   1227:        RETURN();
                   1228: }
                   1229: 
                   1230: /* Evaluate the if the branch should be taken or not. Needs to be done in
                   1231:    the original sequence. The acutal branch is rescheduled to right after the
                   1232:    delay-slot.  */
                   1233: void OPPROTO op_evaluate_bcc (void)
                   1234: {
                   1235:        env->btaken = T0;
                   1236:        RETURN();
                   1237: }
                   1238: 
                   1239: /* this one is used on every alu op, optimize it!.  */
                   1240: void OPPROTO op_goto_if_not_x (void)
                   1241: {
                   1242:        if (env->pregs[SR_CCS] & X_FLAG)
                   1243:                GOTO_LABEL_PARAM(1);
                   1244:        RETURN();
                   1245: }
                   1246: 
                   1247: void OPPROTO op_cc_jmp (void)
                   1248: {
                   1249:        if (env->btaken)
                   1250:                env->pc = PARAM1;
                   1251:        else
                   1252:                env->pc = PARAM2;
                   1253:        RETURN();
                   1254: }
                   1255: 
                   1256: void OPPROTO op_cc_ngoto (void)
                   1257: {
                   1258:        if (!env->btaken)
                   1259:                GOTO_LABEL_PARAM(1);
                   1260:        RETURN();
                   1261: }
                   1262: 
                   1263: void OPPROTO op_movl_btarget_T0 (void)
                   1264: {
                   1265:        env->btarget = T0;
                   1266:        RETURN();
                   1267: }
                   1268: 
                   1269: void OPPROTO op_jmp (void)
                   1270: {
                   1271:        env->pc = env->btarget;
                   1272:        RETURN();
                   1273: }
                   1274: 
                   1275: /* Load and store */
                   1276: #define MEMSUFFIX _raw
                   1277: #include "op_mem.c"
                   1278: #undef MEMSUFFIX
                   1279: #if !defined(CONFIG_USER_ONLY)
                   1280: #define MEMSUFFIX _user
                   1281: #include "op_mem.c"
                   1282: #undef MEMSUFFIX
                   1283: 
                   1284: #define MEMSUFFIX _kernel
                   1285: #include "op_mem.c"
                   1286: #undef MEMSUFFIX
                   1287: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.