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

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
1.1.1.3   root       17:  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
1.1       root       18:  */
                     19: 
                     20: #include <stdint.h>
                     21: #include <stdlib.h>
                     22: #include <stdio.h>
                     23: 
                     24: #include "cpu.h"
                     25: #include "exec-all.h"
                     26: #include "disas.h"
1.1.1.2   root       27: #include "host-utils.h"
                     28: #include "tcg-op.h"
                     29: #include "qemu-common.h"
                     30: 
                     31: #include "helper.h"
                     32: #define GEN_HELPER 1
                     33: #include "helper.h"
1.1       root       34: 
1.1.1.5 ! root       35: #undef ALPHA_DEBUG_DISAS
        !            36: #define CONFIG_SOFTFLOAT_INLINE
1.1.1.2   root       37: 
                     38: #ifdef ALPHA_DEBUG_DISAS
1.1.1.5 ! root       39: #  define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
1.1.1.2   root       40: #else
                     41: #  define LOG_DISAS(...) do { } while (0)
                     42: #endif
1.1       root       43: 
                     44: typedef struct DisasContext DisasContext;
                     45: struct DisasContext {
1.1.1.5 ! root       46:     struct TranslationBlock *tb;
        !            47:     CPUAlphaState *env;
1.1       root       48:     uint64_t pc;
                     49:     int mem_idx;
                     50: #if !defined (CONFIG_USER_ONLY)
                     51:     int pal_mode;
                     52: #endif
                     53:     uint32_t amask;
1.1.1.5 ! root       54: 
        !            55:     /* Current rounding mode for this TB.  */
        !            56:     int tb_rm;
        !            57:     /* Current flush-to-zero setting for this TB.  */
        !            58:     int tb_ftz;
1.1       root       59: };
                     60: 
1.1.1.5 ! root       61: /* Return values from translate_one, indicating the state of the TB.
        !            62:    Note that zero indicates that we are not exiting the TB.  */
        !            63: 
        !            64: typedef enum {
        !            65:     NO_EXIT,
        !            66: 
        !            67:     /* We have emitted one or more goto_tb.  No fixup required.  */
        !            68:     EXIT_GOTO_TB,
        !            69: 
        !            70:     /* We are not using a goto_tb (for whatever reason), but have updated
        !            71:        the PC (for whatever reason), so there's no need to do it again on
        !            72:        exiting the TB.  */
        !            73:     EXIT_PC_UPDATED,
        !            74: 
        !            75:     /* We are exiting the TB, but have neither emitted a goto_tb, nor
        !            76:        updated the PC for the next instruction to be executed.  */
        !            77:     EXIT_PC_STALE,
        !            78: 
        !            79:     /* We are ending the TB with a noreturn function call, e.g. longjmp.
        !            80:        No following code will be executed.  */
        !            81:     EXIT_NORETURN,
        !            82: } ExitStatus;
        !            83: 
1.1.1.2   root       84: /* global register indexes */
                     85: static TCGv_ptr cpu_env;
                     86: static TCGv cpu_ir[31];
                     87: static TCGv cpu_fir[31];
                     88: static TCGv cpu_pc;
1.1.1.5 ! root       89: static TCGv cpu_lock_addr;
        !            90: static TCGv cpu_lock_st_addr;
        !            91: static TCGv cpu_lock_value;
        !            92: #ifdef CONFIG_USER_ONLY
        !            93: static TCGv cpu_uniq;
        !            94: #endif
1.1       root       95: 
1.1.1.2   root       96: /* register names */
                     97: static char cpu_reg_names[10*4+21*5 + 10*5+21*6];
1.1       root       98: 
1.1.1.2   root       99: #include "gen-icount.h"
1.1       root      100: 
1.1.1.2   root      101: static void alpha_translate_init(void)
1.1       root      102: {
1.1.1.2   root      103:     int i;
                    104:     char *p;
                    105:     static int done_init = 0;
1.1       root      106: 
1.1.1.2   root      107:     if (done_init)
                    108:         return;
1.1       root      109: 
1.1.1.2   root      110:     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
1.1       root      111: 
1.1.1.2   root      112:     p = cpu_reg_names;
                    113:     for (i = 0; i < 31; i++) {
                    114:         sprintf(p, "ir%d", i);
                    115:         cpu_ir[i] = tcg_global_mem_new_i64(TCG_AREG0,
                    116:                                            offsetof(CPUState, ir[i]), p);
                    117:         p += (i < 10) ? 4 : 5;
1.1       root      118: 
1.1.1.2   root      119:         sprintf(p, "fir%d", i);
                    120:         cpu_fir[i] = tcg_global_mem_new_i64(TCG_AREG0,
                    121:                                             offsetof(CPUState, fir[i]), p);
                    122:         p += (i < 10) ? 5 : 6;
1.1       root      123:     }
                    124: 
1.1.1.2   root      125:     cpu_pc = tcg_global_mem_new_i64(TCG_AREG0,
                    126:                                     offsetof(CPUState, pc), "pc");
1.1       root      127: 
1.1.1.5 ! root      128:     cpu_lock_addr = tcg_global_mem_new_i64(TCG_AREG0,
        !           129:                                           offsetof(CPUState, lock_addr),
        !           130:                                           "lock_addr");
        !           131:     cpu_lock_st_addr = tcg_global_mem_new_i64(TCG_AREG0,
        !           132:                                              offsetof(CPUState, lock_st_addr),
        !           133:                                              "lock_st_addr");
        !           134:     cpu_lock_value = tcg_global_mem_new_i64(TCG_AREG0,
        !           135:                                            offsetof(CPUState, lock_value),
        !           136:                                            "lock_value");
        !           137: 
        !           138: #ifdef CONFIG_USER_ONLY
        !           139:     cpu_uniq = tcg_global_mem_new_i64(TCG_AREG0,
        !           140:                                       offsetof(CPUState, unique), "uniq");
        !           141: #endif
1.1       root      142: 
1.1.1.2   root      143:     /* register helpers */
                    144: #define GEN_HELPER 2
                    145: #include "helper.h"
1.1       root      146: 
1.1.1.2   root      147:     done_init = 1;
                    148: }
1.1       root      149: 
1.1.1.5 ! root      150: static ExitStatus gen_excp(DisasContext *ctx, int exception, int error_code)
1.1       root      151: {
1.1.1.2   root      152:     TCGv_i32 tmp1, tmp2;
                    153: 
                    154:     tcg_gen_movi_i64(cpu_pc, ctx->pc);
                    155:     tmp1 = tcg_const_i32(exception);
                    156:     tmp2 = tcg_const_i32(error_code);
                    157:     gen_helper_excp(tmp1, tmp2);
                    158:     tcg_temp_free_i32(tmp2);
                    159:     tcg_temp_free_i32(tmp1);
1.1.1.5 ! root      160: 
        !           161:     return EXIT_NORETURN;
1.1       root      162: }
                    163: 
1.1.1.5 ! root      164: static inline ExitStatus gen_invalid(DisasContext *ctx)
1.1       root      165: {
1.1.1.5 ! root      166:     return gen_excp(ctx, EXCP_OPCDEC, 0);
1.1       root      167: }
                    168: 
1.1.1.4   root      169: static inline void gen_qemu_ldf(TCGv t0, TCGv t1, int flags)
1.1       root      170: {
1.1.1.2   root      171:     TCGv tmp = tcg_temp_new();
                    172:     TCGv_i32 tmp32 = tcg_temp_new_i32();
                    173:     tcg_gen_qemu_ld32u(tmp, t1, flags);
                    174:     tcg_gen_trunc_i64_i32(tmp32, tmp);
                    175:     gen_helper_memory_to_f(t0, tmp32);
                    176:     tcg_temp_free_i32(tmp32);
                    177:     tcg_temp_free(tmp);
1.1       root      178: }
                    179: 
1.1.1.4   root      180: static inline void gen_qemu_ldg(TCGv t0, TCGv t1, int flags)
1.1       root      181: {
1.1.1.2   root      182:     TCGv tmp = tcg_temp_new();
                    183:     tcg_gen_qemu_ld64(tmp, t1, flags);
                    184:     gen_helper_memory_to_g(t0, tmp);
                    185:     tcg_temp_free(tmp);
1.1       root      186: }
                    187: 
1.1.1.4   root      188: static inline void gen_qemu_lds(TCGv t0, TCGv t1, int flags)
1.1       root      189: {
1.1.1.2   root      190:     TCGv tmp = tcg_temp_new();
                    191:     TCGv_i32 tmp32 = tcg_temp_new_i32();
                    192:     tcg_gen_qemu_ld32u(tmp, t1, flags);
                    193:     tcg_gen_trunc_i64_i32(tmp32, tmp);
                    194:     gen_helper_memory_to_s(t0, tmp32);
                    195:     tcg_temp_free_i32(tmp32);
                    196:     tcg_temp_free(tmp);
1.1       root      197: }
                    198: 
1.1.1.4   root      199: static inline void gen_qemu_ldl_l(TCGv t0, TCGv t1, int flags)
1.1       root      200: {
1.1.1.2   root      201:     tcg_gen_qemu_ld32s(t0, t1, flags);
1.1.1.5 ! root      202:     tcg_gen_mov_i64(cpu_lock_addr, t1);
        !           203:     tcg_gen_mov_i64(cpu_lock_value, t0);
1.1       root      204: }
                    205: 
1.1.1.4   root      206: static inline void gen_qemu_ldq_l(TCGv t0, TCGv t1, int flags)
1.1       root      207: {
1.1.1.2   root      208:     tcg_gen_qemu_ld64(t0, t1, flags);
1.1.1.5 ! root      209:     tcg_gen_mov_i64(cpu_lock_addr, t1);
        !           210:     tcg_gen_mov_i64(cpu_lock_value, t0);
1.1       root      211: }
                    212: 
1.1.1.4   root      213: static inline void gen_load_mem(DisasContext *ctx,
                    214:                                 void (*tcg_gen_qemu_load)(TCGv t0, TCGv t1,
                    215:                                                           int flags),
                    216:                                 int ra, int rb, int32_t disp16, int fp,
                    217:                                 int clear)
1.1       root      218: {
1.1.1.5 ! root      219:     TCGv addr, va;
1.1.1.2   root      220: 
1.1.1.5 ! root      221:     /* LDQ_U with ra $31 is UNOP.  Other various loads are forms of
        !           222:        prefetches, which we can treat as nops.  No worries about
        !           223:        missed exceptions here.  */
        !           224:     if (unlikely(ra == 31)) {
1.1.1.2   root      225:         return;
1.1.1.5 ! root      226:     }
1.1.1.2   root      227: 
                    228:     addr = tcg_temp_new();
                    229:     if (rb != 31) {
                    230:         tcg_gen_addi_i64(addr, cpu_ir[rb], disp16);
1.1.1.5 ! root      231:         if (clear) {
1.1.1.2   root      232:             tcg_gen_andi_i64(addr, addr, ~0x7);
1.1.1.5 ! root      233:         }
1.1       root      234:     } else {
1.1.1.5 ! root      235:         if (clear) {
1.1.1.2   root      236:             disp16 &= ~0x7;
1.1.1.5 ! root      237:         }
1.1.1.2   root      238:         tcg_gen_movi_i64(addr, disp16);
1.1       root      239:     }
1.1.1.5 ! root      240: 
        !           241:     va = (fp ? cpu_fir[ra] : cpu_ir[ra]);
        !           242:     tcg_gen_qemu_load(va, addr, ctx->mem_idx);
        !           243: 
1.1.1.2   root      244:     tcg_temp_free(addr);
1.1       root      245: }
                    246: 
1.1.1.4   root      247: static inline void gen_qemu_stf(TCGv t0, TCGv t1, int flags)
1.1       root      248: {
1.1.1.2   root      249:     TCGv_i32 tmp32 = tcg_temp_new_i32();
                    250:     TCGv tmp = tcg_temp_new();
                    251:     gen_helper_f_to_memory(tmp32, t0);
                    252:     tcg_gen_extu_i32_i64(tmp, tmp32);
                    253:     tcg_gen_qemu_st32(tmp, t1, flags);
                    254:     tcg_temp_free(tmp);
                    255:     tcg_temp_free_i32(tmp32);
1.1       root      256: }
                    257: 
1.1.1.4   root      258: static inline void gen_qemu_stg(TCGv t0, TCGv t1, int flags)
1.1       root      259: {
1.1.1.2   root      260:     TCGv tmp = tcg_temp_new();
                    261:     gen_helper_g_to_memory(tmp, t0);
                    262:     tcg_gen_qemu_st64(tmp, t1, flags);
                    263:     tcg_temp_free(tmp);
1.1       root      264: }
                    265: 
1.1.1.4   root      266: static inline void gen_qemu_sts(TCGv t0, TCGv t1, int flags)
1.1       root      267: {
1.1.1.2   root      268:     TCGv_i32 tmp32 = tcg_temp_new_i32();
                    269:     TCGv tmp = tcg_temp_new();
                    270:     gen_helper_s_to_memory(tmp32, t0);
                    271:     tcg_gen_extu_i32_i64(tmp, tmp32);
                    272:     tcg_gen_qemu_st32(tmp, t1, flags);
                    273:     tcg_temp_free(tmp);
                    274:     tcg_temp_free_i32(tmp32);
1.1       root      275: }
                    276: 
1.1.1.4   root      277: static inline void gen_store_mem(DisasContext *ctx,
                    278:                                  void (*tcg_gen_qemu_store)(TCGv t0, TCGv t1,
                    279:                                                             int flags),
                    280:                                  int ra, int rb, int32_t disp16, int fp,
1.1.1.5 ! root      281:                                  int clear)
1.1       root      282: {
1.1.1.5 ! root      283:     TCGv addr, va;
        !           284: 
        !           285:     addr = tcg_temp_new();
1.1.1.2   root      286:     if (rb != 31) {
                    287:         tcg_gen_addi_i64(addr, cpu_ir[rb], disp16);
1.1.1.5 ! root      288:         if (clear) {
1.1.1.2   root      289:             tcg_gen_andi_i64(addr, addr, ~0x7);
1.1.1.5 ! root      290:         }
1.1.1.2   root      291:     } else {
1.1.1.5 ! root      292:         if (clear) {
1.1.1.2   root      293:             disp16 &= ~0x7;
1.1.1.5 ! root      294:         }
1.1.1.2   root      295:         tcg_gen_movi_i64(addr, disp16);
1.1       root      296:     }
1.1.1.5 ! root      297: 
        !           298:     if (ra == 31) {
        !           299:         va = tcg_const_i64(0);
        !           300:     } else {
        !           301:         va = (fp ? cpu_fir[ra] : cpu_ir[ra]);
1.1       root      302:     }
1.1.1.5 ! root      303:     tcg_gen_qemu_store(va, addr, ctx->mem_idx);
        !           304: 
1.1.1.2   root      305:     tcg_temp_free(addr);
1.1.1.5 ! root      306:     if (ra == 31) {
        !           307:         tcg_temp_free(va);
        !           308:     }
1.1       root      309: }
                    310: 
1.1.1.5 ! root      311: static ExitStatus gen_store_conditional(DisasContext *ctx, int ra, int rb,
        !           312:                                         int32_t disp16, int quad)
1.1       root      313: {
1.1.1.5 ! root      314:     TCGv addr;
1.1.1.2   root      315: 
1.1.1.5 ! root      316:     if (ra == 31) {
        !           317:         /* ??? Don't bother storing anything.  The user can't tell
        !           318:            the difference, since the zero register always reads zero.  */
        !           319:         return NO_EXIT;
        !           320:     }
        !           321: 
        !           322: #if defined(CONFIG_USER_ONLY)
        !           323:     addr = cpu_lock_st_addr;
        !           324: #else
        !           325:     addr = tcg_local_new();
        !           326: #endif
        !           327: 
        !           328:     if (rb != 31) {
        !           329:         tcg_gen_addi_i64(addr, cpu_ir[rb], disp16);
1.1       root      330:     } else {
1.1.1.5 ! root      331:         tcg_gen_movi_i64(addr, disp16);
1.1.1.2   root      332:     }
1.1.1.5 ! root      333: 
        !           334: #if defined(CONFIG_USER_ONLY)
        !           335:     /* ??? This is handled via a complicated version of compare-and-swap
        !           336:        in the cpu_loop.  Hopefully one day we'll have a real CAS opcode
        !           337:        in TCG so that this isn't necessary.  */
        !           338:     return gen_excp(ctx, quad ? EXCP_STQ_C : EXCP_STL_C, ra);
        !           339: #else
        !           340:     /* ??? In system mode we are never multi-threaded, so CAS can be
        !           341:        implemented via a non-atomic load-compare-store sequence.  */
        !           342:     {
        !           343:         int lab_fail, lab_done;
        !           344:         TCGv val;
        !           345: 
        !           346:         lab_fail = gen_new_label();
        !           347:         lab_done = gen_new_label();
        !           348:         tcg_gen_brcond(TCG_COND_NE, addr, cpu_lock_addr, lab_fail);
        !           349: 
        !           350:         val = tcg_temp_new();
        !           351:         if (quad) {
        !           352:             tcg_gen_qemu_ld64(val, addr, ctx->mem_idx);
        !           353:         } else {
        !           354:             tcg_gen_qemu_ld32s(val, addr, ctx->mem_idx);
        !           355:         }
        !           356:         tcg_gen_brcond(TCG_COND_NE, val, cpu_lock_value, lab_fail);
        !           357: 
        !           358:         if (quad) {
        !           359:             tcg_gen_qemu_st64(cpu_ir[ra], addr, ctx->mem_idx);
        !           360:         } else {
        !           361:             tcg_gen_qemu_st32(cpu_ir[ra], addr, ctx->mem_idx);
        !           362:         }
        !           363:         tcg_gen_movi_i64(cpu_ir[ra], 1);
        !           364:         tcg_gen_br(lab_done);
        !           365: 
        !           366:         gen_set_label(lab_fail);
        !           367:         tcg_gen_movi_i64(cpu_ir[ra], 0);
        !           368: 
        !           369:         gen_set_label(lab_done);
        !           370:         tcg_gen_movi_i64(cpu_lock_addr, -1);
        !           371: 
        !           372:         tcg_temp_free(addr);
        !           373:         return NO_EXIT;
        !           374:     }
        !           375: #endif
        !           376: }
        !           377: 
        !           378: static int use_goto_tb(DisasContext *ctx, uint64_t dest)
        !           379: {
        !           380:     /* Check for the dest on the same page as the start of the TB.  We
        !           381:        also want to suppress goto_tb in the case of single-steping and IO.  */
        !           382:     return (((ctx->tb->pc ^ dest) & TARGET_PAGE_MASK) == 0
        !           383:             && !ctx->env->singlestep_enabled
        !           384:             && !(ctx->tb->cflags & CF_LAST_IO));
1.1       root      385: }
                    386: 
