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

1.1       root        1: /*
                      2:  *  Alpha emulation cpu translation for qemu.
                      3:  *
                      4:  *  Copyright (c) 2007 Jocelyn Mayer
                      5:  *
                      6:  * This library is free software; you can redistribute it and/or
                      7:  * modify it under the terms of the GNU Lesser General Public
                      8:  * License as published by the Free Software Foundation; either
                      9:  * version 2 of the License, or (at your option) any later version.
                     10:  *
                     11:  * This library is distributed in the hope that it will be useful,
                     12:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     14:  * Lesser General Public License for more details.
                     15:  *
                     16:  * You should have received a copy of the GNU Lesser General Public
1.1.1.3   root       17:  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
1.1       root       18:  */
                     19: 
                     20: #include <stdint.h>
                     21: #include <stdlib.h>
                     22: #include <stdio.h>
                     23: 
                     24: #include "cpu.h"
                     25: #include "exec-all.h"
                     26: #include "disas.h"
1.1.1.2   root       27: #include "host-utils.h"
                     28: #include "tcg-op.h"
                     29: #include "qemu-common.h"
                     30: 
                     31: #include "helper.h"
                     32: #define GEN_HELPER 1
                     33: #include "helper.h"
1.1       root       34: 
1.1.1.2   root       35: /* #define DO_SINGLE_STEP */
1.1       root       36: #define ALPHA_DEBUG_DISAS
1.1.1.2   root       37: /* #define DO_TB_FLUSH */
                     38: 
                     39: 
                     40: #ifdef ALPHA_DEBUG_DISAS
                     41: #  define LOG_DISAS(...) qemu_log(__VA_ARGS__)
                     42: #else
                     43: #  define LOG_DISAS(...) do { } while (0)
                     44: #endif
1.1       root       45: 
                     46: typedef struct DisasContext DisasContext;
                     47: struct DisasContext {
                     48:     uint64_t pc;
                     49:     int mem_idx;
                     50: #if !defined (CONFIG_USER_ONLY)
                     51:     int pal_mode;
                     52: #endif
1.1.1.3   root       53:     CPUAlphaState *env;
1.1       root       54:     uint32_t amask;
                     55: };
                     56: 
1.1.1.2   root       57: /* global register indexes */
                     58: static TCGv_ptr cpu_env;
                     59: static TCGv cpu_ir[31];
                     60: static TCGv cpu_fir[31];
                     61: static TCGv cpu_pc;
                     62: static TCGv cpu_lock;
1.1       root       63: 
1.1.1.2   root       64: /* register names */
                     65: static char cpu_reg_names[10*4+21*5 + 10*5+21*6];
1.1       root       66: 
1.1.1.2   root       67: #include "gen-icount.h"
1.1       root       68: 
1.1.1.2   root       69: static void alpha_translate_init(void)
1.1       root       70: {
1.1.1.2   root       71:     int i;
                     72:     char *p;
                     73:     static int done_init = 0;
1.1       root       74: 
1.1.1.2   root       75:     if (done_init)
                     76:         return;
1.1       root       77: 
1.1.1.2   root       78:     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
1.1       root       79: 
1.1.1.2   root       80:     p = cpu_reg_names;
                     81:     for (i = 0; i < 31; i++) {
                     82:         sprintf(p, "ir%d", i);
                     83:         cpu_ir[i] = tcg_global_mem_new_i64(TCG_AREG0,
                     84:                                            offsetof(CPUState, ir[i]), p);
                     85:         p += (i < 10) ? 4 : 5;
1.1       root       86: 
1.1.1.2   root       87:         sprintf(p, "fir%d", i);
                     88:         cpu_fir[i] = tcg_global_mem_new_i64(TCG_AREG0,
                     89:                                             offsetof(CPUState, fir[i]), p);
                     90:         p += (i < 10) ? 5 : 6;
1.1       root       91:     }
                     92: 
1.1.1.2   root       93:     cpu_pc = tcg_global_mem_new_i64(TCG_AREG0,
                     94:                                     offsetof(CPUState, pc), "pc");
1.1       root       95: 
1.1.1.2   root       96:     cpu_lock = tcg_global_mem_new_i64(TCG_AREG0,
                     97:                                       offsetof(CPUState, lock), "lock");
1.1       root       98: 
1.1.1.2   root       99:     /* register helpers */
                    100: #define GEN_HELPER 2
                    101: #include "helper.h"
1.1       root      102: 
1.1.1.2   root      103:     done_init = 1;
                    104: }
1.1       root      105: 
1.1.1.4 ! root      106: static inline void gen_excp(DisasContext *ctx, int exception, int error_code)
1.1       root      107: {
1.1.1.2   root      108:     TCGv_i32 tmp1, tmp2;
                    109: 
                    110:     tcg_gen_movi_i64(cpu_pc, ctx->pc);
                    111:     tmp1 = tcg_const_i32(exception);
                    112:     tmp2 = tcg_const_i32(error_code);
                    113:     gen_helper_excp(tmp1, tmp2);
                    114:     tcg_temp_free_i32(tmp2);
                    115:     tcg_temp_free_i32(tmp1);
1.1       root      116: }
                    117: 
1.1.1.4 ! root      118: static inline void gen_invalid(DisasContext *ctx)
1.1       root      119: {
1.1.1.2   root      120:     gen_excp(ctx, EXCP_OPCDEC, 0);
1.1       root      121: }
                    122: 
1.1.1.4 ! root      123: static inline void gen_qemu_ldf(TCGv t0, TCGv t1, int flags)
1.1       root      124: {
1.1.1.2   root      125:     TCGv tmp = tcg_temp_new();
                    126:     TCGv_i32 tmp32 = tcg_temp_new_i32();
                    127:     tcg_gen_qemu_ld32u(tmp, t1, flags);
                    128:     tcg_gen_trunc_i64_i32(tmp32, tmp);
                    129:     gen_helper_memory_to_f(t0, tmp32);
                    130:     tcg_temp_free_i32(tmp32);
                    131:     tcg_temp_free(tmp);
1.1       root      132: }
                    133: 
1.1.1.4 ! root      134: static inline void gen_qemu_ldg(TCGv t0, TCGv t1, int flags)
1.1       root      135: {
1.1.1.2   root      136:     TCGv tmp = tcg_temp_new();
                    137:     tcg_gen_qemu_ld64(tmp, t1, flags);
                    138:     gen_helper_memory_to_g(t0, tmp);
                    139:     tcg_temp_free(tmp);
1.1       root      140: }
                    141: 
1.1.1.4 ! root      142: static inline void gen_qemu_lds(TCGv t0, TCGv t1, int flags)
1.1       root      143: {
1.1.1.2   root      144:     TCGv tmp = tcg_temp_new();
                    145:     TCGv_i32 tmp32 = tcg_temp_new_i32();
                    146:     tcg_gen_qemu_ld32u(tmp, t1, flags);
                    147:     tcg_gen_trunc_i64_i32(tmp32, tmp);
                    148:     gen_helper_memory_to_s(t0, tmp32);
                    149:     tcg_temp_free_i32(tmp32);
                    150:     tcg_temp_free(tmp);
1.1       root      151: }
                    152: 
1.1.1.4 ! root      153: static inline void gen_qemu_ldl_l(TCGv t0, TCGv t1, int flags)
1.1       root      154: {
1.1.1.2   root      155:     tcg_gen_mov_i64(cpu_lock, t1);
                    156:     tcg_gen_qemu_ld32s(t0, t1, flags);
1.1       root      157: }
                    158: 
1.1.1.4 ! root      159: static inline void gen_qemu_ldq_l(TCGv t0, TCGv t1, int flags)
1.1       root      160: {
1.1.1.2   root      161:     tcg_gen_mov_i64(cpu_lock, t1);
                    162:     tcg_gen_qemu_ld64(t0, t1, flags);
1.1       root      163: }
                    164: 
1.1.1.4 ! root      165: static inline void gen_load_mem(DisasContext *ctx,
        !           166:                                 void (*tcg_gen_qemu_load)(TCGv t0, TCGv t1,
        !           167:                                                           int flags),
        !           168:                                 int ra, int rb, int32_t disp16, int fp,
        !           169:                                 int clear)
1.1       root      170: {
1.1.1.2   root      171:     TCGv addr;
                    172: 
                    173:     if (unlikely(ra == 31))
                    174:         return;
                    175: 
                    176:     addr = tcg_temp_new();
                    177:     if (rb != 31) {
                    178:         tcg_gen_addi_i64(addr, cpu_ir[rb], disp16);
                    179:         if (clear)
                    180:             tcg_gen_andi_i64(addr, addr, ~0x7);
1.1       root      181:     } else {
1.1.1.2   root      182:         if (clear)
                    183:             disp16 &= ~0x7;
                    184:         tcg_gen_movi_i64(addr, disp16);
1.1       root      185:     }
1.1.1.2   root      186:     if (fp)
                    187:         tcg_gen_qemu_load(cpu_fir[ra], addr, ctx->mem_idx);
                    188:     else
                    189:         tcg_gen_qemu_load(cpu_ir[ra], addr, ctx->mem_idx);
                    190:     tcg_temp_free(addr);
1.1       root      191: }
                    192: 
1.1.1.4 ! root      193: static inline void gen_qemu_stf(TCGv t0, TCGv t1, int flags)
1.1       root      194: {
1.1.1.2   root      195:     TCGv_i32 tmp32 = tcg_temp_new_i32();
                    196:     TCGv tmp = tcg_temp_new();
                    197:     gen_helper_f_to_memory(tmp32, t0);
                    198:     tcg_gen_extu_i32_i64(tmp, tmp32);
                    199:     tcg_gen_qemu_st32(tmp, t1, flags);
                    200:     tcg_temp_free(tmp);
                    201:     tcg_temp_free_i32(tmp32);
1.1       root      202: }
                    203: 
1.1.1.4 ! root      204: static inline void gen_qemu_stg(TCGv t0, TCGv t1, int flags)
1.1       root      205: {
1.1.1.2   root      206:     TCGv tmp = tcg_temp_new();
                    207:     gen_helper_g_to_memory(tmp, t0);
                    208:     tcg_gen_qemu_st64(tmp, t1, flags);
                    209:     tcg_temp_free(tmp);
1.1       root      210: }
                    211: 
1.1.1.4 ! root      212: static inline void gen_qemu_sts(TCGv t0, TCGv t1, int flags)
1.1       root      213: {
1.1.1.2   root      214:     TCGv_i32 tmp32 = tcg_temp_new_i32();
                    215:     TCGv tmp = tcg_temp_new();
                    216:     gen_helper_s_to_memory(tmp32, t0);
                    217:     tcg_gen_extu_i32_i64(tmp, tmp32);
                    218:     tcg_gen_qemu_st32(tmp, t1, flags);
                    219:     tcg_temp_free(tmp);
                    220:     tcg_temp_free_i32(tmp32);
1.1       root      221: }
                    222: 
1.1.1.4 ! root      223: static inline void gen_qemu_stl_c(TCGv t0, TCGv t1, int flags)
1.1       root      224: {
1.1.1.2   root      225:     int l1, l2;
                    226: 
                    227:     l1 = gen_new_label();
                    228:     l2 = gen_new_label();
                    229:     tcg_gen_brcond_i64(TCG_COND_NE, cpu_lock, t1, l1);
                    230:     tcg_gen_qemu_st32(t0, t1, flags);
                    231:     tcg_gen_movi_i64(t0, 1);
                    232:     tcg_gen_br(l2);
                    233:     gen_set_label(l1);
                    234:     tcg_gen_movi_i64(t0, 0);
                    235:     gen_set_label(l2);
                    236:     tcg_gen_movi_i64(cpu_lock, -1);
1.1       root      237: }
                    238: 
1.1.1.4 ! root      239: static inline void gen_qemu_stq_c(TCGv t0, TCGv t1, int flags)
1.1       root      240: {
1.1.1.2   root      241:     int l1, l2;
                    242: 
                    243:     l1 = gen_new_label();
                    244:     l2 = gen_new_label();
                    245:     tcg_gen_brcond_i64(TCG_COND_NE, cpu_lock, t1, l1);
                    246:     tcg_gen_qemu_st64(t0, t1, flags);
                    247:     tcg_gen_movi_i64(t0, 1);
                    248:     tcg_gen_br(l2);
                    249:     gen_set_label(l1);
                    250:     tcg_gen_movi_i64(t0, 0);
                    251:     gen_set_label(l2);
                    252:     tcg_gen_movi_i64(cpu_lock, -1);
1.1       root      253: }
                    254: 
1.1.1.4 ! root      255: static inline void gen_store_mem(DisasContext *ctx,
        !           256:                                  void (*tcg_gen_qemu_store)(TCGv t0, TCGv t1,
        !           257:                                                             int flags),
        !           258:                                  int ra, int rb, int32_t disp16, int fp,
        !           259:                                  int clear, int local)
1.1       root      260: {
1.1.1.2   root      261:     TCGv addr;
                    262:     if (local)
                    263:         addr = tcg_temp_local_new();
                    264:     else
                    265:         addr = tcg_temp_new();
                    266:     if (rb != 31) {
                    267:         tcg_gen_addi_i64(addr, cpu_ir[rb], disp16);
                    268:         if (clear)
                    269:             tcg_gen_andi_i64(addr, addr, ~0x7);
                    270:     } else {
                    271:         if (clear)
                    272:             disp16 &= ~0x7;
                    273:         tcg_gen_movi_i64(addr, disp16);
1.1       root      274:     }
1.1.1.2   root      275:     if (ra != 31) {
                    276:         if (fp)
                    277:             tcg_gen_qemu_store(cpu_fir[ra], addr, ctx->mem_idx);
                    278:         else
                    279:             tcg_gen_qemu_store(cpu_ir[ra], addr, ctx->mem_idx);
                    280:     } else {
                    281:         TCGv zero;
                    282:         if (local)
                    283:             zero = tcg_const_local_i64(0);
                    284:         else
                    285:             zero = tcg_const_i64(0);
                    286:         tcg_gen_qemu_store(zero, addr, ctx->mem_idx);
                    287:         tcg_temp_free(zero);
1.1       root      288:     }
1.1.1.2   root      289:     tcg_temp_free(addr);
1.1       root      290: }
                    291: 
1.1.1.4 ! root      292: static inline void gen_bcond(DisasContext *ctx, TCGCond cond, int ra,
        !           293:                              int32_t disp, int mask)
