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

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

unix.superglobalmegacorp.com

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