Annotation of qemu/target-mips/op.c, revision 1.1.1.5

1.1       root        1: /*
                      2:  *  MIPS emulation micro-operations for qemu.
                      3:  * 
                      4:  *  Copyright (c) 2004-2005 Jocelyn Mayer
1.1.1.4   root        5:  *  Copyright (c) 2006 Marius Groeger (FPU operations)
1.1       root        6:  *
                      7:  * This library is free software; you can redistribute it and/or
                      8:  * modify it under the terms of the GNU Lesser General Public
                      9:  * License as published by the Free Software Foundation; either
                     10:  * version 2 of the License, or (at your option) any later version.
                     11:  *
                     12:  * This library is distributed in the hope that it will be useful,
                     13:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                     14:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     15:  * Lesser General Public License for more details.
                     16:  *
                     17:  * You should have received a copy of the GNU Lesser General Public
                     18:  * License along with this library; if not, write to the Free Software
                     19:  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     20:  */
                     21: 
                     22: #include "config.h"
                     23: #include "exec.h"
                     24: 
                     25: #ifndef CALL_FROM_TB0
                     26: #define CALL_FROM_TB0(func) func();
                     27: #endif
                     28: #ifndef CALL_FROM_TB1
                     29: #define CALL_FROM_TB1(func, arg0) func(arg0);
                     30: #endif
                     31: #ifndef CALL_FROM_TB1_CONST16
                     32: #define CALL_FROM_TB1_CONST16(func, arg0) CALL_FROM_TB1(func, arg0);
                     33: #endif
                     34: #ifndef CALL_FROM_TB2
                     35: #define CALL_FROM_TB2(func, arg0, arg1) func(arg0, arg1);
                     36: #endif
                     37: #ifndef CALL_FROM_TB2_CONST16
                     38: #define CALL_FROM_TB2_CONST16(func, arg0, arg1)     \
                     39: CALL_FROM_TB2(func, arg0, arg1);
                     40: #endif
                     41: #ifndef CALL_FROM_TB3
                     42: #define CALL_FROM_TB3(func, arg0, arg1, arg2) func(arg0, arg1, arg2);
                     43: #endif
                     44: #ifndef CALL_FROM_TB4
                     45: #define CALL_FROM_TB4(func, arg0, arg1, arg2, arg3) \
                     46:         func(arg0, arg1, arg2, arg3);
                     47: #endif
                     48: 
                     49: #define REG 1
                     50: #include "op_template.c"
                     51: #undef REG
                     52: #define REG 2
                     53: #include "op_template.c"
                     54: #undef REG
                     55: #define REG 3
                     56: #include "op_template.c"
                     57: #undef REG
                     58: #define REG 4
                     59: #include "op_template.c"
                     60: #undef REG
                     61: #define REG 5
                     62: #include "op_template.c"
                     63: #undef REG
                     64: #define REG 6
                     65: #include "op_template.c"
                     66: #undef REG
                     67: #define REG 7
                     68: #include "op_template.c"
                     69: #undef REG
                     70: #define REG 8
                     71: #include "op_template.c"
                     72: #undef REG
                     73: #define REG 9
                     74: #include "op_template.c"
                     75: #undef REG
                     76: #define REG 10
                     77: #include "op_template.c"
                     78: #undef REG
                     79: #define REG 11
                     80: #include "op_template.c"
                     81: #undef REG
                     82: #define REG 12
                     83: #include "op_template.c"
                     84: #undef REG
                     85: #define REG 13
                     86: #include "op_template.c"
                     87: #undef REG
                     88: #define REG 14
                     89: #include "op_template.c"
                     90: #undef REG
                     91: #define REG 15
                     92: #include "op_template.c"
                     93: #undef REG
                     94: #define REG 16
                     95: #include "op_template.c"
                     96: #undef REG
                     97: #define REG 17
                     98: #include "op_template.c"
                     99: #undef REG
                    100: #define REG 18
                    101: #include "op_template.c"
                    102: #undef REG
                    103: #define REG 19
                    104: #include "op_template.c"
                    105: #undef REG
                    106: #define REG 20
                    107: #include "op_template.c"
                    108: #undef REG
                    109: #define REG 21
                    110: #include "op_template.c"
                    111: #undef REG
                    112: #define REG 22
                    113: #include "op_template.c"
                    114: #undef REG
                    115: #define REG 23
                    116: #include "op_template.c"
                    117: #undef REG
                    118: #define REG 24
                    119: #include "op_template.c"
                    120: #undef REG
                    121: #define REG 25
                    122: #include "op_template.c"
                    123: #undef REG
                    124: #define REG 26
                    125: #include "op_template.c"
                    126: #undef REG
                    127: #define REG 27
                    128: #include "op_template.c"
                    129: #undef REG
                    130: #define REG 28
                    131: #include "op_template.c"
                    132: #undef REG
                    133: #define REG 29
                    134: #include "op_template.c"
                    135: #undef REG
                    136: #define REG 30
                    137: #include "op_template.c"
                    138: #undef REG
                    139: #define REG 31
                    140: #include "op_template.c"
                    141: #undef REG
                    142: 
1.1.1.5 ! root      143: #define TN
1.1       root      144: #include "op_template.c"
                    145: #undef TN
                    146: 
1.1.1.4   root      147: #ifdef MIPS_USES_FPU
                    148: 
                    149: #define SFREG 0
                    150: #define DFREG 0
                    151: #include "fop_template.c"
                    152: #undef SFREG
                    153: #undef DFREG
                    154: #define SFREG 1
                    155: #include "fop_template.c"
                    156: #undef SFREG
                    157: #define SFREG 2
                    158: #define DFREG 2
                    159: #include "fop_template.c"
                    160: #undef SFREG
                    161: #undef DFREG
                    162: #define SFREG 3
                    163: #include "fop_template.c"
                    164: #undef SFREG
                    165: #define SFREG 4
                    166: #define DFREG 4
                    167: #include "fop_template.c"
                    168: #undef SFREG
                    169: #undef DFREG
                    170: #define SFREG 5
                    171: #include "fop_template.c"
                    172: #undef SFREG
                    173: #define SFREG 6
                    174: #define DFREG 6
                    175: #include "fop_template.c"
                    176: #undef SFREG
                    177: #undef DFREG
                    178: #define SFREG 7
                    179: #include "fop_template.c"
                    180: #undef SFREG
                    181: #define SFREG 8
                    182: #define DFREG 8
                    183: #include "fop_template.c"
                    184: #undef SFREG
                    185: #undef DFREG
                    186: #define SFREG 9
                    187: #include "fop_template.c"
                    188: #undef SFREG
                    189: #define SFREG 10
                    190: #define DFREG 10
                    191: #include "fop_template.c"
                    192: #undef SFREG
                    193: #undef DFREG
                    194: #define SFREG 11
                    195: #include "fop_template.c"
                    196: #undef SFREG
                    197: #define SFREG 12
                    198: #define DFREG 12
                    199: #include "fop_template.c"
                    200: #undef SFREG
                    201: #undef DFREG
                    202: #define SFREG 13
                    203: #include "fop_template.c"
                    204: #undef SFREG
                    205: #define SFREG 14
                    206: #define DFREG 14
                    207: #include "fop_template.c"
                    208: #undef SFREG
                    209: #undef DFREG
                    210: #define SFREG 15
                    211: #include "fop_template.c"
                    212: #undef SFREG
                    213: #define SFREG 16
                    214: #define DFREG 16
                    215: #include "fop_template.c"
                    216: #undef SFREG
                    217: #undef DFREG
                    218: #define SFREG 17
                    219: #include "fop_template.c"
                    220: #undef SFREG
                    221: #define SFREG 18
                    222: #define DFREG 18
                    223: #include "fop_template.c"
                    224: #undef SFREG
                    225: #undef DFREG
                    226: #define SFREG 19
                    227: #include "fop_template.c"
                    228: #undef SFREG
                    229: #define SFREG 20
                    230: #define DFREG 20
                    231: #include "fop_template.c"
                    232: #undef SFREG
                    233: #undef DFREG
                    234: #define SFREG 21
                    235: #include "fop_template.c"
                    236: #undef SFREG
                    237: #define SFREG 22
                    238: #define DFREG 22
                    239: #include "fop_template.c"
                    240: #undef SFREG
                    241: #undef DFREG
                    242: #define SFREG 23
                    243: #include "fop_template.c"
                    244: #undef SFREG
                    245: #define SFREG 24
                    246: #define DFREG 24
                    247: #include "fop_template.c"
                    248: #undef SFREG
                    249: #undef DFREG
                    250: #define SFREG 25
                    251: #include "fop_template.c"
                    252: #undef SFREG
                    253: #define SFREG 26
                    254: #define DFREG 26
                    255: #include "fop_template.c"
                    256: #undef SFREG
                    257: #undef DFREG
                    258: #define SFREG 27
                    259: #include "fop_template.c"
                    260: #undef SFREG
                    261: #define SFREG 28
                    262: #define DFREG 28
                    263: #include "fop_template.c"
                    264: #undef SFREG
                    265: #undef DFREG
                    266: #define SFREG 29
                    267: #include "fop_template.c"
                    268: #undef SFREG
                    269: #define SFREG 30
                    270: #define DFREG 30
                    271: #include "fop_template.c"
                    272: #undef SFREG
                    273: #undef DFREG
                    274: #define SFREG 31
                    275: #include "fop_template.c"
                    276: #undef SFREG
                    277: 
                    278: #define FTN
                    279: #include "fop_template.c"
                    280: #undef FTN
                    281: 
                    282: #endif
                    283: 
