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

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: 
                    454: PPC_OP(b)
                    455: {
                    456:     JUMP_TB(b1, PARAM1, 0, PARAM2);
                    457: }
                    458: 
                    459: PPC_OP(b_T1)
                    460: {
                    461:     regs->nip = T1 & ~3;
                    462: }
                    463: 
                    464: PPC_OP(btest) 
                    465: {
                    466:     if (T0) {
                    467:         JUMP_TB(btest, PARAM1, 0, PARAM2);
                    468:     } else {
                    469:         JUMP_TB(btest, PARAM1, 1, PARAM3);
                    470:     }
                    471:     RETURN();
                    472: }
                    473: 
                    474: PPC_OP(btest_T1) 
                    475: {
                    476:     if (T0) {
                    477:         regs->nip = T1 & ~3;
                    478:     } else {
                    479:         regs->nip = PARAM1;
                    480:     }
                    481:     RETURN();
                    482: }
                    483: 
                    484: PPC_OP(movl_T1_ctr)
                    485: {
                    486:     T1 = regs->ctr;
                    487: }
                    488: 
                    489: PPC_OP(movl_T1_lr)
                    490: {
                    491:     T1 = regs->lr;
                    492: }
                    493: 
                    494: /* tests with result in T0 */
                    495: 
                    496: PPC_OP(test_ctr)
                    497: {
                    498:     T0 = regs->ctr;
                    499: }
                    500: 
                    501: PPC_OP(test_ctr_true)
                    502: {
                    503:     T0 = (regs->ctr != 0 && (T0 & PARAM(1)) != 0);
                    504: }
                    505: 
                    506: PPC_OP(test_ctr_false)
                    507: {
                    508:     T0 = (regs->ctr != 0 && (T0 & PARAM(1)) == 0);
                    509: }
                    510: 
                    511: PPC_OP(test_ctrz)
                    512: {
                    513:     T0 = (regs->ctr == 0);
                    514: }
                    515: 
                    516: PPC_OP(test_ctrz_true)
                    517: {
                    518:     T0 = (regs->ctr == 0 && (T0 & PARAM(1)) != 0);
                    519: }
                    520: 
                    521: PPC_OP(test_ctrz_false)
                    522: {
                    523:     T0 = (regs->ctr == 0 && (T0 & PARAM(1)) == 0);
                    524: }
                    525: 
                    526: PPC_OP(test_true)
                    527: {
                    528:     T0 = (T0 & PARAM(1));
                    529: }
                    530: 
                    531: PPC_OP(test_false)
                    532: {
                    533:     T0 = ((T0 & PARAM(1)) == 0);
                    534: }
                    535: 
                    536: /* CTR maintenance */
                    537: PPC_OP(dec_ctr)
                    538: {
                    539:     regs->ctr--;
                    540:     RETURN();
                    541: }
                    542: 
                    543: /***                           Integer arithmetic                          ***/
                    544: /* add */
                    545: PPC_OP(add)
                    546: {
                    547:     T0 += T1;
                    548:     RETURN();
                    549: }
                    550: 
                    551: void do_addo (void);
                    552: void op_addo (void)
                    553: {
                    554:     do_addo();
                    555:     RETURN();
                    556: }
                    557: 
                    558: /* add carrying */
                    559: PPC_OP(addc)
                    560: {
                    561:     T2 = T0;
                    562:     T0 += T1;
                    563:     if (T0 < T2) {
                    564:         xer_ca = 1;
                    565:     } else {
                    566:         xer_ca = 0;
                    567:     }
                    568:     RETURN();
                    569: }
                    570: 
                    571: void do_addco (void);
                    572: void op_addco (void)
                    573: {
                    574:     do_addco();
                    575:     RETURN();
                    576: }
                    577: 
                    578: /* add extended */
                    579: void do_adde (void);
                    580: void op_adde (void)
                    581: {
                    582:     do_adde();
                    583: }
                    584: 
                    585: void do_addeo (void);
                    586: PPC_OP(addeo)
                    587: {
                    588:     do_addeo();
                    589:     RETURN();
                    590: }
                    591: 
                    592: /* add immediate */
                    593: PPC_OP(addi)
                    594: {
                    595:     T0 += PARAM(1);
                    596:     RETURN();
                    597: }
                    598: 
                    599: /* add immediate carrying */
                    600: PPC_OP(addic)
                    601: {
                    602:     T1 = T0;
                    603:     T0 += PARAM(1);
                    604:     if (T0 < T1) {
                    605:         xer_ca = 1;
                    606:     } else {
                    607:         xer_ca = 0;
                    608:     }
                    609:     RETURN();
                    610: }
                    611: 
                    612: /* add to minus one extended */
                    613: PPC_OP(addme)
                    614: {
                    615:     T1 = T0;
                    616:     T0 += xer_ca + (-1);
                    617:     if (T1 != 0)
                    618:         xer_ca = 1;
                    619:     RETURN();
                    620: }
                    621: 
                    622: void do_addmeo (void);
                    623: void op_addmeo (void)
                    624: {
                    625:     do_addmeo();
                    626:     RETURN();
                    627: }
                    628: 
                    629: /* add to zero extended */
                    630: PPC_OP(addze)
                    631: {
                    632:     T1 = T0;
                    633:     T0 += xer_ca;
                    634:     if (T0 < T1) {
                    635:         xer_ca = 1;
                    636:     } else {
                    637:         xer_ca = 0;
                    638:     }
                    639:     RETURN();
                    640: }
                    641: 
                    642: void do_addzeo (void);
                    643: void op_addzeo (void)
                    644: {
                    645:     do_addzeo();
                    646:     RETURN();
                    647: }
                    648: 
                    649: /* divide word */
                    650: PPC_OP(divw)
                    651: {
                    652:     if ((Ts0 == INT32_MIN && Ts1 == -1) || Ts1 == 0) {
                    653:         T0 = (int32_t)((-1) * (T0 >> 31));
                    654:     } else {
                    655:         T0 = (Ts0 / Ts1);
                    656:     }
                    657:     RETURN();
                    658: }
                    659: 
                    660: void do_divwo (void);
                    661: void op_divwo (void)
                    662: {
                    663:     do_divwo();
                    664:     RETURN();
                    665: }
                    666: 
                    667: /* divide word unsigned */
                    668: PPC_OP(divwu)
                    669: {
                    670:     if (T1 == 0) {
                    671:         T0 = 0;
                    672:     } else {
                    673:         T0 /= T1;
                    674:     }
                    675:     RETURN();
                    676: }
                    677: 
                    678: void do_divwuo (void);
                    679: void op_divwuo (void)
                    680: {
                    681:     do_divwuo();
                    682:     RETURN();
                    683: }
                    684: 
                    685: /* multiply high word */
                    686: PPC_OP(mulhw)
                    687: {
                    688:     T0 = ((int64_t)Ts0 * (int64_t)Ts1) >> 32;
                    689:     RETURN();
                    690: }
                    691: 
                    692: /* multiply high word unsigned */
                    693: PPC_OP(mulhwu)
                    694: {
                    695:     T0 = ((uint64_t)T0 * (uint64_t)T1) >> 32;
                    696:     RETURN();
                    697: }
                    698: 
                    699: /* multiply low immediate */
                    700: PPC_OP(mulli)
                    701: {
                    702:     T0 = (Ts0 * SPARAM(1));
                    703:     RETURN();
                    704: }
                    705: 
                    706: /* multiply low word */
                    707: PPC_OP(mullw)
                    708: {
                    709:     T0 *= T1;
                    710:     RETURN();
                    711: }
                    712: 
                    713: void do_mullwo (void);
                    714: void op_mullwo (void)
                    715: {
                    716:     do_mullwo();
                    717:     RETURN();
                    718: }
                    719: 
                    720: /* negate */
                    721: PPC_OP(neg)
                    722: {
                    723:     if (T0 != 0x80000000) {
                    724:         T0 = -Ts0;
                    725:     }
                    726:     RETURN();
                    727: }
                    728: 
                    729: void do_nego (void);
                    730: void op_nego (void)
                    731: {
                    732:     do_nego();
                    733:     RETURN();
                    734: }
                    735: 
                    736: /* substract from */
                    737: PPC_OP(subf)
                    738: {
                    739:     T0 = T1 - T0;
                    740:     RETURN();
                    741: }
                    742: 
                    743: void do_subfo (void);
                    744: void op_subfo (void)
                    745: {
                    746:     do_subfo();
                    747:     RETURN();
                    748: }
                    749: 
                    750: /* substract from carrying */
                    751: PPC_OP(subfc)
                    752: {
                    753:     T0 = T1 - T0;
                    754:     if (T0 <= T1) {
                    755:         xer_ca = 1;
                    756:     } else {
                    757:         xer_ca = 0;
                    758:     }
                    759:     RETURN();
                    760: }
                    761: 
                    762: void do_subfco (void);
                    763: void op_subfco (void)
                    764: {
                    765:     do_subfco();
                    766:     RETURN();
                    767: }
                    768: 
                    769: /* substract from extended */
                    770: void do_subfe (void);
                    771: void op_subfe (void)
                    772: {
                    773:     do_subfe();
                    774:     RETURN();
                    775: }
                    776: 
                    777: void do_subfeo (void);
                    778: PPC_OP(subfeo)
                    779: {
                    780:     do_subfeo();
                    781:     RETURN();
                    782: }
                    783: 
                    784: /* substract from immediate carrying */
                    785: PPC_OP(subfic)
                    786: {
                    787:     T0 = PARAM(1) + ~T0 + 1;
                    788:     if (T0 <= PARAM(1)) {
                    789:         xer_ca = 1;
                    790:     } else {
                    791:         xer_ca = 0;
                    792:     }
                    793:     RETURN();
                    794: }
                    795: 
                    796: /* substract from minus one extended */
                    797: PPC_OP(subfme)
                    798: {
                    799:     T0 = ~T0 + xer_ca - 1;
                    800: 
                    801:     if (T0 != -1)
                    802:         xer_ca = 1;
                    803:     RETURN();
                    804: }
                    805: 
                    806: void do_subfmeo (void);
                    807: void op_subfmeo (void)
                    808: {
                    809:     do_subfmeo();
                    810:     RETURN();
                    811: }
                    812: 
                    813: /* substract from zero extended */
                    814: PPC_OP(subfze)
                    815: {
                    816:     T1 = ~T0;
                    817:     T0 = T1 + xer_ca;
                    818:     if (T0 < T1) {
                    819:         xer_ca = 1;
                    820:     } else {
                    821:         xer_ca = 0;
                    822:     }
                    823:     RETURN();
                    824: }
                    825: 
                    826: void do_subfzeo (void);
                    827: void op_subfzeo (void)
                    828: {
                    829:     do_subfzeo();
                    830:     RETURN();
                    831: }
                    832: 
                    833: /***                           Integer comparison                          ***/
                    834: /* compare */
                    835: PPC_OP(cmp)
                    836: {
                    837:     if (Ts0 < Ts1) {
                    838:         T0 = 0x08;
                    839:     } else if (Ts0 > Ts1) {
                    840:         T0 = 0x04;
                    841:     } else {
                    842:         T0 = 0x02;
                    843:     }
                    844:     RETURN();
                    845: }
                    846: 
                    847: /* compare immediate */
                    848: PPC_OP(cmpi)
                    849: {
                    850:     if (Ts0 < SPARAM(1)) {
                    851:         T0 = 0x08;
                    852:     } else if (Ts0 > SPARAM(1)) {
                    853:         T0 = 0x04;
                    854:     } else {
                    855:         T0 = 0x02;
                    856:     }
                    857:     RETURN();
                    858: }
                    859: 
                    860: /* compare logical */
                    861: PPC_OP(cmpl)
                    862: {
                    863:     if (T0 < T1) {
                    864:         T0 = 0x08;
                    865:     } else if (T0 > T1) {
                    866:         T0 = 0x04;
                    867:     } else {
                    868:         T0 = 0x02;
                    869:     }
                    870:     RETURN();
                    871: }
                    872: 
                    873: /* compare logical immediate */
                    874: PPC_OP(cmpli)
                    875: {
                    876:     if (T0 < PARAM(1)) {
                    877:         T0 = 0x08;
                    878:     } else if (T0 > PARAM(1)) {
                    879:         T0 = 0x04;
                    880:     } else {
                    881:         T0 = 0x02;
                    882:     }
                    883:     RETURN();
                    884: }
                    885: 
                    886: /***                            Integer logical                            ***/
                    887: /* and */
                    888: PPC_OP(and)
                    889: {
                    890:     T0 &= T1;
                    891:     RETURN();
                    892: }
                    893: 
                    894: /* andc */
                    895: PPC_OP(andc)
                    896: {
                    897:     T0 &= ~T1;
                    898:     RETURN();
                    899: }
                    900: 
                    901: /* andi. */
                    902: PPC_OP(andi_)
                    903: {
                    904:     T0 &= PARAM(1);
                    905:     RETURN();
                    906: }
                    907: 
                    908: /* count leading zero */
                    909: PPC_OP(cntlzw)
                    910: {
                    911:     T1 = T0;
                    912:     for (T0 = 32; T1 > 0; T0--)
                    913:         T1 = T1 >> 1;
                    914:     RETURN();
                    915: }
                    916: 
                    917: /* eqv */
                    918: PPC_OP(eqv)
                    919: {
                    920:     T0 = ~(T0 ^ T1);
                    921:     RETURN();
                    922: }
                    923: 
                    924: /* extend sign byte */
                    925: PPC_OP(extsb)
                    926: {
                    927:     T0 = (int32_t)((int8_t)(Ts0));
                    928:     RETURN();
                    929: }
                    930: 
                    931: /* extend sign half word */
                    932: PPC_OP(extsh)
                    933: {
                    934:     T0 = (int32_t)((int16_t)(Ts0));
                    935:     RETURN();
                    936: }
                    937: 
                    938: /* nand */
                    939: PPC_OP(nand)
                    940: {
                    941:     T0 = ~(T0 & T1);
                    942:     RETURN();
                    943: }
                    944: 
                    945: /* nor */
                    946: PPC_OP(nor)
                    947: {
                    948:     T0 = ~(T0 | T1);
                    949:     RETURN();
                    950: }
                    951: 
                    952: /* or */
                    953: PPC_OP(or)
                    954: {
                    955:     T0 |= T1;
                    956:     RETURN();
                    957: }
                    958: 
                    959: /* orc */
                    960: PPC_OP(orc)
                    961: {
                    962:     T0 |= ~T1;
                    963:     RETURN();
                    964: }
                    965: 
                    966: /* ori */
                    967: PPC_OP(ori)
                    968: {
                    969:     T0 |= PARAM(1);
                    970:     RETURN();
                    971: }
                    972: 
                    973: /* xor */
                    974: PPC_OP(xor)
                    975: {
                    976:     T0 ^= T1;
                    977:     RETURN();
                    978: }
                    979: 
                    980: /* xori */
                    981: PPC_OP(xori)
                    982: {
                    983:     T0 ^= PARAM(1);
                    984:     RETURN();
                    985: }
                    986: 
                    987: /***                             Integer rotate                            ***/
                    988: /* rotate left word immediate then mask insert */
                    989: PPC_OP(rlwimi)
                    990: {
                    991:     T0 = (rotl(T0, PARAM(1)) & PARAM(2)) | (T1 & PARAM(3));
                    992:     RETURN();
                    993: }
                    994: 
                    995: /* rotate left immediate then and with mask insert */
                    996: PPC_OP(rotlwi)
                    997: {
                    998:     T0 = rotl(T0, PARAM(1));
                    999:     RETURN();
                   1000: }
                   1001: 
                   1002: PPC_OP(slwi)
                   1003: {
                   1004:     T0 = T0 << PARAM(1);
                   1005:     RETURN();
                   1006: }
                   1007: 
                   1008: PPC_OP(srwi)
                   1009: {
                   1010:     T0 = T0 >> PARAM(1);
                   1011:     RETURN();
                   1012: }
                   1013: 
                   1014: /* rotate left word then and with mask insert */
                   1015: PPC_OP(rlwinm)
                   1016: {
                   1017:     T0 = rotl(T0, PARAM(1)) & PARAM(2);
                   1018:     RETURN();
                   1019: }
                   1020: 
                   1021: PPC_OP(rotl)
                   1022: {
                   1023:     T0 = rotl(T0, T1);
                   1024:     RETURN();
                   1025: }
                   1026: 
                   1027: PPC_OP(rlwnm)
                   1028: {
                   1029:     T0 = rotl(T0, T1) & PARAM(1);
                   1030:     RETURN();
                   1031: }
                   1032: 
                   1033: /***                             Integer shift                             ***/
                   1034: /* shift left word */
                   1035: PPC_OP(slw)
                   1036: {
                   1037:     if (T1 & 0x20) {
                   1038:         T0 = 0;
                   1039:     } else {
                   1040:         T0 = T0 << T1;
                   1041:     }
                   1042:     RETURN();
                   1043: }
                   1044: 
                   1045: /* shift right algebraic word */
                   1046: void op_sraw (void)
                   1047: {
                   1048:     do_sraw();
                   1049:     RETURN();
                   1050: }
                   1051: 
                   1052: /* shift right algebraic word immediate */
                   1053: PPC_OP(srawi)
                   1054: {
                   1055:     T1 = T0;
                   1056:     T0 = (Ts0 >> PARAM(1));
                   1057:     if (Ts1 < 0 && (Ts1 & PARAM(2)) != 0) {
                   1058:         xer_ca = 1;
                   1059:     } else {
                   1060:         xer_ca = 0;
                   1061:     }
                   1062:     RETURN();
                   1063: }
                   1064: 
                   1065: /* shift right word */
                   1066: PPC_OP(srw)
                   1067: {
                   1068:     if (T1 & 0x20) {
                   1069:         T0 = 0;
                   1070:     } else {
                   1071:         T0 = T0 >> T1;
                   1072:     }
                   1073:     RETURN();
                   1074: }
                   1075: 
                   1076: /***                       Floating-Point arithmetic                       ***/
                   1077: /* fadd - fadd. */
                   1078: PPC_OP(fadd)
                   1079: {
                   1080:     FT0 += FT1;
                   1081:     RETURN();
                   1082: }
                   1083: 
                   1084: /* fsub - fsub. */
                   1085: PPC_OP(fsub)
                   1086: {
                   1087:     FT0 -= FT1;
                   1088:     RETURN();
                   1089: }
                   1090: 
                   1091: /* fmul - fmul. */
                   1092: PPC_OP(fmul)
                   1093: {
                   1094:     FT0 *= FT1;
                   1095:     RETURN();
                   1096: }
                   1097: 
                   1098: /* fdiv - fdiv. */
                   1099: PPC_OP(fdiv)
                   1100: {
                   1101:     FT0 = float64_div(FT0, FT1, &env->fp_status);
                   1102:     RETURN();
                   1103: }
                   1104: 
                   1105: /* fsqrt - fsqrt. */
                   1106: PPC_OP(fsqrt)
                   1107: {
                   1108:     do_fsqrt();
                   1109:     RETURN();
                   1110: }
                   1111: 
                   1112: /* fres - fres. */
                   1113: PPC_OP(fres)
                   1114: {
                   1115:     do_fres();
                   1116:     RETURN();
                   1117: }
                   1118: 
                   1119: /* frsqrte  - frsqrte. */
                   1120: PPC_OP(frsqrte)
                   1121: {
                   1122:     do_frsqrte();
                   1123:     RETURN();
                   1124: }
                   1125: 
                   1126: /* fsel - fsel. */
                   1127: PPC_OP(fsel)
                   1128: {
                   1129:     do_fsel();
                   1130:     RETURN();
                   1131: }
                   1132: 
                   1133: /***                     Floating-Point multiply-and-add                   ***/
                   1134: /* fmadd - fmadd. */
                   1135: PPC_OP(fmadd)
                   1136: {
                   1137:     FT0 = (FT0 * FT1) + FT2;
                   1138:     RETURN();
                   1139: }
                   1140: 
                   1141: /* fmsub - fmsub. */
                   1142: PPC_OP(fmsub)
                   1143: {
                   1144:     FT0 = (FT0 * FT1) - FT2;
                   1145:     RETURN();
                   1146: }
                   1147: 
                   1148: /* fnmadd - fnmadd. - fnmadds - fnmadds. */
                   1149: PPC_OP(fnmadd)
                   1150: {
                   1151:     do_fnmadd();
                   1152:     RETURN();
                   1153: }
                   1154: 
                   1155: /* fnmsub - fnmsub. */
                   1156: PPC_OP(fnmsub)
                   1157: {
                   1158:     do_fnmsub();
                   1159:     RETURN();
                   1160: }
                   1161: 
                   1162: /***                     Floating-Point round & convert                    ***/
                   1163: /* frsp - frsp. */
                   1164: PPC_OP(frsp)
                   1165: {
                   1166:     FT0 = (float)FT0;
                   1167:     RETURN();
                   1168: }
                   1169: 
                   1170: /* fctiw - fctiw. */
                   1171: PPC_OP(fctiw)
                   1172: {
                   1173:     do_fctiw();
                   1174:     RETURN();
                   1175: }
                   1176: 
                   1177: /* fctiwz - fctiwz. */
                   1178: PPC_OP(fctiwz)
                   1179: {
                   1180:     do_fctiwz();
                   1181:     RETURN();
                   1182: }
                   1183: 
                   1184: 
                   1185: /***                         Floating-Point compare                        ***/
                   1186: /* fcmpu */
                   1187: PPC_OP(fcmpu)
                   1188: {
                   1189:     do_fcmpu();
                   1190:     RETURN();
                   1191: }
                   1192: 
                   1193: /* fcmpo */
                   1194: PPC_OP(fcmpo)
                   1195: {
                   1196:     do_fcmpo();
                   1197:     RETURN();
                   1198: }
                   1199: 
                   1200: /***                         Floating-point move                           ***/
                   1201: /* fabs */
                   1202: PPC_OP(fabs)
                   1203: {
                   1204:     FT0 = float64_abs(FT0);
                   1205:     RETURN();
                   1206: }
                   1207: 
                   1208: /* fnabs */
                   1209: PPC_OP(fnabs)
                   1210: {
                   1211:     FT0 = float64_abs(FT0);
                   1212:     FT0 = float64_chs(FT0);
                   1213:     RETURN();
                   1214: }
                   1215: 
                   1216: /* fneg */
                   1217: PPC_OP(fneg)
                   1218: {
                   1219:     FT0 = float64_chs(FT0);
                   1220:     RETURN();
                   1221: }
                   1222: 
                   1223: /* Load and store */
                   1224: #define MEMSUFFIX _raw
                   1225: #include "op_mem.h"
                   1226: #if !defined(CONFIG_USER_ONLY)
                   1227: #define MEMSUFFIX _user
                   1228: #include "op_mem.h"
                   1229: 
                   1230: #define MEMSUFFIX _kernel
                   1231: #include "op_mem.h"
                   1232: #endif
                   1233: 
                   1234: /* Special op to check and maybe clear reservation */
                   1235: PPC_OP(check_reservation)
                   1236: {
                   1237:     if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003))
                   1238:         env->reserve = -1;
                   1239:     RETURN();
                   1240: }
                   1241: 
                   1242: /* Return from interrupt */
                   1243: void do_rfi (void);
                   1244: void op_rfi (void)
                   1245: {
                   1246:     do_rfi();
                   1247:     RETURN();
                   1248: }
                   1249: 
                   1250: /* Trap word */
                   1251: void do_tw (uint32_t cmp, int flags);
                   1252: void op_tw (void)
                   1253: {
                   1254:     do_tw(T1, PARAM(1));
                   1255:     RETURN();
                   1256: }
                   1257: 
                   1258: void op_twi (void)
                   1259: {
                   1260:     do_tw(PARAM(1), PARAM(2));
                   1261:     RETURN();
                   1262: }
                   1263: 
                   1264: /* Instruction cache block invalidate */
                   1265: PPC_OP(icbi)
                   1266: {
                   1267:     do_icbi();
                   1268:     RETURN();
                   1269: }
                   1270: 
                   1271: /* tlbia */
                   1272: PPC_OP(tlbia)
                   1273: {
                   1274:     do_tlbia();
                   1275:     RETURN();
                   1276: }
                   1277: 
                   1278: /* tlbie */
                   1279: PPC_OP(tlbie)
                   1280: {
                   1281:     do_tlbie();
                   1282:     RETURN();
                   1283: }
                   1284: 
                   1285: void op_store_pir (void)
                   1286: {
                   1287:     env->spr[SPR_PIR] = T0 & 0x0000000FUL;
                   1288:     RETURN();
                   1289: }

unix.superglobalmegacorp.com

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