1.1       root      294: {
1.1.1.2   root      295:     int l1, l2;
                    296: 
                    297:     l1 = gen_new_label();
                    298:     l2 = gen_new_label();
                    299:     if (likely(ra != 31)) {
                    300:         if (mask) {
                    301:             TCGv tmp = tcg_temp_new();
                    302:             tcg_gen_andi_i64(tmp, cpu_ir[ra], 1);
                    303:             tcg_gen_brcondi_i64(cond, tmp, 0, l1);
                    304:             tcg_temp_free(tmp);
                    305:         } else
                    306:             tcg_gen_brcondi_i64(cond, cpu_ir[ra], 0, l1);
1.1       root      307:     } else {
1.1.1.2   root      308:         /* Very uncommon case - Do not bother to optimize.  */
                    309:         TCGv tmp = tcg_const_i64(0);
                    310:         tcg_gen_brcondi_i64(cond, tmp, 0, l1);
                    311:         tcg_temp_free(tmp);
                    312:     }
                    313:     tcg_gen_movi_i64(cpu_pc, ctx->pc);
                    314:     tcg_gen_br(l2);
                    315:     gen_set_label(l1);
1.1.1.3   root      316:     tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp << 2));
1.1.1.2   root      317:     gen_set_label(l2);
1.1       root      318: }
                    319: 
1.1.1.4 ! root      320: static inline void gen_fbcond(DisasContext *ctx, int opc, int ra,
        !           321:                               int32_t disp16)
1.1       root      322: {
1.1.1.2   root      323:     int l1, l2;
                    324:     TCGv tmp;
                    325:     TCGv src;
                    326: 
                    327:     l1 = gen_new_label();
                    328:     l2 = gen_new_label();
                    329:     if (ra != 31) {
                    330:         tmp = tcg_temp_new();
                    331:         src = cpu_fir[ra];
                    332:     } else  {
                    333:         tmp = tcg_const_i64(0);
                    334:         src = tmp;
1.1       root      335:     }
1.1.1.2   root      336:     switch (opc) {
                    337:     case 0x31: /* FBEQ */
                    338:         gen_helper_cmpfeq(tmp, src);
                    339:         break;
                    340:     case 0x32: /* FBLT */
                    341:         gen_helper_cmpflt(tmp, src);
                    342:         break;
                    343:     case 0x33: /* FBLE */
                    344:         gen_helper_cmpfle(tmp, src);
                    345:         break;
                    346:     case 0x35: /* FBNE */
                    347:         gen_helper_cmpfne(tmp, src);
                    348:         break;
                    349:     case 0x36: /* FBGE */
                    350:         gen_helper_cmpfge(tmp, src);
                    351:         break;
                    352:     case 0x37: /* FBGT */
                    353:         gen_helper_cmpfgt(tmp, src);
                    354:         break;
                    355:     default:
                    356:         abort();
                    357:     }
                    358:     tcg_gen_brcondi_i64(TCG_COND_NE, tmp, 0, l1);
                    359:     tcg_gen_movi_i64(cpu_pc, ctx->pc);
                    360:     tcg_gen_br(l2);
                    361:     gen_set_label(l1);
                    362:     tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp16 << 2));
                    363:     gen_set_label(l2);
1.1       root      364: }
                    365: 
1.1.1.4 ! root      366: static inline void gen_cmov(TCGCond inv_cond, int ra, int rb, int rc,
        !           367:                             int islit, uint8_t lit, int mask)
1.1       root      368: {
1.1.1.2   root      369:     int l1;
1.1       root      370: 
1.1.1.2   root      371:     if (unlikely(rc == 31))
                    372:         return;
1.1       root      373: 
1.1.1.2   root      374:     l1 = gen_new_label();
1.1       root      375: 
1.1.1.2   root      376:     if (ra != 31) {
                    377:         if (mask) {
                    378:             TCGv tmp = tcg_temp_new();
                    379:             tcg_gen_andi_i64(tmp, cpu_ir[ra], 1);
                    380:             tcg_gen_brcondi_i64(inv_cond, tmp, 0, l1);
                    381:             tcg_temp_free(tmp);
                    382:         } else
                    383:             tcg_gen_brcondi_i64(inv_cond, cpu_ir[ra], 0, l1);
                    384:     } else {
                    385:         /* Very uncommon case - Do not bother to optimize.  */
                    386:         TCGv tmp = tcg_const_i64(0);
                    387:         tcg_gen_brcondi_i64(inv_cond, tmp, 0, l1);
                    388:         tcg_temp_free(tmp);
                    389:     }
1.1       root      390: 
1.1.1.2   root      391:     if (islit)
                    392:         tcg_gen_movi_i64(cpu_ir[rc], lit);
                    393:     else
                    394:         tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
                    395:     gen_set_label(l1);
1.1       root      396: }
                    397: 
1.1.1.2   root      398: #define FARITH2(name)                                       \
1.1.1.4 ! root      399: static inline void glue(gen_f, name)(int rb, int rc)        \
1.1.1.2   root      400: {                                                           \
                    401:     if (unlikely(rc == 31))                                 \
                    402:       return;                                               \
                    403:                                                             \
                    404:     if (rb != 31)                                           \
                    405:         gen_helper_ ## name (cpu_fir[rc], cpu_fir[rb]);    \
                    406:     else {                                                  \
                    407:         TCGv tmp = tcg_const_i64(0);                        \
                    408:         gen_helper_ ## name (cpu_fir[rc], tmp);            \
                    409:         tcg_temp_free(tmp);                                 \
                    410:     }                                                       \
                    411: }
                    412: FARITH2(sqrts)
                    413: FARITH2(sqrtf)
                    414: FARITH2(sqrtg)
                    415: FARITH2(sqrtt)
                    416: FARITH2(cvtgf)
                    417: FARITH2(cvtgq)
                    418: FARITH2(cvtqf)
                    419: FARITH2(cvtqg)
                    420: FARITH2(cvtst)
                    421: FARITH2(cvtts)
                    422: FARITH2(cvttq)
                    423: FARITH2(cvtqs)
                    424: FARITH2(cvtqt)
                    425: FARITH2(cvtlq)
                    426: FARITH2(cvtql)
                    427: FARITH2(cvtqlv)
                    428: FARITH2(cvtqlsv)
                    429: 
                    430: #define FARITH3(name)                                                     \
1.1.1.4 ! root      431: static inline void glue(gen_f, name)(int ra, int rb, int rc)              \
1.1.1.2   root      432: {                                                                         \
                    433:     if (unlikely(rc == 31))                                               \
                    434:         return;                                                           \
                    435:                                                                           \
                    436:     if (ra != 31) {                                                       \
                    437:         if (rb != 31)                                                     \
                    438:             gen_helper_ ## name (cpu_fir[rc], cpu_fir[ra], cpu_fir[rb]);  \
                    439:         else {                                                            \
                    440:             TCGv tmp = tcg_const_i64(0);                                  \
                    441:             gen_helper_ ## name (cpu_fir[rc], cpu_fir[ra], tmp);          \
                    442:             tcg_temp_free(tmp);                                           \
                    443:         }                                                                 \
                    444:     } else {                                                              \
                    445:         TCGv tmp = tcg_const_i64(0);                                      \
                    446:         if (rb != 31)                                                     \
                    447:             gen_helper_ ## name (cpu_fir[rc], tmp, cpu_fir[rb]);          \
                    448:         else                                                              \
                    449:             gen_helper_ ## name (cpu_fir[rc], tmp, tmp);                   \
                    450:         tcg_temp_free(tmp);                                               \
                    451:     }                                                                     \
                    452: }
                    453: 
                    454: FARITH3(addf)
                    455: FARITH3(subf)
                    456: FARITH3(mulf)
                    457: FARITH3(divf)
                    458: FARITH3(addg)
                    459: FARITH3(subg)
                    460: FARITH3(mulg)
                    461: FARITH3(divg)
                    462: FARITH3(cmpgeq)
                    463: FARITH3(cmpglt)
                    464: FARITH3(cmpgle)
                    465: FARITH3(adds)
                    466: FARITH3(subs)
                    467: FARITH3(muls)
                    468: FARITH3(divs)
                    469: FARITH3(addt)
                    470: FARITH3(subt)
                    471: FARITH3(mult)
                    472: FARITH3(divt)
                    473: FARITH3(cmptun)
                    474: FARITH3(cmpteq)
                    475: FARITH3(cmptlt)
                    476: FARITH3(cmptle)
                    477: FARITH3(cpys)
                    478: FARITH3(cpysn)
                    479: FARITH3(cpyse)
                    480: 
                    481: #define FCMOV(name)                                                   \
1.1.1.4 ! root      482: static inline void glue(gen_f, name)(int ra, int rb, int rc)          \
1.1.1.2   root      483: {                                                                     \
                    484:     int l1;                                                           \
                    485:     TCGv tmp;                                                         \
                    486:                                                                       \
                    487:     if (unlikely(rc == 31))                                           \
                    488:         return;                                                       \
                    489:                                                                       \
                    490:     l1 = gen_new_label();                                             \
                    491:     tmp = tcg_temp_new();                                 \
                    492:     if (ra != 31) {                                                   \
                    493:         tmp = tcg_temp_new();                             \
                    494:         gen_helper_ ## name (tmp, cpu_fir[ra]);                       \
                    495:     } else  {                                                         \
                    496:         tmp = tcg_const_i64(0);                                       \
                    497:         gen_helper_ ## name (tmp, tmp);                               \
                    498:     }                                                                 \
                    499:     tcg_gen_brcondi_i64(TCG_COND_EQ, tmp, 0, l1);                     \
                    500:     if (rb != 31)                                                     \
                    501:         tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[ra]);                    \
                    502:     else                                                              \
                    503:         tcg_gen_movi_i64(cpu_fir[rc], 0);                             \
                    504:     gen_set_label(l1);                                                \
                    505: }
                    506: FCMOV(cmpfeq)
                    507: FCMOV(cmpfne)
                    508: FCMOV(cmpflt)
                    509: FCMOV(cmpfge)
                    510: FCMOV(cmpfle)
                    511: FCMOV(cmpfgt)
1.1       root      512: 
1.1.1.2   root      513: /* EXTWH, EXTWH, EXTLH, EXTQH */
1.1.1.4 ! root      514: static inline void gen_ext_h(void(*tcg_gen_ext_i64)(TCGv t0, TCGv t1),
        !           515:                              int ra, int rb, int rc, int islit, uint8_t lit)
1.1       root      516: {
1.1.1.2   root      517:     if (unlikely(rc == 31))
                    518:         return;
1.1       root      519: 
1.1.1.2   root      520:     if (ra != 31) {
                    521:         if (islit) {
                    522:             if (lit != 0)
                    523:                 tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], 64 - ((lit & 7) * 8));
                    524:             else
                    525:                 tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
                    526:         } else {
1.1.1.3   root      527:             TCGv tmp1;
1.1.1.2   root      528:             tmp1 = tcg_temp_new();
1.1.1.3   root      529: 
1.1.1.2   root      530:             tcg_gen_andi_i64(tmp1, cpu_ir[rb], 7);
                    531:             tcg_gen_shli_i64(tmp1, tmp1, 3);
1.1.1.3   root      532:             tcg_gen_neg_i64(tmp1, tmp1);
                    533:             tcg_gen_andi_i64(tmp1, tmp1, 0x3f);
1.1.1.2   root      534:             tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], tmp1);
1.1.1.3   root      535: 
1.1.1.2   root      536:             tcg_temp_free(tmp1);
                    537:         }
                    538:         if (tcg_gen_ext_i64)
                    539:             tcg_gen_ext_i64(cpu_ir[rc], cpu_ir[rc]);
                    540:     } else
                    541:         tcg_gen_movi_i64(cpu_ir[rc], 0);
1.1       root      542: }
                    543: 
1.1.1.2   root      544: /* EXTBL, EXTWL, EXTWL, EXTLL, EXTQL */
1.1.1.4 ! root      545: static inline void gen_ext_l(void(*tcg_gen_ext_i64)(TCGv t0, TCGv t1),
        !           546:                              int ra, int rb, int rc, int islit, uint8_t lit)
1.1       root      547: {
1.1.1.2   root      548:     if (unlikely(rc == 31))
                    549:         return;
1.1       root      550: 
1.1.1.2   root      551:     if (ra != 31) {
                    552:         if (islit) {
                    553:                 tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[ra], (lit & 7) * 8);
                    554:         } else {
                    555:             TCGv tmp = tcg_temp_new();
                    556:             tcg_gen_andi_i64(tmp, cpu_ir[rb], 7);
                    557:             tcg_gen_shli_i64(tmp, tmp, 3);
                    558:             tcg_gen_shr_i64(cpu_ir[rc], cpu_ir[ra], tmp);
                    559:             tcg_temp_free(tmp);
                    560:         }
                    561:         if (tcg_gen_ext_i64)
                    562:             tcg_gen_ext_i64(cpu_ir[rc], cpu_ir[rc]);
                    563:     } else
                    564:         tcg_gen_movi_i64(cpu_ir[rc], 0);
                    565: }
                    566: 
                    567: /* Code to call arith3 helpers */
                    568: #define ARITH3(name)                                                  \
1.1.1.4 ! root      569: static inline void glue(gen_, name)(int ra, int rb, int rc, int islit,\
        !           570:                                     uint8_t lit)                      \
1.1.1.2   root      571: {                                                                     \
                    572:     if (unlikely(rc == 31))                                           \
                    573:         return;                                                       \
                    574:                                                                       \
                    575:     if (ra != 31) {                                                   \
                    576:         if (islit) {                                                  \
                    577:             TCGv tmp = tcg_const_i64(lit);                            \
                    578:             gen_helper_ ## name(cpu_ir[rc], cpu_ir[ra], tmp);         \
                    579:             tcg_temp_free(tmp);                                       \
                    580:         } else                                                        \
                    581:             gen_helper_ ## name (cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]); \
                    582:     } else {                                                          \
                    583:         TCGv tmp1 = tcg_const_i64(0);                                 \
                    584:         if (islit) {                                                  \
                    585:             TCGv tmp2 = tcg_const_i64(lit);                           \
                    586:             gen_helper_ ## name (cpu_ir[rc], tmp1, tmp2);             \
                    587:             tcg_temp_free(tmp2);                                      \
                    588:         } else                                                        \
                    589:             gen_helper_ ## name (cpu_ir[rc], tmp1, cpu_ir[rb]);       \
                    590:         tcg_temp_free(tmp1);                                          \
                    591:     }                                                                 \
                    592: }
                    593: ARITH3(cmpbge)
                    594: ARITH3(addlv)
                    595: ARITH3(sublv)
                    596: ARITH3(addqv)
                    597: ARITH3(subqv)
                    598: ARITH3(mskbl)
                    599: ARITH3(insbl)
                    600: ARITH3(mskwl)
                    601: ARITH3(inswl)
                    602: ARITH3(mskll)
                    603: ARITH3(insll)
                    604: ARITH3(zap)
                    605: ARITH3(zapnot)
                    606: ARITH3(mskql)
                    607: ARITH3(insql)
                    608: ARITH3(mskwh)
                    609: ARITH3(inswh)
                    610: ARITH3(msklh)
                    611: ARITH3(inslh)
                    612: ARITH3(mskqh)
                    613: ARITH3(insqh)
                    614: ARITH3(umulh)
                    615: ARITH3(mullv)
                    616: ARITH3(mulqv)
                    617: 