1.1       root      284: void op_dup_T0 (void)
                    285: {
                    286:     T2 = T0;
                    287:     RETURN();
                    288: }
                    289: 
                    290: void op_load_HI (void)
                    291: {
                    292:     T0 = env->HI;
                    293:     RETURN();
                    294: }
                    295: 
                    296: void op_store_HI (void)
                    297: {
                    298:     env->HI = T0;
                    299:     RETURN();
                    300: }
                    301: 
                    302: void op_load_LO (void)
                    303: {
                    304:     T0 = env->LO;
                    305:     RETURN();
                    306: }
                    307: 
                    308: void op_store_LO (void)
                    309: {
                    310:     env->LO = T0;
                    311:     RETURN();
                    312: }
                    313: 
                    314: /* Load and store */
                    315: #define MEMSUFFIX _raw
                    316: #include "op_mem.c"
                    317: #undef MEMSUFFIX
                    318: #if !defined(CONFIG_USER_ONLY)
                    319: #define MEMSUFFIX _user
                    320: #include "op_mem.c"
                    321: #undef MEMSUFFIX
                    322: 
                    323: #define MEMSUFFIX _kernel
                    324: #include "op_mem.c"
                    325: #undef MEMSUFFIX
                    326: #endif
                    327: 
                    328: /* Arithmetic */
                    329: void op_add (void)
                    330: {
1.1.1.5 ! root      331:     T0 = (int32_t)((int32_t)T0 + (int32_t)T1);
1.1       root      332:     RETURN();
                    333: }
                    334: 
                    335: void op_addo (void)
                    336: {
                    337:     target_ulong tmp;
                    338: 
1.1.1.5 ! root      339:     tmp = (int32_t)T0;
        !           340:     T0 = (int32_t)T0 + (int32_t)T1;
        !           341:     if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 31) {
        !           342:         /* operands of same sign, result different sign */
        !           343:         CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
        !           344:     }
        !           345:     T0 = (int32_t)T0;
        !           346:     RETURN();
        !           347: }
        !           348: 
        !           349: void op_sub (void)
        !           350: {
        !           351:     T0 = (int32_t)((int32_t)T0 - (int32_t)T1);
        !           352:     RETURN();
        !           353: }
        !           354: 
        !           355: void op_subo (void)
        !           356: {
        !           357:     target_ulong tmp;
        !           358: 
        !           359:     tmp = (int32_t)T0;
        !           360:     T0 = (int32_t)T0 - (int32_t)T1;
        !           361:     if (((tmp ^ T1) & (tmp ^ T0)) >> 31) {
        !           362:         /* operands of different sign, first operand and result different sign */
        !           363:         CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
        !           364:     }
        !           365:     T0 = (int32_t)T0;
        !           366:     RETURN();
        !           367: }
        !           368: 
        !           369: void op_mul (void)
        !           370: {
        !           371:     T0 = (int32_t)((int32_t)T0 * (int32_t)T1);
        !           372:     RETURN();
        !           373: }
        !           374: 
        !           375: void op_div (void)
        !           376: {
        !           377:     if (T1 != 0) {
        !           378:         env->LO = (int32_t)((int32_t)T0 / (int32_t)T1);
        !           379:         env->HI = (int32_t)((int32_t)T0 % (int32_t)T1);
        !           380:     }
        !           381:     RETURN();
        !           382: }
        !           383: 
        !           384: void op_divu (void)
        !           385: {
        !           386:     if (T1 != 0) {
        !           387:         env->LO = (int32_t)((uint32_t)T0 / (uint32_t)T1);
        !           388:         env->HI = (int32_t)((uint32_t)T0 % (uint32_t)T1);
        !           389:     }
        !           390:     RETURN();
        !           391: }
        !           392: 
        !           393: #ifdef MIPS_HAS_MIPS64
        !           394: /* Arithmetic */
        !           395: void op_dadd (void)
        !           396: {
        !           397:     T0 += T1;
        !           398:     RETURN();
        !           399: }
        !           400: 
        !           401: void op_daddo (void)
        !           402: {
        !           403:     target_long tmp;
        !           404: 
1.1       root      405:     tmp = T0;
                    406:     T0 += T1;
1.1.1.5 ! root      407:     if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 63) {
        !           408:         /* operands of same sign, result different sign */
        !           409:         CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
        !           410:     }
        !           411:     RETURN();
        !           412: }
        !           413: 
        !           414: void op_dsub (void)
        !           415: {
        !           416:     T0 -= T1;
        !           417:     RETURN();
        !           418: }
        !           419: 
        !           420: void op_dsubo (void)
        !           421: {
        !           422:     target_long tmp;
        !           423: 
        !           424:     tmp = T0;
        !           425:     T0 = (int64_t)T0 - (int64_t)T1;
        !           426:     if (((tmp ^ T1) & (tmp ^ T0)) >> 63) {
        !           427:         /* operands of different sign, first operand and result different sign */
1.1.1.2   root      428:         CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
1.1       root      429:     }
                    430:     RETURN();
                    431: }
                    432: 
