Annotation of qemu/target-ppc/op.c, revision 1.1.1.3

1.1       root        1: /*
                      2:  *  PowerPC emulation micro-operations for qemu.
                      3:  * 
                      4:  *  Copyright (c) 2003-2005 Jocelyn Mayer
                      5:  *
                      6:  * This library is free software; you can redistribute it and/or
                      7:  * modify it under the terms of the GNU Lesser General Public
                      8:  * License as published by the Free Software Foundation; either
                      9:  * version 2 of the License, or (at your option) any later version.
                     10:  *
                     11:  * This library is distributed in the hope that it will be useful,
                     12:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     14:  * Lesser General Public License for more details.
                     15:  *
                     16:  * You should have received a copy of the GNU Lesser General Public
                     17:  * License along with this library; if not, write to the Free Software
                     18:  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     19:  */
                     20: 
                     21: //#define DEBUG_OP
                     22: 
                     23: #include "config.h"
                     24: #include "exec.h"
                     25: 
                     26: #define regs (env)
                     27: #define Ts0 (int32_t)T0
                     28: #define Ts1 (int32_t)T1
                     29: #define Ts2 (int32_t)T2
                     30: 
                     31: #define FT0 (env->ft0)
                     32: #define FT1 (env->ft1)
                     33: #define FT2 (env->ft2)
                     34: 
                     35: #define PPC_OP(name) void glue(op_, name)(void)
                     36: 
                     37: #define REG 0
                     38: #include "op_template.h"
                     39: 
                     40: #define REG 1
                     41: #include "op_template.h"
                     42: 
                     43: #define REG 2
                     44: #include "op_template.h"
                     45: 
                     46: #define REG 3
                     47: #include "op_template.h"
                     48: 
                     49: #define REG 4
                     50: #include "op_template.h"
                     51: 
                     52: #define REG 5
                     53: #include "op_template.h"
                     54: 
                     55: #define REG 6
                     56: #include "op_template.h"
                     57: 
                     58: #define REG 7
                     59: #include "op_template.h"
                     60: 
                     61: #define REG 8
                     62: #include "op_template.h"
                     63: 
                     64: #define REG 9
                     65: #include "op_template.h"
                     66: 
                     67: #define REG 10
                     68: #include "op_template.h"
                     69: 
                     70: #define REG 11
                     71: #include "op_template.h"
                     72: 
                     73: #define REG 12
                     74: #include "op_template.h"
                     75: 
                     76: #define REG 13
                     77: #include "op_template.h"
                     78: 
                     79: #define REG 14
                     80: #include "op_template.h"
                     81: 
                     82: #define REG 15
                     83: #include "op_template.h"
                     84: 
                     85: #define REG 16
                     86: #include "op_template.h"
                     87: 
                     88: #define REG 17
                     89: #include "op_template.h"
                     90: 
                     91: #define REG 18
                     92: #include "op_template.h"
                     93: 
                     94: #define REG 19
                     95: #include "op_template.h"
                     96: 
                     97: #define REG 20
                     98: #include "op_template.h"
                     99: 
                    100: #define REG 21
                    101: #include "op_template.h"
                    102: 
                    103: #define REG 22
                    104: #include "op_template.h"
                    105: 
                    106: #define REG 23
                    107: #include "op_template.h"
                    108: 
                    109: #define REG 24
                    110: #include "op_template.h"
                    111: 
                    112: #define REG 25
                    113: #include "op_template.h"
                    114: 
                    115: #define REG 26
                    116: #include "op_template.h"
                    117: 
                    118: #define REG 27
                    119: #include "op_template.h"
                    120: 
                    121: #define REG 28
                    122: #include "op_template.h"
                    123: 
                    124: #define REG 29
                    125: #include "op_template.h"
                    126: 
                    127: #define REG 30
                    128: #include "op_template.h"
                    129: 
                    130: #define REG 31
                    131: #include "op_template.h"
                    132: 
                    133: /* PowerPC state maintenance operations */
                    134: /* set_Rc0 */
                    135: PPC_OP(set_Rc0)
                    136: {
                    137:     uint32_t tmp;
                    138: 
                    139:     if (Ts0 < 0) {
                    140:         tmp = 0x08;
                    141:     } else if (Ts0 > 0) {
                    142:         tmp = 0x04;
                    143:     } else {
                    144:         tmp = 0x02;
                    145:     }
                    146:     tmp |= xer_ov;
                    147:     env->crf[0] = tmp;
                    148:     RETURN();
                    149: }
                    150: 
                    151: /* reset_Rc0 */
                    152: PPC_OP(reset_Rc0)
                    153: {
                    154:     env->crf[0] = 0x02 | xer_ov;
                    155:     RETURN();
                    156: }
                    157: 
                    158: /* set_Rc0_1 */
                    159: PPC_OP(set_Rc0_1)
                    160: {
                    161:     env->crf[0] = 0x04 | xer_ov;
                    162:     RETURN();
                    163: }
                    164: 
                    165: /* Set Rc1 (for floating point arithmetic) */
                    166: PPC_OP(set_Rc1)
                    167: {
                    168:     env->crf[1] = regs->fpscr[7];
                    169:     RETURN();
                    170: }
                    171: 
                    172: /* Constants load */
                    173: PPC_OP(set_T0)
                    174: {
                    175:     T0 = PARAM(1);
                    176:     RETURN();
                    177: }
                    178: 
                    179: PPC_OP(set_T1)
                    180: {
                    181:     T1 = PARAM(1);
                    182:     RETURN();
                    183: }
                    184: 
                    185: PPC_OP(set_T2)
                    186: {
                    187:     T2 = PARAM(1);
                    188:     RETURN();
                    189: }
                    190: 
                    191: /* Generate exceptions */
                    192: PPC_OP(raise_exception_err)
                    193: {
                    194:     do_raise_exception_err(PARAM(1), PARAM(2));
                    195: }
                    196: 
                    197: PPC_OP(raise_exception)
                    198: {
                    199:     do_raise_exception(PARAM(1));
                    200: }
                    201: 
                    202: PPC_OP(update_nip)
                    203: {
                    204:     env->nip = PARAM(1);
                    205: }
                    206: 