1.1.1.4 ! root      618: static inline void gen_cmp(TCGCond cond, int ra, int rb, int rc, int islit,
        !           619:                            uint8_t lit)
1.1.1.2   root      620: {
                    621:     int l1, l2;
                    622:     TCGv tmp;
                    623: 
                    624:     if (unlikely(rc == 31))
                    625:     return;
                    626: 
                    627:     l1 = gen_new_label();
                    628:     l2 = gen_new_label();
                    629: 
                    630:     if (ra != 31) {
                    631:         tmp = tcg_temp_new();
                    632:         tcg_gen_mov_i64(tmp, cpu_ir[ra]);
                    633:     } else
                    634:         tmp = tcg_const_i64(0);
                    635:     if (islit)
                    636:         tcg_gen_brcondi_i64(cond, tmp, lit, l1);
                    637:     else
                    638:         tcg_gen_brcond_i64(cond, tmp, cpu_ir[rb], l1);
1.1       root      639: 
1.1.1.2   root      640:     tcg_gen_movi_i64(cpu_ir[rc], 0);
                    641:     tcg_gen_br(l2);
                    642:     gen_set_label(l1);
                    643:     tcg_gen_movi_i64(cpu_ir[rc], 1);
                    644:     gen_set_label(l2);
1.1       root      645: }
                    646: 
1.1.1.4 ! root      647: static inline int translate_one(DisasContext *ctx, uint32_t insn)
1.1       root      648: {
                    649:     uint32_t palcode;
                    650:     int32_t disp21, disp16, disp12;
                    651:     uint16_t fn11, fn16;
                    652:     uint8_t opc, ra, rb, rc, sbz, fpfn, fn7, fn2, islit;
1.1.1.2   root      653:     uint8_t lit;
1.1       root      654:     int ret;
                    655: 
                    656:     /* Decode all instruction fields */
                    657:     opc = insn >> 26;
                    658:     ra = (insn >> 21) & 0x1F;
                    659:     rb = (insn >> 16) & 0x1F;
                    660:     rc = insn & 0x1F;
                    661:     sbz = (insn >> 13) & 0x07;
                    662:     islit = (insn >> 12) & 1;
1.1.1.2   root      663:     if (rb == 31 && !islit) {
                    664:         islit = 1;
                    665:         lit = 0;
                    666:     } else
                    667:         lit = (insn >> 13) & 0xFF;
1.1       root      668:     palcode = insn & 0x03FFFFFF;
                    669:     disp21 = ((int32_t)((insn & 0x001FFFFF) << 11)) >> 11;
                    670:     disp16 = (int16_t)(insn & 0x0000FFFF);
                    671:     disp12 = (int32_t)((insn & 0x00000FFF) << 20) >> 20;
                    672:     fn16 = insn & 0x0000FFFF;
                    673:     fn11 = (insn >> 5) & 0x000007FF;
                    674:     fpfn = fn11 & 0x3F;
                    675:     fn7 = (insn >> 5) & 0x0000007F;
                    676:     fn2 = (insn >> 5) & 0x00000003;
                    677:     ret = 0;
1.1.1.2   root      678:     LOG_DISAS("opc %02x ra %d rb %d rc %d disp16 %04x\n",
                    679:               opc, ra, rb, rc, disp16);
1.1       root      680:     switch (opc) {
                    681:     case 0x00:
                    682:         /* CALL_PAL */
                    683:         if (palcode >= 0x80 && palcode < 0xC0) {
                    684:             /* Unprivileged PAL call */
1.1.1.3   root      685:             gen_excp(ctx, EXCP_CALL_PAL + ((palcode & 0x3F) << 6), 0);
1.1       root      686: #if !defined (CONFIG_USER_ONLY)
                    687:         } else if (palcode < 0x40) {
                    688:             /* Privileged PAL code */
                    689:             if (ctx->mem_idx & 1)
                    690:                 goto invalid_opc;
                    691:             else
1.1.1.3   root      692:                 gen_excp(ctx, EXCP_CALL_PALP + ((palcode & 0x3F) << 6), 0);
1.1       root      693: #endif
                    694:         } else {
                    695:             /* Invalid PAL call */
                    696:             goto invalid_opc;
                    697:         }
                    698:         ret = 3;
                    699:         break;
                    700:     case 0x01:
                    701:         /* OPC01 */
                    702:         goto invalid_opc;
                    703:     case 0x02:
                    704:         /* OPC02 */
                    705:         goto invalid_opc;
                    706:     case 0x03:
                    707:         /* OPC03 */
                    708:         goto invalid_opc;
                    709:     case 0x04:
                    710:         /* OPC04 */
                    711:         goto invalid_opc;
                    712:     case 0x05:
                    713:         /* OPC05 */
                    714:         goto invalid_opc;
                    715:     case 0x06:
                    716:         /* OPC06 */
                    717:         goto invalid_opc;
                    718:     case 0x07:
                    719:         /* OPC07 */
                    720:         goto invalid_opc;
                    721:     case 0x08:
                    722:         /* LDA */
1.1.1.2   root      723:         if (likely(ra != 31)) {
                    724:             if (rb != 31)
                    725:                 tcg_gen_addi_i64(cpu_ir[ra], cpu_ir[rb], disp16);
                    726:             else
                    727:                 tcg_gen_movi_i64(cpu_ir[ra], disp16);
                    728:         }
1.1       root      729:         break;
                    730:     case 0x09:
                    731:         /* LDAH */
1.1.1.2   root      732:         if (likely(ra != 31)) {
                    733:             if (rb != 31)
                    734:                 tcg_gen_addi_i64(cpu_ir[ra], cpu_ir[rb], disp16 << 16);
                    735:             else
                    736:                 tcg_gen_movi_i64(cpu_ir[ra], disp16 << 16);
                    737:         }
1.1       root      738:         break;
                    739:     case 0x0A:
                    740:         /* LDBU */
                    741:         if (!(ctx->amask & AMASK_BWX))
                    742:             goto invalid_opc;
1.1.1.2   root      743:         gen_load_mem(ctx, &tcg_gen_qemu_ld8u, ra, rb, disp16, 0, 0);
1.1       root      744:         break;
                    745:     case 0x0B:
                    746:         /* LDQ_U */
1.1.1.2   root      747:         gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 1);
1.1       root      748:         break;
                    749:     case 0x0C:
                    750:         /* LDWU */
                    751:         if (!(ctx->amask & AMASK_BWX))
                    752:             goto invalid_opc;
1.1.1.3   root      753:         gen_load_mem(ctx, &tcg_gen_qemu_ld16u, ra, rb, disp16, 0, 0);
1.1       root      754:         break;
                    755:     case 0x0D:
                    756:         /* STW */
1.1.1.2   root      757:         gen_store_mem(ctx, &tcg_gen_qemu_st16, ra, rb, disp16, 0, 0, 0);
1.1       root      758:         break;
                    759:     case 0x0E:
                    760:         /* STB */
1.1.1.2   root      761:         gen_store_mem(ctx, &tcg_gen_qemu_st8, ra, rb, disp16, 0, 0, 0);
1.1       root      762:         break;
                    763:     case 0x0F:
                    764:         /* STQ_U */
1.1.1.2   root      765:         gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 1, 0);
1.1       root      766:         break;
                    767:     case 0x10:
                    768:         switch (fn7) {
                    769:         case 0x00:
                    770:             /* ADDL */
1.1.1.2   root      771:             if (likely(rc != 31)) {
                    772:                 if (ra != 31) {
                    773:                     if (islit) {
                    774:                         tcg_gen_addi_i64(cpu_ir[rc], cpu_ir[ra], lit);
                    775:                         tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
                    776:                     } else {
                    777:                         tcg_gen_add_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
                    778:                         tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
                    779:                     }
                    780:                 } else {
                    781:                     if (islit)
                    782:                         tcg_gen_movi_i64(cpu_ir[rc], lit);
                    783:                     else
                    784:                         tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
                    785:                 }
                    786:             }
1.1       root      787:             break;
                    788:         case 0x02:
                    789:             /* S4ADDL */
1.1.1.2   root      790:             if (likely(rc != 31)) {
                    791:                 if (ra != 31) {
                    792:                     TCGv tmp = tcg_temp_new();
                    793:                     tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
                    794:                     if (islit)
                    795:                         tcg_gen_addi_i64(tmp, tmp, lit);
                    796:                     else
                    797:                         tcg_gen_add_i64(tmp, tmp, cpu_ir[rb]);
                    798:                     tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
                    799:                     tcg_temp_free(tmp);
                    800:                 } else {
                    801:                     if (islit)
                    802:                         tcg_gen_movi_i64(cpu_ir[rc], lit);
                    803:                     else
                    804:                         tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
                    805:                 }
                    806:             }
1.1       root      807:             break;
                    808:         case 0x09:
                    809:             /* SUBL */
1.1.1.2   root      810:             if (likely(rc != 31)) {
                    811:                 if (ra != 31) {
                    812:                     if (islit)
                    813:                         tcg_gen_subi_i64(cpu_ir[rc], cpu_ir[ra], lit);
                    814:                     else
                    815:                         tcg_gen_sub_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
                    816:                     tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
                    817:                 } else {
                    818:                     if (islit)
                    819:                         tcg_gen_movi_i64(cpu_ir[rc], -lit);
                    820:                     else {
                    821:                         tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
                    822:                         tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
                    823:                 }
                    824:             }
1.1       root      825:             break;
                    826:         case 0x0B:
                    827:             /* S4SUBL */
1.1.1.2   root      828:             if (likely(rc != 31)) {
                    829:                 if (ra != 31) {
                    830:                     TCGv tmp = tcg_temp_new();
                    831:                     tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
                    832:                     if (islit)
                    833:                         tcg_gen_subi_i64(tmp, tmp, lit);
                    834:                     else
                    835:                         tcg_gen_sub_i64(tmp, tmp, cpu_ir[rb]);
                    836:                     tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
                    837:                     tcg_temp_free(tmp);
                    838:                 } else {
                    839:                     if (islit)
                    840:                         tcg_gen_movi_i64(cpu_ir[rc], -lit);
                    841:                     else {
                    842:                         tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
                    843:                         tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
                    844:                     }
                    845:                 }
                    846:             }
1.1       root      847:             break;
                    848:         case 0x0F:
                    849:             /* CMPBGE */
1.1.1.2   root      850:             gen_cmpbge(ra, rb, rc, islit, lit);
1.1       root      851:             break;
                    852:         case 0x12:
                    853:             /* S8ADDL */
1.1.1.2   root      854:             if (likely(rc != 31)) {
                    855:                 if (ra != 31) {
                    856:                     TCGv tmp = tcg_temp_new();
                    857:                     tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
                    858:                     if (islit)
                    859:                         tcg_gen_addi_i64(tmp, tmp, lit);
                    860:                     else
                    861:                         tcg_gen_add_i64(tmp, tmp, cpu_ir[rb]);
                    862:                     tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
                    863:                     tcg_temp_free(tmp);
                    864:                 } else {
                    865:                     if (islit)
                    866:                         tcg_gen_movi_i64(cpu_ir[rc], lit);
                    867:                     else
                    868:                         tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
                    869:                 }
                    870:             }
1.1       root      871:             break;
                    872:         case 0x1B:
                    873:             /* S8SUBL */
1.1.1.2   root      874:             if (likely(rc != 31)) {
                    875:                 if (ra != 31) {
                    876:                     TCGv tmp = tcg_temp_new();
                    877:                     tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
                    878:                     if (islit)
                    879:                         tcg_gen_subi_i64(tmp, tmp, lit);
                    880:                     else
                    881:                        tcg_gen_sub_i64(tmp, tmp, cpu_ir[rb]);
                    882:                     tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
                    883:                     tcg_temp_free(tmp);
                    884:                 } else {
                    885:                     if (islit)
                    886:                         tcg_gen_movi_i64(cpu_ir[rc], -lit);
                    887:                     else
                    888:                         tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
                    889:                         tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
                    890:                     }
                    891:                 }
                    892:             }
1.1       root      893:             break;
                    894:         case 0x1D:
                    895:             /* CMPULT */
1.1.1.2   root      896:             gen_cmp(TCG_COND_LTU, ra, rb, rc, islit, lit);
1.1       root      897:             break;
                    898:         case 0x20:
                    899:             /* ADDQ */
1.1.1.2   root      900:             if (likely(rc != 31)) {
                    901:                 if (ra != 31) {
                    902:                     if (islit)
                    903:                         tcg_gen_addi_i64(cpu_ir[rc], cpu_ir[ra], lit);
                    904:                     else
                    905:                         tcg_gen_add_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
                    906:                 } else {
                    907:                     if (islit)
                    908:                         tcg_gen_movi_i64(cpu_ir[rc], lit);
                    909:                     else
                    910:                         tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
                    911:                 }
                    912:             }
1.1       root      913:             break;
                    914:         case 0x22:
                    915:             /* S4ADDQ */
1.1.1.2   root      916:             if (likely(rc != 31)) {
                    917:                 if (ra != 31) {
                    918:                     TCGv tmp = tcg_temp_new();
                    919:                     tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
                    920:                     if (islit)
                    921:                         tcg_gen_addi_i64(cpu_ir[rc], tmp, lit);
                    922:                     else
                    923:                         tcg_gen_add_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
                    924:                     tcg_temp_free(tmp);
                    925:                 } else {
                    926:                     if (islit)
                    927:                         tcg_gen_movi_i64(cpu_ir[rc], lit);
                    928:                     else
                    929:                         tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
                    930:                 }
                    931:             }
1.1       root      932:             break;
                    933:         case 0x29:
                    934:             /* SUBQ */
1.1.1.2   root      935:             if (likely(rc != 31)) {
                    936:                 if (ra != 31) {
                    937:                     if (islit)
                    938:                         tcg_gen_subi_i64(cpu_ir[rc], cpu_ir[ra], lit);
                    939:                     else
                    940:                         tcg_gen_sub_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
                    941:                 } else {
                    942:                     if (islit)
                    943:                         tcg_gen_movi_i64(cpu_ir[rc], -lit);
                    944:                     else
                    945:                         tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
                    946:                 }
                    947:             }
1.1       root      948:             break;
                    949:         case 0x2B:
                    950:             /* S4SUBQ */
1.1.1.2   root      951:             if (likely(rc != 31)) {
                    952:                 if (ra != 31) {
                    953:                     TCGv tmp = tcg_temp_new();
                    954:                     tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
                    955:                     if (islit)
                    956:                         tcg_gen_subi_i64(cpu_ir[rc], tmp, lit);
                    957:                     else
                    958:                         tcg_gen_sub_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
                    959:                     tcg_temp_free(tmp);
                    960:                 } else {
                    961:                     if (islit)
                    962:                         tcg_gen_movi_i64(cpu_ir[rc], -lit);
                    963:                     else
                    964:                         tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
                    965:                 }
                    966:             }
1.1       root      967:             break;
                    968:         case 0x2D:
                    969:             /* CMPEQ */
1.1.1.2   root      970:             gen_cmp(TCG_COND_EQ, ra, rb, rc, islit, lit);
1.1       root      971:             break;
                    972:         case 0x32:
                    973:             /* S8ADDQ */
1.1.1.2   root      974:             if (likely(rc != 31)) {
                    975:                 if (ra != 31) {
                    976:                     TCGv tmp = tcg_temp_new();
                    977:                     tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
                    978:                     if (islit)
                    979:                         tcg_gen_addi_i64(cpu_ir[rc], tmp, lit);
                    980:                     else
                    981:                         tcg_gen_add_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
                    982:                     tcg_temp_free(tmp);
                    983:                 } else {
                    984:                     if (islit)
                    985:                         tcg_gen_movi_i64(cpu_ir[rc], lit);
                    986:                     else
                    987:                         tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
                    988:                 }
                    989:             }
1.1       root      990:             break;
                    991:         case 0x3B:
                    992:             /* S8SUBQ */
1.1.1.2   root      993:             if (likely(rc != 31)) {
                    994:                 if (ra != 31) {
                    995:                     TCGv tmp = tcg_temp_new();
                    996:                     tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
                    997:                     if (islit)
                    998:                         tcg_gen_subi_i64(cpu_ir[rc], tmp, lit);
                    999:                     else
                   1000:                         tcg_gen_sub_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
                   1001:                     tcg_temp_free(tmp);
                   1002:                 } else {
                   1003:                     if (islit)
                   1004:                         tcg_gen_movi_i64(cpu_ir[rc], -lit);
                   1005:                     else
                   1006:                         tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
                   1007:                 }
                   1008:             }
1.1       root     1009:             break;
                   1010:         case 0x3D:
                   1011:             /* CMPULE */
1.1.1.2   root     1012:             gen_cmp(TCG_COND_LEU, ra, rb, rc, islit, lit);
1.1       root     1013:             break;
                   1014:         case 0x40:
                   1015:             /* ADDL/V */
1.1.1.2   root     1016:             gen_addlv(ra, rb, rc, islit, lit);
1.1       root     1017:             break;
                   1018:         case 0x49:
                   1019:             /* SUBL/V */
1.1.1.2   root     1020:             gen_sublv(ra, rb, rc, islit, lit);
1.1       root     1021:             break;
                   1022:         case 0x4D:
                   1023:             /* CMPLT */
1.1.1.2   root     1024:             gen_cmp(TCG_COND_LT, ra, rb, rc, islit, lit);
1.1       root     1025:             break;
                   1026:         case 0x60:
                   1027:             /* ADDQ/V */
1.1.1.2   root     1028:             gen_addqv(ra, rb, rc, islit, lit);
1.1       root     1029:             break;
                   1030:         case 0x69:
                   1031:             /* SUBQ/V */
1.1.1.2   root     1032:             gen_subqv(ra, rb, rc, islit, lit);
1.1       root     1033:             break;
                   1034:         case 0x6D:
                   1035:             /* CMPLE */
1.1.1.2   root     1036:             gen_cmp(TCG_COND_LE, ra, rb, rc, islit, lit);
1.1       root     1037:             break;
                   1038:         default:
                   1039:             goto invalid_opc;
                   1040:         }
                   1041:         break;
                   1042:     case 0x11:
                   1043:         switch (fn7) {
                   1044:         case 0x00:
                   1045:             /* AND */
1.1.1.2   root     1046:             if (likely(rc != 31)) {
                   1047:                 if (ra == 31)
                   1048:                     tcg_gen_movi_i64(cpu_ir[rc], 0);
                   1049:                 else if (islit)
                   1050:                     tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], lit);
                   1051:                 else
                   1052:                     tcg_gen_and_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
                   1053:             }