1.1.1.5 ! root      433: void op_dmul (void)
        !           434: {
        !           435:     T0 = (int64_t)T0 * (int64_t)T1;
        !           436:     RETURN();
        !           437: }
        !           438: 
        !           439: #if TARGET_LONG_BITS > HOST_LONG_BITS
        !           440: /* Those might call libgcc functions.  */
        !           441: void op_ddiv (void)
        !           442: {
        !           443:     do_ddiv();
        !           444:     RETURN();
        !           445: }
        !           446: 
        !           447: void op_ddivu (void)
        !           448: {
        !           449:     do_ddivu();
        !           450:     RETURN();
        !           451: }
        !           452: #else
        !           453: void op_ddiv (void)
        !           454: {
        !           455:     if (T1 != 0) {
        !           456:         env->LO = (int64_t)T0 / (int64_t)T1;
        !           457:         env->HI = (int64_t)T0 % (int64_t)T1;
        !           458:     }
        !           459:     RETURN();
        !           460: }
        !           461: 
        !           462: void op_ddivu (void)
        !           463: {
        !           464:     if (T1 != 0) {
        !           465:         env->LO = T0 / T1;
        !           466:         env->HI = T0 % T1;
        !           467:     }
        !           468:     RETURN();
        !           469: }
        !           470: #endif
        !           471: #endif /* MIPS_HAS_MIPS64 */
        !           472: 
        !           473: /* Logical */
        !           474: void op_and (void)
        !           475: {
        !           476:     T0 &= T1;
        !           477:     RETURN();
        !           478: }
        !           479: 
        !           480: void op_nor (void)
        !           481: {
        !           482:     T0 = ~(T0 | T1);
        !           483:     RETURN();
        !           484: }
        !           485: 
        !           486: void op_or (void)
        !           487: {
        !           488:     T0 |= T1;
        !           489:     RETURN();
        !           490: }
        !           491: 
        !           492: void op_xor (void)
        !           493: {
        !           494:     T0 ^= T1;
        !           495:     RETURN();
        !           496: }
        !           497: 
        !           498: void op_sll (void)
        !           499: {
        !           500:     T0 = (int32_t)((uint32_t)T0 << (uint32_t)T1);
        !           501:     RETURN();
        !           502: }
        !           503: 
        !           504: void op_sra (void)
        !           505: {
        !           506:     T0 = (int32_t)((int32_t)T0 >> (uint32_t)T1);
        !           507:     RETURN();
        !           508: }
        !           509: 
        !           510: void op_srl (void)
        !           511: {
        !           512:     T0 = (int32_t)((uint32_t)T0 >> (uint32_t)T1);
        !           513:     RETURN();
        !           514: }
        !           515: 
        !           516: void op_rotr (void)
        !           517: {
        !           518:     target_ulong tmp;
        !           519: 
        !           520:     if (T1) {
        !           521:        tmp = (int32_t)((uint32_t)T0 << (0x20 - (uint32_t)T1));
        !           522:        T0 = (int32_t)((uint32_t)T0 >> (uint32_t)T1) | tmp;
        !           523:     } else
        !           524:        T0 = T1;
        !           525:     RETURN();
        !           526: }
        !           527: 
        !           528: void op_sllv (void)
        !           529: {
        !           530:     T0 = (int32_t)((uint32_t)T1 << ((uint32_t)T0 & 0x1F));
        !           531:     RETURN();
        !           532: }
        !           533: 
        !           534: void op_srav (void)
        !           535: {
        !           536:     T0 = (int32_t)((int32_t)T1 >> (T0 & 0x1F));
        !           537:     RETURN();
        !           538: }
        !           539: 
        !           540: void op_srlv (void)
        !           541: {
        !           542:     T0 = (int32_t)((uint32_t)T1 >> (T0 & 0x1F));
        !           543:     RETURN();
        !           544: }
        !           545: 
        !           546: void op_rotrv (void)
        !           547: {
        !           548:     target_ulong tmp;
        !           549: 
        !           550:     T0 &= 0x1F;
        !           551:     if (T0) {
        !           552:        tmp = (int32_t)((uint32_t)T1 << (0x20 - T0));
        !           553:        T0 = (int32_t)((uint32_t)T1 >> T0) | tmp;
        !           554:     } else
        !           555:        T0 = T1;
        !           556:     RETURN();
        !           557: }
        !           558: 
        !           559: void op_clo (void)
        !           560: {
        !           561:     int n;
        !           562: 
        !           563:     if (T0 == ~((target_ulong)0)) {
        !           564:         T0 = 32;
        !           565:     } else {
        !           566:         for (n = 0; n < 32; n++) {
        !           567:             if (!(T0 & (1 << 31)))
        !           568:                 break;
        !           569:             T0 = T0 << 1;
        !           570:         }
        !           571:         T0 = n;
        !           572:     }
        !           573:     RETURN();
        !           574: }
        !           575: 
        !           576: void op_clz (void)
        !           577: {
        !           578:     int n;
        !           579: 
        !           580:     if (T0 == 0) {
        !           581:         T0 = 32;
        !           582:     } else {
        !           583:         for (n = 0; n < 32; n++) {
        !           584:             if (T0 & (1 << 31))
        !           585:                 break;
        !           586:             T0 = T0 << 1;
        !           587:         }
        !           588:         T0 = n;
        !           589:     }
        !           590:     RETURN();
        !           591: }
        !           592: 
        !           593: #ifdef MIPS_HAS_MIPS64
        !           594: 
        !           595: #if TARGET_LONG_BITS > HOST_LONG_BITS
        !           596: /* Those might call libgcc functions.  */
        !           597: void op_dsll (void)
        !           598: {
        !           599:     CALL_FROM_TB0(do_dsll);
        !           600:     RETURN();
        !           601: }
        !           602: 
        !           603: void op_dsll32 (void)
        !           604: {
        !           605:     CALL_FROM_TB0(do_dsll32);
        !           606:     RETURN();
        !           607: }
        !           608: 
        !           609: void op_dsra (void)
        !           610: {
        !           611:     CALL_FROM_TB0(do_dsra);
        !           612:     RETURN();
        !           613: }
        !           614: 
        !           615: void op_dsra32 (void)
        !           616: {
        !           617:     CALL_FROM_TB0(do_dsra32);
        !           618:     RETURN();
        !           619: }
        !           620: 
        !           621: void op_dsrl (void)
        !           622: {
        !           623:     CALL_FROM_TB0(do_dsrl);
        !           624:     RETURN();
        !           625: }
        !           626: 
        !           627: void op_dsrl32 (void)
        !           628: {
        !           629:     CALL_FROM_TB0(do_dsrl32);
        !           630:     RETURN();
        !           631: }
        !           632: 
        !           633: void op_drotr (void)
        !           634: {
        !           635:     CALL_FROM_TB0(do_drotr);
        !           636:     RETURN();
        !           637: }
        !           638: 
        !           639: void op_drotr32 (void)
        !           640: {
        !           641:     CALL_FROM_TB0(do_drotr32);
        !           642:     RETURN();
        !           643: }
        !           644: 
        !           645: void op_dsllv (void)
        !           646: {
        !           647:     CALL_FROM_TB0(do_dsllv);
        !           648:     RETURN();
        !           649: }
        !           650: 
        !           651: void op_dsrav (void)
        !           652: {
        !           653:     CALL_FROM_TB0(do_dsrav);
        !           654:     RETURN();
        !           655: }
        !           656: 
        !           657: void op_dsrlv (void)
        !           658: {
        !           659:     CALL_FROM_TB0(do_dsrlv);
        !           660:     RETURN();
        !           661: }
        !           662: 
        !           663: void op_drotrv (void)
        !           664: {
        !           665:     CALL_FROM_TB0(do_drotrv);
        !           666:     RETURN();
        !           667: }
        !           668: 
        !           669: #else /* TARGET_LONG_BITS > HOST_LONG_BITS */
        !           670: 
        !           671: void op_dsll (void)
        !           672: {
        !           673:     T0 = T0 << T1;
        !           674:     RETURN();
        !           675: }
        !           676: 
        !           677: void op_dsll32 (void)
        !           678: {
        !           679:     T0 = T0 << (T1 + 32);
        !           680:     RETURN();
        !           681: }
        !           682: 
        !           683: void op_dsra (void)
        !           684: {
        !           685:     T0 = (int64_t)T0 >> T1;
        !           686:     RETURN();
        !           687: }
        !           688: 
        !           689: void op_dsra32 (void)
        !           690: {
        !           691:     T0 = (int64_t)T0 >> (T1 + 32);
        !           692:     RETURN();
        !           693: }
        !           694: 
        !           695: void op_dsrl (void)
        !           696: {
        !           697:     T0 = T0 >> T1;
        !           698:     RETURN();
        !           699: }
        !           700: 
        !           701: void op_dsrl32 (void)
        !           702: {
        !           703:     T0 = T0 >> (T1 + 32);
        !           704:     RETURN();
        !           705: }
        !           706: 
        !           707: void op_drotr (void)
        !           708: {
        !           709:     target_ulong tmp;
        !           710: 
        !           711:     if (T1) {
        !           712:        tmp = T0 << (0x40 - T1);
        !           713:        T0 = (T0 >> T1) | tmp;
        !           714:     } else
        !           715:        T0 = T1;
        !           716:     RETURN();
        !           717: }
        !           718: 
        !           719: void op_drotr32 (void)
        !           720: {
        !           721:     target_ulong tmp;
        !           722: 
        !           723:     if (T1) {
        !           724:        tmp = T0 << (0x40 - (32 + T1));
        !           725:        T0 = (T0 >> (32 + T1)) | tmp;
        !           726:     } else
        !           727:        T0 = T1;
        !           728:     RETURN();
        !           729: }
        !           730: 
        !           731: void op_dsllv (void)
        !           732: {
        !           733:     T0 = T1 << (T0 & 0x3F);
        !           734:     RETURN();
        !           735: }
        !           736: 
        !           737: void op_dsrav (void)
        !           738: {
        !           739:     T0 = (int64_t)T1 >> (T0 & 0x3F);
        !           740:     RETURN();
        !           741: }
        !           742: 
        !           743: void op_dsrlv (void)
        !           744: {
        !           745:     T0 = T1 >> (T0 & 0x3F);
        !           746:     RETURN();
        !           747: }
        !           748: 
        !           749: void op_drotrv (void)
        !           750: {
        !           751:     target_ulong tmp;
        !           752: 
        !           753:     T0 &= 0x3F;
        !           754:     if (T0) {
        !           755:        tmp = T1 << (0x40 - T0);
        !           756:        T0 = (T1 >> T0) | tmp;
        !           757:     } else
        !           758:        T0 = T1;
        !           759:     RETURN();
        !           760: }
        !           761: #endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
        !           762: 
        !           763: void op_dclo (void)
        !           764: {
        !           765:     int n;
        !           766: 
        !           767:     if (T0 == ~((target_ulong)0)) {
        !           768:         T0 = 64;
        !           769:     } else {
        !           770:         for (n = 0; n < 64; n++) {
        !           771:             if (!(T0 & (1ULL << 63)))
        !           772:                 break;
        !           773:             T0 = T0 << 1;
        !           774:         }
        !           775:         T0 = n;
        !           776:     }
        !           777:     RETURN();
        !           778: }
        !           779: 
        !           780: void op_dclz (void)
        !           781: {
        !           782:     int n;
        !           783: 
        !           784:     if (T0 == 0) {
        !           785:         T0 = 64;
        !           786:     } else {
        !           787:         for (n = 0; n < 64; n++) {
        !           788:             if (T0 & (1ULL << 63))
        !           789:                 break;
        !           790:             T0 = T0 << 1;
        !           791:         }
        !           792:         T0 = n;
        !           793:     }
        !           794:     RETURN();
        !           795: }
        !           796: #endif
        !           797: 
        !           798: /* 64 bits arithmetic */
        !           799: #if TARGET_LONG_BITS > HOST_LONG_BITS
        !           800: void op_mult (void)
        !           801: {
        !           802:     CALL_FROM_TB0(do_mult);
        !           803:     RETURN();
        !           804: }
        !           805: 
        !           806: void op_multu (void)
        !           807: {
        !           808:     CALL_FROM_TB0(do_multu);
        !           809:     RETURN();
        !           810: }
        !           811: 
        !           812: void op_madd (void)
        !           813: {
        !           814:     CALL_FROM_TB0(do_madd);
        !           815:     RETURN();
        !           816: }
        !           817: 
        !           818: void op_maddu (void)
        !           819: {
        !           820:     CALL_FROM_TB0(do_maddu);
        !           821:     RETURN();
        !           822: }
        !           823: 
        !           824: void op_msub (void)
        !           825: {
        !           826:     CALL_FROM_TB0(do_msub);
        !           827:     RETURN();
        !           828: }
        !           829: 
        !           830: void op_msubu (void)
        !           831: {
        !           832:     CALL_FROM_TB0(do_msubu);
        !           833:     RETURN();
        !           834: }
        !           835: 
        !           836: #else /* TARGET_LONG_BITS > HOST_LONG_BITS */
        !           837: 
        !           838: static inline uint64_t get_HILO (void)
        !           839: {
        !           840:     return ((uint64_t)env->HI << 32) | ((uint64_t)(uint32_t)env->LO);
        !           841: }
        !           842: 
        !           843: static inline void set_HILO (uint64_t HILO)
        !           844: {
        !           845:     env->LO = (int32_t)(HILO & 0xFFFFFFFF);
        !           846:     env->HI = (int32_t)(HILO >> 32);
        !           847: }
        !           848: 
        !           849: void op_mult (void)
        !           850: {
        !           851:     set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
        !           852:     RETURN();
        !           853: }
        !           854: 
        !           855: void op_multu (void)
        !           856: {
        !           857:     set_HILO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
        !           858:     RETURN();
        !           859: }
        !           860: 
        !           861: void op_madd (void)
        !           862: {
        !           863:     int64_t tmp;
        !           864: 
        !           865:     tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
        !           866:     set_HILO((int64_t)get_HILO() + tmp);
        !           867:     RETURN();
        !           868: }
        !           869: 
        !           870: void op_maddu (void)
        !           871: {
        !           872:     uint64_t tmp;
        !           873: 
        !           874:     tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
        !           875:     set_HILO(get_HILO() + tmp);
        !           876:     RETURN();
        !           877: }
        !           878: 
        !           879: void op_msub (void)
        !           880: {
        !           881:     int64_t tmp;
        !           882: 
        !           883:     tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
        !           884:     set_HILO((int64_t)get_HILO() - tmp);
        !           885:     RETURN();
        !           886: }
        !           887: 
        !           888: void op_msubu (void)
        !           889: {
        !           890:     uint64_t tmp;
        !           891: 
        !           892:     tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
        !           893:     set_HILO(get_HILO() - tmp);
        !           894:     RETURN();
        !           895: }
        !           896: #endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
        !           897: 
        !           898: #ifdef MIPS_HAS_MIPS64
        !           899: void op_dmult (void)
        !           900: {
        !           901:     CALL_FROM_TB0(do_dmult);
        !           902:     RETURN();
        !           903: }
        !           904: 
        !           905: void op_dmultu (void)
        !           906: {
        !           907:     CALL_FROM_TB0(do_dmultu);
        !           908:     RETURN();
        !           909: }
        !           910: #endif
        !           911: 
        !           912: /* Conditional moves */
        !           913: void op_movn (void)
        !           914: {
        !           915:     if (T1 != 0)
        !           916:         env->gpr[PARAM1] = T0;
        !           917:     RETURN();
        !           918: }
        !           919: 
        !           920: void op_movz (void)
        !           921: {
        !           922:     if (T1 == 0)
        !           923:         env->gpr[PARAM1] = T0;
        !           924:     RETURN();
        !           925: }
        !           926: 
        !           927: #ifdef MIPS_USES_FPU
        !           928: void op_movf (void)
        !           929: {
        !           930:     if (!(env->fcr31 & PARAM1))
        !           931:         env->gpr[PARAM2] = env->gpr[PARAM3];
        !           932:     RETURN();
        !           933: }
        !           934: 
        !           935: void op_movt (void)
        !           936: {
        !           937:     if (env->fcr31 & PARAM1)
        !           938:         env->gpr[PARAM2] = env->gpr[PARAM3];
        !           939:     RETURN();
        !           940: }
        !           941: #endif
        !           942: 
        !           943: /* Tests */
        !           944: #define OP_COND(name, cond) \
        !           945: void glue(op_, name) (void) \
        !           946: {                           \
        !           947:     if (cond) {             \
        !           948:         T0 = 1;             \
        !           949:     } else {                \
        !           950:         T0 = 0;             \
        !           951:     }                       \
        !           952:     RETURN();               \
        !           953: }
        !           954: 
        !           955: OP_COND(eq, T0 == T1);
        !           956: OP_COND(ne, T0 != T1);
        !           957: OP_COND(ge, (int32_t)T0 >= (int32_t)T1);
        !           958: OP_COND(geu, T0 >= T1);
        !           959: OP_COND(lt, (int32_t)T0 < (int32_t)T1);
        !           960: OP_COND(ltu, T0 < T1);
        !           961: OP_COND(gez, (int32_t)T0 >= 0);
        !           962: OP_COND(gtz, (int32_t)T0 > 0);
        !           963: OP_COND(lez, (int32_t)T0 <= 0);
        !           964: OP_COND(ltz, (int32_t)T0 < 0);
        !           965: 
        !           966: /* Branches */
        !           967: //#undef USE_DIRECT_JUMP
        !           968: 
        !           969: void OPPROTO op_goto_tb0(void)
        !           970: {
        !           971:     GOTO_TB(op_goto_tb0, PARAM1, 0);
        !           972:     RETURN();
        !           973: }
        !           974: 
        !           975: void OPPROTO op_goto_tb1(void)
        !           976: {
        !           977:     GOTO_TB(op_goto_tb1, PARAM1, 1);
        !           978:     RETURN();
        !           979: }
        !           980: 
        !           981: /* Branch to register */
        !           982: void op_save_breg_target (void)
        !           983: {
        !           984:     env->btarget = T2;
        !           985:     RETURN();
        !           986: }
        !           987: 
        !           988: void op_restore_breg_target (void)
        !           989: {
        !           990:     T2 = env->btarget;
        !           991:     RETURN();
        !           992: }
        !           993: 
        !           994: void op_breg (void)
        !           995: {
        !           996:     env->PC = T2;
        !           997:     RETURN();
        !           998: }
        !           999: 
        !          1000: void op_save_btarget (void)
        !          1001: {
        !          1002:     env->btarget = PARAM1;
        !          1003:     RETURN();
        !          1004: }
        !          1005: 
        !          1006: /* Conditional branch */
        !          1007: void op_set_bcond (void)
        !          1008: {
        !          1009:     T2 = T0;
        !          1010:     RETURN();
        !          1011: }
        !          1012: 
        !          1013: void op_save_bcond (void)
        !          1014: {
        !          1015:     env->bcond = T2;
        !          1016:     RETURN();
        !          1017: }
        !          1018: 
        !          1019: void op_restore_bcond (void)
        !          1020: {
        !          1021:     T2 = env->bcond;
        !          1022:     RETURN();
        !          1023: }
        !          1024: 
        !          1025: void op_jnz_T2 (void)
        !          1026: {
        !          1027:     if (T2)
        !          1028:         GOTO_LABEL_PARAM(1);
        !          1029:     RETURN();
        !          1030: }
        !          1031: 
        !          1032: /* CP0 functions */
        !          1033: void op_mfc0_index (void)
        !          1034: {
        !          1035:     T0 = env->CP0_Index;
        !          1036:     RETURN();
        !          1037: }
        !          1038: 
        !          1039: void op_mfc0_random (void)
        !          1040: {
        !          1041:     CALL_FROM_TB0(do_mfc0_random);
        !          1042:     RETURN();
        !          1043: }
        !          1044: 
        !          1045: void op_mfc0_entrylo0 (void)
        !          1046: {
        !          1047:     T0 = (int32_t)env->CP0_EntryLo0;
        !          1048:     RETURN();
        !          1049: }
        !          1050: 
        !          1051: void op_mfc0_entrylo1 (void)
        !          1052: {
        !          1053:     T0 = (int32_t)env->CP0_EntryLo1;
        !          1054:     RETURN();
        !          1055: }
        !          1056: 
        !          1057: void op_mfc0_context (void)
        !          1058: {
        !          1059:     T0 = (int32_t)env->CP0_Context;
        !          1060:     RETURN();
        !          1061: }
        !          1062: 
        !          1063: void op_mfc0_pagemask (void)
        !          1064: {
        !          1065:     T0 = env->CP0_PageMask;
        !          1066:     RETURN();
        !          1067: }
        !          1068: 
        !          1069: void op_mfc0_pagegrain (void)
        !          1070: {
        !          1071:     T0 = env->CP0_PageGrain;
        !          1072:     RETURN();
        !          1073: }
        !          1074: 
        !          1075: void op_mfc0_wired (void)
        !          1076: {
        !          1077:     T0 = env->CP0_Wired;
        !          1078:     RETURN();
        !          1079: }
        !          1080: 
        !          1081: void op_mfc0_hwrena (void)
        !          1082: {
        !          1083:     T0 = env->CP0_HWREna;
        !          1084:     RETURN();
        !          1085: }
        !          1086: 
        !          1087: void op_mfc0_badvaddr (void)
        !          1088: {
        !          1089:     T0 = (int32_t)env->CP0_BadVAddr;
        !          1090:     RETURN();
        !          1091: }
        !          1092: 
        !          1093: void op_mfc0_count (void)
        !          1094: {
        !          1095:     CALL_FROM_TB0(do_mfc0_count);
        !          1096:     RETURN();
        !          1097: }
        !          1098: 
        !          1099: void op_mfc0_entryhi (void)
        !          1100: {
        !          1101:     T0 = (int32_t)env->CP0_EntryHi;
        !          1102:     RETURN();
        !          1103: }
        !          1104: 
        !          1105: void op_mfc0_compare (void)
        !          1106: {
        !          1107:     T0 = env->CP0_Compare;
        !          1108:     RETURN();
        !          1109: }
        !          1110: 
        !          1111: void op_mfc0_status (void)
        !          1112: {
        !          1113:     T0 = env->CP0_Status;
        !          1114:     if (env->hflags & MIPS_HFLAG_UM)
        !          1115:         T0 |= (1 << CP0St_UM);
        !          1116:     if (env->hflags & MIPS_HFLAG_ERL)
        !          1117:         T0 |= (1 << CP0St_ERL);
        !          1118:     if (env->hflags & MIPS_HFLAG_EXL)
        !          1119:         T0 |= (1 << CP0St_EXL);
        !          1120:     RETURN();
        !          1121: }
        !          1122: 
        !          1123: void op_mfc0_intctl (void)
        !          1124: {
        !          1125:     T0 = env->CP0_IntCtl;
        !          1126:     RETURN();
        !          1127: }
        !          1128: 
        !          1129: void op_mfc0_srsctl (void)
        !          1130: {
        !          1131:     T0 = env->CP0_SRSCtl;
        !          1132:     RETURN();
        !          1133: }
        !          1134: 
        !          1135: void op_mfc0_srsmap (void)
        !          1136: {
        !          1137:     T0 = env->CP0_SRSMap;
        !          1138:     RETURN();
        !          1139: }
        !          1140: 
        !          1141: void op_mfc0_cause (void)
        !          1142: {
        !          1143:     T0 = env->CP0_Cause;
        !          1144:     RETURN();
        !          1145: }
        !          1146: 
        !          1147: void op_mfc0_epc (void)
        !          1148: {
        !          1149:     T0 = (int32_t)env->CP0_EPC;
        !          1150:     RETURN();
        !          1151: }
        !          1152: 
        !          1153: void op_mfc0_prid (void)
        !          1154: {
        !          1155:     T0 = env->CP0_PRid;
        !          1156:     RETURN();
        !          1157: }
        !          1158: 
        !          1159: void op_mfc0_ebase (void)
        !          1160: {
        !          1161:     T0 = env->CP0_EBase;
        !          1162:     RETURN();
        !          1163: }
        !          1164: 
        !          1165: void op_mfc0_config0 (void)
        !          1166: {
        !          1167:     T0 = env->CP0_Config0;
        !          1168:     RETURN();
        !          1169: }
        !          1170: 
        !          1171: void op_mfc0_config1 (void)
        !          1172: {
        !          1173:     T0 = env->CP0_Config1;
        !          1174:     RETURN();
        !          1175: }
        !          1176: 
        !          1177: void op_mfc0_config2 (void)
        !          1178: {
        !          1179:     T0 = env->CP0_Config2;
        !          1180:     RETURN();
        !          1181: }
        !          1182: 
        !          1183: void op_mfc0_config3 (void)
        !          1184: {
        !          1185:     T0 = env->CP0_Config3;
        !          1186:     RETURN();
        !          1187: }
        !          1188: 
        !          1189: void op_mfc0_lladdr (void)
        !          1190: {
        !          1191:     T0 = (int32_t)env->CP0_LLAddr >> 4;
        !          1192:     RETURN();
        !          1193: }
        !          1194: 
        !          1195: void op_mfc0_watchlo0 (void)
        !          1196: {
        !          1197:     T0 = (int32_t)env->CP0_WatchLo;
        !          1198:     RETURN();
        !          1199: }
        !          1200: 
        !          1201: void op_mfc0_watchhi0 (void)
        !          1202: {
        !          1203:     T0 = env->CP0_WatchHi;
        !          1204:     RETURN();
        !          1205: }
        !          1206: 
        !          1207: void op_mfc0_xcontext (void)
        !          1208: {
        !          1209:     T0 = (int32_t)env->CP0_XContext;
        !          1210:     RETURN();
        !          1211: }
        !          1212: 
        !          1213: void op_mfc0_framemask (void)
        !          1214: {
        !          1215:     T0 = env->CP0_Framemask;
        !          1216:     RETURN();
        !          1217: }
        !          1218: 
        !          1219: void op_mfc0_debug (void)
        !          1220: {
        !          1221:     T0 = env->CP0_Debug;
        !          1222:     if (env->hflags & MIPS_HFLAG_DM)
        !          1223:         T0 |= 1 << CP0DB_DM;
        !          1224:     RETURN();
        !          1225: }
        !          1226: 
        !          1227: void op_mfc0_depc (void)
        !          1228: {
        !          1229:     T0 = (int32_t)env->CP0_DEPC;
        !          1230:     RETURN();
        !          1231: }
        !          1232: 
        !          1233: void op_mfc0_performance0 (void)
        !          1234: {
        !          1235:     T0 = env->CP0_Performance0;
        !          1236:     RETURN();
        !          1237: }
        !          1238: 
        !          1239: void op_mfc0_taglo (void)
        !          1240: {
        !          1241:     T0 = env->CP0_TagLo;
        !          1242:     RETURN();
        !          1243: }
        !          1244: 
        !          1245: void op_mfc0_datalo (void)
        !          1246: {
        !          1247:     T0 = env->CP0_DataLo;
        !          1248:     RETURN();
        !          1249: }
        !          1250: 
        !          1251: void op_mfc0_taghi (void)
        !          1252: {
        !          1253:     T0 = env->CP0_TagHi;
        !          1254:     RETURN();
        !          1255: }
        !          1256: 
        !          1257: void op_mfc0_datahi (void)
        !          1258: {
        !          1259:     T0 = env->CP0_DataHi;
        !          1260:     RETURN();
        !          1261: }
        !          1262: 
        !          1263: void op_mfc0_errorepc (void)
        !          1264: {
        !          1265:     T0 = (int32_t)env->CP0_ErrorEPC;
        !          1266:     RETURN();
        !          1267: }
        !          1268: 
        !          1269: void op_mfc0_desave (void)
        !          1270: {
        !          1271:     T0 = env->CP0_DESAVE;
        !          1272:     RETURN();
        !          1273: }
        !          1274: 
        !          1275: void op_mtc0_index (void)
        !          1276: {
        !          1277:     env->CP0_Index = (env->CP0_Index & 0x80000000) | (T0 & (MIPS_TLB_NB - 1));
        !          1278:     RETURN();
        !          1279: }
        !          1280: 
        !          1281: void op_mtc0_entrylo0 (void)
        !          1282: {
        !          1283:     /* Large physaddr not implemented */
        !          1284:     /* 1k pages not implemented */
        !          1285:     env->CP0_EntryLo0 = (int32_t)T0 & 0x3FFFFFFF;
        !          1286:     RETURN();
        !          1287: }
        !          1288: 
        !          1289: void op_mtc0_entrylo1 (void)
        !          1290: {
        !          1291:     /* Large physaddr not implemented */
        !          1292:     /* 1k pages not implemented */
        !          1293:     env->CP0_EntryLo1 = (int32_t)T0 & 0x3FFFFFFF;
        !          1294:     RETURN();
        !          1295: }
        !          1296: 
        !          1297: void op_mtc0_context (void)
        !          1298: {
        !          1299:     env->CP0_Context = (env->CP0_Context & ~0x007FFFFF) | (T0 & 0x007FFFF0);
        !          1300:     RETURN();
        !          1301: }
        !          1302: 
        !          1303: void op_mtc0_pagemask (void)