1.1.1.5 ! root      387: static ExitStatus gen_bdirect(DisasContext *ctx, int ra, int32_t disp)
1.1       root      388: {
1.1.1.5 ! root      389:     uint64_t dest = ctx->pc + (disp << 2);
1.1.1.2   root      390: 
                    391:     if (ra != 31) {
1.1.1.5 ! root      392:         tcg_gen_movi_i64(cpu_ir[ra], ctx->pc);
1.1       root      393:     }
1.1.1.5 ! root      394: 
        !           395:     /* Notice branch-to-next; used to initialize RA with the PC.  */
        !           396:     if (disp == 0) {
        !           397:         return 0;
        !           398:     } else if (use_goto_tb(ctx, dest)) {
        !           399:         tcg_gen_goto_tb(0);
        !           400:         tcg_gen_movi_i64(cpu_pc, dest);
        !           401:         tcg_gen_exit_tb((long)ctx->tb);
        !           402:         return EXIT_GOTO_TB;
        !           403:     } else {
        !           404:         tcg_gen_movi_i64(cpu_pc, dest);
        !           405:         return EXIT_PC_UPDATED;
        !           406:     }
        !           407: }
        !           408: 
        !           409: static ExitStatus gen_bcond_internal(DisasContext *ctx, TCGCond cond,
        !           410:                                      TCGv cmp, int32_t disp)
        !           411: {
        !           412:     uint64_t dest = ctx->pc + (disp << 2);
        !           413:     int lab_true = gen_new_label();
        !           414: 
        !           415:     if (use_goto_tb(ctx, dest)) {
        !           416:         tcg_gen_brcondi_i64(cond, cmp, 0, lab_true);
        !           417: 
        !           418:         tcg_gen_goto_tb(0);
        !           419:         tcg_gen_movi_i64(cpu_pc, ctx->pc);
        !           420:         tcg_gen_exit_tb((long)ctx->tb);
        !           421: 
        !           422:         gen_set_label(lab_true);
        !           423:         tcg_gen_goto_tb(1);
        !           424:         tcg_gen_movi_i64(cpu_pc, dest);
        !           425:         tcg_gen_exit_tb((long)ctx->tb + 1);
        !           426: 
        !           427:         return EXIT_GOTO_TB;
        !           428:     } else {
        !           429:         int lab_over = gen_new_label();
        !           430: 
        !           431:         /* ??? Consider using either
        !           432:              movi pc, next
        !           433:              addi tmp, pc, disp
        !           434:              movcond pc, cond, 0, tmp, pc
        !           435:            or
        !           436:              setcond tmp, cond, 0
        !           437:              movi pc, next
        !           438:              neg tmp, tmp
        !           439:              andi tmp, tmp, disp
        !           440:              add pc, pc, tmp
        !           441:            The current diamond subgraph surely isn't efficient.  */
        !           442: 
        !           443:         tcg_gen_brcondi_i64(cond, cmp, 0, lab_true);
        !           444:         tcg_gen_movi_i64(cpu_pc, ctx->pc);
        !           445:         tcg_gen_br(lab_over);
        !           446:         gen_set_label(lab_true);
        !           447:         tcg_gen_movi_i64(cpu_pc, dest);
        !           448:         gen_set_label(lab_over);
        !           449: 
        !           450:         return EXIT_PC_UPDATED;
        !           451:     }
        !           452: }
        !           453: 
        !           454: static ExitStatus gen_bcond(DisasContext *ctx, TCGCond cond, int ra,
        !           455:                             int32_t disp, int mask)
        !           456: {
        !           457:     TCGv cmp_tmp;
        !           458: 
        !           459:     if (unlikely(ra == 31)) {
        !           460:         cmp_tmp = tcg_const_i64(0);
        !           461:     } else {
        !           462:         cmp_tmp = tcg_temp_new();
        !           463:         if (mask) {
        !           464:             tcg_gen_andi_i64(cmp_tmp, cpu_ir[ra], 1);
        !           465:         } else {
        !           466:             tcg_gen_mov_i64(cmp_tmp, cpu_ir[ra]);
        !           467:         }
        !           468:     }
        !           469: 
        !           470:     return gen_bcond_internal(ctx, cond, cmp_tmp, disp);
        !           471: }
        !           472: 
        !           473: /* Fold -0.0 for comparison with COND.  */
        !           474: 
        !           475: static void gen_fold_mzero(TCGCond cond, TCGv dest, TCGv src)
        !           476: {
        !           477:     uint64_t mzero = 1ull << 63;
        !           478: 
        !           479:     switch (cond) {
        !           480:     case TCG_COND_LE:
        !           481:     case TCG_COND_GT:
        !           482:         /* For <= or >, the -0.0 value directly compares the way we want.  */
        !           483:         tcg_gen_mov_i64(dest, src);
1.1.1.2   root      484:         break;
1.1.1.5 ! root      485: 
        !           486:     case TCG_COND_EQ:
        !           487:     case TCG_COND_NE:
        !           488:         /* For == or !=, we can simply mask off the sign bit and compare.  */
        !           489:         tcg_gen_andi_i64(dest, src, mzero - 1);
1.1.1.2   root      490:         break;
1.1.1.5 ! root      491: 
        !           492:     case TCG_COND_GE:
        !           493:     case TCG_COND_LT:
        !           494:         /* For >= or <, map -0.0 to +0.0 via comparison and mask.  */
        !           495:         tcg_gen_setcondi_i64(TCG_COND_NE, dest, src, mzero);
        !           496:         tcg_gen_neg_i64(dest, dest);
        !           497:         tcg_gen_and_i64(dest, dest, src);
1.1.1.2   root      498:         break;
1.1.1.5 ! root      499: 
1.1.1.2   root      500:     default:
                    501:         abort();
                    502:     }
1.1       root      503: }
                    504: 
1.1.1.5 ! root      505: static ExitStatus gen_fbcond(DisasContext *ctx, TCGCond cond, int ra,
        !           506:                              int32_t disp)
1.1       root      507: {
1.1.1.5 ! root      508:     TCGv cmp_tmp;
        !           509: 
        !           510:     if (unlikely(ra == 31)) {
        !           511:         /* Very uncommon case, but easier to optimize it to an integer
        !           512:            comparison than continuing with the floating point comparison.  */
        !           513:         return gen_bcond(ctx, cond, ra, disp, 0);
        !           514:     }
        !           515: 
        !           516:     cmp_tmp = tcg_temp_new();
        !           517:     gen_fold_mzero(cond, cmp_tmp, cpu_fir[ra]);
        !           518:     return gen_bcond_internal(ctx, cond, cmp_tmp, disp);
        !           519: }
        !           520: 
        !           521: static void gen_cmov(TCGCond cond, int ra, int rb, int rc,
        !           522:                      int islit, uint8_t lit, int mask)
        !           523: {
        !           524:     TCGCond inv_cond = tcg_invert_cond(cond);
1.1.1.2   root      525:     int l1;
1.1       root      526: 
1.1.1.2   root      527:     if (unlikely(rc == 31))
                    528:         return;
1.1       root      529: 
1.1.1.2   root      530:     l1 = gen_new_label();
1.1       root      531: 
1.1.1.2   root      532:     if (ra != 31) {
                    533:         if (mask) {
                    534:             TCGv tmp = tcg_temp_new();
                    535:             tcg_gen_andi_i64(tmp, cpu_ir[ra], 1);
                    536:             tcg_gen_brcondi_i64(inv_cond, tmp, 0, l1);
                    537:             tcg_temp_free(tmp);
                    538:         } else
                    539:             tcg_gen_brcondi_i64(inv_cond, cpu_ir[ra], 0, l1);
                    540:     } else {
                    541:         /* Very uncommon case - Do not bother to optimize.  */
                    542:         TCGv tmp = tcg_const_i64(0);
                    543:         tcg_gen_brcondi_i64(inv_cond, tmp, 0, l1);
                    544:         tcg_temp_free(tmp);
                    545:     }
1.1       root      546: 
1.1.1.2   root      547:     if (islit)
                    548:         tcg_gen_movi_i64(cpu_ir[rc], lit);
                    549:     else
                    550:         tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
                    551:     gen_set_label(l1);
1.1       root      552: }
                    553: 
1.1.1.5 ! root      554: static void gen_fcmov(TCGCond cond, int ra, int rb, int rc)
        !           555: {
        !           556:     TCGv cmp_tmp;
        !           557:     int l1;
        !           558: 
        !           559:     if (unlikely(rc == 31)) {
        !           560:         return;
        !           561:     }
        !           562: 
        !           563:     cmp_tmp = tcg_temp_new();
        !           564:     if (unlikely(ra == 31)) {
        !           565:         tcg_gen_movi_i64(cmp_tmp, 0);
        !           566:     } else {
        !           567:         gen_fold_mzero(cond, cmp_tmp, cpu_fir[ra]);
        !           568:     }
        !           569: 
        !           570:     l1 = gen_new_label();
        !           571:     tcg_gen_brcondi_i64(tcg_invert_cond(cond), cmp_tmp, 0, l1);
        !           572:     tcg_temp_free(cmp_tmp);
        !           573: 
        !           574:     if (rb != 31)
        !           575:         tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[rb]);
        !           576:     else
        !           577:         tcg_gen_movi_i64(cpu_fir[rc], 0);
        !           578:     gen_set_label(l1);
1.1.1.2   root      579: }
1.1.1.5 ! root      580: 
        !           581: #define QUAL_RM_N       0x080   /* Round mode nearest even */
        !           582: #define QUAL_RM_C       0x000   /* Round mode chopped */
        !           583: #define QUAL_RM_M       0x040   /* Round mode minus infinity */
        !           584: #define QUAL_RM_D       0x0c0   /* Round mode dynamic */
        !           585: #define QUAL_RM_MASK    0x0c0
        !           586: 
        !           587: #define QUAL_U          0x100   /* Underflow enable (fp output) */
        !           588: #define QUAL_V          0x100   /* Overflow enable (int output) */
        !           589: #define QUAL_S          0x400   /* Software completion enable */
        !           590: #define QUAL_I          0x200   /* Inexact detection enable */
        !           591: 
        !           592: static void gen_qual_roundmode(DisasContext *ctx, int fn11)
        !           593: {
        !           594:     TCGv_i32 tmp;
        !           595: 
        !           596:     fn11 &= QUAL_RM_MASK;
        !           597:     if (fn11 == ctx->tb_rm) {
        !           598:         return;
        !           599:     }
        !           600:     ctx->tb_rm = fn11;
        !           601: 
        !           602:     tmp = tcg_temp_new_i32();
        !           603:     switch (fn11) {
        !           604:     case QUAL_RM_N:
        !           605:         tcg_gen_movi_i32(tmp, float_round_nearest_even);
        !           606:         break;
        !           607:     case QUAL_RM_C:
        !           608:         tcg_gen_movi_i32(tmp, float_round_to_zero);
        !           609:         break;
        !           610:     case QUAL_RM_M:
        !           611:         tcg_gen_movi_i32(tmp, float_round_down);
        !           612:         break;
        !           613:     case QUAL_RM_D:
        !           614:         tcg_gen_ld8u_i32(tmp, cpu_env, offsetof(CPUState, fpcr_dyn_round));
        !           615:         break;
        !           616:     }
        !           617: 
        !           618: #if defined(CONFIG_SOFTFLOAT_INLINE)
        !           619:     /* ??? The "softfloat.h" interface is to call set_float_rounding_mode.
        !           620:        With CONFIG_SOFTFLOAT that expands to an out-of-line call that just
        !           621:        sets the one field.  */
        !           622:     tcg_gen_st8_i32(tmp, cpu_env,
        !           623:                     offsetof(CPUState, fp_status.float_rounding_mode));
        !           624: #else
        !           625:     gen_helper_setroundmode(tmp);
        !           626: #endif
        !           627: 
        !           628:     tcg_temp_free_i32(tmp);
        !           629: }
        !           630: 
        !           631: static void gen_qual_flushzero(DisasContext *ctx, int fn11)
        !           632: {
        !           633:     TCGv_i32 tmp;
        !           634: 
        !           635:     fn11 &= QUAL_U;
        !           636:     if (fn11 == ctx->tb_ftz) {
        !           637:         return;
        !           638:     }
        !           639:     ctx->tb_ftz = fn11;
        !           640: 
        !           641:     tmp = tcg_temp_new_i32();
        !           642:     if (fn11) {
        !           643:         /* Underflow is enabled, use the FPCR setting.  */
        !           644:         tcg_gen_ld8u_i32(tmp, cpu_env, offsetof(CPUState, fpcr_flush_to_zero));
        !           645:     } else {
        !           646:         /* Underflow is disabled, force flush-to-zero.  */
        !           647:         tcg_gen_movi_i32(tmp, 1);
        !           648:     }
        !           649: 
        !           650: #if defined(CONFIG_SOFTFLOAT_INLINE)
        !           651:     tcg_gen_st8_i32(tmp, cpu_env,
        !           652:                     offsetof(CPUState, fp_status.flush_to_zero));
        !           653: #else
        !           654:     gen_helper_setflushzero(tmp);
        !           655: #endif
        !           656: 
        !           657:     tcg_temp_free_i32(tmp);
        !           658: }
        !           659: 
        !           660: static TCGv gen_ieee_input(int reg, int fn11, int is_cmp)
        !           661: {
        !           662:     TCGv val = tcg_temp_new();
        !           663:     if (reg == 31) {
        !           664:         tcg_gen_movi_i64(val, 0);
        !           665:     } else if (fn11 & QUAL_S) {
        !           666:         gen_helper_ieee_input_s(val, cpu_fir[reg]);
        !           667:     } else if (is_cmp) {
        !           668:         gen_helper_ieee_input_cmp(val, cpu_fir[reg]);
        !           669:     } else {
        !           670:         gen_helper_ieee_input(val, cpu_fir[reg]);
        !           671:     }
        !           672:     return val;
        !           673: }
        !           674: 
        !           675: static void gen_fp_exc_clear(void)
        !           676: {
        !           677: #if defined(CONFIG_SOFTFLOAT_INLINE)
        !           678:     TCGv_i32 zero = tcg_const_i32(0);
        !           679:     tcg_gen_st8_i32(zero, cpu_env,
        !           680:                     offsetof(CPUState, fp_status.float_exception_flags));
        !           681:     tcg_temp_free_i32(zero);
        !           682: #else
        !           683:     gen_helper_fp_exc_clear();
        !           684: #endif
        !           685: }
        !           686: 
        !           687: static void gen_fp_exc_raise_ignore(int rc, int fn11, int ignore)
        !           688: {
        !           689:     /* ??? We ought to be able to do something with imprecise exceptions.
        !           690:        E.g. notice we're still in the trap shadow of something within the
        !           691:        TB and do not generate the code to signal the exception; end the TB
        !           692:        when an exception is forced to arrive, either by consumption of a
        !           693:        register value or TRAPB or EXCB.  */
        !           694:     TCGv_i32 exc = tcg_temp_new_i32();
        !           695:     TCGv_i32 reg;
        !           696: 
        !           697: #if defined(CONFIG_SOFTFLOAT_INLINE)
        !           698:     tcg_gen_ld8u_i32(exc, cpu_env,
        !           699:                      offsetof(CPUState, fp_status.float_exception_flags));
        !           700: #else
        !           701:     gen_helper_fp_exc_get(exc);
        !           702: #endif
        !           703: 
        !           704:     if (ignore) {
        !           705:         tcg_gen_andi_i32(exc, exc, ~ignore);
        !           706:     }
        !           707: 
        !           708:     /* ??? Pass in the regno of the destination so that the helper can
        !           709:        set EXC_MASK, which contains a bitmask of destination registers
        !           710:        that have caused arithmetic traps.  A simple userspace emulation
        !           711:        does not require this.  We do need it for a guest kernel's entArith,
        !           712:        or if we were to do something clever with imprecise exceptions.  */
        !           713:     reg = tcg_const_i32(rc + 32);
        !           714: 
        !           715:     if (fn11 & QUAL_S) {
        !           716:         gen_helper_fp_exc_raise_s(exc, reg);
        !           717:     } else {
        !           718:         gen_helper_fp_exc_raise(exc, reg);
        !           719:     }
        !           720: 
        !           721:     tcg_temp_free_i32(reg);
        !           722:     tcg_temp_free_i32(exc);
        !           723: }
        !           724: 
        !           725: static inline void gen_fp_exc_raise(int rc, int fn11)
        !           726: {
        !           727:     gen_fp_exc_raise_ignore(rc, fn11, fn11 & QUAL_I ? 0 : float_flag_inexact);
        !           728: }
        !           729: 
        !           730: static void gen_fcvtlq(int rb, int rc)
        !           731: {
        !           732:     if (unlikely(rc == 31)) {
        !           733:         return;
        !           734:     }
        !           735:     if (unlikely(rb == 31)) {
        !           736:         tcg_gen_movi_i64(cpu_fir[rc], 0);
        !           737:     } else {
        !           738:         TCGv tmp = tcg_temp_new();
        !           739: 
        !           740:         /* The arithmetic right shift here, plus the sign-extended mask below
        !           741:            yields a sign-extended result without an explicit ext32s_i64.  */
        !           742:         tcg_gen_sari_i64(tmp, cpu_fir[rb], 32);
        !           743:         tcg_gen_shri_i64(cpu_fir[rc], cpu_fir[rb], 29);
        !           744:         tcg_gen_andi_i64(tmp, tmp, (int32_t)0xc0000000);
        !           745:         tcg_gen_andi_i64(cpu_fir[rc], cpu_fir[rc], 0x3fffffff);
        !           746:         tcg_gen_or_i64(cpu_fir[rc], cpu_fir[rc], tmp);
        !           747: 
        !           748:         tcg_temp_free(tmp);
        !           749:     }
        !           750: }
        !           751: 
        !           752: static void gen_fcvtql(int rb, int rc)
        !           753: {
        !           754:     if (unlikely(rc == 31)) {
        !           755:         return;
        !           756:     }
        !           757:     if (unlikely(rb == 31)) {
        !           758:         tcg_gen_movi_i64(cpu_fir[rc], 0);
        !           759:     } else {
        !           760:         TCGv tmp = tcg_temp_new();
        !           761: 
        !           762:         tcg_gen_andi_i64(tmp, cpu_fir[rb], 0xC0000000);
        !           763:         tcg_gen_andi_i64(cpu_fir[rc], cpu_fir[rb], 0x3FFFFFFF);
        !           764:         tcg_gen_shli_i64(tmp, tmp, 32);
        !           765:         tcg_gen_shli_i64(cpu_fir[rc], cpu_fir[rc], 29);
        !           766:         tcg_gen_or_i64(cpu_fir[rc], cpu_fir[rc], tmp);
        !           767: 
        !           768:         tcg_temp_free(tmp);
        !           769:     }
        !           770: }
        !           771: 
        !           772: static void gen_fcvtql_v(DisasContext *ctx, int rb, int rc)
        !           773: {
        !           774:     if (rb != 31) {
        !           775:         int lab = gen_new_label();
        !           776:         TCGv tmp = tcg_temp_new();
        !           777: 
        !           778:         tcg_gen_ext32s_i64(tmp, cpu_fir[rb]);
        !           779:         tcg_gen_brcond_i64(TCG_COND_EQ, tmp, cpu_fir[rb], lab);
        !           780:         gen_excp(ctx, EXCP_ARITH, EXC_M_IOV);
        !           781: 
        !           782:         gen_set_label(lab);
        !           783:     }
        !           784:     gen_fcvtql(rb, rc);
        !           785: }
        !           786: 
        !           787: #define FARITH2(name)                                   \
        !           788: static inline void glue(gen_f, name)(int rb, int rc)    \
        !           789: {                                                       \
        !           790:     if (unlikely(rc == 31)) {                           \
        !           791:         return;                                         \
        !           792:     }                                                   \
        !           793:     if (rb != 31) {                                     \
        !           794:         gen_helper_ ## name (cpu_fir[rc], cpu_fir[rb]); \
        !           795:     } else {                                           \
        !           796:         TCGv tmp = tcg_const_i64(0);                    \
        !           797:         gen_helper_ ## name (cpu_fir[rc], tmp);         \
        !           798:         tcg_temp_free(tmp);                             \
        !           799:     }                                                   \
        !           800: }
        !           801: 
        !           802: /* ??? VAX instruction qualifiers ignored.  */
1.1.1.2   root      803: FARITH2(sqrtf)
                    804: FARITH2(sqrtg)
                    805: FARITH2(cvtgf)
                    806: FARITH2(cvtgq)
                    807: FARITH2(cvtqf)
                    808: FARITH2(cvtqg)