1.1       root     1054:             break;
                   1055:         case 0x08:
                   1056:             /* BIC */
1.1.1.2   root     1057:             if (likely(rc != 31)) {
                   1058:                 if (ra != 31) {
                   1059:                     if (islit)
                   1060:                         tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
                   1061:                     else
                   1062:                         tcg_gen_andc_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
                   1063:                 } else
                   1064:                     tcg_gen_movi_i64(cpu_ir[rc], 0);
                   1065:             }
1.1       root     1066:             break;
                   1067:         case 0x14:
                   1068:             /* CMOVLBS */
1.1.1.2   root     1069:             gen_cmov(TCG_COND_EQ, ra, rb, rc, islit, lit, 1);
1.1       root     1070:             break;
                   1071:         case 0x16:
                   1072:             /* CMOVLBC */
1.1.1.2   root     1073:             gen_cmov(TCG_COND_NE, ra, rb, rc, islit, lit, 1);
1.1       root     1074:             break;
                   1075:         case 0x20:
                   1076:             /* BIS */
1.1.1.2   root     1077:             if (likely(rc != 31)) {
                   1078:                 if (ra != 31) {
                   1079:                     if (islit)
                   1080:                         tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], lit);
                   1081:                     else
                   1082:                         tcg_gen_or_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1.1       root     1083:                 } else {
1.1.1.2   root     1084:                     if (islit)
                   1085:                         tcg_gen_movi_i64(cpu_ir[rc], lit);
                   1086:                     else
                   1087:                         tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
1.1       root     1088:                 }
                   1089:             }
                   1090:             break;
                   1091:         case 0x24:
                   1092:             /* CMOVEQ */
1.1.1.2   root     1093:             gen_cmov(TCG_COND_NE, ra, rb, rc, islit, lit, 0);
1.1       root     1094:             break;
                   1095:         case 0x26:
                   1096:             /* CMOVNE */
1.1.1.2   root     1097:             gen_cmov(TCG_COND_EQ, ra, rb, rc, islit, lit, 0);
1.1       root     1098:             break;
                   1099:         case 0x28:
                   1100:             /* ORNOT */
1.1.1.2   root     1101:             if (likely(rc != 31)) {
                   1102:                 if (ra != 31) {
                   1103:                     if (islit)
                   1104:                         tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
                   1105:                     else
                   1106:                         tcg_gen_orc_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
                   1107:                 } else {
                   1108:                     if (islit)
                   1109:                         tcg_gen_movi_i64(cpu_ir[rc], ~lit);
                   1110:                     else
                   1111:                         tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]);
                   1112:                 }
                   1113:             }
1.1       root     1114:             break;
                   1115:         case 0x40:
                   1116:             /* XOR */
1.1.1.2   root     1117:             if (likely(rc != 31)) {
                   1118:                 if (ra != 31) {
                   1119:                     if (islit)
                   1120:                         tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], lit);
                   1121:                     else
                   1122:                         tcg_gen_xor_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
                   1123:                 } else {
                   1124:                     if (islit)
                   1125:                         tcg_gen_movi_i64(cpu_ir[rc], lit);
                   1126:                     else
                   1127:                         tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
                   1128:                 }
                   1129:             }
1.1       root     1130:             break;
                   1131:         case 0x44:
                   1132:             /* CMOVLT */
1.1.1.2   root     1133:             gen_cmov(TCG_COND_GE, ra, rb, rc, islit, lit, 0);
1.1       root     1134:             break;
                   1135:         case 0x46:
                   1136:             /* CMOVGE */
1.1.1.2   root     1137:             gen_cmov(TCG_COND_LT, ra, rb, rc, islit, lit, 0);
1.1       root     1138:             break;
                   1139:         case 0x48:
                   1140:             /* EQV */
1.1.1.2   root     1141:             if (likely(rc != 31)) {
                   1142:                 if (ra != 31) {
                   1143:                     if (islit)
                   1144:                         tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
                   1145:                     else
                   1146:                         tcg_gen_eqv_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
                   1147:                 } else {
                   1148:                     if (islit)
                   1149:                         tcg_gen_movi_i64(cpu_ir[rc], ~lit);
                   1150:                     else
                   1151:                         tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]);
                   1152:                 }
                   1153:             }
1.1       root     1154:             break;
                   1155:         case 0x61:
                   1156:             /* AMASK */
1.1.1.2   root     1157:             if (likely(rc != 31)) {
                   1158:                 if (islit)
1.1.1.3   root     1159:                     tcg_gen_movi_i64(cpu_ir[rc], lit);
1.1.1.2   root     1160:                 else
1.1.1.3   root     1161:                     tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
                   1162:                 switch (ctx->env->implver) {
                   1163:                 case IMPLVER_2106x:
                   1164:                     /* EV4, EV45, LCA, LCA45 & EV5 */
                   1165:                     break;
                   1166:                 case IMPLVER_21164:
                   1167:                 case IMPLVER_21264:
                   1168:                 case IMPLVER_21364:
                   1169:                     tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[rc],
                   1170:                                      ~(uint64_t)ctx->amask);
                   1171:                     break;
                   1172:                 }
1.1.1.2   root     1173:             }
1.1       root     1174:             break;
                   1175:         case 0x64:
                   1176:             /* CMOVLE */
1.1.1.2   root     1177:             gen_cmov(TCG_COND_GT, ra, rb, rc, islit, lit, 0);
1.1       root     1178:             break;
                   1179:         case 0x66:
                   1180:             /* CMOVGT */
1.1.1.2   root     1181:             gen_cmov(TCG_COND_LE, ra, rb, rc, islit, lit, 0);
1.1       root     1182:             break;
                   1183:         case 0x6C:
                   1184:             /* IMPLVER */
1.1.1.2   root     1185:             if (rc != 31)
1.1.1.3   root     1186:                 tcg_gen_movi_i64(cpu_ir[rc], ctx->env->implver);
1.1       root     1187:             break;
                   1188:         default:
                   1189:             goto invalid_opc;
                   1190:         }
                   1191:         break;
                   1192:     case 0x12:
                   1193:         switch (fn7) {
                   1194:         case 0x02:
                   1195:             /* MSKBL */
1.1.1.2   root     1196:             gen_mskbl(ra, rb, rc, islit, lit);
1.1       root     1197:             break;
                   1198:         case 0x06:
                   1199:             /* EXTBL */
1.1.1.2   root     1200:             gen_ext_l(&tcg_gen_ext8u_i64, ra, rb, rc, islit, lit);
1.1       root     1201:             break;
                   1202:         case 0x0B:
                   1203:             /* INSBL */
1.1.1.2   root     1204:             gen_insbl(ra, rb, rc, islit, lit);
1.1       root     1205:             break;
                   1206:         case 0x12:
                   1207:             /* MSKWL */
1.1.1.2   root     1208:             gen_mskwl(ra, rb, rc, islit, lit);
1.1       root     1209:             break;
                   1210:         case 0x16:
                   1211:             /* EXTWL */
1.1.1.2   root     1212:             gen_ext_l(&tcg_gen_ext16u_i64, ra, rb, rc, islit, lit);
1.1       root     1213:             break;
                   1214:         case 0x1B:
                   1215:             /* INSWL */
1.1.1.2   root     1216:             gen_inswl(ra, rb, rc, islit, lit);
1.1       root     1217:             break;
                   1218:         case 0x22:
                   1219:             /* MSKLL */
1.1.1.2   root     1220:             gen_mskll(ra, rb, rc, islit, lit);
1.1       root     1221:             break;
                   1222:         case 0x26:
                   1223:             /* EXTLL */
1.1.1.2   root     1224:             gen_ext_l(&tcg_gen_ext32u_i64, ra, rb, rc, islit, lit);
1.1       root     1225:             break;
                   1226:         case 0x2B:
                   1227:             /* INSLL */
1.1.1.2   root     1228:             gen_insll(ra, rb, rc, islit, lit);
1.1       root     1229:             break;
                   1230:         case 0x30:
                   1231:             /* ZAP */
1.1.1.2   root     1232:             gen_zap(ra, rb, rc, islit, lit);
1.1       root     1233:             break;
                   1234:         case 0x31:
                   1235:             /* ZAPNOT */
1.1.1.2   root     1236:             gen_zapnot(ra, rb, rc, islit, lit);
1.1       root     1237:             break;
                   1238:         case 0x32:
                   1239:             /* MSKQL */
1.1.1.2   root     1240:             gen_mskql(ra, rb, rc, islit, lit);
1.1       root     1241:             break;
                   1242:         case 0x34:
                   1243:             /* SRL */
1.1.1.2   root     1244:             if (likely(rc != 31)) {
                   1245:                 if (ra != 31) {
                   1246:                     if (islit)
                   1247:                         tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
                   1248:                     else {
                   1249:                         TCGv shift = tcg_temp_new();
                   1250:                         tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
                   1251:                         tcg_gen_shr_i64(cpu_ir[rc], cpu_ir[ra], shift);
                   1252:                         tcg_temp_free(shift);
                   1253:                     }
                   1254:                 } else
                   1255:                     tcg_gen_movi_i64(cpu_ir[rc], 0);
                   1256:             }
1.1       root     1257:             break;
                   1258:         case 0x36:
                   1259:             /* EXTQL */
1.1.1.2   root     1260:             gen_ext_l(NULL, ra, rb, rc, islit, lit);
1.1       root     1261:             break;
                   1262:         case 0x39:
                   1263:             /* SLL */
1.1.1.2   root     1264:             if (likely(rc != 31)) {
                   1265:                 if (ra != 31) {
                   1266:                     if (islit)
                   1267:                         tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
                   1268:                     else {
                   1269:                         TCGv shift = tcg_temp_new();
                   1270:                         tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
                   1271:                         tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], shift);
                   1272:                         tcg_temp_free(shift);
                   1273:                     }
                   1274:                 } else
                   1275:                     tcg_gen_movi_i64(cpu_ir[rc], 0);
                   1276:             }