1.1       root     1304: {
1.1.1.5 ! root     1305:     /* 1k pages not implemented */
        !          1306:     env->CP0_PageMask = T0 & 0x1FFFE000;
1.1       root     1307:     RETURN();
                   1308: }
                   1309: 
1.1.1.5 ! root     1310: void op_mtc0_pagegrain (void)
1.1       root     1311: {
1.1.1.5 ! root     1312:     /* SmartMIPS not implemented */
        !          1313:     /* Large physaddr not implemented */
        !          1314:     /* 1k pages not implemented */
        !          1315:     env->CP0_PageGrain = 0;
1.1       root     1316:     RETURN();
                   1317: }
                   1318: 
1.1.1.5 ! root     1319: void op_mtc0_wired (void)
1.1       root     1320: {
1.1.1.5 ! root     1321:     env->CP0_Wired = T0 & (MIPS_TLB_NB - 1);
1.1       root     1322:     RETURN();
                   1323: }
                   1324: 
1.1.1.5 ! root     1325: void op_mtc0_hwrena (void)
1.1       root     1326: {
1.1.1.5 ! root     1327:     env->CP0_HWREna = T0 & 0x0000000F;
1.1       root     1328:     RETURN();
                   1329: }
                   1330: 
1.1.1.5 ! root     1331: void op_mtc0_count (void)
1.1       root     1332: {
1.1.1.5 ! root     1333:     CALL_FROM_TB2(cpu_mips_store_count, env, T0);
1.1       root     1334:     RETURN();
                   1335: }
                   1336: 