1.1.1.5 ! root      809: 
        !           810: static void gen_ieee_arith2(DisasContext *ctx, void (*helper)(TCGv, TCGv),
        !           811:                             int rb, int rc, int fn11)
        !           812: {
        !           813:     TCGv vb;
        !           814: 
        !           815:     /* ??? This is wrong: the instruction is not a nop, it still may
        !           816:        raise exceptions.  */
        !           817:     if (unlikely(rc == 31)) {
        !           818:         return;
        !           819:     }
        !           820: 
        !           821:     gen_qual_roundmode(ctx, fn11);
        !           822:     gen_qual_flushzero(ctx, fn11);
        !           823:     gen_fp_exc_clear();
        !           824: 
        !           825:     vb = gen_ieee_input(rb, fn11, 0);
        !           826:     helper(cpu_fir[rc], vb);
        !           827:     tcg_temp_free(vb);
        !           828: 
        !           829:     gen_fp_exc_raise(rc, fn11);
        !           830: }
        !           831: 
        !           832: #define IEEE_ARITH2(name)                                       \
        !           833: static inline void glue(gen_f, name)(DisasContext *ctx,         \
        !           834:                                      int rb, int rc, int fn11)  \
        !           835: {                                                               \
        !           836:     gen_ieee_arith2(ctx, gen_helper_##name, rb, rc, fn11);      \
        !           837: }
        !           838: IEEE_ARITH2(sqrts)
        !           839: IEEE_ARITH2(sqrtt)
        !           840: IEEE_ARITH2(cvtst)
        !           841: IEEE_ARITH2(cvtts)
        !           842: 
        !           843: static void gen_fcvttq(DisasContext *ctx, int rb, int rc, int fn11)
        !           844: {
        !           845:     TCGv vb;
        !           846:     int ignore = 0;
        !           847: 
        !           848:     /* ??? This is wrong: the instruction is not a nop, it still may
        !           849:        raise exceptions.  */
        !           850:     if (unlikely(rc == 31)) {
        !           851:         return;
        !           852:     }
        !           853: 
        !           854:     /* No need to set flushzero, since we have an integer output.  */
        !           855:     gen_fp_exc_clear();
        !           856:     vb = gen_ieee_input(rb, fn11, 0);
        !           857: 
        !           858:     /* Almost all integer conversions use cropped rounding, and most
        !           859:        also do not have integer overflow enabled.  Special case that.  */
        !           860:     switch (fn11) {
        !           861:     case QUAL_RM_C:
        !           862:         gen_helper_cvttq_c(cpu_fir[rc], vb);
        !           863:         break;
        !           864:     case QUAL_V | QUAL_RM_C:
        !           865:     case QUAL_S | QUAL_V | QUAL_RM_C:
        !           866:         ignore = float_flag_inexact;
        !           867:         /* FALLTHRU */
        !           868:     case QUAL_S | QUAL_V | QUAL_I | QUAL_RM_C:
        !           869:         gen_helper_cvttq_svic(cpu_fir[rc], vb);
        !           870:         break;
        !           871:     default:
        !           872:         gen_qual_roundmode(ctx, fn11);
        !           873:         gen_helper_cvttq(cpu_fir[rc], vb);
        !           874:         ignore |= (fn11 & QUAL_V ? 0 : float_flag_overflow);
        !           875:         ignore |= (fn11 & QUAL_I ? 0 : float_flag_inexact);
        !           876:         break;
        !           877:     }
        !           878:     tcg_temp_free(vb);
        !           879: 
        !           880:     gen_fp_exc_raise_ignore(rc, fn11, ignore);
        !           881: }
        !           882: 
        !           883: static void gen_ieee_intcvt(DisasContext *ctx, void (*helper)(TCGv, TCGv),
        !           884:                            int rb, int rc, int fn11)
        !           885: {
        !           886:     TCGv vb;
        !           887: 
        !           888:     /* ??? This is wrong: the instruction is not a nop, it still may
        !           889:        raise exceptions.  */
        !           890:     if (unlikely(rc == 31)) {
        !           891:         return;
        !           892:     }
        !           893: 
        !           894:     gen_qual_roundmode(ctx, fn11);
        !           895: 
        !           896:     if (rb == 31) {
        !           897:         vb = tcg_const_i64(0);
        !           898:     } else {
        !           899:         vb = cpu_fir[rb];
        !           900:     }
        !           901: 
        !           902:     /* The only exception that can be raised by integer conversion
        !           903:        is inexact.  Thus we only need to worry about exceptions when
        !           904:        inexact handling is requested.  */
        !           905:     if (fn11 & QUAL_I) {
        !           906:         gen_fp_exc_clear();
        !           907:         helper(cpu_fir[rc], vb);
        !           908:         gen_fp_exc_raise(rc, fn11);
        !           909:     } else {
        !           910:         helper(cpu_fir[rc], vb);
        !           911:     }
        !           912: 
        !           913:     if (rb == 31) {
        !           914:         tcg_temp_free(vb);
        !           915:     }
        !           916: }
        !           917: 
        !           918: #define IEEE_INTCVT(name)                                       \
        !           919: static inline void glue(gen_f, name)(DisasContext *ctx,         \
        !           920:                                      int rb, int rc, int fn11)  \
        !           921: {                                                               \
        !           922:     gen_ieee_intcvt(ctx, gen_helper_##name, rb, rc, fn11);      \
        !           923: }
        !           924: IEEE_INTCVT(cvtqs)
        !           925: IEEE_INTCVT(cvtqt)
        !           926: 
        !           927: static void gen_cpys_internal(int ra, int rb, int rc, int inv_a, uint64_t mask)
        !           928: {
        !           929:     TCGv va, vb, vmask;
        !           930:     int za = 0, zb = 0;
        !           931: 
        !           932:     if (unlikely(rc == 31)) {
        !           933:         return;
        !           934:     }
        !           935: 
        !           936:     vmask = tcg_const_i64(mask);
        !           937: 
        !           938:     TCGV_UNUSED_I64(va);
        !           939:     if (ra == 31) {
        !           940:         if (inv_a) {
        !           941:             va = vmask;
        !           942:         } else {
        !           943:             za = 1;
        !           944:         }
        !           945:     } else {
        !           946:         va = tcg_temp_new_i64();
        !           947:         tcg_gen_mov_i64(va, cpu_fir[ra]);
        !           948:         if (inv_a) {
        !           949:             tcg_gen_andc_i64(va, vmask, va);
        !           950:         } else {
        !           951:             tcg_gen_and_i64(va, va, vmask);
        !           952:         }
        !           953:     }
        !           954: 
        !           955:     TCGV_UNUSED_I64(vb);
        !           956:     if (rb == 31) {
        !           957:         zb = 1;
        !           958:     } else {
        !           959:         vb = tcg_temp_new_i64();
        !           960:         tcg_gen_andc_i64(vb, cpu_fir[rb], vmask);
        !           961:     }
        !           962: 
        !           963:     switch (za << 1 | zb) {
        !           964:     case 0 | 0:
        !           965:         tcg_gen_or_i64(cpu_fir[rc], va, vb);
        !           966:         break;
        !           967:     case 0 | 1:
        !           968:         tcg_gen_mov_i64(cpu_fir[rc], va);
        !           969:         break;
        !           970:     case 2 | 0:
        !           971:         tcg_gen_mov_i64(cpu_fir[rc], vb);
        !           972:         break;
        !           973:     case 2 | 1:
        !           974:         tcg_gen_movi_i64(cpu_fir[rc], 0);
        !           975:         break;
        !           976:     }
        !           977: 
        !           978:     tcg_temp_free(vmask);
        !           979:     if (ra != 31) {
        !           980:         tcg_temp_free(va);
        !           981:     }
        !           982:     if (rb != 31) {
        !           983:         tcg_temp_free(vb);
        !           984:     }
        !           985: }
        !           986: 
        !           987: static inline void gen_fcpys(int ra, int rb, int rc)
        !           988: {
        !           989:     gen_cpys_internal(ra, rb, rc, 0, 0x8000000000000000ULL);
1.1.1.2   root      990: }
                    991: 
1.1.1.5 ! root      992: static inline void gen_fcpysn(int ra, int rb, int rc)
        !           993: {
        !           994:     gen_cpys_internal(ra, rb, rc, 1, 0x8000000000000000ULL);
        !           995: }
        !           996: 
        !           997: static inline void gen_fcpyse(int ra, int rb, int rc)
        !           998: {
        !           999:     gen_cpys_internal(ra, rb, rc, 0, 0xFFF0000000000000ULL);
        !          1000: }
        !          1001: 
        !          1002: #define FARITH3(name)                                           \
        !          1003: static inline void glue(gen_f, name)(int ra, int rb, int rc)    \
        !          1004: {                                                               \
        !          1005:     TCGv va, vb;                                                \
        !          1006:                                                                 \
        !          1007:     if (unlikely(rc == 31)) {                                   \
        !          1008:         return;                                                 \
        !          1009:     }                                                           \
        !          1010:     if (ra == 31) {                                             \
        !          1011:         va = tcg_const_i64(0);                                  \
        !          1012:     } else {                                                    \
        !          1013:         va = cpu_fir[ra];                                       \
        !          1014:     }                                                           \
        !          1015:     if (rb == 31) {                                             \
        !          1016:         vb = tcg_const_i64(0);                                  \
        !          1017:     } else {                                                    \
        !          1018:         vb = cpu_fir[rb];                                       \
        !          1019:     }                                                           \
        !          1020:                                                                 \
        !          1021:     gen_helper_ ## name (cpu_fir[rc], va, vb);                  \
        !          1022:                                                                 \
        !          1023:     if (ra == 31) {                                             \
        !          1024:         tcg_temp_free(va);                                      \
        !          1025:     }                                                           \
        !          1026:     if (rb == 31) {                                             \
        !          1027:         tcg_temp_free(vb);                                      \
        !          1028:     }                                                           \
        !          1029: }
        !          1030: 
        !          1031: /* ??? VAX instruction qualifiers ignored.  */
1.1.1.2   root     1032: FARITH3(addf)
                   1033: FARITH3(subf)
                   1034: FARITH3(mulf)
                   1035: FARITH3(divf)
                   1036: FARITH3(addg)
                   1037: FARITH3(subg)
                   1038: FARITH3(mulg)
                   1039: FARITH3(divg)
                   1040: FARITH3(cmpgeq)
                   1041: FARITH3(cmpglt)
                   1042: FARITH3(cmpgle)
                   1043: 
1.1.1.5 ! root     1044: static void gen_ieee_arith3(DisasContext *ctx,
        !          1045:                             void (*helper)(TCGv, TCGv, TCGv),
        !          1046:                             int ra, int rb, int rc, int fn11)
        !          1047: {
        !          1048:     TCGv va, vb;
        !          1049: 
        !          1050:     /* ??? This is wrong: the instruction is not a nop, it still may
        !          1051:        raise exceptions.  */
        !          1052:     if (unlikely(rc == 31)) {
        !          1053:         return;
        !          1054:     }
        !          1055: 
        !          1056:     gen_qual_roundmode(ctx, fn11);
        !          1057:     gen_qual_flushzero(ctx, fn11);
        !          1058:     gen_fp_exc_clear();
        !          1059: 
        !          1060:     va = gen_ieee_input(ra, fn11, 0);
        !          1061:     vb = gen_ieee_input(rb, fn11, 0);
        !          1062:     helper(cpu_fir[rc], va, vb);
        !          1063:     tcg_temp_free(va);
        !          1064:     tcg_temp_free(vb);
        !          1065: 
        !          1066:     gen_fp_exc_raise(rc, fn11);
        !          1067: }
        !          1068: 
        !          1069: #define IEEE_ARITH3(name)                                               \
        !          1070: static inline void glue(gen_f, name)(DisasContext *ctx,                 \
        !          1071:                                      int ra, int rb, int rc, int fn11)  \
        !          1072: {                                                                       \
        !          1073:     gen_ieee_arith3(ctx, gen_helper_##name, ra, rb, rc, fn11);          \
        !          1074: }
        !          1075: IEEE_ARITH3(adds)
        !          1076: IEEE_ARITH3(subs)
        !          1077: IEEE_ARITH3(muls)
        !          1078: IEEE_ARITH3(divs)
        !          1079: IEEE_ARITH3(addt)
        !          1080: IEEE_ARITH3(subt)
        !          1081: IEEE_ARITH3(mult)
        !          1082: IEEE_ARITH3(divt)
        !          1083: 
        !          1084: static void gen_ieee_compare(DisasContext *ctx,
        !          1085:                              void (*helper)(TCGv, TCGv, TCGv),
        !          1086:                              int ra, int rb, int rc, int fn11)
        !          1087: {
        !          1088:     TCGv va, vb;
        !          1089: 
        !          1090:     /* ??? This is wrong: the instruction is not a nop, it still may
        !          1091:        raise exceptions.  */
        !          1092:     if (unlikely(rc == 31)) {
        !          1093:         return;
        !          1094:     }
        !          1095: 
        !          1096:     gen_fp_exc_clear();
        !          1097: 
        !          1098:     va = gen_ieee_input(ra, fn11, 1);
        !          1099:     vb = gen_ieee_input(rb, fn11, 1);
        !          1100:     helper(cpu_fir[rc], va, vb);
        !          1101:     tcg_temp_free(va);
        !          1102:     tcg_temp_free(vb);
        !          1103: 
        !          1104:     gen_fp_exc_raise(rc, fn11);
        !          1105: }
        !          1106: 
        !          1107: #define IEEE_CMP3(name)                                                 \
        !          1108: static inline void glue(gen_f, name)(DisasContext *ctx,                 \
        !          1109:                                      int ra, int rb, int rc, int fn11)  \
        !          1110: {                                                                       \
        !          1111:     gen_ieee_compare(ctx, gen_helper_##name, ra, rb, rc, fn11);         \
        !          1112: }
        !          1113: IEEE_CMP3(cmptun)
        !          1114: IEEE_CMP3(cmpteq)
        !          1115: IEEE_CMP3(cmptlt)
        !          1116: IEEE_CMP3(cmptle)
        !          1117: 
        !          1118: static inline uint64_t zapnot_mask(uint8_t lit)
        !          1119: {
        !          1120:     uint64_t mask = 0;
        !          1121:     int i;
        !          1122: 
        !          1123:     for (i = 0; i < 8; ++i) {
        !          1124:         if ((lit >> i) & 1)
        !          1125:             mask |= 0xffull << (i * 8);
        !          1126:     }
        !          1127:     return mask;
        !          1128: }
        !          1129: 
        !          1130: /* Implement zapnot with an immediate operand, which expands to some
        !          1131:    form of immediate AND.  This is a basic building block in the
        !          1132:    definition of many of the other byte manipulation instructions.  */
        !          1133: static void gen_zapnoti(TCGv dest, TCGv src, uint8_t lit)
        !          1134: {
        !          1135:     switch (lit) {
        !          1136:     case 0x00:
        !          1137:         tcg_gen_movi_i64(dest, 0);
        !          1138:         break;
        !          1139:     case 0x01:
        !          1140:         tcg_gen_ext8u_i64(dest, src);
        !          1141:         break;
        !          1142:     case 0x03:
        !          1143:         tcg_gen_ext16u_i64(dest, src);
        !          1144:         break;
        !          1145:     case 0x0f:
        !          1146:         tcg_gen_ext32u_i64(dest, src);
        !          1147:         break;
        !          1148:     case 0xff:
        !          1149:         tcg_gen_mov_i64(dest, src);
        !          1150:         break;
        !          1151:     default:
        !          1152:         tcg_gen_andi_i64 (dest, src, zapnot_mask (lit));
        !          1153:         break;
        !          1154:     }
        !          1155: }
        !          1156: 
        !          1157: static inline void gen_zapnot(int ra, int rb, int rc, int islit, uint8_t lit)
1.1       root     1158: {
1.1.1.2   root     1159:     if (unlikely(rc == 31))
                   1160:         return;
1.1.1.5 ! root     1161:     else if (unlikely(ra == 31))
        !          1162:         tcg_gen_movi_i64(cpu_ir[rc], 0);
        !          1163:     else if (islit)
        !          1164:         gen_zapnoti(cpu_ir[rc], cpu_ir[ra], lit);
        !          1165:     else
        !          1166:         gen_helper_zapnot (cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
        !          1167: }
1.1       root     1168: 
1.1.1.5 ! root     1169: static inline void gen_zap(int ra, int rb, int rc, int islit, uint8_t lit)
        !          1170: {
        !          1171:     if (unlikely(rc == 31))
        !          1172:         return;
        !          1173:     else if (unlikely(ra == 31))
        !          1174:         tcg_gen_movi_i64(cpu_ir[rc], 0);
        !          1175:     else if (islit)
        !          1176:         gen_zapnoti(cpu_ir[rc], cpu_ir[ra], ~lit);
        !          1177:     else
        !          1178:         gen_helper_zap (cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
        !          1179: }
        !          1180: 
        !          1181: 
        !          1182: /* EXTWH, EXTLH, EXTQH */
        !          1183: static void gen_ext_h(int ra, int rb, int rc, int islit,
        !          1184:                       uint8_t lit, uint8_t byte_mask)
        !          1185: {
        !          1186:     if (unlikely(rc == 31))
        !          1187:         return;
        !          1188:     else if (unlikely(ra == 31))
        !          1189:         tcg_gen_movi_i64(cpu_ir[rc], 0);
        !          1190:     else {
1.1.1.2   root     1191:         if (islit) {
1.1.1.5 ! root     1192:             lit = (64 - (lit & 7) * 8) & 0x3f;
        !          1193:             tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], lit);
1.1.1.2   root     1194:         } else {
1.1.1.5 ! root     1195:             TCGv tmp1 = tcg_temp_new();
1.1.1.2   root     1196:             tcg_gen_andi_i64(tmp1, cpu_ir[rb], 7);
                   1197:             tcg_gen_shli_i64(tmp1, tmp1, 3);
1.1.1.3   root     1198:             tcg_gen_neg_i64(tmp1, tmp1);
                   1199:             tcg_gen_andi_i64(tmp1, tmp1, 0x3f);
1.1.1.2   root     1200:             tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], tmp1);
                   1201:             tcg_temp_free(tmp1);
                   1202:         }
1.1.1.5 ! root     1203:         gen_zapnoti(cpu_ir[rc], cpu_ir[rc], byte_mask);
        !          1204:     }
1.1       root     1205: }
                   1206: 
1.1.1.5 ! root     1207: /* EXTBL, EXTWL, EXTLL, EXTQL */
        !          1208: static void gen_ext_l(int ra, int rb, int rc, int islit,
        !          1209:                       uint8_t lit, uint8_t byte_mask)
1.1       root     1210: {
1.1.1.2   root     1211:     if (unlikely(rc == 31))
                   1212:         return;
1.1.1.5 ! root     1213:     else if (unlikely(ra == 31))
        !          1214:         tcg_gen_movi_i64(cpu_ir[rc], 0);
        !          1215:     else {
1.1.1.2   root     1216:         if (islit) {
1.1.1.5 ! root     1217:             tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[ra], (lit & 7) * 8);
1.1.1.2   root     1218:         } else {
                   1219:             TCGv tmp = tcg_temp_new();
                   1220:             tcg_gen_andi_i64(tmp, cpu_ir[rb], 7);
                   1221:             tcg_gen_shli_i64(tmp, tmp, 3);
                   1222:             tcg_gen_shr_i64(cpu_ir[rc], cpu_ir[ra], tmp);
                   1223:             tcg_temp_free(tmp);
                   1224:         }
1.1.1.5 ! root     1225:         gen_zapnoti(cpu_ir[rc], cpu_ir[rc], byte_mask);
        !          1226:     }
        !          1227: }
        !          1228: 
        !          1229: /* INSWH, INSLH, INSQH */
        !          1230: static void gen_ins_h(int ra, int rb, int rc, int islit,
        !          1231:                       uint8_t lit, uint8_t byte_mask)
        !          1232: {
        !          1233:     if (unlikely(rc == 31))
        !          1234:         return;
        !          1235:     else if (unlikely(ra == 31) || (islit && (lit & 7) == 0))
        !          1236:         tcg_gen_movi_i64(cpu_ir[rc], 0);
        !          1237:     else {
        !          1238:         TCGv tmp = tcg_temp_new();
        !          1239: 
        !          1240:         /* The instruction description has us left-shift the byte mask
        !          1241:            and extract bits <15:8> and apply that zap at the end.  This
        !          1242:            is equivalent to simply performing the zap first and shifting
        !          1243:            afterward.  */
        !          1244:         gen_zapnoti (tmp, cpu_ir[ra], byte_mask);
        !          1245: 
        !          1246:         if (islit) {
        !          1247:             /* Note that we have handled the lit==0 case above.  */
        !          1248:             tcg_gen_shri_i64 (cpu_ir[rc], tmp, 64 - (lit & 7) * 8);
        !          1249:         } else {
        !          1250:             TCGv shift = tcg_temp_new();
        !          1251: 
        !          1252:             /* If (B & 7) == 0, we need to shift by 64 and leave a zero.
        !          1253:                Do this portably by splitting the shift into two parts:
        !          1254:                shift_count-1 and 1.  Arrange for the -1 by using
        !          1255:                ones-complement instead of twos-complement in the negation:
        !          1256:                ~((B & 7) * 8) & 63.  */
        !          1257: 
        !          1258:             tcg_gen_andi_i64(shift, cpu_ir[rb], 7);
        !          1259:             tcg_gen_shli_i64(shift, shift, 3);
        !          1260:             tcg_gen_not_i64(shift, shift);
        !          1261:             tcg_gen_andi_i64(shift, shift, 0x3f);
        !          1262: 
        !          1263:             tcg_gen_shr_i64(cpu_ir[rc], tmp, shift);
        !          1264:             tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[rc], 1);
        !          1265:             tcg_temp_free(shift);
        !          1266:         }
        !          1267:         tcg_temp_free(tmp);
        !          1268:     }
        !          1269: }
        !          1270: 
        !          1271: /* INSBL, INSWL, INSLL, INSQL */
        !          1272: static void gen_ins_l(int ra, int rb, int rc, int islit,
        !          1273:                       uint8_t lit, uint8_t byte_mask)
        !          1274: {
        !          1275:     if (unlikely(rc == 31))
        !          1276:         return;
        !          1277:     else if (unlikely(ra == 31))
        !          1278:         tcg_gen_movi_i64(cpu_ir[rc], 0);
        !          1279:     else {
        !          1280:         TCGv tmp = tcg_temp_new();
        !          1281: 
        !          1282:         /* The instruction description has us left-shift the byte mask
        !          1283:            the same number of byte slots as the data and apply the zap
        !          1284:            at the end.  This is equivalent to simply performing the zap
        !          1285:            first and shifting afterward.  */
        !          1286:         gen_zapnoti (tmp, cpu_ir[ra], byte_mask);
        !          1287: 
        !          1288:         if (islit) {
        !          1289:             tcg_gen_shli_i64(cpu_ir[rc], tmp, (lit & 7) * 8);
        !          1290:         } else {
        !          1291:             TCGv shift = tcg_temp_new();
        !          1292:             tcg_gen_andi_i64(shift, cpu_ir[rb], 7);
        !          1293:             tcg_gen_shli_i64(shift, shift, 3);
        !          1294:             tcg_gen_shl_i64(cpu_ir[rc], tmp, shift);
        !          1295:             tcg_temp_free(shift);
        !          1296:         }
        !          1297:         tcg_temp_free(tmp);
        !          1298:     }
        !          1299: }
        !          1300: 
        !          1301: /* MSKWH, MSKLH, MSKQH */
        !          1302: static void gen_msk_h(int ra, int rb, int rc, int islit,
        !          1303:                       uint8_t lit, uint8_t byte_mask)
        !          1304: {
        !          1305:     if (unlikely(rc == 31))
        !          1306:         return;
        !          1307:     else if (unlikely(ra == 31))
        !          1308:         tcg_gen_movi_i64(cpu_ir[rc], 0);
        !          1309:     else if (islit) {
        !          1310:         gen_zapnoti (cpu_ir[rc], cpu_ir[ra], ~((byte_mask << (lit & 7)) >> 8));
        !          1311:     } else {
        !          1312:         TCGv shift = tcg_temp_new();
        !          1313:         TCGv mask = tcg_temp_new();
        !          1314: 
        !          1315:         /* The instruction description is as above, where the byte_mask
        !          1316:            is shifted left, and then we extract bits <15:8>.  This can be
        !          1317:            emulated with a right-shift on the expanded byte mask.  This
        !          1318:            requires extra care because for an input <2:0> == 0 we need a
        !          1319:            shift of 64 bits in order to generate a zero.  This is done by
        !          1320:            splitting the shift into two parts, the variable shift - 1
        !          1321:            followed by a constant 1 shift.  The code we expand below is
        !          1322:            equivalent to ~((B & 7) * 8) & 63.  */
        !          1323: 
        !          1324:         tcg_gen_andi_i64(shift, cpu_ir[rb], 7);
        !          1325:         tcg_gen_shli_i64(shift, shift, 3);
        !          1326:         tcg_gen_not_i64(shift, shift);
        !          1327:         tcg_gen_andi_i64(shift, shift, 0x3f);
        !          1328:         tcg_gen_movi_i64(mask, zapnot_mask (byte_mask));
        !          1329:         tcg_gen_shr_i64(mask, mask, shift);
        !          1330:         tcg_gen_shri_i64(mask, mask, 1);
        !          1331: 
        !          1332:         tcg_gen_andc_i64(cpu_ir[rc], cpu_ir[ra], mask);
        !          1333: 
        !          1334:         tcg_temp_free(mask);
        !          1335:         tcg_temp_free(shift);
        !          1336:     }
        !          1337: }
        !          1338: 
        !          1339: /* MSKBL, MSKWL, MSKLL, MSKQL */
        !          1340: static void gen_msk_l(int ra, int rb, int rc, int islit,
        !          1341:                       uint8_t lit, uint8_t byte_mask)
        !          1342: {
        !          1343:     if (unlikely(rc == 31))
        !          1344:         return;
        !          1345:     else if (unlikely(ra == 31))
1.1.1.2   root     1346:         tcg_gen_movi_i64(cpu_ir[rc], 0);
1.1.1.5 ! root     1347:     else if (islit) {
        !          1348:         gen_zapnoti (cpu_ir[rc], cpu_ir[ra], ~(byte_mask << (lit & 7)));
        !          1349:     } else {
        !          1350:         TCGv shift = tcg_temp_new();
        !          1351:         TCGv mask = tcg_temp_new();
        !          1352: 
        !          1353:         tcg_gen_andi_i64(shift, cpu_ir[rb], 7);
        !          1354:         tcg_gen_shli_i64(shift, shift, 3);
        !          1355:         tcg_gen_movi_i64(mask, zapnot_mask (byte_mask));
        !          1356:         tcg_gen_shl_i64(mask, mask, shift);
        !          1357: 
        !          1358:         tcg_gen_andc_i64(cpu_ir[rc], cpu_ir[ra], mask);
        !          1359: 
        !          1360:         tcg_temp_free(mask);
        !          1361:         tcg_temp_free(shift);
        !          1362:     }
1.1.1.2   root     1363: }
                   1364: 
                   1365: /* Code to call arith3 helpers */
                   1366: #define ARITH3(name)                                                  \
