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

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

unix.superglobalmegacorp.com

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