1.1.1.5 ! root     1337: void op_mtc0_entryhi (void)
1.1       root     1338: {
1.1.1.5 ! root     1339:     target_ulong old, val;
        !          1340: 
        !          1341:     /* 1k pages not implemented */
        !          1342:     /* Ignore MIPS64 TLB for now */
        !          1343:     val = (int32_t)T0 & 0xFFFFE0FF;
        !          1344:     old = env->CP0_EntryHi;
        !          1345:     env->CP0_EntryHi = val;
        !          1346:     /* If the ASID changes, flush qemu's TLB.  */
        !          1347:     if ((old & 0xFF) != (val & 0xFF))
        !          1348:         CALL_FROM_TB2(cpu_mips_tlb_flush, env, 1);
1.1       root     1349:     RETURN();
                   1350: }
                   1351: 
1.1.1.5 ! root     1352: void op_mtc0_compare (void)
1.1       root     1353: {
1.1.1.5 ! root     1354:     CALL_FROM_TB2(cpu_mips_store_compare, env, T0);
1.1       root     1355:     RETURN();
                   1356: }
                   1357: 
1.1.1.5 ! root     1358: void op_mtc0_status (void)
1.1       root     1359: {
1.1.1.5 ! root     1360:     uint32_t val, old;
        !          1361: 
        !          1362:     val = (int32_t)T0 & 0xFA78FF01;
        !          1363:     old = env->CP0_Status;
        !          1364:     if (T0 & (1 << CP0St_UM))
        !          1365:         env->hflags |= MIPS_HFLAG_UM;
        !          1366:     else
        !          1367:         env->hflags &= ~MIPS_HFLAG_UM;
        !          1368:     if (T0 & (1 << CP0St_ERL))
        !          1369:         env->hflags |= MIPS_HFLAG_ERL;
        !          1370:     else
        !          1371:         env->hflags &= ~MIPS_HFLAG_ERL;
        !          1372:     if (T0 & (1 << CP0St_EXL))
        !          1373:         env->hflags |= MIPS_HFLAG_EXL;
        !          1374:     else
        !          1375:         env->hflags &= ~MIPS_HFLAG_EXL;
        !          1376:     env->CP0_Status = val;
        !          1377:     if (loglevel & CPU_LOG_TB_IN_ASM)
        !          1378:        CALL_FROM_TB2(do_mtc0_status_debug, old, val);
        !          1379:     CALL_FROM_TB1(cpu_mips_update_irq, env);
1.1       root     1380:     RETURN();
                   1381: }
                   1382: 
1.1.1.5 ! root     1383: void op_mtc0_intctl (void)
1.1       root     1384: {
1.1.1.5 ! root     1385:     /* vectored interrupts not implemented */
        !          1386:     env->CP0_IntCtl = 0;
1.1       root     1387:     RETURN();
                   1388: }
                   1389: 
1.1.1.5 ! root     1390: void op_mtc0_srsctl (void)
1.1       root     1391: {
1.1.1.5 ! root     1392:     /* shadow registers not implemented */
        !          1393:     env->CP0_SRSCtl = 0;
1.1       root     1394:     RETURN();
                   1395: }
                   1396: 
1.1.1.5 ! root     1397: void op_mtc0_srsmap (void)
1.1       root     1398: {
1.1.1.5 ! root     1399:     /* shadow registers not implemented */
        !          1400:     env->CP0_SRSMap = 0;
1.1       root     1401:     RETURN();
                   1402: }
                   1403: 
1.1.1.5 ! root     1404: void op_mtc0_cause (void)
1.1       root     1405: {
1.1.1.5 ! root     1406:     env->CP0_Cause = (env->CP0_Cause & 0xB000F87C) | (T0 & 0x00C00300);
        !          1407: 
        !          1408:     /* Handle the software interrupt as an hardware one, as they
        !          1409:        are very similar */
        !          1410:     if (T0 & CP0Ca_IP_mask) {
        !          1411:         CALL_FROM_TB1(cpu_mips_update_irq, env);
        !          1412:     }
1.1       root     1413:     RETURN();
                   1414: }
                   1415: 
1.1.1.5 ! root     1416: void op_mtc0_epc (void)
1.1       root     1417: {
1.1.1.5 ! root     1418:     env->CP0_EPC = (int32_t)T0;
1.1       root     1419:     RETURN();
                   1420: }
                   1421: 
1.1.1.5 ! root     1422: void op_mtc0_ebase (void)
1.1       root     1423: {
1.1.1.5 ! root     1424:     /* vectored interrupts not implemented */
        !          1425:     /* Multi-CPU not implemented */
        !          1426:     env->CP0_EBase = 0x80000000 | (T0 & 0x3FFFF000);
1.1       root     1427:     RETURN();
                   1428: }
                   1429: 
1.1.1.5 ! root     1430: void op_mtc0_config0 (void)
1.1       root     1431: {
1.1.1.5 ! root     1432: #if defined(MIPS_USES_R4K_TLB)
        !          1433:      /* Fixed mapping MMU not implemented */
        !          1434:     env->CP0_Config0 = (env->CP0_Config0 & 0x8017FF88) | (T0 & 0x00000001);
        !          1435: #else
        !          1436:     env->CP0_Config0 = (env->CP0_Config0 & 0xFE17FF88) | (T0 & 0x00000001);
        !          1437: #endif
1.1       root     1438:     RETURN();
                   1439: }
                   1440: 
1.1.1.5 ! root     1441: void op_mtc0_config2 (void)
1.1       root     1442: {
1.1.1.5 ! root     1443:     /* tertiary/secondary caches not implemented */
        !          1444:     env->CP0_Config2 = (env->CP0_Config2 & 0x8FFF0FFF);
1.1       root     1445:     RETURN();
                   1446: }
                   1447: 
1.1.1.5 ! root     1448: void op_mtc0_watchlo0 (void)
1.1       root     1449: {
1.1.1.5 ! root     1450:     env->CP0_WatchLo = (int32_t)T0;
1.1       root     1451:     RETURN();
                   1452: }
                   1453: 
1.1.1.5 ! root     1454: void op_mtc0_watchhi0 (void)
1.1       root     1455: {
1.1.1.5 ! root     1456:     env->CP0_WatchHi = T0 & 0x40FF0FF8;
        !          1457:     RETURN();
1.1       root     1458: }
                   1459: 
1.1.1.5 ! root     1460: void op_mtc0_xcontext (void)
1.1       root     1461: {
1.1.1.5 ! root     1462:     env->CP0_XContext = (int32_t)T0; /* XXX */
        !          1463:     RETURN();
1.1       root     1464: }
                   1465: 
1.1.1.5 ! root     1466: void op_mtc0_framemask (void)
1.1       root     1467: {
1.1.1.5 ! root     1468:     env->CP0_Framemask = T0; /* XXX */
1.1       root     1469:     RETURN();
                   1470: }
                   1471: 
1.1.1.5 ! root     1472: void op_mtc0_debug (void)
1.1       root     1473: {
1.1.1.5 ! root     1474:     env->CP0_Debug = (env->CP0_Debug & 0x8C03FC1F) | (T0 & 0x13300120);
        !          1475:     if (T0 & (1 << CP0DB_DM))
        !          1476:         env->hflags |= MIPS_HFLAG_DM;
        !          1477:     else
        !          1478:         env->hflags &= ~MIPS_HFLAG_DM;
1.1       root     1479:     RETURN();
                   1480: }
                   1481: 
1.1.1.5 ! root     1482: void op_mtc0_depc (void)
1.1       root     1483: {
1.1.1.5 ! root     1484:     env->CP0_DEPC = (int32_t)T0;
1.1       root     1485:     RETURN();
                   1486: }
                   1487: 
1.1.1.5 ! root     1488: void op_mtc0_performance0 (void)
1.1       root     1489: {
1.1.1.5 ! root     1490:     env->CP0_Performance0 = T0; /* XXX */
1.1       root     1491:     RETURN();
                   1492: }
                   1493: 
1.1.1.5 ! root     1494: void op_mtc0_taglo (void)
1.1       root     1495: {
1.1.1.5 ! root     1496:     env->CP0_TagLo = T0 & 0xFFFFFCF6;
1.1       root     1497:     RETURN();
                   1498: }
                   1499: 
1.1.1.5 ! root     1500: void op_mtc0_datalo (void)
1.1       root     1501: {
1.1.1.5 ! root     1502:     env->CP0_DataLo = T0; /* XXX */
1.1       root     1503:     RETURN();
                   1504: }
1.1.1.5 ! root     1505: 
        !          1506: void op_mtc0_taghi (void)
1.1       root     1507: {
1.1.1.5 ! root     1508:     env->CP0_TagHi = T0; /* XXX */
1.1       root     1509:     RETURN();
                   1510: }
                   1511: 
