Annotation of qemu/target-ppc/op.c, revision 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.