1.1       root     1277:             break;
                   1278:         case 0x3B:
                   1279:             /* INSQL */
1.1.1.2   root     1280:             gen_insql(ra, rb, rc, islit, lit);
1.1       root     1281:             break;
                   1282:         case 0x3C:
                   1283:             /* SRA */
1.1.1.2   root     1284:             if (likely(rc != 31)) {
                   1285:                 if (ra != 31) {
                   1286:                     if (islit)
                   1287:                         tcg_gen_sari_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
                   1288:                     else {
                   1289:                         TCGv shift = tcg_temp_new();
                   1290:                         tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
                   1291:                         tcg_gen_sar_i64(cpu_ir[rc], cpu_ir[ra], shift);
                   1292:                         tcg_temp_free(shift);
                   1293:                     }
                   1294:                 } else
                   1295:                     tcg_gen_movi_i64(cpu_ir[rc], 0);
                   1296:             }
1.1       root     1297:             break;
                   1298:         case 0x52:
                   1299:             /* MSKWH */
1.1.1.2   root     1300:             gen_mskwh(ra, rb, rc, islit, lit);
1.1       root     1301:             break;
                   1302:         case 0x57:
                   1303:             /* INSWH */
1.1.1.2   root     1304:             gen_inswh(ra, rb, rc, islit, lit);
1.1       root     1305:             break;
                   1306:         case 0x5A:
                   1307:             /* EXTWH */
1.1.1.2   root     1308:             gen_ext_h(&tcg_gen_ext16u_i64, ra, rb, rc, islit, lit);
1.1       root     1309:             break;
                   1310:         case 0x62:
                   1311:             /* MSKLH */
1.1.1.2   root     1312:             gen_msklh(ra, rb, rc, islit, lit);
1.1       root     1313:             break;
                   1314:         case 0x67:
                   1315:             /* INSLH */
1.1.1.2   root     1316:             gen_inslh(ra, rb, rc, islit, lit);
1.1       root     1317:             break;
                   1318:         case 0x6A:
                   1319:             /* EXTLH */
1.1.1.3   root     1320:             gen_ext_h(&tcg_gen_ext32u_i64, ra, rb, rc, islit, lit);
1.1       root     1321:             break;
                   1322:         case 0x72:
                   1323:             /* MSKQH */
1.1.1.2   root     1324:             gen_mskqh(ra, rb, rc, islit, lit);
1.1       root     1325:             break;
                   1326:         case 0x77:
                   1327:             /* INSQH */
1.1.1.2   root     1328:             gen_insqh(ra, rb, rc, islit, lit);
1.1       root     1329:             break;
                   1330:         case 0x7A:
                   1331:             /* EXTQH */
1.1.1.2   root     1332:             gen_ext_h(NULL, ra, rb, rc, islit, lit);
1.1       root     1333:             break;
                   1334:         default:
                   1335:             goto invalid_opc;
                   1336:         }
                   1337:         break;
                   1338:     case 0x13:
                   1339:         switch (fn7) {
                   1340:         case 0x00:
                   1341:             /* MULL */
1.1.1.2   root     1342:             if (likely(rc != 31)) {
                   1343:                 if (ra == 31)
                   1344:                     tcg_gen_movi_i64(cpu_ir[rc], 0);
                   1345:                 else {
                   1346:                     if (islit)
                   1347:                         tcg_gen_muli_i64(cpu_ir[rc], cpu_ir[ra], lit);
                   1348:                     else
                   1349:                         tcg_gen_mul_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
                   1350:                     tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
                   1351:                 }
                   1352:             }
1.1       root     1353:             break;
                   1354:         case 0x20:
                   1355:             /* MULQ */
1.1.1.2   root     1356:             if (likely(rc != 31)) {
                   1357:                 if (ra == 31)
                   1358:                     tcg_gen_movi_i64(cpu_ir[rc], 0);
                   1359:                 else if (islit)
                   1360:                     tcg_gen_muli_i64(cpu_ir[rc], cpu_ir[ra], lit);
                   1361:                 else
                   1362:                     tcg_gen_mul_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
                   1363:             }
1.1       root     1364:             break;
                   1365:         case 0x30:
                   1366:             /* UMULH */
1.1.1.2   root     1367:             gen_umulh(ra, rb, rc, islit, lit);
1.1       root     1368:             break;
                   1369:         case 0x40:
                   1370:             /* MULL/V */
1.1.1.2   root     1371:             gen_mullv(ra, rb, rc, islit, lit);
1.1       root     1372:             break;
                   1373:         case 0x60:
                   1374:             /* MULQ/V */
1.1.1.2   root     1375:             gen_mulqv(ra, rb, rc, islit, lit);
1.1       root     1376:             break;
                   1377:         default:
                   1378:             goto invalid_opc;
                   1379:         }
                   1380:         break;
                   1381:     case 0x14:
                   1382:         switch (fpfn) { /* f11 & 0x3F */
                   1383:         case 0x04:
                   1384:             /* ITOFS */
                   1385:             if (!(ctx->amask & AMASK_FIX))
                   1386:                 goto invalid_opc;
1.1.1.2   root     1387:             if (likely(rc != 31)) {
                   1388:                 if (ra != 31) {
                   1389:                     TCGv_i32 tmp = tcg_temp_new_i32();
                   1390:                     tcg_gen_trunc_i64_i32(tmp, cpu_ir[ra]);
                   1391:                     gen_helper_memory_to_s(cpu_fir[rc], tmp);
                   1392:                     tcg_temp_free_i32(tmp);
                   1393:                 } else
                   1394:                     tcg_gen_movi_i64(cpu_fir[rc], 0);
                   1395:             }
1.1       root     1396:             break;
                   1397:         case 0x0A:
                   1398:             /* SQRTF */
                   1399:             if (!(ctx->amask & AMASK_FIX))
                   1400:                 goto invalid_opc;
1.1.1.2   root     1401:             gen_fsqrtf(rb, rc);
1.1       root     1402:             break;
                   1403:         case 0x0B:
                   1404:             /* SQRTS */
                   1405:             if (!(ctx->amask & AMASK_FIX))
                   1406:                 goto invalid_opc;
1.1.1.2   root     1407:             gen_fsqrts(rb, rc);
1.1       root     1408:             break;
                   1409:         case 0x14:
                   1410:             /* ITOFF */
                   1411:             if (!(ctx->amask & AMASK_FIX))
                   1412:                 goto invalid_opc;
1.1.1.2   root     1413:             if (likely(rc != 31)) {
                   1414:                 if (ra != 31) {
                   1415:                     TCGv_i32 tmp = tcg_temp_new_i32();
                   1416:                     tcg_gen_trunc_i64_i32(tmp, cpu_ir[ra]);
                   1417:                     gen_helper_memory_to_f(cpu_fir[rc], tmp);
                   1418:                     tcg_temp_free_i32(tmp);
                   1419:                 } else
                   1420:                     tcg_gen_movi_i64(cpu_fir[rc], 0);
                   1421:             }
1.1       root     1422:             break;
                   1423:         case 0x24:
                   1424:             /* ITOFT */
                   1425:             if (!(ctx->amask & AMASK_FIX))
                   1426:                 goto invalid_opc;
1.1.1.2   root     1427:             if (likely(rc != 31)) {
                   1428:                 if (ra != 31)
                   1429:                     tcg_gen_mov_i64(cpu_fir[rc], cpu_ir[ra]);
                   1430:                 else
                   1431:                     tcg_gen_movi_i64(cpu_fir[rc], 0);
                   1432:             }
1.1       root     1433:             break;
                   1434:         case 0x2A:
                   1435:             /* SQRTG */
                   1436:             if (!(ctx->amask & AMASK_FIX))
                   1437:                 goto invalid_opc;
1.1.1.2   root     1438:             gen_fsqrtg(rb, rc);
1.1       root     1439:             break;
                   1440:         case 0x02B:
                   1441:             /* SQRTT */
                   1442:             if (!(ctx->amask & AMASK_FIX))
                   1443:                 goto invalid_opc;
1.1.1.2   root     1444:             gen_fsqrtt(rb, rc);
1.1       root     1445:             break;
                   1446:         default:
                   1447:             goto invalid_opc;
                   1448:         }
                   1449:         break;
                   1450:     case 0x15:
                   1451:         /* VAX floating point */
                   1452:         /* XXX: rounding mode and trap are ignored (!) */
                   1453:         switch (fpfn) { /* f11 & 0x3F */
                   1454:         case 0x00:
                   1455:             /* ADDF */
1.1.1.2   root     1456:             gen_faddf(ra, rb, rc);
1.1       root     1457:             break;
                   1458:         case 0x01:
                   1459:             /* SUBF */
1.1.1.2   root     1460:             gen_fsubf(ra, rb, rc);
1.1       root     1461:             break;
                   1462:         case 0x02:
                   1463:             /* MULF */
1.1.1.2   root     1464:             gen_fmulf(ra, rb, rc);
1.1       root     1465:             break;
                   1466:         case 0x03:
                   1467:             /* DIVF */
1.1.1.2   root     1468:             gen_fdivf(ra, rb, rc);
1.1       root     1469:             break;
                   1470:         case 0x1E:
                   1471:             /* CVTDG */
                   1472: #if 0 // TODO
1.1.1.2   root     1473:             gen_fcvtdg(rb, rc);
1.1       root     1474: #else
                   1475:             goto invalid_opc;
                   1476: #endif
                   1477:             break;
                   1478:         case 0x20:
                   1479:             /* ADDG */
1.1.1.2   root     1480:             gen_faddg(ra, rb, rc);
1.1       root     1481:             break;
                   1482:         case 0x21:
                   1483:             /* SUBG */
1.1.1.2   root     1484:             gen_fsubg(ra, rb, rc);
1.1       root     1485:             break;
                   1486:         case 0x22:
                   1487:             /* MULG */
1.1.1.2   root     1488:             gen_fmulg(ra, rb, rc);
1.1       root     1489:             break;
                   1490:         case 0x23:
                   1491:             /* DIVG */
1.1.1.2   root     1492:             gen_fdivg(ra, rb, rc);
1.1       root     1493:             break;
                   1494:         case 0x25:
                   1495:             /* CMPGEQ */
1.1.1.2   root     1496:             gen_fcmpgeq(ra, rb, rc);
1.1       root     1497:             break;
                   1498:         case 0x26:
                   1499:             /* CMPGLT */
1.1.1.2   root     1500:             gen_fcmpglt(ra, rb, rc);
1.1       root     1501:             break;
                   1502:         case 0x27:
                   1503:             /* CMPGLE */
1.1.1.2   root     1504:             gen_fcmpgle(ra, rb, rc);
1.1       root     1505:             break;
                   1506:         case 0x2C:
                   1507:             /* CVTGF */
1.1.1.2   root     1508:             gen_fcvtgf(rb, rc);
1.1       root     1509:             break;
                   1510:         case 0x2D:
                   1511:             /* CVTGD */
                   1512: #if 0 // TODO
1.1.1.2   root     1513:             gen_fcvtgd(rb, rc);
1.1       root     1514: #else
                   1515:             goto invalid_opc;
                   1516: #endif
                   1517:             break;
                   1518:         case 0x2F:
                   1519:             /* CVTGQ */
1.1.1.2   root     1520:             gen_fcvtgq(rb, rc);
1.1       root     1521:             break;
                   1522:         case 0x3C:
                   1523:             /* CVTQF */
1.1.1.2   root     1524:             gen_fcvtqf(rb, rc);
1.1       root     1525:             break;
                   1526:         case 0x3E:
                   1527:             /* CVTQG */
1.1.1.2   root     1528:             gen_fcvtqg(rb, rc);
1.1       root     1529:             break;
                   1530:         default:
                   1531:             goto invalid_opc;
                   1532:         }
                   1533:         break;
                   1534:     case 0x16:
                   1535:         /* IEEE floating-point */
                   1536:         /* XXX: rounding mode and traps are ignored (!) */
                   1537:         switch (fpfn) { /* f11 & 0x3F */
                   1538:         case 0x00:
                   1539:             /* ADDS */
1.1.1.2   root     1540:             gen_fadds(ra, rb, rc);
1.1       root     1541:             break;
                   1542:         case 0x01:
                   1543:             /* SUBS */
1.1.1.2   root     1544:             gen_fsubs(ra, rb, rc);
1.1       root     1545:             break;
                   1546:         case 0x02:
                   1547:             /* MULS */
1.1.1.2   root     1548:             gen_fmuls(ra, rb, rc);
1.1       root     1549:             break;
                   1550:         case 0x03:
                   1551:             /* DIVS */
1.1.1.2   root     1552:             gen_fdivs(ra, rb, rc);
1.1       root     1553:             break;
                   1554:         case 0x20:
                   1555:             /* ADDT */
1.1.1.2   root     1556:             gen_faddt(ra, rb, rc);
1.1       root     1557:             break;
                   1558:         case 0x21:
                   1559:             /* SUBT */
1.1.1.2   root     1560:             gen_fsubt(ra, rb, rc);
1.1       root     1561:             break;
                   1562:         case 0x22:
                   1563:             /* MULT */
1.1.1.2   root     1564:             gen_fmult(ra, rb, rc);
1.1       root     1565:             break;
                   1566:         case 0x23:
                   1567:             /* DIVT */
1.1.1.2   root     1568:             gen_fdivt(ra, rb, rc);
1.1       root     1569:             break;
                   1570:         case 0x24:
                   1571:             /* CMPTUN */
1.1.1.2   root     1572:             gen_fcmptun(ra, rb, rc);
1.1       root     1573:             break;
                   1574:         case 0x25:
                   1575:             /* CMPTEQ */
1.1.1.2   root     1576:             gen_fcmpteq(ra, rb, rc);
1.1       root     1577:             break;
                   1578:         case 0x26:
                   1579:             /* CMPTLT */
1.1.1.2   root     1580:             gen_fcmptlt(ra, rb, rc);
1.1       root     1581:             break;
                   1582:         case 0x27:
                   1583:             /* CMPTLE */
1.1.1.2   root     1584:             gen_fcmptle(ra, rb, rc);
1.1       root     1585:             break;
                   1586:         case 0x2C:
                   1587:             /* XXX: incorrect */
1.1.1.2   root     1588:             if (fn11 == 0x2AC || fn11 == 0x6AC) {
1.1       root     1589:                 /* CVTST */
1.1.1.2   root     1590:                 gen_fcvtst(rb, rc);
1.1       root     1591:             } else {
                   1592:                 /* CVTTS */
1.1.1.2   root     1593:                 gen_fcvtts(rb, rc);
1.1       root     1594:             }
                   1595:             break;
                   1596:         case 0x2F:
                   1597:             /* CVTTQ */
1.1.1.2   root     1598:             gen_fcvttq(rb, rc);
1.1       root     1599:             break;
                   1600:         case 0x3C:
                   1601:             /* CVTQS */
1.1.1.2   root     1602:             gen_fcvtqs(rb, rc);
1.1       root     1603:             break;
                   1604:         case 0x3E:
                   1605:             /* CVTQT */
1.1.1.2   root     1606:             gen_fcvtqt(rb, rc);
1.1       root     1607:             break;
                   1608:         default:
                   1609:             goto invalid_opc;
                   1610:         }
                   1611:         break;
                   1612:     case 0x17:
                   1613:         switch (fn11) {
                   1614:         case 0x010:
                   1615:             /* CVTLQ */
1.1.1.2   root     1616:             gen_fcvtlq(rb, rc);
1.1       root     1617:             break;
                   1618:         case 0x020:
1.1.1.2   root     1619:             if (likely(rc != 31)) {
                   1620:                 if (ra == rb)
1.1       root     1621:                     /* FMOV */
1.1.1.2   root     1622:                     tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[ra]);
                   1623:                 else
                   1624:                     /* CPYS */
                   1625:                     gen_fcpys(ra, rb, rc);
1.1       root     1626:             }
                   1627:             break;
                   1628:         case 0x021:
                   1629:             /* CPYSN */