1.1.1.5 ! root     1512: void op_mtc0_datahi (void)
1.1       root     1513: {
1.1.1.5 ! root     1514:     env->CP0_DataHi = T0; /* XXX */
1.1       root     1515:     RETURN();
                   1516: }
                   1517: 
1.1.1.5 ! root     1518: void op_mtc0_errorepc (void)
1.1       root     1519: {
1.1.1.5 ! root     1520:     env->CP0_ErrorEPC = (int32_t)T0;
1.1       root     1521:     RETURN();
                   1522: }
                   1523: 
1.1.1.5 ! root     1524: void op_mtc0_desave (void)
1.1       root     1525: {
1.1.1.5 ! root     1526:     env->CP0_DESAVE = T0;
1.1       root     1527:     RETURN();
                   1528: }
                   1529: 
1.1.1.5 ! root     1530: void op_dmfc0_entrylo0 (void)
1.1       root     1531: {
1.1.1.5 ! root     1532:     T0 = env->CP0_EntryLo0;
1.1       root     1533:     RETURN();
                   1534: }
                   1535: 
1.1.1.5 ! root     1536: void op_dmfc0_entrylo1 (void)
1.1       root     1537: {
1.1.1.5 ! root     1538:     T0 = env->CP0_EntryLo1;
1.1       root     1539:     RETURN();
                   1540: }
                   1541: 
1.1.1.5 ! root     1542: void op_dmfc0_context (void)
1.1       root     1543: {
1.1.1.5 ! root     1544:     T0 = env->CP0_Context;
1.1       root     1545:     RETURN();
                   1546: }
                   1547: 
1.1.1.5 ! root     1548: void op_dmfc0_badvaddr (void)
1.1       root     1549: {
1.1.1.5 ! root     1550:     T0 = env->CP0_BadVAddr;
1.1       root     1551:     RETURN();
                   1552: }
                   1553: 
1.1.1.5 ! root     1554: void op_dmfc0_entryhi (void)
        !          1555: {
        !          1556:     T0 = env->CP0_EntryHi;
        !          1557:     RETURN();
1.1       root     1558: }
                   1559: 
1.1.1.5 ! root     1560: void op_dmfc0_epc (void)
        !          1561: {
        !          1562:     T0 = env->CP0_EPC;
        !          1563:     RETURN();
        !          1564: }
1.1       root     1565: 
1.1.1.5 ! root     1566: void op_dmfc0_lladdr (void)
        !          1567: {
        !          1568:     T0 = env->CP0_LLAddr >> 4;
        !          1569:     RETURN();
        !          1570: }
1.1.1.2   root     1571: 
1.1.1.5 ! root     1572: void op_dmfc0_watchlo0 (void)
1.1.1.2   root     1573: {
1.1.1.5 ! root     1574:     T0 = env->CP0_WatchLo;
        !          1575:     RETURN();
1.1.1.2   root     1576: }
                   1577: 
1.1.1.5 ! root     1578: void op_dmfc0_xcontext (void)
1.1.1.2   root     1579: {
1.1.1.5 ! root     1580:     T0 = env->CP0_XContext;
        !          1581:     RETURN();
1.1.1.2   root     1582: }
1.1       root     1583: 
1.1.1.5 ! root     1584: void op_dmfc0_depc (void)
1.1       root     1585: {
1.1.1.5 ! root     1586:     T0 = env->CP0_DEPC;
        !          1587:     RETURN();
1.1       root     1588: }
                   1589: 
1.1.1.5 ! root     1590: void op_dmfc0_errorepc (void)
1.1       root     1591: {
1.1.1.5 ! root     1592:     T0 = env->CP0_ErrorEPC;
        !          1593:     RETURN();
1.1       root     1594: }
                   1595: 
1.1.1.5 ! root     1596: void op_dmtc0_entrylo0 (void)
1.1       root     1597: {
1.1.1.5 ! root     1598:     /* Large physaddr not implemented */
        !          1599:     /* 1k pages not implemented */
        !          1600:     env->CP0_EntryLo0 = T0 & 0x3FFFFFFF;
1.1       root     1601:     RETURN();
                   1602: }
                   1603: 
1.1.1.5 ! root     1604: void op_dmtc0_entrylo1 (void)
1.1       root     1605: {
1.1.1.5 ! root     1606:     /* Large physaddr not implemented */
        !          1607:     /* 1k pages not implemented */
        !          1608:     env->CP0_EntryLo1 = T0 & 0x3FFFFFFF;
1.1       root     1609:     RETURN();
                   1610: }
                   1611: 
1.1.1.5 ! root     1612: void op_dmtc0_context (void)
1.1       root     1613: {
1.1.1.5 ! root     1614:     env->CP0_Context = (env->CP0_Context & ~0x007FFFFF) | (T0 & 0x007FFFF0);
1.1       root     1615:     RETURN();
                   1616: }
                   1617: 
1.1.1.5 ! root     1618: void op_dmtc0_epc (void)
1.1       root     1619: {
1.1.1.5 ! root     1620:     env->CP0_EPC = T0;
1.1       root     1621:     RETURN();
                   1622: }
                   1623: 
1.1.1.5 ! root     1624: void op_dmtc0_watchlo0 (void)
1.1       root     1625: {
1.1.1.5 ! root     1626:     env->CP0_WatchLo = T0;
1.1       root     1627:     RETURN();
                   1628: }
                   1629: 
1.1.1.5 ! root     1630: void op_dmtc0_xcontext (void)
1.1       root     1631: {
1.1.1.5 ! root     1632:     env->CP0_XContext = T0; /* XXX */
1.1       root     1633:     RETURN();
                   1634: }
                   1635: 
1.1.1.5 ! root     1636: void op_dmtc0_depc (void)
1.1       root     1637: {
1.1.1.5 ! root     1638:     env->CP0_DEPC = T0;
1.1       root     1639:     RETURN();
                   1640: }
                   1641: 
1.1.1.5 ! root     1642: void op_dmtc0_errorepc (void)
1.1       root     1643: {
1.1.1.5 ! root     1644:     env->CP0_ErrorEPC = T0;
1.1       root     1645:     RETURN();
                   1646: }
                   1647: 
1.1.1.4   root     1648: #ifdef MIPS_USES_FPU
                   1649: 
                   1650: #if 0
                   1651: # define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env)
                   1652: #else
                   1653: # define DEBUG_FPU_STATE() do { } while(0)
                   1654: #endif
                   1655: 
                   1656: void op_cp1_enabled(void)
                   1657: {
                   1658:     if (!(env->CP0_Status & (1 << CP0St_CU1))) {
                   1659:         CALL_FROM_TB2(do_raise_exception_err, EXCP_CpU, 1);
                   1660:     }
                   1661:     RETURN();
                   1662: }
                   1663: 
                   1664: /* CP1 functions */
                   1665: void op_cfc1 (void)
                   1666: {
                   1667:     if (T1 == 0) {
                   1668:         T0 = env->fcr0;
                   1669:     }
                   1670:     else {
                   1671:         /* fetch fcr31, masking unused bits */
                   1672:         T0 = env->fcr31 & 0x0183FFFF;
                   1673:     }
                   1674:     DEBUG_FPU_STATE();
                   1675:     RETURN();
                   1676: }
                   1677: 
                   1678: /* convert MIPS rounding mode in FCR31 to IEEE library */
                   1679: unsigned int ieee_rm[] = { 
                   1680:     float_round_nearest_even,
                   1681:     float_round_to_zero,
                   1682:     float_round_up,
                   1683:     float_round_down
                   1684: };
                   1685: 
                   1686: #define RESTORE_ROUNDING_MODE \
                   1687:     set_float_rounding_mode(ieee_rm[env->fcr31 & 3], &env->fp_status)
                   1688: 
                   1689: void op_ctc1 (void)
                   1690: {
                   1691:     if (T1 == 0) {
                   1692:         /* XXX should this throw an exception?
                   1693:          * don't write to FCR0.
                   1694:          * env->fcr0 = T0; 
                   1695:          */
                   1696:     }
                   1697:     else {
                   1698:         /* store new fcr31, masking unused bits */  
                   1699:         env->fcr31 = T0 & 0x0183FFFF;
                   1700: 
                   1701:         /* set rounding mode */
                   1702:         RESTORE_ROUNDING_MODE;
                   1703: 
                   1704: #ifndef CONFIG_SOFTFLOAT
                   1705:         /* no floating point exception for native float */
                   1706:         SET_FP_ENABLE(env->fcr31, 0);
                   1707: #endif
                   1708:     }
                   1709:     DEBUG_FPU_STATE();
                   1710:     RETURN();
                   1711: }
                   1712: 
                   1713: void op_mfc1 (void)
                   1714: {
                   1715:     T0 = WT0;
                   1716:     DEBUG_FPU_STATE();
                   1717:     RETURN();
                   1718: }
                   1719: 
                   1720: void op_mtc1 (void)
                   1721: {
                   1722:     WT0 = T0;
                   1723:     DEBUG_FPU_STATE();
                   1724:     RETURN();
                   1725: }
                   1726: 
                   1727: /* Float support.
                   1728:    Single precition routines have a "s" suffix, double precision a
                   1729:    "d" suffix.  */
                   1730: 
                   1731: #define FLOAT_OP(name, p) void OPPROTO op_float_##name##_##p(void)
                   1732: 
1.1.1.5 ! root     1733: FLOAT_OP(cvtd, s)
        !          1734: {
        !          1735:     FDT2 = float32_to_float64(WT0, &env->fp_status);
        !          1736:     DEBUG_FPU_STATE();
        !          1737:     RETURN();
        !          1738: }
1.1.1.4   root     1739: FLOAT_OP(cvtd, w)
                   1740: {
                   1741:     FDT2 = int32_to_float64(WT0, &env->fp_status);
                   1742:     DEBUG_FPU_STATE();
                   1743:     RETURN();
                   1744: }
1.1.1.5 ! root     1745: FLOAT_OP(cvts, d)
        !          1746: {
        !          1747:     FST2 = float64_to_float32(FDT0, &env->fp_status);
        !          1748:     DEBUG_FPU_STATE();
        !          1749:     RETURN();
        !          1750: }