1.1.1.3 ! root      207: PPC_OP(debug)
        !           208: {
        !           209:     do_raise_exception(EXCP_DEBUG);
        !           210: }
        !           211: 
1.1       root      212: /* Segment registers load and store with immediate index */
                    213: PPC_OP(load_srin)
                    214: {
                    215:     T0 = regs->sr[T1 >> 28];
                    216:     RETURN();
                    217: }
                    218: 
                    219: PPC_OP(store_srin)
                    220: {
                    221:     do_store_sr(env, ((uint32_t)T1 >> 28), T0);
                    222:     RETURN();
                    223: }
                    224: 
                    225: PPC_OP(load_sdr1)
                    226: {
                    227:     T0 = regs->sdr1;
                    228:     RETURN();
                    229: }
                    230: 
                    231: PPC_OP(store_sdr1)
                    232: {
                    233:     do_store_sdr1(env, T0);
                    234:     RETURN();
                    235: }
                    236: 
                    237: PPC_OP(exit_tb)
                    238: {
                    239:     EXIT_TB();
                    240: }
                    241: 
                    242: /* Load/store special registers */
                    243: PPC_OP(load_cr)
                    244: {
                    245:     T0 = do_load_cr(env);
                    246:     RETURN();
                    247: }
                    248: 
                    249: PPC_OP(store_cr)
                    250: {
                    251:     do_store_cr(env, T0, PARAM(1));
                    252:     RETURN();
                    253: }
                    254: 
                    255: PPC_OP(load_xer_cr)
                    256: {
                    257:     T0 = (xer_so << 3) | (xer_ov << 2) | (xer_ca << 1);
                    258:     RETURN();
                    259: }
                    260: 
                    261: PPC_OP(clear_xer_cr)
                    262: {
                    263:     xer_so = 0;
                    264:     xer_ov = 0;
                    265:     xer_ca = 0;
                    266:     RETURN();
                    267: }
                    268: 
                    269: PPC_OP(load_xer_bc)
                    270: {
                    271:     T1 = xer_bc;
                    272:     RETURN();
                    273: }
                    274: 
                    275: PPC_OP(load_xer)
                    276: {
                    277:     T0 = do_load_xer(env);
                    278:     RETURN();
                    279: }
                    280: 
                    281: PPC_OP(store_xer)
                    282: {
                    283:     do_store_xer(env, T0);
                    284:     RETURN();
                    285: }
                    286: 
                    287: PPC_OP(load_msr)
                    288: {
                    289:     T0 = do_load_msr(env);
                    290:     RETURN();
                    291: }
                    292: 
                    293: PPC_OP(store_msr)
                    294: {
                    295:     do_store_msr(env, T0);
                    296:     RETURN();
                    297: }
                    298: 
                    299: /* SPR */
                    300: PPC_OP(load_spr)
                    301: {
                    302:     T0 = regs->spr[PARAM(1)];
                    303:     RETURN();
                    304: }
                    305: 
                    306: PPC_OP(store_spr)
                    307: {
                    308:     regs->spr[PARAM(1)] = T0;
                    309:     RETURN();
                    310: }
                    311: 
                    312: PPC_OP(load_lr)
                    313: {
                    314:     T0 = regs->lr;
                    315:     RETURN();
                    316: }
                    317: 
                    318: PPC_OP(store_lr)
                    319: {
                    320:     regs->lr = T0;
                    321:     RETURN();
                    322: }
                    323: 
                    324: PPC_OP(load_ctr)
                    325: {
                    326:     T0 = regs->ctr;
                    327:     RETURN();
                    328: }
                    329: 
                    330: PPC_OP(store_ctr)
                    331: {
                    332:     regs->ctr = T0;
                    333:     RETURN();
                    334: }
                    335: 
                    336: PPC_OP(load_tbl)
                    337: {
                    338:     T0 = cpu_ppc_load_tbl(regs);
                    339:     RETURN();
                    340: }
                    341: 
                    342: PPC_OP(load_tbu)
                    343: {
                    344:     T0 = cpu_ppc_load_tbu(regs);
                    345:     RETURN();
                    346: }
                    347: 
                    348: PPC_OP(store_tbl)
                    349: {
                    350:     cpu_ppc_store_tbl(regs, T0);
                    351:     RETURN();
                    352: }
                    353: 
                    354: PPC_OP(store_tbu)
                    355: {
                    356:     cpu_ppc_store_tbu(regs, T0);
                    357:     RETURN();
                    358: }
                    359: 
                    360: PPC_OP(load_decr)
                    361: {
                    362:     T0 = cpu_ppc_load_decr(regs);
                    363:     }
                    364: 
                    365: PPC_OP(store_decr)
                    366: {
                    367:     cpu_ppc_store_decr(regs, T0);
                    368:     RETURN();
                    369: }
                    370: 
                    371: PPC_OP(load_ibat)
                    372: {
                    373:     T0 = regs->IBAT[PARAM(1)][PARAM(2)];
                    374: }
                    375: 
                    376: void op_store_ibatu (void)
                    377: {
                    378:     do_store_ibatu(env, PARAM1, T0);
                    379:     RETURN();
                    380: }
                    381: 
                    382: void op_store_ibatl (void)
                    383: {
                    384: #if 1
                    385:     env->IBAT[1][PARAM1] = T0;
                    386: #else
                    387:     do_store_ibatl(env, PARAM1, T0);
                    388: #endif
                    389:     RETURN();
                    390: }
                    391: 
                    392: PPC_OP(load_dbat)
                    393: {
                    394:     T0 = regs->DBAT[PARAM(1)][PARAM(2)];
                    395: }
                    396: 
                    397: void op_store_dbatu (void)
                    398: {
                    399:     do_store_dbatu(env, PARAM1, T0);
                    400:     RETURN();
                    401: }
                    402: 
                    403: void op_store_dbatl (void)
                    404: {
                    405: #if 1
                    406:     env->DBAT[1][PARAM1] = T0;
                    407: #else
                    408:     do_store_dbatl(env, PARAM1, T0);
                    409: #endif
                    410:     RETURN();
                    411: }
                    412: 
                    413: /* FPSCR */
                    414: PPC_OP(load_fpscr)
                    415: {
                    416:     FT0 = do_load_fpscr(env);
                    417:     RETURN();
                    418: }
                    419: 
                    420: PPC_OP(store_fpscr)
                    421: {
                    422:     do_store_fpscr(env, FT0, PARAM1);
                    423:     RETURN();
                    424: }
                    425: 
                    426: PPC_OP(reset_scrfx)
                    427: {
                    428:     regs->fpscr[7] &= ~0x8;
                    429:     RETURN();
                    430: }
                    431: 
                    432: /* crf operations */
                    433: PPC_OP(getbit_T0)
                    434: {
                    435:     T0 = (T0 >> PARAM(1)) & 1;
                    436:     RETURN();
                    437: }
                    438: 
                    439: PPC_OP(getbit_T1)
                    440: {
                    441:     T1 = (T1 >> PARAM(1)) & 1;
                    442:     RETURN();
                    443: }
                    444: 
                    445: PPC_OP(setcrfbit)
                    446: {
                    447:     T1 = (T1 & PARAM(1)) | (T0 << PARAM(2)); 
                    448:     RETURN();
                    449: }
                    450: 
                    451: /* Branch */
                    452: #define EIP regs->nip
                    453: 
                    454: PPC_OP(setlr)
                    455: {
                    456:     regs->lr = PARAM1;
                    457: }
                    458: 