1.1.1.4   root     1367: static inline void glue(gen_, name)(int ra, int rb, int rc, int islit,\
                   1368:                                     uint8_t lit)                      \
1.1.1.2   root     1369: {                                                                     \
                   1370:     if (unlikely(rc == 31))                                           \
                   1371:         return;                                                       \
                   1372:                                                                       \
                   1373:     if (ra != 31) {                                                   \
                   1374:         if (islit) {                                                  \
                   1375:             TCGv tmp = tcg_const_i64(lit);                            \
                   1376:             gen_helper_ ## name(cpu_ir[rc], cpu_ir[ra], tmp);         \
                   1377:             tcg_temp_free(tmp);                                       \
                   1378:         } else                                                        \
                   1379:             gen_helper_ ## name (cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]); \
                   1380:     } else {                                                          \
                   1381:         TCGv tmp1 = tcg_const_i64(0);                                 \
                   1382:         if (islit) {                                                  \
                   1383:             TCGv tmp2 = tcg_const_i64(lit);                           \
                   1384:             gen_helper_ ## name (cpu_ir[rc], tmp1, tmp2);             \
                   1385:             tcg_temp_free(tmp2);                                      \
                   1386:         } else                                                        \
                   1387:             gen_helper_ ## name (cpu_ir[rc], tmp1, cpu_ir[rb]);       \
                   1388:         tcg_temp_free(tmp1);                                          \
                   1389:     }                                                                 \
                   1390: }
                   1391: ARITH3(cmpbge)
                   1392: ARITH3(addlv)
                   1393: ARITH3(sublv)
                   1394: ARITH3(addqv)
                   1395: ARITH3(subqv)
                   1396: ARITH3(umulh)
                   1397: ARITH3(mullv)
                   1398: ARITH3(mulqv)
1.1.1.5 ! root     1399: ARITH3(minub8)
        !          1400: ARITH3(minsb8)
        !          1401: ARITH3(minuw4)
        !          1402: ARITH3(minsw4)
        !          1403: ARITH3(maxub8)
        !          1404: ARITH3(maxsb8)
        !          1405: ARITH3(maxuw4)
        !          1406: ARITH3(maxsw4)
        !          1407: ARITH3(perr)
        !          1408: 
        !          1409: #define MVIOP2(name)                                    \
        !          1410: static inline void glue(gen_, name)(int rb, int rc)     \
        !          1411: {                                                       \
        !          1412:     if (unlikely(rc == 31))                             \
        !          1413:         return;                                         \
        !          1414:     if (unlikely(rb == 31))                             \
        !          1415:         tcg_gen_movi_i64(cpu_ir[rc], 0);                \
        !          1416:     else                                                \
        !          1417:         gen_helper_ ## name (cpu_ir[rc], cpu_ir[rb]);   \
        !          1418: }
        !          1419: MVIOP2(pklb)
        !          1420: MVIOP2(pkwb)
        !          1421: MVIOP2(unpkbl)
        !          1422: MVIOP2(unpkbw)
1.1.1.2   root     1423: 
1.1.1.5 ! root     1424: static void gen_cmp(TCGCond cond, int ra, int rb, int rc,
        !          1425:                     int islit, uint8_t lit)
1.1.1.2   root     1426: {
1.1.1.5 ! root     1427:     TCGv va, vb;
1.1.1.2   root     1428: 
1.1.1.5 ! root     1429:     if (unlikely(rc == 31)) {
        !          1430:         return;
        !          1431:     }
1.1.1.2   root     1432: 
1.1.1.5 ! root     1433:     if (ra == 31) {
        !          1434:         va = tcg_const_i64(0);
        !          1435:     } else {
        !          1436:         va = cpu_ir[ra];
        !          1437:     }
        !          1438:     if (islit) {
        !          1439:         vb = tcg_const_i64(lit);
        !          1440:     } else {
        !          1441:         vb = cpu_ir[rb];
        !          1442:     }
        !          1443: 
        !          1444:     tcg_gen_setcond_i64(cond, cpu_ir[rc], va, vb);
        !          1445: 
        !          1446:     if (ra == 31) {
        !          1447:         tcg_temp_free(va);
        !          1448:     }
        !          1449:     if (islit) {
        !          1450:         tcg_temp_free(vb);
        !          1451:     }
        !          1452: }
        !          1453: 
        !          1454: static void gen_rx(int ra, int set)
        !          1455: {
        !          1456:     TCGv_i32 tmp;
1.1.1.2   root     1457: 
                   1458:     if (ra != 31) {
1.1.1.5 ! root     1459:         tcg_gen_ld8u_i64(cpu_ir[ra], cpu_env, offsetof(CPUState, intr_flag));
        !          1460:     }
1.1       root     1461: 
1.1.1.5 ! root     1462:     tmp = tcg_const_i32(set);
        !          1463:     tcg_gen_st8_i32(tmp, cpu_env, offsetof(CPUState, intr_flag));
        !          1464:     tcg_temp_free_i32(tmp);
1.1       root     1465: }
                   1466: 
1.1.1.5 ! root     1467: static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
1.1       root     1468: {
                   1469:     uint32_t palcode;
                   1470:     int32_t disp21, disp16, disp12;
1.1.1.5 ! root     1471:     uint16_t fn11;
        !          1472:     uint8_t opc, ra, rb, rc, fpfn, fn7, fn2, islit, real_islit;
1.1.1.2   root     1473:     uint8_t lit;
1.1.1.5 ! root     1474:     ExitStatus ret;
1.1       root     1475: 
                   1476:     /* Decode all instruction fields */
                   1477:     opc = insn >> 26;
                   1478:     ra = (insn >> 21) & 0x1F;
                   1479:     rb = (insn >> 16) & 0x1F;
                   1480:     rc = insn & 0x1F;
1.1.1.5 ! root     1481:     real_islit = islit = (insn >> 12) & 1;
1.1.1.2   root     1482:     if (rb == 31 && !islit) {
                   1483:         islit = 1;
                   1484:         lit = 0;
                   1485:     } else
                   1486:         lit = (insn >> 13) & 0xFF;
1.1       root     1487:     palcode = insn & 0x03FFFFFF;
                   1488:     disp21 = ((int32_t)((insn & 0x001FFFFF) << 11)) >> 11;
                   1489:     disp16 = (int16_t)(insn & 0x0000FFFF);
                   1490:     disp12 = (int32_t)((insn & 0x00000FFF) << 20) >> 20;
                   1491:     fn11 = (insn >> 5) & 0x000007FF;
                   1492:     fpfn = fn11 & 0x3F;
                   1493:     fn7 = (insn >> 5) & 0x0000007F;
                   1494:     fn2 = (insn >> 5) & 0x00000003;
1.1.1.5 ! root     1495:     LOG_DISAS("opc %02x ra %2d rb %2d rc %2d disp16 %6d\n",
1.1.1.2   root     1496:               opc, ra, rb, rc, disp16);
1.1.1.5 ! root     1497: 
        !          1498:     ret = NO_EXIT;
1.1       root     1499:     switch (opc) {
                   1500:     case 0x00:
                   1501:         /* CALL_PAL */
1.1.1.5 ! root     1502: #ifdef CONFIG_USER_ONLY
        !          1503:         if (palcode == 0x9E) {
        !          1504:             /* RDUNIQUE */
        !          1505:             tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_uniq);
        !          1506:             break;
        !          1507:         } else if (palcode == 0x9F) {
        !          1508:             /* WRUNIQUE */
        !          1509:             tcg_gen_mov_i64(cpu_uniq, cpu_ir[IR_A0]);
        !          1510:             break;
        !          1511:         }
        !          1512: #endif
1.1       root     1513:         if (palcode >= 0x80 && palcode < 0xC0) {
                   1514:             /* Unprivileged PAL call */
1.1.1.5 ! root     1515:             ret = gen_excp(ctx, EXCP_CALL_PAL + ((palcode & 0x3F) << 6), 0);
        !          1516:             break;
        !          1517:         }
        !          1518: #ifndef CONFIG_USER_ONLY
        !          1519:         if (palcode < 0x40) {
1.1       root     1520:             /* Privileged PAL code */
                   1521:             if (ctx->mem_idx & 1)
                   1522:                 goto invalid_opc;
1.1.1.5 ! root     1523:             ret = gen_excp(ctx, EXCP_CALL_PALP + ((palcode & 0x3F) << 6), 0);
1.1       root     1524:         }
1.1.1.5 ! root     1525: #endif
        !          1526:         /* Invalid PAL call */
        !          1527:         goto invalid_opc;
1.1       root     1528:     case 0x01:
                   1529:         /* OPC01 */
                   1530:         goto invalid_opc;
                   1531:     case 0x02:
                   1532:         /* OPC02 */
                   1533:         goto invalid_opc;
                   1534:     case 0x03:
                   1535:         /* OPC03 */
                   1536:         goto invalid_opc;
                   1537:     case 0x04:
                   1538:         /* OPC04 */
                   1539:         goto invalid_opc;
                   1540:     case 0x05:
                   1541:         /* OPC05 */
                   1542:         goto invalid_opc;
                   1543:     case 0x06:
                   1544:         /* OPC06 */
                   1545:         goto invalid_opc;
                   1546:     case 0x07:
                   1547:         /* OPC07 */
                   1548:         goto invalid_opc;
                   1549:     case 0x08:
                   1550:         /* LDA */
1.1.1.2   root     1551:         if (likely(ra != 31)) {
                   1552:             if (rb != 31)
                   1553:                 tcg_gen_addi_i64(cpu_ir[ra], cpu_ir[rb], disp16);
                   1554:             else
                   1555:                 tcg_gen_movi_i64(cpu_ir[ra], disp16);
                   1556:         }
1.1       root     1557:         break;
                   1558:     case 0x09:
                   1559:         /* LDAH */
1.1.1.2   root     1560:         if (likely(ra != 31)) {
                   1561:             if (rb != 31)
                   1562:                 tcg_gen_addi_i64(cpu_ir[ra], cpu_ir[rb], disp16 << 16);
                   1563:             else
                   1564:                 tcg_gen_movi_i64(cpu_ir[ra], disp16 << 16);
                   1565:         }
1.1       root     1566:         break;
                   1567:     case 0x0A:
                   1568:         /* LDBU */
                   1569:         if (!(ctx->amask & AMASK_BWX))
                   1570:             goto invalid_opc;
1.1.1.2   root     1571:         gen_load_mem(ctx, &tcg_gen_qemu_ld8u, ra, rb, disp16, 0, 0);
1.1       root     1572:         break;
                   1573:     case 0x0B:
                   1574:         /* LDQ_U */
1.1.1.2   root     1575:         gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 1);
1.1       root     1576:         break;
                   1577:     case 0x0C:
                   1578:         /* LDWU */
                   1579:         if (!(ctx->amask & AMASK_BWX))
                   1580:             goto invalid_opc;
1.1.1.3   root     1581:         gen_load_mem(ctx, &tcg_gen_qemu_ld16u, ra, rb, disp16, 0, 0);
1.1       root     1582:         break;
                   1583:     case 0x0D:
                   1584:         /* STW */
1.1.1.5 ! root     1585:         gen_store_mem(ctx, &tcg_gen_qemu_st16, ra, rb, disp16, 0, 0);
1.1       root     1586:         break;
                   1587:     case 0x0E:
                   1588:         /* STB */
1.1.1.5 ! root     1589:         gen_store_mem(ctx, &tcg_gen_qemu_st8, ra, rb, disp16, 0, 0);
1.1       root     1590:         break;
                   1591:     case 0x0F:
                   1592:         /* STQ_U */