1.1.1.4   root     1751: FLOAT_OP(cvts, w)
                   1752: {
                   1753:     FST2 = int32_to_float32(WT0, &env->fp_status);
                   1754:     DEBUG_FPU_STATE();
                   1755:     RETURN();
                   1756: }
                   1757: FLOAT_OP(cvtw, s)
                   1758: {
                   1759:     WT2 = float32_to_int32(FST0, &env->fp_status);
                   1760:     DEBUG_FPU_STATE();
                   1761:     RETURN();
                   1762: }
                   1763: FLOAT_OP(cvtw, d)
                   1764: {
                   1765:     WT2 = float64_to_int32(FDT0, &env->fp_status);
                   1766:     DEBUG_FPU_STATE();
                   1767:     RETURN();
                   1768: }
                   1769: 
                   1770: FLOAT_OP(roundw, d)
                   1771: {
                   1772:     set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
                   1773:     WT2 = float64_round_to_int(FDT0, &env->fp_status);
                   1774:     RESTORE_ROUNDING_MODE;
                   1775: 
                   1776:     DEBUG_FPU_STATE();
                   1777:     RETURN();
                   1778: }
                   1779: FLOAT_OP(roundw, s)
                   1780: {
                   1781:     set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
                   1782:     WT2 = float32_round_to_int(FST0, &env->fp_status);
                   1783:     RESTORE_ROUNDING_MODE;
                   1784:     DEBUG_FPU_STATE();
                   1785:     RETURN();
                   1786: }
                   1787: 
                   1788: FLOAT_OP(truncw, d)
                   1789: {
                   1790:     WT2 = float64_to_int32_round_to_zero(FDT0, &env->fp_status);
                   1791:     DEBUG_FPU_STATE();
                   1792:     RETURN();
                   1793: }
                   1794: FLOAT_OP(truncw, s)
                   1795: {
                   1796:     WT2 = float32_to_int32_round_to_zero(FST0, &env->fp_status);
                   1797:     DEBUG_FPU_STATE();
                   1798:     RETURN();
                   1799: }
                   1800: 
                   1801: FLOAT_OP(ceilw, d)
                   1802: {
                   1803:     set_float_rounding_mode(float_round_up, &env->fp_status);
                   1804:     WT2 = float64_round_to_int(FDT0, &env->fp_status);
                   1805:     RESTORE_ROUNDING_MODE;
                   1806: 
                   1807:     DEBUG_FPU_STATE();
                   1808:     RETURN();
                   1809: }
                   1810: FLOAT_OP(ceilw, s)
                   1811: {
                   1812:     set_float_rounding_mode(float_round_up, &env->fp_status);
                   1813:     WT2 = float32_round_to_int(FST0, &env->fp_status);
                   1814:     RESTORE_ROUNDING_MODE;
                   1815:     DEBUG_FPU_STATE();
                   1816:     RETURN();
                   1817: }
                   1818: 
                   1819: FLOAT_OP(floorw, d)
                   1820: {
                   1821:     set_float_rounding_mode(float_round_down, &env->fp_status);
                   1822:     WT2 = float64_round_to_int(FDT0, &env->fp_status);
                   1823:     RESTORE_ROUNDING_MODE;
                   1824: 
                   1825:     DEBUG_FPU_STATE();
                   1826:     RETURN();
                   1827: }
                   1828: FLOAT_OP(floorw, s)
                   1829: {
                   1830:     set_float_rounding_mode(float_round_down, &env->fp_status);
                   1831:     WT2 = float32_round_to_int(FST0, &env->fp_status);
                   1832:     RESTORE_ROUNDING_MODE;
                   1833:     DEBUG_FPU_STATE();
                   1834:     RETURN();
                   1835: }
                   1836: 
                   1837: /* binary operations */
                   1838: #define FLOAT_BINOP(name) \
                   1839: FLOAT_OP(name, d)         \
                   1840: {                         \
                   1841:     FDT2 = float64_ ## name (FDT0, FDT1, &env->fp_status);    \
                   1842:     DEBUG_FPU_STATE();    \
                   1843: }                         \
                   1844: FLOAT_OP(name, s)         \
                   1845: {                         \
                   1846:     FST2 = float32_ ## name (FST0, FST1, &env->fp_status);    \
                   1847:     DEBUG_FPU_STATE();    \
                   1848: }
                   1849: FLOAT_BINOP(add)
                   1850: FLOAT_BINOP(sub)
                   1851: FLOAT_BINOP(mul)
                   1852: FLOAT_BINOP(div)
                   1853: #undef FLOAT_BINOP
                   1854: 
                   1855: /* unary operations, modifying fp status  */
                   1856: #define FLOAT_UNOP(name)  \
                   1857: FLOAT_OP(name, d)         \
                   1858: {                         \
                   1859:     FDT2 = float64_ ## name(FDT0, &env->fp_status);   \
                   1860:     DEBUG_FPU_STATE();    \
                   1861: }                         \
                   1862: FLOAT_OP(name, s)         \
                   1863: {                         \
                   1864:     FST2 = float32_ ## name(FST0, &env->fp_status);   \
                   1865:     DEBUG_FPU_STATE();    \
                   1866: }
                   1867: FLOAT_UNOP(sqrt)
                   1868: #undef FLOAT_UNOP
                   1869: 
                   1870: /* unary operations, not modifying fp status  */
                   1871: #define FLOAT_UNOP(name)  \
                   1872: FLOAT_OP(name, d)         \
                   1873: {                         \
                   1874:     FDT2 = float64_ ## name(FDT0);   \
                   1875:     DEBUG_FPU_STATE();    \
                   1876: }                         \
                   1877: FLOAT_OP(name, s)         \
                   1878: {                         \
                   1879:     FST2 = float32_ ## name(FST0);   \
                   1880:     DEBUG_FPU_STATE();    \
                   1881: }
                   1882: FLOAT_UNOP(abs)
                   1883: FLOAT_UNOP(chs)
                   1884: #undef FLOAT_UNOP
                   1885: 
                   1886: FLOAT_OP(mov, d)
                   1887: {
                   1888:     FDT2 = FDT0;
                   1889:     DEBUG_FPU_STATE();
                   1890:     RETURN();
                   1891: }
                   1892: FLOAT_OP(mov, s)
                   1893: {
                   1894:     FST2 = FST0;
                   1895:     DEBUG_FPU_STATE();
                   1896:     RETURN();
                   1897: }
                   1898: 
                   1899: #ifdef CONFIG_SOFTFLOAT
                   1900: #define clear_invalid() do {                                \
                   1901:     int flags = get_float_exception_flags(&env->fp_status); \
                   1902:     flags &= ~float_flag_invalid;                           \
                   1903:     set_float_exception_flags(flags, &env->fp_status);      \
                   1904: } while(0)
                   1905: #else
                   1906: #define clear_invalid() do { } while(0)
                   1907: #endif
                   1908: 
                   1909: extern void dump_fpu_s(CPUState *env);
                   1910: 
                   1911: #define FOP_COND(fmt, op, sig, cond)           \
                   1912: void op_cmp_ ## fmt ## _ ## op (void)          \
                   1913: {                                              \
                   1914:     if (cond)                                  \
                   1915:         SET_FP_COND(env->fcr31);               \
                   1916:     else                                       \
                   1917:         CLEAR_FP_COND(env->fcr31);             \
                   1918:     if (!sig)                                  \
                   1919:         clear_invalid();                       \
                   1920:     /*CALL_FROM_TB1(dump_fpu_s, env);*/ \
                   1921:     DEBUG_FPU_STATE();                         \
                   1922:     RETURN();                                  \
                   1923: }
                   1924: 
1.1.1.5 ! root     1925: int float64_is_unordered(float64 a, float64 b STATUS_PARAM)
1.1.1.4   root     1926: {
                   1927:     if (float64_is_nan(a) || float64_is_nan(b)) {
                   1928:         float_raise(float_flag_invalid, status);
                   1929:         return 1;
                   1930:     }
                   1931:     else {
                   1932:         return 0;
                   1933:     }
                   1934: }
                   1935: 
                   1936: FOP_COND(d, f,   0,                                                      0) 
                   1937: FOP_COND(d, un,  0, float64_is_unordered(FDT1, FDT0, &env->fp_status))
                   1938: FOP_COND(d, eq,  0,                                                      float64_eq(FDT0, FDT1, &env->fp_status))
                   1939: FOP_COND(d, ueq, 0, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_eq(FDT0, FDT1, &env->fp_status))
                   1940: FOP_COND(d, olt, 0,                                                      float64_lt(FDT0, FDT1, &env->fp_status))
                   1941: FOP_COND(d, ult, 0, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_lt(FDT0, FDT1, &env->fp_status))
                   1942: FOP_COND(d, ole, 0,                                                      float64_le(FDT0, FDT1, &env->fp_status))
                   1943: FOP_COND(d, ule, 0, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_le(FDT0, FDT1, &env->fp_status))
                   1944: /* NOTE: the comma operator will make "cond" to eval to false,
                   1945:  * but float*_is_unordered() is still called
                   1946:  */
                   1947: FOP_COND(d, sf,  1,                                                      (float64_is_unordered(FDT0, FDT1, &env->fp_status), 0))
                   1948: FOP_COND(d, ngle,1, float64_is_unordered(FDT1, FDT0, &env->fp_status))
                   1949: FOP_COND(d, seq, 1,                                                      float64_eq(FDT0, FDT1, &env->fp_status))
                   1950: FOP_COND(d, ngl, 1, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_eq(FDT0, FDT1, &env->fp_status))
                   1951: FOP_COND(d, lt,  1,                                                      float64_lt(FDT0, FDT1, &env->fp_status))
                   1952: FOP_COND(d, nge, 1, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_lt(FDT0, FDT1, &env->fp_status))
                   1953: FOP_COND(d, le,  1,                                                      float64_le(FDT0, FDT1, &env->fp_status))
                   1954: FOP_COND(d, ngt, 1, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_le(FDT0, FDT1, &env->fp_status))
                   1955: 
                   1956: flag float32_is_unordered(float32 a, float32 b STATUS_PARAM)
                   1957: {
                   1958:     extern flag float32_is_nan( float32 a );
                   1959:     if (float32_is_nan(a) || float32_is_nan(b)) {
                   1960:         float_raise(float_flag_invalid, status);
                   1961:         return 1;
                   1962:     }
                   1963:     else {
                   1964:         return 0;
                   1965:     }
                   1966: }
                   1967: 
                   1968: /* NOTE: the comma operator will make "cond" to eval to false,
                   1969:  * but float*_is_unordered() is still called
                   1970:  */
                   1971: FOP_COND(s, f,   0,                                                      0) 
                   1972: FOP_COND(s, un,  0, float32_is_unordered(FST1, FST0, &env->fp_status))
                   1973: FOP_COND(s, eq,  0,                                                      float32_eq(FST0, FST1, &env->fp_status))
                   1974: FOP_COND(s, ueq, 0, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status))
                   1975: FOP_COND(s, olt, 0,                                                      float32_lt(FST0, FST1, &env->fp_status))
                   1976: FOP_COND(s, ult, 0, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_lt(FST0, FST1, &env->fp_status))
                   1977: FOP_COND(s, ole, 0,                                                      float32_le(FST0, FST1, &env->fp_status))
                   1978: FOP_COND(s, ule, 0, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_le(FST0, FST1, &env->fp_status))
                   1979: /* NOTE: the comma operator will make "cond" to eval to false,
                   1980:  * but float*_is_unordered() is still called
                   1981:  */
                   1982: FOP_COND(s, sf,  1,                                                      (float32_is_unordered(FST0, FST1, &env->fp_status), 0))
                   1983: FOP_COND(s, ngle,1, float32_is_unordered(FST1, FST0, &env->fp_status))
                   1984: FOP_COND(s, seq, 1,                                                      float32_eq(FST0, FST1, &env->fp_status))
                   1985: FOP_COND(s, ngl, 1, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status))
                   1986: FOP_COND(s, lt,  1,                                                      float32_lt(FST0, FST1, &env->fp_status))
                   1987: FOP_COND(s, nge, 1, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_lt(FST0, FST1, &env->fp_status))
                   1988: FOP_COND(s, le,  1,                                                      float32_le(FST0, FST1, &env->fp_status))
                   1989: FOP_COND(s, ngt, 1, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_le(FST0, FST1, &env->fp_status))
                   1990: 
                   1991: void op_bc1f (void)
                   1992: {
                   1993:     T0 = ! IS_FP_COND_SET(env->fcr31);
                   1994:     DEBUG_FPU_STATE();
                   1995:     RETURN();
                   1996: }
                   1997: 
                   1998: void op_bc1t (void)
                   1999: {
                   2000:     T0 = IS_FP_COND_SET(env->fcr31);
                   2001:     DEBUG_FPU_STATE();
                   2002:     RETURN();
                   2003: }
                   2004: #endif /* MIPS_USES_FPU */
                   2005: 
