Annotation of qemu/target-alpha/translate.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *  Alpha emulation cpu translation for qemu.
        !             3:  *
        !             4:  *  Copyright (c) 2007 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: #include <stdint.h>
        !            22: #include <stdlib.h>
        !            23: #include <stdio.h>
        !            24: 
        !            25: #include "cpu.h"
        !            26: #include "exec-all.h"
        !            27: #include "disas.h"
        !            28: 
        !            29: #define DO_SINGLE_STEP
        !            30: #define GENERATE_NOP
        !            31: #define ALPHA_DEBUG_DISAS
        !            32: #define DO_TB_FLUSH
        !            33: 
        !            34: typedef struct DisasContext DisasContext;
        !            35: struct DisasContext {
        !            36:     uint64_t pc;
        !            37:     int mem_idx;
        !            38: #if !defined (CONFIG_USER_ONLY)
        !            39:     int pal_mode;
        !            40: #endif
        !            41:     uint32_t amask;
        !            42: };
        !            43: 
        !            44: #ifdef USE_DIRECT_JUMP
        !            45: #define TBPARAM(x)
        !            46: #else
        !            47: #define TBPARAM(x) (long)(x)
        !            48: #endif
        !            49: 
        !            50: enum {
        !            51: #define DEF(s, n, copy_size) INDEX_op_ ## s,
        !            52: #include "opc.h"
        !            53: #undef DEF
        !            54:     NB_OPS,
        !            55: };
        !            56: 
        !            57: static uint16_t *gen_opc_ptr;
        !            58: static uint32_t *gen_opparam_ptr;
        !            59: 
        !            60: #include "gen-op.h"
        !            61: 
        !            62: static always_inline void gen_op_nop (void)
        !            63: {
        !            64: #if defined(GENERATE_NOP)
        !            65:     gen_op_no_op();
        !            66: #endif
        !            67: }
        !            68: 
        !            69: #define GEN32(func, NAME) \
        !            70: static GenOpFunc *NAME ## _table [32] = {                                     \
        !            71: NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
        !            72: NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
        !            73: NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
        !            74: NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
        !            75: NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
        !            76: NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
        !            77: NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
        !            78: NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
        !            79: };                                                                            \
        !            80: static always_inline void func (int n)                                        \
        !            81: {                                                                             \
        !            82:     NAME ## _table[n]();                                                      \
        !            83: }
        !            84: 
        !            85: /* IR moves */
        !            86: /* Special hacks for ir31 */
        !            87: #define gen_op_load_T0_ir31 gen_op_reset_T0
        !            88: #define gen_op_load_T1_ir31 gen_op_reset_T1
        !            89: #define gen_op_load_T2_ir31 gen_op_reset_T2
        !            90: #define gen_op_store_T0_ir31 gen_op_nop
        !            91: #define gen_op_store_T1_ir31 gen_op_nop
        !            92: #define gen_op_store_T2_ir31 gen_op_nop
        !            93: #define gen_op_cmov_ir31 gen_op_nop
        !            94: GEN32(gen_op_load_T0_ir, gen_op_load_T0_ir);
        !            95: GEN32(gen_op_load_T1_ir, gen_op_load_T1_ir);
        !            96: GEN32(gen_op_load_T2_ir, gen_op_load_T2_ir);
        !            97: GEN32(gen_op_store_T0_ir, gen_op_store_T0_ir);
        !            98: GEN32(gen_op_store_T1_ir, gen_op_store_T1_ir);
        !            99: GEN32(gen_op_store_T2_ir, gen_op_store_T2_ir);
        !           100: GEN32(gen_op_cmov_ir, gen_op_cmov_ir);
        !           101: 
        !           102: static always_inline void gen_load_ir (DisasContext *ctx, int irn, int Tn)
        !           103: {
        !           104:     switch (Tn) {
        !           105:     case 0:
        !           106:         gen_op_load_T0_ir(irn);
        !           107:         break;
        !           108:     case 1:
        !           109:         gen_op_load_T1_ir(irn);
        !           110:         break;
        !           111:     case 2:
        !           112:         gen_op_load_T2_ir(irn);
        !           113:         break;
        !           114:     }
        !           115: }
        !           116: 
        !           117: static always_inline void gen_store_ir (DisasContext *ctx, int irn, int Tn)
        !           118: {
        !           119:     switch (Tn) {
        !           120:     case 0:
        !           121:         gen_op_store_T0_ir(irn);
        !           122:         break;
        !           123:     case 1:
        !           124:         gen_op_store_T1_ir(irn);
        !           125:         break;
        !           126:     case 2:
        !           127:         gen_op_store_T2_ir(irn);
        !           128:         break;
        !           129:     }
        !           130: }
        !           131: 
        !           132: /* FIR moves */
        !           133: /* Special hacks for fir31 */
        !           134: #define gen_op_load_FT0_fir31 gen_op_reset_FT0
        !           135: #define gen_op_load_FT1_fir31 gen_op_reset_FT1
        !           136: #define gen_op_load_FT2_fir31 gen_op_reset_FT2
        !           137: #define gen_op_store_FT0_fir31 gen_op_nop
        !           138: #define gen_op_store_FT1_fir31 gen_op_nop
        !           139: #define gen_op_store_FT2_fir31 gen_op_nop
        !           140: #define gen_op_cmov_fir31 gen_op_nop
        !           141: GEN32(gen_op_load_FT0_fir, gen_op_load_FT0_fir);
        !           142: GEN32(gen_op_load_FT1_fir, gen_op_load_FT1_fir);
        !           143: GEN32(gen_op_load_FT2_fir, gen_op_load_FT2_fir);
        !           144: GEN32(gen_op_store_FT0_fir, gen_op_store_FT0_fir);
        !           145: GEN32(gen_op_store_FT1_fir, gen_op_store_FT1_fir);
        !           146: GEN32(gen_op_store_FT2_fir, gen_op_store_FT2_fir);
        !           147: GEN32(gen_op_cmov_fir, gen_op_cmov_fir);
        !           148: 
        !           149: static always_inline void gen_load_fir (DisasContext *ctx, int firn, int Tn)
        !           150: {
        !           151:     switch (Tn) {
        !           152:     case 0:
        !           153:         gen_op_load_FT0_fir(firn);
        !           154:         break;
        !           155:     case 1:
        !           156:         gen_op_load_FT1_fir(firn);
        !           157:         break;
        !           158:     case 2:
        !           159:         gen_op_load_FT2_fir(firn);
        !           160:         break;
        !           161:     }
        !           162: }
        !           163: 
        !           164: static always_inline void gen_store_fir (DisasContext *ctx, int firn, int Tn)
        !           165: {
        !           166:     switch (Tn) {
        !           167:     case 0:
        !           168:         gen_op_store_FT0_fir(firn);
        !           169:         break;
        !           170:     case 1:
        !           171:         gen_op_store_FT1_fir(firn);
        !           172:         break;
        !           173:     case 2:
        !           174:         gen_op_store_FT2_fir(firn);
        !           175:         break;
        !           176:     }
        !           177: }
        !           178: 
        !           179: /* Memory moves */
        !           180: #if defined(CONFIG_USER_ONLY)
        !           181: #define OP_LD_TABLE(width)                                                    \
        !           182: static GenOpFunc *gen_op_ld##width[] = {                                      \
        !           183:     &gen_op_ld##width##_raw,                                                  \
        !           184: }
        !           185: #define OP_ST_TABLE(width)                                                    \
        !           186: static GenOpFunc *gen_op_st##width[] = {                                      \
        !           187:     &gen_op_st##width##_raw,                                                  \
        !           188: }
        !           189: #else
        !           190: #define OP_LD_TABLE(width)                                                    \
        !           191: static GenOpFunc *gen_op_ld##width[] = {                                      \
        !           192:     &gen_op_ld##width##_kernel,                                               \
        !           193:     &gen_op_ld##width##_executive,                                            \
        !           194:     &gen_op_ld##width##_supervisor,                                           \
        !           195:     &gen_op_ld##width##_user,                                                 \
        !           196: }
        !           197: #define OP_ST_TABLE(width)                                                    \
        !           198: static GenOpFunc *gen_op_st##width[] = {                                      \
        !           199:     &gen_op_st##width##_kernel,                                               \
        !           200:     &gen_op_st##width##_executive,                                            \
        !           201:     &gen_op_st##width##_supervisor,                                           \
        !           202:     &gen_op_st##width##_user,                                                 \
        !           203: }
        !           204: #endif
        !           205: 
        !           206: #define GEN_LD(width)                                                         \
        !           207: OP_LD_TABLE(width);                                                           \
        !           208: static always_inline void gen_ld##width (DisasContext *ctx)                   \
        !           209: {                                                                             \
        !           210:     (*gen_op_ld##width[ctx->mem_idx])();                                      \
        !           211: }
        !           212: 
        !           213: #define GEN_ST(width)                                                         \
        !           214: OP_ST_TABLE(width);                                                           \
        !           215: static always_inline void gen_st##width (DisasContext *ctx)                   \
        !           216: {                                                                             \
        !           217:     (*gen_op_st##width[ctx->mem_idx])();                                      \
        !           218: }
        !           219: 
        !           220: GEN_LD(bu);
        !           221: GEN_ST(b);
        !           222: GEN_LD(wu);
        !           223: GEN_ST(w);
        !           224: GEN_LD(l);
        !           225: GEN_ST(l);
        !           226: GEN_LD(q);
        !           227: GEN_ST(q);
        !           228: GEN_LD(q_u);
        !           229: GEN_ST(q_u);
        !           230: GEN_LD(l_l);
        !           231: GEN_ST(l_c);
        !           232: GEN_LD(q_l);
        !           233: GEN_ST(q_c);
        !           234: 
        !           235: #if 0 /* currently unused */
        !           236: GEN_LD(f);
        !           237: GEN_ST(f);
        !           238: GEN_LD(g);
        !           239: GEN_ST(g);
        !           240: #endif /* 0 */
        !           241: GEN_LD(s);
        !           242: GEN_ST(s);
        !           243: GEN_LD(t);
        !           244: GEN_ST(t);
        !           245: 
        !           246: #if defined(__i386__) || defined(__x86_64__)
        !           247: static always_inline void gen_op_set_s16_T0 (int16_t imm)
        !           248: {
        !           249:     gen_op_set_s32_T0((int32_t)imm);
        !           250: }
        !           251: 
        !           252: static always_inline void gen_op_set_s16_T1 (int16_t imm)
        !           253: {
        !           254:     gen_op_set_s32_T1((int32_t)imm);
        !           255: }
        !           256: 
        !           257: static always_inline void gen_op_set_u16_T0 (uint16_t imm)
        !           258: {
        !           259:     gen_op_set_s32_T0((uint32_t)imm);
        !           260: }
        !           261: 
        !           262: static always_inline void gen_op_set_u16_T1 (uint16_t imm)
        !           263: {
        !           264:     gen_op_set_s32_T1((uint32_t)imm);
        !           265: }
        !           266: #endif
        !           267: 
        !           268: static always_inline void gen_set_sT0 (DisasContext *ctx, int64_t imm)
        !           269: {
        !           270:     int32_t imm32;
        !           271:     int16_t imm16;
        !           272: 
        !           273:     imm32 = imm;
        !           274:     if (imm32 == imm) {
        !           275:         imm16 = imm;
        !           276:         if (imm16 == imm) {
        !           277:             if (imm == 0) {
        !           278:                 gen_op_reset_T0();
        !           279:             } else {
        !           280:                 gen_op_set_s16_T0(imm16);
        !           281:             }
        !           282:         } else {
        !           283:             gen_op_set_s32_T0(imm32);
        !           284:         }
        !           285:     } else {
        !           286: #if 0 // Qemu does not know how to do this...
        !           287:         gen_op_set_64_T0(imm);
        !           288: #else
        !           289:         gen_op_set_64_T0(imm >> 32, imm);
        !           290: #endif
        !           291:     }
        !           292: }
        !           293: 
        !           294: static always_inline void gen_set_sT1 (DisasContext *ctx, int64_t imm)
        !           295: {
        !           296:     int32_t imm32;
        !           297:     int16_t imm16;
        !           298: 
        !           299:     imm32 = imm;
        !           300:     if (imm32 == imm) {
        !           301:         imm16 = imm;
        !           302:         if (imm16 == imm) {
        !           303:             if (imm == 0) {
        !           304:                 gen_op_reset_T1();
        !           305:             } else {
        !           306:                 gen_op_set_s16_T1(imm16);
        !           307:             }
        !           308:         } else {
        !           309:             gen_op_set_s32_T1(imm32);
        !           310:         }
        !           311:     } else {
        !           312: #if 0 // Qemu does not know how to do this...
        !           313:         gen_op_set_64_T1(imm);
        !           314: #else
        !           315:         gen_op_set_64_T1(imm >> 32, imm);
        !           316: #endif
        !           317:     }
        !           318: }
        !           319: 
        !           320: static always_inline void gen_set_uT0 (DisasContext *ctx, uint64_t imm)
        !           321: {
        !           322:     if (!(imm >> 32)) {
        !           323:         if ((!imm >> 16)) {
        !           324:             if (imm == 0)
        !           325:                 gen_op_reset_T0();
        !           326:             else
        !           327:                 gen_op_set_u16_T0(imm);
        !           328:         } else {
        !           329:             gen_op_set_u32_T0(imm);
        !           330:         }
        !           331:     } else {
        !           332: #if 0 // Qemu does not know how to do this...
        !           333:         gen_op_set_64_T0(imm);
        !           334: #else
        !           335:         gen_op_set_64_T0(imm >> 32, imm);
        !           336: #endif
        !           337:     }
        !           338: }
        !           339: 
        !           340: static always_inline void gen_set_uT1 (DisasContext *ctx, uint64_t imm)
        !           341: {
        !           342:     if (!(imm >> 32)) {
        !           343:         if ((!imm >> 16)) {
        !           344:             if (imm == 0)
        !           345:                 gen_op_reset_T1();
        !           346:             else
        !           347:                 gen_op_set_u16_T1(imm);
        !           348:         } else {
        !           349:             gen_op_set_u32_T1(imm);
        !           350:         }
        !           351:     } else {
        !           352: #if 0 // Qemu does not know how to do this...
        !           353:         gen_op_set_64_T1(imm);
        !           354: #else
        !           355:         gen_op_set_64_T1(imm >> 32, imm);
        !           356: #endif
        !           357:     }
        !           358: }
        !           359: 
        !           360: static always_inline void gen_update_pc (DisasContext *ctx)
        !           361: {
        !           362:     if (!(ctx->pc >> 32)) {
        !           363:         gen_op_update_pc32(ctx->pc);
        !           364:     } else {
        !           365: #if 0 // Qemu does not know how to do this...
        !           366:         gen_op_update_pc(ctx->pc);
        !           367: #else
        !           368:         gen_op_update_pc(ctx->pc >> 32, ctx->pc);
        !           369: #endif
        !           370:     }
        !           371: }
        !           372: 
        !           373: static always_inline void _gen_op_bcond (DisasContext *ctx)
        !           374: {
        !           375: #if 0 // Qemu does not know how to do this...
        !           376:     gen_op_bcond(ctx->pc);
        !           377: #else
        !           378:     gen_op_bcond(ctx->pc >> 32, ctx->pc);
        !           379: #endif
        !           380: }
        !           381: 
        !           382: static always_inline void gen_excp (DisasContext *ctx,
        !           383:                                     int exception, int error_code)
        !           384: {
        !           385:     gen_update_pc(ctx);
        !           386:     gen_op_excp(exception, error_code);
        !           387: }
        !           388: 
        !           389: static always_inline void gen_invalid (DisasContext *ctx)
        !           390: {
        !           391:     gen_excp(ctx, EXCP_OPCDEC, 0);
        !           392: }
        !           393: 
        !           394: static always_inline void gen_load_mem (DisasContext *ctx,
        !           395:                                         void (*gen_load_op)(DisasContext *ctx),
        !           396:                                         int ra, int rb, int32_t disp16,
        !           397:                                         int clear)
        !           398: {
        !           399:     if (ra == 31 && disp16 == 0) {
        !           400:         /* UNOP */
        !           401:         gen_op_nop();
        !           402:     } else {
        !           403:         gen_load_ir(ctx, rb, 0);
        !           404:         if (disp16 != 0) {
        !           405:             gen_set_sT1(ctx, disp16);
        !           406:             gen_op_addq();
        !           407:         }
        !           408:         if (clear)
        !           409:             gen_op_n7();
        !           410:         (*gen_load_op)(ctx);
        !           411:         gen_store_ir(ctx, ra, 1);
        !           412:     }
        !           413: }
        !           414: 
        !           415: static always_inline void gen_store_mem (DisasContext *ctx,
        !           416:                                          void (*gen_store_op)(DisasContext *ctx),
        !           417:                                          int ra, int rb, int32_t disp16,
        !           418:                                          int clear)
        !           419: {
        !           420:     gen_load_ir(ctx, rb, 0);
        !           421:     if (disp16 != 0) {
        !           422:         gen_set_sT1(ctx, disp16);
        !           423:         gen_op_addq();
        !           424:     }
        !           425:     if (clear)
        !           426:         gen_op_n7();
        !           427:     gen_load_ir(ctx, ra, 1);
        !           428:     (*gen_store_op)(ctx);
        !           429: }
        !           430: 
        !           431: static always_inline void gen_load_fmem (DisasContext *ctx,
        !           432:                                          void (*gen_load_fop)(DisasContext *ctx),
        !           433:                                          int ra, int rb, int32_t disp16)
        !           434: {
        !           435:     gen_load_ir(ctx, rb, 0);
        !           436:     if (disp16 != 0) {
        !           437:         gen_set_sT1(ctx, disp16);
        !           438:         gen_op_addq();
        !           439:     }
        !           440:     (*gen_load_fop)(ctx);
        !           441:     gen_store_fir(ctx, ra, 1);
        !           442: }
        !           443: 
        !           444: static always_inline void gen_store_fmem (DisasContext *ctx,
        !           445:                                           void (*gen_store_fop)(DisasContext *ctx),
        !           446:                                           int ra, int rb, int32_t disp16)
        !           447: {
        !           448:     gen_load_ir(ctx, rb, 0);
        !           449:     if (disp16 != 0) {
        !           450:         gen_set_sT1(ctx, disp16);
        !           451:         gen_op_addq();
        !           452:     }
        !           453:     gen_load_fir(ctx, ra, 1);
        !           454:     (*gen_store_fop)(ctx);
        !           455: }
        !           456: 
        !           457: static always_inline void gen_bcond (DisasContext *ctx,
        !           458:                                      void (*gen_test_op)(void),
        !           459:                                      int ra, int32_t disp16)
        !           460: {
        !           461:     if (disp16 != 0) {
        !           462:         gen_set_uT0(ctx, ctx->pc);
        !           463:         gen_set_sT1(ctx, disp16 << 2);
        !           464:         gen_op_addq1();
        !           465:     } else {
        !           466:         gen_set_uT1(ctx, ctx->pc);
        !           467:     }
        !           468:     gen_load_ir(ctx, ra, 0);
        !           469:     (*gen_test_op)();
        !           470:     _gen_op_bcond(ctx);
        !           471: }
        !           472: 
        !           473: static always_inline void gen_fbcond (DisasContext *ctx,
        !           474:                                       void (*gen_test_op)(void),
        !           475:                                       int ra, int32_t disp16)
        !           476: {
        !           477:     if (disp16 != 0) {
        !           478:         gen_set_uT0(ctx, ctx->pc);
        !           479:         gen_set_sT1(ctx, disp16 << 2);
        !           480:         gen_op_addq1();
        !           481:     } else {
        !           482:         gen_set_uT1(ctx, ctx->pc);
        !           483:     }
        !           484:     gen_load_fir(ctx, ra, 0);
        !           485:     (*gen_test_op)();
        !           486:     _gen_op_bcond(ctx);
        !           487: }
        !           488: 
        !           489: static always_inline void gen_arith2 (DisasContext *ctx,
        !           490:                                       void (*gen_arith_op)(void),
        !           491:                                       int rb, int rc, int islit, int8_t lit)
        !           492: {
        !           493:     if (islit)
        !           494:         gen_set_sT0(ctx, lit);
        !           495:     else
        !           496:         gen_load_ir(ctx, rb, 0);
        !           497:     (*gen_arith_op)();
        !           498:     gen_store_ir(ctx, rc, 0);
        !           499: }
        !           500: 
        !           501: static always_inline void gen_arith3 (DisasContext *ctx,
        !           502:                                       void (*gen_arith_op)(void),
        !           503:                                       int ra, int rb, int rc,
        !           504:                                       int islit, int8_t lit)
        !           505: {
        !           506:     gen_load_ir(ctx, ra, 0);
        !           507:     if (islit)
        !           508:         gen_set_sT1(ctx, lit);
        !           509:     else
        !           510:         gen_load_ir(ctx, rb, 1);
        !           511:     (*gen_arith_op)();
        !           512:     gen_store_ir(ctx, rc, 0);
        !           513: }
        !           514: 
        !           515: static always_inline void gen_cmov (DisasContext *ctx,
        !           516:                                     void (*gen_test_op)(void),
        !           517:                                     int ra, int rb, int rc,
        !           518:                                     int islit, int8_t lit)
        !           519: {
        !           520:     gen_load_ir(ctx, ra, 1);
        !           521:     if (islit)
        !           522:         gen_set_sT0(ctx, lit);
        !           523:     else
        !           524:         gen_load_ir(ctx, rb, 0);
        !           525:     (*gen_test_op)();
        !           526:     gen_op_cmov_ir(rc);
        !           527: }
        !           528: 
        !           529: static always_inline void gen_farith2 (DisasContext *ctx,
        !           530:                                        void (*gen_arith_fop)(void),
        !           531:                                        int rb, int rc)
        !           532: {
        !           533:     gen_load_fir(ctx, rb, 0);
        !           534:     (*gen_arith_fop)();
        !           535:     gen_store_fir(ctx, rc, 0);
        !           536: }
        !           537: 
        !           538: static always_inline void gen_farith3 (DisasContext *ctx,
        !           539:                                        void (*gen_arith_fop)(void),
        !           540:                                        int ra, int rb, int rc)
        !           541: {
        !           542:     gen_load_fir(ctx, ra, 0);
        !           543:     gen_load_fir(ctx, rb, 1);
        !           544:     (*gen_arith_fop)();
        !           545:     gen_store_fir(ctx, rc, 0);
        !           546: }
        !           547: 
        !           548: static always_inline void gen_fcmov (DisasContext *ctx,
        !           549:                                      void (*gen_test_fop)(void),
        !           550:                                      int ra, int rb, int rc)
        !           551: {
        !           552:     gen_load_fir(ctx, ra, 0);
        !           553:     gen_load_fir(ctx, rb, 1);
        !           554:     (*gen_test_fop)();
        !           555:     gen_op_cmov_fir(rc);
        !           556: }
        !           557: 
        !           558: static always_inline void gen_fti (DisasContext *ctx,
        !           559:                                    void (*gen_move_fop)(void),
        !           560:                                    int ra, int rc)
        !           561: {
        !           562:     gen_load_fir(ctx, rc, 0);
        !           563:     (*gen_move_fop)();
        !           564:     gen_store_ir(ctx, ra, 0);
        !           565: }
        !           566: 
        !           567: static always_inline void gen_itf (DisasContext *ctx,
        !           568:                                    void (*gen_move_fop)(void),
        !           569:                                    int ra, int rc)
        !           570: {
        !           571:     gen_load_ir(ctx, ra, 0);
        !           572:     (*gen_move_fop)();
        !           573:     gen_store_fir(ctx, rc, 0);
        !           574: }
        !           575: 
        !           576: static always_inline void gen_s4addl (void)
        !           577: {
        !           578:     gen_op_s4();
        !           579:     gen_op_addl();
        !           580: }
        !           581: 
        !           582: static always_inline void gen_s4subl (void)
        !           583: {
        !           584:     gen_op_s4();
        !           585:     gen_op_subl();
        !           586: }
        !           587: 
        !           588: static always_inline void gen_s8addl (void)
        !           589: {
        !           590:     gen_op_s8();
        !           591:     gen_op_addl();
        !           592: }
        !           593: 
        !           594: static always_inline void gen_s8subl (void)
        !           595: {
        !           596:     gen_op_s8();
        !           597:     gen_op_subl();
        !           598: }
        !           599: 
        !           600: static always_inline void gen_s4addq (void)
        !           601: {
        !           602:     gen_op_s4();
        !           603:     gen_op_addq();
        !           604: }
        !           605: 
        !           606: static always_inline void gen_s4subq (void)
        !           607: {
        !           608:     gen_op_s4();
        !           609:     gen_op_subq();
        !           610: }
        !           611: 
        !           612: static always_inline void gen_s8addq (void)
        !           613: {
        !           614:     gen_op_s8();
        !           615:     gen_op_addq();
        !           616: }
        !           617: 
        !           618: static always_inline void gen_s8subq (void)
        !           619: {
        !           620:     gen_op_s8();
        !           621:     gen_op_subq();
        !           622: }
        !           623: 
        !           624: static always_inline void gen_amask (void)
        !           625: {
        !           626:     gen_op_load_amask();
        !           627:     gen_op_bic();
        !           628: }
        !           629: 
        !           630: static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
        !           631: {
        !           632:     uint32_t palcode;
        !           633:     int32_t disp21, disp16, disp12;
        !           634:     uint16_t fn11, fn16;
        !           635:     uint8_t opc, ra, rb, rc, sbz, fpfn, fn7, fn2, islit;
        !           636:     int8_t lit;
        !           637:     int ret;
        !           638: 
        !           639:     /* Decode all instruction fields */
        !           640:     opc = insn >> 26;
        !           641:     ra = (insn >> 21) & 0x1F;
        !           642:     rb = (insn >> 16) & 0x1F;
        !           643:     rc = insn & 0x1F;
        !           644:     sbz = (insn >> 13) & 0x07;
        !           645:     islit = (insn >> 12) & 1;
        !           646:     lit = (insn >> 13) & 0xFF;
        !           647:     palcode = insn & 0x03FFFFFF;
        !           648:     disp21 = ((int32_t)((insn & 0x001FFFFF) << 11)) >> 11;
        !           649:     disp16 = (int16_t)(insn & 0x0000FFFF);
        !           650:     disp12 = (int32_t)((insn & 0x00000FFF) << 20) >> 20;
        !           651:     fn16 = insn & 0x0000FFFF;
        !           652:     fn11 = (insn >> 5) & 0x000007FF;
        !           653:     fpfn = fn11 & 0x3F;
        !           654:     fn7 = (insn >> 5) & 0x0000007F;
        !           655:     fn2 = (insn >> 5) & 0x00000003;
        !           656:     ret = 0;
        !           657: #if defined ALPHA_DEBUG_DISAS
        !           658:     if (logfile != NULL) {
        !           659:         fprintf(logfile, "opc %02x ra %d rb %d rc %d disp16 %04x\n",
        !           660:                 opc, ra, rb, rc, disp16);
        !           661:     }
        !           662: #endif
        !           663:     switch (opc) {
        !           664:     case 0x00:
        !           665:         /* CALL_PAL */
        !           666:         if (palcode >= 0x80 && palcode < 0xC0) {
        !           667:             /* Unprivileged PAL call */
        !           668:             gen_excp(ctx, EXCP_CALL_PAL + ((palcode & 0x1F) << 6), 0);
        !           669: #if !defined (CONFIG_USER_ONLY)
        !           670:         } else if (palcode < 0x40) {
        !           671:             /* Privileged PAL code */
        !           672:             if (ctx->mem_idx & 1)
        !           673:                 goto invalid_opc;
        !           674:             else
        !           675:                 gen_excp(ctx, EXCP_CALL_PALP + ((palcode & 0x1F) << 6), 0);
        !           676: #endif
        !           677:         } else {
        !           678:             /* Invalid PAL call */
        !           679:             goto invalid_opc;
        !           680:         }
        !           681:         ret = 3;
        !           682:         break;
        !           683:     case 0x01:
        !           684:         /* OPC01 */
        !           685:         goto invalid_opc;
        !           686:     case 0x02:
        !           687:         /* OPC02 */
        !           688:         goto invalid_opc;
        !           689:     case 0x03:
        !           690:         /* OPC03 */
        !           691:         goto invalid_opc;
        !           692:     case 0x04:
        !           693:         /* OPC04 */
        !           694:         goto invalid_opc;
        !           695:     case 0x05:
        !           696:         /* OPC05 */
        !           697:         goto invalid_opc;
        !           698:     case 0x06:
        !           699:         /* OPC06 */
        !           700:         goto invalid_opc;
        !           701:     case 0x07:
        !           702:         /* OPC07 */
        !           703:         goto invalid_opc;
        !           704:     case 0x08:
        !           705:         /* LDA */
        !           706:         gen_load_ir(ctx, rb, 0);
        !           707:         gen_set_sT1(ctx, disp16);
        !           708:         gen_op_addq();
        !           709:         gen_store_ir(ctx, ra, 0);
        !           710:         break;
        !           711:     case 0x09:
        !           712:         /* LDAH */
        !           713:         gen_load_ir(ctx, rb, 0);
        !           714:         gen_set_sT1(ctx, disp16 << 16);
        !           715:         gen_op_addq();
        !           716:         gen_store_ir(ctx, ra, 0);
        !           717:         break;
        !           718:     case 0x0A:
        !           719:         /* LDBU */
        !           720:         if (!(ctx->amask & AMASK_BWX))
        !           721:             goto invalid_opc;
        !           722:         gen_load_mem(ctx, &gen_ldbu, ra, rb, disp16, 0);
        !           723:         break;
        !           724:     case 0x0B:
        !           725:         /* LDQ_U */
        !           726:         gen_load_mem(ctx, &gen_ldq_u, ra, rb, disp16, 1);
        !           727:         break;
        !           728:     case 0x0C:
        !           729:         /* LDWU */
        !           730:         if (!(ctx->amask & AMASK_BWX))
        !           731:             goto invalid_opc;
        !           732:         gen_load_mem(ctx, &gen_ldwu, ra, rb, disp16, 0);
        !           733:         break;
        !           734:     case 0x0D:
        !           735:         /* STW */
        !           736:         if (!(ctx->amask & AMASK_BWX))
        !           737:             goto invalid_opc;
        !           738:         gen_store_mem(ctx, &gen_stw, ra, rb, disp16, 0);
        !           739:         break;
        !           740:     case 0x0E:
        !           741:         /* STB */
        !           742:         if (!(ctx->amask & AMASK_BWX))
        !           743:             goto invalid_opc;
        !           744:         gen_store_mem(ctx, &gen_stb, ra, rb, disp16, 0);
        !           745:         break;
        !           746:     case 0x0F:
        !           747:         /* STQ_U */
        !           748:         gen_store_mem(ctx, &gen_stq_u, ra, rb, disp16, 1);
        !           749:         break;
        !           750:     case 0x10:
        !           751:         switch (fn7) {
        !           752:         case 0x00:
        !           753:             /* ADDL */
        !           754:             gen_arith3(ctx, &gen_op_addl, ra, rb, rc, islit, lit);
        !           755:             break;
        !           756:         case 0x02:
        !           757:             /* S4ADDL */
        !           758:             gen_arith3(ctx, &gen_s4addl, ra, rb, rc, islit, lit);
        !           759:             break;
        !           760:         case 0x09:
        !           761:             /* SUBL */
        !           762:             gen_arith3(ctx, &gen_op_subl, ra, rb, rc, islit, lit);
        !           763:             break;
        !           764:         case 0x0B:
        !           765:             /* S4SUBL */
        !           766:             gen_arith3(ctx, &gen_s4subl, ra, rb, rc, islit, lit);
        !           767:             break;
        !           768:         case 0x0F:
        !           769:             /* CMPBGE */
        !           770:             gen_arith3(ctx, &gen_op_cmpbge, ra, rb, rc, islit, lit);
        !           771:             break;
        !           772:         case 0x12:
        !           773:             /* S8ADDL */
        !           774:             gen_arith3(ctx, &gen_s8addl, ra, rb, rc, islit, lit);
        !           775:             break;
        !           776:         case 0x1B:
        !           777:             /* S8SUBL */
        !           778:             gen_arith3(ctx, &gen_s8subl, ra, rb, rc, islit, lit);
        !           779:             break;
        !           780:         case 0x1D:
        !           781:             /* CMPULT */
        !           782:             gen_arith3(ctx, &gen_op_cmpult, ra, rb, rc, islit, lit);
        !           783:             break;
        !           784:         case 0x20:
        !           785:             /* ADDQ */
        !           786:             gen_arith3(ctx, &gen_op_addq, ra, rb, rc, islit, lit);
        !           787:             break;
        !           788:         case 0x22:
        !           789:             /* S4ADDQ */
        !           790:             gen_arith3(ctx, &gen_s4addq, ra, rb, rc, islit, lit);
        !           791:             break;
        !           792:         case 0x29:
        !           793:             /* SUBQ */
        !           794:             gen_arith3(ctx, &gen_op_subq, ra, rb, rc, islit, lit);
        !           795:             break;
        !           796:         case 0x2B:
        !           797:             /* S4SUBQ */
        !           798:             gen_arith3(ctx, &gen_s4subq, ra, rb, rc, islit, lit);
        !           799:             break;
        !           800:         case 0x2D:
        !           801:             /* CMPEQ */
        !           802:             gen_arith3(ctx, &gen_op_cmpeq, ra, rb, rc, islit, lit);
        !           803:             break;
        !           804:         case 0x32:
        !           805:             /* S8ADDQ */
        !           806:             gen_arith3(ctx, &gen_s8addq, ra, rb, rc, islit, lit);
        !           807:             break;
        !           808:         case 0x3B:
        !           809:             /* S8SUBQ */
        !           810:             gen_arith3(ctx, &gen_s8subq, ra, rb, rc, islit, lit);
        !           811:             break;
        !           812:         case 0x3D:
        !           813:             /* CMPULE */
        !           814:             gen_arith3(ctx, &gen_op_cmpule, ra, rb, rc, islit, lit);
        !           815:             break;
        !           816:         case 0x40:
        !           817:             /* ADDL/V */
        !           818:             gen_arith3(ctx, &gen_op_addlv, ra, rb, rc, islit, lit);
        !           819:             break;
        !           820:         case 0x49:
        !           821:             /* SUBL/V */
        !           822:             gen_arith3(ctx, &gen_op_sublv, ra, rb, rc, islit, lit);
        !           823:             break;
        !           824:         case 0x4D:
        !           825:             /* CMPLT */
        !           826:             gen_arith3(ctx, &gen_op_cmplt, ra, rb, rc, islit, lit);
        !           827:             break;
        !           828:         case 0x60:
        !           829:             /* ADDQ/V */
        !           830:             gen_arith3(ctx, &gen_op_addqv, ra, rb, rc, islit, lit);
        !           831:             break;
        !           832:         case 0x69:
        !           833:             /* SUBQ/V */
        !           834:             gen_arith3(ctx, &gen_op_subqv, ra, rb, rc, islit, lit);
        !           835:             break;
        !           836:         case 0x6D:
        !           837:             /* CMPLE */
        !           838:             gen_arith3(ctx, &gen_op_cmple, ra, rb, rc, islit, lit);
        !           839:             break;
        !           840:         default:
        !           841:             goto invalid_opc;
        !           842:         }
        !           843:         break;
        !           844:     case 0x11:
        !           845:         switch (fn7) {
        !           846:         case 0x00:
        !           847:             /* AND */
        !           848:             gen_arith3(ctx, &gen_op_and, ra, rb, rc, islit, lit);
        !           849:             break;
        !           850:         case 0x08:
        !           851:             /* BIC */
        !           852:             gen_arith3(ctx, &gen_op_bic, ra, rb, rc, islit, lit);
        !           853:             break;
        !           854:         case 0x14:
        !           855:             /* CMOVLBS */
        !           856:             gen_cmov(ctx, &gen_op_cmplbs, ra, rb, rc, islit, lit);
        !           857:             break;
        !           858:         case 0x16:
        !           859:             /* CMOVLBC */
        !           860:             gen_cmov(ctx, &gen_op_cmplbc, ra, rb, rc, islit, lit);
        !           861:             break;
        !           862:         case 0x20:
        !           863:             /* BIS */
        !           864:             if (ra == rb || ra == 31 || rb == 31) {
        !           865:                 if (ra == 31 && rc == 31) {
        !           866:                     /* NOP */
        !           867:                     gen_op_nop();
        !           868:                 } else {
        !           869:                     /* MOV */
        !           870:                     gen_load_ir(ctx, rb, 0);
        !           871:                     gen_store_ir(ctx, rc, 0);
        !           872:                 }
        !           873:             } else {
        !           874:                 gen_arith3(ctx, &gen_op_bis, ra, rb, rc, islit, lit);
        !           875:             }
        !           876:             break;
        !           877:         case 0x24:
        !           878:             /* CMOVEQ */
        !           879:             gen_cmov(ctx, &gen_op_cmpeqz, ra, rb, rc, islit, lit);
        !           880:             break;
        !           881:         case 0x26:
        !           882:             /* CMOVNE */
        !           883:             gen_cmov(ctx, &gen_op_cmpnez, ra, rb, rc, islit, lit);
        !           884:             break;
        !           885:         case 0x28:
        !           886:             /* ORNOT */
        !           887:             gen_arith3(ctx, &gen_op_ornot, ra, rb, rc, islit, lit);
        !           888:             break;
        !           889:         case 0x40:
        !           890:             /* XOR */
        !           891:             gen_arith3(ctx, &gen_op_xor, ra, rb, rc, islit, lit);
        !           892:             break;
        !           893:         case 0x44:
        !           894:             /* CMOVLT */
        !           895:             gen_cmov(ctx, &gen_op_cmpltz, ra, rb, rc, islit, lit);
        !           896:             break;
        !           897:         case 0x46:
        !           898:             /* CMOVGE */
        !           899:             gen_cmov(ctx, &gen_op_cmpgez, ra, rb, rc, islit, lit);
        !           900:             break;
        !           901:         case 0x48:
        !           902:             /* EQV */
        !           903:             gen_arith3(ctx, &gen_op_eqv, ra, rb, rc, islit, lit);
        !           904:             break;
        !           905:         case 0x61:
        !           906:             /* AMASK */
        !           907:             gen_arith2(ctx, &gen_amask, rb, rc, islit, lit);
        !           908:             break;
        !           909:         case 0x64:
        !           910:             /* CMOVLE */
        !           911:             gen_cmov(ctx, &gen_op_cmplez, ra, rb, rc, islit, lit);
        !           912:             break;
        !           913:         case 0x66:
        !           914:             /* CMOVGT */
        !           915:             gen_cmov(ctx, &gen_op_cmpgtz, ra, rb, rc, islit, lit);
        !           916:             break;
        !           917:         case 0x6C:
        !           918:             /* IMPLVER */
        !           919:             gen_op_load_implver();
        !           920:             gen_store_ir(ctx, rc, 0);
        !           921:             break;
        !           922:         default:
        !           923:             goto invalid_opc;
        !           924:         }
        !           925:         break;
        !           926:     case 0x12:
        !           927:         switch (fn7) {
        !           928:         case 0x02:
        !           929:             /* MSKBL */
        !           930:             gen_arith3(ctx, &gen_op_mskbl, ra, rb, rc, islit, lit);
        !           931:             break;
        !           932:         case 0x06:
        !           933:             /* EXTBL */
        !           934:             gen_arith3(ctx, &gen_op_extbl, ra, rb, rc, islit, lit);
        !           935:             break;
        !           936:         case 0x0B:
        !           937:             /* INSBL */
        !           938:             gen_arith3(ctx, &gen_op_insbl, ra, rb, rc, islit, lit);
        !           939:             break;
        !           940:         case 0x12:
        !           941:             /* MSKWL */
        !           942:             gen_arith3(ctx, &gen_op_mskwl, ra, rb, rc, islit, lit);
        !           943:             break;
        !           944:         case 0x16:
        !           945:             /* EXTWL */
        !           946:             gen_arith3(ctx, &gen_op_extwl, ra, rb, rc, islit, lit);
        !           947:             break;
        !           948:         case 0x1B:
        !           949:             /* INSWL */
        !           950:             gen_arith3(ctx, &gen_op_inswl, ra, rb, rc, islit, lit);
        !           951:             break;
        !           952:         case 0x22:
        !           953:             /* MSKLL */
        !           954:             gen_arith3(ctx, &gen_op_mskll, ra, rb, rc, islit, lit);
        !           955:             break;
        !           956:         case 0x26:
        !           957:             /* EXTLL */
        !           958:             gen_arith3(ctx, &gen_op_extll, ra, rb, rc, islit, lit);
        !           959:             break;
        !           960:         case 0x2B:
        !           961:             /* INSLL */
        !           962:             gen_arith3(ctx, &gen_op_insll, ra, rb, rc, islit, lit);
        !           963:             break;
        !           964:         case 0x30:
        !           965:             /* ZAP */
        !           966:             gen_arith3(ctx, &gen_op_zap, ra, rb, rc, islit, lit);
        !           967:             break;
        !           968:         case 0x31:
        !           969:             /* ZAPNOT */
        !           970:             gen_arith3(ctx, &gen_op_zapnot, ra, rb, rc, islit, lit);
        !           971:             break;
        !           972:         case 0x32:
        !           973:             /* MSKQL */
        !           974:             gen_arith3(ctx, &gen_op_mskql, ra, rb, rc, islit, lit);
        !           975:             break;
        !           976:         case 0x34:
        !           977:             /* SRL */
        !           978:             gen_arith3(ctx, &gen_op_srl, ra, rb, rc, islit, lit);
        !           979:             break;
        !           980:         case 0x36:
        !           981:             /* EXTQL */
        !           982:             gen_arith3(ctx, &gen_op_extql, ra, rb, rc, islit, lit);
        !           983:             break;
        !           984:         case 0x39:
        !           985:             /* SLL */
        !           986:             gen_arith3(ctx, &gen_op_sll, ra, rb, rc, islit, lit);
        !           987:             break;
        !           988:         case 0x3B:
        !           989:             /* INSQL */
        !           990:             gen_arith3(ctx, &gen_op_insql, ra, rb, rc, islit, lit);
        !           991:             break;
        !           992:         case 0x3C:
        !           993:             /* SRA */
        !           994:             gen_arith3(ctx, &gen_op_sra, ra, rb, rc, islit, lit);
        !           995:             break;
        !           996:         case 0x52:
        !           997:             /* MSKWH */
        !           998:             gen_arith3(ctx, &gen_op_mskwh, ra, rb, rc, islit, lit);
        !           999:             break;
        !          1000:         case 0x57:
        !          1001:             /* INSWH */
        !          1002:             gen_arith3(ctx, &gen_op_inswh, ra, rb, rc, islit, lit);
        !          1003:             break;
        !          1004:         case 0x5A:
        !          1005:             /* EXTWH */
        !          1006:             gen_arith3(ctx, &gen_op_extwh, ra, rb, rc, islit, lit);
        !          1007:             break;
        !          1008:         case 0x62:
        !          1009:             /* MSKLH */
        !          1010:             gen_arith3(ctx, &gen_op_msklh, ra, rb, rc, islit, lit);
        !          1011:             break;
        !          1012:         case 0x67:
        !          1013:             /* INSLH */
        !          1014:             gen_arith3(ctx, &gen_op_inslh, ra, rb, rc, islit, lit);
        !          1015:             break;
        !          1016:         case 0x6A:
        !          1017:             /* EXTLH */
        !          1018:             gen_arith3(ctx, &gen_op_extlh, ra, rb, rc, islit, lit);
        !          1019:             break;
        !          1020:         case 0x72:
        !          1021:             /* MSKQH */
        !          1022:             gen_arith3(ctx, &gen_op_mskqh, ra, rb, rc, islit, lit);
        !          1023:             break;
        !          1024:         case 0x77:
        !          1025:             /* INSQH */
        !          1026:             gen_arith3(ctx, &gen_op_insqh, ra, rb, rc, islit, lit);
        !          1027:             break;
        !          1028:         case 0x7A:
        !          1029:             /* EXTQH */
        !          1030:             gen_arith3(ctx, &gen_op_extqh, ra, rb, rc, islit, lit);
        !          1031:             break;
        !          1032:         default:
        !          1033:             goto invalid_opc;
        !          1034:         }
        !          1035:         break;
        !          1036:     case 0x13:
        !          1037:         switch (fn7) {
        !          1038:         case 0x00:
        !          1039:             /* MULL */
        !          1040:             gen_arith3(ctx, &gen_op_mull, ra, rb, rc, islit, lit);
        !          1041:             break;
        !          1042:         case 0x20:
        !          1043:             /* MULQ */
        !          1044:             gen_arith3(ctx, &gen_op_mulq, ra, rb, rc, islit, lit);
        !          1045:             break;
        !          1046:         case 0x30:
        !          1047:             /* UMULH */
        !          1048:             gen_arith3(ctx, &gen_op_umulh, ra, rb, rc, islit, lit);
        !          1049:             break;
        !          1050:         case 0x40:
        !          1051:             /* MULL/V */
        !          1052:             gen_arith3(ctx, &gen_op_mullv, ra, rb, rc, islit, lit);
        !          1053:             break;
        !          1054:         case 0x60:
        !          1055:             /* MULQ/V */
        !          1056:             gen_arith3(ctx, &gen_op_mulqv, ra, rb, rc, islit, lit);
        !          1057:             break;
        !          1058:         default:
        !          1059:             goto invalid_opc;
        !          1060:         }
        !          1061:         break;
        !          1062:     case 0x14:
        !          1063:         switch (fpfn) { /* f11 & 0x3F */
        !          1064:         case 0x04:
        !          1065:             /* ITOFS */
        !          1066:             if (!(ctx->amask & AMASK_FIX))
        !          1067:                 goto invalid_opc;
        !          1068:             gen_itf(ctx, &gen_op_itofs, ra, rc);
        !          1069:             break;
        !          1070:         case 0x0A:
        !          1071:             /* SQRTF */
        !          1072:             if (!(ctx->amask & AMASK_FIX))
        !          1073:                 goto invalid_opc;
        !          1074:             gen_farith2(ctx, &gen_op_sqrtf, rb, rc);
        !          1075:             break;
        !          1076:         case 0x0B:
        !          1077:             /* SQRTS */
        !          1078:             if (!(ctx->amask & AMASK_FIX))
        !          1079:                 goto invalid_opc;
        !          1080:             gen_farith2(ctx, &gen_op_sqrts, rb, rc);
        !          1081:             break;
        !          1082:         case 0x14:
        !          1083:             /* ITOFF */
        !          1084:             if (!(ctx->amask & AMASK_FIX))
        !          1085:                 goto invalid_opc;
        !          1086: #if 0 // TODO
        !          1087:             gen_itf(ctx, &gen_op_itoff, ra, rc);
        !          1088: #else
        !          1089:             goto invalid_opc;
        !          1090: #endif
        !          1091:             break;
        !          1092:         case 0x24:
        !          1093:             /* ITOFT */
        !          1094:             if (!(ctx->amask & AMASK_FIX))
        !          1095:                 goto invalid_opc;
        !          1096:             gen_itf(ctx, &gen_op_itoft, ra, rc);
        !          1097:             break;
        !          1098:         case 0x2A:
        !          1099:             /* SQRTG */
        !          1100:             if (!(ctx->amask & AMASK_FIX))
        !          1101:                 goto invalid_opc;
        !          1102:             gen_farith2(ctx, &gen_op_sqrtg, rb, rc);
        !          1103:             break;
        !          1104:         case 0x02B:
        !          1105:             /* SQRTT */
        !          1106:             if (!(ctx->amask & AMASK_FIX))
        !          1107:                 goto invalid_opc;
        !          1108:             gen_farith2(ctx, &gen_op_sqrtt, rb, rc);
        !          1109:             break;
        !          1110:         default:
        !          1111:             goto invalid_opc;
        !          1112:         }
        !          1113:         break;
        !          1114:     case 0x15:
        !          1115:         /* VAX floating point */
        !          1116:         /* XXX: rounding mode and trap are ignored (!) */
        !          1117:         switch (fpfn) { /* f11 & 0x3F */
        !          1118:         case 0x00:
        !          1119:             /* ADDF */
        !          1120:             gen_farith3(ctx, &gen_op_addf, ra, rb, rc);
        !          1121:             break;
        !          1122:         case 0x01:
        !          1123:             /* SUBF */
        !          1124:             gen_farith3(ctx, &gen_op_subf, ra, rb, rc);
        !          1125:             break;
        !          1126:         case 0x02:
        !          1127:             /* MULF */
        !          1128:             gen_farith3(ctx, &gen_op_mulf, ra, rb, rc);
        !          1129:             break;
        !          1130:         case 0x03:
        !          1131:             /* DIVF */
        !          1132:             gen_farith3(ctx, &gen_op_divf, ra, rb, rc);
        !          1133:             break;
        !          1134:         case 0x1E:
        !          1135:             /* CVTDG */
        !          1136: #if 0 // TODO
        !          1137:             gen_farith2(ctx, &gen_op_cvtdg, rb, rc);
        !          1138: #else
        !          1139:             goto invalid_opc;
        !          1140: #endif
        !          1141:             break;
        !          1142:         case 0x20:
        !          1143:             /* ADDG */
        !          1144:             gen_farith3(ctx, &gen_op_addg, ra, rb, rc);
        !          1145:             break;
        !          1146:         case 0x21:
        !          1147:             /* SUBG */
        !          1148:             gen_farith3(ctx, &gen_op_subg, ra, rb, rc);
        !          1149:             break;
        !          1150:         case 0x22:
        !          1151:             /* MULG */
        !          1152:             gen_farith3(ctx, &gen_op_mulg, ra, rb, rc);
        !          1153:             break;
        !          1154:         case 0x23:
        !          1155:             /* DIVG */
        !          1156:             gen_farith3(ctx, &gen_op_divg, ra, rb, rc);
        !          1157:             break;
        !          1158:         case 0x25:
        !          1159:             /* CMPGEQ */
        !          1160:             gen_farith3(ctx, &gen_op_cmpgeq, ra, rb, rc);
        !          1161:             break;
        !          1162:         case 0x26:
        !          1163:             /* CMPGLT */
        !          1164:             gen_farith3(ctx, &gen_op_cmpglt, ra, rb, rc);
        !          1165:             break;
        !          1166:         case 0x27:
        !          1167:             /* CMPGLE */
        !          1168:             gen_farith3(ctx, &gen_op_cmpgle, ra, rb, rc);
        !          1169:             break;
        !          1170:         case 0x2C:
        !          1171:             /* CVTGF */
        !          1172:             gen_farith2(ctx, &gen_op_cvtgf, rb, rc);
        !          1173:             break;
        !          1174:         case 0x2D:
        !          1175:             /* CVTGD */
        !          1176: #if 0 // TODO
        !          1177:             gen_farith2(ctx, &gen_op_cvtgd, rb, rc);
        !          1178: #else
        !          1179:             goto invalid_opc;
        !          1180: #endif
        !          1181:             break;
        !          1182:         case 0x2F:
        !          1183:             /* CVTGQ */
        !          1184:             gen_farith2(ctx, &gen_op_cvtgq, rb, rc);
        !          1185:             break;
        !          1186:         case 0x3C:
        !          1187:             /* CVTQF */
        !          1188:             gen_farith2(ctx, &gen_op_cvtqf, rb, rc);
        !          1189:             break;
        !          1190:         case 0x3E:
        !          1191:             /* CVTQG */
        !          1192:             gen_farith2(ctx, &gen_op_cvtqg, rb, rc);
        !          1193:             break;
        !          1194:         default:
        !          1195:             goto invalid_opc;
        !          1196:         }
        !          1197:         break;
        !          1198:     case 0x16:
        !          1199:         /* IEEE floating-point */
        !          1200:         /* XXX: rounding mode and traps are ignored (!) */
        !          1201:         switch (fpfn) { /* f11 & 0x3F */
        !          1202:         case 0x00:
        !          1203:             /* ADDS */
        !          1204:             gen_farith3(ctx, &gen_op_adds, ra, rb, rc);
        !          1205:             break;
        !          1206:         case 0x01:
        !          1207:             /* SUBS */
        !          1208:             gen_farith3(ctx, &gen_op_subs, ra, rb, rc);
        !          1209:             break;
        !          1210:         case 0x02:
        !          1211:             /* MULS */
        !          1212:             gen_farith3(ctx, &gen_op_muls, ra, rb, rc);
        !          1213:             break;
        !          1214:         case 0x03:
        !          1215:             /* DIVS */
        !          1216:             gen_farith3(ctx, &gen_op_divs, ra, rb, rc);
        !          1217:             break;
        !          1218:         case 0x20:
        !          1219:             /* ADDT */
        !          1220:             gen_farith3(ctx, &gen_op_addt, ra, rb, rc);
        !          1221:             break;
        !          1222:         case 0x21:
        !          1223:             /* SUBT */
        !          1224:             gen_farith3(ctx, &gen_op_subt, ra, rb, rc);
        !          1225:             break;
        !          1226:         case 0x22:
        !          1227:             /* MULT */
        !          1228:             gen_farith3(ctx, &gen_op_mult, ra, rb, rc);
        !          1229:             break;
        !          1230:         case 0x23:
        !          1231:             /* DIVT */
        !          1232:             gen_farith3(ctx, &gen_op_divt, ra, rb, rc);
        !          1233:             break;
        !          1234:         case 0x24:
        !          1235:             /* CMPTUN */
        !          1236:             gen_farith3(ctx, &gen_op_cmptun, ra, rb, rc);
        !          1237:             break;
        !          1238:         case 0x25:
        !          1239:             /* CMPTEQ */
        !          1240:             gen_farith3(ctx, &gen_op_cmpteq, ra, rb, rc);
        !          1241:             break;
        !          1242:         case 0x26:
        !          1243:             /* CMPTLT */
        !          1244:             gen_farith3(ctx, &gen_op_cmptlt, ra, rb, rc);
        !          1245:             break;
        !          1246:         case 0x27:
        !          1247:             /* CMPTLE */
        !          1248:             gen_farith3(ctx, &gen_op_cmptle, ra, rb, rc);
        !          1249:             break;
        !          1250:         case 0x2C:
        !          1251:             /* XXX: incorrect */
        !          1252:             if (fn11 == 0x2AC) {
        !          1253:                 /* CVTST */
        !          1254:                 gen_farith2(ctx, &gen_op_cvtst, rb, rc);
        !          1255:             } else {
        !          1256:                 /* CVTTS */
        !          1257:                 gen_farith2(ctx, &gen_op_cvtts, rb, rc);
        !          1258:             }
        !          1259:             break;
        !          1260:         case 0x2F:
        !          1261:             /* CVTTQ */
        !          1262:             gen_farith2(ctx, &gen_op_cvttq, rb, rc);
        !          1263:             break;
        !          1264:         case 0x3C:
        !          1265:             /* CVTQS */
        !          1266:             gen_farith2(ctx, &gen_op_cvtqs, rb, rc);
        !          1267:             break;
        !          1268:         case 0x3E:
        !          1269:             /* CVTQT */
        !          1270:             gen_farith2(ctx, &gen_op_cvtqt, rb, rc);
        !          1271:             break;
        !          1272:         default:
        !          1273:             goto invalid_opc;
        !          1274:         }
        !          1275:         break;
        !          1276:     case 0x17:
        !          1277:         switch (fn11) {
        !          1278:         case 0x010:
        !          1279:             /* CVTLQ */
        !          1280:             gen_farith2(ctx, &gen_op_cvtlq, rb, rc);
        !          1281:             break;
        !          1282:         case 0x020:
        !          1283:             /* CPYS */
        !          1284:             if (ra == rb) {
        !          1285:                 if (ra == 31 && rc == 31) {
        !          1286:                     /* FNOP */
        !          1287:                     gen_op_nop();
        !          1288:                 } else {
        !          1289:                     /* FMOV */
        !          1290:                     gen_load_fir(ctx, rb, 0);
        !          1291:                     gen_store_fir(ctx, rc, 0);
        !          1292:                 }
        !          1293:             } else {
        !          1294:                 gen_farith3(ctx, &gen_op_cpys, ra, rb, rc);
        !          1295:             }
        !          1296:             break;
        !          1297:         case 0x021:
        !          1298:             /* CPYSN */
        !          1299:             gen_farith2(ctx, &gen_op_cpysn, rb, rc);
        !          1300:             break;
        !          1301:         case 0x022:
        !          1302:             /* CPYSE */
        !          1303:             gen_farith2(ctx, &gen_op_cpyse, rb, rc);
        !          1304:             break;
        !          1305:         case 0x024:
        !          1306:             /* MT_FPCR */
        !          1307:             gen_load_fir(ctx, ra, 0);
        !          1308:             gen_op_store_fpcr();
        !          1309:             break;
        !          1310:         case 0x025:
        !          1311:             /* MF_FPCR */
        !          1312:             gen_op_load_fpcr();
        !          1313:             gen_store_fir(ctx, ra, 0);
        !          1314:             break;
        !          1315:         case 0x02A:
        !          1316:             /* FCMOVEQ */
        !          1317:             gen_fcmov(ctx, &gen_op_cmpfeq, ra, rb, rc);
        !          1318:             break;
        !          1319:         case 0x02B:
        !          1320:             /* FCMOVNE */
        !          1321:             gen_fcmov(ctx, &gen_op_cmpfne, ra, rb, rc);
        !          1322:             break;
        !          1323:         case 0x02C:
        !          1324:             /* FCMOVLT */
        !          1325:             gen_fcmov(ctx, &gen_op_cmpflt, ra, rb, rc);
        !          1326:             break;
        !          1327:         case 0x02D:
        !          1328:             /* FCMOVGE */
        !          1329:             gen_fcmov(ctx, &gen_op_cmpfge, ra, rb, rc);
        !          1330:             break;
        !          1331:         case 0x02E:
        !          1332:             /* FCMOVLE */
        !          1333:             gen_fcmov(ctx, &gen_op_cmpfle, ra, rb, rc);
        !          1334:             break;
        !          1335:         case 0x02F:
        !          1336:             /* FCMOVGT */
        !          1337:             gen_fcmov(ctx, &gen_op_cmpfgt, ra, rb, rc);
        !          1338:             break;
        !          1339:         case 0x030:
        !          1340:             /* CVTQL */
        !          1341:             gen_farith2(ctx, &gen_op_cvtql, rb, rc);
        !          1342:             break;
        !          1343:         case 0x130:
        !          1344:             /* CVTQL/V */
        !          1345:             gen_farith2(ctx, &gen_op_cvtqlv, rb, rc);
        !          1346:             break;
        !          1347:         case 0x530:
        !          1348:             /* CVTQL/SV */
        !          1349:             gen_farith2(ctx, &gen_op_cvtqlsv, rb, rc);
        !          1350:             break;
        !          1351:         default:
        !          1352:             goto invalid_opc;
        !          1353:         }
        !          1354:         break;
        !          1355:     case 0x18:
        !          1356:         switch ((uint16_t)disp16) {
        !          1357:         case 0x0000:
        !          1358:             /* TRAPB */
        !          1359:             /* No-op. Just exit from the current tb */
        !          1360:             ret = 2;
        !          1361:             break;
        !          1362:         case 0x0400:
        !          1363:             /* EXCB */
        !          1364:             /* No-op. Just exit from the current tb */
        !          1365:             ret = 2;
        !          1366:             break;
        !          1367:         case 0x4000:
        !          1368:             /* MB */
        !          1369:             /* No-op */
        !          1370:             break;
        !          1371:         case 0x4400:
        !          1372:             /* WMB */
        !          1373:             /* No-op */
        !          1374:             break;
        !          1375:         case 0x8000:
        !          1376:             /* FETCH */
        !          1377:             /* No-op */
        !          1378:             break;
        !          1379:         case 0xA000:
        !          1380:             /* FETCH_M */
        !          1381:             /* No-op */
        !          1382:             break;
        !          1383:         case 0xC000:
        !          1384:             /* RPCC */
        !          1385:             gen_op_load_pcc();
        !          1386:             gen_store_ir(ctx, ra, 0);
        !          1387:             break;
        !          1388:         case 0xE000:
        !          1389:             /* RC */
        !          1390:             gen_op_load_irf();
        !          1391:             gen_store_ir(ctx, ra, 0);
        !          1392:             gen_op_clear_irf();
        !          1393:             break;
        !          1394:         case 0xE800:
        !          1395:             /* ECB */
        !          1396:             /* XXX: TODO: evict tb cache at address rb */
        !          1397: #if 0
        !          1398:             ret = 2;
        !          1399: #else
        !          1400:             goto invalid_opc;
        !          1401: #endif
        !          1402:             break;
        !          1403:         case 0xF000:
        !          1404:             /* RS */
        !          1405:             gen_op_load_irf();
        !          1406:             gen_store_ir(ctx, ra, 0);
        !          1407:             gen_op_set_irf();
        !          1408:             break;
        !          1409:         case 0xF800:
        !          1410:             /* WH64 */
        !          1411:             /* No-op */
        !          1412:             break;
        !          1413:         default:
        !          1414:             goto invalid_opc;
        !          1415:         }
        !          1416:         break;
        !          1417:     case 0x19:
        !          1418:         /* HW_MFPR (PALcode) */
        !          1419: #if defined (CONFIG_USER_ONLY)
        !          1420:         goto invalid_opc;
        !          1421: #else
        !          1422:         if (!ctx->pal_mode)
        !          1423:             goto invalid_opc;
        !          1424:         gen_op_mfpr(insn & 0xFF);
        !          1425:         gen_store_ir(ctx, ra, 0);
        !          1426:         break;
        !          1427: #endif
        !          1428:     case 0x1A:
        !          1429:         gen_load_ir(ctx, rb, 0);
        !          1430:         if (ra != 31) {
        !          1431:             gen_set_uT1(ctx, ctx->pc);
        !          1432:             gen_store_ir(ctx, ra, 1);
        !          1433:         }
        !          1434:         gen_op_branch();
        !          1435:         /* Those four jumps only differ by the branch prediction hint */
        !          1436:         switch (fn2) {
        !          1437:         case 0x0:
        !          1438:             /* JMP */
        !          1439:             break;
        !          1440:         case 0x1:
        !          1441:             /* JSR */
        !          1442:             break;
        !          1443:         case 0x2:
        !          1444:             /* RET */
        !          1445:             break;
        !          1446:         case 0x3:
        !          1447:             /* JSR_COROUTINE */
        !          1448:             break;
        !          1449:         }
        !          1450:         ret = 1;
        !          1451:         break;
        !          1452:     case 0x1B:
        !          1453:         /* HW_LD (PALcode) */
        !          1454: #if defined (CONFIG_USER_ONLY)
        !          1455:         goto invalid_opc;
        !          1456: #else
        !          1457:         if (!ctx->pal_mode)
        !          1458:             goto invalid_opc;
        !          1459:         gen_load_ir(ctx, rb, 0);
        !          1460:         gen_set_sT1(ctx, disp12);
        !          1461:         gen_op_addq();
        !          1462:         switch ((insn >> 12) & 0xF) {
        !          1463:         case 0x0:
        !          1464:             /* Longword physical access */
        !          1465:             gen_op_ldl_raw();
        !          1466:             break;
        !          1467:         case 0x1:
        !          1468:             /* Quadword physical access */
        !          1469:             gen_op_ldq_raw();
        !          1470:             break;
        !          1471:         case 0x2:
        !          1472:             /* Longword physical access with lock */
        !          1473:             gen_op_ldl_l_raw();
        !          1474:             break;
        !          1475:         case 0x3:
        !          1476:             /* Quadword physical access with lock */
        !          1477:             gen_op_ldq_l_raw();
        !          1478:             break;
        !          1479:         case 0x4:
        !          1480:             /* Longword virtual PTE fetch */
        !          1481:             gen_op_ldl_kernel();
        !          1482:             break;
        !          1483:         case 0x5:
        !          1484:             /* Quadword virtual PTE fetch */
        !          1485:             gen_op_ldq_kernel();
        !          1486:             break;
        !          1487:         case 0x6:
        !          1488:             /* Invalid */
        !          1489:             goto invalid_opc;
        !          1490:         case 0x7:
        !          1491:             /* Invalid */
        !          1492:             goto invalid_opc;
        !          1493:         case 0x8:
        !          1494:             /* Longword virtual access */
        !          1495:             gen_op_ld_phys_to_virt();
        !          1496:             gen_op_ldl_raw();
        !          1497:             break;
        !          1498:         case 0x9:
        !          1499:             /* Quadword virtual access */
        !          1500:             gen_op_ld_phys_to_virt();
        !          1501:             gen_op_ldq_raw();
        !          1502:             break;
        !          1503:         case 0xA:
        !          1504:             /* Longword virtual access with protection check */
        !          1505:             gen_ldl(ctx);
        !          1506:             break;
        !          1507:         case 0xB:
        !          1508:             /* Quadword virtual access with protection check */
        !          1509:             gen_ldq(ctx);
        !          1510:             break;
        !          1511:         case 0xC:
        !          1512:             /* Longword virtual access with altenate access mode */
        !          1513:             gen_op_set_alt_mode();
        !          1514:             gen_op_ld_phys_to_virt();
        !          1515:             gen_op_ldl_raw();
        !          1516:             gen_op_restore_mode();
        !          1517:             break;
        !          1518:         case 0xD:
        !          1519:             /* Quadword virtual access with altenate access mode */
        !          1520:             gen_op_set_alt_mode();
        !          1521:             gen_op_ld_phys_to_virt();
        !          1522:             gen_op_ldq_raw();
        !          1523:             gen_op_restore_mode();
        !          1524:             break;
        !          1525:         case 0xE:
        !          1526:             /* Longword virtual access with alternate access mode and
        !          1527:              * protection checks
        !          1528:              */
        !          1529:             gen_op_set_alt_mode();
        !          1530:             gen_op_ldl_data();
        !          1531:             gen_op_restore_mode();
        !          1532:             break;
        !          1533:         case 0xF:
        !          1534:             /* Quadword virtual access with alternate access mode and
        !          1535:              * protection checks
        !          1536:              */
        !          1537:             gen_op_set_alt_mode();
        !          1538:             gen_op_ldq_data();
        !          1539:             gen_op_restore_mode();
        !          1540:             break;
        !          1541:         }
        !          1542:         gen_store_ir(ctx, ra, 1);
        !          1543:         break;
        !          1544: #endif
        !          1545:     case 0x1C:
        !          1546:         switch (fn7) {
        !          1547:         case 0x00:
        !          1548:             /* SEXTB */
        !          1549:             if (!(ctx->amask & AMASK_BWX))
        !          1550:                 goto invalid_opc;
        !          1551:             gen_arith2(ctx, &gen_op_sextb, rb, rc, islit, lit);
        !          1552:             break;
        !          1553:         case 0x01:
        !          1554:             /* SEXTW */
        !          1555:             if (!(ctx->amask & AMASK_BWX))
        !          1556:                 goto invalid_opc;
        !          1557:             gen_arith2(ctx, &gen_op_sextw, rb, rc, islit, lit);
        !          1558:             break;
        !          1559:         case 0x30:
        !          1560:             /* CTPOP */
        !          1561:             if (!(ctx->amask & AMASK_CIX))
        !          1562:                 goto invalid_opc;
        !          1563:             gen_arith2(ctx, &gen_op_ctpop, rb, rc, 0, 0);
        !          1564:             break;
        !          1565:         case 0x31:
        !          1566:             /* PERR */
        !          1567:             if (!(ctx->amask & AMASK_MVI))
        !          1568:                 goto invalid_opc;
        !          1569:             /* XXX: TODO */
        !          1570:             goto invalid_opc;
        !          1571:             break;
        !          1572:         case 0x32:
        !          1573:             /* CTLZ */
        !          1574:             if (!(ctx->amask & AMASK_CIX))
        !          1575:                 goto invalid_opc;
        !          1576:             gen_arith2(ctx, &gen_op_ctlz, rb, rc, 0, 0);
        !          1577:             break;
        !          1578:         case 0x33:
        !          1579:             /* CTTZ */
        !          1580:             if (!(ctx->amask & AMASK_CIX))
        !          1581:                 goto invalid_opc;
        !          1582:             gen_arith2(ctx, &gen_op_cttz, rb, rc, 0, 0);
        !          1583:             break;
        !          1584:         case 0x34:
        !          1585:             /* UNPKBW */
        !          1586:             if (!(ctx->amask & AMASK_MVI))
        !          1587:                 goto invalid_opc;
        !          1588:             /* XXX: TODO */
        !          1589:             goto invalid_opc;
        !          1590:             break;
        !          1591:         case 0x35:
        !          1592:             /* UNPKWL */
        !          1593:             if (!(ctx->amask & AMASK_MVI))
        !          1594:                 goto invalid_opc;
        !          1595:             /* XXX: TODO */
        !          1596:             goto invalid_opc;
        !          1597:             break;
        !          1598:         case 0x36:
        !          1599:             /* PKWB */
        !          1600:             if (!(ctx->amask & AMASK_MVI))
        !          1601:                 goto invalid_opc;
        !          1602:             /* XXX: TODO */
        !          1603:             goto invalid_opc;
        !          1604:             break;
        !          1605:         case 0x37:
        !          1606:             /* PKLB */
        !          1607:             if (!(ctx->amask & AMASK_MVI))
        !          1608:                 goto invalid_opc;
        !          1609:             /* XXX: TODO */
        !          1610:             goto invalid_opc;
        !          1611:             break;
        !          1612:         case 0x38:
        !          1613:             /* MINSB8 */
        !          1614:             if (!(ctx->amask & AMASK_MVI))
        !          1615:                 goto invalid_opc;
        !          1616:             /* XXX: TODO */
        !          1617:             goto invalid_opc;
        !          1618:             break;
        !          1619:         case 0x39:
        !          1620:             /* MINSW4 */
        !          1621:             if (!(ctx->amask & AMASK_MVI))
        !          1622:                 goto invalid_opc;
        !          1623:             /* XXX: TODO */
        !          1624:             goto invalid_opc;
        !          1625:             break;
        !          1626:         case 0x3A:
        !          1627:             /* MINUB8 */
        !          1628:             if (!(ctx->amask & AMASK_MVI))
        !          1629:                 goto invalid_opc;
        !          1630:             /* XXX: TODO */
        !          1631:             goto invalid_opc;
        !          1632:             break;
        !          1633:         case 0x3B:
        !          1634:             /* MINUW4 */
        !          1635:             if (!(ctx->amask & AMASK_MVI))
        !          1636:                 goto invalid_opc;
        !          1637:             /* XXX: TODO */
        !          1638:             goto invalid_opc;
        !          1639:             break;
        !          1640:         case 0x3C:
        !          1641:             /* MAXUB8 */
        !          1642:             if (!(ctx->amask & AMASK_MVI))
        !          1643:                 goto invalid_opc;
        !          1644:             /* XXX: TODO */
        !          1645:             goto invalid_opc;
        !          1646:             break;
        !          1647:         case 0x3D:
        !          1648:             /* MAXUW4 */
        !          1649:             if (!(ctx->amask & AMASK_MVI))
        !          1650:                 goto invalid_opc;
        !          1651:             /* XXX: TODO */
        !          1652:             goto invalid_opc;
        !          1653:             break;
        !          1654:         case 0x3E:
        !          1655:             /* MAXSB8 */
        !          1656:             if (!(ctx->amask & AMASK_MVI))
        !          1657:                 goto invalid_opc;
        !          1658:             /* XXX: TODO */
        !          1659:             goto invalid_opc;
        !          1660:             break;
        !          1661:         case 0x3F:
        !          1662:             /* MAXSW4 */
        !          1663:             if (!(ctx->amask & AMASK_MVI))
        !          1664:                 goto invalid_opc;
        !          1665:             /* XXX: TODO */
        !          1666:             goto invalid_opc;
        !          1667:             break;
        !          1668:         case 0x70:
        !          1669:             /* FTOIT */
        !          1670:             if (!(ctx->amask & AMASK_FIX))
        !          1671:                 goto invalid_opc;
        !          1672:             gen_fti(ctx, &gen_op_ftoit, ra, rb);
        !          1673:             break;
        !          1674:         case 0x78:
        !          1675:             /* FTOIS */
        !          1676:             if (!(ctx->amask & AMASK_FIX))
        !          1677:                 goto invalid_opc;
        !          1678:             gen_fti(ctx, &gen_op_ftois, ra, rb);
        !          1679:             break;
        !          1680:         default:
        !          1681:             goto invalid_opc;
        !          1682:         }
        !          1683:         break;
        !          1684:     case 0x1D:
        !          1685:         /* HW_MTPR (PALcode) */
        !          1686: #if defined (CONFIG_USER_ONLY)
        !          1687:         goto invalid_opc;
        !          1688: #else
        !          1689:         if (!ctx->pal_mode)
        !          1690:             goto invalid_opc;
        !          1691:         gen_load_ir(ctx, ra, 0);
        !          1692:         gen_op_mtpr(insn & 0xFF);
        !          1693:         ret = 2;
        !          1694:         break;
        !          1695: #endif
        !          1696:     case 0x1E:
        !          1697:         /* HW_REI (PALcode) */
        !          1698: #if defined (CONFIG_USER_ONLY)
        !          1699:         goto invalid_opc;
        !          1700: #else
        !          1701:         if (!ctx->pal_mode)
        !          1702:             goto invalid_opc;
        !          1703:         if (rb == 31) {
        !          1704:             /* "Old" alpha */
        !          1705:             gen_op_hw_rei();
        !          1706:         } else {
        !          1707:             gen_load_ir(ctx, rb, 0);
        !          1708:             gen_set_uT1(ctx, (((int64_t)insn << 51) >> 51));
        !          1709:             gen_op_addq();
        !          1710:             gen_op_hw_ret();
        !          1711:         }
        !          1712:         ret = 2;
        !          1713:         break;
        !          1714: #endif
        !          1715:     case 0x1F:
        !          1716:         /* HW_ST (PALcode) */
        !          1717: #if defined (CONFIG_USER_ONLY)
        !          1718:         goto invalid_opc;
        !          1719: #else
        !          1720:         if (!ctx->pal_mode)
        !          1721:             goto invalid_opc;
        !          1722:         gen_load_ir(ctx, rb, 0);
        !          1723:         gen_set_sT1(ctx, disp12);
        !          1724:         gen_op_addq();
        !          1725:         gen_load_ir(ctx, ra, 1);
        !          1726:         switch ((insn >> 12) & 0xF) {
        !          1727:         case 0x0:
        !          1728:             /* Longword physical access */
        !          1729:             gen_op_stl_raw();
        !          1730:             break;
        !          1731:         case 0x1:
        !          1732:             /* Quadword physical access */
        !          1733:             gen_op_stq_raw();
        !          1734:             break;
        !          1735:         case 0x2:
        !          1736:             /* Longword physical access with lock */
        !          1737:             gen_op_stl_c_raw();
        !          1738:             break;
        !          1739:         case 0x3:
        !          1740:             /* Quadword physical access with lock */
        !          1741:             gen_op_stq_c_raw();
        !          1742:             break;
        !          1743:         case 0x4:
        !          1744:             /* Longword virtual access */
        !          1745:             gen_op_st_phys_to_virt();
        !          1746:             gen_op_stl_raw();
        !          1747:             break;
        !          1748:         case 0x5:
        !          1749:             /* Quadword virtual access */
        !          1750:             gen_op_st_phys_to_virt();
        !          1751:             gen_op_stq_raw();
        !          1752:             break;
        !          1753:         case 0x6:
        !          1754:             /* Invalid */
        !          1755:             goto invalid_opc;
        !          1756:         case 0x7:
        !          1757:             /* Invalid */
        !          1758:             goto invalid_opc;
        !          1759:         case 0x8:
        !          1760:             /* Invalid */
        !          1761:             goto invalid_opc;
        !          1762:         case 0x9:
        !          1763:             /* Invalid */
        !          1764:             goto invalid_opc;
        !          1765:         case 0xA:
        !          1766:             /* Invalid */
        !          1767:             goto invalid_opc;
        !          1768:         case 0xB:
        !          1769:             /* Invalid */
        !          1770:             goto invalid_opc;
        !          1771:         case 0xC:
        !          1772:             /* Longword virtual access with alternate access mode */
        !          1773:             gen_op_set_alt_mode();
        !          1774:             gen_op_st_phys_to_virt();
        !          1775:             gen_op_ldl_raw();
        !          1776:             gen_op_restore_mode();
        !          1777:             break;
        !          1778:         case 0xD:
        !          1779:             /* Quadword virtual access with alternate access mode */
        !          1780:             gen_op_set_alt_mode();
        !          1781:             gen_op_st_phys_to_virt();
        !          1782:             gen_op_ldq_raw();
        !          1783:             gen_op_restore_mode();
        !          1784:             break;
        !          1785:         case 0xE:
        !          1786:             /* Invalid */
        !          1787:             goto invalid_opc;
        !          1788:         case 0xF:
        !          1789:             /* Invalid */
        !          1790:             goto invalid_opc;
        !          1791:         }
        !          1792:         ret = 2;
        !          1793:         break;
        !          1794: #endif
        !          1795:     case 0x20:
        !          1796:         /* LDF */
        !          1797: #if 0 // TODO
        !          1798:         gen_load_fmem(ctx, &gen_ldf, ra, rb, disp16);
        !          1799: #else
        !          1800:         goto invalid_opc;
        !          1801: #endif
        !          1802:         break;
        !          1803:     case 0x21:
        !          1804:         /* LDG */
        !          1805: #if 0 // TODO
        !          1806:         gen_load_fmem(ctx, &gen_ldg, ra, rb, disp16);
        !          1807: #else
        !          1808:         goto invalid_opc;
        !          1809: #endif
        !          1810:         break;
        !          1811:     case 0x22:
        !          1812:         /* LDS */
        !          1813:         gen_load_fmem(ctx, &gen_lds, ra, rb, disp16);
        !          1814:         break;
        !          1815:     case 0x23:
        !          1816:         /* LDT */
        !          1817:         gen_load_fmem(ctx, &gen_ldt, ra, rb, disp16);
        !          1818:         break;
        !          1819:     case 0x24:
        !          1820:         /* STF */
        !          1821: #if 0 // TODO
        !          1822:         gen_store_fmem(ctx, &gen_stf, ra, rb, disp16);
        !          1823: #else
        !          1824:         goto invalid_opc;
        !          1825: #endif
        !          1826:         break;
        !          1827:     case 0x25:
        !          1828:         /* STG */
        !          1829: #if 0 // TODO
        !          1830:         gen_store_fmem(ctx, &gen_stg, ra, rb, disp16);
        !          1831: #else
        !          1832:         goto invalid_opc;
        !          1833: #endif
        !          1834:         break;
        !          1835:     case 0x26:
        !          1836:         /* STS */
        !          1837:         gen_store_fmem(ctx, &gen_sts, ra, rb, disp16);
        !          1838:         break;
        !          1839:     case 0x27:
        !          1840:         /* STT */
        !          1841:         gen_store_fmem(ctx, &gen_stt, ra, rb, disp16);
        !          1842:         break;
        !          1843:     case 0x28:
        !          1844:         /* LDL */
        !          1845:         gen_load_mem(ctx, &gen_ldl, ra, rb, disp16, 0);
        !          1846:         break;
        !          1847:     case 0x29:
        !          1848:         /* LDQ */
        !          1849:         gen_load_mem(ctx, &gen_ldq, ra, rb, disp16, 0);
        !          1850:         break;
        !          1851:     case 0x2A:
        !          1852:         /* LDL_L */
        !          1853:         gen_load_mem(ctx, &gen_ldl_l, ra, rb, disp16, 0);
        !          1854:         break;
        !          1855:     case 0x2B:
        !          1856:         /* LDQ_L */
        !          1857:         gen_load_mem(ctx, &gen_ldq_l, ra, rb, disp16, 0);
        !          1858:         break;
        !          1859:     case 0x2C:
        !          1860:         /* STL */
        !          1861:         gen_store_mem(ctx, &gen_stl, ra, rb, disp16, 0);
        !          1862:         break;
        !          1863:     case 0x2D:
        !          1864:         /* STQ */
        !          1865:         gen_store_mem(ctx, &gen_stq, ra, rb, disp16, 0);
        !          1866:         break;
        !          1867:     case 0x2E:
        !          1868:         /* STL_C */
        !          1869:         gen_store_mem(ctx, &gen_stl_c, ra, rb, disp16, 0);
        !          1870:         break;
        !          1871:     case 0x2F:
        !          1872:         /* STQ_C */
        !          1873:         gen_store_mem(ctx, &gen_stq_c, ra, rb, disp16, 0);
        !          1874:         break;
        !          1875:     case 0x30:
        !          1876:         /* BR */
        !          1877:         gen_set_uT0(ctx, ctx->pc);
        !          1878:         gen_store_ir(ctx, ra, 0);
        !          1879:         if (disp21 != 0) {
        !          1880:             gen_set_sT1(ctx, disp21 << 2);
        !          1881:             gen_op_addq();
        !          1882:         }
        !          1883:         gen_op_branch();
        !          1884:         ret = 1;
        !          1885:         break;
        !          1886:     case 0x31:
        !          1887:         /* FBEQ */
        !          1888:         gen_fbcond(ctx, &gen_op_cmpfeq, ra, disp16);
        !          1889:         ret = 1;
        !          1890:         break;
        !          1891:     case 0x32:
        !          1892:         /* FBLT */
        !          1893:         gen_fbcond(ctx, &gen_op_cmpflt, ra, disp16);
        !          1894:         ret = 1;
        !          1895:         break;
        !          1896:     case 0x33:
        !          1897:         /* FBLE */
        !          1898:         gen_fbcond(ctx, &gen_op_cmpfle, ra, disp16);
        !          1899:         ret = 1;
        !          1900:         break;
        !          1901:     case 0x34:
        !          1902:         /* BSR */
        !          1903:         gen_set_uT0(ctx, ctx->pc);
        !          1904:         gen_store_ir(ctx, ra, 0);
        !          1905:         if (disp21 != 0) {
        !          1906:             gen_set_sT1(ctx, disp21 << 2);
        !          1907:             gen_op_addq();
        !          1908:         }
        !          1909:         gen_op_branch();
        !          1910:         ret = 1;
        !          1911:         break;
        !          1912:     case 0x35:
        !          1913:         /* FBNE */
        !          1914:         gen_fbcond(ctx, &gen_op_cmpfne, ra, disp16);
        !          1915:         ret = 1;
        !          1916:         break;
        !          1917:     case 0x36:
        !          1918:         /* FBGE */
        !          1919:         gen_fbcond(ctx, &gen_op_cmpfge, ra, disp16);
        !          1920:         ret = 1;
        !          1921:         break;
        !          1922:     case 0x37:
        !          1923:         /* FBGT */
        !          1924:         gen_fbcond(ctx, &gen_op_cmpfgt, ra, disp16);
        !          1925:         ret = 1;
        !          1926:         break;
        !          1927:     case 0x38:
        !          1928:         /* BLBC */
        !          1929:         gen_bcond(ctx, &gen_op_cmplbc, ra, disp16);
        !          1930:         ret = 1;
        !          1931:         break;
        !          1932:     case 0x39:
        !          1933:         /* BEQ */
        !          1934:         gen_bcond(ctx, &gen_op_cmpeqz, ra, disp16);
        !          1935:         ret = 1;
        !          1936:         break;
        !          1937:     case 0x3A:
        !          1938:         /* BLT */
        !          1939:         gen_bcond(ctx, &gen_op_cmpltz, ra, disp16);
        !          1940:         ret = 1;
        !          1941:         break;
        !          1942:     case 0x3B:
        !          1943:         /* BLE */
        !          1944:         gen_bcond(ctx, &gen_op_cmplez, ra, disp16);
        !          1945:         ret = 1;
        !          1946:         break;
        !          1947:     case 0x3C:
        !          1948:         /* BLBS */
        !          1949:         gen_bcond(ctx, &gen_op_cmplbs, ra, disp16);
        !          1950:         ret = 1;
        !          1951:         break;
        !          1952:     case 0x3D:
        !          1953:         /* BNE */
        !          1954:         gen_bcond(ctx, &gen_op_cmpnez, ra, disp16);
        !          1955:         ret = 1;
        !          1956:         break;
        !          1957:     case 0x3E:
        !          1958:         /* BGE */
        !          1959:         gen_bcond(ctx, &gen_op_cmpgez, ra, disp16);
        !          1960:         ret = 1;
        !          1961:         break;
        !          1962:     case 0x3F:
        !          1963:         /* BGT */
        !          1964:         gen_bcond(ctx, &gen_op_cmpgtz, ra, disp16);
        !          1965:         ret = 1;
        !          1966:         break;
        !          1967:     invalid_opc:
        !          1968:         gen_invalid(ctx);
        !          1969:         ret = 3;
        !          1970:         break;
        !          1971:     }
        !          1972: 
        !          1973:     return ret;
        !          1974: }
        !          1975: 
        !          1976: static always_inline int gen_intermediate_code_internal (CPUState *env,
        !          1977:                                                          TranslationBlock *tb,
        !          1978:                                                          int search_pc)
        !          1979: {
        !          1980: #if defined ALPHA_DEBUG_DISAS
        !          1981:     static int insn_count;
        !          1982: #endif
        !          1983:     DisasContext ctx, *ctxp = &ctx;
        !          1984:     target_ulong pc_start;
        !          1985:     uint32_t insn;
        !          1986:     uint16_t *gen_opc_end;
        !          1987:     int j, lj = -1;
        !          1988:     int ret;
        !          1989: 
        !          1990:     pc_start = tb->pc;
        !          1991:     gen_opc_ptr = gen_opc_buf;
        !          1992:     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
        !          1993:     gen_opparam_ptr = gen_opparam_buf;
        !          1994:     nb_gen_labels = 0;
        !          1995:     ctx.pc = pc_start;
        !          1996:     ctx.amask = env->amask;
        !          1997: #if defined (CONFIG_USER_ONLY)
        !          1998:     ctx.mem_idx = 0;
        !          1999: #else
        !          2000:     ctx.mem_idx = ((env->ps >> 3) & 3);
        !          2001:     ctx.pal_mode = env->ipr[IPR_EXC_ADDR] & 1;
        !          2002: #endif
        !          2003:     for (ret = 0; ret == 0;) {
        !          2004:         if (env->nb_breakpoints > 0) {
        !          2005:             for(j = 0; j < env->nb_breakpoints; j++) {
        !          2006:                 if (env->breakpoints[j] == ctx.pc) {
        !          2007:                     gen_excp(&ctx, EXCP_DEBUG, 0);
        !          2008:                     break;
        !          2009:                 }
        !          2010:             }
        !          2011:         }
        !          2012:         if (search_pc) {
        !          2013:             j = gen_opc_ptr - gen_opc_buf;
        !          2014:             if (lj < j) {
        !          2015:                 lj++;
        !          2016:                 while (lj < j)
        !          2017:                     gen_opc_instr_start[lj++] = 0;
        !          2018:                 gen_opc_pc[lj] = ctx.pc;
        !          2019:                 gen_opc_instr_start[lj] = 1;
        !          2020:             }
        !          2021:         }
        !          2022: #if defined ALPHA_DEBUG_DISAS
        !          2023:         insn_count++;
        !          2024:         if (logfile != NULL) {
        !          2025:             fprintf(logfile, "pc " TARGET_FMT_lx " mem_idx %d\n",
        !          2026:                     ctx.pc, ctx.mem_idx);
        !          2027:         }
        !          2028: #endif
        !          2029:         insn = ldl_code(ctx.pc);
        !          2030: #if defined ALPHA_DEBUG_DISAS
        !          2031:         insn_count++;
        !          2032:         if (logfile != NULL) {
        !          2033:             fprintf(logfile, "opcode %08x %d\n", insn, insn_count);
        !          2034:         }
        !          2035: #endif
        !          2036:         ctx.pc += 4;
        !          2037:         ret = translate_one(ctxp, insn);
        !          2038:         if (ret != 0)
        !          2039:             break;
        !          2040:         /* if we reach a page boundary or are single stepping, stop
        !          2041:          * generation
        !          2042:          */
        !          2043:         if (((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0) ||
        !          2044:             (env->singlestep_enabled)) {
        !          2045:             break;
        !          2046:         }
        !          2047: #if defined (DO_SINGLE_STEP)
        !          2048:         break;
        !          2049: #endif
        !          2050:     }
        !          2051:     if (ret != 1 && ret != 3) {
        !          2052:         gen_update_pc(&ctx);
        !          2053:     }
        !          2054:     gen_op_reset_T0();
        !          2055: #if defined (DO_TB_FLUSH)
        !          2056:     gen_op_tb_flush();
        !          2057: #endif
        !          2058:     /* Generate the return instruction */
        !          2059:     gen_op_exit_tb();
        !          2060:     *gen_opc_ptr = INDEX_op_end;
        !          2061:     if (search_pc) {
        !          2062:         j = gen_opc_ptr - gen_opc_buf;
        !          2063:         lj++;
        !          2064:         while (lj <= j)
        !          2065:             gen_opc_instr_start[lj++] = 0;
        !          2066:     } else {
        !          2067:         tb->size = ctx.pc - pc_start;
        !          2068:     }
        !          2069: #if defined ALPHA_DEBUG_DISAS
        !          2070:     if (loglevel & CPU_LOG_TB_CPU) {
        !          2071:         cpu_dump_state(env, logfile, fprintf, 0);
        !          2072:     }
        !          2073:     if (loglevel & CPU_LOG_TB_IN_ASM) {
        !          2074:         fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
        !          2075:        target_disas(logfile, pc_start, ctx.pc - pc_start, 1);
        !          2076:         fprintf(logfile, "\n");
        !          2077:     }
        !          2078:     if (loglevel & CPU_LOG_TB_OP) {
        !          2079:         fprintf(logfile, "OP:\n");
        !          2080:         dump_ops(gen_opc_buf, gen_opparam_buf);
        !          2081:         fprintf(logfile, "\n");
        !          2082:     }
        !          2083: #endif
        !          2084: 
        !          2085:     return 0;
        !          2086: }
        !          2087: 
        !          2088: int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
        !          2089: {
        !          2090:     return gen_intermediate_code_internal(env, tb, 0);
        !          2091: }
        !          2092: 
        !          2093: int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
        !          2094: {
        !          2095:     return gen_intermediate_code_internal(env, tb, 1);
        !          2096: }
        !          2097: 
        !          2098: CPUAlphaState * cpu_alpha_init (const char *cpu_model)
        !          2099: {
        !          2100:     CPUAlphaState *env;
        !          2101:     uint64_t hwpcb;
        !          2102: 
        !          2103:     env = qemu_mallocz(sizeof(CPUAlphaState));
        !          2104:     if (!env)
        !          2105:         return NULL;
        !          2106:     cpu_exec_init(env);
        !          2107:     tlb_flush(env, 1);
        !          2108:     /* XXX: should not be hardcoded */
        !          2109:     env->implver = IMPLVER_2106x;
        !          2110:     env->ps = 0x1F00;
        !          2111: #if defined (CONFIG_USER_ONLY)
        !          2112:     env->ps |= 1 << 3;
        !          2113: #endif
        !          2114:     pal_init(env);
        !          2115:     /* Initialize IPR */
        !          2116:     hwpcb = env->ipr[IPR_PCBB];
        !          2117:     env->ipr[IPR_ASN] = 0;
        !          2118:     env->ipr[IPR_ASTEN] = 0;
        !          2119:     env->ipr[IPR_ASTSR] = 0;
        !          2120:     env->ipr[IPR_DATFX] = 0;
        !          2121:     /* XXX: fix this */
        !          2122:     //    env->ipr[IPR_ESP] = ldq_raw(hwpcb + 8);
        !          2123:     //    env->ipr[IPR_KSP] = ldq_raw(hwpcb + 0);
        !          2124:     //    env->ipr[IPR_SSP] = ldq_raw(hwpcb + 16);
        !          2125:     //    env->ipr[IPR_USP] = ldq_raw(hwpcb + 24);
        !          2126:     env->ipr[IPR_FEN] = 0;
        !          2127:     env->ipr[IPR_IPL] = 31;
        !          2128:     env->ipr[IPR_MCES] = 0;
        !          2129:     env->ipr[IPR_PERFMON] = 0; /* Implementation specific */
        !          2130:     //    env->ipr[IPR_PTBR] = ldq_raw(hwpcb + 32);
        !          2131:     env->ipr[IPR_SISR] = 0;
        !          2132:     env->ipr[IPR_VIRBND] = -1ULL;
        !          2133: 
        !          2134:     return env;
        !          2135: }
        !          2136: 

unix.superglobalmegacorp.com

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