1.1.1.2   root     1630:             gen_fcpysn(ra, rb, rc);
1.1       root     1631:             break;
                   1632:         case 0x022:
                   1633:             /* CPYSE */
1.1.1.2   root     1634:             gen_fcpyse(ra, rb, rc);
1.1       root     1635:             break;
                   1636:         case 0x024:
                   1637:             /* MT_FPCR */
1.1.1.2   root     1638:             if (likely(ra != 31))
                   1639:                 gen_helper_store_fpcr(cpu_fir[ra]);
                   1640:             else {
                   1641:                 TCGv tmp = tcg_const_i64(0);
                   1642:                 gen_helper_store_fpcr(tmp);
                   1643:                 tcg_temp_free(tmp);
                   1644:             }
1.1       root     1645:             break;
                   1646:         case 0x025:
                   1647:             /* MF_FPCR */
1.1.1.2   root     1648:             if (likely(ra != 31))
                   1649:                 gen_helper_load_fpcr(cpu_fir[ra]);
1.1       root     1650:             break;
                   1651:         case 0x02A:
                   1652:             /* FCMOVEQ */
1.1.1.2   root     1653:             gen_fcmpfeq(ra, rb, rc);
1.1       root     1654:             break;
                   1655:         case 0x02B:
                   1656:             /* FCMOVNE */
1.1.1.2   root     1657:             gen_fcmpfne(ra, rb, rc);
1.1       root     1658:             break;
                   1659:         case 0x02C:
                   1660:             /* FCMOVLT */
1.1.1.2   root     1661:             gen_fcmpflt(ra, rb, rc);
1.1       root     1662:             break;
                   1663:         case 0x02D:
                   1664:             /* FCMOVGE */
1.1.1.2   root     1665:             gen_fcmpfge(ra, rb, rc);
1.1       root     1666:             break;
                   1667:         case 0x02E:
                   1668:             /* FCMOVLE */
1.1.1.2   root     1669:             gen_fcmpfle(ra, rb, rc);
1.1       root     1670:             break;
                   1671:         case 0x02F:
                   1672:             /* FCMOVGT */
1.1.1.2   root     1673:             gen_fcmpfgt(ra, rb, rc);
1.1       root     1674:             break;
                   1675:         case 0x030:
                   1676:             /* CVTQL */
1.1.1.2   root     1677:             gen_fcvtql(rb, rc);
1.1       root     1678:             break;
                   1679:         case 0x130:
                   1680:             /* CVTQL/V */
1.1.1.2   root     1681:             gen_fcvtqlv(rb, rc);
1.1       root     1682:             break;
                   1683:         case 0x530:
                   1684:             /* CVTQL/SV */
1.1.1.2   root     1685:             gen_fcvtqlsv(rb, rc);
1.1       root     1686:             break;
                   1687:         default:
                   1688:             goto invalid_opc;
                   1689:         }
                   1690:         break;
                   1691:     case 0x18:
                   1692:         switch ((uint16_t)disp16) {
                   1693:         case 0x0000:
                   1694:             /* TRAPB */
                   1695:             /* No-op. Just exit from the current tb */
                   1696:             ret = 2;
                   1697:             break;
                   1698:         case 0x0400:
                   1699:             /* EXCB */
                   1700:             /* No-op. Just exit from the current tb */
                   1701:             ret = 2;
                   1702:             break;
                   1703:         case 0x4000:
                   1704:             /* MB */
                   1705:             /* No-op */
                   1706:             break;
                   1707:         case 0x4400:
                   1708:             /* WMB */
                   1709:             /* No-op */
                   1710:             break;
                   1711:         case 0x8000:
                   1712:             /* FETCH */
                   1713:             /* No-op */
                   1714:             break;
                   1715:         case 0xA000:
                   1716:             /* FETCH_M */
                   1717:             /* No-op */
                   1718:             break;
                   1719:         case 0xC000:
                   1720:             /* RPCC */
1.1.1.2   root     1721:             if (ra != 31)
                   1722:                 gen_helper_load_pcc(cpu_ir[ra]);
1.1       root     1723:             break;
                   1724:         case 0xE000:
                   1725:             /* RC */
1.1.1.2   root     1726:             if (ra != 31)
                   1727:                 gen_helper_rc(cpu_ir[ra]);
1.1       root     1728:             break;
                   1729:         case 0xE800:
                   1730:             /* ECB */
                   1731:             break;
                   1732:         case 0xF000:
                   1733:             /* RS */
1.1.1.2   root     1734:             if (ra != 31)
                   1735:                 gen_helper_rs(cpu_ir[ra]);
1.1       root     1736:             break;
                   1737:         case 0xF800:
                   1738:             /* WH64 */
                   1739:             /* No-op */
                   1740:             break;
                   1741:         default:
                   1742:             goto invalid_opc;
                   1743:         }
                   1744:         break;
                   1745:     case 0x19:
                   1746:         /* HW_MFPR (PALcode) */
                   1747: #if defined (CONFIG_USER_ONLY)
                   1748:         goto invalid_opc;
                   1749: #else
                   1750:         if (!ctx->pal_mode)
                   1751:             goto invalid_opc;
1.1.1.2   root     1752:         if (ra != 31) {
                   1753:             TCGv tmp = tcg_const_i32(insn & 0xFF);
                   1754:             gen_helper_mfpr(cpu_ir[ra], tmp, cpu_ir[ra]);
                   1755:             tcg_temp_free(tmp);
                   1756:         }
1.1       root     1757:         break;
                   1758: #endif
                   1759:     case 0x1A:
1.1.1.2   root     1760:         if (rb != 31)
                   1761:             tcg_gen_andi_i64(cpu_pc, cpu_ir[rb], ~3);
                   1762:         else
                   1763:             tcg_gen_movi_i64(cpu_pc, 0);
                   1764:         if (ra != 31)
                   1765:             tcg_gen_movi_i64(cpu_ir[ra], ctx->pc);
1.1       root     1766:         /* Those four jumps only differ by the branch prediction hint */
                   1767:         switch (fn2) {
                   1768:         case 0x0:
                   1769:             /* JMP */
                   1770:             break;
                   1771:         case 0x1:
                   1772:             /* JSR */
                   1773:             break;
                   1774:         case 0x2:
                   1775:             /* RET */
                   1776:             break;
                   1777:         case 0x3:
                   1778:             /* JSR_COROUTINE */
                   1779:             break;
                   1780:         }
                   1781:         ret = 1;
                   1782:         break;
                   1783:     case 0x1B:
                   1784:         /* HW_LD (PALcode) */
                   1785: #if defined (CONFIG_USER_ONLY)
                   1786:         goto invalid_opc;
                   1787: #else
                   1788:         if (!ctx->pal_mode)
                   1789:             goto invalid_opc;
1.1.1.2   root     1790:         if (ra != 31) {
                   1791:             TCGv addr = tcg_temp_new();
                   1792:             if (rb != 31)
                   1793:                 tcg_gen_addi_i64(addr, cpu_ir[rb], disp12);
                   1794:             else
                   1795:                 tcg_gen_movi_i64(addr, disp12);
                   1796:             switch ((insn >> 12) & 0xF) {
                   1797:             case 0x0:
1.1.1.3   root     1798:                 /* Longword physical access (hw_ldl/p) */
1.1.1.2   root     1799:                 gen_helper_ldl_raw(cpu_ir[ra], addr);
                   1800:                 break;
                   1801:             case 0x1:
1.1.1.3   root     1802:                 /* Quadword physical access (hw_ldq/p) */
1.1.1.2   root     1803:                 gen_helper_ldq_raw(cpu_ir[ra], addr);
                   1804:                 break;
                   1805:             case 0x2:
1.1.1.3   root     1806:                 /* Longword physical access with lock (hw_ldl_l/p) */
1.1.1.2   root     1807:                 gen_helper_ldl_l_raw(cpu_ir[ra], addr);
                   1808:                 break;
                   1809:             case 0x3:
1.1.1.3   root     1810:                 /* Quadword physical access with lock (hw_ldq_l/p) */
1.1.1.2   root     1811:                 gen_helper_ldq_l_raw(cpu_ir[ra], addr);
                   1812:                 break;
                   1813:             case 0x4:
1.1.1.3   root     1814:                 /* Longword virtual PTE fetch (hw_ldl/v) */
                   1815:                 tcg_gen_qemu_ld32s(cpu_ir[ra], addr, 0);
1.1.1.2   root     1816:                 break;
                   1817:             case 0x5:
1.1.1.3   root     1818:                 /* Quadword virtual PTE fetch (hw_ldq/v) */
                   1819:                 tcg_gen_qemu_ld64(cpu_ir[ra], addr, 0);
1.1.1.2   root     1820:                 break;
                   1821:             case 0x6:
                   1822:                 /* Incpu_ir[ra]id */
1.1.1.3   root     1823:                 goto invalid_opc;
1.1.1.2   root     1824:             case 0x7:
                   1825:                 /* Incpu_ir[ra]id */
1.1.1.3   root     1826:                 goto invalid_opc;
1.1.1.2   root     1827:             case 0x8:
1.1.1.3   root     1828:                 /* Longword virtual access (hw_ldl) */
1.1.1.2   root     1829:                 gen_helper_st_virt_to_phys(addr, addr);
                   1830:                 gen_helper_ldl_raw(cpu_ir[ra], addr);
                   1831:                 break;
                   1832:             case 0x9:
1.1.1.3   root     1833:                 /* Quadword virtual access (hw_ldq) */
1.1.1.2   root     1834:                 gen_helper_st_virt_to_phys(addr, addr);
                   1835:                 gen_helper_ldq_raw(cpu_ir[ra], addr);
                   1836:                 break;
                   1837:             case 0xA:
1.1.1.3   root     1838:                 /* Longword virtual access with protection check (hw_ldl/w) */
                   1839:                 tcg_gen_qemu_ld32s(cpu_ir[ra], addr, 0);
1.1.1.2   root     1840:                 break;
                   1841:             case 0xB:
1.1.1.3   root     1842:                 /* Quadword virtual access with protection check (hw_ldq/w) */
                   1843:                 tcg_gen_qemu_ld64(cpu_ir[ra], addr, 0);
1.1.1.2   root     1844:                 break;
                   1845:             case 0xC:
1.1.1.3   root     1846:                 /* Longword virtual access with alt access mode (hw_ldl/a)*/
1.1.1.2   root     1847:                 gen_helper_set_alt_mode();
                   1848:                 gen_helper_st_virt_to_phys(addr, addr);
                   1849:                 gen_helper_ldl_raw(cpu_ir[ra], addr);
                   1850:                 gen_helper_restore_mode();
                   1851:                 break;
                   1852:             case 0xD:
1.1.1.3   root     1853:                 /* Quadword virtual access with alt access mode (hw_ldq/a) */
1.1.1.2   root     1854:                 gen_helper_set_alt_mode();
                   1855:                 gen_helper_st_virt_to_phys(addr, addr);
                   1856:                 gen_helper_ldq_raw(cpu_ir[ra], addr);
                   1857:                 gen_helper_restore_mode();
                   1858:                 break;
                   1859:             case 0xE:
                   1860:                 /* Longword virtual access with alternate access mode and
1.1.1.3   root     1861:                  * protection checks (hw_ldl/wa)
1.1.1.2   root     1862:                  */
                   1863:                 gen_helper_set_alt_mode();
                   1864:                 gen_helper_ldl_data(cpu_ir[ra], addr);
                   1865:                 gen_helper_restore_mode();
                   1866:                 break;
                   1867:             case 0xF:
                   1868:                 /* Quadword virtual access with alternate access mode and
1.1.1.3   root     1869:                  * protection checks (hw_ldq/wa)
1.1.1.2   root     1870:                  */
                   1871:                 gen_helper_set_alt_mode();
                   1872:                 gen_helper_ldq_data(cpu_ir[ra], addr);
                   1873:                 gen_helper_restore_mode();
                   1874:                 break;
                   1875:             }
                   1876:             tcg_temp_free(addr);
1.1       root     1877:         }
                   1878:         break;
                   1879: #endif
                   1880:     case 0x1C:
                   1881:         switch (fn7) {
                   1882:         case 0x00:
                   1883:             /* SEXTB */
                   1884:             if (!(ctx->amask & AMASK_BWX))
                   1885:                 goto invalid_opc;
1.1.1.2   root     1886:             if (likely(rc != 31)) {
                   1887:                 if (islit)
                   1888:                     tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int8_t)lit));
                   1889:                 else
                   1890:                     tcg_gen_ext8s_i64(cpu_ir[rc], cpu_ir[rb]);
                   1891:             }