1.1.1.5 ! root     1593:         gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 1);
1.1       root     1594:         break;
                   1595:     case 0x10:
                   1596:         switch (fn7) {
                   1597:         case 0x00:
                   1598:             /* ADDL */
1.1.1.2   root     1599:             if (likely(rc != 31)) {
                   1600:                 if (ra != 31) {
                   1601:                     if (islit) {
                   1602:                         tcg_gen_addi_i64(cpu_ir[rc], cpu_ir[ra], lit);
                   1603:                         tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
                   1604:                     } else {
                   1605:                         tcg_gen_add_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
                   1606:                         tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
                   1607:                     }
                   1608:                 } else {
                   1609:                     if (islit)
                   1610:                         tcg_gen_movi_i64(cpu_ir[rc], lit);
                   1611:                     else
                   1612:                         tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
                   1613:                 }
                   1614:             }
1.1       root     1615:             break;
                   1616:         case 0x02:
                   1617:             /* S4ADDL */
1.1.1.2   root     1618:             if (likely(rc != 31)) {
                   1619:                 if (ra != 31) {
                   1620:                     TCGv tmp = tcg_temp_new();
                   1621:                     tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
                   1622:                     if (islit)
                   1623:                         tcg_gen_addi_i64(tmp, tmp, lit);
                   1624:                     else
                   1625:                         tcg_gen_add_i64(tmp, tmp, cpu_ir[rb]);
                   1626:                     tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
                   1627:                     tcg_temp_free(tmp);
                   1628:                 } else {
                   1629:                     if (islit)
                   1630:                         tcg_gen_movi_i64(cpu_ir[rc], lit);
                   1631:                     else
                   1632:                         tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
                   1633:                 }
                   1634:             }
1.1       root     1635:             break;
                   1636:         case 0x09:
                   1637:             /* SUBL */
1.1.1.2   root     1638:             if (likely(rc != 31)) {
                   1639:                 if (ra != 31) {
                   1640:                     if (islit)
                   1641:                         tcg_gen_subi_i64(cpu_ir[rc], cpu_ir[ra], lit);
                   1642:                     else
                   1643:                         tcg_gen_sub_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
                   1644:                     tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
                   1645:                 } else {
                   1646:                     if (islit)
                   1647:                         tcg_gen_movi_i64(cpu_ir[rc], -lit);
                   1648:                     else {
                   1649:                         tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
                   1650:                         tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
                   1651:                 }
                   1652:             }
1.1       root     1653:             break;
                   1654:         case 0x0B:
                   1655:             /* S4SUBL */
1.1.1.2   root     1656:             if (likely(rc != 31)) {
                   1657:                 if (ra != 31) {
                   1658:                     TCGv tmp = tcg_temp_new();
                   1659:                     tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
                   1660:                     if (islit)
                   1661:                         tcg_gen_subi_i64(tmp, tmp, lit);
                   1662:                     else
                   1663:                         tcg_gen_sub_i64(tmp, tmp, cpu_ir[rb]);
                   1664:                     tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
                   1665:                     tcg_temp_free(tmp);
                   1666:                 } else {
                   1667:                     if (islit)
                   1668:                         tcg_gen_movi_i64(cpu_ir[rc], -lit);
                   1669:                     else {
                   1670:                         tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
                   1671:                         tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
                   1672:                     }
                   1673:                 }
                   1674:             }
1.1       root     1675:             break;
                   1676:         case 0x0F:
                   1677:             /* CMPBGE */
1.1.1.2   root     1678:             gen_cmpbge(ra, rb, rc, islit, lit);
1.1       root     1679:             break;
                   1680:         case 0x12:
                   1681:             /* S8ADDL */
1.1.1.2   root     1682:             if (likely(rc != 31)) {
                   1683:                 if (ra != 31) {
                   1684:                     TCGv tmp = tcg_temp_new();
                   1685:                     tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
                   1686:                     if (islit)
                   1687:                         tcg_gen_addi_i64(tmp, tmp, lit);
                   1688:                     else
                   1689:                         tcg_gen_add_i64(tmp, tmp, cpu_ir[rb]);
                   1690:                     tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
                   1691:                     tcg_temp_free(tmp);
                   1692:                 } else {
                   1693:                     if (islit)
                   1694:                         tcg_gen_movi_i64(cpu_ir[rc], lit);
                   1695:                     else
                   1696:                         tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
                   1697:                 }
                   1698:             }
1.1       root     1699:             break;
                   1700:         case 0x1B:
                   1701:             /* S8SUBL */
1.1.1.2   root     1702:             if (likely(rc != 31)) {
                   1703:                 if (ra != 31) {
                   1704:                     TCGv tmp = tcg_temp_new();
                   1705:                     tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
                   1706:                     if (islit)
                   1707:                         tcg_gen_subi_i64(tmp, tmp, lit);
                   1708:                     else
                   1709:                        tcg_gen_sub_i64(tmp, tmp, cpu_ir[rb]);
                   1710:                     tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
                   1711:                     tcg_temp_free(tmp);
                   1712:                 } else {
                   1713:                     if (islit)
                   1714:                         tcg_gen_movi_i64(cpu_ir[rc], -lit);
                   1715:                     else
                   1716:                         tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
                   1717:                         tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
                   1718:                     }
                   1719:                 }
                   1720:             }
1.1       root     1721:             break;
                   1722:         case 0x1D:
                   1723:             /* CMPULT */
1.1.1.2   root     1724:             gen_cmp(TCG_COND_LTU, ra, rb, rc, islit, lit);
1.1       root     1725:             break;
                   1726:         case 0x20:
                   1727:             /* ADDQ */
1.1.1.2   root     1728:             if (likely(rc != 31)) {
                   1729:                 if (ra != 31) {
                   1730:                     if (islit)
                   1731:                         tcg_gen_addi_i64(cpu_ir[rc], cpu_ir[ra], lit);
                   1732:                     else
                   1733:                         tcg_gen_add_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
                   1734:                 } else {
                   1735:                     if (islit)
                   1736:                         tcg_gen_movi_i64(cpu_ir[rc], lit);
                   1737:                     else
                   1738:                         tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
                   1739:                 }
                   1740:             }
1.1       root     1741:             break;
                   1742:         case 0x22:
                   1743:             /* S4ADDQ */
1.1.1.2   root     1744:             if (likely(rc != 31)) {
                   1745:                 if (ra != 31) {
                   1746:                     TCGv tmp = tcg_temp_new();
                   1747:                     tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
                   1748:                     if (islit)
                   1749:                         tcg_gen_addi_i64(cpu_ir[rc], tmp, lit);
                   1750:                     else
                   1751:                         tcg_gen_add_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
                   1752:                     tcg_temp_free(tmp);
                   1753:                 } else {
                   1754:                     if (islit)
                   1755:                         tcg_gen_movi_i64(cpu_ir[rc], lit);
                   1756:                     else
                   1757:                         tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
                   1758:                 }
                   1759:             }
1.1       root     1760:             break;
                   1761:         case 0x29:
                   1762:             /* SUBQ */
1.1.1.2   root     1763:             if (likely(rc != 31)) {
                   1764:                 if (ra != 31) {
                   1765:                     if (islit)
                   1766:                         tcg_gen_subi_i64(cpu_ir[rc], cpu_ir[ra], lit);
                   1767:                     else
                   1768:                         tcg_gen_sub_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
                   1769:                 } else {
                   1770:                     if (islit)
                   1771:                         tcg_gen_movi_i64(cpu_ir[rc], -lit);
                   1772:                     else
                   1773:                         tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
                   1774:                 }
                   1775:             }
1.1       root     1776:             break;
                   1777:         case 0x2B:
                   1778:             /* S4SUBQ */
1.1.1.2   root     1779:             if (likely(rc != 31)) {
                   1780:                 if (ra != 31) {
                   1781:                     TCGv tmp = tcg_temp_new();
                   1782:                     tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
                   1783:                     if (islit)
                   1784:                         tcg_gen_subi_i64(cpu_ir[rc], tmp, lit);
                   1785:                     else
                   1786:                         tcg_gen_sub_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
                   1787:                     tcg_temp_free(tmp);
                   1788:                 } else {
                   1789:                     if (islit)
                   1790:                         tcg_gen_movi_i64(cpu_ir[rc], -lit);
                   1791:                     else
                   1792:                         tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
                   1793:                 }
                   1794:             }
1.1       root     1795:             break;
                   1796:         case 0x2D:
                   1797:             /* CMPEQ */
1.1.1.2   root     1798:             gen_cmp(TCG_COND_EQ, ra, rb, rc, islit, lit);
1.1       root     1799:             break;
                   1800:         case 0x32:
                   1801:             /* S8ADDQ */
1.1.1.2   root     1802:             if (likely(rc != 31)) {
                   1803:                 if (ra != 31) {
                   1804:                     TCGv tmp = tcg_temp_new();
                   1805:                     tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
                   1806:                     if (islit)
                   1807:                         tcg_gen_addi_i64(cpu_ir[rc], tmp, lit);
                   1808:                     else
                   1809:                         tcg_gen_add_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
                   1810:                     tcg_temp_free(tmp);
                   1811:                 } else {
                   1812:                     if (islit)
                   1813:                         tcg_gen_movi_i64(cpu_ir[rc], lit);
                   1814:                     else
                   1815:                         tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
                   1816:                 }
                   1817:             }
1.1       root     1818:             break;
                   1819:         case 0x3B:
                   1820:             /* S8SUBQ */
1.1.1.2   root     1821:             if (likely(rc != 31)) {
                   1822:                 if (ra != 31) {
                   1823:                     TCGv tmp = tcg_temp_new();
                   1824:                     tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
                   1825:                     if (islit)
                   1826:                         tcg_gen_subi_i64(cpu_ir[rc], tmp, lit);
                   1827:                     else
                   1828:                         tcg_gen_sub_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
                   1829:                     tcg_temp_free(tmp);
                   1830:                 } else {
                   1831:                     if (islit)
                   1832:                         tcg_gen_movi_i64(cpu_ir[rc], -lit);
                   1833:                     else
                   1834:                         tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
                   1835:                 }
                   1836:             }
1.1       root     1837:             break;
                   1838:         case 0x3D:
                   1839:             /* CMPULE */
1.1.1.2   root     1840:             gen_cmp(TCG_COND_LEU, ra, rb, rc, islit, lit);
1.1       root     1841:             break;
                   1842:         case 0x40:
                   1843:             /* ADDL/V */
1.1.1.2   root     1844:             gen_addlv(ra, rb, rc, islit, lit);
1.1       root     1845:             break;
                   1846:         case 0x49:
                   1847:             /* SUBL/V */
1.1.1.2   root     1848:             gen_sublv(ra, rb, rc, islit, lit);
1.1       root     1849:             break;
                   1850:         case 0x4D:
                   1851:             /* CMPLT */
1.1.1.2   root     1852:             gen_cmp(TCG_COND_LT, ra, rb, rc, islit, lit);
1.1       root     1853:             break;
                   1854:         case 0x60:
                   1855:             /* ADDQ/V */
1.1.1.2   root     1856:             gen_addqv(ra, rb, rc, islit, lit);
1.1       root     1857:             break;
                   1858:         case 0x69:
                   1859:             /* SUBQ/V */
1.1.1.2   root     1860:             gen_subqv(ra, rb, rc, islit, lit);
1.1       root     1861:             break;
                   1862:         case 0x6D:
                   1863:             /* CMPLE */
1.1.1.2   root     1864:             gen_cmp(TCG_COND_LE, ra, rb, rc, islit, lit);
1.1       root     1865:             break;
                   1866:         default:
                   1867:             goto invalid_opc;
                   1868:         }
                   1869:         break;
                   1870:     case 0x11:
                   1871:         switch (fn7) {
                   1872:         case 0x00:
                   1873:             /* AND */
1.1.1.2   root     1874:             if (likely(rc != 31)) {
                   1875:                 if (ra == 31)
                   1876:                     tcg_gen_movi_i64(cpu_ir[rc], 0);
                   1877:                 else if (islit)
                   1878:                     tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], lit);
                   1879:                 else
                   1880:                     tcg_gen_and_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
                   1881:             }
1.1       root     1882:             break;
                   1883:         case 0x08:
                   1884:             /* BIC */
1.1.1.2   root     1885:             if (likely(rc != 31)) {
                   1886:                 if (ra != 31) {
                   1887:                     if (islit)
                   1888:                         tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
                   1889:                     else
                   1890:                         tcg_gen_andc_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
                   1891:                 } else
                   1892:                     tcg_gen_movi_i64(cpu_ir[rc], 0);
                   1893:             }
1.1       root     1894:             break;
                   1895:         case 0x14:
                   1896:             /* CMOVLBS */
1.1.1.5 ! root     1897:             gen_cmov(TCG_COND_NE, ra, rb, rc, islit, lit, 1);
1.1       root     1898:             break;
                   1899:         case 0x16:
                   1900:             /* CMOVLBC */
1.1.1.5 ! root     1901:             gen_cmov(TCG_COND_EQ, ra, rb, rc, islit, lit, 1);
1.1       root     1902:             break;
                   1903:         case 0x20:
                   1904:             /* BIS */
1.1.1.2   root     1905:             if (likely(rc != 31)) {
                   1906:                 if (ra != 31) {
                   1907:                     if (islit)
                   1908:                         tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], lit);
                   1909:                     else
                   1910:                         tcg_gen_or_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1.1       root     1911:                 } else {
1.1.1.2   root     1912:                     if (islit)
                   1913:                         tcg_gen_movi_i64(cpu_ir[rc], lit);
                   1914:                     else
                   1915:                         tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
1.1       root     1916:                 }
                   1917:             }
                   1918:             break;
                   1919:         case 0x24:
                   1920:             /* CMOVEQ */
1.1.1.5 ! root     1921:             gen_cmov(TCG_COND_EQ, ra, rb, rc, islit, lit, 0);
1.1       root     1922:             break;
                   1923:         case 0x26:
                   1924:             /* CMOVNE */
1.1.1.5 ! root     1925:             gen_cmov(TCG_COND_NE, ra, rb, rc, islit, lit, 0);
1.1       root     1926:             break;
                   1927:         case 0x28:
                   1928:             /* ORNOT */
1.1.1.2   root     1929:             if (likely(rc != 31)) {
                   1930:                 if (ra != 31) {
                   1931:                     if (islit)
                   1932:                         tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
                   1933:                     else
                   1934:                         tcg_gen_orc_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
                   1935:                 } else {
                   1936:                     if (islit)
                   1937:                         tcg_gen_movi_i64(cpu_ir[rc], ~lit);
                   1938:                     else
                   1939:                         tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]);
                   1940:                 }
                   1941:             }
1.1       root     1942:             break;
                   1943:         case 0x40:
                   1944:             /* XOR */
1.1.1.2   root     1945:             if (likely(rc != 31)) {
                   1946:                 if (ra != 31) {
                   1947:                     if (islit)
                   1948:                         tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], lit);
                   1949:                     else
                   1950:                         tcg_gen_xor_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
                   1951:                 } else {
                   1952:                     if (islit)
                   1953:                         tcg_gen_movi_i64(cpu_ir[rc], lit);
                   1954:                     else
                   1955:                         tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
                   1956:                 }
                   1957:             }
1.1       root     1958:             break;
                   1959:         case 0x44:
                   1960:             /* CMOVLT */
1.1.1.5 ! root     1961:             gen_cmov(TCG_COND_LT, ra, rb, rc, islit, lit, 0);
1.1       root     1962:             break;
                   1963:         case 0x46:
                   1964:             /* CMOVGE */
1.1.1.5 ! root     1965:             gen_cmov(TCG_COND_GE, ra, rb, rc, islit, lit, 0);
1.1       root     1966:             break;
                   1967:         case 0x48:
                   1968:             /* EQV */
1.1.1.2   root     1969:             if (likely(rc != 31)) {
                   1970:                 if (ra != 31) {
                   1971:                     if (islit)
                   1972:                         tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
                   1973:                     else
                   1974:                         tcg_gen_eqv_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
                   1975:                 } else {
                   1976:                     if (islit)
                   1977:                         tcg_gen_movi_i64(cpu_ir[rc], ~lit);
                   1978:                     else
                   1979:                         tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]);
                   1980:                 }
                   1981:             }
1.1       root     1982:             break;
                   1983:         case 0x61:
                   1984:             /* AMASK */
1.1.1.2   root     1985:             if (likely(rc != 31)) {
                   1986:                 if (islit)
1.1.1.3   root     1987:                     tcg_gen_movi_i64(cpu_ir[rc], lit);
1.1.1.2   root     1988:                 else
1.1.1.3   root     1989:                     tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
                   1990:                 switch (ctx->env->implver) {
                   1991:                 case IMPLVER_2106x:
                   1992:                     /* EV4, EV45, LCA, LCA45 & EV5 */
                   1993:                     break;
                   1994:                 case IMPLVER_21164:
                   1995:                 case IMPLVER_21264:
                   1996:                 case IMPLVER_21364:
                   1997:                     tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[rc],
                   1998:                                      ~(uint64_t)ctx->amask);
                   1999:                     break;
                   2000:                 }
1.1.1.2   root     2001:             }
1.1       root     2002:             break;
                   2003:         case 0x64:
                   2004:             /* CMOVLE */
1.1.1.5 ! root     2005:             gen_cmov(TCG_COND_LE, ra, rb, rc, islit, lit, 0);
1.1       root     2006:             break;
                   2007:         case 0x66:
                   2008:             /* CMOVGT */
1.1.1.5 ! root     2009:             gen_cmov(TCG_COND_GT, ra, rb, rc, islit, lit, 0);
1.1       root     2010:             break;
                   2011:         case 0x6C:
                   2012:             /* IMPLVER */
1.1.1.2   root     2013:             if (rc != 31)
1.1.1.3   root     2014:                 tcg_gen_movi_i64(cpu_ir[rc], ctx->env->implver);
1.1       root     2015:             break;
                   2016:         default:
                   2017:             goto invalid_opc;
                   2018:         }
                   2019:         break;
                   2020:     case 0x12:
                   2021:         switch (fn7) {
                   2022:         case 0x02:
                   2023:             /* MSKBL */
1.1.1.5 ! root     2024:             gen_msk_l(ra, rb, rc, islit, lit, 0x01);
1.1       root     2025:             break;
                   2026:         case 0x06:
                   2027:             /* EXTBL */
1.1.1.5 ! root     2028:             gen_ext_l(ra, rb, rc, islit, lit, 0x01);
1.1       root     2029:             break;
                   2030:         case 0x0B:
                   2031:             /* INSBL */
1.1.1.5 ! root     2032:             gen_ins_l(ra, rb, rc, islit, lit, 0x01);
1.1       root     2033:             break;
                   2034:         case 0x12:
                   2035:             /* MSKWL */
1.1.1.5 ! root     2036:             gen_msk_l(ra, rb, rc, islit, lit, 0x03);
1.1       root     2037:             break;
                   2038:         case 0x16:
                   2039:             /* EXTWL */
1.1.1.5 ! root     2040:             gen_ext_l(ra, rb, rc, islit, lit, 0x03);
1.1       root     2041:             break;
                   2042:         case 0x1B:
                   2043:             /* INSWL */
1.1.1.5 ! root     2044:             gen_ins_l(ra, rb, rc, islit, lit, 0x03);
1.1       root     2045:             break;
                   2046:         case 0x22:
                   2047:             /* MSKLL */
1.1.1.5 ! root     2048:             gen_msk_l(ra, rb, rc, islit, lit, 0x0f);
1.1       root     2049:             break;
                   2050:         case 0x26:
                   2051:             /* EXTLL */
1.1.1.5 ! root     2052:             gen_ext_l(ra, rb, rc, islit, lit, 0x0f);
1.1       root     2053:             break;
                   2054:         case 0x2B:
                   2055:             /* INSLL */
1.1.1.5 ! root     2056:             gen_ins_l(ra, rb, rc, islit, lit, 0x0f);
1.1       root     2057:             break;
                   2058:         case 0x30:
                   2059:             /* ZAP */
1.1.1.2   root     2060:             gen_zap(ra, rb, rc, islit, lit);
1.1       root     2061:             break;
                   2062:         case 0x31:
                   2063:             /* ZAPNOT */
1.1.1.2   root     2064:             gen_zapnot(ra, rb, rc, islit, lit);
1.1       root     2065:             break;
                   2066:         case 0x32:
                   2067:             /* MSKQL */
1.1.1.5 ! root     2068:             gen_msk_l(ra, rb, rc, islit, lit, 0xff);
1.1       root     2069:             break;
                   2070:         case 0x34:
                   2071:             /* SRL */
1.1.1.2   root     2072:             if (likely(rc != 31)) {
                   2073:                 if (ra != 31) {
                   2074:                     if (islit)
                   2075:                         tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
                   2076:                     else {
                   2077:                         TCGv shift = tcg_temp_new();
                   2078:                         tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
                   2079:                         tcg_gen_shr_i64(cpu_ir[rc], cpu_ir[ra], shift);
                   2080:                         tcg_temp_free(shift);
                   2081:                     }
                   2082:                 } else
                   2083:                     tcg_gen_movi_i64(cpu_ir[rc], 0);
                   2084:             }
1.1       root     2085:             break;
                   2086:         case 0x36:
                   2087:             /* EXTQL */
1.1.1.5 ! root     2088:             gen_ext_l(ra, rb, rc, islit, lit, 0xff);
1.1       root     2089:             break;
                   2090:         case 0x39:
                   2091:             /* SLL */
1.1.1.2   root     2092:             if (likely(rc != 31)) {
                   2093:                 if (ra != 31) {
                   2094:                     if (islit)
                   2095:                         tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
                   2096:                     else {
                   2097:                         TCGv shift = tcg_temp_new();
                   2098:                         tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
                   2099:                         tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], shift);
                   2100:                         tcg_temp_free(shift);
                   2101:                     }
                   2102:                 } else
                   2103:                     tcg_gen_movi_i64(cpu_ir[rc], 0);
                   2104:             }
1.1       root     2105:             break;
                   2106:         case 0x3B:
                   2107:             /* INSQL */
1.1.1.5 ! root     2108:             gen_ins_l(ra, rb, rc, islit, lit, 0xff);
1.1       root     2109:             break;
                   2110:         case 0x3C:
                   2111:             /* SRA */
1.1.1.2   root     2112:             if (likely(rc != 31)) {
                   2113:                 if (ra != 31) {
                   2114:                     if (islit)
                   2115:                         tcg_gen_sari_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
                   2116:                     else {
                   2117:                         TCGv shift = tcg_temp_new();
                   2118:                         tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
                   2119:                         tcg_gen_sar_i64(cpu_ir[rc], cpu_ir[ra], shift);
                   2120:                         tcg_temp_free(shift);
                   2121:                     }
                   2122:                 } else
                   2123:                     tcg_gen_movi_i64(cpu_ir[rc], 0);
                   2124:             }
1.1       root     2125:             break;
                   2126:         case 0x52:
                   2127:             /* MSKWH */
1.1.1.5 ! root     2128:             gen_msk_h(ra, rb, rc, islit, lit, 0x03);
1.1       root     2129:             break;
                   2130:         case 0x57:
                   2131:             /* INSWH */
1.1.1.5 ! root     2132:             gen_ins_h(ra, rb, rc, islit, lit, 0x03);
1.1       root     2133:             break;
                   2134:         case 0x5A:
                   2135:             /* EXTWH */
1.1.1.5 ! root     2136:             gen_ext_h(ra, rb, rc, islit, lit, 0x03);
1.1       root     2137:             break;
                   2138:         case 0x62:
                   2139:             /* MSKLH */
1.1.1.5 ! root     2140:             gen_msk_h(ra, rb, rc, islit, lit, 0x0f);
1.1       root     2141:             break;
                   2142:         case 0x67:
                   2143:             /* INSLH */