1.1       root     2006: #if defined(MIPS_USES_R4K_TLB)
                   2007: void op_tlbwi (void)
                   2008: {
                   2009:     CALL_FROM_TB0(do_tlbwi);
                   2010:     RETURN();
                   2011: }
                   2012: 
                   2013: void op_tlbwr (void)
                   2014: {
                   2015:     CALL_FROM_TB0(do_tlbwr);
                   2016:     RETURN();
                   2017: }
                   2018: 
                   2019: void op_tlbp (void)
                   2020: {
                   2021:     CALL_FROM_TB0(do_tlbp);
                   2022:     RETURN();
                   2023: }
                   2024: 
                   2025: void op_tlbr (void)
                   2026: {
                   2027:     CALL_FROM_TB0(do_tlbr);
                   2028:     RETURN();
                   2029: }
                   2030: #endif
                   2031: 
                   2032: /* Specials */
                   2033: void op_pmon (void)
                   2034: {
                   2035:     CALL_FROM_TB1(do_pmon, PARAM1);
1.1.1.5 ! root     2036:     RETURN();
        !          2037: }
        !          2038: 
        !          2039: void op_di (void)
        !          2040: {
        !          2041:     T0 = env->CP0_Status;
        !          2042:     env->CP0_Status = T0 & ~(1 << CP0St_IE);
        !          2043:     CALL_FROM_TB1(cpu_mips_update_irq, env);
        !          2044:     RETURN();
        !          2045: }
        !          2046: 
        !          2047: void op_ei (void)
        !          2048: {
        !          2049:     T0 = env->CP0_Status;
        !          2050:     env->CP0_Status = T0 | (1 << CP0St_IE);
        !          2051:     CALL_FROM_TB1(cpu_mips_update_irq, env);
        !          2052:     RETURN();
1.1       root     2053: }
                   2054: 
                   2055: void op_trap (void)
                   2056: {
                   2057:     if (T0) {
1.1.1.2   root     2058:         CALL_FROM_TB1(do_raise_exception_direct, EXCP_TRAP);
1.1       root     2059:     }
                   2060:     RETURN();
                   2061: }
                   2062: 
1.1.1.2   root     2063: void op_debug (void)
                   2064: {
1.1.1.5 ! root     2065:     CALL_FROM_TB1(do_raise_exception, EXCP_DEBUG);
        !          2066:     RETURN();
1.1.1.2   root     2067: }
                   2068: 
1.1       root     2069: void op_set_lladdr (void)
                   2070: {
                   2071:     env->CP0_LLAddr = T2;
1.1.1.5 ! root     2072:     RETURN();
1.1       root     2073: }
                   2074: 
                   2075: void debug_eret (void);
                   2076: void op_eret (void)
                   2077: {
                   2078:     CALL_FROM_TB0(debug_eret);
                   2079:     if (env->hflags & MIPS_HFLAG_ERL) {
                   2080:         env->PC = env->CP0_ErrorEPC;
                   2081:         env->hflags &= ~MIPS_HFLAG_ERL;
1.1.1.4   root     2082:        env->CP0_Status &= ~(1 << CP0St_ERL);
1.1       root     2083:     } else {
                   2084:         env->PC = env->CP0_EPC;
                   2085:         env->hflags &= ~MIPS_HFLAG_EXL;
1.1.1.4   root     2086:        env->CP0_Status &= ~(1 << CP0St_EXL);
1.1       root     2087:     }
                   2088:     env->CP0_LLAddr = 1;
1.1.1.5 ! root     2089:     RETURN();
1.1       root     2090: }
                   2091: 
                   2092: void op_deret (void)
                   2093: {
                   2094:     CALL_FROM_TB0(debug_eret);
                   2095:     env->PC = env->CP0_DEPC;
1.1.1.5 ! root     2096:     RETURN();
        !          2097: }
        !          2098: 
        !          2099: void op_rdhwr_cpunum(void)
        !          2100: {
        !          2101:     if (env->CP0_HWREna & (1 << 0))
        !          2102:        T0 = env->CP0_EBase & 0x2ff;
        !          2103:     else
        !          2104:        CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI);
        !          2105:     RETURN();
        !          2106: }
        !          2107: 
        !          2108: void op_rdhwr_synci_step(void)
        !          2109: {
        !          2110:     if (env->CP0_HWREna & (1 << 1))
        !          2111:        T0 = env->SYNCI_Step;
        !          2112:     else
        !          2113:        CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI);
        !          2114:     RETURN();
        !          2115: }
        !          2116: 
        !          2117: void op_rdhwr_cc(void)
        !          2118: {
        !          2119:     if (env->CP0_HWREna & (1 << 2))
        !          2120:        T0 = env->CP0_Count;
        !          2121:     else
        !          2122:        CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI);
        !          2123:     RETURN();
        !          2124: }
        !          2125: 
        !          2126: void op_rdhwr_ccres(void)
        !          2127: {
        !          2128:     if (env->CP0_HWREna & (1 << 3))
        !          2129:        T0 = env->CCRes;
        !          2130:     else
        !          2131:        CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI);
        !          2132:     RETURN();
1.1       root     2133: }
                   2134: 
                   2135: void op_save_state (void)
                   2136: {
                   2137:     env->hflags = PARAM1;
                   2138:     RETURN();
                   2139: }
                   2140: 
                   2141: void op_save_pc (void)
                   2142: {
                   2143:     env->PC = PARAM1;
                   2144:     RETURN();
                   2145: }
                   2146: 
                   2147: void op_raise_exception (void)
                   2148: {
                   2149:     CALL_FROM_TB1(do_raise_exception, PARAM1);
                   2150:     RETURN();
                   2151: }
                   2152: 
                   2153: void op_raise_exception_err (void)
                   2154: {
                   2155:     CALL_FROM_TB2(do_raise_exception_err, PARAM1, PARAM2);
                   2156:     RETURN();
                   2157: }
                   2158: 
                   2159: void op_exit_tb (void)
                   2160: {
                   2161:     EXIT_TB();
1.1.1.5 ! root     2162:     RETURN();
1.1       root     2163: }
                   2164: 
1.1.1.2   root     2165: void op_wait (void)
                   2166: {
                   2167:     env->halted = 1;
                   2168:     CALL_FROM_TB1(do_raise_exception, EXCP_HLT);
1.1.1.5 ! root     2169:     RETURN();
        !          2170: }
        !          2171: 
        !          2172: /* Bitfield operations. */
        !          2173: void op_ext(void)
        !          2174: {
        !          2175:     unsigned int pos = PARAM1;
        !          2176:     unsigned int size = PARAM2;
        !          2177: 
        !          2178:     T0 = ((uint32_t)T1 >> pos) & ((1 << size) - 1);
        !          2179:     RETURN();
        !          2180: }
        !          2181: 
        !          2182: void op_ins(void)
        !          2183: {
        !          2184:     unsigned int pos = PARAM1;
        !          2185:     unsigned int size = PARAM2;
        !          2186:     target_ulong mask = ((1 << size) - 1) << pos;
        !          2187: 
        !          2188:     T0 = (T2 & ~mask) | (((uint32_t)T1 << pos) & mask);
        !          2189:     RETURN();
        !          2190: }
        !          2191: 
        !          2192: void op_wsbh(void)
        !          2193: {
        !          2194:     T0 = ((T1 << 8) & ~0x00FF00FF) | ((T1 >> 8) & 0x00FF00FF);
        !          2195:     RETURN();
        !          2196: }
        !          2197: 
        !          2198: #ifdef MIPS_HAS_MIPS64
        !          2199: void op_dext(void)
        !          2200: {
        !          2201:     unsigned int pos = PARAM1;
        !          2202:     unsigned int size = PARAM2;
        !          2203: 
        !          2204:     T0 = (T1 >> pos) & ((1 << size) - 1);
        !          2205:     RETURN();
        !          2206: }
        !          2207: 
        !          2208: void op_dins(void)
        !          2209: {
        !          2210:     unsigned int pos = PARAM1;
        !          2211:     unsigned int size = PARAM2;
        !          2212:     target_ulong mask = ((1 << size) - 1) << pos;
        !          2213: 
        !          2214:     T0 = (T2 & ~mask) | ((T1 << pos) & mask);
        !          2215:     RETURN();
        !          2216: }
        !          2217: 
        !          2218: void op_dsbh(void)
        !          2219: {
        !          2220:     T0 = ((T1 << 8) & ~0x00FF00FF00FF00FFULL) | ((T1 >> 8) & 0x00FF00FF00FF00FFULL);
        !          2221:     RETURN();
        !          2222: }
        !          2223: 
        !          2224: void op_dshd(void)
        !          2225: {
        !          2226:     T0 = ((T1 << 16) & ~0x0000FFFF0000FFFFULL) | ((T1 >> 16) & 0x0000FFFF0000FFFFULL);
        !          2227:     RETURN();
        !          2228: }
        !          2229: #endif
        !          2230: 
        !          2231: void op_seb(void)
        !          2232: {
        !          2233:     T0 = ((T1 & 0xFF) ^ 0x80) - 0x80;
        !          2234:     RETURN();
        !          2235: }
        !          2236: 
        !          2237: void op_seh(void)
        !          2238: {
        !          2239:     T0 = ((T1 & 0xFFFF) ^ 0x8000) - 0x8000;
        !          2240:     RETURN();
1.1.1.2   root     2241: }

unix.superglobalmegacorp.com

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