1.1       root     1892:             break;
                   1893:         case 0x01:
                   1894:             /* SEXTW */
                   1895:             if (!(ctx->amask & AMASK_BWX))
                   1896:                 goto invalid_opc;
1.1.1.2   root     1897:             if (likely(rc != 31)) {
                   1898:                 if (islit)
                   1899:                     tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int16_t)lit));
                   1900:                 else
                   1901:                     tcg_gen_ext16s_i64(cpu_ir[rc], cpu_ir[rb]);
                   1902:             }
1.1       root     1903:             break;
                   1904:         case 0x30:
                   1905:             /* CTPOP */
                   1906:             if (!(ctx->amask & AMASK_CIX))
                   1907:                 goto invalid_opc;
1.1.1.2   root     1908:             if (likely(rc != 31)) {
                   1909:                 if (islit)
                   1910:                     tcg_gen_movi_i64(cpu_ir[rc], ctpop64(lit));
                   1911:                 else
                   1912:                     gen_helper_ctpop(cpu_ir[rc], cpu_ir[rb]);
                   1913:             }
1.1       root     1914:             break;
                   1915:         case 0x31:
                   1916:             /* PERR */
                   1917:             if (!(ctx->amask & AMASK_MVI))
                   1918:                 goto invalid_opc;
                   1919:             /* XXX: TODO */
                   1920:             goto invalid_opc;
                   1921:             break;
                   1922:         case 0x32:
                   1923:             /* CTLZ */
                   1924:             if (!(ctx->amask & AMASK_CIX))
                   1925:                 goto invalid_opc;
1.1.1.2   root     1926:             if (likely(rc != 31)) {
                   1927:                 if (islit)
                   1928:                     tcg_gen_movi_i64(cpu_ir[rc], clz64(lit));
                   1929:                 else
                   1930:                     gen_helper_ctlz(cpu_ir[rc], cpu_ir[rb]);
                   1931:             }
1.1       root     1932:             break;
                   1933:         case 0x33:
                   1934:             /* CTTZ */
                   1935:             if (!(ctx->amask & AMASK_CIX))
                   1936:                 goto invalid_opc;
1.1.1.2   root     1937:             if (likely(rc != 31)) {
                   1938:                 if (islit)
                   1939:                     tcg_gen_movi_i64(cpu_ir[rc], ctz64(lit));
                   1940:                 else
                   1941:                     gen_helper_cttz(cpu_ir[rc], cpu_ir[rb]);
                   1942:             }
1.1       root     1943:             break;
                   1944:         case 0x34:
                   1945:             /* UNPKBW */
                   1946:             if (!(ctx->amask & AMASK_MVI))
                   1947:                 goto invalid_opc;
                   1948:             /* XXX: TODO */
                   1949:             goto invalid_opc;
                   1950:             break;
                   1951:         case 0x35:
                   1952:             /* UNPKWL */
                   1953:             if (!(ctx->amask & AMASK_MVI))
                   1954:                 goto invalid_opc;
                   1955:             /* XXX: TODO */
                   1956:             goto invalid_opc;
                   1957:             break;
                   1958:         case 0x36:
                   1959:             /* PKWB */
                   1960:             if (!(ctx->amask & AMASK_MVI))
                   1961:                 goto invalid_opc;
                   1962:             /* XXX: TODO */
                   1963:             goto invalid_opc;
                   1964:             break;
                   1965:         case 0x37:
                   1966:             /* PKLB */
                   1967:             if (!(ctx->amask & AMASK_MVI))
                   1968:                 goto invalid_opc;
                   1969:             /* XXX: TODO */
                   1970:             goto invalid_opc;
                   1971:             break;
                   1972:         case 0x38:
                   1973:             /* MINSB8 */
                   1974:             if (!(ctx->amask & AMASK_MVI))
                   1975:                 goto invalid_opc;
                   1976:             /* XXX: TODO */
                   1977:             goto invalid_opc;
                   1978:             break;
                   1979:         case 0x39:
                   1980:             /* MINSW4 */
                   1981:             if (!(ctx->amask & AMASK_MVI))
                   1982:                 goto invalid_opc;
                   1983:             /* XXX: TODO */
                   1984:             goto invalid_opc;
                   1985:             break;
                   1986:         case 0x3A:
                   1987:             /* MINUB8 */
                   1988:             if (!(ctx->amask & AMASK_MVI))
                   1989:                 goto invalid_opc;
                   1990:             /* XXX: TODO */
                   1991:             goto invalid_opc;
                   1992:             break;
                   1993:         case 0x3B:
                   1994:             /* MINUW4 */
                   1995:             if (!(ctx->amask & AMASK_MVI))
                   1996:                 goto invalid_opc;
                   1997:             /* XXX: TODO */
                   1998:             goto invalid_opc;
                   1999:             break;
                   2000:         case 0x3C:
                   2001:             /* MAXUB8 */
                   2002:             if (!(ctx->amask & AMASK_MVI))
                   2003:                 goto invalid_opc;
                   2004:             /* XXX: TODO */
                   2005:             goto invalid_opc;
                   2006:             break;
                   2007:         case 0x3D:
                   2008:             /* MAXUW4 */
                   2009:             if (!(ctx->amask & AMASK_MVI))
                   2010:                 goto invalid_opc;
                   2011:             /* XXX: TODO */
                   2012:             goto invalid_opc;
                   2013:             break;
                   2014:         case 0x3E:
                   2015:             /* MAXSB8 */
                   2016:             if (!(ctx->amask & AMASK_MVI))
                   2017:                 goto invalid_opc;
                   2018:             /* XXX: TODO */
                   2019:             goto invalid_opc;
                   2020:             break;
                   2021:         case 0x3F:
                   2022:             /* MAXSW4 */
                   2023:             if (!(ctx->amask & AMASK_MVI))
                   2024:                 goto invalid_opc;
                   2025:             /* XXX: TODO */
                   2026:             goto invalid_opc;
                   2027:             break;
                   2028:         case 0x70:
                   2029:             /* FTOIT */
                   2030:             if (!(ctx->amask & AMASK_FIX))
                   2031:                 goto invalid_opc;
1.1.1.2   root     2032:             if (likely(rc != 31)) {
                   2033:                 if (ra != 31)
                   2034:                     tcg_gen_mov_i64(cpu_ir[rc], cpu_fir[ra]);
                   2035:                 else
                   2036:                     tcg_gen_movi_i64(cpu_ir[rc], 0);
                   2037:             }
1.1       root     2038:             break;
                   2039:         case 0x78:
                   2040:             /* FTOIS */
                   2041:             if (!(ctx->amask & AMASK_FIX))
                   2042:                 goto invalid_opc;
1.1.1.2   root     2043:             if (rc != 31) {
                   2044:                 TCGv_i32 tmp1 = tcg_temp_new_i32();
                   2045:                 if (ra != 31)
                   2046:                     gen_helper_s_to_memory(tmp1, cpu_fir[ra]);
                   2047:                 else {
                   2048:                     TCGv tmp2 = tcg_const_i64(0);
                   2049:                     gen_helper_s_to_memory(tmp1, tmp2);
                   2050:                     tcg_temp_free(tmp2);
                   2051:                 }
                   2052:                 tcg_gen_ext_i32_i64(cpu_ir[rc], tmp1);
                   2053:                 tcg_temp_free_i32(tmp1);
                   2054:             }
1.1       root     2055:             break;
                   2056:         default:
                   2057:             goto invalid_opc;
                   2058:         }
                   2059:         break;
                   2060:     case 0x1D:
                   2061:         /* HW_MTPR (PALcode) */
                   2062: #if defined (CONFIG_USER_ONLY)
                   2063:         goto invalid_opc;
                   2064: #else
                   2065:         if (!ctx->pal_mode)
                   2066:             goto invalid_opc;
1.1.1.2   root     2067:         else {
                   2068:             TCGv tmp1 = tcg_const_i32(insn & 0xFF);
                   2069:             if (ra != 31)
                   2070:                 gen_helper_mtpr(tmp1, cpu_ir[ra]);
                   2071:             else {
                   2072:                 TCGv tmp2 = tcg_const_i64(0);
                   2073:                 gen_helper_mtpr(tmp1, tmp2);
                   2074:                 tcg_temp_free(tmp2);
                   2075:             }
                   2076:             tcg_temp_free(tmp1);
                   2077:             ret = 2;
                   2078:         }
1.1       root     2079:         break;
                   2080: #endif
                   2081:     case 0x1E:
                   2082:         /* HW_REI (PALcode) */
                   2083: #if defined (CONFIG_USER_ONLY)
                   2084:         goto invalid_opc;
                   2085: #else
                   2086:         if (!ctx->pal_mode)
                   2087:             goto invalid_opc;
                   2088:         if (rb == 31) {
                   2089:             /* "Old" alpha */
1.1.1.2   root     2090:             gen_helper_hw_rei();
1.1       root     2091:         } else {
1.1.1.2   root     2092:             TCGv tmp;
                   2093: 
                   2094:             if (ra != 31) {
                   2095:                 tmp = tcg_temp_new();
                   2096:                 tcg_gen_addi_i64(tmp, cpu_ir[rb], (((int64_t)insn << 51) >> 51));
                   2097:             } else
                   2098:                 tmp = tcg_const_i64(((int64_t)insn << 51) >> 51);
                   2099:             gen_helper_hw_ret(tmp);
                   2100:             tcg_temp_free(tmp);
1.1       root     2101:         }
                   2102:         ret = 2;
                   2103:         break;
                   2104: #endif
                   2105:     case 0x1F:
                   2106:         /* HW_ST (PALcode) */
                   2107: #if defined (CONFIG_USER_ONLY)
                   2108:         goto invalid_opc;
                   2109: #else
                   2110:         if (!ctx->pal_mode)
                   2111:             goto invalid_opc;
1.1.1.2   root     2112:         else {
                   2113:             TCGv addr, val;
                   2114:             addr = tcg_temp_new();
                   2115:             if (rb != 31)
                   2116:                 tcg_gen_addi_i64(addr, cpu_ir[rb], disp12);
                   2117:             else
                   2118:                 tcg_gen_movi_i64(addr, disp12);
                   2119:             if (ra != 31)
                   2120:                 val = cpu_ir[ra];
                   2121:             else {
                   2122:                 val = tcg_temp_new();
                   2123:                 tcg_gen_movi_i64(val, 0);
                   2124:             }
                   2125:             switch ((insn >> 12) & 0xF) {
                   2126:             case 0x0:
                   2127:                 /* Longword physical access */
                   2128:                 gen_helper_stl_raw(val, addr);
                   2129:                 break;
                   2130:             case 0x1:
                   2131:                 /* Quadword physical access */
                   2132:                 gen_helper_stq_raw(val, addr);
                   2133:                 break;
                   2134:             case 0x2:
                   2135:                 /* Longword physical access with lock */
                   2136:                 gen_helper_stl_c_raw(val, val, addr);
                   2137:                 break;
                   2138:             case 0x3:
                   2139:                 /* Quadword physical access with lock */
                   2140:                 gen_helper_stq_c_raw(val, val, addr);
                   2141:                 break;
                   2142:             case 0x4:
                   2143:                 /* Longword virtual access */
                   2144:                 gen_helper_st_virt_to_phys(addr, addr);
                   2145:                 gen_helper_stl_raw(val, addr);
                   2146:                 break;
                   2147:             case 0x5:
                   2148:                 /* Quadword virtual access */
                   2149:                 gen_helper_st_virt_to_phys(addr, addr);
                   2150:                 gen_helper_stq_raw(val, addr);
                   2151:                 break;
                   2152:             case 0x6:
                   2153:                 /* Invalid */
                   2154:                 goto invalid_opc;
                   2155:             case 0x7:
                   2156:                 /* Invalid */
                   2157:                 goto invalid_opc;
                   2158:             case 0x8:
                   2159:                 /* Invalid */
                   2160:                 goto invalid_opc;
                   2161:             case 0x9:
                   2162:                 /* Invalid */
                   2163:                 goto invalid_opc;
                   2164:             case 0xA:
                   2165:                 /* Invalid */
                   2166:                 goto invalid_opc;
                   2167:             case 0xB:
                   2168:                 /* Invalid */
                   2169:                 goto invalid_opc;
                   2170:             case 0xC:
                   2171:                 /* Longword virtual access with alternate access mode */
                   2172:                 gen_helper_set_alt_mode();
                   2173:                 gen_helper_st_virt_to_phys(addr, addr);
                   2174:                 gen_helper_stl_raw(val, addr);
                   2175:                 gen_helper_restore_mode();
                   2176:                 break;
                   2177:             case 0xD:
                   2178:                 /* Quadword virtual access with alternate access mode */
                   2179:                 gen_helper_set_alt_mode();
                   2180:                 gen_helper_st_virt_to_phys(addr, addr);
                   2181:                 gen_helper_stl_raw(val, addr);
                   2182:                 gen_helper_restore_mode();
                   2183:                 break;
                   2184:             case 0xE:
                   2185:                 /* Invalid */
                   2186:                 goto invalid_opc;
                   2187:             case 0xF:
                   2188:                 /* Invalid */
                   2189:                 goto invalid_opc;
                   2190:             }
1.1.1.3   root     2191:             if (ra == 31)
1.1.1.2   root     2192:                 tcg_temp_free(val);
                   2193:             tcg_temp_free(addr);
1.1       root     2194:         }
                   2195:         break;
                   2196: #endif
                   2197:     case 0x20:
                   2198:         /* LDF */
1.1.1.2   root     2199:         gen_load_mem(ctx, &gen_qemu_ldf, ra, rb, disp16, 1, 0);
1.1       root     2200:         break;
                   2201:     case 0x21:
                   2202:         /* LDG */
1.1.1.2   root     2203:         gen_load_mem(ctx, &gen_qemu_ldg, ra, rb, disp16, 1, 0);
1.1       root     2204:         break;
                   2205:     case 0x22:
                   2206:         /* LDS */
1.1.1.2   root     2207:         gen_load_mem(ctx, &gen_qemu_lds, ra, rb, disp16, 1, 0);
1.1       root     2208:         break;
                   2209:     case 0x23:
                   2210:         /* LDT */
1.1.1.2   root     2211:         gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 1, 0);
1.1       root     2212:         break;
                   2213:     case 0x24:
                   2214:         /* STF */
1.1.1.2   root     2215:         gen_store_mem(ctx, &gen_qemu_stf, ra, rb, disp16, 1, 0, 0);
1.1       root     2216:         break;
                   2217:     case 0x25:
                   2218:         /* STG */