1.1.1.5 ! root     2144:             gen_ins_h(ra, rb, rc, islit, lit, 0x0f);
1.1       root     2145:             break;
                   2146:         case 0x6A:
                   2147:             /* EXTLH */
1.1.1.5 ! root     2148:             gen_ext_h(ra, rb, rc, islit, lit, 0x0f);
1.1       root     2149:             break;
                   2150:         case 0x72:
                   2151:             /* MSKQH */
1.1.1.5 ! root     2152:             gen_msk_h(ra, rb, rc, islit, lit, 0xff);
1.1       root     2153:             break;
                   2154:         case 0x77:
                   2155:             /* INSQH */
1.1.1.5 ! root     2156:             gen_ins_h(ra, rb, rc, islit, lit, 0xff);
1.1       root     2157:             break;
                   2158:         case 0x7A:
                   2159:             /* EXTQH */
1.1.1.5 ! root     2160:             gen_ext_h(ra, rb, rc, islit, lit, 0xff);
1.1       root     2161:             break;
                   2162:         default:
                   2163:             goto invalid_opc;
                   2164:         }
                   2165:         break;
                   2166:     case 0x13:
                   2167:         switch (fn7) {
                   2168:         case 0x00:
                   2169:             /* MULL */
1.1.1.2   root     2170:             if (likely(rc != 31)) {
                   2171:                 if (ra == 31)
                   2172:                     tcg_gen_movi_i64(cpu_ir[rc], 0);
                   2173:                 else {
                   2174:                     if (islit)
                   2175:                         tcg_gen_muli_i64(cpu_ir[rc], cpu_ir[ra], lit);
                   2176:                     else
                   2177:                         tcg_gen_mul_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
                   2178:                     tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
                   2179:                 }
                   2180:             }
1.1       root     2181:             break;
                   2182:         case 0x20:
                   2183:             /* MULQ */
1.1.1.2   root     2184:             if (likely(rc != 31)) {
                   2185:                 if (ra == 31)
                   2186:                     tcg_gen_movi_i64(cpu_ir[rc], 0);
                   2187:                 else if (islit)
                   2188:                     tcg_gen_muli_i64(cpu_ir[rc], cpu_ir[ra], lit);
                   2189:                 else
                   2190:                     tcg_gen_mul_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
                   2191:             }
1.1       root     2192:             break;
                   2193:         case 0x30:
                   2194:             /* UMULH */
1.1.1.2   root     2195:             gen_umulh(ra, rb, rc, islit, lit);
1.1       root     2196:             break;
                   2197:         case 0x40:
                   2198:             /* MULL/V */
1.1.1.2   root     2199:             gen_mullv(ra, rb, rc, islit, lit);
1.1       root     2200:             break;
                   2201:         case 0x60:
                   2202:             /* MULQ/V */
1.1.1.2   root     2203:             gen_mulqv(ra, rb, rc, islit, lit);
1.1       root     2204:             break;
                   2205:         default:
                   2206:             goto invalid_opc;
                   2207:         }
                   2208:         break;
                   2209:     case 0x14:
1.1.1.5 ! root     2210:         switch (fpfn) { /* fn11 & 0x3F */
1.1       root     2211:         case 0x04:
                   2212:             /* ITOFS */
                   2213:             if (!(ctx->amask & AMASK_FIX))
                   2214:                 goto invalid_opc;
1.1.1.2   root     2215:             if (likely(rc != 31)) {
                   2216:                 if (ra != 31) {
                   2217:                     TCGv_i32 tmp = tcg_temp_new_i32();
                   2218:                     tcg_gen_trunc_i64_i32(tmp, cpu_ir[ra]);
                   2219:                     gen_helper_memory_to_s(cpu_fir[rc], tmp);
                   2220:                     tcg_temp_free_i32(tmp);
                   2221:                 } else
                   2222:                     tcg_gen_movi_i64(cpu_fir[rc], 0);
                   2223:             }
1.1       root     2224:             break;
                   2225:         case 0x0A:
                   2226:             /* SQRTF */
                   2227:             if (!(ctx->amask & AMASK_FIX))
                   2228:                 goto invalid_opc;
1.1.1.2   root     2229:             gen_fsqrtf(rb, rc);
1.1       root     2230:             break;
                   2231:         case 0x0B:
                   2232:             /* SQRTS */
                   2233:             if (!(ctx->amask & AMASK_FIX))
                   2234:                 goto invalid_opc;
1.1.1.5 ! root     2235:             gen_fsqrts(ctx, rb, rc, fn11);
1.1       root     2236:             break;
                   2237:         case 0x14:
                   2238:             /* ITOFF */
                   2239:             if (!(ctx->amask & AMASK_FIX))
                   2240:                 goto invalid_opc;
1.1.1.2   root     2241:             if (likely(rc != 31)) {
                   2242:                 if (ra != 31) {
                   2243:                     TCGv_i32 tmp = tcg_temp_new_i32();
                   2244:                     tcg_gen_trunc_i64_i32(tmp, cpu_ir[ra]);
                   2245:                     gen_helper_memory_to_f(cpu_fir[rc], tmp);
                   2246:                     tcg_temp_free_i32(tmp);
                   2247:                 } else
                   2248:                     tcg_gen_movi_i64(cpu_fir[rc], 0);
                   2249:             }
1.1       root     2250:             break;
                   2251:         case 0x24:
                   2252:             /* ITOFT */
                   2253:             if (!(ctx->amask & AMASK_FIX))
                   2254:                 goto invalid_opc;
1.1.1.2   root     2255:             if (likely(rc != 31)) {
                   2256:                 if (ra != 31)
                   2257:                     tcg_gen_mov_i64(cpu_fir[rc], cpu_ir[ra]);
                   2258:                 else
                   2259:                     tcg_gen_movi_i64(cpu_fir[rc], 0);
                   2260:             }
1.1       root     2261:             break;
                   2262:         case 0x2A:
                   2263:             /* SQRTG */
                   2264:             if (!(ctx->amask & AMASK_FIX))
                   2265:                 goto invalid_opc;
1.1.1.2   root     2266:             gen_fsqrtg(rb, rc);
1.1       root     2267:             break;
                   2268:         case 0x02B:
                   2269:             /* SQRTT */
                   2270:             if (!(ctx->amask & AMASK_FIX))
                   2271:                 goto invalid_opc;
1.1.1.5 ! root     2272:             gen_fsqrtt(ctx, rb, rc, fn11);
1.1       root     2273:             break;
                   2274:         default:
                   2275:             goto invalid_opc;
                   2276:         }
                   2277:         break;
                   2278:     case 0x15:
                   2279:         /* VAX floating point */
                   2280:         /* XXX: rounding mode and trap are ignored (!) */
1.1.1.5 ! root     2281:         switch (fpfn) { /* fn11 & 0x3F */
1.1       root     2282:         case 0x00:
                   2283:             /* ADDF */
1.1.1.2   root     2284:             gen_faddf(ra, rb, rc);
1.1       root     2285:             break;
                   2286:         case 0x01:
                   2287:             /* SUBF */
1.1.1.2   root     2288:             gen_fsubf(ra, rb, rc);
1.1       root     2289:             break;
                   2290:         case 0x02:
                   2291:             /* MULF */
1.1.1.2   root     2292:             gen_fmulf(ra, rb, rc);
1.1       root     2293:             break;
                   2294:         case 0x03:
                   2295:             /* DIVF */
1.1.1.2   root     2296:             gen_fdivf(ra, rb, rc);
1.1       root     2297:             break;
                   2298:         case 0x1E:
                   2299:             /* CVTDG */
                   2300: #if 0 // TODO
1.1.1.2   root     2301:             gen_fcvtdg(rb, rc);
1.1       root     2302: #else
                   2303:             goto invalid_opc;
                   2304: #endif
                   2305:             break;
                   2306:         case 0x20:
                   2307:             /* ADDG */
1.1.1.2   root     2308:             gen_faddg(ra, rb, rc);
1.1       root     2309:             break;
                   2310:         case 0x21:
                   2311:             /* SUBG */
1.1.1.2   root     2312:             gen_fsubg(ra, rb, rc);
1.1       root     2313:             break;
                   2314:         case 0x22:
                   2315:             /* MULG */
1.1.1.2   root     2316:             gen_fmulg(ra, rb, rc);
1.1       root     2317:             break;
                   2318:         case 0x23:
                   2319:             /* DIVG */
1.1.1.2   root     2320:             gen_fdivg(ra, rb, rc);
1.1       root     2321:             break;
                   2322:         case 0x25:
                   2323:             /* CMPGEQ */
1.1.1.2   root     2324:             gen_fcmpgeq(ra, rb, rc);
1.1       root     2325:             break;
                   2326:         case 0x26:
                   2327:             /* CMPGLT */
1.1.1.2   root     2328:             gen_fcmpglt(ra, rb, rc);
1.1       root     2329:             break;
                   2330:         case 0x27:
                   2331:             /* CMPGLE */
1.1.1.2   root     2332:             gen_fcmpgle(ra, rb, rc);
1.1       root     2333:             break;
                   2334:         case 0x2C:
                   2335:             /* CVTGF */
1.1.1.2   root     2336:             gen_fcvtgf(rb, rc);
1.1       root     2337:             break;
                   2338:         case 0x2D:
                   2339:             /* CVTGD */
                   2340: #if 0 // TODO
1.1.1.2   root     2341:             gen_fcvtgd(rb, rc);
1.1       root     2342: #else
                   2343:             goto invalid_opc;
                   2344: #endif
                   2345:             break;
                   2346:         case 0x2F:
                   2347:             /* CVTGQ */
1.1.1.2   root     2348:             gen_fcvtgq(rb, rc);
1.1       root     2349:             break;
                   2350:         case 0x3C:
                   2351:             /* CVTQF */
1.1.1.2   root     2352:             gen_fcvtqf(rb, rc);
1.1       root     2353:             break;
                   2354:         case 0x3E:
                   2355:             /* CVTQG */
1.1.1.2   root     2356:             gen_fcvtqg(rb, rc);
1.1       root     2357:             break;
                   2358:         default:
                   2359:             goto invalid_opc;
                   2360:         }
                   2361:         break;
                   2362:     case 0x16:
                   2363:         /* IEEE floating-point */
1.1.1.5 ! root     2364:         switch (fpfn) { /* fn11 & 0x3F */
1.1       root     2365:         case 0x00:
                   2366:             /* ADDS */
1.1.1.5 ! root     2367:             gen_fadds(ctx, ra, rb, rc, fn11);
1.1       root     2368:             break;
                   2369:         case 0x01:
                   2370:             /* SUBS */
1.1.1.5 ! root     2371:             gen_fsubs(ctx, ra, rb, rc, fn11);
1.1       root     2372:             break;
                   2373:         case 0x02:
                   2374:             /* MULS */
1.1.1.5 ! root     2375:             gen_fmuls(ctx, ra, rb, rc, fn11);
1.1       root     2376:             break;
                   2377:         case 0x03:
                   2378:             /* DIVS */
1.1.1.5 ! root     2379:             gen_fdivs(ctx, ra, rb, rc, fn11);
1.1       root     2380:             break;
                   2381:         case 0x20:
                   2382:             /* ADDT */
1.1.1.5 ! root     2383:             gen_faddt(ctx, ra, rb, rc, fn11);
1.1       root     2384:             break;
                   2385:         case 0x21:
                   2386:             /* SUBT */
1.1.1.5 ! root     2387:             gen_fsubt(ctx, ra, rb, rc, fn11);
1.1       root     2388:             break;
                   2389:         case 0x22:
                   2390:             /* MULT */
1.1.1.5 ! root     2391:             gen_fmult(ctx, ra, rb, rc, fn11);
1.1       root     2392:             break;
                   2393:         case 0x23:
                   2394:             /* DIVT */
1.1.1.5 ! root     2395:             gen_fdivt(ctx, ra, rb, rc, fn11);
1.1       root     2396:             break;
                   2397:         case 0x24:
                   2398:             /* CMPTUN */
1.1.1.5 ! root     2399:             gen_fcmptun(ctx, ra, rb, rc, fn11);
1.1       root     2400:             break;
                   2401:         case 0x25:
                   2402:             /* CMPTEQ */
1.1.1.5 ! root     2403:             gen_fcmpteq(ctx, ra, rb, rc, fn11);
1.1       root     2404:             break;
                   2405:         case 0x26:
                   2406:             /* CMPTLT */
1.1.1.5 ! root     2407:             gen_fcmptlt(ctx, ra, rb, rc, fn11);
1.1       root     2408:             break;
                   2409:         case 0x27:
                   2410:             /* CMPTLE */
1.1.1.5 ! root     2411:             gen_fcmptle(ctx, ra, rb, rc, fn11);
1.1       root     2412:             break;
                   2413:         case 0x2C:
1.1.1.2   root     2414:             if (fn11 == 0x2AC || fn11 == 0x6AC) {
1.1       root     2415:                 /* CVTST */
1.1.1.5 ! root     2416:                 gen_fcvtst(ctx, rb, rc, fn11);
1.1       root     2417:             } else {
                   2418:                 /* CVTTS */
1.1.1.5 ! root     2419:                 gen_fcvtts(ctx, rb, rc, fn11);
1.1       root     2420:             }
                   2421:             break;
                   2422:         case 0x2F:
                   2423:             /* CVTTQ */
1.1.1.5 ! root     2424:             gen_fcvttq(ctx, rb, rc, fn11);
1.1       root     2425:             break;
                   2426:         case 0x3C:
                   2427:             /* CVTQS */
1.1.1.5 ! root     2428:             gen_fcvtqs(ctx, rb, rc, fn11);
1.1       root     2429:             break;
                   2430:         case 0x3E:
                   2431:             /* CVTQT */
1.1.1.5 ! root     2432:             gen_fcvtqt(ctx, rb, rc, fn11);
1.1       root     2433:             break;
                   2434:         default:
                   2435:             goto invalid_opc;
                   2436:         }
                   2437:         break;
                   2438:     case 0x17:
                   2439:         switch (fn11) {
                   2440:         case 0x010:
                   2441:             /* CVTLQ */
1.1.1.2   root     2442:             gen_fcvtlq(rb, rc);
1.1       root     2443:             break;
                   2444:         case 0x020:
1.1.1.2   root     2445:             if (likely(rc != 31)) {
1.1.1.5 ! root     2446:                 if (ra == rb) {
1.1       root     2447:                     /* FMOV */
1.1.1.5 ! root     2448:                     if (ra == 31)
        !          2449:                         tcg_gen_movi_i64(cpu_fir[rc], 0);
        !          2450:                     else
        !          2451:                         tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[ra]);
        !          2452:                 } else {
1.1.1.2   root     2453:                     /* CPYS */
                   2454:                     gen_fcpys(ra, rb, rc);
1.1.1.5 ! root     2455:                 }
1.1       root     2456:             }
                   2457:             break;
                   2458:         case 0x021:
                   2459:             /* CPYSN */
1.1.1.2   root     2460:             gen_fcpysn(ra, rb, rc);
1.1       root     2461:             break;
                   2462:         case 0x022:
                   2463:             /* CPYSE */
1.1.1.2   root     2464:             gen_fcpyse(ra, rb, rc);
1.1       root     2465:             break;
                   2466:         case 0x024:
                   2467:             /* MT_FPCR */
1.1.1.2   root     2468:             if (likely(ra != 31))
                   2469:                 gen_helper_store_fpcr(cpu_fir[ra]);
                   2470:             else {
                   2471:                 TCGv tmp = tcg_const_i64(0);
                   2472:                 gen_helper_store_fpcr(tmp);
                   2473:                 tcg_temp_free(tmp);
                   2474:             }
1.1       root     2475:             break;
                   2476:         case 0x025:
                   2477:             /* MF_FPCR */
1.1.1.2   root     2478:             if (likely(ra != 31))
                   2479:                 gen_helper_load_fpcr(cpu_fir[ra]);
1.1       root     2480:             break;
                   2481:         case 0x02A:
                   2482:             /* FCMOVEQ */
1.1.1.5 ! root     2483:             gen_fcmov(TCG_COND_EQ, ra, rb, rc);
1.1       root     2484:             break;
                   2485:         case 0x02B:
                   2486:             /* FCMOVNE */
1.1.1.5 ! root     2487:             gen_fcmov(TCG_COND_NE, ra, rb, rc);
1.1       root     2488:             break;
                   2489:         case 0x02C:
                   2490:             /* FCMOVLT */
1.1.1.5 ! root     2491:             gen_fcmov(TCG_COND_LT, ra, rb, rc);
1.1       root     2492:             break;
                   2493:         case 0x02D:
                   2494:             /* FCMOVGE */
1.1.1.5 ! root     2495:             gen_fcmov(TCG_COND_GE, ra, rb, rc);
1.1       root     2496:             break;
                   2497:         case 0x02E:
                   2498:             /* FCMOVLE */
1.1.1.5 ! root     2499:             gen_fcmov(TCG_COND_LE, ra, rb, rc);
1.1       root     2500:             break;
                   2501:         case 0x02F:
                   2502:             /* FCMOVGT */
1.1.1.5 ! root     2503:             gen_fcmov(TCG_COND_GT, ra, rb, rc);
1.1       root     2504:             break;
                   2505:         case 0x030:
                   2506:             /* CVTQL */
1.1.1.2   root     2507:             gen_fcvtql(rb, rc);
1.1       root     2508:             break;
                   2509:         case 0x130:
                   2510:             /* CVTQL/V */
                   2511:         case 0x530:
                   2512:             /* CVTQL/SV */
1.1.1.5 ! root     2513:             /* ??? I'm pretty sure there's nothing that /sv needs to do that
        !          2514:                /v doesn't do.  The only thing I can think is that /sv is a
        !          2515:                valid instruction merely for completeness in the ISA.  */
        !          2516:             gen_fcvtql_v(ctx, rb, rc);
1.1       root     2517:             break;
                   2518:         default:
                   2519:             goto invalid_opc;
                   2520:         }
                   2521:         break;
                   2522:     case 0x18:
                   2523:         switch ((uint16_t)disp16) {
                   2524:         case 0x0000:
                   2525:             /* TRAPB */
1.1.1.5 ! root     2526:             /* No-op.  */
1.1       root     2527:             break;
                   2528:         case 0x0400:
                   2529:             /* EXCB */
1.1.1.5 ! root     2530:             /* No-op.  */
1.1       root     2531:             break;
                   2532:         case 0x4000:
                   2533:             /* MB */
                   2534:             /* No-op */
                   2535:             break;
                   2536:         case 0x4400:
                   2537:             /* WMB */
                   2538:             /* No-op */
                   2539:             break;
                   2540:         case 0x8000:
                   2541:             /* FETCH */
                   2542:             /* No-op */
                   2543:             break;
                   2544:         case 0xA000:
                   2545:             /* FETCH_M */
                   2546:             /* No-op */
                   2547:             break;
                   2548:         case 0xC000:
                   2549:             /* RPCC */
1.1.1.2   root     2550:             if (ra != 31)
                   2551:                 gen_helper_load_pcc(cpu_ir[ra]);
1.1       root     2552:             break;
                   2553:         case 0xE000:
                   2554:             /* RC */
1.1.1.5 ! root     2555:             gen_rx(ra, 0);
1.1       root     2556:             break;
                   2557:         case 0xE800:
                   2558:             /* ECB */
                   2559:             break;
                   2560:         case 0xF000:
                   2561:             /* RS */
1.1.1.5 ! root     2562:             gen_rx(ra, 1);
1.1       root     2563:             break;
                   2564:         case 0xF800:
                   2565:             /* WH64 */
                   2566:             /* No-op */
                   2567:             break;
                   2568:         default:
                   2569:             goto invalid_opc;
                   2570:         }
                   2571:         break;
                   2572:     case 0x19:
                   2573:         /* HW_MFPR (PALcode) */
                   2574: #if defined (CONFIG_USER_ONLY)
                   2575:         goto invalid_opc;
                   2576: #else
                   2577:         if (!ctx->pal_mode)
                   2578:             goto invalid_opc;
1.1.1.2   root     2579:         if (ra != 31) {
                   2580:             TCGv tmp = tcg_const_i32(insn & 0xFF);
                   2581:             gen_helper_mfpr(cpu_ir[ra], tmp, cpu_ir[ra]);
                   2582:             tcg_temp_free(tmp);
                   2583:         }
1.1       root     2584:         break;
                   2585: #endif
                   2586:     case 0x1A:
1.1.1.5 ! root     2587:         /* JMP, JSR, RET, JSR_COROUTINE.  These only differ by the branch
        !          2588:            prediction stack action, which of course we don't implement.  */
        !          2589:         if (rb != 31) {
1.1.1.2   root     2590:             tcg_gen_andi_i64(cpu_pc, cpu_ir[rb], ~3);
1.1.1.5 ! root     2591:         } else {
1.1.1.2   root     2592:             tcg_gen_movi_i64(cpu_pc, 0);
1.1.1.5 ! root     2593:         }
        !          2594:         if (ra != 31) {
1.1.1.2   root     2595:             tcg_gen_movi_i64(cpu_ir[ra], ctx->pc);
1.1       root     2596:         }
1.1.1.5 ! root     2597:         ret = EXIT_PC_UPDATED;
1.1       root     2598:         break;
                   2599:     case 0x1B:
                   2600:         /* HW_LD (PALcode) */
                   2601: #if defined (CONFIG_USER_ONLY)
                   2602:         goto invalid_opc;
                   2603: #else
                   2604:         if (!ctx->pal_mode)
                   2605:             goto invalid_opc;
1.1.1.2   root     2606:         if (ra != 31) {
                   2607:             TCGv addr = tcg_temp_new();
                   2608:             if (rb != 31)
                   2609:                 tcg_gen_addi_i64(addr, cpu_ir[rb], disp12);
                   2610:             else
                   2611:                 tcg_gen_movi_i64(addr, disp12);
                   2612:             switch ((insn >> 12) & 0xF) {
                   2613:             case 0x0:
1.1.1.3   root     2614:                 /* Longword physical access (hw_ldl/p) */
1.1.1.2   root     2615:                 gen_helper_ldl_raw(cpu_ir[ra], addr);
                   2616:                 break;
                   2617:             case 0x1:
1.1.1.3   root     2618:                 /* Quadword physical access (hw_ldq/p) */
1.1.1.2   root     2619:                 gen_helper_ldq_raw(cpu_ir[ra], addr);
                   2620:                 break;
                   2621:             case 0x2:
1.1.1.3   root     2622:                 /* Longword physical access with lock (hw_ldl_l/p) */
1.1.1.2   root     2623:                 gen_helper_ldl_l_raw(cpu_ir[ra], addr);
                   2624:                 break;
                   2625:             case 0x3:
1.1.1.3   root     2626:                 /* Quadword physical access with lock (hw_ldq_l/p) */
1.1.1.2   root     2627:                 gen_helper_ldq_l_raw(cpu_ir[ra], addr);
                   2628:                 break;
                   2629:             case 0x4:
1.1.1.3   root     2630:                 /* Longword virtual PTE fetch (hw_ldl/v) */
                   2631:                 tcg_gen_qemu_ld32s(cpu_ir[ra], addr, 0);
1.1.1.2   root     2632:                 break;
                   2633:             case 0x5:
1.1.1.3   root     2634:                 /* Quadword virtual PTE fetch (hw_ldq/v) */
                   2635:                 tcg_gen_qemu_ld64(cpu_ir[ra], addr, 0);
1.1.1.2   root     2636:                 break;
                   2637:             case 0x6:
                   2638:                 /* Incpu_ir[ra]id */
1.1.1.3   root     2639:                 goto invalid_opc;
1.1.1.2   root     2640:             case 0x7:
                   2641:                 /* Incpu_ir[ra]id */
1.1.1.3   root     2642:                 goto invalid_opc;
1.1.1.2   root     2643:             case 0x8:
1.1.1.3   root     2644:                 /* Longword virtual access (hw_ldl) */
1.1.1.2   root     2645:                 gen_helper_st_virt_to_phys(addr, addr);
                   2646:                 gen_helper_ldl_raw(cpu_ir[ra], addr);
                   2647:                 break;
                   2648:             case 0x9:
1.1.1.3   root     2649:                 /* Quadword virtual access (hw_ldq) */
1.1.1.2   root     2650:                 gen_helper_st_virt_to_phys(addr, addr);
                   2651:                 gen_helper_ldq_raw(cpu_ir[ra], addr);
                   2652:                 break;
                   2653:             case 0xA:
1.1.1.3   root     2654:                 /* Longword virtual access with protection check (hw_ldl/w) */
                   2655:                 tcg_gen_qemu_ld32s(cpu_ir[ra], addr, 0);
1.1.1.2   root     2656:                 break;
                   2657:             case 0xB:
1.1.1.3   root     2658:                 /* Quadword virtual access with protection check (hw_ldq/w) */
                   2659:                 tcg_gen_qemu_ld64(cpu_ir[ra], addr, 0);
1.1.1.2   root     2660:                 break;
                   2661:             case 0xC:
1.1.1.3   root     2662:                 /* Longword virtual access with alt access mode (hw_ldl/a)*/
1.1.1.2   root     2663:                 gen_helper_set_alt_mode();
                   2664:                 gen_helper_st_virt_to_phys(addr, addr);
                   2665:                 gen_helper_ldl_raw(cpu_ir[ra], addr);
                   2666:                 gen_helper_restore_mode();
                   2667:                 break;
                   2668:             case 0xD:
1.1.1.3   root     2669:                 /* Quadword virtual access with alt access mode (hw_ldq/a) */
1.1.1.2   root     2670:                 gen_helper_set_alt_mode();
                   2671:                 gen_helper_st_virt_to_phys(addr, addr);
                   2672:                 gen_helper_ldq_raw(cpu_ir[ra], addr);
                   2673:                 gen_helper_restore_mode();
                   2674:                 break;
                   2675:             case 0xE:
                   2676:                 /* Longword virtual access with alternate access mode and
1.1.1.3   root     2677:                  * protection checks (hw_ldl/wa)
1.1.1.2   root     2678:                  */
                   2679:                 gen_helper_set_alt_mode();
                   2680:                 gen_helper_ldl_data(cpu_ir[ra], addr);
                   2681:                 gen_helper_restore_mode();
                   2682:                 break;
                   2683:             case 0xF:
                   2684:                 /* Quadword virtual access with alternate access mode and
1.1.1.3   root     2685:                  * protection checks (hw_ldq/wa)
1.1.1.2   root     2686:                  */
                   2687:                 gen_helper_set_alt_mode();
                   2688:                 gen_helper_ldq_data(cpu_ir[ra], addr);
                   2689:                 gen_helper_restore_mode();
                   2690:                 break;
                   2691:             }
                   2692:             tcg_temp_free(addr);
1.1       root     2693:         }
                   2694:         break;
                   2695: #endif
                   2696:     case 0x1C:
                   2697:         switch (fn7) {
                   2698:         case 0x00:
                   2699:             /* SEXTB */
                   2700:             if (!(ctx->amask & AMASK_BWX))
                   2701:                 goto invalid_opc;
1.1.1.2   root     2702:             if (likely(rc != 31)) {
                   2703:                 if (islit)
                   2704:                     tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int8_t)lit));
                   2705:                 else
                   2706:                     tcg_gen_ext8s_i64(cpu_ir[rc], cpu_ir[rb]);
                   2707:             }
1.1       root     2708:             break;
                   2709:         case 0x01:
                   2710:             /* SEXTW */
                   2711:             if (!(ctx->amask & AMASK_BWX))
                   2712:                 goto invalid_opc;
1.1.1.2   root     2713:             if (likely(rc != 31)) {
                   2714:                 if (islit)
                   2715:                     tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int16_t)lit));
                   2716:                 else
                   2717:                     tcg_gen_ext16s_i64(cpu_ir[rc], cpu_ir[rb]);
                   2718:             }
1.1       root     2719:             break;
                   2720:         case 0x30:
                   2721:             /* CTPOP */
                   2722:             if (!(ctx->amask & AMASK_CIX))
                   2723:                 goto invalid_opc;
1.1.1.2   root     2724:             if (likely(rc != 31)) {
                   2725:                 if (islit)
                   2726:                     tcg_gen_movi_i64(cpu_ir[rc], ctpop64(lit));
                   2727:                 else
                   2728:                     gen_helper_ctpop(cpu_ir[rc], cpu_ir[rb]);
                   2729:             }
1.1       root     2730:             break;
                   2731:         case 0x31:
                   2732:             /* PERR */
                   2733:             if (!(ctx->amask & AMASK_MVI))
                   2734:                 goto invalid_opc;
1.1.1.5 ! root     2735:             gen_perr(ra, rb, rc, islit, lit);
1.1       root     2736:             break;
                   2737:         case 0x32:
                   2738:             /* CTLZ */
                   2739:             if (!(ctx->amask & AMASK_CIX))
                   2740:                 goto invalid_opc;
1.1.1.2   root     2741:             if (likely(rc != 31)) {
                   2742:                 if (islit)
                   2743:                     tcg_gen_movi_i64(cpu_ir[rc], clz64(lit));
                   2744:                 else
                   2745:                     gen_helper_ctlz(cpu_ir[rc], cpu_ir[rb]);
                   2746:             }
1.1       root     2747:             break;
                   2748:         case 0x33:
                   2749:             /* CTTZ */
                   2750:             if (!(ctx->amask & AMASK_CIX))
                   2751:                 goto invalid_opc;
1.1.1.2   root     2752:             if (likely(rc != 31)) {
                   2753:                 if (islit)
                   2754:                     tcg_gen_movi_i64(cpu_ir[rc], ctz64(lit));
                   2755:                 else
                   2756:                     gen_helper_cttz(cpu_ir[rc], cpu_ir[rb]);
                   2757:             }
1.1       root     2758:             break;
                   2759:         case 0x34:
                   2760:             /* UNPKBW */
                   2761:             if (!(ctx->amask & AMASK_MVI))
                   2762:                 goto invalid_opc;
1.1.1.5 ! root     2763:             if (real_islit || ra != 31)
        !          2764:                 goto invalid_opc;
        !          2765:             gen_unpkbw (rb, rc);
1.1       root     2766:             break;
                   2767:         case 0x35:
1.1.1.5 ! root     2768:             /* UNPKBL */
1.1       root     2769:             if (!(ctx->amask & AMASK_MVI))
                   2770:                 goto invalid_opc;
1.1.1.5 ! root     2771:             if (real_islit || ra != 31)
        !          2772:                 goto invalid_opc;
        !          2773:             gen_unpkbl (rb, rc);
1.1       root     2774:             break;
                   2775:         case 0x36:
                   2776:             /* PKWB */
                   2777:             if (!(ctx->amask & AMASK_MVI))
                   2778:                 goto invalid_opc;
1.1.1.5 ! root     2779:             if (real_islit || ra != 31)
        !          2780:                 goto invalid_opc;
        !          2781:             gen_pkwb (rb, rc);
1.1       root     2782:             break;
                   2783:         case 0x37:
                   2784:             /* PKLB */
                   2785:             if (!(ctx->amask & AMASK_MVI))
                   2786:                 goto invalid_opc;
1.1.1.5 ! root     2787:             if (real_islit || ra != 31)
        !          2788:                 goto invalid_opc;
        !          2789:             gen_pklb (rb, rc);
1.1       root     2790:             break;
                   2791:         case 0x38:
                   2792:             /* MINSB8 */
                   2793:             if (!(ctx->amask & AMASK_MVI))
                   2794:                 goto invalid_opc;
1.1.1.5 ! root     2795:             gen_minsb8 (ra, rb, rc, islit, lit);
1.1       root     2796:             break;
                   2797:         case 0x39:
                   2798:             /* MINSW4 */
                   2799:             if (!(ctx->amask & AMASK_MVI))
                   2800:                 goto invalid_opc;
1.1.1.5 ! root     2801:             gen_minsw4 (ra, rb, rc, islit, lit);
1.1       root     2802:             break;
                   2803:         case 0x3A:
                   2804:             /* MINUB8 */
                   2805:             if (!(ctx->amask & AMASK_MVI))
                   2806:                 goto invalid_opc;
1.1.1.5 ! root     2807:             gen_minub8 (ra, rb, rc, islit, lit);
1.1       root     2808:             break;
                   2809:         case 0x3B:
                   2810:             /* MINUW4 */
                   2811:             if (!(ctx->amask & AMASK_MVI))
                   2812:                 goto invalid_opc;
1.1.1.5 ! root     2813:             gen_minuw4 (ra, rb, rc, islit, lit);
1.1       root     2814:             break;
                   2815:         case 0x3C:
                   2816:             /* MAXUB8 */
                   2817:             if (!(ctx->amask & AMASK_MVI))
                   2818:                 goto invalid_opc;
1.1.1.5 ! root     2819:             gen_maxub8 (ra, rb, rc, islit, lit);
1.1       root     2820:             break;
                   2821:         case 0x3D:
                   2822:             /* MAXUW4 */
                   2823:             if (!(ctx->amask & AMASK_MVI))
                   2824:                 goto invalid_opc;
1.1.1.5 ! root     2825:             gen_maxuw4 (ra, rb, rc, islit, lit);
1.1       root     2826:             break;
                   2827:         case 0x3E:
                   2828:             /* MAXSB8 */
                   2829:             if (!(ctx->amask & AMASK_MVI))
                   2830:                 goto invalid_opc;
1.1.1.5 ! root     2831:             gen_maxsb8 (ra, rb, rc, islit, lit);
1.1       root     2832:             break;
                   2833:         case 0x3F:
                   2834:             /* MAXSW4 */
                   2835:             if (!(ctx->amask & AMASK_MVI))
                   2836:                 goto invalid_opc;
1.1.1.5 ! root     2837:             gen_maxsw4 (ra, rb, rc, islit, lit);
1.1       root     2838:             break;
                   2839:         case 0x70:
                   2840:             /* FTOIT */
                   2841:             if (!(ctx->amask & AMASK_FIX))
                   2842:                 goto invalid_opc;
1.1.1.2   root     2843:             if (likely(rc != 31)) {
                   2844:                 if (ra != 31)
                   2845:                     tcg_gen_mov_i64(cpu_ir[rc], cpu_fir[ra]);
                   2846:                 else
                   2847:                     tcg_gen_movi_i64(cpu_ir[rc], 0);
                   2848:             }
1.1       root     2849:             break;
                   2850:         case 0x78:
                   2851:             /* FTOIS */
                   2852:             if (!(ctx->amask & AMASK_FIX))
                   2853:                 goto invalid_opc;
1.1.1.2   root     2854:             if (rc != 31) {
                   2855:                 TCGv_i32 tmp1 = tcg_temp_new_i32();
                   2856:                 if (ra != 31)
                   2857:                     gen_helper_s_to_memory(tmp1, cpu_fir[ra]);
                   2858:                 else {
                   2859:                     TCGv tmp2 = tcg_const_i64(0);
                   2860:                     gen_helper_s_to_memory(tmp1, tmp2);
                   2861:                     tcg_temp_free(tmp2);
                   2862:                 }
                   2863:                 tcg_gen_ext_i32_i64(cpu_ir[rc], tmp1);
                   2864:                 tcg_temp_free_i32(tmp1);
                   2865:             }
1.1       root     2866:             break;
                   2867:         default:
                   2868:             goto invalid_opc;
                   2869:         }
                   2870:         break;
                   2871:     case 0x1D:
                   2872:         /* HW_MTPR (PALcode) */
                   2873: #if defined (CONFIG_USER_ONLY)
                   2874:         goto invalid_opc;
                   2875: #else
                   2876:         if (!ctx->pal_mode)
                   2877:             goto invalid_opc;
1.1.1.2   root     2878:         else {
                   2879:             TCGv tmp1 = tcg_const_i32(insn & 0xFF);
                   2880:             if (ra != 31)
                   2881:                 gen_helper_mtpr(tmp1, cpu_ir[ra]);
                   2882:             else {
                   2883:                 TCGv tmp2 = tcg_const_i64(0);
                   2884:                 gen_helper_mtpr(tmp1, tmp2);
                   2885:                 tcg_temp_free(tmp2);
                   2886:             }
                   2887:             tcg_temp_free(tmp1);
1.1.1.5 ! root     2888:             ret = EXIT_PC_STALE;
1.1.1.2   root     2889:         }
1.1       root     2890:         break;
                   2891: #endif
                   2892:     case 0x1E:
                   2893:         /* HW_REI (PALcode) */
                   2894: #if defined (CONFIG_USER_ONLY)
                   2895:         goto invalid_opc;
                   2896: #else
                   2897:         if (!ctx->pal_mode)
                   2898:             goto invalid_opc;
                   2899:         if (rb == 31) {
                   2900:             /* "Old" alpha */
1.1.1.2   root     2901:             gen_helper_hw_rei();
1.1       root     2902:         } else {
1.1.1.2   root     2903:             TCGv tmp;
                   2904: 
                   2905:             if (ra != 31) {
                   2906:                 tmp = tcg_temp_new();
                   2907:                 tcg_gen_addi_i64(tmp, cpu_ir[rb], (((int64_t)insn << 51) >> 51));
                   2908:             } else
                   2909:                 tmp = tcg_const_i64(((int64_t)insn << 51) >> 51);
                   2910:             gen_helper_hw_ret(tmp);
                   2911:             tcg_temp_free(tmp);
1.1       root     2912:         }
1.1.1.5 ! root     2913:         ret = EXIT_PC_UPDATED;
1.1       root     2914:         break;
                   2915: #endif
                   2916:     case 0x1F:
                   2917:         /* HW_ST (PALcode) */
                   2918: #if defined (CONFIG_USER_ONLY)
                   2919:         goto invalid_opc;
                   2920: #else
                   2921:         if (!ctx->pal_mode)
                   2922:             goto invalid_opc;
1.1.1.2   root     2923:         else {
                   2924:             TCGv addr, val;
                   2925:             addr = tcg_temp_new();
                   2926:             if (rb != 31)
                   2927:                 tcg_gen_addi_i64(addr, cpu_ir[rb], disp12);
                   2928:             else
                   2929:                 tcg_gen_movi_i64(addr, disp12);
                   2930:             if (ra != 31)
                   2931:                 val = cpu_ir[ra];
                   2932:             else {
                   2933:                 val = tcg_temp_new();
                   2934:                 tcg_gen_movi_i64(val, 0);
                   2935:             }
                   2936:             switch ((insn >> 12) & 0xF) {
                   2937:             case 0x0:
                   2938:                 /* Longword physical access */
                   2939:                 gen_helper_stl_raw(val, addr);
                   2940:                 break;
                   2941:             case 0x1:
                   2942:                 /* Quadword physical access */
                   2943:                 gen_helper_stq_raw(val, addr);
                   2944:                 break;
                   2945:             case 0x2:
                   2946:                 /* Longword physical access with lock */
                   2947:                 gen_helper_stl_c_raw(val, val, addr);
                   2948:                 break;
                   2949:             case 0x3:
                   2950:                 /* Quadword physical access with lock */
                   2951:                 gen_helper_stq_c_raw(val, val, addr);
                   2952:                 break;
                   2953:             case 0x4:
                   2954:                 /* Longword virtual access */
                   2955:                 gen_helper_st_virt_to_phys(addr, addr);
                   2956:                 gen_helper_stl_raw(val, addr);
                   2957:                 break;
                   2958:             case 0x5:
                   2959:                 /* Quadword virtual access */
                   2960:                 gen_helper_st_virt_to_phys(addr, addr);
                   2961:                 gen_helper_stq_raw(val, addr);
                   2962:                 break;
                   2963:             case 0x6:
                   2964:                 /* Invalid */
                   2965:                 goto invalid_opc;
                   2966:             case 0x7:
                   2967:                 /* Invalid */
                   2968:                 goto invalid_opc;
                   2969:             case 0x8:
                   2970:                 /* Invalid */
                   2971:                 goto invalid_opc;
                   2972:             case 0x9:
                   2973:                 /* Invalid */
                   2974:                 goto invalid_opc;
                   2975:             case 0xA:
                   2976:                 /* Invalid */
                   2977:                 goto invalid_opc;
                   2978:             case 0xB:
                   2979:                 /* Invalid */
                   2980:                 goto invalid_opc;
                   2981:             case 0xC:
                   2982:                 /* Longword virtual access with alternate access mode */
                   2983:                 gen_helper_set_alt_mode();
                   2984:                 gen_helper_st_virt_to_phys(addr, addr);
                   2985:                 gen_helper_stl_raw(val, addr);
                   2986:                 gen_helper_restore_mode();
                   2987:                 break;
                   2988:             case 0xD:
                   2989:                 /* Quadword virtual access with alternate access mode */
                   2990:                 gen_helper_set_alt_mode();
                   2991:                 gen_helper_st_virt_to_phys(addr, addr);
                   2992:                 gen_helper_stl_raw(val, addr);
                   2993:                 gen_helper_restore_mode();
                   2994:                 break;
                   2995:             case 0xE:
                   2996:                 /* Invalid */
                   2997:                 goto invalid_opc;
                   2998:             case 0xF:
                   2999:                 /* Invalid */
                   3000:                 goto invalid_opc;
                   3001:             }
1.1.1.3   root     3002:             if (ra == 31)
1.1.1.2   root     3003:                 tcg_temp_free(val);
                   3004:             tcg_temp_free(addr);
1.1       root     3005:         }
                   3006:         break;
                   3007: #endif
                   3008:     case 0x20:
                   3009:         /* LDF */