1.1.1.2   root      459: PPC_OP(goto_tb0)
1.1       root      460: {
1.1.1.2   root      461:     GOTO_TB(op_goto_tb0, PARAM1, 0);
                    462: }
                    463: 
                    464: PPC_OP(goto_tb1)
                    465: {
                    466:     GOTO_TB(op_goto_tb1, PARAM1, 1);
1.1       root      467: }
                    468: 
                    469: PPC_OP(b_T1)
                    470: {
                    471:     regs->nip = T1 & ~3;
                    472: }
                    473: 
1.1.1.2   root      474: PPC_OP(jz_T0)
1.1       root      475: {
1.1.1.2   root      476:     if (!T0)
                    477:         GOTO_LABEL_PARAM(1);
1.1       root      478:     RETURN();
                    479: }
                    480: 
                    481: PPC_OP(btest_T1) 
                    482: {
                    483:     if (T0) {
                    484:         regs->nip = T1 & ~3;
                    485:     } else {
                    486:         regs->nip = PARAM1;
                    487:     }
                    488:     RETURN();
                    489: }
                    490: 
                    491: PPC_OP(movl_T1_ctr)
                    492: {
                    493:     T1 = regs->ctr;
                    494: }
                    495: 
                    496: PPC_OP(movl_T1_lr)
                    497: {
                    498:     T1 = regs->lr;
                    499: }
                    500: 
                    501: /* tests with result in T0 */
                    502: 
                    503: PPC_OP(test_ctr)
                    504: {
                    505:     T0 = regs->ctr;
                    506: }
                    507: 
                    508: PPC_OP(test_ctr_true)
                    509: {
                    510:     T0 = (regs->ctr != 0 && (T0 & PARAM(1)) != 0);
                    511: }
                    512: 
                    513: PPC_OP(test_ctr_false)
                    514: {
                    515:     T0 = (regs->ctr != 0 && (T0 & PARAM(1)) == 0);
                    516: }
                    517: 
                    518: PPC_OP(test_ctrz)
                    519: {
                    520:     T0 = (regs->ctr == 0);
                    521: }
                    522: 
                    523: PPC_OP(test_ctrz_true)
                    524: {
                    525:     T0 = (regs->ctr == 0 && (T0 & PARAM(1)) != 0);
                    526: }
                    527: 
                    528: PPC_OP(test_ctrz_false)
                    529: {
                    530:     T0 = (regs->ctr == 0 && (T0 & PARAM(1)) == 0);
                    531: }
                    532: 
                    533: PPC_OP(test_true)
                    534: {
                    535:     T0 = (T0 & PARAM(1));
                    536: }
                    537: 
                    538: PPC_OP(test_false)
                    539: {
                    540:     T0 = ((T0 & PARAM(1)) == 0);
                    541: }
                    542: 
                    543: /* CTR maintenance */
                    544: PPC_OP(dec_ctr)
                    545: {
                    546:     regs->ctr--;
                    547:     RETURN();
                    548: }
                    549: 
                    550: /***                           Integer arithmetic                          ***/
                    551: /* add */
                    552: PPC_OP(add)
                    553: {
                    554:     T0 += T1;
                    555:     RETURN();
                    556: }
                    557: 
                    558: void do_addo (void);
                    559: void op_addo (void)
                    560: {
                    561:     do_addo();
                    562:     RETURN();
                    563: }
                    564: 
                    565: /* add carrying */
                    566: PPC_OP(addc)
                    567: {
                    568:     T2 = T0;
                    569:     T0 += T1;
                    570:     if (T0 < T2) {
                    571:         xer_ca = 1;
                    572:     } else {
                    573:         xer_ca = 0;
                    574:     }
                    575:     RETURN();
                    576: }
                    577: 
                    578: void do_addco (void);
                    579: void op_addco (void)
                    580: {
                    581:     do_addco();
                    582:     RETURN();
                    583: }
                    584: 
                    585: /* add extended */
                    586: void do_adde (void);
                    587: void op_adde (void)
                    588: {
                    589:     do_adde();
                    590: }
                    591: 
                    592: void do_addeo (void);
                    593: PPC_OP(addeo)
                    594: {
                    595:     do_addeo();
                    596:     RETURN();
                    597: }
                    598: 
                    599: /* add immediate */
                    600: PPC_OP(addi)
                    601: {
                    602:     T0 += PARAM(1);
                    603:     RETURN();
                    604: }
                    605: 
                    606: /* add immediate carrying */
                    607: PPC_OP(addic)
                    608: {
                    609:     T1 = T0;
                    610:     T0 += PARAM(1);
                    611:     if (T0 < T1) {
                    612:         xer_ca = 1;
                    613:     } else {
                    614:         xer_ca = 0;
                    615:     }
                    616:     RETURN();
                    617: }
                    618: 
                    619: /* add to minus one extended */
                    620: PPC_OP(addme)
                    621: {
                    622:     T1 = T0;
                    623:     T0 += xer_ca + (-1);
                    624:     if (T1 != 0)
                    625:         xer_ca = 1;
                    626:     RETURN();
                    627: }
                    628: 
                    629: void do_addmeo (void);
                    630: void op_addmeo (void)
                    631: {
                    632:     do_addmeo();
                    633:     RETURN();
                    634: }
                    635: 
                    636: /* add to zero extended */
                    637: PPC_OP(addze)
                    638: {
                    639:     T1 = T0;
                    640:     T0 += xer_ca;
                    641:     if (T0 < T1) {
                    642:         xer_ca = 1;
                    643:     } else {
                    644:         xer_ca = 0;
                    645:     }
                    646:     RETURN();
                    647: }
                    648: 
                    649: void do_addzeo (void);
                    650: void op_addzeo (void)
                    651: {
                    652:     do_addzeo();
                    653:     RETURN();
                    654: }
                    655: 
                    656: /* divide word */
                    657: PPC_OP(divw)
                    658: {
                    659:     if ((Ts0 == INT32_MIN && Ts1 == -1) || Ts1 == 0) {
                    660:         T0 = (int32_t)((-1) * (T0 >> 31));
                    661:     } else {
                    662:         T0 = (Ts0 / Ts1);
                    663:     }
                    664:     RETURN();
                    665: }
                    666: 
                    667: void do_divwo (void);
                    668: void op_divwo (void)
                    669: {
                    670:     do_divwo();
                    671:     RETURN();
                    672: }
                    673: 
                    674: /* divide word unsigned */
                    675: PPC_OP(divwu)
                    676: {
                    677:     if (T1 == 0) {
                    678:         T0 = 0;
                    679:     } else {
                    680:         T0 /= T1;
                    681:     }
                    682:     RETURN();
                    683: }
                    684: 
                    685: void do_divwuo (void);
                    686: void op_divwuo (void)
                    687: {
                    688:     do_divwuo();
                    689:     RETURN();
                    690: }
                    691: 
                    692: /* multiply high word */
                    693: PPC_OP(mulhw)
                    694: {
                    695:     T0 = ((int64_t)Ts0 * (int64_t)Ts1) >> 32;
                    696:     RETURN();
                    697: }
                    698: 
                    699: /* multiply high word unsigned */
                    700: PPC_OP(mulhwu)
                    701: {
                    702:     T0 = ((uint64_t)T0 * (uint64_t)T1) >> 32;
                    703:     RETURN();
                    704: }
                    705: 
                    706: /* multiply low immediate */
                    707: PPC_OP(mulli)
                    708: {
                    709:     T0 = (Ts0 * SPARAM(1));
                    710:     RETURN();
                    711: }
                    712: 
                    713: /* multiply low word */
                    714: PPC_OP(mullw)
                    715: {
                    716:     T0 *= T1;
                    717:     RETURN();
                    718: }
                    719: 
                    720: void do_mullwo (void);
                    721: void op_mullwo (void)
                    722: {
                    723:     do_mullwo();
                    724:     RETURN();
                    725: }
                    726: 
                    727: /* negate */
                    728: PPC_OP(neg)
                    729: {
                    730:     if (T0 != 0x80000000) {
                    731:         T0 = -Ts0;
                    732:     }
                    733:     RETURN();
                    734: }
                    735: 
                    736: void do_nego (void);
                    737: void op_nego (void)
                    738: {
                    739:     do_nego();
                    740:     RETURN();
                    741: }
                    742: 
                    743: /* substract from */
                    744: PPC_OP(subf)
                    745: {
                    746:     T0 = T1 - T0;
                    747:     RETURN();
                    748: }
                    749: 
                    750: void do_subfo (void);
                    751: void op_subfo (void)
                    752: {
                    753:     do_subfo();
                    754:     RETURN();
                    755: }
                    756: 
                    757: /* substract from carrying */
                    758: PPC_OP(subfc)
                    759: {
                    760:     T0 = T1 - T0;
                    761:     if (T0 <= T1) {
                    762:         xer_ca = 1;
                    763:     } else {
                    764:         xer_ca = 0;
                    765:     }
                    766:     RETURN();
                    767: }
                    768: 
                    769: void do_subfco (void);
                    770: void op_subfco (void)
                    771: {
                    772:     do_subfco();
                    773:     RETURN();
                    774: }
                    775: 
                    776: /* substract from extended */
                    777: void do_subfe (void);
                    778: void op_subfe (void)
                    779: {
                    780:     do_subfe();
                    781:     RETURN();
                    782: }
                    783: 
                    784: void do_subfeo (void);
                    785: PPC_OP(subfeo)
                    786: {
                    787:     do_subfeo();
                    788:     RETURN();
                    789: }
                    790: 
                    791: /* substract from immediate carrying */
                    792: PPC_OP(subfic)
                    793: {
                    794:     T0 = PARAM(1) + ~T0 + 1;
                    795:     if (T0 <= PARAM(1)) {
                    796:         xer_ca = 1;
                    797:     } else {
                    798:         xer_ca = 0;
                    799:     }
                    800:     RETURN();
                    801: }
                    802: 
                    803: /* substract from minus one extended */
                    804: PPC_OP(subfme)
                    805: {
                    806:     T0 = ~T0 + xer_ca - 1;
                    807: 
                    808:     if (T0 != -1)
                    809:         xer_ca = 1;
                    810:     RETURN();
                    811: }
                    812: 
                    813: void do_subfmeo (void);
                    814: void op_subfmeo (void)
                    815: {
                    816:     do_subfmeo();
                    817:     RETURN();
                    818: }
                    819: 
                    820: /* substract from zero extended */
                    821: PPC_OP(subfze)
                    822: {
                    823:     T1 = ~T0;
                    824:     T0 = T1 + xer_ca;
                    825:     if (T0 < T1) {
                    826:         xer_ca = 1;
                    827:     } else {
                    828:         xer_ca = 0;
                    829:     }
                    830:     RETURN();
                    831: }
                    832: 
                    833: void do_subfzeo (void);
                    834: void op_subfzeo (void)
                    835: {
                    836:     do_subfzeo();
                    837:     RETURN();
                    838: }
                    839: 
                    840: /***                           Integer comparison                          ***/
                    841: /* compare */
                    842: PPC_OP(cmp)
                    843: {
                    844:     if (Ts0 < Ts1) {
                    845:         T0 = 0x08;
                    846:     } else if (Ts0 > Ts1) {
                    847:         T0 = 0x04;
                    848:     } else {
                    849:         T0 = 0x02;
                    850:     }
                    851:     RETURN();
                    852: }
                    853: 
                    854: /* compare immediate */
                    855: PPC_OP(cmpi)
                    856: {
                    857:     if (Ts0 < SPARAM(1)) {
                    858:         T0 = 0x08;
                    859:     } else if (Ts0 > SPARAM(1)) {
                    860:         T0 = 0x04;
                    861:     } else {
                    862:         T0 = 0x02;
                    863:     }
                    864:     RETURN();
                    865: }
                    866: 
                    867: /* compare logical */
                    868: PPC_OP(cmpl)
                    869: {
                    870:     if (T0 < T1) {
                    871:         T0 = 0x08;
                    872:     } else if (T0 > T1) {
                    873:         T0 = 0x04;
                    874:     } else {
                    875:         T0 = 0x02;
                    876:     }
                    877:     RETURN();
                    878: }
                    879: 
                    880: /* compare logical immediate */
                    881: PPC_OP(cmpli)
                    882: {
                    883:     if (T0 < PARAM(1)) {
                    884:         T0 = 0x08;
                    885:     } else if (T0 > PARAM(1)) {
                    886:         T0 = 0x04;
                    887:     } else {
                    888:         T0 = 0x02;
                    889:     }
                    890:     RETURN();
                    891: }
                    892: 
                    893: /***                            Integer logical                            ***/
                    894: /* and */
                    895: PPC_OP(and)
                    896: {
                    897:     T0 &= T1;
                    898:     RETURN();
                    899: }
                    900: 
                    901: /* andc */
                    902: PPC_OP(andc)
                    903: {
                    904:     T0 &= ~T1;
                    905:     RETURN();
                    906: }
                    907: 
                    908: /* andi. */
                    909: PPC_OP(andi_)
                    910: {
                    911:     T0 &= PARAM(1);
                    912:     RETURN();
                    913: }
                    914: 
                    915: /* count leading zero */
                    916: PPC_OP(cntlzw)
                    917: {
                    918:     T1 = T0;
                    919:     for (T0 = 32; T1 > 0; T0--)
                    920:         T1 = T1 >> 1;
                    921:     RETURN();
                    922: }
                    923: 
                    924: /* eqv */
                    925: PPC_OP(eqv)
                    926: {
                    927:     T0 = ~(T0 ^ T1);
                    928:     RETURN();
                    929: }
                    930: 
                    931: /* extend sign byte */
                    932: PPC_OP(extsb)
                    933: {
                    934:     T0 = (int32_t)((int8_t)(Ts0));
                    935:     RETURN();
                    936: }
                    937: 
                    938: /* extend sign half word */
                    939: PPC_OP(extsh)
                    940: {
                    941:     T0 = (int32_t)((int16_t)(Ts0));
                    942:     RETURN();
                    943: }
                    944: 
                    945: /* nand */
                    946: PPC_OP(nand)
                    947: {
                    948:     T0 = ~(T0 & T1);
                    949:     RETURN();
                    950: }
                    951: 
                    952: /* nor */
                    953: PPC_OP(nor)
                    954: {
                    955:     T0 = ~(T0 | T1);
                    956:     RETURN();
                    957: }
                    958: 
                    959: /* or */
                    960: PPC_OP(or)
                    961: {
                    962:     T0 |= T1;
                    963:     RETURN();
                    964: }
                    965: 
                    966: /* orc */
                    967: PPC_OP(orc)
                    968: {
                    969:     T0 |= ~T1;
                    970:     RETURN();
                    971: }
                    972: 
                    973: /* ori */
                    974: PPC_OP(ori)
                    975: {
                    976:     T0 |= PARAM(1);
                    977:     RETURN();
                    978: }
                    979: 
                    980: /* xor */
                    981: PPC_OP(xor)
                    982: {
                    983:     T0 ^= T1;
                    984:     RETURN();
                    985: }
                    986: 
                    987: /* xori */
                    988: PPC_OP(xori)
                    989: {
                    990:     T0 ^= PARAM(1);
                    991:     RETURN();
                    992: }
                    993: 
                    994: /***                             Integer rotate                            ***/
                    995: /* rotate left word immediate then mask insert */
                    996: PPC_OP(rlwimi)
                    997: {
                    998:     T0 = (rotl(T0, PARAM(1)) & PARAM(2)) | (T1 & PARAM(3));
                    999:     RETURN();
                   1000: }
                   1001: 
                   1002: /* rotate left immediate then and with mask insert */
                   1003: PPC_OP(rotlwi)
                   1004: {
                   1005:     T0 = rotl(T0, PARAM(1));
                   1006:     RETURN();
                   1007: }
                   1008: 
                   1009: PPC_OP(slwi)
                   1010: {
                   1011:     T0 = T0 << PARAM(1);
                   1012:     RETURN();
                   1013: }
                   1014: 
                   1015: PPC_OP(srwi)
                   1016: {
                   1017:     T0 = T0 >> PARAM(1);
                   1018:     RETURN();
                   1019: }
                   1020: 
                   1021: /* rotate left word then and with mask insert */
                   1022: PPC_OP(rlwinm)
                   1023: {
                   1024:     T0 = rotl(T0, PARAM(1)) & PARAM(2);
                   1025:     RETURN();
                   1026: }
                   1027: 
                   1028: PPC_OP(rotl)
                   1029: {
                   1030:     T0 = rotl(T0, T1);
                   1031:     RETURN();
                   1032: }
                   1033: 
                   1034: PPC_OP(rlwnm)
                   1035: {
                   1036:     T0 = rotl(T0, T1) & PARAM(1);
                   1037:     RETURN();
                   1038: }
                   1039: 
                   1040: /***                             Integer shift                             ***/
                   1041: /* shift left word */
                   1042: PPC_OP(slw)
                   1043: {
                   1044:     if (T1 & 0x20) {
                   1045:         T0 = 0;
                   1046:     } else {
                   1047:         T0 = T0 << T1;
                   1048:     }
                   1049:     RETURN();
                   1050: }
                   1051: 
                   1052: /* shift right algebraic word */
                   1053: void op_sraw (void)
                   1054: {
                   1055:     do_sraw();
                   1056:     RETURN();
                   1057: }
                   1058: 
                   1059: /* shift right algebraic word immediate */
                   1060: PPC_OP(srawi)
                   1061: {
                   1062:     T1 = T0;
                   1063:     T0 = (Ts0 >> PARAM(1));
                   1064:     if (Ts1 < 0 && (Ts1 & PARAM(2)) != 0) {
                   1065:         xer_ca = 1;
                   1066:     } else {
                   1067:         xer_ca = 0;
                   1068:     }
                   1069:     RETURN();
                   1070: }
                   1071: 
                   1072: /* shift right word */
                   1073: PPC_OP(srw)
                   1074: {
                   1075:     if (T1 & 0x20) {
                   1076:         T0 = 0;
                   1077:     } else {
                   1078:         T0 = T0 >> T1;
                   1079:     }
                   1080:     RETURN();
                   1081: }
                   1082: 
                   1083: /***                       Floating-Point arithmetic                       ***/
                   1084: /* fadd - fadd. */
                   1085: PPC_OP(fadd)
                   1086: {
                   1087:     FT0 += FT1;
                   1088:     RETURN();
                   1089: }
                   1090: 
                   1091: /* fsub - fsub. */
                   1092: PPC_OP(fsub)
                   1093: {
                   1094:     FT0 -= FT1;
                   1095:     RETURN();
                   1096: }
                   1097: 
                   1098: /* fmul - fmul. */
                   1099: PPC_OP(fmul)
                   1100: {
                   1101:     FT0 *= FT1;
                   1102:     RETURN();
                   1103: }
                   1104: 
                   1105: /* fdiv - fdiv. */
                   1106: PPC_OP(fdiv)
                   1107: {
                   1108:     FT0 = float64_div(FT0, FT1, &env->fp_status);
                   1109:     RETURN();
                   1110: }
                   1111: 
                   1112: /* fsqrt - fsqrt. */
                   1113: PPC_OP(fsqrt)
                   1114: {
                   1115:     do_fsqrt();
                   1116:     RETURN();
                   1117: }
                   1118: 
                   1119: /* fres - fres. */
                   1120: PPC_OP(fres)
                   1121: {
                   1122:     do_fres();
                   1123:     RETURN();
                   1124: }
                   1125: 
                   1126: /* frsqrte  - frsqrte. */
                   1127: PPC_OP(frsqrte)
                   1128: {
                   1129:     do_frsqrte();
                   1130:     RETURN();
                   1131: }
                   1132: 
                   1133: /* fsel - fsel. */
                   1134: PPC_OP(fsel)
                   1135: {
                   1136:     do_fsel();
                   1137:     RETURN();
                   1138: }
                   1139: 
                   1140: /***                     Floating-Point multiply-and-add                   ***/
                   1141: /* fmadd - fmadd. */
                   1142: PPC_OP(fmadd)
                   1143: {
                   1144:     FT0 = (FT0 * FT1) + FT2;
                   1145:     RETURN();
                   1146: }
                   1147: 
                   1148: /* fmsub - fmsub. */
                   1149: PPC_OP(fmsub)
                   1150: {
                   1151:     FT0 = (FT0 * FT1) - FT2;
                   1152:     RETURN();
                   1153: }
                   1154: 
                   1155: /* fnmadd - fnmadd. - fnmadds - fnmadds. */
                   1156: PPC_OP(fnmadd)
                   1157: {
                   1158:     do_fnmadd();
                   1159:     RETURN();
                   1160: }
                   1161: 
                   1162: /* fnmsub - fnmsub. */
                   1163: PPC_OP(fnmsub)
                   1164: {
                   1165:     do_fnmsub();
                   1166:     RETURN();
                   1167: }
                   1168: 
                   1169: /***                     Floating-Point round & convert                    ***/
                   1170: /* frsp - frsp. */
                   1171: PPC_OP(frsp)
                   1172: {
                   1173:     FT0 = (float)FT0;
                   1174:     RETURN();
                   1175: }
                   1176: 
                   1177: /* fctiw - fctiw. */
                   1178: PPC_OP(fctiw)
                   1179: {
                   1180:     do_fctiw();
                   1181:     RETURN();
                   1182: }
                   1183: 
                   1184: /* fctiwz - fctiwz. */
                   1185: PPC_OP(fctiwz)
                   1186: {
                   1187:     do_fctiwz();
                   1188:     RETURN();
                   1189: }
                   1190: 
                   1191: 
                   1192: /***                         Floating-Point compare                        ***/
                   1193: /* fcmpu */
                   1194: PPC_OP(fcmpu)
                   1195: {
                   1196:     do_fcmpu();
                   1197:     RETURN();
                   1198: }
                   1199: 
                   1200: /* fcmpo */
                   1201: PPC_OP(fcmpo)
                   1202: {
                   1203:     do_fcmpo();
                   1204:     RETURN();
                   1205: }
                   1206: 
                   1207: /***                         Floating-point move                           ***/
                   1208: /* fabs */
                   1209: PPC_OP(fabs)
                   1210: {
                   1211:     FT0 = float64_abs(FT0);
                   1212:     RETURN();
                   1213: }
                   1214: 
                   1215: /* fnabs */
                   1216: PPC_OP(fnabs)
                   1217: {
                   1218:     FT0 = float64_abs(FT0);
                   1219:     FT0 = float64_chs(FT0);
                   1220:     RETURN();
                   1221: }
                   1222: 
                   1223: /* fneg */
                   1224: PPC_OP(fneg)
                   1225: {
                   1226:     FT0 = float64_chs(FT0);
                   1227:     RETURN();
                   1228: }
                   1229: 
                   1230: /* Load and store */
                   1231: #define MEMSUFFIX _raw
                   1232: #include "op_mem.h"
                   1233: #if !defined(CONFIG_USER_ONLY)
                   1234: #define MEMSUFFIX _user
                   1235: #include "op_mem.h"
                   1236: 
                   1237: #define MEMSUFFIX _kernel
                   1238: #include "op_mem.h"
                   1239: #endif
                   1240: 
                   1241: /* Special op to check and maybe clear reservation */
                   1242: PPC_OP(check_reservation)
                   1243: {
                   1244:     if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003))
                   1245:         env->reserve = -1;
                   1246:     RETURN();
                   1247: }
                   1248: 
                   1249: /* Return from interrupt */
                   1250: void do_rfi (void);
                   1251: void op_rfi (void)
                   1252: {
                   1253:     do_rfi();
                   1254:     RETURN();
                   1255: }
                   1256: 
                   1257: /* Trap word */
                   1258: void do_tw (uint32_t cmp, int flags);
                   1259: void op_tw (void)
                   1260: {
                   1261:     do_tw(T1, PARAM(1));
                   1262:     RETURN();
                   1263: }
                   1264: 
                   1265: void op_twi (void)
                   1266: {
                   1267:     do_tw(PARAM(1), PARAM(2));
                   1268:     RETURN();
                   1269: }
                   1270: 
                   1271: /* Instruction cache block invalidate */
                   1272: PPC_OP(icbi)
                   1273: {
                   1274:     do_icbi();
                   1275:     RETURN();
                   1276: }
                   1277: 
                   1278: /* tlbia */
                   1279: PPC_OP(tlbia)
                   1280: {
                   1281:     do_tlbia();
                   1282:     RETURN();
                   1283: }
                   1284: 
                   1285: /* tlbie */
                   1286: PPC_OP(tlbie)
                   1287: {
                   1288:     do_tlbie();
                   1289:     RETURN();
                   1290: }
                   1291: 
                   1292: void op_store_pir (void)
                   1293: {
                   1294:     env->spr[SPR_PIR] = T0 & 0x0000000FUL;
                   1295:     RETURN();
                   1296: }

unix.superglobalmegacorp.com

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