1.1.1.2   root     2219:         gen_store_mem(ctx, &gen_qemu_stg, ra, rb, disp16, 1, 0, 0);
1.1       root     2220:         break;
                   2221:     case 0x26:
                   2222:         /* STS */
1.1.1.2   root     2223:         gen_store_mem(ctx, &gen_qemu_sts, ra, rb, disp16, 1, 0, 0);
1.1       root     2224:         break;
                   2225:     case 0x27:
                   2226:         /* STT */
1.1.1.2   root     2227:         gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 1, 0, 0);
1.1       root     2228:         break;
                   2229:     case 0x28:
                   2230:         /* LDL */
1.1.1.2   root     2231:         gen_load_mem(ctx, &tcg_gen_qemu_ld32s, ra, rb, disp16, 0, 0);
1.1       root     2232:         break;
                   2233:     case 0x29:
                   2234:         /* LDQ */
1.1.1.2   root     2235:         gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 0);
1.1       root     2236:         break;
                   2237:     case 0x2A:
                   2238:         /* LDL_L */
1.1.1.2   root     2239:         gen_load_mem(ctx, &gen_qemu_ldl_l, ra, rb, disp16, 0, 0);
1.1       root     2240:         break;
                   2241:     case 0x2B:
                   2242:         /* LDQ_L */
1.1.1.2   root     2243:         gen_load_mem(ctx, &gen_qemu_ldq_l, ra, rb, disp16, 0, 0);
1.1       root     2244:         break;
                   2245:     case 0x2C:
                   2246:         /* STL */
1.1.1.2   root     2247:         gen_store_mem(ctx, &tcg_gen_qemu_st32, ra, rb, disp16, 0, 0, 0);
1.1       root     2248:         break;
                   2249:     case 0x2D:
                   2250:         /* STQ */
1.1.1.2   root     2251:         gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 0, 0);
1.1       root     2252:         break;
                   2253:     case 0x2E:
                   2254:         /* STL_C */
1.1.1.2   root     2255:         gen_store_mem(ctx, &gen_qemu_stl_c, ra, rb, disp16, 0, 0, 1);
1.1       root     2256:         break;
                   2257:     case 0x2F:
                   2258:         /* STQ_C */
1.1.1.2   root     2259:         gen_store_mem(ctx, &gen_qemu_stq_c, ra, rb, disp16, 0, 0, 1);
1.1       root     2260:         break;
                   2261:     case 0x30:
                   2262:         /* BR */
1.1.1.2   root     2263:         if (ra != 31)
                   2264:             tcg_gen_movi_i64(cpu_ir[ra], ctx->pc);
                   2265:         tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp21 << 2));
1.1       root     2266:         ret = 1;
                   2267:         break;
1.1.1.2   root     2268:     case 0x31: /* FBEQ */
                   2269:     case 0x32: /* FBLT */
                   2270:     case 0x33: /* FBLE */
                   2271:         gen_fbcond(ctx, opc, ra, disp16);
1.1       root     2272:         ret = 1;
                   2273:         break;
                   2274:     case 0x34:
                   2275:         /* BSR */
1.1.1.2   root     2276:         if (ra != 31)
                   2277:             tcg_gen_movi_i64(cpu_ir[ra], ctx->pc);
                   2278:         tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp21 << 2));
1.1       root     2279:         ret = 1;
                   2280:         break;
1.1.1.2   root     2281:     case 0x35: /* FBNE */
                   2282:     case 0x36: /* FBGE */
                   2283:     case 0x37: /* FBGT */
                   2284:         gen_fbcond(ctx, opc, ra, disp16);
1.1       root     2285:         ret = 1;
                   2286:         break;
                   2287:     case 0x38:
                   2288:         /* BLBC */
1.1.1.3   root     2289:         gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 1);
1.1       root     2290:         ret = 1;
                   2291:         break;
                   2292:     case 0x39:
                   2293:         /* BEQ */
1.1.1.3   root     2294:         gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 0);
1.1       root     2295:         ret = 1;
                   2296:         break;
                   2297:     case 0x3A:
                   2298:         /* BLT */
1.1.1.3   root     2299:         gen_bcond(ctx, TCG_COND_LT, ra, disp21, 0);
1.1       root     2300:         ret = 1;
                   2301:         break;
                   2302:     case 0x3B:
                   2303:         /* BLE */
1.1.1.3   root     2304:         gen_bcond(ctx, TCG_COND_LE, ra, disp21, 0);
1.1       root     2305:         ret = 1;
                   2306:         break;
                   2307:     case 0x3C:
                   2308:         /* BLBS */
1.1.1.3   root     2309:         gen_bcond(ctx, TCG_COND_NE, ra, disp21, 1);
1.1       root     2310:         ret = 1;
                   2311:         break;
                   2312:     case 0x3D:
                   2313:         /* BNE */
1.1.1.3   root     2314:         gen_bcond(ctx, TCG_COND_NE, ra, disp21, 0);
1.1       root     2315:         ret = 1;
                   2316:         break;
                   2317:     case 0x3E:
                   2318:         /* BGE */
1.1.1.3   root     2319:         gen_bcond(ctx, TCG_COND_GE, ra, disp21, 0);
1.1       root     2320:         ret = 1;
                   2321:         break;
                   2322:     case 0x3F:
                   2323:         /* BGT */
1.1.1.3   root     2324:         gen_bcond(ctx, TCG_COND_GT, ra, disp21, 0);
1.1       root     2325:         ret = 1;
                   2326:         break;
                   2327:     invalid_opc:
                   2328:         gen_invalid(ctx);
                   2329:         ret = 3;
                   2330:         break;
                   2331:     }
                   2332: 
                   2333:     return ret;
                   2334: }
                   2335: 
1.1.1.4 ! root     2336: static inline void gen_intermediate_code_internal(CPUState *env,
        !          2337:                                                   TranslationBlock *tb,
        !          2338:                                                   int search_pc)
1.1       root     2339: {
                   2340: #if defined ALPHA_DEBUG_DISAS
                   2341:     static int insn_count;
                   2342: #endif
                   2343:     DisasContext ctx, *ctxp = &ctx;
                   2344:     target_ulong pc_start;
                   2345:     uint32_t insn;
                   2346:     uint16_t *gen_opc_end;
1.1.1.2   root     2347:     CPUBreakpoint *bp;
1.1       root     2348:     int j, lj = -1;
                   2349:     int ret;
1.1.1.2   root     2350:     int num_insns;
                   2351:     int max_insns;
1.1       root     2352: 
                   2353:     pc_start = tb->pc;
                   2354:     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
                   2355:     ctx.pc = pc_start;
                   2356:     ctx.amask = env->amask;
1.1.1.3   root     2357:     ctx.env = env;
1.1       root     2358: #if defined (CONFIG_USER_ONLY)
                   2359:     ctx.mem_idx = 0;
                   2360: #else
                   2361:     ctx.mem_idx = ((env->ps >> 3) & 3);
                   2362:     ctx.pal_mode = env->ipr[IPR_EXC_ADDR] & 1;
                   2363: #endif
1.1.1.2   root     2364:     num_insns = 0;
                   2365:     max_insns = tb->cflags & CF_COUNT_MASK;
                   2366:     if (max_insns == 0)
                   2367:         max_insns = CF_COUNT_MASK;
                   2368: 
                   2369:     gen_icount_start();
1.1       root     2370:     for (ret = 0; ret == 0;) {
1.1.1.4 ! root     2371:         if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
        !          2372:             QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
1.1.1.2   root     2373:                 if (bp->pc == ctx.pc) {
1.1       root     2374:                     gen_excp(&ctx, EXCP_DEBUG, 0);
                   2375:                     break;
                   2376:                 }
                   2377:             }
                   2378:         }
                   2379:         if (search_pc) {
                   2380:             j = gen_opc_ptr - gen_opc_buf;
                   2381:             if (lj < j) {
                   2382:                 lj++;
                   2383:                 while (lj < j)
                   2384:                     gen_opc_instr_start[lj++] = 0;
                   2385:             }
1.1.1.3   root     2386:             gen_opc_pc[lj] = ctx.pc;
                   2387:             gen_opc_instr_start[lj] = 1;
                   2388:             gen_opc_icount[lj] = num_insns;
1.1       root     2389:         }
1.1.1.2   root     2390:         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
                   2391:             gen_io_start();
1.1       root     2392: #if defined ALPHA_DEBUG_DISAS
                   2393:         insn_count++;
1.1.1.2   root     2394:         LOG_DISAS("pc " TARGET_FMT_lx " mem_idx %d\n",
                   2395:                   ctx.pc, ctx.mem_idx);
1.1       root     2396: #endif
                   2397:         insn = ldl_code(ctx.pc);
                   2398: #if defined ALPHA_DEBUG_DISAS
                   2399:         insn_count++;
1.1.1.2   root     2400:         LOG_DISAS("opcode %08x %d\n", insn, insn_count);
1.1       root     2401: #endif
1.1.1.2   root     2402:         num_insns++;
1.1       root     2403:         ctx.pc += 4;
                   2404:         ret = translate_one(ctxp, insn);
                   2405:         if (ret != 0)
                   2406:             break;
                   2407:         /* if we reach a page boundary or are single stepping, stop
                   2408:          * generation
                   2409:          */
1.1.1.3   root     2410:         if (env->singlestep_enabled) {
                   2411:             gen_excp(&ctx, EXCP_DEBUG, 0);
1.1       root     2412:             break;
                   2413:         }
1.1.1.2   root     2414: 
1.1.1.3   root     2415:         if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1.1.1.2   root     2416:             break;
                   2417: 
1.1.1.3   root     2418:         if (gen_opc_ptr >= gen_opc_end)
                   2419:             break;
                   2420: 
                   2421:         if (num_insns >= max_insns)
                   2422:             break;
                   2423: 
                   2424:         if (singlestep) {
                   2425:             break;
                   2426:         }
1.1       root     2427:     }
                   2428:     if (ret != 1 && ret != 3) {
1.1.1.2   root     2429:         tcg_gen_movi_i64(cpu_pc, ctx.pc);
1.1       root     2430:     }
                   2431: #if defined (DO_TB_FLUSH)
1.1.1.2   root     2432:     gen_helper_tb_flush();
1.1       root     2433: #endif
1.1.1.2   root     2434:     if (tb->cflags & CF_LAST_IO)
                   2435:         gen_io_end();
1.1       root     2436:     /* Generate the return instruction */
1.1.1.2   root     2437:     tcg_gen_exit_tb(0);
                   2438:     gen_icount_end(tb, num_insns);
1.1       root     2439:     *gen_opc_ptr = INDEX_op_end;
                   2440:     if (search_pc) {
                   2441:         j = gen_opc_ptr - gen_opc_buf;
                   2442:         lj++;
                   2443:         while (lj <= j)
                   2444:             gen_opc_instr_start[lj++] = 0;
                   2445:     } else {
                   2446:         tb->size = ctx.pc - pc_start;
1.1.1.2   root     2447:         tb->icount = num_insns;
1.1       root     2448:     }
                   2449: #if defined ALPHA_DEBUG_DISAS
1.1.1.2   root     2450:     log_cpu_state_mask(CPU_LOG_TB_CPU, env, 0);
                   2451:     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
                   2452:         qemu_log("IN: %s\n", lookup_symbol(pc_start));
                   2453:         log_target_disas(pc_start, ctx.pc - pc_start, 1);
                   2454:         qemu_log("\n");
1.1       root     2455:     }
                   2456: #endif
                   2457: }
                   2458: 
1.1.1.2   root     2459: void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
1.1       root     2460: {
1.1.1.2   root     2461:     gen_intermediate_code_internal(env, tb, 0);
1.1       root     2462: }
                   2463: 
1.1.1.2   root     2464: void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
1.1       root     2465: {
1.1.1.2   root     2466:     gen_intermediate_code_internal(env, tb, 1);
1.1       root     2467: }
                   2468: 
                   2469: CPUAlphaState * cpu_alpha_init (const char *cpu_model)
                   2470: {
                   2471:     CPUAlphaState *env;
                   2472:     uint64_t hwpcb;
                   2473: 
                   2474:     env = qemu_mallocz(sizeof(CPUAlphaState));
                   2475:     cpu_exec_init(env);
1.1.1.2   root     2476:     alpha_translate_init();
1.1       root     2477:     tlb_flush(env, 1);
                   2478:     /* XXX: should not be hardcoded */
                   2479:     env->implver = IMPLVER_2106x;
                   2480:     env->ps = 0x1F00;
                   2481: #if defined (CONFIG_USER_ONLY)
                   2482:     env->ps |= 1 << 3;
                   2483: #endif
                   2484:     pal_init(env);
                   2485:     /* Initialize IPR */
                   2486:     hwpcb = env->ipr[IPR_PCBB];
                   2487:     env->ipr[IPR_ASN] = 0;
                   2488:     env->ipr[IPR_ASTEN] = 0;
                   2489:     env->ipr[IPR_ASTSR] = 0;
                   2490:     env->ipr[IPR_DATFX] = 0;
                   2491:     /* XXX: fix this */
                   2492:     //    env->ipr[IPR_ESP] = ldq_raw(hwpcb + 8);
                   2493:     //    env->ipr[IPR_KSP] = ldq_raw(hwpcb + 0);
                   2494:     //    env->ipr[IPR_SSP] = ldq_raw(hwpcb + 16);
                   2495:     //    env->ipr[IPR_USP] = ldq_raw(hwpcb + 24);
                   2496:     env->ipr[IPR_FEN] = 0;
                   2497:     env->ipr[IPR_IPL] = 31;
                   2498:     env->ipr[IPR_MCES] = 0;
                   2499:     env->ipr[IPR_PERFMON] = 0; /* Implementation specific */
                   2500:     //    env->ipr[IPR_PTBR] = ldq_raw(hwpcb + 32);
                   2501:     env->ipr[IPR_SISR] = 0;
                   2502:     env->ipr[IPR_VIRBND] = -1ULL;
                   2503: 
1.1.1.3   root     2504:     qemu_init_vcpu(env);
1.1       root     2505:     return env;
                   2506: }
                   2507: 
1.1.1.2   root     2508: void gen_pc_load(CPUState *env, TranslationBlock *tb,
                   2509:                 unsigned long searched_pc, int pc_pos, void *puc)
                   2510: {
                   2511:     env->pc = gen_opc_pc[pc_pos];
                   2512: }

unix.superglobalmegacorp.com

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