1.1.1.2   root     3010:         gen_load_mem(ctx, &gen_qemu_ldf, ra, rb, disp16, 1, 0);
1.1       root     3011:         break;
                   3012:     case 0x21:
                   3013:         /* LDG */
1.1.1.2   root     3014:         gen_load_mem(ctx, &gen_qemu_ldg, ra, rb, disp16, 1, 0);
1.1       root     3015:         break;
                   3016:     case 0x22:
                   3017:         /* LDS */
1.1.1.2   root     3018:         gen_load_mem(ctx, &gen_qemu_lds, ra, rb, disp16, 1, 0);
1.1       root     3019:         break;
                   3020:     case 0x23:
                   3021:         /* LDT */
1.1.1.2   root     3022:         gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 1, 0);
1.1       root     3023:         break;
                   3024:     case 0x24:
                   3025:         /* STF */
1.1.1.5 ! root     3026:         gen_store_mem(ctx, &gen_qemu_stf, ra, rb, disp16, 1, 0);
1.1       root     3027:         break;
                   3028:     case 0x25:
                   3029:         /* STG */
1.1.1.5 ! root     3030:         gen_store_mem(ctx, &gen_qemu_stg, ra, rb, disp16, 1, 0);
1.1       root     3031:         break;
                   3032:     case 0x26:
                   3033:         /* STS */
1.1.1.5 ! root     3034:         gen_store_mem(ctx, &gen_qemu_sts, ra, rb, disp16, 1, 0);
1.1       root     3035:         break;
                   3036:     case 0x27:
                   3037:         /* STT */
1.1.1.5 ! root     3038:         gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 1, 0);
1.1       root     3039:         break;
                   3040:     case 0x28:
                   3041:         /* LDL */
1.1.1.2   root     3042:         gen_load_mem(ctx, &tcg_gen_qemu_ld32s, ra, rb, disp16, 0, 0);
1.1       root     3043:         break;
                   3044:     case 0x29:
                   3045:         /* LDQ */
1.1.1.2   root     3046:         gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 0);
1.1       root     3047:         break;
                   3048:     case 0x2A:
                   3049:         /* LDL_L */
1.1.1.2   root     3050:         gen_load_mem(ctx, &gen_qemu_ldl_l, ra, rb, disp16, 0, 0);
1.1       root     3051:         break;
                   3052:     case 0x2B:
                   3053:         /* LDQ_L */
1.1.1.2   root     3054:         gen_load_mem(ctx, &gen_qemu_ldq_l, ra, rb, disp16, 0, 0);
1.1       root     3055:         break;
                   3056:     case 0x2C:
                   3057:         /* STL */
1.1.1.5 ! root     3058:         gen_store_mem(ctx, &tcg_gen_qemu_st32, ra, rb, disp16, 0, 0);
1.1       root     3059:         break;
                   3060:     case 0x2D:
                   3061:         /* STQ */
1.1.1.5 ! root     3062:         gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 0);
1.1       root     3063:         break;
                   3064:     case 0x2E:
                   3065:         /* STL_C */
1.1.1.5 ! root     3066:         ret = gen_store_conditional(ctx, ra, rb, disp16, 0);
1.1       root     3067:         break;
                   3068:     case 0x2F:
                   3069:         /* STQ_C */
1.1.1.5 ! root     3070:         ret = gen_store_conditional(ctx, ra, rb, disp16, 1);
1.1       root     3071:         break;
                   3072:     case 0x30:
                   3073:         /* BR */
1.1.1.5 ! root     3074:         ret = gen_bdirect(ctx, ra, disp21);
1.1       root     3075:         break;
1.1.1.2   root     3076:     case 0x31: /* FBEQ */
1.1.1.5 ! root     3077:         ret = gen_fbcond(ctx, TCG_COND_EQ, ra, disp21);
        !          3078:         break;
1.1.1.2   root     3079:     case 0x32: /* FBLT */
1.1.1.5 ! root     3080:         ret = gen_fbcond(ctx, TCG_COND_LT, ra, disp21);
        !          3081:         break;
1.1.1.2   root     3082:     case 0x33: /* FBLE */
1.1.1.5 ! root     3083:         ret = gen_fbcond(ctx, TCG_COND_LE, ra, disp21);
1.1       root     3084:         break;
                   3085:     case 0x34:
                   3086:         /* BSR */
1.1.1.5 ! root     3087:         ret = gen_bdirect(ctx, ra, disp21);
1.1       root     3088:         break;
1.1.1.2   root     3089:     case 0x35: /* FBNE */
1.1.1.5 ! root     3090:         ret = gen_fbcond(ctx, TCG_COND_NE, ra, disp21);
        !          3091:         break;
1.1.1.2   root     3092:     case 0x36: /* FBGE */
1.1.1.5 ! root     3093:         ret = gen_fbcond(ctx, TCG_COND_GE, ra, disp21);
        !          3094:         break;
1.1.1.2   root     3095:     case 0x37: /* FBGT */
1.1.1.5 ! root     3096:         ret = gen_fbcond(ctx, TCG_COND_GT, ra, disp21);
1.1       root     3097:         break;
                   3098:     case 0x38:
                   3099:         /* BLBC */
1.1.1.5 ! root     3100:         ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 1);
1.1       root     3101:         break;
                   3102:     case 0x39:
                   3103:         /* BEQ */
1.1.1.5 ! root     3104:         ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 0);
1.1       root     3105:         break;
                   3106:     case 0x3A:
                   3107:         /* BLT */
1.1.1.5 ! root     3108:         ret = gen_bcond(ctx, TCG_COND_LT, ra, disp21, 0);
1.1       root     3109:         break;
                   3110:     case 0x3B:
                   3111:         /* BLE */
1.1.1.5 ! root     3112:         ret = gen_bcond(ctx, TCG_COND_LE, ra, disp21, 0);
1.1       root     3113:         break;
                   3114:     case 0x3C:
                   3115:         /* BLBS */
1.1.1.5 ! root     3116:         ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21, 1);
1.1       root     3117:         break;
                   3118:     case 0x3D:
                   3119:         /* BNE */
1.1.1.5 ! root     3120:         ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21, 0);
1.1       root     3121:         break;
                   3122:     case 0x3E:
                   3123:         /* BGE */
1.1.1.5 ! root     3124:         ret = gen_bcond(ctx, TCG_COND_GE, ra, disp21, 0);
1.1       root     3125:         break;
                   3126:     case 0x3F:
                   3127:         /* BGT */
1.1.1.5 ! root     3128:         ret = gen_bcond(ctx, TCG_COND_GT, ra, disp21, 0);
1.1       root     3129:         break;
                   3130:     invalid_opc:
1.1.1.5 ! root     3131:         ret = gen_invalid(ctx);
1.1       root     3132:         break;
                   3133:     }
                   3134: 
                   3135:     return ret;
                   3136: }
                   3137: 
1.1.1.4   root     3138: static inline void gen_intermediate_code_internal(CPUState *env,
                   3139:                                                   TranslationBlock *tb,
                   3140:                                                   int search_pc)
1.1       root     3141: {
                   3142:     DisasContext ctx, *ctxp = &ctx;
                   3143:     target_ulong pc_start;
                   3144:     uint32_t insn;
                   3145:     uint16_t *gen_opc_end;
1.1.1.2   root     3146:     CPUBreakpoint *bp;
1.1       root     3147:     int j, lj = -1;
1.1.1.5 ! root     3148:     ExitStatus ret;
1.1.1.2   root     3149:     int num_insns;
                   3150:     int max_insns;
1.1       root     3151: 
                   3152:     pc_start = tb->pc;
                   3153:     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1.1.1.5 ! root     3154: 
        !          3155:     ctx.tb = tb;
        !          3156:     ctx.env = env;
1.1       root     3157:     ctx.pc = pc_start;
                   3158:     ctx.amask = env->amask;
                   3159: #if defined (CONFIG_USER_ONLY)
                   3160:     ctx.mem_idx = 0;
                   3161: #else
                   3162:     ctx.mem_idx = ((env->ps >> 3) & 3);
                   3163:     ctx.pal_mode = env->ipr[IPR_EXC_ADDR] & 1;
                   3164: #endif
1.1.1.5 ! root     3165: 
        !          3166:     /* ??? Every TB begins with unset rounding mode, to be initialized on
        !          3167:        the first fp insn of the TB.  Alternately we could define a proper
        !          3168:        default for every TB (e.g. QUAL_RM_N or QUAL_RM_D) and make sure
        !          3169:        to reset the FP_STATUS to that default at the end of any TB that
        !          3170:        changes the default.  We could even (gasp) dynamiclly figure out
        !          3171:        what default would be most efficient given the running program.  */
        !          3172:     ctx.tb_rm = -1;
        !          3173:     /* Similarly for flush-to-zero.  */
        !          3174:     ctx.tb_ftz = -1;
        !          3175: 
1.1.1.2   root     3176:     num_insns = 0;
                   3177:     max_insns = tb->cflags & CF_COUNT_MASK;
                   3178:     if (max_insns == 0)
                   3179:         max_insns = CF_COUNT_MASK;
                   3180: 
                   3181:     gen_icount_start();
1.1.1.5 ! root     3182:     do {
1.1.1.4   root     3183:         if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
                   3184:             QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
1.1.1.2   root     3185:                 if (bp->pc == ctx.pc) {
1.1       root     3186:                     gen_excp(&ctx, EXCP_DEBUG, 0);
                   3187:                     break;
                   3188:                 }
                   3189:             }
                   3190:         }
                   3191:         if (search_pc) {
                   3192:             j = gen_opc_ptr - gen_opc_buf;
                   3193:             if (lj < j) {
                   3194:                 lj++;
                   3195:                 while (lj < j)
                   3196:                     gen_opc_instr_start[lj++] = 0;
                   3197:             }
1.1.1.3   root     3198:             gen_opc_pc[lj] = ctx.pc;
                   3199:             gen_opc_instr_start[lj] = 1;
                   3200:             gen_opc_icount[lj] = num_insns;
1.1       root     3201:         }
1.1.1.2   root     3202:         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
                   3203:             gen_io_start();
1.1       root     3204:         insn = ldl_code(ctx.pc);
1.1.1.2   root     3205:         num_insns++;
                   3206: 
1.1.1.5 ! root     3207:        if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
        !          3208:             tcg_gen_debug_insn_start(ctx.pc);
        !          3209:         }
1.1.1.3   root     3210: 
1.1.1.5 ! root     3211:         ctx.pc += 4;
        !          3212:         ret = translate_one(ctxp, insn);
1.1.1.3   root     3213: 
1.1.1.5 ! root     3214:         if (ret == NO_EXIT) {
        !          3215:             /* If we reach a page boundary, are single stepping,
        !          3216:                or exhaust instruction count, stop generation.  */
        !          3217:             if (env->singlestep_enabled) {
        !          3218:                 gen_excp(&ctx, EXCP_DEBUG, 0);
        !          3219:                 ret = EXIT_PC_UPDATED;
        !          3220:             } else if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0
        !          3221:                        || gen_opc_ptr >= gen_opc_end
        !          3222:                        || num_insns >= max_insns
        !          3223:                        || singlestep) {
        !          3224:                 ret = EXIT_PC_STALE;
        !          3225:             }
1.1.1.3   root     3226:         }
1.1.1.5 ! root     3227:     } while (ret == NO_EXIT);
        !          3228: 
        !          3229:     if (tb->cflags & CF_LAST_IO) {
        !          3230:         gen_io_end();
1.1       root     3231:     }
1.1.1.5 ! root     3232: 
        !          3233:     switch (ret) {
        !          3234:     case EXIT_GOTO_TB:
        !          3235:     case EXIT_NORETURN:
        !          3236:         break;
        !          3237:     case EXIT_PC_STALE:
1.1.1.2   root     3238:         tcg_gen_movi_i64(cpu_pc, ctx.pc);
1.1.1.5 ! root     3239:         /* FALLTHRU */
        !          3240:     case EXIT_PC_UPDATED:
        !          3241:         tcg_gen_exit_tb(0);
        !          3242:         break;
        !          3243:     default:
        !          3244:         abort();
1.1       root     3245:     }
1.1.1.5 ! root     3246: 
1.1.1.2   root     3247:     gen_icount_end(tb, num_insns);
1.1       root     3248:     *gen_opc_ptr = INDEX_op_end;
                   3249:     if (search_pc) {
                   3250:         j = gen_opc_ptr - gen_opc_buf;
                   3251:         lj++;
                   3252:         while (lj <= j)
                   3253:             gen_opc_instr_start[lj++] = 0;
                   3254:     } else {
                   3255:         tb->size = ctx.pc - pc_start;
1.1.1.2   root     3256:         tb->icount = num_insns;
1.1       root     3257:     }
1.1.1.5 ! root     3258: 
        !          3259: #ifdef DEBUG_DISAS
1.1.1.2   root     3260:     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
                   3261:         qemu_log("IN: %s\n", lookup_symbol(pc_start));
                   3262:         log_target_disas(pc_start, ctx.pc - pc_start, 1);
                   3263:         qemu_log("\n");
1.1       root     3264:     }
                   3265: #endif
                   3266: }
                   3267: 
1.1.1.2   root     3268: void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
1.1       root     3269: {
1.1.1.2   root     3270:     gen_intermediate_code_internal(env, tb, 0);
1.1       root     3271: }
                   3272: 
1.1.1.2   root     3273: void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
1.1       root     3274: {
1.1.1.2   root     3275:     gen_intermediate_code_internal(env, tb, 1);
1.1       root     3276: }
                   3277: 
1.1.1.5 ! root     3278: struct cpu_def_t {
        !          3279:     const char *name;
        !          3280:     int implver, amask;
        !          3281: };
        !          3282: 
        !          3283: static const struct cpu_def_t cpu_defs[] = {
        !          3284:     { "ev4",   IMPLVER_2106x, 0 },
        !          3285:     { "ev5",   IMPLVER_21164, 0 },
        !          3286:     { "ev56",  IMPLVER_21164, AMASK_BWX },
        !          3287:     { "pca56", IMPLVER_21164, AMASK_BWX | AMASK_MVI },
        !          3288:     { "ev6",   IMPLVER_21264, AMASK_BWX | AMASK_FIX | AMASK_MVI | AMASK_TRAP },
        !          3289:     { "ev67",  IMPLVER_21264, (AMASK_BWX | AMASK_FIX | AMASK_CIX
        !          3290:                               | AMASK_MVI | AMASK_TRAP | AMASK_PREFETCH), },
        !          3291:     { "ev68",  IMPLVER_21264, (AMASK_BWX | AMASK_FIX | AMASK_CIX
        !          3292:                               | AMASK_MVI | AMASK_TRAP | AMASK_PREFETCH), },
        !          3293:     { "21064", IMPLVER_2106x, 0 },
        !          3294:     { "21164", IMPLVER_21164, 0 },
        !          3295:     { "21164a", IMPLVER_21164, AMASK_BWX },
        !          3296:     { "21164pc", IMPLVER_21164, AMASK_BWX | AMASK_MVI },
        !          3297:     { "21264", IMPLVER_21264, AMASK_BWX | AMASK_FIX | AMASK_MVI | AMASK_TRAP },
        !          3298:     { "21264a", IMPLVER_21264, (AMASK_BWX | AMASK_FIX | AMASK_CIX
        !          3299:                                | AMASK_MVI | AMASK_TRAP | AMASK_PREFETCH), }
        !          3300: };
        !          3301: 
1.1       root     3302: CPUAlphaState * cpu_alpha_init (const char *cpu_model)
                   3303: {
                   3304:     CPUAlphaState *env;
1.1.1.5 ! root     3305:     int implver, amask, i, max;
1.1       root     3306: 
                   3307:     env = qemu_mallocz(sizeof(CPUAlphaState));
                   3308:     cpu_exec_init(env);
1.1.1.2   root     3309:     alpha_translate_init();
1.1       root     3310:     tlb_flush(env, 1);
1.1.1.5 ! root     3311: 
        !          3312:     /* Default to ev67; no reason not to emulate insns by default.  */
        !          3313:     implver = IMPLVER_21264;
        !          3314:     amask = (AMASK_BWX | AMASK_FIX | AMASK_CIX | AMASK_MVI
        !          3315:             | AMASK_TRAP | AMASK_PREFETCH);
        !          3316: 
        !          3317:     max = ARRAY_SIZE(cpu_defs);
        !          3318:     for (i = 0; i < max; i++) {
        !          3319:         if (strcmp (cpu_model, cpu_defs[i].name) == 0) {
        !          3320:             implver = cpu_defs[i].implver;
        !          3321:             amask = cpu_defs[i].amask;
        !          3322:             break;
        !          3323:         }
        !          3324:     }
        !          3325:     env->implver = implver;
        !          3326:     env->amask = amask;
        !          3327: 
1.1       root     3328:     env->ps = 0x1F00;
                   3329: #if defined (CONFIG_USER_ONLY)
                   3330:     env->ps |= 1 << 3;
1.1.1.5 ! root     3331:     cpu_alpha_store_fpcr(env, (FPCR_INVD | FPCR_DZED | FPCR_OVFD
        !          3332:                                | FPCR_UNFD | FPCR_INED | FPCR_DNOD));
        !          3333: #else
1.1       root     3334:     pal_init(env);
1.1.1.5 ! root     3335: #endif
        !          3336:     env->lock_addr = -1;
        !          3337: 
1.1       root     3338:     /* Initialize IPR */
1.1.1.5 ! root     3339: #if defined (CONFIG_USER_ONLY)
        !          3340:     env->ipr[IPR_EXC_ADDR] = 0;
        !          3341:     env->ipr[IPR_EXC_SUM] = 0;
        !          3342:     env->ipr[IPR_EXC_MASK] = 0;
        !          3343: #else
        !          3344:     {
        !          3345:         // uint64_t hwpcb;
        !          3346:         // hwpcb = env->ipr[IPR_PCBB];
        !          3347:         env->ipr[IPR_ASN] = 0;
        !          3348:         env->ipr[IPR_ASTEN] = 0;
        !          3349:         env->ipr[IPR_ASTSR] = 0;
        !          3350:         env->ipr[IPR_DATFX] = 0;
        !          3351:         /* XXX: fix this */
        !          3352:         //    env->ipr[IPR_ESP] = ldq_raw(hwpcb + 8);
        !          3353:         //    env->ipr[IPR_KSP] = ldq_raw(hwpcb + 0);
        !          3354:         //    env->ipr[IPR_SSP] = ldq_raw(hwpcb + 16);
        !          3355:         //    env->ipr[IPR_USP] = ldq_raw(hwpcb + 24);
        !          3356:         env->ipr[IPR_FEN] = 0;
        !          3357:         env->ipr[IPR_IPL] = 31;
        !          3358:         env->ipr[IPR_MCES] = 0;
        !          3359:         env->ipr[IPR_PERFMON] = 0; /* Implementation specific */
        !          3360:         //    env->ipr[IPR_PTBR] = ldq_raw(hwpcb + 32);
        !          3361:         env->ipr[IPR_SISR] = 0;
        !          3362:         env->ipr[IPR_VIRBND] = -1ULL;
        !          3363:     }
        !          3364: #endif
1.1       root     3365: 
1.1.1.3   root     3366:     qemu_init_vcpu(env);
1.1       root     3367:     return env;
                   3368: }
                   3369: 
1.1.1.2   root     3370: void gen_pc_load(CPUState *env, TranslationBlock *tb,
                   3371:                 unsigned long searched_pc, int pc_pos, void *puc)
                   3372: {
                   3373:     env->pc = gen_opc_pc[pc_pos];
                   3374: }

unix.superglobalmegacorp.com

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