qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

translate.c (174585B)


      1 /*
      2  *  m68k translation
      3  *
      4  *  Copyright (c) 2005-2007 CodeSourcery
      5  *  Written by Paul Brook
      6  *
      7  * This library is free software; you can redistribute it and/or
      8  * modify it under the terms of the GNU Lesser General Public
      9  * License as published by the Free Software Foundation; either
     10  * version 2.1 of the License, or (at your option) any later version.
     11  *
     12  * This library is distributed in the hope that it will be useful,
     13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15  * Lesser General Public License for more details.
     16  *
     17  * You should have received a copy of the GNU Lesser General Public
     18  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
     19  */
     20 
     21 #include "qemu/osdep.h"
     22 #include "cpu.h"
     23 #include "disas/disas.h"
     24 #include "exec/exec-all.h"
     25 #include "tcg/tcg-op.h"
     26 #include "qemu/log.h"
     27 #include "qemu/qemu-print.h"
     28 #include "exec/cpu_ldst.h"
     29 #include "exec/translator.h"
     30 
     31 #include "exec/helper-proto.h"
     32 #include "exec/helper-gen.h"
     33 
     34 #include "exec/log.h"
     35 #include "fpu/softfloat.h"
     36 
     37 
     38 //#define DEBUG_DISPATCH 1
     39 
     40 #define DEFO32(name, offset) static TCGv QREG_##name;
     41 #define DEFO64(name, offset) static TCGv_i64 QREG_##name;
     42 #include "qregs.h.inc"
     43 #undef DEFO32
     44 #undef DEFO64
     45 
     46 static TCGv_i32 cpu_halted;
     47 static TCGv_i32 cpu_exception_index;
     48 
     49 static char cpu_reg_names[2 * 8 * 3 + 5 * 4];
     50 static TCGv cpu_dregs[8];
     51 static TCGv cpu_aregs[8];
     52 static TCGv_i64 cpu_macc[4];
     53 
     54 #define REG(insn, pos)  (((insn) >> (pos)) & 7)
     55 #define DREG(insn, pos) cpu_dregs[REG(insn, pos)]
     56 #define AREG(insn, pos) get_areg(s, REG(insn, pos))
     57 #define MACREG(acc)     cpu_macc[acc]
     58 #define QREG_SP         get_areg(s, 7)
     59 
     60 static TCGv NULL_QREG;
     61 #define IS_NULL_QREG(t) (t == NULL_QREG)
     62 /* Used to distinguish stores from bad addressing modes.  */
     63 static TCGv store_dummy;
     64 
     65 #include "exec/gen-icount.h"
     66 
     67 void m68k_tcg_init(void)
     68 {
     69     char *p;
     70     int i;
     71 
     72 #define DEFO32(name, offset) \
     73     QREG_##name = tcg_global_mem_new_i32(cpu_env, \
     74         offsetof(CPUM68KState, offset), #name);
     75 #define DEFO64(name, offset) \
     76     QREG_##name = tcg_global_mem_new_i64(cpu_env, \
     77         offsetof(CPUM68KState, offset), #name);
     78 #include "qregs.h.inc"
     79 #undef DEFO32
     80 #undef DEFO64
     81 
     82     cpu_halted = tcg_global_mem_new_i32(cpu_env,
     83                                         -offsetof(M68kCPU, env) +
     84                                         offsetof(CPUState, halted), "HALTED");
     85     cpu_exception_index = tcg_global_mem_new_i32(cpu_env,
     86                                                  -offsetof(M68kCPU, env) +
     87                                                  offsetof(CPUState, exception_index),
     88                                                  "EXCEPTION");
     89 
     90     p = cpu_reg_names;
     91     for (i = 0; i < 8; i++) {
     92         sprintf(p, "D%d", i);
     93         cpu_dregs[i] = tcg_global_mem_new(cpu_env,
     94                                           offsetof(CPUM68KState, dregs[i]), p);
     95         p += 3;
     96         sprintf(p, "A%d", i);
     97         cpu_aregs[i] = tcg_global_mem_new(cpu_env,
     98                                           offsetof(CPUM68KState, aregs[i]), p);
     99         p += 3;
    100     }
    101     for (i = 0; i < 4; i++) {
    102         sprintf(p, "ACC%d", i);
    103         cpu_macc[i] = tcg_global_mem_new_i64(cpu_env,
    104                                          offsetof(CPUM68KState, macc[i]), p);
    105         p += 5;
    106     }
    107 
    108     NULL_QREG = tcg_global_mem_new(cpu_env, -4, "NULL");
    109     store_dummy = tcg_global_mem_new(cpu_env, -8, "NULL");
    110 }
    111 
    112 /* internal defines */
    113 typedef struct DisasContext {
    114     DisasContextBase base;
    115     CPUM68KState *env;
    116     target_ulong pc;
    117     target_ulong pc_prev;
    118     CCOp cc_op; /* Current CC operation */
    119     int cc_op_synced;
    120     TCGv_i64 mactmp;
    121     int done_mac;
    122     int writeback_mask;
    123     TCGv writeback[8];
    124 #define MAX_TO_RELEASE 8
    125     int release_count;
    126     TCGv release[MAX_TO_RELEASE];
    127     bool ss_active;
    128 } DisasContext;
    129 
    130 static void init_release_array(DisasContext *s)
    131 {
    132 #ifdef CONFIG_DEBUG_TCG
    133     memset(s->release, 0, sizeof(s->release));
    134 #endif
    135     s->release_count = 0;
    136 }
    137 
    138 static void do_release(DisasContext *s)
    139 {
    140     int i;
    141     for (i = 0; i < s->release_count; i++) {
    142         tcg_temp_free(s->release[i]);
    143     }
    144     init_release_array(s);
    145 }
    146 
    147 static TCGv mark_to_release(DisasContext *s, TCGv tmp)
    148 {
    149     g_assert(s->release_count < MAX_TO_RELEASE);
    150     return s->release[s->release_count++] = tmp;
    151 }
    152 
    153 static TCGv get_areg(DisasContext *s, unsigned regno)
    154 {
    155     if (s->writeback_mask & (1 << regno)) {
    156         return s->writeback[regno];
    157     } else {
    158         return cpu_aregs[regno];
    159     }
    160 }
    161 
    162 static void delay_set_areg(DisasContext *s, unsigned regno,
    163                            TCGv val, bool give_temp)
    164 {
    165     if (s->writeback_mask & (1 << regno)) {
    166         if (give_temp) {
    167             tcg_temp_free(s->writeback[regno]);
    168             s->writeback[regno] = val;
    169         } else {
    170             tcg_gen_mov_i32(s->writeback[regno], val);
    171         }
    172     } else {
    173         s->writeback_mask |= 1 << regno;
    174         if (give_temp) {
    175             s->writeback[regno] = val;
    176         } else {
    177             TCGv tmp = tcg_temp_new();
    178             s->writeback[regno] = tmp;
    179             tcg_gen_mov_i32(tmp, val);
    180         }
    181     }
    182 }
    183 
    184 static void do_writebacks(DisasContext *s)
    185 {
    186     unsigned mask = s->writeback_mask;
    187     if (mask) {
    188         s->writeback_mask = 0;
    189         do {
    190             unsigned regno = ctz32(mask);
    191             tcg_gen_mov_i32(cpu_aregs[regno], s->writeback[regno]);
    192             tcg_temp_free(s->writeback[regno]);
    193             mask &= mask - 1;
    194         } while (mask);
    195     }
    196 }
    197 
    198 /* is_jmp field values */
    199 #define DISAS_JUMP      DISAS_TARGET_0 /* only pc was modified dynamically */
    200 #define DISAS_EXIT      DISAS_TARGET_1 /* cpu state was modified dynamically */
    201 
    202 #if defined(CONFIG_USER_ONLY)
    203 #define IS_USER(s) 1
    204 #else
    205 #define IS_USER(s)   (!(s->base.tb->flags & TB_FLAGS_MSR_S))
    206 #define SFC_INDEX(s) ((s->base.tb->flags & TB_FLAGS_SFC_S) ? \
    207                       MMU_KERNEL_IDX : MMU_USER_IDX)
    208 #define DFC_INDEX(s) ((s->base.tb->flags & TB_FLAGS_DFC_S) ? \
    209                       MMU_KERNEL_IDX : MMU_USER_IDX)
    210 #endif
    211 
    212 typedef void (*disas_proc)(CPUM68KState *env, DisasContext *s, uint16_t insn);
    213 
    214 #ifdef DEBUG_DISPATCH
    215 #define DISAS_INSN(name)                                                \
    216     static void real_disas_##name(CPUM68KState *env, DisasContext *s,   \
    217                                   uint16_t insn);                       \
    218     static void disas_##name(CPUM68KState *env, DisasContext *s,        \
    219                              uint16_t insn)                             \
    220     {                                                                   \
    221         qemu_log("Dispatch " #name "\n");                               \
    222         real_disas_##name(env, s, insn);                                \
    223     }                                                                   \
    224     static void real_disas_##name(CPUM68KState *env, DisasContext *s,   \
    225                                   uint16_t insn)
    226 #else
    227 #define DISAS_INSN(name)                                                \
    228     static void disas_##name(CPUM68KState *env, DisasContext *s,        \
    229                              uint16_t insn)
    230 #endif
    231 
    232 static const uint8_t cc_op_live[CC_OP_NB] = {
    233     [CC_OP_DYNAMIC] = CCF_C | CCF_V | CCF_Z | CCF_N | CCF_X,
    234     [CC_OP_FLAGS] = CCF_C | CCF_V | CCF_Z | CCF_N | CCF_X,
    235     [CC_OP_ADDB ... CC_OP_ADDL] = CCF_X | CCF_N | CCF_V,
    236     [CC_OP_SUBB ... CC_OP_SUBL] = CCF_X | CCF_N | CCF_V,
    237     [CC_OP_CMPB ... CC_OP_CMPL] = CCF_X | CCF_N | CCF_V,
    238     [CC_OP_LOGIC] = CCF_X | CCF_N
    239 };
    240 
    241 static void set_cc_op(DisasContext *s, CCOp op)
    242 {
    243     CCOp old_op = s->cc_op;
    244     int dead;
    245 
    246     if (old_op == op) {
    247         return;
    248     }
    249     s->cc_op = op;
    250     s->cc_op_synced = 0;
    251 
    252     /*
    253      * Discard CC computation that will no longer be used.
    254      * Note that X and N are never dead.
    255      */
    256     dead = cc_op_live[old_op] & ~cc_op_live[op];
    257     if (dead & CCF_C) {
    258         tcg_gen_discard_i32(QREG_CC_C);
    259     }
    260     if (dead & CCF_Z) {
    261         tcg_gen_discard_i32(QREG_CC_Z);
    262     }
    263     if (dead & CCF_V) {
    264         tcg_gen_discard_i32(QREG_CC_V);
    265     }
    266 }
    267 
    268 /* Update the CPU env CC_OP state.  */
    269 static void update_cc_op(DisasContext *s)
    270 {
    271     if (!s->cc_op_synced) {
    272         s->cc_op_synced = 1;
    273         tcg_gen_movi_i32(QREG_CC_OP, s->cc_op);
    274     }
    275 }
    276 
    277 /* Generate a jump to an immediate address.  */
    278 static void gen_jmp_im(DisasContext *s, uint32_t dest)
    279 {
    280     update_cc_op(s);
    281     tcg_gen_movi_i32(QREG_PC, dest);
    282     s->base.is_jmp = DISAS_JUMP;
    283 }
    284 
    285 /* Generate a jump to the address in qreg DEST.  */
    286 static void gen_jmp(DisasContext *s, TCGv dest)
    287 {
    288     update_cc_op(s);
    289     tcg_gen_mov_i32(QREG_PC, dest);
    290     s->base.is_jmp = DISAS_JUMP;
    291 }
    292 
    293 static void gen_raise_exception(int nr)
    294 {
    295     TCGv_i32 tmp;
    296 
    297     tmp = tcg_const_i32(nr);
    298     gen_helper_raise_exception(cpu_env, tmp);
    299     tcg_temp_free_i32(tmp);
    300 }
    301 
    302 static void gen_raise_exception_format2(DisasContext *s, int nr,
    303                                         target_ulong this_pc)
    304 {
    305     /*
    306      * Pass the address of the insn to the exception handler,
    307      * for recording in the Format $2 (6-word) stack frame.
    308      * Re-use mmu.ar for the purpose, since that's only valid
    309      * after tlb_fill.
    310      */
    311     tcg_gen_st_i32(tcg_constant_i32(this_pc), cpu_env,
    312                    offsetof(CPUM68KState, mmu.ar));
    313     gen_raise_exception(nr);
    314     s->base.is_jmp = DISAS_NORETURN;
    315 }
    316 
    317 static void gen_exception(DisasContext *s, uint32_t dest, int nr)
    318 {
    319     update_cc_op(s);
    320     tcg_gen_movi_i32(QREG_PC, dest);
    321 
    322     gen_raise_exception(nr);
    323 
    324     s->base.is_jmp = DISAS_NORETURN;
    325 }
    326 
    327 static inline void gen_addr_fault(DisasContext *s)
    328 {
    329     gen_exception(s, s->base.pc_next, EXCP_ADDRESS);
    330 }
    331 
    332 /*
    333  * Generate a load from the specified address.  Narrow values are
    334  *  sign extended to full register width.
    335  */
    336 static inline TCGv gen_load(DisasContext *s, int opsize, TCGv addr,
    337                             int sign, int index)
    338 {
    339     TCGv tmp;
    340     tmp = tcg_temp_new_i32();
    341     switch(opsize) {
    342     case OS_BYTE:
    343         if (sign)
    344             tcg_gen_qemu_ld8s(tmp, addr, index);
    345         else
    346             tcg_gen_qemu_ld8u(tmp, addr, index);
    347         break;
    348     case OS_WORD:
    349         if (sign)
    350             tcg_gen_qemu_ld16s(tmp, addr, index);
    351         else
    352             tcg_gen_qemu_ld16u(tmp, addr, index);
    353         break;
    354     case OS_LONG:
    355         tcg_gen_qemu_ld32u(tmp, addr, index);
    356         break;
    357     default:
    358         g_assert_not_reached();
    359     }
    360     return tmp;
    361 }
    362 
    363 /* Generate a store.  */
    364 static inline void gen_store(DisasContext *s, int opsize, TCGv addr, TCGv val,
    365                              int index)
    366 {
    367     switch(opsize) {
    368     case OS_BYTE:
    369         tcg_gen_qemu_st8(val, addr, index);
    370         break;
    371     case OS_WORD:
    372         tcg_gen_qemu_st16(val, addr, index);
    373         break;
    374     case OS_LONG:
    375         tcg_gen_qemu_st32(val, addr, index);
    376         break;
    377     default:
    378         g_assert_not_reached();
    379     }
    380 }
    381 
    382 typedef enum {
    383     EA_STORE,
    384     EA_LOADU,
    385     EA_LOADS
    386 } ea_what;
    387 
    388 /*
    389  * Generate an unsigned load if VAL is 0 a signed load if val is -1,
    390  * otherwise generate a store.
    391  */
    392 static TCGv gen_ldst(DisasContext *s, int opsize, TCGv addr, TCGv val,
    393                      ea_what what, int index)
    394 {
    395     if (what == EA_STORE) {
    396         gen_store(s, opsize, addr, val, index);
    397         return store_dummy;
    398     } else {
    399         return mark_to_release(s, gen_load(s, opsize, addr,
    400                                            what == EA_LOADS, index));
    401     }
    402 }
    403 
    404 /* Read a 16-bit immediate constant */
    405 static inline uint16_t read_im16(CPUM68KState *env, DisasContext *s)
    406 {
    407     uint16_t im;
    408     im = translator_lduw(env, &s->base, s->pc);
    409     s->pc += 2;
    410     return im;
    411 }
    412 
    413 /* Read an 8-bit immediate constant */
    414 static inline uint8_t read_im8(CPUM68KState *env, DisasContext *s)
    415 {
    416     return read_im16(env, s);
    417 }
    418 
    419 /* Read a 32-bit immediate constant.  */
    420 static inline uint32_t read_im32(CPUM68KState *env, DisasContext *s)
    421 {
    422     uint32_t im;
    423     im = read_im16(env, s) << 16;
    424     im |= 0xffff & read_im16(env, s);
    425     return im;
    426 }
    427 
    428 /* Read a 64-bit immediate constant.  */
    429 static inline uint64_t read_im64(CPUM68KState *env, DisasContext *s)
    430 {
    431     uint64_t im;
    432     im = (uint64_t)read_im32(env, s) << 32;
    433     im |= (uint64_t)read_im32(env, s);
    434     return im;
    435 }
    436 
    437 /* Calculate and address index.  */
    438 static TCGv gen_addr_index(DisasContext *s, uint16_t ext, TCGv tmp)
    439 {
    440     TCGv add;
    441     int scale;
    442 
    443     add = (ext & 0x8000) ? AREG(ext, 12) : DREG(ext, 12);
    444     if ((ext & 0x800) == 0) {
    445         tcg_gen_ext16s_i32(tmp, add);
    446         add = tmp;
    447     }
    448     scale = (ext >> 9) & 3;
    449     if (scale != 0) {
    450         tcg_gen_shli_i32(tmp, add, scale);
    451         add = tmp;
    452     }
    453     return add;
    454 }
    455 
    456 /*
    457  * Handle a base + index + displacement effective address.
    458  * A NULL_QREG base means pc-relative.
    459  */
    460 static TCGv gen_lea_indexed(CPUM68KState *env, DisasContext *s, TCGv base)
    461 {
    462     uint32_t offset;
    463     uint16_t ext;
    464     TCGv add;
    465     TCGv tmp;
    466     uint32_t bd, od;
    467 
    468     offset = s->pc;
    469     ext = read_im16(env, s);
    470 
    471     if ((ext & 0x800) == 0 && !m68k_feature(s->env, M68K_FEATURE_WORD_INDEX))
    472         return NULL_QREG;
    473 
    474     if (m68k_feature(s->env, M68K_FEATURE_M68K) &&
    475         !m68k_feature(s->env, M68K_FEATURE_SCALED_INDEX)) {
    476         ext &= ~(3 << 9);
    477     }
    478 
    479     if (ext & 0x100) {
    480         /* full extension word format */
    481         if (!m68k_feature(s->env, M68K_FEATURE_EXT_FULL))
    482             return NULL_QREG;
    483 
    484         if ((ext & 0x30) > 0x10) {
    485             /* base displacement */
    486             if ((ext & 0x30) == 0x20) {
    487                 bd = (int16_t)read_im16(env, s);
    488             } else {
    489                 bd = read_im32(env, s);
    490             }
    491         } else {
    492             bd = 0;
    493         }
    494         tmp = mark_to_release(s, tcg_temp_new());
    495         if ((ext & 0x44) == 0) {
    496             /* pre-index */
    497             add = gen_addr_index(s, ext, tmp);
    498         } else {
    499             add = NULL_QREG;
    500         }
    501         if ((ext & 0x80) == 0) {
    502             /* base not suppressed */
    503             if (IS_NULL_QREG(base)) {
    504                 base = mark_to_release(s, tcg_const_i32(offset + bd));
    505                 bd = 0;
    506             }
    507             if (!IS_NULL_QREG(add)) {
    508                 tcg_gen_add_i32(tmp, add, base);
    509                 add = tmp;
    510             } else {
    511                 add = base;
    512             }
    513         }
    514         if (!IS_NULL_QREG(add)) {
    515             if (bd != 0) {
    516                 tcg_gen_addi_i32(tmp, add, bd);
    517                 add = tmp;
    518             }
    519         } else {
    520             add = mark_to_release(s, tcg_const_i32(bd));
    521         }
    522         if ((ext & 3) != 0) {
    523             /* memory indirect */
    524             base = mark_to_release(s, gen_load(s, OS_LONG, add, 0, IS_USER(s)));
    525             if ((ext & 0x44) == 4) {
    526                 add = gen_addr_index(s, ext, tmp);
    527                 tcg_gen_add_i32(tmp, add, base);
    528                 add = tmp;
    529             } else {
    530                 add = base;
    531             }
    532             if ((ext & 3) > 1) {
    533                 /* outer displacement */
    534                 if ((ext & 3) == 2) {
    535                     od = (int16_t)read_im16(env, s);
    536                 } else {
    537                     od = read_im32(env, s);
    538                 }
    539             } else {
    540                 od = 0;
    541             }
    542             if (od != 0) {
    543                 tcg_gen_addi_i32(tmp, add, od);
    544                 add = tmp;
    545             }
    546         }
    547     } else {
    548         /* brief extension word format */
    549         tmp = mark_to_release(s, tcg_temp_new());
    550         add = gen_addr_index(s, ext, tmp);
    551         if (!IS_NULL_QREG(base)) {
    552             tcg_gen_add_i32(tmp, add, base);
    553             if ((int8_t)ext)
    554                 tcg_gen_addi_i32(tmp, tmp, (int8_t)ext);
    555         } else {
    556             tcg_gen_addi_i32(tmp, add, offset + (int8_t)ext);
    557         }
    558         add = tmp;
    559     }
    560     return add;
    561 }
    562 
    563 /* Sign or zero extend a value.  */
    564 
    565 static inline void gen_ext(TCGv res, TCGv val, int opsize, int sign)
    566 {
    567     switch (opsize) {
    568     case OS_BYTE:
    569         if (sign) {
    570             tcg_gen_ext8s_i32(res, val);
    571         } else {
    572             tcg_gen_ext8u_i32(res, val);
    573         }
    574         break;
    575     case OS_WORD:
    576         if (sign) {
    577             tcg_gen_ext16s_i32(res, val);
    578         } else {
    579             tcg_gen_ext16u_i32(res, val);
    580         }
    581         break;
    582     case OS_LONG:
    583         tcg_gen_mov_i32(res, val);
    584         break;
    585     default:
    586         g_assert_not_reached();
    587     }
    588 }
    589 
    590 /* Evaluate all the CC flags.  */
    591 
    592 static void gen_flush_flags(DisasContext *s)
    593 {
    594     TCGv t0, t1;
    595 
    596     switch (s->cc_op) {
    597     case CC_OP_FLAGS:
    598         return;
    599 
    600     case CC_OP_ADDB:
    601     case CC_OP_ADDW:
    602     case CC_OP_ADDL:
    603         tcg_gen_mov_i32(QREG_CC_C, QREG_CC_X);
    604         tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N);
    605         /* Compute signed overflow for addition.  */
    606         t0 = tcg_temp_new();
    607         t1 = tcg_temp_new();
    608         tcg_gen_sub_i32(t0, QREG_CC_N, QREG_CC_V);
    609         gen_ext(t0, t0, s->cc_op - CC_OP_ADDB, 1);
    610         tcg_gen_xor_i32(t1, QREG_CC_N, QREG_CC_V);
    611         tcg_gen_xor_i32(QREG_CC_V, QREG_CC_V, t0);
    612         tcg_temp_free(t0);
    613         tcg_gen_andc_i32(QREG_CC_V, t1, QREG_CC_V);
    614         tcg_temp_free(t1);
    615         break;
    616 
    617     case CC_OP_SUBB:
    618     case CC_OP_SUBW:
    619     case CC_OP_SUBL:
    620         tcg_gen_mov_i32(QREG_CC_C, QREG_CC_X);
    621         tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N);
    622         /* Compute signed overflow for subtraction.  */
    623         t0 = tcg_temp_new();
    624         t1 = tcg_temp_new();
    625         tcg_gen_add_i32(t0, QREG_CC_N, QREG_CC_V);
    626         gen_ext(t0, t0, s->cc_op - CC_OP_SUBB, 1);
    627         tcg_gen_xor_i32(t1, QREG_CC_N, t0);
    628         tcg_gen_xor_i32(QREG_CC_V, QREG_CC_V, t0);
    629         tcg_temp_free(t0);
    630         tcg_gen_and_i32(QREG_CC_V, QREG_CC_V, t1);
    631         tcg_temp_free(t1);
    632         break;
    633 
    634     case CC_OP_CMPB:
    635     case CC_OP_CMPW:
    636     case CC_OP_CMPL:
    637         tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_C, QREG_CC_N, QREG_CC_V);
    638         tcg_gen_sub_i32(QREG_CC_Z, QREG_CC_N, QREG_CC_V);
    639         gen_ext(QREG_CC_Z, QREG_CC_Z, s->cc_op - CC_OP_CMPB, 1);
    640         /* Compute signed overflow for subtraction.  */
    641         t0 = tcg_temp_new();
    642         tcg_gen_xor_i32(t0, QREG_CC_Z, QREG_CC_N);
    643         tcg_gen_xor_i32(QREG_CC_V, QREG_CC_V, QREG_CC_N);
    644         tcg_gen_and_i32(QREG_CC_V, QREG_CC_V, t0);
    645         tcg_temp_free(t0);
    646         tcg_gen_mov_i32(QREG_CC_N, QREG_CC_Z);
    647         break;
    648 
    649     case CC_OP_LOGIC:
    650         tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N);
    651         tcg_gen_movi_i32(QREG_CC_C, 0);
    652         tcg_gen_movi_i32(QREG_CC_V, 0);
    653         break;
    654 
    655     case CC_OP_DYNAMIC:
    656         gen_helper_flush_flags(cpu_env, QREG_CC_OP);
    657         s->cc_op_synced = 1;
    658         break;
    659 
    660     default:
    661         t0 = tcg_const_i32(s->cc_op);
    662         gen_helper_flush_flags(cpu_env, t0);
    663         tcg_temp_free(t0);
    664         s->cc_op_synced = 1;
    665         break;
    666     }
    667 
    668     /* Note that flush_flags also assigned to env->cc_op.  */
    669     s->cc_op = CC_OP_FLAGS;
    670 }
    671 
    672 static inline TCGv gen_extend(DisasContext *s, TCGv val, int opsize, int sign)
    673 {
    674     TCGv tmp;
    675 
    676     if (opsize == OS_LONG) {
    677         tmp = val;
    678     } else {
    679         tmp = mark_to_release(s, tcg_temp_new());
    680         gen_ext(tmp, val, opsize, sign);
    681     }
    682 
    683     return tmp;
    684 }
    685 
    686 static void gen_logic_cc(DisasContext *s, TCGv val, int opsize)
    687 {
    688     gen_ext(QREG_CC_N, val, opsize, 1);
    689     set_cc_op(s, CC_OP_LOGIC);
    690 }
    691 
    692 static void gen_update_cc_cmp(DisasContext *s, TCGv dest, TCGv src, int opsize)
    693 {
    694     tcg_gen_mov_i32(QREG_CC_N, dest);
    695     tcg_gen_mov_i32(QREG_CC_V, src);
    696     set_cc_op(s, CC_OP_CMPB + opsize);
    697 }
    698 
    699 static void gen_update_cc_add(TCGv dest, TCGv src, int opsize)
    700 {
    701     gen_ext(QREG_CC_N, dest, opsize, 1);
    702     tcg_gen_mov_i32(QREG_CC_V, src);
    703 }
    704 
    705 static inline int opsize_bytes(int opsize)
    706 {
    707     switch (opsize) {
    708     case OS_BYTE: return 1;
    709     case OS_WORD: return 2;
    710     case OS_LONG: return 4;
    711     case OS_SINGLE: return 4;
    712     case OS_DOUBLE: return 8;
    713     case OS_EXTENDED: return 12;
    714     case OS_PACKED: return 12;
    715     default:
    716         g_assert_not_reached();
    717     }
    718 }
    719 
    720 static inline int insn_opsize(int insn)
    721 {
    722     switch ((insn >> 6) & 3) {
    723     case 0: return OS_BYTE;
    724     case 1: return OS_WORD;
    725     case 2: return OS_LONG;
    726     default:
    727         g_assert_not_reached();
    728     }
    729 }
    730 
    731 static inline int ext_opsize(int ext, int pos)
    732 {
    733     switch ((ext >> pos) & 7) {
    734     case 0: return OS_LONG;
    735     case 1: return OS_SINGLE;
    736     case 2: return OS_EXTENDED;
    737     case 3: return OS_PACKED;
    738     case 4: return OS_WORD;
    739     case 5: return OS_DOUBLE;
    740     case 6: return OS_BYTE;
    741     default:
    742         g_assert_not_reached();
    743     }
    744 }
    745 
    746 /*
    747  * Assign value to a register.  If the width is less than the register width
    748  * only the low part of the register is set.
    749  */
    750 static void gen_partset_reg(int opsize, TCGv reg, TCGv val)
    751 {
    752     TCGv tmp;
    753     switch (opsize) {
    754     case OS_BYTE:
    755         tcg_gen_andi_i32(reg, reg, 0xffffff00);
    756         tmp = tcg_temp_new();
    757         tcg_gen_ext8u_i32(tmp, val);
    758         tcg_gen_or_i32(reg, reg, tmp);
    759         tcg_temp_free(tmp);
    760         break;
    761     case OS_WORD:
    762         tcg_gen_andi_i32(reg, reg, 0xffff0000);
    763         tmp = tcg_temp_new();
    764         tcg_gen_ext16u_i32(tmp, val);
    765         tcg_gen_or_i32(reg, reg, tmp);
    766         tcg_temp_free(tmp);
    767         break;
    768     case OS_LONG:
    769     case OS_SINGLE:
    770         tcg_gen_mov_i32(reg, val);
    771         break;
    772     default:
    773         g_assert_not_reached();
    774     }
    775 }
    776 
    777 /*
    778  * Generate code for an "effective address".  Does not adjust the base
    779  * register for autoincrement addressing modes.
    780  */
    781 static TCGv gen_lea_mode(CPUM68KState *env, DisasContext *s,
    782                          int mode, int reg0, int opsize)
    783 {
    784     TCGv reg;
    785     TCGv tmp;
    786     uint16_t ext;
    787     uint32_t offset;
    788 
    789     switch (mode) {
    790     case 0: /* Data register direct.  */
    791     case 1: /* Address register direct.  */
    792         return NULL_QREG;
    793     case 3: /* Indirect postincrement.  */
    794         if (opsize == OS_UNSIZED) {
    795             return NULL_QREG;
    796         }
    797         /* fallthru */
    798     case 2: /* Indirect register */
    799         return get_areg(s, reg0);
    800     case 4: /* Indirect predecrememnt.  */
    801         if (opsize == OS_UNSIZED) {
    802             return NULL_QREG;
    803         }
    804         reg = get_areg(s, reg0);
    805         tmp = mark_to_release(s, tcg_temp_new());
    806         if (reg0 == 7 && opsize == OS_BYTE &&
    807             m68k_feature(s->env, M68K_FEATURE_M68K)) {
    808             tcg_gen_subi_i32(tmp, reg, 2);
    809         } else {
    810             tcg_gen_subi_i32(tmp, reg, opsize_bytes(opsize));
    811         }
    812         return tmp;
    813     case 5: /* Indirect displacement.  */
    814         reg = get_areg(s, reg0);
    815         tmp = mark_to_release(s, tcg_temp_new());
    816         ext = read_im16(env, s);
    817         tcg_gen_addi_i32(tmp, reg, (int16_t)ext);
    818         return tmp;
    819     case 6: /* Indirect index + displacement.  */
    820         reg = get_areg(s, reg0);
    821         return gen_lea_indexed(env, s, reg);
    822     case 7: /* Other */
    823         switch (reg0) {
    824         case 0: /* Absolute short.  */
    825             offset = (int16_t)read_im16(env, s);
    826             return mark_to_release(s, tcg_const_i32(offset));
    827         case 1: /* Absolute long.  */
    828             offset = read_im32(env, s);
    829             return mark_to_release(s, tcg_const_i32(offset));
    830         case 2: /* pc displacement  */
    831             offset = s->pc;
    832             offset += (int16_t)read_im16(env, s);
    833             return mark_to_release(s, tcg_const_i32(offset));
    834         case 3: /* pc index+displacement.  */
    835             return gen_lea_indexed(env, s, NULL_QREG);
    836         case 4: /* Immediate.  */
    837         default:
    838             return NULL_QREG;
    839         }
    840     }
    841     /* Should never happen.  */
    842     return NULL_QREG;
    843 }
    844 
    845 static TCGv gen_lea(CPUM68KState *env, DisasContext *s, uint16_t insn,
    846                     int opsize)
    847 {
    848     int mode = extract32(insn, 3, 3);
    849     int reg0 = REG(insn, 0);
    850     return gen_lea_mode(env, s, mode, reg0, opsize);
    851 }
    852 
    853 /*
    854  * Generate code to load/store a value from/into an EA.  If WHAT > 0 this is
    855  * a write otherwise it is a read (0 == sign extend, -1 == zero extend).
    856  * ADDRP is non-null for readwrite operands.
    857  */
    858 static TCGv gen_ea_mode(CPUM68KState *env, DisasContext *s, int mode, int reg0,
    859                         int opsize, TCGv val, TCGv *addrp, ea_what what,
    860                         int index)
    861 {
    862     TCGv reg, tmp, result;
    863     int32_t offset;
    864 
    865     switch (mode) {
    866     case 0: /* Data register direct.  */
    867         reg = cpu_dregs[reg0];
    868         if (what == EA_STORE) {
    869             gen_partset_reg(opsize, reg, val);
    870             return store_dummy;
    871         } else {
    872             return gen_extend(s, reg, opsize, what == EA_LOADS);
    873         }
    874     case 1: /* Address register direct.  */
    875         reg = get_areg(s, reg0);
    876         if (what == EA_STORE) {
    877             tcg_gen_mov_i32(reg, val);
    878             return store_dummy;
    879         } else {
    880             return gen_extend(s, reg, opsize, what == EA_LOADS);
    881         }
    882     case 2: /* Indirect register */
    883         reg = get_areg(s, reg0);
    884         return gen_ldst(s, opsize, reg, val, what, index);
    885     case 3: /* Indirect postincrement.  */
    886         reg = get_areg(s, reg0);
    887         result = gen_ldst(s, opsize, reg, val, what, index);
    888         if (what == EA_STORE || !addrp) {
    889             TCGv tmp = tcg_temp_new();
    890             if (reg0 == 7 && opsize == OS_BYTE &&
    891                 m68k_feature(s->env, M68K_FEATURE_M68K)) {
    892                 tcg_gen_addi_i32(tmp, reg, 2);
    893             } else {
    894                 tcg_gen_addi_i32(tmp, reg, opsize_bytes(opsize));
    895             }
    896             delay_set_areg(s, reg0, tmp, true);
    897         }
    898         return result;
    899     case 4: /* Indirect predecrememnt.  */
    900         if (addrp && what == EA_STORE) {
    901             tmp = *addrp;
    902         } else {
    903             tmp = gen_lea_mode(env, s, mode, reg0, opsize);
    904             if (IS_NULL_QREG(tmp)) {
    905                 return tmp;
    906             }
    907             if (addrp) {
    908                 *addrp = tmp;
    909             }
    910         }
    911         result = gen_ldst(s, opsize, tmp, val, what, index);
    912         if (what == EA_STORE || !addrp) {
    913             delay_set_areg(s, reg0, tmp, false);
    914         }
    915         return result;
    916     case 5: /* Indirect displacement.  */
    917     case 6: /* Indirect index + displacement.  */
    918     do_indirect:
    919         if (addrp && what == EA_STORE) {
    920             tmp = *addrp;
    921         } else {
    922             tmp = gen_lea_mode(env, s, mode, reg0, opsize);
    923             if (IS_NULL_QREG(tmp)) {
    924                 return tmp;
    925             }
    926             if (addrp) {
    927                 *addrp = tmp;
    928             }
    929         }
    930         return gen_ldst(s, opsize, tmp, val, what, index);
    931     case 7: /* Other */
    932         switch (reg0) {
    933         case 0: /* Absolute short.  */
    934         case 1: /* Absolute long.  */
    935         case 2: /* pc displacement  */
    936         case 3: /* pc index+displacement.  */
    937             goto do_indirect;
    938         case 4: /* Immediate.  */
    939             /* Sign extend values for consistency.  */
    940             switch (opsize) {
    941             case OS_BYTE:
    942                 if (what == EA_LOADS) {
    943                     offset = (int8_t)read_im8(env, s);
    944                 } else {
    945                     offset = read_im8(env, s);
    946                 }
    947                 break;
    948             case OS_WORD:
    949                 if (what == EA_LOADS) {
    950                     offset = (int16_t)read_im16(env, s);
    951                 } else {
    952                     offset = read_im16(env, s);
    953                 }
    954                 break;
    955             case OS_LONG:
    956                 offset = read_im32(env, s);
    957                 break;
    958             default:
    959                 g_assert_not_reached();
    960             }
    961             return mark_to_release(s, tcg_const_i32(offset));
    962         default:
    963             return NULL_QREG;
    964         }
    965     }
    966     /* Should never happen.  */
    967     return NULL_QREG;
    968 }
    969 
    970 static TCGv gen_ea(CPUM68KState *env, DisasContext *s, uint16_t insn,
    971                    int opsize, TCGv val, TCGv *addrp, ea_what what, int index)
    972 {
    973     int mode = extract32(insn, 3, 3);
    974     int reg0 = REG(insn, 0);
    975     return gen_ea_mode(env, s, mode, reg0, opsize, val, addrp, what, index);
    976 }
    977 
    978 static TCGv_ptr gen_fp_ptr(int freg)
    979 {
    980     TCGv_ptr fp = tcg_temp_new_ptr();
    981     tcg_gen_addi_ptr(fp, cpu_env, offsetof(CPUM68KState, fregs[freg]));
    982     return fp;
    983 }
    984 
    985 static TCGv_ptr gen_fp_result_ptr(void)
    986 {
    987     TCGv_ptr fp = tcg_temp_new_ptr();
    988     tcg_gen_addi_ptr(fp, cpu_env, offsetof(CPUM68KState, fp_result));
    989     return fp;
    990 }
    991 
    992 static void gen_fp_move(TCGv_ptr dest, TCGv_ptr src)
    993 {
    994     TCGv t32;
    995     TCGv_i64 t64;
    996 
    997     t32 = tcg_temp_new();
    998     tcg_gen_ld16u_i32(t32, src, offsetof(FPReg, l.upper));
    999     tcg_gen_st16_i32(t32, dest, offsetof(FPReg, l.upper));
   1000     tcg_temp_free(t32);
   1001 
   1002     t64 = tcg_temp_new_i64();
   1003     tcg_gen_ld_i64(t64, src, offsetof(FPReg, l.lower));
   1004     tcg_gen_st_i64(t64, dest, offsetof(FPReg, l.lower));
   1005     tcg_temp_free_i64(t64);
   1006 }
   1007 
   1008 static void gen_load_fp(DisasContext *s, int opsize, TCGv addr, TCGv_ptr fp,
   1009                         int index)
   1010 {
   1011     TCGv tmp;
   1012     TCGv_i64 t64;
   1013 
   1014     t64 = tcg_temp_new_i64();
   1015     tmp = tcg_temp_new();
   1016     switch (opsize) {
   1017     case OS_BYTE:
   1018         tcg_gen_qemu_ld8s(tmp, addr, index);
   1019         gen_helper_exts32(cpu_env, fp, tmp);
   1020         break;
   1021     case OS_WORD:
   1022         tcg_gen_qemu_ld16s(tmp, addr, index);
   1023         gen_helper_exts32(cpu_env, fp, tmp);
   1024         break;
   1025     case OS_LONG:
   1026         tcg_gen_qemu_ld32u(tmp, addr, index);
   1027         gen_helper_exts32(cpu_env, fp, tmp);
   1028         break;
   1029     case OS_SINGLE:
   1030         tcg_gen_qemu_ld32u(tmp, addr, index);
   1031         gen_helper_extf32(cpu_env, fp, tmp);
   1032         break;
   1033     case OS_DOUBLE:
   1034         tcg_gen_qemu_ld64(t64, addr, index);
   1035         gen_helper_extf64(cpu_env, fp, t64);
   1036         break;
   1037     case OS_EXTENDED:
   1038         if (m68k_feature(s->env, M68K_FEATURE_CF_FPU)) {
   1039             gen_exception(s, s->base.pc_next, EXCP_FP_UNIMP);
   1040             break;
   1041         }
   1042         tcg_gen_qemu_ld32u(tmp, addr, index);
   1043         tcg_gen_shri_i32(tmp, tmp, 16);
   1044         tcg_gen_st16_i32(tmp, fp, offsetof(FPReg, l.upper));
   1045         tcg_gen_addi_i32(tmp, addr, 4);
   1046         tcg_gen_qemu_ld64(t64, tmp, index);
   1047         tcg_gen_st_i64(t64, fp, offsetof(FPReg, l.lower));
   1048         break;
   1049     case OS_PACKED:
   1050         /*
   1051          * unimplemented data type on 68040/ColdFire
   1052          * FIXME if needed for another FPU
   1053          */
   1054         gen_exception(s, s->base.pc_next, EXCP_FP_UNIMP);
   1055         break;
   1056     default:
   1057         g_assert_not_reached();
   1058     }
   1059     tcg_temp_free(tmp);
   1060     tcg_temp_free_i64(t64);
   1061 }
   1062 
   1063 static void gen_store_fp(DisasContext *s, int opsize, TCGv addr, TCGv_ptr fp,
   1064                          int index)
   1065 {
   1066     TCGv tmp;
   1067     TCGv_i64 t64;
   1068 
   1069     t64 = tcg_temp_new_i64();
   1070     tmp = tcg_temp_new();
   1071     switch (opsize) {
   1072     case OS_BYTE:
   1073         gen_helper_reds32(tmp, cpu_env, fp);
   1074         tcg_gen_qemu_st8(tmp, addr, index);
   1075         break;
   1076     case OS_WORD:
   1077         gen_helper_reds32(tmp, cpu_env, fp);
   1078         tcg_gen_qemu_st16(tmp, addr, index);
   1079         break;
   1080     case OS_LONG:
   1081         gen_helper_reds32(tmp, cpu_env, fp);
   1082         tcg_gen_qemu_st32(tmp, addr, index);
   1083         break;
   1084     case OS_SINGLE:
   1085         gen_helper_redf32(tmp, cpu_env, fp);
   1086         tcg_gen_qemu_st32(tmp, addr, index);
   1087         break;
   1088     case OS_DOUBLE:
   1089         gen_helper_redf64(t64, cpu_env, fp);
   1090         tcg_gen_qemu_st64(t64, addr, index);
   1091         break;
   1092     case OS_EXTENDED:
   1093         if (m68k_feature(s->env, M68K_FEATURE_CF_FPU)) {
   1094             gen_exception(s, s->base.pc_next, EXCP_FP_UNIMP);
   1095             break;
   1096         }
   1097         tcg_gen_ld16u_i32(tmp, fp, offsetof(FPReg, l.upper));
   1098         tcg_gen_shli_i32(tmp, tmp, 16);
   1099         tcg_gen_qemu_st32(tmp, addr, index);
   1100         tcg_gen_addi_i32(tmp, addr, 4);
   1101         tcg_gen_ld_i64(t64, fp, offsetof(FPReg, l.lower));
   1102         tcg_gen_qemu_st64(t64, tmp, index);
   1103         break;
   1104     case OS_PACKED:
   1105         /*
   1106          * unimplemented data type on 68040/ColdFire
   1107          * FIXME if needed for another FPU
   1108          */
   1109         gen_exception(s, s->base.pc_next, EXCP_FP_UNIMP);
   1110         break;
   1111     default:
   1112         g_assert_not_reached();
   1113     }
   1114     tcg_temp_free(tmp);
   1115     tcg_temp_free_i64(t64);
   1116 }
   1117 
   1118 static void gen_ldst_fp(DisasContext *s, int opsize, TCGv addr,
   1119                         TCGv_ptr fp, ea_what what, int index)
   1120 {
   1121     if (what == EA_STORE) {
   1122         gen_store_fp(s, opsize, addr, fp, index);
   1123     } else {
   1124         gen_load_fp(s, opsize, addr, fp, index);
   1125     }
   1126 }
   1127 
   1128 static int gen_ea_mode_fp(CPUM68KState *env, DisasContext *s, int mode,
   1129                           int reg0, int opsize, TCGv_ptr fp, ea_what what,
   1130                           int index)
   1131 {
   1132     TCGv reg, addr, tmp;
   1133     TCGv_i64 t64;
   1134 
   1135     switch (mode) {
   1136     case 0: /* Data register direct.  */
   1137         reg = cpu_dregs[reg0];
   1138         if (what == EA_STORE) {
   1139             switch (opsize) {
   1140             case OS_BYTE:
   1141             case OS_WORD:
   1142             case OS_LONG:
   1143                 gen_helper_reds32(reg, cpu_env, fp);
   1144                 break;
   1145             case OS_SINGLE:
   1146                 gen_helper_redf32(reg, cpu_env, fp);
   1147                 break;
   1148             default:
   1149                 g_assert_not_reached();
   1150             }
   1151         } else {
   1152             tmp = tcg_temp_new();
   1153             switch (opsize) {
   1154             case OS_BYTE:
   1155                 tcg_gen_ext8s_i32(tmp, reg);
   1156                 gen_helper_exts32(cpu_env, fp, tmp);
   1157                 break;
   1158             case OS_WORD:
   1159                 tcg_gen_ext16s_i32(tmp, reg);
   1160                 gen_helper_exts32(cpu_env, fp, tmp);
   1161                 break;
   1162             case OS_LONG:
   1163                 gen_helper_exts32(cpu_env, fp, reg);
   1164                 break;
   1165             case OS_SINGLE:
   1166                 gen_helper_extf32(cpu_env, fp, reg);
   1167                 break;
   1168             default:
   1169                 g_assert_not_reached();
   1170             }
   1171             tcg_temp_free(tmp);
   1172         }
   1173         return 0;
   1174     case 1: /* Address register direct.  */
   1175         return -1;
   1176     case 2: /* Indirect register */
   1177         addr = get_areg(s, reg0);
   1178         gen_ldst_fp(s, opsize, addr, fp, what, index);
   1179         return 0;
   1180     case 3: /* Indirect postincrement.  */
   1181         addr = cpu_aregs[reg0];
   1182         gen_ldst_fp(s, opsize, addr, fp, what, index);
   1183         tcg_gen_addi_i32(addr, addr, opsize_bytes(opsize));
   1184         return 0;
   1185     case 4: /* Indirect predecrememnt.  */
   1186         addr = gen_lea_mode(env, s, mode, reg0, opsize);
   1187         if (IS_NULL_QREG(addr)) {
   1188             return -1;
   1189         }
   1190         gen_ldst_fp(s, opsize, addr, fp, what, index);
   1191         tcg_gen_mov_i32(cpu_aregs[reg0], addr);
   1192         return 0;
   1193     case 5: /* Indirect displacement.  */
   1194     case 6: /* Indirect index + displacement.  */
   1195     do_indirect:
   1196         addr = gen_lea_mode(env, s, mode, reg0, opsize);
   1197         if (IS_NULL_QREG(addr)) {
   1198             return -1;
   1199         }
   1200         gen_ldst_fp(s, opsize, addr, fp, what, index);
   1201         return 0;
   1202     case 7: /* Other */
   1203         switch (reg0) {
   1204         case 0: /* Absolute short.  */
   1205         case 1: /* Absolute long.  */
   1206         case 2: /* pc displacement  */
   1207         case 3: /* pc index+displacement.  */
   1208             goto do_indirect;
   1209         case 4: /* Immediate.  */
   1210             if (what == EA_STORE) {
   1211                 return -1;
   1212             }
   1213             switch (opsize) {
   1214             case OS_BYTE:
   1215                 tmp = tcg_const_i32((int8_t)read_im8(env, s));
   1216                 gen_helper_exts32(cpu_env, fp, tmp);
   1217                 tcg_temp_free(tmp);
   1218                 break;
   1219             case OS_WORD:
   1220                 tmp = tcg_const_i32((int16_t)read_im16(env, s));
   1221                 gen_helper_exts32(cpu_env, fp, tmp);
   1222                 tcg_temp_free(tmp);
   1223                 break;
   1224             case OS_LONG:
   1225                 tmp = tcg_const_i32(read_im32(env, s));
   1226                 gen_helper_exts32(cpu_env, fp, tmp);
   1227                 tcg_temp_free(tmp);
   1228                 break;
   1229             case OS_SINGLE:
   1230                 tmp = tcg_const_i32(read_im32(env, s));
   1231                 gen_helper_extf32(cpu_env, fp, tmp);
   1232                 tcg_temp_free(tmp);
   1233                 break;
   1234             case OS_DOUBLE:
   1235                 t64 = tcg_const_i64(read_im64(env, s));
   1236                 gen_helper_extf64(cpu_env, fp, t64);
   1237                 tcg_temp_free_i64(t64);
   1238                 break;
   1239             case OS_EXTENDED:
   1240                 if (m68k_feature(s->env, M68K_FEATURE_CF_FPU)) {
   1241                     gen_exception(s, s->base.pc_next, EXCP_FP_UNIMP);
   1242                     break;
   1243                 }
   1244                 tmp = tcg_const_i32(read_im32(env, s) >> 16);
   1245                 tcg_gen_st16_i32(tmp, fp, offsetof(FPReg, l.upper));
   1246                 tcg_temp_free(tmp);
   1247                 t64 = tcg_const_i64(read_im64(env, s));
   1248                 tcg_gen_st_i64(t64, fp, offsetof(FPReg, l.lower));
   1249                 tcg_temp_free_i64(t64);
   1250                 break;
   1251             case OS_PACKED:
   1252                 /*
   1253                  * unimplemented data type on 68040/ColdFire
   1254                  * FIXME if needed for another FPU
   1255                  */
   1256                 gen_exception(s, s->base.pc_next, EXCP_FP_UNIMP);
   1257                 break;
   1258             default:
   1259                 g_assert_not_reached();
   1260             }
   1261             return 0;
   1262         default:
   1263             return -1;
   1264         }
   1265     }
   1266     return -1;
   1267 }
   1268 
   1269 static int gen_ea_fp(CPUM68KState *env, DisasContext *s, uint16_t insn,
   1270                        int opsize, TCGv_ptr fp, ea_what what, int index)
   1271 {
   1272     int mode = extract32(insn, 3, 3);
   1273     int reg0 = REG(insn, 0);
   1274     return gen_ea_mode_fp(env, s, mode, reg0, opsize, fp, what, index);
   1275 }
   1276 
   1277 typedef struct {
   1278     TCGCond tcond;
   1279     bool g1;
   1280     bool g2;
   1281     TCGv v1;
   1282     TCGv v2;
   1283 } DisasCompare;
   1284 
   1285 static void gen_cc_cond(DisasCompare *c, DisasContext *s, int cond)
   1286 {
   1287     TCGv tmp, tmp2;
   1288     TCGCond tcond;
   1289     CCOp op = s->cc_op;
   1290 
   1291     /* The CC_OP_CMP form can handle most normal comparisons directly.  */
   1292     if (op == CC_OP_CMPB || op == CC_OP_CMPW || op == CC_OP_CMPL) {
   1293         c->g1 = c->g2 = 1;
   1294         c->v1 = QREG_CC_N;
   1295         c->v2 = QREG_CC_V;
   1296         switch (cond) {
   1297         case 2: /* HI */
   1298         case 3: /* LS */
   1299             tcond = TCG_COND_LEU;
   1300             goto done;
   1301         case 4: /* CC */
   1302         case 5: /* CS */
   1303             tcond = TCG_COND_LTU;
   1304             goto done;
   1305         case 6: /* NE */
   1306         case 7: /* EQ */
   1307             tcond = TCG_COND_EQ;
   1308             goto done;
   1309         case 10: /* PL */
   1310         case 11: /* MI */
   1311             c->g1 = c->g2 = 0;
   1312             c->v2 = tcg_const_i32(0);
   1313             c->v1 = tmp = tcg_temp_new();
   1314             tcg_gen_sub_i32(tmp, QREG_CC_N, QREG_CC_V);
   1315             gen_ext(tmp, tmp, op - CC_OP_CMPB, 1);
   1316             /* fallthru */
   1317         case 12: /* GE */
   1318         case 13: /* LT */
   1319             tcond = TCG_COND_LT;
   1320             goto done;
   1321         case 14: /* GT */
   1322         case 15: /* LE */
   1323             tcond = TCG_COND_LE;
   1324             goto done;
   1325         }
   1326     }
   1327 
   1328     c->g1 = 1;
   1329     c->g2 = 0;
   1330     c->v2 = tcg_const_i32(0);
   1331 
   1332     switch (cond) {
   1333     case 0: /* T */
   1334     case 1: /* F */
   1335         c->v1 = c->v2;
   1336         tcond = TCG_COND_NEVER;
   1337         goto done;
   1338     case 14: /* GT (!(Z || (N ^ V))) */
   1339     case 15: /* LE (Z || (N ^ V)) */
   1340         /*
   1341          * Logic operations clear V, which simplifies LE to (Z || N),
   1342          * and since Z and N are co-located, this becomes a normal
   1343          * comparison vs N.
   1344          */
   1345         if (op == CC_OP_LOGIC) {
   1346             c->v1 = QREG_CC_N;
   1347             tcond = TCG_COND_LE;
   1348             goto done;
   1349         }
   1350         break;
   1351     case 12: /* GE (!(N ^ V)) */
   1352     case 13: /* LT (N ^ V) */
   1353         /* Logic operations clear V, which simplifies this to N.  */
   1354         if (op != CC_OP_LOGIC) {
   1355             break;
   1356         }
   1357         /* fallthru */
   1358     case 10: /* PL (!N) */
   1359     case 11: /* MI (N) */
   1360         /* Several cases represent N normally.  */
   1361         if (op == CC_OP_ADDB || op == CC_OP_ADDW || op == CC_OP_ADDL ||
   1362             op == CC_OP_SUBB || op == CC_OP_SUBW || op == CC_OP_SUBL ||
   1363             op == CC_OP_LOGIC) {
   1364             c->v1 = QREG_CC_N;
   1365             tcond = TCG_COND_LT;
   1366             goto done;
   1367         }
   1368         break;
   1369     case 6: /* NE (!Z) */
   1370     case 7: /* EQ (Z) */
   1371         /* Some cases fold Z into N.  */
   1372         if (op == CC_OP_ADDB || op == CC_OP_ADDW || op == CC_OP_ADDL ||
   1373             op == CC_OP_SUBB || op == CC_OP_SUBW || op == CC_OP_SUBL ||
   1374             op == CC_OP_LOGIC) {
   1375             tcond = TCG_COND_EQ;
   1376             c->v1 = QREG_CC_N;
   1377             goto done;
   1378         }
   1379         break;
   1380     case 4: /* CC (!C) */
   1381     case 5: /* CS (C) */
   1382         /* Some cases fold C into X.  */
   1383         if (op == CC_OP_ADDB || op == CC_OP_ADDW || op == CC_OP_ADDL ||
   1384             op == CC_OP_SUBB || op == CC_OP_SUBW || op == CC_OP_SUBL) {
   1385             tcond = TCG_COND_NE;
   1386             c->v1 = QREG_CC_X;
   1387             goto done;
   1388         }
   1389         /* fallthru */
   1390     case 8: /* VC (!V) */
   1391     case 9: /* VS (V) */
   1392         /* Logic operations clear V and C.  */
   1393         if (op == CC_OP_LOGIC) {
   1394             tcond = TCG_COND_NEVER;
   1395             c->v1 = c->v2;
   1396             goto done;
   1397         }
   1398         break;
   1399     }
   1400 
   1401     /* Otherwise, flush flag state to CC_OP_FLAGS.  */
   1402     gen_flush_flags(s);
   1403 
   1404     switch (cond) {
   1405     case 0: /* T */
   1406     case 1: /* F */
   1407     default:
   1408         /* Invalid, or handled above.  */
   1409         abort();
   1410     case 2: /* HI (!C && !Z) -> !(C || Z)*/
   1411     case 3: /* LS (C || Z) */
   1412         c->v1 = tmp = tcg_temp_new();
   1413         c->g1 = 0;
   1414         tcg_gen_setcond_i32(TCG_COND_EQ, tmp, QREG_CC_Z, c->v2);
   1415         tcg_gen_or_i32(tmp, tmp, QREG_CC_C);
   1416         tcond = TCG_COND_NE;
   1417         break;
   1418     case 4: /* CC (!C) */
   1419     case 5: /* CS (C) */
   1420         c->v1 = QREG_CC_C;
   1421         tcond = TCG_COND_NE;
   1422         break;
   1423     case 6: /* NE (!Z) */
   1424     case 7: /* EQ (Z) */
   1425         c->v1 = QREG_CC_Z;
   1426         tcond = TCG_COND_EQ;
   1427         break;
   1428     case 8: /* VC (!V) */
   1429     case 9: /* VS (V) */
   1430         c->v1 = QREG_CC_V;
   1431         tcond = TCG_COND_LT;
   1432         break;
   1433     case 10: /* PL (!N) */
   1434     case 11: /* MI (N) */
   1435         c->v1 = QREG_CC_N;
   1436         tcond = TCG_COND_LT;
   1437         break;
   1438     case 12: /* GE (!(N ^ V)) */
   1439     case 13: /* LT (N ^ V) */
   1440         c->v1 = tmp = tcg_temp_new();
   1441         c->g1 = 0;
   1442         tcg_gen_xor_i32(tmp, QREG_CC_N, QREG_CC_V);
   1443         tcond = TCG_COND_LT;
   1444         break;
   1445     case 14: /* GT (!(Z || (N ^ V))) */
   1446     case 15: /* LE (Z || (N ^ V)) */
   1447         c->v1 = tmp = tcg_temp_new();
   1448         c->g1 = 0;
   1449         tcg_gen_setcond_i32(TCG_COND_EQ, tmp, QREG_CC_Z, c->v2);
   1450         tcg_gen_neg_i32(tmp, tmp);
   1451         tmp2 = tcg_temp_new();
   1452         tcg_gen_xor_i32(tmp2, QREG_CC_N, QREG_CC_V);
   1453         tcg_gen_or_i32(tmp, tmp, tmp2);
   1454         tcg_temp_free(tmp2);
   1455         tcond = TCG_COND_LT;
   1456         break;
   1457     }
   1458 
   1459  done:
   1460     if ((cond & 1) == 0) {
   1461         tcond = tcg_invert_cond(tcond);
   1462     }
   1463     c->tcond = tcond;
   1464 }
   1465 
   1466 static void free_cond(DisasCompare *c)
   1467 {
   1468     if (!c->g1) {
   1469         tcg_temp_free(c->v1);
   1470     }
   1471     if (!c->g2) {
   1472         tcg_temp_free(c->v2);
   1473     }
   1474 }
   1475 
   1476 static void gen_jmpcc(DisasContext *s, int cond, TCGLabel *l1)
   1477 {
   1478   DisasCompare c;
   1479 
   1480   gen_cc_cond(&c, s, cond);
   1481   update_cc_op(s);
   1482   tcg_gen_brcond_i32(c.tcond, c.v1, c.v2, l1);
   1483   free_cond(&c);
   1484 }
   1485 
   1486 /* Force a TB lookup after an instruction that changes the CPU state.  */
   1487 static void gen_exit_tb(DisasContext *s)
   1488 {
   1489     update_cc_op(s);
   1490     tcg_gen_movi_i32(QREG_PC, s->pc);
   1491     s->base.is_jmp = DISAS_EXIT;
   1492 }
   1493 
   1494 #define SRC_EA(env, result, opsize, op_sign, addrp) do {                \
   1495         result = gen_ea(env, s, insn, opsize, NULL_QREG, addrp,         \
   1496                         op_sign ? EA_LOADS : EA_LOADU, IS_USER(s));     \
   1497         if (IS_NULL_QREG(result)) {                                     \
   1498             gen_addr_fault(s);                                          \
   1499             return;                                                     \
   1500         }                                                               \
   1501     } while (0)
   1502 
   1503 #define DEST_EA(env, insn, opsize, val, addrp) do {                     \
   1504         TCGv ea_result = gen_ea(env, s, insn, opsize, val, addrp,       \
   1505                                 EA_STORE, IS_USER(s));                  \
   1506         if (IS_NULL_QREG(ea_result)) {                                  \
   1507             gen_addr_fault(s);                                          \
   1508             return;                                                     \
   1509         }                                                               \
   1510     } while (0)
   1511 
   1512 /* Generate a jump to an immediate address.  */
   1513 static void gen_jmp_tb(DisasContext *s, int n, target_ulong dest,
   1514                        target_ulong src)
   1515 {
   1516     if (unlikely(s->ss_active)) {
   1517         update_cc_op(s);
   1518         tcg_gen_movi_i32(QREG_PC, dest);
   1519         gen_raise_exception_format2(s, EXCP_TRACE, src);
   1520     } else if (translator_use_goto_tb(&s->base, dest)) {
   1521         tcg_gen_goto_tb(n);
   1522         tcg_gen_movi_i32(QREG_PC, dest);
   1523         tcg_gen_exit_tb(s->base.tb, n);
   1524     } else {
   1525         gen_jmp_im(s, dest);
   1526         tcg_gen_exit_tb(NULL, 0);
   1527     }
   1528     s->base.is_jmp = DISAS_NORETURN;
   1529 }
   1530 
   1531 DISAS_INSN(scc)
   1532 {
   1533     DisasCompare c;
   1534     int cond;
   1535     TCGv tmp;
   1536 
   1537     cond = (insn >> 8) & 0xf;
   1538     gen_cc_cond(&c, s, cond);
   1539 
   1540     tmp = tcg_temp_new();
   1541     tcg_gen_setcond_i32(c.tcond, tmp, c.v1, c.v2);
   1542     free_cond(&c);
   1543 
   1544     tcg_gen_neg_i32(tmp, tmp);
   1545     DEST_EA(env, insn, OS_BYTE, tmp, NULL);
   1546     tcg_temp_free(tmp);
   1547 }
   1548 
   1549 DISAS_INSN(dbcc)
   1550 {
   1551     TCGLabel *l1;
   1552     TCGv reg;
   1553     TCGv tmp;
   1554     int16_t offset;
   1555     uint32_t base;
   1556 
   1557     reg = DREG(insn, 0);
   1558     base = s->pc;
   1559     offset = (int16_t)read_im16(env, s);
   1560     l1 = gen_new_label();
   1561     gen_jmpcc(s, (insn >> 8) & 0xf, l1);
   1562 
   1563     tmp = tcg_temp_new();
   1564     tcg_gen_ext16s_i32(tmp, reg);
   1565     tcg_gen_addi_i32(tmp, tmp, -1);
   1566     gen_partset_reg(OS_WORD, reg, tmp);
   1567     tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, -1, l1);
   1568     gen_jmp_tb(s, 1, base + offset, s->base.pc_next);
   1569     gen_set_label(l1);
   1570     gen_jmp_tb(s, 0, s->pc, s->base.pc_next);
   1571 }
   1572 
   1573 DISAS_INSN(undef_mac)
   1574 {
   1575     gen_exception(s, s->base.pc_next, EXCP_LINEA);
   1576 }
   1577 
   1578 DISAS_INSN(undef_fpu)
   1579 {
   1580     gen_exception(s, s->base.pc_next, EXCP_LINEF);
   1581 }
   1582 
   1583 DISAS_INSN(undef)
   1584 {
   1585     /*
   1586      * ??? This is both instructions that are as yet unimplemented
   1587      * for the 680x0 series, as well as those that are implemented
   1588      * but actually illegal for CPU32 or pre-68020.
   1589      */
   1590     qemu_log_mask(LOG_UNIMP, "Illegal instruction: %04x @ %08x\n",
   1591                   insn, s->base.pc_next);
   1592     gen_exception(s, s->base.pc_next, EXCP_ILLEGAL);
   1593 }
   1594 
   1595 DISAS_INSN(mulw)
   1596 {
   1597     TCGv reg;
   1598     TCGv tmp;
   1599     TCGv src;
   1600     int sign;
   1601 
   1602     sign = (insn & 0x100) != 0;
   1603     reg = DREG(insn, 9);
   1604     tmp = tcg_temp_new();
   1605     if (sign)
   1606         tcg_gen_ext16s_i32(tmp, reg);
   1607     else
   1608         tcg_gen_ext16u_i32(tmp, reg);
   1609     SRC_EA(env, src, OS_WORD, sign, NULL);
   1610     tcg_gen_mul_i32(tmp, tmp, src);
   1611     tcg_gen_mov_i32(reg, tmp);
   1612     gen_logic_cc(s, tmp, OS_LONG);
   1613     tcg_temp_free(tmp);
   1614 }
   1615 
   1616 DISAS_INSN(divw)
   1617 {
   1618     int sign;
   1619     TCGv src;
   1620     TCGv destr;
   1621     TCGv ilen;
   1622 
   1623     /* divX.w <EA>,Dn    32/16 -> 16r:16q */
   1624 
   1625     sign = (insn & 0x100) != 0;
   1626 
   1627     /* dest.l / src.w */
   1628 
   1629     SRC_EA(env, src, OS_WORD, sign, NULL);
   1630     destr = tcg_constant_i32(REG(insn, 9));
   1631     ilen = tcg_constant_i32(s->pc - s->base.pc_next);
   1632     if (sign) {
   1633         gen_helper_divsw(cpu_env, destr, src, ilen);
   1634     } else {
   1635         gen_helper_divuw(cpu_env, destr, src, ilen);
   1636     }
   1637 
   1638     set_cc_op(s, CC_OP_FLAGS);
   1639 }
   1640 
   1641 DISAS_INSN(divl)
   1642 {
   1643     TCGv num, reg, den, ilen;
   1644     int sign;
   1645     uint16_t ext;
   1646 
   1647     ext = read_im16(env, s);
   1648 
   1649     sign = (ext & 0x0800) != 0;
   1650 
   1651     if (ext & 0x400) {
   1652         if (!m68k_feature(s->env, M68K_FEATURE_QUAD_MULDIV)) {
   1653             gen_exception(s, s->base.pc_next, EXCP_ILLEGAL);
   1654             return;
   1655         }
   1656 
   1657         /* divX.l <EA>, Dr:Dq    64/32 -> 32r:32q */
   1658 
   1659         SRC_EA(env, den, OS_LONG, 0, NULL);
   1660         num = tcg_constant_i32(REG(ext, 12));
   1661         reg = tcg_constant_i32(REG(ext, 0));
   1662         ilen = tcg_constant_i32(s->pc - s->base.pc_next);
   1663         if (sign) {
   1664             gen_helper_divsll(cpu_env, num, reg, den, ilen);
   1665         } else {
   1666             gen_helper_divull(cpu_env, num, reg, den, ilen);
   1667         }
   1668         set_cc_op(s, CC_OP_FLAGS);
   1669         return;
   1670     }
   1671 
   1672     /* divX.l <EA>, Dq        32/32 -> 32q     */
   1673     /* divXl.l <EA>, Dr:Dq    32/32 -> 32r:32q */
   1674 
   1675     SRC_EA(env, den, OS_LONG, 0, NULL);
   1676     num = tcg_constant_i32(REG(ext, 12));
   1677     reg = tcg_constant_i32(REG(ext, 0));
   1678     ilen = tcg_constant_i32(s->pc - s->base.pc_next);
   1679     if (sign) {
   1680         gen_helper_divsl(cpu_env, num, reg, den, ilen);
   1681     } else {
   1682         gen_helper_divul(cpu_env, num, reg, den, ilen);
   1683     }
   1684 
   1685     set_cc_op(s, CC_OP_FLAGS);
   1686 }
   1687 
   1688 static void bcd_add(TCGv dest, TCGv src)
   1689 {
   1690     TCGv t0, t1;
   1691 
   1692     /*
   1693      * dest10 = dest10 + src10 + X
   1694      *
   1695      *        t1 = src
   1696      *        t2 = t1 + 0x066
   1697      *        t3 = t2 + dest + X
   1698      *        t4 = t2 ^ dest
   1699      *        t5 = t3 ^ t4
   1700      *        t6 = ~t5 & 0x110
   1701      *        t7 = (t6 >> 2) | (t6 >> 3)
   1702      *        return t3 - t7
   1703      */
   1704 
   1705     /*
   1706      * t1 = (src + 0x066) + dest + X
   1707      *    = result with some possible exceeding 0x6
   1708      */
   1709 
   1710     t0 = tcg_const_i32(0x066);
   1711     tcg_gen_add_i32(t0, t0, src);
   1712 
   1713     t1 = tcg_temp_new();
   1714     tcg_gen_add_i32(t1, t0, dest);
   1715     tcg_gen_add_i32(t1, t1, QREG_CC_X);
   1716 
   1717     /* we will remove exceeding 0x6 where there is no carry */
   1718 
   1719     /*
   1720      * t0 = (src + 0x0066) ^ dest
   1721      *    = t1 without carries
   1722      */
   1723 
   1724     tcg_gen_xor_i32(t0, t0, dest);
   1725 
   1726     /*
   1727      * extract the carries
   1728      * t0 = t0 ^ t1
   1729      *    = only the carries
   1730      */
   1731 
   1732     tcg_gen_xor_i32(t0, t0, t1);
   1733 
   1734     /*
   1735      * generate 0x1 where there is no carry
   1736      * and for each 0x10, generate a 0x6
   1737      */
   1738 
   1739     tcg_gen_shri_i32(t0, t0, 3);
   1740     tcg_gen_not_i32(t0, t0);
   1741     tcg_gen_andi_i32(t0, t0, 0x22);
   1742     tcg_gen_add_i32(dest, t0, t0);
   1743     tcg_gen_add_i32(dest, dest, t0);
   1744     tcg_temp_free(t0);
   1745 
   1746     /*
   1747      * remove the exceeding 0x6
   1748      * for digits that have not generated a carry
   1749      */
   1750 
   1751     tcg_gen_sub_i32(dest, t1, dest);
   1752     tcg_temp_free(t1);
   1753 }
   1754 
   1755 static void bcd_sub(TCGv dest, TCGv src)
   1756 {
   1757     TCGv t0, t1, t2;
   1758 
   1759     /*
   1760      *  dest10 = dest10 - src10 - X
   1761      *         = bcd_add(dest + 1 - X, 0x199 - src)
   1762      */
   1763 
   1764     /* t0 = 0x066 + (0x199 - src) */
   1765 
   1766     t0 = tcg_temp_new();
   1767     tcg_gen_subfi_i32(t0, 0x1ff, src);
   1768 
   1769     /* t1 = t0 + dest + 1 - X*/
   1770 
   1771     t1 = tcg_temp_new();
   1772     tcg_gen_add_i32(t1, t0, dest);
   1773     tcg_gen_addi_i32(t1, t1, 1);
   1774     tcg_gen_sub_i32(t1, t1, QREG_CC_X);
   1775 
   1776     /* t2 = t0 ^ dest */
   1777 
   1778     t2 = tcg_temp_new();
   1779     tcg_gen_xor_i32(t2, t0, dest);
   1780 
   1781     /* t0 = t1 ^ t2 */
   1782 
   1783     tcg_gen_xor_i32(t0, t1, t2);
   1784 
   1785     /*
   1786      * t2 = ~t0 & 0x110
   1787      * t0 = (t2 >> 2) | (t2 >> 3)
   1788      *
   1789      * to fit on 8bit operands, changed in:
   1790      *
   1791      * t2 = ~(t0 >> 3) & 0x22
   1792      * t0 = t2 + t2
   1793      * t0 = t0 + t2
   1794      */
   1795 
   1796     tcg_gen_shri_i32(t2, t0, 3);
   1797     tcg_gen_not_i32(t2, t2);
   1798     tcg_gen_andi_i32(t2, t2, 0x22);
   1799     tcg_gen_add_i32(t0, t2, t2);
   1800     tcg_gen_add_i32(t0, t0, t2);
   1801     tcg_temp_free(t2);
   1802 
   1803     /* return t1 - t0 */
   1804 
   1805     tcg_gen_sub_i32(dest, t1, t0);
   1806     tcg_temp_free(t0);
   1807     tcg_temp_free(t1);
   1808 }
   1809 
   1810 static void bcd_flags(TCGv val)
   1811 {
   1812     tcg_gen_andi_i32(QREG_CC_C, val, 0x0ff);
   1813     tcg_gen_or_i32(QREG_CC_Z, QREG_CC_Z, QREG_CC_C);
   1814 
   1815     tcg_gen_extract_i32(QREG_CC_C, val, 8, 1);
   1816 
   1817     tcg_gen_mov_i32(QREG_CC_X, QREG_CC_C);
   1818 }
   1819 
   1820 DISAS_INSN(abcd_reg)
   1821 {
   1822     TCGv src;
   1823     TCGv dest;
   1824 
   1825     gen_flush_flags(s); /* !Z is sticky */
   1826 
   1827     src = gen_extend(s, DREG(insn, 0), OS_BYTE, 0);
   1828     dest = gen_extend(s, DREG(insn, 9), OS_BYTE, 0);
   1829     bcd_add(dest, src);
   1830     gen_partset_reg(OS_BYTE, DREG(insn, 9), dest);
   1831 
   1832     bcd_flags(dest);
   1833 }
   1834 
   1835 DISAS_INSN(abcd_mem)
   1836 {
   1837     TCGv src, dest, addr;
   1838 
   1839     gen_flush_flags(s); /* !Z is sticky */
   1840 
   1841     /* Indirect pre-decrement load (mode 4) */
   1842 
   1843     src = gen_ea_mode(env, s, 4, REG(insn, 0), OS_BYTE,
   1844                       NULL_QREG, NULL, EA_LOADU, IS_USER(s));
   1845     dest = gen_ea_mode(env, s, 4, REG(insn, 9), OS_BYTE,
   1846                        NULL_QREG, &addr, EA_LOADU, IS_USER(s));
   1847 
   1848     bcd_add(dest, src);
   1849 
   1850     gen_ea_mode(env, s, 4, REG(insn, 9), OS_BYTE, dest, &addr,
   1851                 EA_STORE, IS_USER(s));
   1852 
   1853     bcd_flags(dest);
   1854 }
   1855 
   1856 DISAS_INSN(sbcd_reg)
   1857 {
   1858     TCGv src, dest;
   1859 
   1860     gen_flush_flags(s); /* !Z is sticky */
   1861 
   1862     src = gen_extend(s, DREG(insn, 0), OS_BYTE, 0);
   1863     dest = gen_extend(s, DREG(insn, 9), OS_BYTE, 0);
   1864 
   1865     bcd_sub(dest, src);
   1866 
   1867     gen_partset_reg(OS_BYTE, DREG(insn, 9), dest);
   1868 
   1869     bcd_flags(dest);
   1870 }
   1871 
   1872 DISAS_INSN(sbcd_mem)
   1873 {
   1874     TCGv src, dest, addr;
   1875 
   1876     gen_flush_flags(s); /* !Z is sticky */
   1877 
   1878     /* Indirect pre-decrement load (mode 4) */
   1879 
   1880     src = gen_ea_mode(env, s, 4, REG(insn, 0), OS_BYTE,
   1881                       NULL_QREG, NULL, EA_LOADU, IS_USER(s));
   1882     dest = gen_ea_mode(env, s, 4, REG(insn, 9), OS_BYTE,
   1883                        NULL_QREG, &addr, EA_LOADU, IS_USER(s));
   1884 
   1885     bcd_sub(dest, src);
   1886 
   1887     gen_ea_mode(env, s, 4, REG(insn, 9), OS_BYTE, dest, &addr,
   1888                 EA_STORE, IS_USER(s));
   1889 
   1890     bcd_flags(dest);
   1891 }
   1892 
   1893 DISAS_INSN(nbcd)
   1894 {
   1895     TCGv src, dest;
   1896     TCGv addr;
   1897 
   1898     gen_flush_flags(s); /* !Z is sticky */
   1899 
   1900     SRC_EA(env, src, OS_BYTE, 0, &addr);
   1901 
   1902     dest = tcg_const_i32(0);
   1903     bcd_sub(dest, src);
   1904 
   1905     DEST_EA(env, insn, OS_BYTE, dest, &addr);
   1906 
   1907     bcd_flags(dest);
   1908 
   1909     tcg_temp_free(dest);
   1910 }
   1911 
   1912 DISAS_INSN(addsub)
   1913 {
   1914     TCGv reg;
   1915     TCGv dest;
   1916     TCGv src;
   1917     TCGv tmp;
   1918     TCGv addr;
   1919     int add;
   1920     int opsize;
   1921 
   1922     add = (insn & 0x4000) != 0;
   1923     opsize = insn_opsize(insn);
   1924     reg = gen_extend(s, DREG(insn, 9), opsize, 1);
   1925     dest = tcg_temp_new();
   1926     if (insn & 0x100) {
   1927         SRC_EA(env, tmp, opsize, 1, &addr);
   1928         src = reg;
   1929     } else {
   1930         tmp = reg;
   1931         SRC_EA(env, src, opsize, 1, NULL);
   1932     }
   1933     if (add) {
   1934         tcg_gen_add_i32(dest, tmp, src);
   1935         tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, dest, src);
   1936         set_cc_op(s, CC_OP_ADDB + opsize);
   1937     } else {
   1938         tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, tmp, src);
   1939         tcg_gen_sub_i32(dest, tmp, src);
   1940         set_cc_op(s, CC_OP_SUBB + opsize);
   1941     }
   1942     gen_update_cc_add(dest, src, opsize);
   1943     if (insn & 0x100) {
   1944         DEST_EA(env, insn, opsize, dest, &addr);
   1945     } else {
   1946         gen_partset_reg(opsize, DREG(insn, 9), dest);
   1947     }
   1948     tcg_temp_free(dest);
   1949 }
   1950 
   1951 /* Reverse the order of the bits in REG.  */
   1952 DISAS_INSN(bitrev)
   1953 {
   1954     TCGv reg;
   1955     reg = DREG(insn, 0);
   1956     gen_helper_bitrev(reg, reg);
   1957 }
   1958 
   1959 DISAS_INSN(bitop_reg)
   1960 {
   1961     int opsize;
   1962     int op;
   1963     TCGv src1;
   1964     TCGv src2;
   1965     TCGv tmp;
   1966     TCGv addr;
   1967     TCGv dest;
   1968 
   1969     if ((insn & 0x38) != 0)
   1970         opsize = OS_BYTE;
   1971     else
   1972         opsize = OS_LONG;
   1973     op = (insn >> 6) & 3;
   1974     SRC_EA(env, src1, opsize, 0, op ? &addr: NULL);
   1975 
   1976     gen_flush_flags(s);
   1977     src2 = tcg_temp_new();
   1978     if (opsize == OS_BYTE)
   1979         tcg_gen_andi_i32(src2, DREG(insn, 9), 7);
   1980     else
   1981         tcg_gen_andi_i32(src2, DREG(insn, 9), 31);
   1982 
   1983     tmp = tcg_const_i32(1);
   1984     tcg_gen_shl_i32(tmp, tmp, src2);
   1985     tcg_temp_free(src2);
   1986 
   1987     tcg_gen_and_i32(QREG_CC_Z, src1, tmp);
   1988 
   1989     dest = tcg_temp_new();
   1990     switch (op) {
   1991     case 1: /* bchg */
   1992         tcg_gen_xor_i32(dest, src1, tmp);
   1993         break;
   1994     case 2: /* bclr */
   1995         tcg_gen_andc_i32(dest, src1, tmp);
   1996         break;
   1997     case 3: /* bset */
   1998         tcg_gen_or_i32(dest, src1, tmp);
   1999         break;
   2000     default: /* btst */
   2001         break;
   2002     }
   2003     tcg_temp_free(tmp);
   2004     if (op) {
   2005         DEST_EA(env, insn, opsize, dest, &addr);
   2006     }
   2007     tcg_temp_free(dest);
   2008 }
   2009 
   2010 DISAS_INSN(sats)
   2011 {
   2012     TCGv reg;
   2013     reg = DREG(insn, 0);
   2014     gen_flush_flags(s);
   2015     gen_helper_sats(reg, reg, QREG_CC_V);
   2016     gen_logic_cc(s, reg, OS_LONG);
   2017 }
   2018 
   2019 static void gen_push(DisasContext *s, TCGv val)
   2020 {
   2021     TCGv tmp;
   2022 
   2023     tmp = tcg_temp_new();
   2024     tcg_gen_subi_i32(tmp, QREG_SP, 4);
   2025     gen_store(s, OS_LONG, tmp, val, IS_USER(s));
   2026     tcg_gen_mov_i32(QREG_SP, tmp);
   2027     tcg_temp_free(tmp);
   2028 }
   2029 
   2030 static TCGv mreg(int reg)
   2031 {
   2032     if (reg < 8) {
   2033         /* Dx */
   2034         return cpu_dregs[reg];
   2035     }
   2036     /* Ax */
   2037     return cpu_aregs[reg & 7];
   2038 }
   2039 
   2040 DISAS_INSN(movem)
   2041 {
   2042     TCGv addr, incr, tmp, r[16];
   2043     int is_load = (insn & 0x0400) != 0;
   2044     int opsize = (insn & 0x40) != 0 ? OS_LONG : OS_WORD;
   2045     uint16_t mask = read_im16(env, s);
   2046     int mode = extract32(insn, 3, 3);
   2047     int reg0 = REG(insn, 0);
   2048     int i;
   2049 
   2050     tmp = cpu_aregs[reg0];
   2051 
   2052     switch (mode) {
   2053     case 0: /* data register direct */
   2054     case 1: /* addr register direct */
   2055     do_addr_fault:
   2056         gen_addr_fault(s);
   2057         return;
   2058 
   2059     case 2: /* indirect */
   2060         break;
   2061 
   2062     case 3: /* indirect post-increment */
   2063         if (!is_load) {
   2064             /* post-increment is not allowed */
   2065             goto do_addr_fault;
   2066         }
   2067         break;
   2068 
   2069     case 4: /* indirect pre-decrement */
   2070         if (is_load) {
   2071             /* pre-decrement is not allowed */
   2072             goto do_addr_fault;
   2073         }
   2074         /*
   2075          * We want a bare copy of the address reg, without any pre-decrement
   2076          * adjustment, as gen_lea would provide.
   2077          */
   2078         break;
   2079 
   2080     default:
   2081         tmp = gen_lea_mode(env, s, mode, reg0, opsize);
   2082         if (IS_NULL_QREG(tmp)) {
   2083             goto do_addr_fault;
   2084         }
   2085         break;
   2086     }
   2087 
   2088     addr = tcg_temp_new();
   2089     tcg_gen_mov_i32(addr, tmp);
   2090     incr = tcg_const_i32(opsize_bytes(opsize));
   2091 
   2092     if (is_load) {
   2093         /* memory to register */
   2094         for (i = 0; i < 16; i++) {
   2095             if (mask & (1 << i)) {
   2096                 r[i] = gen_load(s, opsize, addr, 1, IS_USER(s));
   2097                 tcg_gen_add_i32(addr, addr, incr);
   2098             }
   2099         }
   2100         for (i = 0; i < 16; i++) {
   2101             if (mask & (1 << i)) {
   2102                 tcg_gen_mov_i32(mreg(i), r[i]);
   2103                 tcg_temp_free(r[i]);
   2104             }
   2105         }
   2106         if (mode == 3) {
   2107             /* post-increment: movem (An)+,X */
   2108             tcg_gen_mov_i32(cpu_aregs[reg0], addr);
   2109         }
   2110     } else {
   2111         /* register to memory */
   2112         if (mode == 4) {
   2113             /* pre-decrement: movem X,-(An) */
   2114             for (i = 15; i >= 0; i--) {
   2115                 if ((mask << i) & 0x8000) {
   2116                     tcg_gen_sub_i32(addr, addr, incr);
   2117                     if (reg0 + 8 == i &&
   2118                         m68k_feature(s->env, M68K_FEATURE_EXT_FULL)) {
   2119                         /*
   2120                          * M68020+: if the addressing register is the
   2121                          * register moved to memory, the value written
   2122                          * is the initial value decremented by the size of
   2123                          * the operation, regardless of how many actual
   2124                          * stores have been performed until this point.
   2125                          * M68000/M68010: the value is the initial value.
   2126                          */
   2127                         tmp = tcg_temp_new();
   2128                         tcg_gen_sub_i32(tmp, cpu_aregs[reg0], incr);
   2129                         gen_store(s, opsize, addr, tmp, IS_USER(s));
   2130                         tcg_temp_free(tmp);
   2131                     } else {
   2132                         gen_store(s, opsize, addr, mreg(i), IS_USER(s));
   2133                     }
   2134                 }
   2135             }
   2136             tcg_gen_mov_i32(cpu_aregs[reg0], addr);
   2137         } else {
   2138             for (i = 0; i < 16; i++) {
   2139                 if (mask & (1 << i)) {
   2140                     gen_store(s, opsize, addr, mreg(i), IS_USER(s));
   2141                     tcg_gen_add_i32(addr, addr, incr);
   2142                 }
   2143             }
   2144         }
   2145     }
   2146 
   2147     tcg_temp_free(incr);
   2148     tcg_temp_free(addr);
   2149 }
   2150 
   2151 DISAS_INSN(movep)
   2152 {
   2153     uint8_t i;
   2154     int16_t displ;
   2155     TCGv reg;
   2156     TCGv addr;
   2157     TCGv abuf;
   2158     TCGv dbuf;
   2159 
   2160     displ = read_im16(env, s);
   2161 
   2162     addr = AREG(insn, 0);
   2163     reg = DREG(insn, 9);
   2164 
   2165     abuf = tcg_temp_new();
   2166     tcg_gen_addi_i32(abuf, addr, displ);
   2167     dbuf = tcg_temp_new();
   2168 
   2169     if (insn & 0x40) {
   2170         i = 4;
   2171     } else {
   2172         i = 2;
   2173     }
   2174 
   2175     if (insn & 0x80) {
   2176         for ( ; i > 0 ; i--) {
   2177             tcg_gen_shri_i32(dbuf, reg, (i - 1) * 8);
   2178             tcg_gen_qemu_st8(dbuf, abuf, IS_USER(s));
   2179             if (i > 1) {
   2180                 tcg_gen_addi_i32(abuf, abuf, 2);
   2181             }
   2182         }
   2183     } else {
   2184         for ( ; i > 0 ; i--) {
   2185             tcg_gen_qemu_ld8u(dbuf, abuf, IS_USER(s));
   2186             tcg_gen_deposit_i32(reg, reg, dbuf, (i - 1) * 8, 8);
   2187             if (i > 1) {
   2188                 tcg_gen_addi_i32(abuf, abuf, 2);
   2189             }
   2190         }
   2191     }
   2192     tcg_temp_free(abuf);
   2193     tcg_temp_free(dbuf);
   2194 }
   2195 
   2196 DISAS_INSN(bitop_im)
   2197 {
   2198     int opsize;
   2199     int op;
   2200     TCGv src1;
   2201     uint32_t mask;
   2202     int bitnum;
   2203     TCGv tmp;
   2204     TCGv addr;
   2205 
   2206     if ((insn & 0x38) != 0)
   2207         opsize = OS_BYTE;
   2208     else
   2209         opsize = OS_LONG;
   2210     op = (insn >> 6) & 3;
   2211 
   2212     bitnum = read_im16(env, s);
   2213     if (m68k_feature(s->env, M68K_FEATURE_M68K)) {
   2214         if (bitnum & 0xfe00) {
   2215             disas_undef(env, s, insn);
   2216             return;
   2217         }
   2218     } else {
   2219         if (bitnum & 0xff00) {
   2220             disas_undef(env, s, insn);
   2221             return;
   2222         }
   2223     }
   2224 
   2225     SRC_EA(env, src1, opsize, 0, op ? &addr: NULL);
   2226 
   2227     gen_flush_flags(s);
   2228     if (opsize == OS_BYTE)
   2229         bitnum &= 7;
   2230     else
   2231         bitnum &= 31;
   2232     mask = 1 << bitnum;
   2233 
   2234    tcg_gen_andi_i32(QREG_CC_Z, src1, mask);
   2235 
   2236     if (op) {
   2237         tmp = tcg_temp_new();
   2238         switch (op) {
   2239         case 1: /* bchg */
   2240             tcg_gen_xori_i32(tmp, src1, mask);
   2241             break;
   2242         case 2: /* bclr */
   2243             tcg_gen_andi_i32(tmp, src1, ~mask);
   2244             break;
   2245         case 3: /* bset */
   2246             tcg_gen_ori_i32(tmp, src1, mask);
   2247             break;
   2248         default: /* btst */
   2249             break;
   2250         }
   2251         DEST_EA(env, insn, opsize, tmp, &addr);
   2252         tcg_temp_free(tmp);
   2253     }
   2254 }
   2255 
   2256 static TCGv gen_get_ccr(DisasContext *s)
   2257 {
   2258     TCGv dest;
   2259 
   2260     update_cc_op(s);
   2261     dest = tcg_temp_new();
   2262     gen_helper_get_ccr(dest, cpu_env);
   2263     return dest;
   2264 }
   2265 
   2266 static TCGv gen_get_sr(DisasContext *s)
   2267 {
   2268     TCGv ccr;
   2269     TCGv sr;
   2270 
   2271     ccr = gen_get_ccr(s);
   2272     sr = tcg_temp_new();
   2273     tcg_gen_andi_i32(sr, QREG_SR, 0xffe0);
   2274     tcg_gen_or_i32(sr, sr, ccr);
   2275     tcg_temp_free(ccr);
   2276     return sr;
   2277 }
   2278 
   2279 static void gen_set_sr_im(DisasContext *s, uint16_t val, int ccr_only)
   2280 {
   2281     if (ccr_only) {
   2282         tcg_gen_movi_i32(QREG_CC_C, val & CCF_C ? 1 : 0);
   2283         tcg_gen_movi_i32(QREG_CC_V, val & CCF_V ? -1 : 0);
   2284         tcg_gen_movi_i32(QREG_CC_Z, val & CCF_Z ? 0 : 1);
   2285         tcg_gen_movi_i32(QREG_CC_N, val & CCF_N ? -1 : 0);
   2286         tcg_gen_movi_i32(QREG_CC_X, val & CCF_X ? 1 : 0);
   2287     } else {
   2288         /* Must writeback before changing security state. */
   2289         do_writebacks(s);
   2290         gen_helper_set_sr(cpu_env, tcg_constant_i32(val));
   2291     }
   2292     set_cc_op(s, CC_OP_FLAGS);
   2293 }
   2294 
   2295 static void gen_set_sr(DisasContext *s, TCGv val, int ccr_only)
   2296 {
   2297     if (ccr_only) {
   2298         gen_helper_set_ccr(cpu_env, val);
   2299     } else {
   2300         /* Must writeback before changing security state. */
   2301         do_writebacks(s);
   2302         gen_helper_set_sr(cpu_env, val);
   2303     }
   2304     set_cc_op(s, CC_OP_FLAGS);
   2305 }
   2306 
   2307 static void gen_move_to_sr(CPUM68KState *env, DisasContext *s, uint16_t insn,
   2308                            bool ccr_only)
   2309 {
   2310     if ((insn & 0x3f) == 0x3c) {
   2311         uint16_t val;
   2312         val = read_im16(env, s);
   2313         gen_set_sr_im(s, val, ccr_only);
   2314     } else {
   2315         TCGv src;
   2316         SRC_EA(env, src, OS_WORD, 0, NULL);
   2317         gen_set_sr(s, src, ccr_only);
   2318     }
   2319 }
   2320 
   2321 DISAS_INSN(arith_im)
   2322 {
   2323     int op;
   2324     TCGv im;
   2325     TCGv src1;
   2326     TCGv dest;
   2327     TCGv addr;
   2328     int opsize;
   2329     bool with_SR = ((insn & 0x3f) == 0x3c);
   2330 
   2331     op = (insn >> 9) & 7;
   2332     opsize = insn_opsize(insn);
   2333     switch (opsize) {
   2334     case OS_BYTE:
   2335         im = tcg_const_i32((int8_t)read_im8(env, s));
   2336         break;
   2337     case OS_WORD:
   2338         im = tcg_const_i32((int16_t)read_im16(env, s));
   2339         break;
   2340     case OS_LONG:
   2341         im = tcg_const_i32(read_im32(env, s));
   2342         break;
   2343     default:
   2344         g_assert_not_reached();
   2345     }
   2346 
   2347     if (with_SR) {
   2348         /* SR/CCR can only be used with andi/eori/ori */
   2349         if (op == 2 || op == 3 || op == 6) {
   2350             disas_undef(env, s, insn);
   2351             return;
   2352         }
   2353         switch (opsize) {
   2354         case OS_BYTE:
   2355             src1 = gen_get_ccr(s);
   2356             break;
   2357         case OS_WORD:
   2358             if (IS_USER(s)) {
   2359                 gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE);
   2360                 return;
   2361             }
   2362             src1 = gen_get_sr(s);
   2363             break;
   2364         default:
   2365             /* OS_LONG; others already g_assert_not_reached.  */
   2366             disas_undef(env, s, insn);
   2367             return;
   2368         }
   2369     } else {
   2370         SRC_EA(env, src1, opsize, 1, (op == 6) ? NULL : &addr);
   2371     }
   2372     dest = tcg_temp_new();
   2373     switch (op) {
   2374     case 0: /* ori */
   2375         tcg_gen_or_i32(dest, src1, im);
   2376         if (with_SR) {
   2377             gen_set_sr(s, dest, opsize == OS_BYTE);
   2378             gen_exit_tb(s);
   2379         } else {
   2380             DEST_EA(env, insn, opsize, dest, &addr);
   2381             gen_logic_cc(s, dest, opsize);
   2382         }
   2383         break;
   2384     case 1: /* andi */
   2385         tcg_gen_and_i32(dest, src1, im);
   2386         if (with_SR) {
   2387             gen_set_sr(s, dest, opsize == OS_BYTE);
   2388             gen_exit_tb(s);
   2389         } else {
   2390             DEST_EA(env, insn, opsize, dest, &addr);
   2391             gen_logic_cc(s, dest, opsize);
   2392         }
   2393         break;
   2394     case 2: /* subi */
   2395         tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, src1, im);
   2396         tcg_gen_sub_i32(dest, src1, im);
   2397         gen_update_cc_add(dest, im, opsize);
   2398         set_cc_op(s, CC_OP_SUBB + opsize);
   2399         DEST_EA(env, insn, opsize, dest, &addr);
   2400         break;
   2401     case 3: /* addi */
   2402         tcg_gen_add_i32(dest, src1, im);
   2403         gen_update_cc_add(dest, im, opsize);
   2404         tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, dest, im);
   2405         set_cc_op(s, CC_OP_ADDB + opsize);
   2406         DEST_EA(env, insn, opsize, dest, &addr);
   2407         break;
   2408     case 5: /* eori */
   2409         tcg_gen_xor_i32(dest, src1, im);
   2410         if (with_SR) {
   2411             gen_set_sr(s, dest, opsize == OS_BYTE);
   2412             gen_exit_tb(s);
   2413         } else {
   2414             DEST_EA(env, insn, opsize, dest, &addr);
   2415             gen_logic_cc(s, dest, opsize);
   2416         }
   2417         break;
   2418     case 6: /* cmpi */
   2419         gen_update_cc_cmp(s, src1, im, opsize);
   2420         break;
   2421     default:
   2422         abort();
   2423     }
   2424     tcg_temp_free(im);
   2425     tcg_temp_free(dest);
   2426 }
   2427 
   2428 DISAS_INSN(cas)
   2429 {
   2430     int opsize;
   2431     TCGv addr;
   2432     uint16_t ext;
   2433     TCGv load;
   2434     TCGv cmp;
   2435     MemOp opc;
   2436 
   2437     switch ((insn >> 9) & 3) {
   2438     case 1:
   2439         opsize = OS_BYTE;
   2440         opc = MO_SB;
   2441         break;
   2442     case 2:
   2443         opsize = OS_WORD;
   2444         opc = MO_TESW;
   2445         break;
   2446     case 3:
   2447         opsize = OS_LONG;
   2448         opc = MO_TESL;
   2449         break;
   2450     default:
   2451         g_assert_not_reached();
   2452     }
   2453 
   2454     ext = read_im16(env, s);
   2455 
   2456     /* cas Dc,Du,<EA> */
   2457 
   2458     addr = gen_lea(env, s, insn, opsize);
   2459     if (IS_NULL_QREG(addr)) {
   2460         gen_addr_fault(s);
   2461         return;
   2462     }
   2463 
   2464     cmp = gen_extend(s, DREG(ext, 0), opsize, 1);
   2465 
   2466     /*
   2467      * if  <EA> == Dc then
   2468      *     <EA> = Du
   2469      *     Dc = <EA> (because <EA> == Dc)
   2470      * else
   2471      *     Dc = <EA>
   2472      */
   2473 
   2474     load = tcg_temp_new();
   2475     tcg_gen_atomic_cmpxchg_i32(load, addr, cmp, DREG(ext, 6),
   2476                                IS_USER(s), opc);
   2477     /* update flags before setting cmp to load */
   2478     gen_update_cc_cmp(s, load, cmp, opsize);
   2479     gen_partset_reg(opsize, DREG(ext, 0), load);
   2480 
   2481     tcg_temp_free(load);
   2482 
   2483     switch (extract32(insn, 3, 3)) {
   2484     case 3: /* Indirect postincrement.  */
   2485         tcg_gen_addi_i32(AREG(insn, 0), addr, opsize_bytes(opsize));
   2486         break;
   2487     case 4: /* Indirect predecrememnt.  */
   2488         tcg_gen_mov_i32(AREG(insn, 0), addr);
   2489         break;
   2490     }
   2491 }
   2492 
   2493 DISAS_INSN(cas2w)
   2494 {
   2495     uint16_t ext1, ext2;
   2496     TCGv addr1, addr2;
   2497     TCGv regs;
   2498 
   2499     /* cas2 Dc1:Dc2,Du1:Du2,(Rn1):(Rn2) */
   2500 
   2501     ext1 = read_im16(env, s);
   2502 
   2503     if (ext1 & 0x8000) {
   2504         /* Address Register */
   2505         addr1 = AREG(ext1, 12);
   2506     } else {
   2507         /* Data Register */
   2508         addr1 = DREG(ext1, 12);
   2509     }
   2510 
   2511     ext2 = read_im16(env, s);
   2512     if (ext2 & 0x8000) {
   2513         /* Address Register */
   2514         addr2 = AREG(ext2, 12);
   2515     } else {
   2516         /* Data Register */
   2517         addr2 = DREG(ext2, 12);
   2518     }
   2519 
   2520     /*
   2521      * if (R1) == Dc1 && (R2) == Dc2 then
   2522      *     (R1) = Du1
   2523      *     (R2) = Du2
   2524      * else
   2525      *     Dc1 = (R1)
   2526      *     Dc2 = (R2)
   2527      */
   2528 
   2529     regs = tcg_const_i32(REG(ext2, 6) |
   2530                          (REG(ext1, 6) << 3) |
   2531                          (REG(ext2, 0) << 6) |
   2532                          (REG(ext1, 0) << 9));
   2533     if (tb_cflags(s->base.tb) & CF_PARALLEL) {
   2534         gen_helper_exit_atomic(cpu_env);
   2535     } else {
   2536         gen_helper_cas2w(cpu_env, regs, addr1, addr2);
   2537     }
   2538     tcg_temp_free(regs);
   2539 
   2540     /* Note that cas2w also assigned to env->cc_op.  */
   2541     s->cc_op = CC_OP_CMPW;
   2542     s->cc_op_synced = 1;
   2543 }
   2544 
   2545 DISAS_INSN(cas2l)
   2546 {
   2547     uint16_t ext1, ext2;
   2548     TCGv addr1, addr2, regs;
   2549 
   2550     /* cas2 Dc1:Dc2,Du1:Du2,(Rn1):(Rn2) */
   2551 
   2552     ext1 = read_im16(env, s);
   2553 
   2554     if (ext1 & 0x8000) {
   2555         /* Address Register */
   2556         addr1 = AREG(ext1, 12);
   2557     } else {
   2558         /* Data Register */
   2559         addr1 = DREG(ext1, 12);
   2560     }
   2561 
   2562     ext2 = read_im16(env, s);
   2563     if (ext2 & 0x8000) {
   2564         /* Address Register */
   2565         addr2 = AREG(ext2, 12);
   2566     } else {
   2567         /* Data Register */
   2568         addr2 = DREG(ext2, 12);
   2569     }
   2570 
   2571     /*
   2572      * if (R1) == Dc1 && (R2) == Dc2 then
   2573      *     (R1) = Du1
   2574      *     (R2) = Du2
   2575      * else
   2576      *     Dc1 = (R1)
   2577      *     Dc2 = (R2)
   2578      */
   2579 
   2580     regs = tcg_const_i32(REG(ext2, 6) |
   2581                          (REG(ext1, 6) << 3) |
   2582                          (REG(ext2, 0) << 6) |
   2583                          (REG(ext1, 0) << 9));
   2584     if (tb_cflags(s->base.tb) & CF_PARALLEL) {
   2585         gen_helper_cas2l_parallel(cpu_env, regs, addr1, addr2);
   2586     } else {
   2587         gen_helper_cas2l(cpu_env, regs, addr1, addr2);
   2588     }
   2589     tcg_temp_free(regs);
   2590 
   2591     /* Note that cas2l also assigned to env->cc_op.  */
   2592     s->cc_op = CC_OP_CMPL;
   2593     s->cc_op_synced = 1;
   2594 }
   2595 
   2596 DISAS_INSN(byterev)
   2597 {
   2598     TCGv reg;
   2599 
   2600     reg = DREG(insn, 0);
   2601     tcg_gen_bswap32_i32(reg, reg);
   2602 }
   2603 
   2604 DISAS_INSN(move)
   2605 {
   2606     TCGv src;
   2607     TCGv dest;
   2608     int op;
   2609     int opsize;
   2610 
   2611     switch (insn >> 12) {
   2612     case 1: /* move.b */
   2613         opsize = OS_BYTE;
   2614         break;
   2615     case 2: /* move.l */
   2616         opsize = OS_LONG;
   2617         break;
   2618     case 3: /* move.w */
   2619         opsize = OS_WORD;
   2620         break;
   2621     default:
   2622         abort();
   2623     }
   2624     SRC_EA(env, src, opsize, 1, NULL);
   2625     op = (insn >> 6) & 7;
   2626     if (op == 1) {
   2627         /* movea */
   2628         /* The value will already have been sign extended.  */
   2629         dest = AREG(insn, 9);
   2630         tcg_gen_mov_i32(dest, src);
   2631     } else {
   2632         /* normal move */
   2633         uint16_t dest_ea;
   2634         dest_ea = ((insn >> 9) & 7) | (op << 3);
   2635         DEST_EA(env, dest_ea, opsize, src, NULL);
   2636         /* This will be correct because loads sign extend.  */
   2637         gen_logic_cc(s, src, opsize);
   2638     }
   2639 }
   2640 
   2641 DISAS_INSN(negx)
   2642 {
   2643     TCGv z;
   2644     TCGv src;
   2645     TCGv addr;
   2646     int opsize;
   2647 
   2648     opsize = insn_opsize(insn);
   2649     SRC_EA(env, src, opsize, 1, &addr);
   2650 
   2651     gen_flush_flags(s); /* compute old Z */
   2652 
   2653     /*
   2654      * Perform subtract with borrow.
   2655      * (X, N) =  -(src + X);
   2656      */
   2657 
   2658     z = tcg_const_i32(0);
   2659     tcg_gen_add2_i32(QREG_CC_N, QREG_CC_X, src, z, QREG_CC_X, z);
   2660     tcg_gen_sub2_i32(QREG_CC_N, QREG_CC_X, z, z, QREG_CC_N, QREG_CC_X);
   2661     tcg_temp_free(z);
   2662     gen_ext(QREG_CC_N, QREG_CC_N, opsize, 1);
   2663 
   2664     tcg_gen_andi_i32(QREG_CC_X, QREG_CC_X, 1);
   2665 
   2666     /*
   2667      * Compute signed-overflow for negation.  The normal formula for
   2668      * subtraction is (res ^ src) & (src ^ dest), but with dest==0
   2669      * this simplifies to res & src.
   2670      */
   2671 
   2672     tcg_gen_and_i32(QREG_CC_V, QREG_CC_N, src);
   2673 
   2674     /* Copy the rest of the results into place.  */
   2675     tcg_gen_or_i32(QREG_CC_Z, QREG_CC_Z, QREG_CC_N); /* !Z is sticky */
   2676     tcg_gen_mov_i32(QREG_CC_C, QREG_CC_X);
   2677 
   2678     set_cc_op(s, CC_OP_FLAGS);
   2679 
   2680     /* result is in QREG_CC_N */
   2681 
   2682     DEST_EA(env, insn, opsize, QREG_CC_N, &addr);
   2683 }
   2684 
   2685 DISAS_INSN(lea)
   2686 {
   2687     TCGv reg;
   2688     TCGv tmp;
   2689 
   2690     reg = AREG(insn, 9);
   2691     tmp = gen_lea(env, s, insn, OS_LONG);
   2692     if (IS_NULL_QREG(tmp)) {
   2693         gen_addr_fault(s);
   2694         return;
   2695     }
   2696     tcg_gen_mov_i32(reg, tmp);
   2697 }
   2698 
   2699 DISAS_INSN(clr)
   2700 {
   2701     int opsize;
   2702     TCGv zero;
   2703 
   2704     zero = tcg_const_i32(0);
   2705 
   2706     opsize = insn_opsize(insn);
   2707     DEST_EA(env, insn, opsize, zero, NULL);
   2708     gen_logic_cc(s, zero, opsize);
   2709     tcg_temp_free(zero);
   2710 }
   2711 
   2712 DISAS_INSN(move_from_ccr)
   2713 {
   2714     TCGv ccr;
   2715 
   2716     ccr = gen_get_ccr(s);
   2717     DEST_EA(env, insn, OS_WORD, ccr, NULL);
   2718 }
   2719 
   2720 DISAS_INSN(neg)
   2721 {
   2722     TCGv src1;
   2723     TCGv dest;
   2724     TCGv addr;
   2725     int opsize;
   2726 
   2727     opsize = insn_opsize(insn);
   2728     SRC_EA(env, src1, opsize, 1, &addr);
   2729     dest = tcg_temp_new();
   2730     tcg_gen_neg_i32(dest, src1);
   2731     set_cc_op(s, CC_OP_SUBB + opsize);
   2732     gen_update_cc_add(dest, src1, opsize);
   2733     tcg_gen_setcondi_i32(TCG_COND_NE, QREG_CC_X, dest, 0);
   2734     DEST_EA(env, insn, opsize, dest, &addr);
   2735     tcg_temp_free(dest);
   2736 }
   2737 
   2738 DISAS_INSN(move_to_ccr)
   2739 {
   2740     gen_move_to_sr(env, s, insn, true);
   2741 }
   2742 
   2743 DISAS_INSN(not)
   2744 {
   2745     TCGv src1;
   2746     TCGv dest;
   2747     TCGv addr;
   2748     int opsize;
   2749 
   2750     opsize = insn_opsize(insn);
   2751     SRC_EA(env, src1, opsize, 1, &addr);
   2752     dest = tcg_temp_new();
   2753     tcg_gen_not_i32(dest, src1);
   2754     DEST_EA(env, insn, opsize, dest, &addr);
   2755     gen_logic_cc(s, dest, opsize);
   2756 }
   2757 
   2758 DISAS_INSN(swap)
   2759 {
   2760     TCGv src1;
   2761     TCGv src2;
   2762     TCGv reg;
   2763 
   2764     src1 = tcg_temp_new();
   2765     src2 = tcg_temp_new();
   2766     reg = DREG(insn, 0);
   2767     tcg_gen_shli_i32(src1, reg, 16);
   2768     tcg_gen_shri_i32(src2, reg, 16);
   2769     tcg_gen_or_i32(reg, src1, src2);
   2770     tcg_temp_free(src2);
   2771     tcg_temp_free(src1);
   2772     gen_logic_cc(s, reg, OS_LONG);
   2773 }
   2774 
   2775 DISAS_INSN(bkpt)
   2776 {
   2777     gen_exception(s, s->base.pc_next, EXCP_DEBUG);
   2778 }
   2779 
   2780 DISAS_INSN(pea)
   2781 {
   2782     TCGv tmp;
   2783 
   2784     tmp = gen_lea(env, s, insn, OS_LONG);
   2785     if (IS_NULL_QREG(tmp)) {
   2786         gen_addr_fault(s);
   2787         return;
   2788     }
   2789     gen_push(s, tmp);
   2790 }
   2791 
   2792 DISAS_INSN(ext)
   2793 {
   2794     int op;
   2795     TCGv reg;
   2796     TCGv tmp;
   2797 
   2798     reg = DREG(insn, 0);
   2799     op = (insn >> 6) & 7;
   2800     tmp = tcg_temp_new();
   2801     if (op == 3)
   2802         tcg_gen_ext16s_i32(tmp, reg);
   2803     else
   2804         tcg_gen_ext8s_i32(tmp, reg);
   2805     if (op == 2)
   2806         gen_partset_reg(OS_WORD, reg, tmp);
   2807     else
   2808         tcg_gen_mov_i32(reg, tmp);
   2809     gen_logic_cc(s, tmp, OS_LONG);
   2810     tcg_temp_free(tmp);
   2811 }
   2812 
   2813 DISAS_INSN(tst)
   2814 {
   2815     int opsize;
   2816     TCGv tmp;
   2817 
   2818     opsize = insn_opsize(insn);
   2819     SRC_EA(env, tmp, opsize, 1, NULL);
   2820     gen_logic_cc(s, tmp, opsize);
   2821 }
   2822 
   2823 DISAS_INSN(pulse)
   2824 {
   2825   /* Implemented as a NOP.  */
   2826 }
   2827 
   2828 DISAS_INSN(illegal)
   2829 {
   2830     gen_exception(s, s->base.pc_next, EXCP_ILLEGAL);
   2831 }
   2832 
   2833 DISAS_INSN(tas)
   2834 {
   2835     int mode = extract32(insn, 3, 3);
   2836     int reg0 = REG(insn, 0);
   2837 
   2838     if (mode == 0) {
   2839         /* data register direct */
   2840         TCGv dest = cpu_dregs[reg0];
   2841         gen_logic_cc(s, dest, OS_BYTE);
   2842         tcg_gen_ori_tl(dest, dest, 0x80);
   2843     } else {
   2844         TCGv src1, addr;
   2845 
   2846         addr = gen_lea_mode(env, s, mode, reg0, OS_BYTE);
   2847         if (IS_NULL_QREG(addr)) {
   2848             gen_addr_fault(s);
   2849             return;
   2850         }
   2851         src1 = tcg_temp_new();
   2852         tcg_gen_atomic_fetch_or_tl(src1, addr, tcg_constant_tl(0x80),
   2853                                    IS_USER(s), MO_SB);
   2854         gen_logic_cc(s, src1, OS_BYTE);
   2855         tcg_temp_free(src1);
   2856 
   2857         switch (mode) {
   2858         case 3: /* Indirect postincrement.  */
   2859             tcg_gen_addi_i32(AREG(insn, 0), addr, 1);
   2860             break;
   2861         case 4: /* Indirect predecrememnt.  */
   2862             tcg_gen_mov_i32(AREG(insn, 0), addr);
   2863             break;
   2864         }
   2865     }
   2866 }
   2867 
   2868 DISAS_INSN(mull)
   2869 {
   2870     uint16_t ext;
   2871     TCGv src1;
   2872     int sign;
   2873 
   2874     ext = read_im16(env, s);
   2875 
   2876     sign = ext & 0x800;
   2877 
   2878     if (ext & 0x400) {
   2879         if (!m68k_feature(s->env, M68K_FEATURE_QUAD_MULDIV)) {
   2880             gen_exception(s, s->base.pc_next, EXCP_ILLEGAL);
   2881             return;
   2882         }
   2883 
   2884         SRC_EA(env, src1, OS_LONG, 0, NULL);
   2885 
   2886         if (sign) {
   2887             tcg_gen_muls2_i32(QREG_CC_Z, QREG_CC_N, src1, DREG(ext, 12));
   2888         } else {
   2889             tcg_gen_mulu2_i32(QREG_CC_Z, QREG_CC_N, src1, DREG(ext, 12));
   2890         }
   2891         /* if Dl == Dh, 68040 returns low word */
   2892         tcg_gen_mov_i32(DREG(ext, 0), QREG_CC_N);
   2893         tcg_gen_mov_i32(DREG(ext, 12), QREG_CC_Z);
   2894         tcg_gen_or_i32(QREG_CC_Z, QREG_CC_Z, QREG_CC_N);
   2895 
   2896         tcg_gen_movi_i32(QREG_CC_V, 0);
   2897         tcg_gen_movi_i32(QREG_CC_C, 0);
   2898 
   2899         set_cc_op(s, CC_OP_FLAGS);
   2900         return;
   2901     }
   2902     SRC_EA(env, src1, OS_LONG, 0, NULL);
   2903     if (m68k_feature(s->env, M68K_FEATURE_M68K)) {
   2904         tcg_gen_movi_i32(QREG_CC_C, 0);
   2905         if (sign) {
   2906             tcg_gen_muls2_i32(QREG_CC_N, QREG_CC_V, src1, DREG(ext, 12));
   2907             /* QREG_CC_V is -(QREG_CC_V != (QREG_CC_N >> 31)) */
   2908             tcg_gen_sari_i32(QREG_CC_Z, QREG_CC_N, 31);
   2909             tcg_gen_setcond_i32(TCG_COND_NE, QREG_CC_V, QREG_CC_V, QREG_CC_Z);
   2910         } else {
   2911             tcg_gen_mulu2_i32(QREG_CC_N, QREG_CC_V, src1, DREG(ext, 12));
   2912             /* QREG_CC_V is -(QREG_CC_V != 0), use QREG_CC_C as 0 */
   2913             tcg_gen_setcond_i32(TCG_COND_NE, QREG_CC_V, QREG_CC_V, QREG_CC_C);
   2914         }
   2915         tcg_gen_neg_i32(QREG_CC_V, QREG_CC_V);
   2916         tcg_gen_mov_i32(DREG(ext, 12), QREG_CC_N);
   2917 
   2918         tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N);
   2919 
   2920         set_cc_op(s, CC_OP_FLAGS);
   2921     } else {
   2922         /*
   2923          * The upper 32 bits of the product are discarded, so
   2924          * muls.l and mulu.l are functionally equivalent.
   2925          */
   2926         tcg_gen_mul_i32(DREG(ext, 12), src1, DREG(ext, 12));
   2927         gen_logic_cc(s, DREG(ext, 12), OS_LONG);
   2928     }
   2929 }
   2930 
   2931 static void gen_link(DisasContext *s, uint16_t insn, int32_t offset)
   2932 {
   2933     TCGv reg;
   2934     TCGv tmp;
   2935 
   2936     reg = AREG(insn, 0);
   2937     tmp = tcg_temp_new();
   2938     tcg_gen_subi_i32(tmp, QREG_SP, 4);
   2939     gen_store(s, OS_LONG, tmp, reg, IS_USER(s));
   2940     if ((insn & 7) != 7) {
   2941         tcg_gen_mov_i32(reg, tmp);
   2942     }
   2943     tcg_gen_addi_i32(QREG_SP, tmp, offset);
   2944     tcg_temp_free(tmp);
   2945 }
   2946 
   2947 DISAS_INSN(link)
   2948 {
   2949     int16_t offset;
   2950 
   2951     offset = read_im16(env, s);
   2952     gen_link(s, insn, offset);
   2953 }
   2954 
   2955 DISAS_INSN(linkl)
   2956 {
   2957     int32_t offset;
   2958 
   2959     offset = read_im32(env, s);
   2960     gen_link(s, insn, offset);
   2961 }
   2962 
   2963 DISAS_INSN(unlk)
   2964 {
   2965     TCGv src;
   2966     TCGv reg;
   2967     TCGv tmp;
   2968 
   2969     src = tcg_temp_new();
   2970     reg = AREG(insn, 0);
   2971     tcg_gen_mov_i32(src, reg);
   2972     tmp = gen_load(s, OS_LONG, src, 0, IS_USER(s));
   2973     tcg_gen_mov_i32(reg, tmp);
   2974     tcg_gen_addi_i32(QREG_SP, src, 4);
   2975     tcg_temp_free(src);
   2976     tcg_temp_free(tmp);
   2977 }
   2978 
   2979 #if defined(CONFIG_SOFTMMU)
   2980 DISAS_INSN(reset)
   2981 {
   2982     if (IS_USER(s)) {
   2983         gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE);
   2984         return;
   2985     }
   2986 
   2987     gen_helper_reset(cpu_env);
   2988 }
   2989 #endif
   2990 
   2991 DISAS_INSN(nop)
   2992 {
   2993 }
   2994 
   2995 DISAS_INSN(rtd)
   2996 {
   2997     TCGv tmp;
   2998     int16_t offset = read_im16(env, s);
   2999 
   3000     tmp = gen_load(s, OS_LONG, QREG_SP, 0, IS_USER(s));
   3001     tcg_gen_addi_i32(QREG_SP, QREG_SP, offset + 4);
   3002     gen_jmp(s, tmp);
   3003 }
   3004 
   3005 DISAS_INSN(rtr)
   3006 {
   3007     TCGv tmp;
   3008     TCGv ccr;
   3009     TCGv sp;
   3010 
   3011     sp = tcg_temp_new();
   3012     ccr = gen_load(s, OS_WORD, QREG_SP, 0, IS_USER(s));
   3013     tcg_gen_addi_i32(sp, QREG_SP, 2);
   3014     tmp = gen_load(s, OS_LONG, sp, 0, IS_USER(s));
   3015     tcg_gen_addi_i32(QREG_SP, sp, 4);
   3016     tcg_temp_free(sp);
   3017 
   3018     gen_set_sr(s, ccr, true);
   3019     tcg_temp_free(ccr);
   3020 
   3021     gen_jmp(s, tmp);
   3022 }
   3023 
   3024 DISAS_INSN(rts)
   3025 {
   3026     TCGv tmp;
   3027 
   3028     tmp = gen_load(s, OS_LONG, QREG_SP, 0, IS_USER(s));
   3029     tcg_gen_addi_i32(QREG_SP, QREG_SP, 4);
   3030     gen_jmp(s, tmp);
   3031 }
   3032 
   3033 DISAS_INSN(jump)
   3034 {
   3035     TCGv tmp;
   3036 
   3037     /*
   3038      * Load the target address first to ensure correct exception
   3039      * behavior.
   3040      */
   3041     tmp = gen_lea(env, s, insn, OS_LONG);
   3042     if (IS_NULL_QREG(tmp)) {
   3043         gen_addr_fault(s);
   3044         return;
   3045     }
   3046     if ((insn & 0x40) == 0) {
   3047         /* jsr */
   3048         gen_push(s, tcg_const_i32(s->pc));
   3049     }
   3050     gen_jmp(s, tmp);
   3051 }
   3052 
   3053 DISAS_INSN(addsubq)
   3054 {
   3055     TCGv src;
   3056     TCGv dest;
   3057     TCGv val;
   3058     int imm;
   3059     TCGv addr;
   3060     int opsize;
   3061 
   3062     if ((insn & 070) == 010) {
   3063         /* Operation on address register is always long.  */
   3064         opsize = OS_LONG;
   3065     } else {
   3066         opsize = insn_opsize(insn);
   3067     }
   3068     SRC_EA(env, src, opsize, 1, &addr);
   3069     imm = (insn >> 9) & 7;
   3070     if (imm == 0) {
   3071         imm = 8;
   3072     }
   3073     val = tcg_const_i32(imm);
   3074     dest = tcg_temp_new();
   3075     tcg_gen_mov_i32(dest, src);
   3076     if ((insn & 0x38) == 0x08) {
   3077         /*
   3078          * Don't update condition codes if the destination is an
   3079          * address register.
   3080          */
   3081         if (insn & 0x0100) {
   3082             tcg_gen_sub_i32(dest, dest, val);
   3083         } else {
   3084             tcg_gen_add_i32(dest, dest, val);
   3085         }
   3086     } else {
   3087         if (insn & 0x0100) {
   3088             tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, dest, val);
   3089             tcg_gen_sub_i32(dest, dest, val);
   3090             set_cc_op(s, CC_OP_SUBB + opsize);
   3091         } else {
   3092             tcg_gen_add_i32(dest, dest, val);
   3093             tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, dest, val);
   3094             set_cc_op(s, CC_OP_ADDB + opsize);
   3095         }
   3096         gen_update_cc_add(dest, val, opsize);
   3097     }
   3098     tcg_temp_free(val);
   3099     DEST_EA(env, insn, opsize, dest, &addr);
   3100     tcg_temp_free(dest);
   3101 }
   3102 
   3103 DISAS_INSN(branch)
   3104 {
   3105     int32_t offset;
   3106     uint32_t base;
   3107     int op;
   3108 
   3109     base = s->pc;
   3110     op = (insn >> 8) & 0xf;
   3111     offset = (int8_t)insn;
   3112     if (offset == 0) {
   3113         offset = (int16_t)read_im16(env, s);
   3114     } else if (offset == -1) {
   3115         offset = read_im32(env, s);
   3116     }
   3117     if (op == 1) {
   3118         /* bsr */
   3119         gen_push(s, tcg_const_i32(s->pc));
   3120     }
   3121     if (op > 1) {
   3122         /* Bcc */
   3123         TCGLabel *l1 = gen_new_label();
   3124         gen_jmpcc(s, ((insn >> 8) & 0xf) ^ 1, l1);
   3125         gen_jmp_tb(s, 1, base + offset, s->base.pc_next);
   3126         gen_set_label(l1);
   3127         gen_jmp_tb(s, 0, s->pc, s->base.pc_next);
   3128     } else {
   3129         /* Unconditional branch.  */
   3130         update_cc_op(s);
   3131         gen_jmp_tb(s, 0, base + offset, s->base.pc_next);
   3132     }
   3133 }
   3134 
   3135 DISAS_INSN(moveq)
   3136 {
   3137     tcg_gen_movi_i32(DREG(insn, 9), (int8_t)insn);
   3138     gen_logic_cc(s, DREG(insn, 9), OS_LONG);
   3139 }
   3140 
   3141 DISAS_INSN(mvzs)
   3142 {
   3143     int opsize;
   3144     TCGv src;
   3145     TCGv reg;
   3146 
   3147     if (insn & 0x40)
   3148         opsize = OS_WORD;
   3149     else
   3150         opsize = OS_BYTE;
   3151     SRC_EA(env, src, opsize, (insn & 0x80) == 0, NULL);
   3152     reg = DREG(insn, 9);
   3153     tcg_gen_mov_i32(reg, src);
   3154     gen_logic_cc(s, src, opsize);
   3155 }
   3156 
   3157 DISAS_INSN(or)
   3158 {
   3159     TCGv reg;
   3160     TCGv dest;
   3161     TCGv src;
   3162     TCGv addr;
   3163     int opsize;
   3164 
   3165     opsize = insn_opsize(insn);
   3166     reg = gen_extend(s, DREG(insn, 9), opsize, 0);
   3167     dest = tcg_temp_new();
   3168     if (insn & 0x100) {
   3169         SRC_EA(env, src, opsize, 0, &addr);
   3170         tcg_gen_or_i32(dest, src, reg);
   3171         DEST_EA(env, insn, opsize, dest, &addr);
   3172     } else {
   3173         SRC_EA(env, src, opsize, 0, NULL);
   3174         tcg_gen_or_i32(dest, src, reg);
   3175         gen_partset_reg(opsize, DREG(insn, 9), dest);
   3176     }
   3177     gen_logic_cc(s, dest, opsize);
   3178     tcg_temp_free(dest);
   3179 }
   3180 
   3181 DISAS_INSN(suba)
   3182 {
   3183     TCGv src;
   3184     TCGv reg;
   3185 
   3186     SRC_EA(env, src, (insn & 0x100) ? OS_LONG : OS_WORD, 1, NULL);
   3187     reg = AREG(insn, 9);
   3188     tcg_gen_sub_i32(reg, reg, src);
   3189 }
   3190 
   3191 static inline void gen_subx(DisasContext *s, TCGv src, TCGv dest, int opsize)
   3192 {
   3193     TCGv tmp;
   3194 
   3195     gen_flush_flags(s); /* compute old Z */
   3196 
   3197     /*
   3198      * Perform subtract with borrow.
   3199      * (X, N) = dest - (src + X);
   3200      */
   3201 
   3202     tmp = tcg_const_i32(0);
   3203     tcg_gen_add2_i32(QREG_CC_N, QREG_CC_X, src, tmp, QREG_CC_X, tmp);
   3204     tcg_gen_sub2_i32(QREG_CC_N, QREG_CC_X, dest, tmp, QREG_CC_N, QREG_CC_X);
   3205     gen_ext(QREG_CC_N, QREG_CC_N, opsize, 1);
   3206     tcg_gen_andi_i32(QREG_CC_X, QREG_CC_X, 1);
   3207 
   3208     /* Compute signed-overflow for subtract.  */
   3209 
   3210     tcg_gen_xor_i32(QREG_CC_V, QREG_CC_N, dest);
   3211     tcg_gen_xor_i32(tmp, dest, src);
   3212     tcg_gen_and_i32(QREG_CC_V, QREG_CC_V, tmp);
   3213     tcg_temp_free(tmp);
   3214 
   3215     /* Copy the rest of the results into place.  */
   3216     tcg_gen_or_i32(QREG_CC_Z, QREG_CC_Z, QREG_CC_N); /* !Z is sticky */
   3217     tcg_gen_mov_i32(QREG_CC_C, QREG_CC_X);
   3218 
   3219     set_cc_op(s, CC_OP_FLAGS);
   3220 
   3221     /* result is in QREG_CC_N */
   3222 }
   3223 
   3224 DISAS_INSN(subx_reg)
   3225 {
   3226     TCGv dest;
   3227     TCGv src;
   3228     int opsize;
   3229 
   3230     opsize = insn_opsize(insn);
   3231 
   3232     src = gen_extend(s, DREG(insn, 0), opsize, 1);
   3233     dest = gen_extend(s, DREG(insn, 9), opsize, 1);
   3234 
   3235     gen_subx(s, src, dest, opsize);
   3236 
   3237     gen_partset_reg(opsize, DREG(insn, 9), QREG_CC_N);
   3238 }
   3239 
   3240 DISAS_INSN(subx_mem)
   3241 {
   3242     TCGv src;
   3243     TCGv addr_src;
   3244     TCGv dest;
   3245     TCGv addr_dest;
   3246     int opsize;
   3247 
   3248     opsize = insn_opsize(insn);
   3249 
   3250     addr_src = AREG(insn, 0);
   3251     tcg_gen_subi_i32(addr_src, addr_src, opsize_bytes(opsize));
   3252     src = gen_load(s, opsize, addr_src, 1, IS_USER(s));
   3253 
   3254     addr_dest = AREG(insn, 9);
   3255     tcg_gen_subi_i32(addr_dest, addr_dest, opsize_bytes(opsize));
   3256     dest = gen_load(s, opsize, addr_dest, 1, IS_USER(s));
   3257 
   3258     gen_subx(s, src, dest, opsize);
   3259 
   3260     gen_store(s, opsize, addr_dest, QREG_CC_N, IS_USER(s));
   3261 
   3262     tcg_temp_free(dest);
   3263     tcg_temp_free(src);
   3264 }
   3265 
   3266 DISAS_INSN(mov3q)
   3267 {
   3268     TCGv src;
   3269     int val;
   3270 
   3271     val = (insn >> 9) & 7;
   3272     if (val == 0)
   3273         val = -1;
   3274     src = tcg_const_i32(val);
   3275     gen_logic_cc(s, src, OS_LONG);
   3276     DEST_EA(env, insn, OS_LONG, src, NULL);
   3277     tcg_temp_free(src);
   3278 }
   3279 
   3280 DISAS_INSN(cmp)
   3281 {
   3282     TCGv src;
   3283     TCGv reg;
   3284     int opsize;
   3285 
   3286     opsize = insn_opsize(insn);
   3287     SRC_EA(env, src, opsize, 1, NULL);
   3288     reg = gen_extend(s, DREG(insn, 9), opsize, 1);
   3289     gen_update_cc_cmp(s, reg, src, opsize);
   3290 }
   3291 
   3292 DISAS_INSN(cmpa)
   3293 {
   3294     int opsize;
   3295     TCGv src;
   3296     TCGv reg;
   3297 
   3298     if (insn & 0x100) {
   3299         opsize = OS_LONG;
   3300     } else {
   3301         opsize = OS_WORD;
   3302     }
   3303     SRC_EA(env, src, opsize, 1, NULL);
   3304     reg = AREG(insn, 9);
   3305     gen_update_cc_cmp(s, reg, src, OS_LONG);
   3306 }
   3307 
   3308 DISAS_INSN(cmpm)
   3309 {
   3310     int opsize = insn_opsize(insn);
   3311     TCGv src, dst;
   3312 
   3313     /* Post-increment load (mode 3) from Ay.  */
   3314     src = gen_ea_mode(env, s, 3, REG(insn, 0), opsize,
   3315                       NULL_QREG, NULL, EA_LOADS, IS_USER(s));
   3316     /* Post-increment load (mode 3) from Ax.  */
   3317     dst = gen_ea_mode(env, s, 3, REG(insn, 9), opsize,
   3318                       NULL_QREG, NULL, EA_LOADS, IS_USER(s));
   3319 
   3320     gen_update_cc_cmp(s, dst, src, opsize);
   3321 }
   3322 
   3323 DISAS_INSN(eor)
   3324 {
   3325     TCGv src;
   3326     TCGv dest;
   3327     TCGv addr;
   3328     int opsize;
   3329 
   3330     opsize = insn_opsize(insn);
   3331 
   3332     SRC_EA(env, src, opsize, 0, &addr);
   3333     dest = tcg_temp_new();
   3334     tcg_gen_xor_i32(dest, src, DREG(insn, 9));
   3335     gen_logic_cc(s, dest, opsize);
   3336     DEST_EA(env, insn, opsize, dest, &addr);
   3337     tcg_temp_free(dest);
   3338 }
   3339 
   3340 static void do_exg(TCGv reg1, TCGv reg2)
   3341 {
   3342     TCGv temp = tcg_temp_new();
   3343     tcg_gen_mov_i32(temp, reg1);
   3344     tcg_gen_mov_i32(reg1, reg2);
   3345     tcg_gen_mov_i32(reg2, temp);
   3346     tcg_temp_free(temp);
   3347 }
   3348 
   3349 DISAS_INSN(exg_dd)
   3350 {
   3351     /* exchange Dx and Dy */
   3352     do_exg(DREG(insn, 9), DREG(insn, 0));
   3353 }
   3354 
   3355 DISAS_INSN(exg_aa)
   3356 {
   3357     /* exchange Ax and Ay */
   3358     do_exg(AREG(insn, 9), AREG(insn, 0));
   3359 }
   3360 
   3361 DISAS_INSN(exg_da)
   3362 {
   3363     /* exchange Dx and Ay */
   3364     do_exg(DREG(insn, 9), AREG(insn, 0));
   3365 }
   3366 
   3367 DISAS_INSN(and)
   3368 {
   3369     TCGv src;
   3370     TCGv reg;
   3371     TCGv dest;
   3372     TCGv addr;
   3373     int opsize;
   3374 
   3375     dest = tcg_temp_new();
   3376 
   3377     opsize = insn_opsize(insn);
   3378     reg = DREG(insn, 9);
   3379     if (insn & 0x100) {
   3380         SRC_EA(env, src, opsize, 0, &addr);
   3381         tcg_gen_and_i32(dest, src, reg);
   3382         DEST_EA(env, insn, opsize, dest, &addr);
   3383     } else {
   3384         SRC_EA(env, src, opsize, 0, NULL);
   3385         tcg_gen_and_i32(dest, src, reg);
   3386         gen_partset_reg(opsize, reg, dest);
   3387     }
   3388     gen_logic_cc(s, dest, opsize);
   3389     tcg_temp_free(dest);
   3390 }
   3391 
   3392 DISAS_INSN(adda)
   3393 {
   3394     TCGv src;
   3395     TCGv reg;
   3396 
   3397     SRC_EA(env, src, (insn & 0x100) ? OS_LONG : OS_WORD, 1, NULL);
   3398     reg = AREG(insn, 9);
   3399     tcg_gen_add_i32(reg, reg, src);
   3400 }
   3401 
   3402 static inline void gen_addx(DisasContext *s, TCGv src, TCGv dest, int opsize)
   3403 {
   3404     TCGv tmp;
   3405 
   3406     gen_flush_flags(s); /* compute old Z */
   3407 
   3408     /*
   3409      * Perform addition with carry.
   3410      * (X, N) = src + dest + X;
   3411      */
   3412 
   3413     tmp = tcg_const_i32(0);
   3414     tcg_gen_add2_i32(QREG_CC_N, QREG_CC_X, QREG_CC_X, tmp, dest, tmp);
   3415     tcg_gen_add2_i32(QREG_CC_N, QREG_CC_X, QREG_CC_N, QREG_CC_X, src, tmp);
   3416     gen_ext(QREG_CC_N, QREG_CC_N, opsize, 1);
   3417 
   3418     /* Compute signed-overflow for addition.  */
   3419 
   3420     tcg_gen_xor_i32(QREG_CC_V, QREG_CC_N, src);
   3421     tcg_gen_xor_i32(tmp, dest, src);
   3422     tcg_gen_andc_i32(QREG_CC_V, QREG_CC_V, tmp);
   3423     tcg_temp_free(tmp);
   3424 
   3425     /* Copy the rest of the results into place.  */
   3426     tcg_gen_or_i32(QREG_CC_Z, QREG_CC_Z, QREG_CC_N); /* !Z is sticky */
   3427     tcg_gen_mov_i32(QREG_CC_C, QREG_CC_X);
   3428 
   3429     set_cc_op(s, CC_OP_FLAGS);
   3430 
   3431     /* result is in QREG_CC_N */
   3432 }
   3433 
   3434 DISAS_INSN(addx_reg)
   3435 {
   3436     TCGv dest;
   3437     TCGv src;
   3438     int opsize;
   3439 
   3440     opsize = insn_opsize(insn);
   3441 
   3442     dest = gen_extend(s, DREG(insn, 9), opsize, 1);
   3443     src = gen_extend(s, DREG(insn, 0), opsize, 1);
   3444 
   3445     gen_addx(s, src, dest, opsize);
   3446 
   3447     gen_partset_reg(opsize, DREG(insn, 9), QREG_CC_N);
   3448 }
   3449 
   3450 DISAS_INSN(addx_mem)
   3451 {
   3452     TCGv src;
   3453     TCGv addr_src;
   3454     TCGv dest;
   3455     TCGv addr_dest;
   3456     int opsize;
   3457 
   3458     opsize = insn_opsize(insn);
   3459 
   3460     addr_src = AREG(insn, 0);
   3461     tcg_gen_subi_i32(addr_src, addr_src, opsize_bytes(opsize));
   3462     src = gen_load(s, opsize, addr_src, 1, IS_USER(s));
   3463 
   3464     addr_dest = AREG(insn, 9);
   3465     tcg_gen_subi_i32(addr_dest, addr_dest, opsize_bytes(opsize));
   3466     dest = gen_load(s, opsize, addr_dest, 1, IS_USER(s));
   3467 
   3468     gen_addx(s, src, dest, opsize);
   3469 
   3470     gen_store(s, opsize, addr_dest, QREG_CC_N, IS_USER(s));
   3471 
   3472     tcg_temp_free(dest);
   3473     tcg_temp_free(src);
   3474 }
   3475 
   3476 static inline void shift_im(DisasContext *s, uint16_t insn, int opsize)
   3477 {
   3478     int count = (insn >> 9) & 7;
   3479     int logical = insn & 8;
   3480     int left = insn & 0x100;
   3481     int bits = opsize_bytes(opsize) * 8;
   3482     TCGv reg = gen_extend(s, DREG(insn, 0), opsize, !logical);
   3483 
   3484     if (count == 0) {
   3485         count = 8;
   3486     }
   3487 
   3488     tcg_gen_movi_i32(QREG_CC_V, 0);
   3489     if (left) {
   3490         tcg_gen_shri_i32(QREG_CC_C, reg, bits - count);
   3491         tcg_gen_shli_i32(QREG_CC_N, reg, count);
   3492 
   3493         /*
   3494          * Note that ColdFire always clears V (done above),
   3495          * while M68000 sets if the most significant bit is changed at
   3496          * any time during the shift operation.
   3497          */
   3498         if (!logical && m68k_feature(s->env, M68K_FEATURE_M68K)) {
   3499             /* if shift count >= bits, V is (reg != 0) */
   3500             if (count >= bits) {
   3501                 tcg_gen_setcond_i32(TCG_COND_NE, QREG_CC_V, reg, QREG_CC_V);
   3502             } else {
   3503                 TCGv t0 = tcg_temp_new();
   3504                 tcg_gen_sari_i32(QREG_CC_V, reg, bits - 1);
   3505                 tcg_gen_sari_i32(t0, reg, bits - count - 1);
   3506                 tcg_gen_setcond_i32(TCG_COND_NE, QREG_CC_V, QREG_CC_V, t0);
   3507                 tcg_temp_free(t0);
   3508             }
   3509             tcg_gen_neg_i32(QREG_CC_V, QREG_CC_V);
   3510         }
   3511     } else {
   3512         tcg_gen_shri_i32(QREG_CC_C, reg, count - 1);
   3513         if (logical) {
   3514             tcg_gen_shri_i32(QREG_CC_N, reg, count);
   3515         } else {
   3516             tcg_gen_sari_i32(QREG_CC_N, reg, count);
   3517         }
   3518     }
   3519 
   3520     gen_ext(QREG_CC_N, QREG_CC_N, opsize, 1);
   3521     tcg_gen_andi_i32(QREG_CC_C, QREG_CC_C, 1);
   3522     tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N);
   3523     tcg_gen_mov_i32(QREG_CC_X, QREG_CC_C);
   3524 
   3525     gen_partset_reg(opsize, DREG(insn, 0), QREG_CC_N);
   3526     set_cc_op(s, CC_OP_FLAGS);
   3527 }
   3528 
   3529 static inline void shift_reg(DisasContext *s, uint16_t insn, int opsize)
   3530 {
   3531     int logical = insn & 8;
   3532     int left = insn & 0x100;
   3533     int bits = opsize_bytes(opsize) * 8;
   3534     TCGv reg = gen_extend(s, DREG(insn, 0), opsize, !logical);
   3535     TCGv s32;
   3536     TCGv_i64 t64, s64;
   3537 
   3538     t64 = tcg_temp_new_i64();
   3539     s64 = tcg_temp_new_i64();
   3540     s32 = tcg_temp_new();
   3541 
   3542     /*
   3543      * Note that m68k truncates the shift count modulo 64, not 32.
   3544      * In addition, a 64-bit shift makes it easy to find "the last
   3545      * bit shifted out", for the carry flag.
   3546      */
   3547     tcg_gen_andi_i32(s32, DREG(insn, 9), 63);
   3548     tcg_gen_extu_i32_i64(s64, s32);
   3549     tcg_gen_extu_i32_i64(t64, reg);
   3550 
   3551     /* Optimistically set V=0.  Also used as a zero source below.  */
   3552     tcg_gen_movi_i32(QREG_CC_V, 0);
   3553     if (left) {
   3554         tcg_gen_shl_i64(t64, t64, s64);
   3555 
   3556         if (opsize == OS_LONG) {
   3557             tcg_gen_extr_i64_i32(QREG_CC_N, QREG_CC_C, t64);
   3558             /* Note that C=0 if shift count is 0, and we get that for free.  */
   3559         } else {
   3560             TCGv zero = tcg_const_i32(0);
   3561             tcg_gen_extrl_i64_i32(QREG_CC_N, t64);
   3562             tcg_gen_shri_i32(QREG_CC_C, QREG_CC_N, bits);
   3563             tcg_gen_movcond_i32(TCG_COND_EQ, QREG_CC_C,
   3564                                 s32, zero, zero, QREG_CC_C);
   3565             tcg_temp_free(zero);
   3566         }
   3567         tcg_gen_andi_i32(QREG_CC_C, QREG_CC_C, 1);
   3568 
   3569         /* X = C, but only if the shift count was non-zero.  */
   3570         tcg_gen_movcond_i32(TCG_COND_NE, QREG_CC_X, s32, QREG_CC_V,
   3571                             QREG_CC_C, QREG_CC_X);
   3572 
   3573         /*
   3574          * M68000 sets V if the most significant bit is changed at
   3575          * any time during the shift operation.  Do this via creating
   3576          * an extension of the sign bit, comparing, and discarding
   3577          * the bits below the sign bit.  I.e.
   3578          *     int64_t s = (intN_t)reg;
   3579          *     int64_t t = (int64_t)(intN_t)reg << count;
   3580          *     V = ((s ^ t) & (-1 << (bits - 1))) != 0
   3581          */
   3582         if (!logical && m68k_feature(s->env, M68K_FEATURE_M68K)) {
   3583             TCGv_i64 tt = tcg_const_i64(32);
   3584             /* if shift is greater than 32, use 32 */
   3585             tcg_gen_movcond_i64(TCG_COND_GT, s64, s64, tt, tt, s64);
   3586             tcg_temp_free_i64(tt);
   3587             /* Sign extend the input to 64 bits; re-do the shift.  */
   3588             tcg_gen_ext_i32_i64(t64, reg);
   3589             tcg_gen_shl_i64(s64, t64, s64);
   3590             /* Clear all bits that are unchanged.  */
   3591             tcg_gen_xor_i64(t64, t64, s64);
   3592             /* Ignore the bits below the sign bit.  */
   3593             tcg_gen_andi_i64(t64, t64, -1ULL << (bits - 1));
   3594             /* If any bits remain set, we have overflow.  */
   3595             tcg_gen_setcondi_i64(TCG_COND_NE, t64, t64, 0);
   3596             tcg_gen_extrl_i64_i32(QREG_CC_V, t64);
   3597             tcg_gen_neg_i32(QREG_CC_V, QREG_CC_V);
   3598         }
   3599     } else {
   3600         tcg_gen_shli_i64(t64, t64, 32);
   3601         if (logical) {
   3602             tcg_gen_shr_i64(t64, t64, s64);
   3603         } else {
   3604             tcg_gen_sar_i64(t64, t64, s64);
   3605         }
   3606         tcg_gen_extr_i64_i32(QREG_CC_C, QREG_CC_N, t64);
   3607 
   3608         /* Note that C=0 if shift count is 0, and we get that for free.  */
   3609         tcg_gen_shri_i32(QREG_CC_C, QREG_CC_C, 31);
   3610 
   3611         /* X = C, but only if the shift count was non-zero.  */
   3612         tcg_gen_movcond_i32(TCG_COND_NE, QREG_CC_X, s32, QREG_CC_V,
   3613                             QREG_CC_C, QREG_CC_X);
   3614     }
   3615     gen_ext(QREG_CC_N, QREG_CC_N, opsize, 1);
   3616     tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N);
   3617 
   3618     tcg_temp_free(s32);
   3619     tcg_temp_free_i64(s64);
   3620     tcg_temp_free_i64(t64);
   3621 
   3622     /* Write back the result.  */
   3623     gen_partset_reg(opsize, DREG(insn, 0), QREG_CC_N);
   3624     set_cc_op(s, CC_OP_FLAGS);
   3625 }
   3626 
   3627 DISAS_INSN(shift8_im)
   3628 {
   3629     shift_im(s, insn, OS_BYTE);
   3630 }
   3631 
   3632 DISAS_INSN(shift16_im)
   3633 {
   3634     shift_im(s, insn, OS_WORD);
   3635 }
   3636 
   3637 DISAS_INSN(shift_im)
   3638 {
   3639     shift_im(s, insn, OS_LONG);
   3640 }
   3641 
   3642 DISAS_INSN(shift8_reg)
   3643 {
   3644     shift_reg(s, insn, OS_BYTE);
   3645 }
   3646 
   3647 DISAS_INSN(shift16_reg)
   3648 {
   3649     shift_reg(s, insn, OS_WORD);
   3650 }
   3651 
   3652 DISAS_INSN(shift_reg)
   3653 {
   3654     shift_reg(s, insn, OS_LONG);
   3655 }
   3656 
   3657 DISAS_INSN(shift_mem)
   3658 {
   3659     int logical = insn & 8;
   3660     int left = insn & 0x100;
   3661     TCGv src;
   3662     TCGv addr;
   3663 
   3664     SRC_EA(env, src, OS_WORD, !logical, &addr);
   3665     tcg_gen_movi_i32(QREG_CC_V, 0);
   3666     if (left) {
   3667         tcg_gen_shri_i32(QREG_CC_C, src, 15);
   3668         tcg_gen_shli_i32(QREG_CC_N, src, 1);
   3669 
   3670         /*
   3671          * Note that ColdFire always clears V,
   3672          * while M68000 sets if the most significant bit is changed at
   3673          * any time during the shift operation
   3674          */
   3675         if (!logical && m68k_feature(s->env, M68K_FEATURE_M68K)) {
   3676             src = gen_extend(s, src, OS_WORD, 1);
   3677             tcg_gen_xor_i32(QREG_CC_V, QREG_CC_N, src);
   3678         }
   3679     } else {
   3680         tcg_gen_mov_i32(QREG_CC_C, src);
   3681         if (logical) {
   3682             tcg_gen_shri_i32(QREG_CC_N, src, 1);
   3683         } else {
   3684             tcg_gen_sari_i32(QREG_CC_N, src, 1);
   3685         }
   3686     }
   3687 
   3688     gen_ext(QREG_CC_N, QREG_CC_N, OS_WORD, 1);
   3689     tcg_gen_andi_i32(QREG_CC_C, QREG_CC_C, 1);
   3690     tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N);
   3691     tcg_gen_mov_i32(QREG_CC_X, QREG_CC_C);
   3692 
   3693     DEST_EA(env, insn, OS_WORD, QREG_CC_N, &addr);
   3694     set_cc_op(s, CC_OP_FLAGS);
   3695 }
   3696 
   3697 static void rotate(TCGv reg, TCGv shift, int left, int size)
   3698 {
   3699     switch (size) {
   3700     case 8:
   3701         /* Replicate the 8-bit input so that a 32-bit rotate works.  */
   3702         tcg_gen_ext8u_i32(reg, reg);
   3703         tcg_gen_muli_i32(reg, reg, 0x01010101);
   3704         goto do_long;
   3705     case 16:
   3706         /* Replicate the 16-bit input so that a 32-bit rotate works.  */
   3707         tcg_gen_deposit_i32(reg, reg, reg, 16, 16);
   3708         goto do_long;
   3709     do_long:
   3710     default:
   3711         if (left) {
   3712             tcg_gen_rotl_i32(reg, reg, shift);
   3713         } else {
   3714             tcg_gen_rotr_i32(reg, reg, shift);
   3715         }
   3716     }
   3717 
   3718     /* compute flags */
   3719 
   3720     switch (size) {
   3721     case 8:
   3722         tcg_gen_ext8s_i32(reg, reg);
   3723         break;
   3724     case 16:
   3725         tcg_gen_ext16s_i32(reg, reg);
   3726         break;
   3727     default:
   3728         break;
   3729     }
   3730 
   3731     /* QREG_CC_X is not affected */
   3732 
   3733     tcg_gen_mov_i32(QREG_CC_N, reg);
   3734     tcg_gen_mov_i32(QREG_CC_Z, reg);
   3735 
   3736     if (left) {
   3737         tcg_gen_andi_i32(QREG_CC_C, reg, 1);
   3738     } else {
   3739         tcg_gen_shri_i32(QREG_CC_C, reg, 31);
   3740     }
   3741 
   3742     tcg_gen_movi_i32(QREG_CC_V, 0); /* always cleared */
   3743 }
   3744 
   3745 static void rotate_x_flags(TCGv reg, TCGv X, int size)
   3746 {
   3747     switch (size) {
   3748     case 8:
   3749         tcg_gen_ext8s_i32(reg, reg);
   3750         break;
   3751     case 16:
   3752         tcg_gen_ext16s_i32(reg, reg);
   3753         break;
   3754     default:
   3755         break;
   3756     }
   3757     tcg_gen_mov_i32(QREG_CC_N, reg);
   3758     tcg_gen_mov_i32(QREG_CC_Z, reg);
   3759     tcg_gen_mov_i32(QREG_CC_X, X);
   3760     tcg_gen_mov_i32(QREG_CC_C, X);
   3761     tcg_gen_movi_i32(QREG_CC_V, 0);
   3762 }
   3763 
   3764 /* Result of rotate_x() is valid if 0 <= shift <= size */
   3765 static TCGv rotate_x(TCGv reg, TCGv shift, int left, int size)
   3766 {
   3767     TCGv X, shl, shr, shx, sz, zero;
   3768 
   3769     sz = tcg_const_i32(size);
   3770 
   3771     shr = tcg_temp_new();
   3772     shl = tcg_temp_new();
   3773     shx = tcg_temp_new();
   3774     if (left) {
   3775         tcg_gen_mov_i32(shl, shift);      /* shl = shift */
   3776         tcg_gen_movi_i32(shr, size + 1);
   3777         tcg_gen_sub_i32(shr, shr, shift); /* shr = size + 1 - shift */
   3778         tcg_gen_subi_i32(shx, shift, 1);  /* shx = shift - 1 */
   3779         /* shx = shx < 0 ? size : shx; */
   3780         zero = tcg_const_i32(0);
   3781         tcg_gen_movcond_i32(TCG_COND_LT, shx, shx, zero, sz, shx);
   3782         tcg_temp_free(zero);
   3783     } else {
   3784         tcg_gen_mov_i32(shr, shift);      /* shr = shift */
   3785         tcg_gen_movi_i32(shl, size + 1);
   3786         tcg_gen_sub_i32(shl, shl, shift); /* shl = size + 1 - shift */
   3787         tcg_gen_sub_i32(shx, sz, shift); /* shx = size - shift */
   3788     }
   3789     tcg_temp_free_i32(sz);
   3790 
   3791     /* reg = (reg << shl) | (reg >> shr) | (x << shx); */
   3792 
   3793     tcg_gen_shl_i32(shl, reg, shl);
   3794     tcg_gen_shr_i32(shr, reg, shr);
   3795     tcg_gen_or_i32(reg, shl, shr);
   3796     tcg_temp_free(shl);
   3797     tcg_temp_free(shr);
   3798     tcg_gen_shl_i32(shx, QREG_CC_X, shx);
   3799     tcg_gen_or_i32(reg, reg, shx);
   3800     tcg_temp_free(shx);
   3801 
   3802     /* X = (reg >> size) & 1 */
   3803 
   3804     X = tcg_temp_new();
   3805     tcg_gen_extract_i32(X, reg, size, 1);
   3806 
   3807     return X;
   3808 }
   3809 
   3810 /* Result of rotate32_x() is valid if 0 <= shift < 33 */
   3811 static TCGv rotate32_x(TCGv reg, TCGv shift, int left)
   3812 {
   3813     TCGv_i64 t0, shift64;
   3814     TCGv X, lo, hi, zero;
   3815 
   3816     shift64 = tcg_temp_new_i64();
   3817     tcg_gen_extu_i32_i64(shift64, shift);
   3818 
   3819     t0 = tcg_temp_new_i64();
   3820 
   3821     X = tcg_temp_new();
   3822     lo = tcg_temp_new();
   3823     hi = tcg_temp_new();
   3824 
   3825     if (left) {
   3826         /* create [reg:X:..] */
   3827 
   3828         tcg_gen_shli_i32(lo, QREG_CC_X, 31);
   3829         tcg_gen_concat_i32_i64(t0, lo, reg);
   3830 
   3831         /* rotate */
   3832 
   3833         tcg_gen_rotl_i64(t0, t0, shift64);
   3834         tcg_temp_free_i64(shift64);
   3835 
   3836         /* result is [reg:..:reg:X] */
   3837 
   3838         tcg_gen_extr_i64_i32(lo, hi, t0);
   3839         tcg_gen_andi_i32(X, lo, 1);
   3840 
   3841         tcg_gen_shri_i32(lo, lo, 1);
   3842     } else {
   3843         /* create [..:X:reg] */
   3844 
   3845         tcg_gen_concat_i32_i64(t0, reg, QREG_CC_X);
   3846 
   3847         tcg_gen_rotr_i64(t0, t0, shift64);
   3848         tcg_temp_free_i64(shift64);
   3849 
   3850         /* result is value: [X:reg:..:reg] */
   3851 
   3852         tcg_gen_extr_i64_i32(lo, hi, t0);
   3853 
   3854         /* extract X */
   3855 
   3856         tcg_gen_shri_i32(X, hi, 31);
   3857 
   3858         /* extract result */
   3859 
   3860         tcg_gen_shli_i32(hi, hi, 1);
   3861     }
   3862     tcg_temp_free_i64(t0);
   3863     tcg_gen_or_i32(lo, lo, hi);
   3864     tcg_temp_free(hi);
   3865 
   3866     /* if shift == 0, register and X are not affected */
   3867 
   3868     zero = tcg_const_i32(0);
   3869     tcg_gen_movcond_i32(TCG_COND_EQ, X, shift, zero, QREG_CC_X, X);
   3870     tcg_gen_movcond_i32(TCG_COND_EQ, reg, shift, zero, reg, lo);
   3871     tcg_temp_free(zero);
   3872     tcg_temp_free(lo);
   3873 
   3874     return X;
   3875 }
   3876 
   3877 DISAS_INSN(rotate_im)
   3878 {
   3879     TCGv shift;
   3880     int tmp;
   3881     int left = (insn & 0x100);
   3882 
   3883     tmp = (insn >> 9) & 7;
   3884     if (tmp == 0) {
   3885         tmp = 8;
   3886     }
   3887 
   3888     shift = tcg_const_i32(tmp);
   3889     if (insn & 8) {
   3890         rotate(DREG(insn, 0), shift, left, 32);
   3891     } else {
   3892         TCGv X = rotate32_x(DREG(insn, 0), shift, left);
   3893         rotate_x_flags(DREG(insn, 0), X, 32);
   3894         tcg_temp_free(X);
   3895     }
   3896     tcg_temp_free(shift);
   3897 
   3898     set_cc_op(s, CC_OP_FLAGS);
   3899 }
   3900 
   3901 DISAS_INSN(rotate8_im)
   3902 {
   3903     int left = (insn & 0x100);
   3904     TCGv reg;
   3905     TCGv shift;
   3906     int tmp;
   3907 
   3908     reg = gen_extend(s, DREG(insn, 0), OS_BYTE, 0);
   3909 
   3910     tmp = (insn >> 9) & 7;
   3911     if (tmp == 0) {
   3912         tmp = 8;
   3913     }
   3914 
   3915     shift = tcg_const_i32(tmp);
   3916     if (insn & 8) {
   3917         rotate(reg, shift, left, 8);
   3918     } else {
   3919         TCGv X = rotate_x(reg, shift, left, 8);
   3920         rotate_x_flags(reg, X, 8);
   3921         tcg_temp_free(X);
   3922     }
   3923     tcg_temp_free(shift);
   3924     gen_partset_reg(OS_BYTE, DREG(insn, 0), reg);
   3925     set_cc_op(s, CC_OP_FLAGS);
   3926 }
   3927 
   3928 DISAS_INSN(rotate16_im)
   3929 {
   3930     int left = (insn & 0x100);
   3931     TCGv reg;
   3932     TCGv shift;
   3933     int tmp;
   3934 
   3935     reg = gen_extend(s, DREG(insn, 0), OS_WORD, 0);
   3936     tmp = (insn >> 9) & 7;
   3937     if (tmp == 0) {
   3938         tmp = 8;
   3939     }
   3940 
   3941     shift = tcg_const_i32(tmp);
   3942     if (insn & 8) {
   3943         rotate(reg, shift, left, 16);
   3944     } else {
   3945         TCGv X = rotate_x(reg, shift, left, 16);
   3946         rotate_x_flags(reg, X, 16);
   3947         tcg_temp_free(X);
   3948     }
   3949     tcg_temp_free(shift);
   3950     gen_partset_reg(OS_WORD, DREG(insn, 0), reg);
   3951     set_cc_op(s, CC_OP_FLAGS);
   3952 }
   3953 
   3954 DISAS_INSN(rotate_reg)
   3955 {
   3956     TCGv reg;
   3957     TCGv src;
   3958     TCGv t0, t1;
   3959     int left = (insn & 0x100);
   3960 
   3961     reg = DREG(insn, 0);
   3962     src = DREG(insn, 9);
   3963     /* shift in [0..63] */
   3964     t0 = tcg_temp_new();
   3965     tcg_gen_andi_i32(t0, src, 63);
   3966     t1 = tcg_temp_new_i32();
   3967     if (insn & 8) {
   3968         tcg_gen_andi_i32(t1, src, 31);
   3969         rotate(reg, t1, left, 32);
   3970         /* if shift == 0, clear C */
   3971         tcg_gen_movcond_i32(TCG_COND_EQ, QREG_CC_C,
   3972                             t0, QREG_CC_V /* 0 */,
   3973                             QREG_CC_V /* 0 */, QREG_CC_C);
   3974     } else {
   3975         TCGv X;
   3976         /* modulo 33 */
   3977         tcg_gen_movi_i32(t1, 33);
   3978         tcg_gen_remu_i32(t1, t0, t1);
   3979         X = rotate32_x(DREG(insn, 0), t1, left);
   3980         rotate_x_flags(DREG(insn, 0), X, 32);
   3981         tcg_temp_free(X);
   3982     }
   3983     tcg_temp_free(t1);
   3984     tcg_temp_free(t0);
   3985     set_cc_op(s, CC_OP_FLAGS);
   3986 }
   3987 
   3988 DISAS_INSN(rotate8_reg)
   3989 {
   3990     TCGv reg;
   3991     TCGv src;
   3992     TCGv t0, t1;
   3993     int left = (insn & 0x100);
   3994 
   3995     reg = gen_extend(s, DREG(insn, 0), OS_BYTE, 0);
   3996     src = DREG(insn, 9);
   3997     /* shift in [0..63] */
   3998     t0 = tcg_temp_new_i32();
   3999     tcg_gen_andi_i32(t0, src, 63);
   4000     t1 = tcg_temp_new_i32();
   4001     if (insn & 8) {
   4002         tcg_gen_andi_i32(t1, src, 7);
   4003         rotate(reg, t1, left, 8);
   4004         /* if shift == 0, clear C */
   4005         tcg_gen_movcond_i32(TCG_COND_EQ, QREG_CC_C,
   4006                             t0, QREG_CC_V /* 0 */,
   4007                             QREG_CC_V /* 0 */, QREG_CC_C);
   4008     } else {
   4009         TCGv X;
   4010         /* modulo 9 */
   4011         tcg_gen_movi_i32(t1, 9);
   4012         tcg_gen_remu_i32(t1, t0, t1);
   4013         X = rotate_x(reg, t1, left, 8);
   4014         rotate_x_flags(reg, X, 8);
   4015         tcg_temp_free(X);
   4016     }
   4017     tcg_temp_free(t1);
   4018     tcg_temp_free(t0);
   4019     gen_partset_reg(OS_BYTE, DREG(insn, 0), reg);
   4020     set_cc_op(s, CC_OP_FLAGS);
   4021 }
   4022 
   4023 DISAS_INSN(rotate16_reg)
   4024 {
   4025     TCGv reg;
   4026     TCGv src;
   4027     TCGv t0, t1;
   4028     int left = (insn & 0x100);
   4029 
   4030     reg = gen_extend(s, DREG(insn, 0), OS_WORD, 0);
   4031     src = DREG(insn, 9);
   4032     /* shift in [0..63] */
   4033     t0 = tcg_temp_new_i32();
   4034     tcg_gen_andi_i32(t0, src, 63);
   4035     t1 = tcg_temp_new_i32();
   4036     if (insn & 8) {
   4037         tcg_gen_andi_i32(t1, src, 15);
   4038         rotate(reg, t1, left, 16);
   4039         /* if shift == 0, clear C */
   4040         tcg_gen_movcond_i32(TCG_COND_EQ, QREG_CC_C,
   4041                             t0, QREG_CC_V /* 0 */,
   4042                             QREG_CC_V /* 0 */, QREG_CC_C);
   4043     } else {
   4044         TCGv X;
   4045         /* modulo 17 */
   4046         tcg_gen_movi_i32(t1, 17);
   4047         tcg_gen_remu_i32(t1, t0, t1);
   4048         X = rotate_x(reg, t1, left, 16);
   4049         rotate_x_flags(reg, X, 16);
   4050         tcg_temp_free(X);
   4051     }
   4052     tcg_temp_free(t1);
   4053     tcg_temp_free(t0);
   4054     gen_partset_reg(OS_WORD, DREG(insn, 0), reg);
   4055     set_cc_op(s, CC_OP_FLAGS);
   4056 }
   4057 
   4058 DISAS_INSN(rotate_mem)
   4059 {
   4060     TCGv src;
   4061     TCGv addr;
   4062     TCGv shift;
   4063     int left = (insn & 0x100);
   4064 
   4065     SRC_EA(env, src, OS_WORD, 0, &addr);
   4066 
   4067     shift = tcg_const_i32(1);
   4068     if (insn & 0x0200) {
   4069         rotate(src, shift, left, 16);
   4070     } else {
   4071         TCGv X = rotate_x(src, shift, left, 16);
   4072         rotate_x_flags(src, X, 16);
   4073         tcg_temp_free(X);
   4074     }
   4075     tcg_temp_free(shift);
   4076     DEST_EA(env, insn, OS_WORD, src, &addr);
   4077     set_cc_op(s, CC_OP_FLAGS);
   4078 }
   4079 
   4080 DISAS_INSN(bfext_reg)
   4081 {
   4082     int ext = read_im16(env, s);
   4083     int is_sign = insn & 0x200;
   4084     TCGv src = DREG(insn, 0);
   4085     TCGv dst = DREG(ext, 12);
   4086     int len = ((extract32(ext, 0, 5) - 1) & 31) + 1;
   4087     int ofs = extract32(ext, 6, 5);  /* big bit-endian */
   4088     int pos = 32 - ofs - len;        /* little bit-endian */
   4089     TCGv tmp = tcg_temp_new();
   4090     TCGv shift;
   4091 
   4092     /*
   4093      * In general, we're going to rotate the field so that it's at the
   4094      * top of the word and then right-shift by the complement of the
   4095      * width to extend the field.
   4096      */
   4097     if (ext & 0x20) {
   4098         /* Variable width.  */
   4099         if (ext & 0x800) {
   4100             /* Variable offset.  */
   4101             tcg_gen_andi_i32(tmp, DREG(ext, 6), 31);
   4102             tcg_gen_rotl_i32(tmp, src, tmp);
   4103         } else {
   4104             tcg_gen_rotli_i32(tmp, src, ofs);
   4105         }
   4106 
   4107         shift = tcg_temp_new();
   4108         tcg_gen_neg_i32(shift, DREG(ext, 0));
   4109         tcg_gen_andi_i32(shift, shift, 31);
   4110         tcg_gen_sar_i32(QREG_CC_N, tmp, shift);
   4111         if (is_sign) {
   4112             tcg_gen_mov_i32(dst, QREG_CC_N);
   4113         } else {
   4114             tcg_gen_shr_i32(dst, tmp, shift);
   4115         }
   4116         tcg_temp_free(shift);
   4117     } else {
   4118         /* Immediate width.  */
   4119         if (ext & 0x800) {
   4120             /* Variable offset */
   4121             tcg_gen_andi_i32(tmp, DREG(ext, 6), 31);
   4122             tcg_gen_rotl_i32(tmp, src, tmp);
   4123             src = tmp;
   4124             pos = 32 - len;
   4125         } else {
   4126             /*
   4127              * Immediate offset.  If the field doesn't wrap around the
   4128              * end of the word, rely on (s)extract completely.
   4129              */
   4130             if (pos < 0) {
   4131                 tcg_gen_rotli_i32(tmp, src, ofs);
   4132                 src = tmp;
   4133                 pos = 32 - len;
   4134             }
   4135         }
   4136 
   4137         tcg_gen_sextract_i32(QREG_CC_N, src, pos, len);
   4138         if (is_sign) {
   4139             tcg_gen_mov_i32(dst, QREG_CC_N);
   4140         } else {
   4141             tcg_gen_extract_i32(dst, src, pos, len);
   4142         }
   4143     }
   4144 
   4145     tcg_temp_free(tmp);
   4146     set_cc_op(s, CC_OP_LOGIC);
   4147 }
   4148 
   4149 DISAS_INSN(bfext_mem)
   4150 {
   4151     int ext = read_im16(env, s);
   4152     int is_sign = insn & 0x200;
   4153     TCGv dest = DREG(ext, 12);
   4154     TCGv addr, len, ofs;
   4155 
   4156     addr = gen_lea(env, s, insn, OS_UNSIZED);
   4157     if (IS_NULL_QREG(addr)) {
   4158         gen_addr_fault(s);
   4159         return;
   4160     }
   4161 
   4162     if (ext & 0x20) {
   4163         len = DREG(ext, 0);
   4164     } else {
   4165         len = tcg_const_i32(extract32(ext, 0, 5));
   4166     }
   4167     if (ext & 0x800) {
   4168         ofs = DREG(ext, 6);
   4169     } else {
   4170         ofs = tcg_const_i32(extract32(ext, 6, 5));
   4171     }
   4172 
   4173     if (is_sign) {
   4174         gen_helper_bfexts_mem(dest, cpu_env, addr, ofs, len);
   4175         tcg_gen_mov_i32(QREG_CC_N, dest);
   4176     } else {
   4177         TCGv_i64 tmp = tcg_temp_new_i64();
   4178         gen_helper_bfextu_mem(tmp, cpu_env, addr, ofs, len);
   4179         tcg_gen_extr_i64_i32(dest, QREG_CC_N, tmp);
   4180         tcg_temp_free_i64(tmp);
   4181     }
   4182     set_cc_op(s, CC_OP_LOGIC);
   4183 
   4184     if (!(ext & 0x20)) {
   4185         tcg_temp_free(len);
   4186     }
   4187     if (!(ext & 0x800)) {
   4188         tcg_temp_free(ofs);
   4189     }
   4190 }
   4191 
   4192 DISAS_INSN(bfop_reg)
   4193 {
   4194     int ext = read_im16(env, s);
   4195     TCGv src = DREG(insn, 0);
   4196     int len = ((extract32(ext, 0, 5) - 1) & 31) + 1;
   4197     int ofs = extract32(ext, 6, 5);  /* big bit-endian */
   4198     TCGv mask, tofs, tlen;
   4199 
   4200     tofs = NULL;
   4201     tlen = NULL;
   4202     if ((insn & 0x0f00) == 0x0d00) { /* bfffo */
   4203         tofs = tcg_temp_new();
   4204         tlen = tcg_temp_new();
   4205     }
   4206 
   4207     if ((ext & 0x820) == 0) {
   4208         /* Immediate width and offset.  */
   4209         uint32_t maski = 0x7fffffffu >> (len - 1);
   4210         if (ofs + len <= 32) {
   4211             tcg_gen_shli_i32(QREG_CC_N, src, ofs);
   4212         } else {
   4213             tcg_gen_rotli_i32(QREG_CC_N, src, ofs);
   4214         }
   4215         tcg_gen_andi_i32(QREG_CC_N, QREG_CC_N, ~maski);
   4216         mask = tcg_const_i32(ror32(maski, ofs));
   4217         if (tofs) {
   4218             tcg_gen_movi_i32(tofs, ofs);
   4219             tcg_gen_movi_i32(tlen, len);
   4220         }
   4221     } else {
   4222         TCGv tmp = tcg_temp_new();
   4223         if (ext & 0x20) {
   4224             /* Variable width */
   4225             tcg_gen_subi_i32(tmp, DREG(ext, 0), 1);
   4226             tcg_gen_andi_i32(tmp, tmp, 31);
   4227             mask = tcg_const_i32(0x7fffffffu);
   4228             tcg_gen_shr_i32(mask, mask, tmp);
   4229             if (tlen) {
   4230                 tcg_gen_addi_i32(tlen, tmp, 1);
   4231             }
   4232         } else {
   4233             /* Immediate width */
   4234             mask = tcg_const_i32(0x7fffffffu >> (len - 1));
   4235             if (tlen) {
   4236                 tcg_gen_movi_i32(tlen, len);
   4237             }
   4238         }
   4239         if (ext & 0x800) {
   4240             /* Variable offset */
   4241             tcg_gen_andi_i32(tmp, DREG(ext, 6), 31);
   4242             tcg_gen_rotl_i32(QREG_CC_N, src, tmp);
   4243             tcg_gen_andc_i32(QREG_CC_N, QREG_CC_N, mask);
   4244             tcg_gen_rotr_i32(mask, mask, tmp);
   4245             if (tofs) {
   4246                 tcg_gen_mov_i32(tofs, tmp);
   4247             }
   4248         } else {
   4249             /* Immediate offset (and variable width) */
   4250             tcg_gen_rotli_i32(QREG_CC_N, src, ofs);
   4251             tcg_gen_andc_i32(QREG_CC_N, QREG_CC_N, mask);
   4252             tcg_gen_rotri_i32(mask, mask, ofs);
   4253             if (tofs) {
   4254                 tcg_gen_movi_i32(tofs, ofs);
   4255             }
   4256         }
   4257         tcg_temp_free(tmp);
   4258     }
   4259     set_cc_op(s, CC_OP_LOGIC);
   4260 
   4261     switch (insn & 0x0f00) {
   4262     case 0x0a00: /* bfchg */
   4263         tcg_gen_eqv_i32(src, src, mask);
   4264         break;
   4265     case 0x0c00: /* bfclr */
   4266         tcg_gen_and_i32(src, src, mask);
   4267         break;
   4268     case 0x0d00: /* bfffo */
   4269         gen_helper_bfffo_reg(DREG(ext, 12), QREG_CC_N, tofs, tlen);
   4270         tcg_temp_free(tlen);
   4271         tcg_temp_free(tofs);
   4272         break;
   4273     case 0x0e00: /* bfset */
   4274         tcg_gen_orc_i32(src, src, mask);
   4275         break;
   4276     case 0x0800: /* bftst */
   4277         /* flags already set; no other work to do.  */
   4278         break;
   4279     default:
   4280         g_assert_not_reached();
   4281     }
   4282     tcg_temp_free(mask);
   4283 }
   4284 
   4285 DISAS_INSN(bfop_mem)
   4286 {
   4287     int ext = read_im16(env, s);
   4288     TCGv addr, len, ofs;
   4289     TCGv_i64 t64;
   4290 
   4291     addr = gen_lea(env, s, insn, OS_UNSIZED);
   4292     if (IS_NULL_QREG(addr)) {
   4293         gen_addr_fault(s);
   4294         return;
   4295     }
   4296 
   4297     if (ext & 0x20) {
   4298         len = DREG(ext, 0);
   4299     } else {
   4300         len = tcg_const_i32(extract32(ext, 0, 5));
   4301     }
   4302     if (ext & 0x800) {
   4303         ofs = DREG(ext, 6);
   4304     } else {
   4305         ofs = tcg_const_i32(extract32(ext, 6, 5));
   4306     }
   4307 
   4308     switch (insn & 0x0f00) {
   4309     case 0x0a00: /* bfchg */
   4310         gen_helper_bfchg_mem(QREG_CC_N, cpu_env, addr, ofs, len);
   4311         break;
   4312     case 0x0c00: /* bfclr */
   4313         gen_helper_bfclr_mem(QREG_CC_N, cpu_env, addr, ofs, len);
   4314         break;
   4315     case 0x0d00: /* bfffo */
   4316         t64 = tcg_temp_new_i64();
   4317         gen_helper_bfffo_mem(t64, cpu_env, addr, ofs, len);
   4318         tcg_gen_extr_i64_i32(DREG(ext, 12), QREG_CC_N, t64);
   4319         tcg_temp_free_i64(t64);
   4320         break;
   4321     case 0x0e00: /* bfset */
   4322         gen_helper_bfset_mem(QREG_CC_N, cpu_env, addr, ofs, len);
   4323         break;
   4324     case 0x0800: /* bftst */
   4325         gen_helper_bfexts_mem(QREG_CC_N, cpu_env, addr, ofs, len);
   4326         break;
   4327     default:
   4328         g_assert_not_reached();
   4329     }
   4330     set_cc_op(s, CC_OP_LOGIC);
   4331 
   4332     if (!(ext & 0x20)) {
   4333         tcg_temp_free(len);
   4334     }
   4335     if (!(ext & 0x800)) {
   4336         tcg_temp_free(ofs);
   4337     }
   4338 }
   4339 
   4340 DISAS_INSN(bfins_reg)
   4341 {
   4342     int ext = read_im16(env, s);
   4343     TCGv dst = DREG(insn, 0);
   4344     TCGv src = DREG(ext, 12);
   4345     int len = ((extract32(ext, 0, 5) - 1) & 31) + 1;
   4346     int ofs = extract32(ext, 6, 5);  /* big bit-endian */
   4347     int pos = 32 - ofs - len;        /* little bit-endian */
   4348     TCGv tmp;
   4349 
   4350     tmp = tcg_temp_new();
   4351 
   4352     if (ext & 0x20) {
   4353         /* Variable width */
   4354         tcg_gen_neg_i32(tmp, DREG(ext, 0));
   4355         tcg_gen_andi_i32(tmp, tmp, 31);
   4356         tcg_gen_shl_i32(QREG_CC_N, src, tmp);
   4357     } else {
   4358         /* Immediate width */
   4359         tcg_gen_shli_i32(QREG_CC_N, src, 32 - len);
   4360     }
   4361     set_cc_op(s, CC_OP_LOGIC);
   4362 
   4363     /* Immediate width and offset */
   4364     if ((ext & 0x820) == 0) {
   4365         /* Check for suitability for deposit.  */
   4366         if (pos >= 0) {
   4367             tcg_gen_deposit_i32(dst, dst, src, pos, len);
   4368         } else {
   4369             uint32_t maski = -2U << (len - 1);
   4370             uint32_t roti = (ofs + len) & 31;
   4371             tcg_gen_andi_i32(tmp, src, ~maski);
   4372             tcg_gen_rotri_i32(tmp, tmp, roti);
   4373             tcg_gen_andi_i32(dst, dst, ror32(maski, roti));
   4374             tcg_gen_or_i32(dst, dst, tmp);
   4375         }
   4376     } else {
   4377         TCGv mask = tcg_temp_new();
   4378         TCGv rot = tcg_temp_new();
   4379 
   4380         if (ext & 0x20) {
   4381             /* Variable width */
   4382             tcg_gen_subi_i32(rot, DREG(ext, 0), 1);
   4383             tcg_gen_andi_i32(rot, rot, 31);
   4384             tcg_gen_movi_i32(mask, -2);
   4385             tcg_gen_shl_i32(mask, mask, rot);
   4386             tcg_gen_mov_i32(rot, DREG(ext, 0));
   4387             tcg_gen_andc_i32(tmp, src, mask);
   4388         } else {
   4389             /* Immediate width (variable offset) */
   4390             uint32_t maski = -2U << (len - 1);
   4391             tcg_gen_andi_i32(tmp, src, ~maski);
   4392             tcg_gen_movi_i32(mask, maski);
   4393             tcg_gen_movi_i32(rot, len & 31);
   4394         }
   4395         if (ext & 0x800) {
   4396             /* Variable offset */
   4397             tcg_gen_add_i32(rot, rot, DREG(ext, 6));
   4398         } else {
   4399             /* Immediate offset (variable width) */
   4400             tcg_gen_addi_i32(rot, rot, ofs);
   4401         }
   4402         tcg_gen_andi_i32(rot, rot, 31);
   4403         tcg_gen_rotr_i32(mask, mask, rot);
   4404         tcg_gen_rotr_i32(tmp, tmp, rot);
   4405         tcg_gen_and_i32(dst, dst, mask);
   4406         tcg_gen_or_i32(dst, dst, tmp);
   4407 
   4408         tcg_temp_free(rot);
   4409         tcg_temp_free(mask);
   4410     }
   4411     tcg_temp_free(tmp);
   4412 }
   4413 
   4414 DISAS_INSN(bfins_mem)
   4415 {
   4416     int ext = read_im16(env, s);
   4417     TCGv src = DREG(ext, 12);
   4418     TCGv addr, len, ofs;
   4419 
   4420     addr = gen_lea(env, s, insn, OS_UNSIZED);
   4421     if (IS_NULL_QREG(addr)) {
   4422         gen_addr_fault(s);
   4423         return;
   4424     }
   4425 
   4426     if (ext & 0x20) {
   4427         len = DREG(ext, 0);
   4428     } else {
   4429         len = tcg_const_i32(extract32(ext, 0, 5));
   4430     }
   4431     if (ext & 0x800) {
   4432         ofs = DREG(ext, 6);
   4433     } else {
   4434         ofs = tcg_const_i32(extract32(ext, 6, 5));
   4435     }
   4436 
   4437     gen_helper_bfins_mem(QREG_CC_N, cpu_env, addr, src, ofs, len);
   4438     set_cc_op(s, CC_OP_LOGIC);
   4439 
   4440     if (!(ext & 0x20)) {
   4441         tcg_temp_free(len);
   4442     }
   4443     if (!(ext & 0x800)) {
   4444         tcg_temp_free(ofs);
   4445     }
   4446 }
   4447 
   4448 DISAS_INSN(ff1)
   4449 {
   4450     TCGv reg;
   4451     reg = DREG(insn, 0);
   4452     gen_logic_cc(s, reg, OS_LONG);
   4453     gen_helper_ff1(reg, reg);
   4454 }
   4455 
   4456 DISAS_INSN(chk)
   4457 {
   4458     TCGv src, reg;
   4459     int opsize;
   4460 
   4461     switch ((insn >> 7) & 3) {
   4462     case 3:
   4463         opsize = OS_WORD;
   4464         break;
   4465     case 2:
   4466         if (m68k_feature(env, M68K_FEATURE_CHK2)) {
   4467             opsize = OS_LONG;
   4468             break;
   4469         }
   4470         /* fallthru */
   4471     default:
   4472         gen_exception(s, s->base.pc_next, EXCP_ILLEGAL);
   4473         return;
   4474     }
   4475     SRC_EA(env, src, opsize, 1, NULL);
   4476     reg = gen_extend(s, DREG(insn, 9), opsize, 1);
   4477 
   4478     gen_flush_flags(s);
   4479     gen_helper_chk(cpu_env, reg, src);
   4480 }
   4481 
   4482 DISAS_INSN(chk2)
   4483 {
   4484     uint16_t ext;
   4485     TCGv addr1, addr2, bound1, bound2, reg;
   4486     int opsize;
   4487 
   4488     switch ((insn >> 9) & 3) {
   4489     case 0:
   4490         opsize = OS_BYTE;
   4491         break;
   4492     case 1:
   4493         opsize = OS_WORD;
   4494         break;
   4495     case 2:
   4496         opsize = OS_LONG;
   4497         break;
   4498     default:
   4499         gen_exception(s, s->base.pc_next, EXCP_ILLEGAL);
   4500         return;
   4501     }
   4502 
   4503     ext = read_im16(env, s);
   4504     if ((ext & 0x0800) == 0) {
   4505         gen_exception(s, s->base.pc_next, EXCP_ILLEGAL);
   4506         return;
   4507     }
   4508 
   4509     addr1 = gen_lea(env, s, insn, OS_UNSIZED);
   4510     addr2 = tcg_temp_new();
   4511     tcg_gen_addi_i32(addr2, addr1, opsize_bytes(opsize));
   4512 
   4513     bound1 = gen_load(s, opsize, addr1, 1, IS_USER(s));
   4514     tcg_temp_free(addr1);
   4515     bound2 = gen_load(s, opsize, addr2, 1, IS_USER(s));
   4516     tcg_temp_free(addr2);
   4517 
   4518     reg = tcg_temp_new();
   4519     if (ext & 0x8000) {
   4520         tcg_gen_mov_i32(reg, AREG(ext, 12));
   4521     } else {
   4522         gen_ext(reg, DREG(ext, 12), opsize, 1);
   4523     }
   4524 
   4525     gen_flush_flags(s);
   4526     gen_helper_chk2(cpu_env, reg, bound1, bound2);
   4527     tcg_temp_free(reg);
   4528     tcg_temp_free(bound1);
   4529     tcg_temp_free(bound2);
   4530 }
   4531 
   4532 static void m68k_copy_line(TCGv dst, TCGv src, int index)
   4533 {
   4534     TCGv addr;
   4535     TCGv_i64 t0, t1;
   4536 
   4537     addr = tcg_temp_new();
   4538 
   4539     t0 = tcg_temp_new_i64();
   4540     t1 = tcg_temp_new_i64();
   4541 
   4542     tcg_gen_andi_i32(addr, src, ~15);
   4543     tcg_gen_qemu_ld64(t0, addr, index);
   4544     tcg_gen_addi_i32(addr, addr, 8);
   4545     tcg_gen_qemu_ld64(t1, addr, index);
   4546 
   4547     tcg_gen_andi_i32(addr, dst, ~15);
   4548     tcg_gen_qemu_st64(t0, addr, index);
   4549     tcg_gen_addi_i32(addr, addr, 8);
   4550     tcg_gen_qemu_st64(t1, addr, index);
   4551 
   4552     tcg_temp_free_i64(t0);
   4553     tcg_temp_free_i64(t1);
   4554     tcg_temp_free(addr);
   4555 }
   4556 
   4557 DISAS_INSN(move16_reg)
   4558 {
   4559     int index = IS_USER(s);
   4560     TCGv tmp;
   4561     uint16_t ext;
   4562 
   4563     ext = read_im16(env, s);
   4564     if ((ext & (1 << 15)) == 0) {
   4565         gen_exception(s, s->base.pc_next, EXCP_ILLEGAL);
   4566     }
   4567 
   4568     m68k_copy_line(AREG(ext, 12), AREG(insn, 0), index);
   4569 
   4570     /* Ax can be Ay, so save Ay before incrementing Ax */
   4571     tmp = tcg_temp_new();
   4572     tcg_gen_mov_i32(tmp, AREG(ext, 12));
   4573     tcg_gen_addi_i32(AREG(insn, 0), AREG(insn, 0), 16);
   4574     tcg_gen_addi_i32(AREG(ext, 12), tmp, 16);
   4575     tcg_temp_free(tmp);
   4576 }
   4577 
   4578 DISAS_INSN(move16_mem)
   4579 {
   4580     int index = IS_USER(s);
   4581     TCGv reg, addr;
   4582 
   4583     reg = AREG(insn, 0);
   4584     addr = tcg_const_i32(read_im32(env, s));
   4585 
   4586     if ((insn >> 3) & 1) {
   4587         /* MOVE16 (xxx).L, (Ay) */
   4588         m68k_copy_line(reg, addr, index);
   4589     } else {
   4590         /* MOVE16 (Ay), (xxx).L */
   4591         m68k_copy_line(addr, reg, index);
   4592     }
   4593 
   4594     tcg_temp_free(addr);
   4595 
   4596     if (((insn >> 3) & 2) == 0) {
   4597         /* (Ay)+ */
   4598         tcg_gen_addi_i32(reg, reg, 16);
   4599     }
   4600 }
   4601 
   4602 DISAS_INSN(strldsr)
   4603 {
   4604     uint16_t ext;
   4605     uint32_t addr;
   4606 
   4607     addr = s->pc - 2;
   4608     ext = read_im16(env, s);
   4609     if (ext != 0x46FC) {
   4610         gen_exception(s, addr, EXCP_ILLEGAL);
   4611         return;
   4612     }
   4613     ext = read_im16(env, s);
   4614     if (IS_USER(s) || (ext & SR_S) == 0) {
   4615         gen_exception(s, addr, EXCP_PRIVILEGE);
   4616         return;
   4617     }
   4618     gen_push(s, gen_get_sr(s));
   4619     gen_set_sr_im(s, ext, 0);
   4620     gen_exit_tb(s);
   4621 }
   4622 
   4623 DISAS_INSN(move_from_sr)
   4624 {
   4625     TCGv sr;
   4626 
   4627     if (IS_USER(s) && m68k_feature(env, M68K_FEATURE_MOVEFROMSR_PRIV)) {
   4628         gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE);
   4629         return;
   4630     }
   4631     sr = gen_get_sr(s);
   4632     DEST_EA(env, insn, OS_WORD, sr, NULL);
   4633 }
   4634 
   4635 #if defined(CONFIG_SOFTMMU)
   4636 DISAS_INSN(moves)
   4637 {
   4638     int opsize;
   4639     uint16_t ext;
   4640     TCGv reg;
   4641     TCGv addr;
   4642     int extend;
   4643 
   4644     if (IS_USER(s)) {
   4645         gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE);
   4646         return;
   4647     }
   4648 
   4649     ext = read_im16(env, s);
   4650 
   4651     opsize = insn_opsize(insn);
   4652 
   4653     if (ext & 0x8000) {
   4654         /* address register */
   4655         reg = AREG(ext, 12);
   4656         extend = 1;
   4657     } else {
   4658         /* data register */
   4659         reg = DREG(ext, 12);
   4660         extend = 0;
   4661     }
   4662 
   4663     addr = gen_lea(env, s, insn, opsize);
   4664     if (IS_NULL_QREG(addr)) {
   4665         gen_addr_fault(s);
   4666         return;
   4667     }
   4668 
   4669     if (ext & 0x0800) {
   4670         /* from reg to ea */
   4671         gen_store(s, opsize, addr, reg, DFC_INDEX(s));
   4672     } else {
   4673         /* from ea to reg */
   4674         TCGv tmp = gen_load(s, opsize, addr, 0, SFC_INDEX(s));
   4675         if (extend) {
   4676             gen_ext(reg, tmp, opsize, 1);
   4677         } else {
   4678             gen_partset_reg(opsize, reg, tmp);
   4679         }
   4680         tcg_temp_free(tmp);
   4681     }
   4682     switch (extract32(insn, 3, 3)) {
   4683     case 3: /* Indirect postincrement.  */
   4684         tcg_gen_addi_i32(AREG(insn, 0), addr,
   4685                          REG(insn, 0) == 7 && opsize == OS_BYTE
   4686                          ? 2
   4687                          : opsize_bytes(opsize));
   4688         break;
   4689     case 4: /* Indirect predecrememnt.  */
   4690         tcg_gen_mov_i32(AREG(insn, 0), addr);
   4691         break;
   4692     }
   4693 }
   4694 
   4695 DISAS_INSN(move_to_sr)
   4696 {
   4697     if (IS_USER(s)) {
   4698         gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE);
   4699         return;
   4700     }
   4701     gen_move_to_sr(env, s, insn, false);
   4702     gen_exit_tb(s);
   4703 }
   4704 
   4705 DISAS_INSN(move_from_usp)
   4706 {
   4707     if (IS_USER(s)) {
   4708         gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE);
   4709         return;
   4710     }
   4711     tcg_gen_ld_i32(AREG(insn, 0), cpu_env,
   4712                    offsetof(CPUM68KState, sp[M68K_USP]));
   4713 }
   4714 
   4715 DISAS_INSN(move_to_usp)
   4716 {
   4717     if (IS_USER(s)) {
   4718         gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE);
   4719         return;
   4720     }
   4721     tcg_gen_st_i32(AREG(insn, 0), cpu_env,
   4722                    offsetof(CPUM68KState, sp[M68K_USP]));
   4723 }
   4724 
   4725 DISAS_INSN(halt)
   4726 {
   4727     if (IS_USER(s)) {
   4728         gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE);
   4729         return;
   4730     }
   4731 
   4732     gen_exception(s, s->pc, EXCP_HALT_INSN);
   4733 }
   4734 
   4735 DISAS_INSN(stop)
   4736 {
   4737     uint16_t ext;
   4738 
   4739     if (IS_USER(s)) {
   4740         gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE);
   4741         return;
   4742     }
   4743 
   4744     ext = read_im16(env, s);
   4745 
   4746     gen_set_sr_im(s, ext, 0);
   4747     tcg_gen_movi_i32(cpu_halted, 1);
   4748     gen_exception(s, s->pc, EXCP_HLT);
   4749 }
   4750 
   4751 DISAS_INSN(rte)
   4752 {
   4753     if (IS_USER(s)) {
   4754         gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE);
   4755         return;
   4756     }
   4757     gen_exception(s, s->base.pc_next, EXCP_RTE);
   4758 }
   4759 
   4760 DISAS_INSN(cf_movec)
   4761 {
   4762     uint16_t ext;
   4763     TCGv reg;
   4764 
   4765     if (IS_USER(s)) {
   4766         gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE);
   4767         return;
   4768     }
   4769 
   4770     ext = read_im16(env, s);
   4771 
   4772     if (ext & 0x8000) {
   4773         reg = AREG(ext, 12);
   4774     } else {
   4775         reg = DREG(ext, 12);
   4776     }
   4777     gen_helper_cf_movec_to(cpu_env, tcg_const_i32(ext & 0xfff), reg);
   4778     gen_exit_tb(s);
   4779 }
   4780 
   4781 DISAS_INSN(m68k_movec)
   4782 {
   4783     uint16_t ext;
   4784     TCGv reg;
   4785 
   4786     if (IS_USER(s)) {
   4787         gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE);
   4788         return;
   4789     }
   4790 
   4791     ext = read_im16(env, s);
   4792 
   4793     if (ext & 0x8000) {
   4794         reg = AREG(ext, 12);
   4795     } else {
   4796         reg = DREG(ext, 12);
   4797     }
   4798     if (insn & 1) {
   4799         gen_helper_m68k_movec_to(cpu_env, tcg_const_i32(ext & 0xfff), reg);
   4800     } else {
   4801         gen_helper_m68k_movec_from(reg, cpu_env, tcg_const_i32(ext & 0xfff));
   4802     }
   4803     gen_exit_tb(s);
   4804 }
   4805 
   4806 DISAS_INSN(intouch)
   4807 {
   4808     if (IS_USER(s)) {
   4809         gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE);
   4810         return;
   4811     }
   4812     /* ICache fetch.  Implement as no-op.  */
   4813 }
   4814 
   4815 DISAS_INSN(cpushl)
   4816 {
   4817     if (IS_USER(s)) {
   4818         gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE);
   4819         return;
   4820     }
   4821     /* Cache push/invalidate.  Implement as no-op.  */
   4822 }
   4823 
   4824 DISAS_INSN(cpush)
   4825 {
   4826     if (IS_USER(s)) {
   4827         gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE);
   4828         return;
   4829     }
   4830     /* Cache push/invalidate.  Implement as no-op.  */
   4831 }
   4832 
   4833 DISAS_INSN(cinv)
   4834 {
   4835     if (IS_USER(s)) {
   4836         gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE);
   4837         return;
   4838     }
   4839     /* Invalidate cache line.  Implement as no-op.  */
   4840 }
   4841 
   4842 #if defined(CONFIG_SOFTMMU)
   4843 DISAS_INSN(pflush)
   4844 {
   4845     TCGv opmode;
   4846 
   4847     if (IS_USER(s)) {
   4848         gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE);
   4849         return;
   4850     }
   4851 
   4852     opmode = tcg_const_i32((insn >> 3) & 3);
   4853     gen_helper_pflush(cpu_env, AREG(insn, 0), opmode);
   4854     tcg_temp_free(opmode);
   4855 }
   4856 
   4857 DISAS_INSN(ptest)
   4858 {
   4859     TCGv is_read;
   4860 
   4861     if (IS_USER(s)) {
   4862         gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE);
   4863         return;
   4864     }
   4865     is_read = tcg_const_i32((insn >> 5) & 1);
   4866     gen_helper_ptest(cpu_env, AREG(insn, 0), is_read);
   4867     tcg_temp_free(is_read);
   4868 }
   4869 #endif
   4870 
   4871 DISAS_INSN(wddata)
   4872 {
   4873     gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE);
   4874 }
   4875 
   4876 DISAS_INSN(wdebug)
   4877 {
   4878     if (IS_USER(s)) {
   4879         gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE);
   4880         return;
   4881     }
   4882     /* TODO: Implement wdebug.  */
   4883     cpu_abort(env_cpu(env), "WDEBUG not implemented");
   4884 }
   4885 #endif
   4886 
   4887 DISAS_INSN(trap)
   4888 {
   4889     gen_exception(s, s->pc, EXCP_TRAP0 + (insn & 0xf));
   4890 }
   4891 
   4892 static void do_trapcc(DisasContext *s, DisasCompare *c)
   4893 {
   4894     if (c->tcond != TCG_COND_NEVER) {
   4895         TCGLabel *over = NULL;
   4896 
   4897         update_cc_op(s);
   4898 
   4899         if (c->tcond != TCG_COND_ALWAYS) {
   4900             /* Jump over if !c. */
   4901             over = gen_new_label();
   4902             tcg_gen_brcond_i32(tcg_invert_cond(c->tcond), c->v1, c->v2, over);
   4903         }
   4904 
   4905         tcg_gen_movi_i32(QREG_PC, s->pc);
   4906         gen_raise_exception_format2(s, EXCP_TRAPCC, s->base.pc_next);
   4907 
   4908         if (over != NULL) {
   4909             gen_set_label(over);
   4910             s->base.is_jmp = DISAS_NEXT;
   4911         }
   4912     }
   4913     free_cond(c);
   4914 }
   4915 
   4916 DISAS_INSN(trapcc)
   4917 {
   4918     DisasCompare c;
   4919 
   4920     /* Consume and discard the immediate operand. */
   4921     switch (extract32(insn, 0, 3)) {
   4922     case 2: /* trapcc.w */
   4923         (void)read_im16(env, s);
   4924         break;
   4925     case 3: /* trapcc.l */
   4926         (void)read_im32(env, s);
   4927         break;
   4928     case 4: /* trapcc (no operand) */
   4929         break;
   4930     default:
   4931         /* trapcc registered with only valid opmodes */
   4932         g_assert_not_reached();
   4933     }
   4934 
   4935     gen_cc_cond(&c, s, extract32(insn, 8, 4));
   4936     do_trapcc(s, &c);
   4937 }
   4938 
   4939 DISAS_INSN(trapv)
   4940 {
   4941     DisasCompare c;
   4942 
   4943     gen_cc_cond(&c, s, 9); /* V set */
   4944     do_trapcc(s, &c);
   4945 }
   4946 
   4947 static void gen_load_fcr(DisasContext *s, TCGv res, int reg)
   4948 {
   4949     switch (reg) {
   4950     case M68K_FPIAR:
   4951         tcg_gen_movi_i32(res, 0);
   4952         break;
   4953     case M68K_FPSR:
   4954         tcg_gen_ld_i32(res, cpu_env, offsetof(CPUM68KState, fpsr));
   4955         break;
   4956     case M68K_FPCR:
   4957         tcg_gen_ld_i32(res, cpu_env, offsetof(CPUM68KState, fpcr));
   4958         break;
   4959     }
   4960 }
   4961 
   4962 static void gen_store_fcr(DisasContext *s, TCGv val, int reg)
   4963 {
   4964     switch (reg) {
   4965     case M68K_FPIAR:
   4966         break;
   4967     case M68K_FPSR:
   4968         tcg_gen_st_i32(val, cpu_env, offsetof(CPUM68KState, fpsr));
   4969         break;
   4970     case M68K_FPCR:
   4971         gen_helper_set_fpcr(cpu_env, val);
   4972         break;
   4973     }
   4974 }
   4975 
   4976 static void gen_qemu_store_fcr(DisasContext *s, TCGv addr, int reg)
   4977 {
   4978     int index = IS_USER(s);
   4979     TCGv tmp;
   4980 
   4981     tmp = tcg_temp_new();
   4982     gen_load_fcr(s, tmp, reg);
   4983     tcg_gen_qemu_st32(tmp, addr, index);
   4984     tcg_temp_free(tmp);
   4985 }
   4986 
   4987 static void gen_qemu_load_fcr(DisasContext *s, TCGv addr, int reg)
   4988 {
   4989     int index = IS_USER(s);
   4990     TCGv tmp;
   4991 
   4992     tmp = tcg_temp_new();
   4993     tcg_gen_qemu_ld32u(tmp, addr, index);
   4994     gen_store_fcr(s, tmp, reg);
   4995     tcg_temp_free(tmp);
   4996 }
   4997 
   4998 
   4999 static void gen_op_fmove_fcr(CPUM68KState *env, DisasContext *s,
   5000                              uint32_t insn, uint32_t ext)
   5001 {
   5002     int mask = (ext >> 10) & 7;
   5003     int is_write = (ext >> 13) & 1;
   5004     int mode = extract32(insn, 3, 3);
   5005     int i;
   5006     TCGv addr, tmp;
   5007 
   5008     switch (mode) {
   5009     case 0: /* Dn */
   5010         if (mask != M68K_FPIAR && mask != M68K_FPSR && mask != M68K_FPCR) {
   5011             gen_exception(s, s->base.pc_next, EXCP_ILLEGAL);
   5012             return;
   5013         }
   5014         if (is_write) {
   5015             gen_load_fcr(s, DREG(insn, 0), mask);
   5016         } else {
   5017             gen_store_fcr(s, DREG(insn, 0), mask);
   5018         }
   5019         return;
   5020     case 1: /* An, only with FPIAR */
   5021         if (mask != M68K_FPIAR) {
   5022             gen_exception(s, s->base.pc_next, EXCP_ILLEGAL);
   5023             return;
   5024         }
   5025         if (is_write) {
   5026             gen_load_fcr(s, AREG(insn, 0), mask);
   5027         } else {
   5028             gen_store_fcr(s, AREG(insn, 0), mask);
   5029         }
   5030         return;
   5031     case 7: /* Immediate */
   5032         if (REG(insn, 0) == 4) {
   5033             if (is_write ||
   5034                 (mask != M68K_FPIAR && mask != M68K_FPSR &&
   5035                  mask != M68K_FPCR)) {
   5036                 gen_exception(s, s->base.pc_next, EXCP_ILLEGAL);
   5037                 return;
   5038             }
   5039             tmp = tcg_const_i32(read_im32(env, s));
   5040             gen_store_fcr(s, tmp, mask);
   5041             tcg_temp_free(tmp);
   5042             return;
   5043         }
   5044         break;
   5045     default:
   5046         break;
   5047     }
   5048 
   5049     tmp = gen_lea(env, s, insn, OS_LONG);
   5050     if (IS_NULL_QREG(tmp)) {
   5051         gen_addr_fault(s);
   5052         return;
   5053     }
   5054 
   5055     addr = tcg_temp_new();
   5056     tcg_gen_mov_i32(addr, tmp);
   5057 
   5058     /*
   5059      * mask:
   5060      *
   5061      * 0b100 Floating-Point Control Register
   5062      * 0b010 Floating-Point Status Register
   5063      * 0b001 Floating-Point Instruction Address Register
   5064      *
   5065      */
   5066 
   5067     if (is_write && mode == 4) {
   5068         for (i = 2; i >= 0; i--, mask >>= 1) {
   5069             if (mask & 1) {
   5070                 gen_qemu_store_fcr(s, addr, 1 << i);
   5071                 if (mask != 1) {
   5072                     tcg_gen_subi_i32(addr, addr, opsize_bytes(OS_LONG));
   5073                 }
   5074             }
   5075        }
   5076        tcg_gen_mov_i32(AREG(insn, 0), addr);
   5077     } else {
   5078         for (i = 0; i < 3; i++, mask >>= 1) {
   5079             if (mask & 1) {
   5080                 if (is_write) {
   5081                     gen_qemu_store_fcr(s, addr, 1 << i);
   5082                 } else {
   5083                     gen_qemu_load_fcr(s, addr, 1 << i);
   5084                 }
   5085                 if (mask != 1 || mode == 3) {
   5086                     tcg_gen_addi_i32(addr, addr, opsize_bytes(OS_LONG));
   5087                 }
   5088             }
   5089         }
   5090         if (mode == 3) {
   5091             tcg_gen_mov_i32(AREG(insn, 0), addr);
   5092         }
   5093     }
   5094     tcg_temp_free_i32(addr);
   5095 }
   5096 
   5097 static void gen_op_fmovem(CPUM68KState *env, DisasContext *s,
   5098                           uint32_t insn, uint32_t ext)
   5099 {
   5100     int opsize;
   5101     TCGv addr, tmp;
   5102     int mode = (ext >> 11) & 0x3;
   5103     int is_load = ((ext & 0x2000) == 0);
   5104 
   5105     if (m68k_feature(s->env, M68K_FEATURE_FPU)) {
   5106         opsize = OS_EXTENDED;
   5107     } else {
   5108         opsize = OS_DOUBLE;  /* FIXME */
   5109     }
   5110 
   5111     addr = gen_lea(env, s, insn, opsize);
   5112     if (IS_NULL_QREG(addr)) {
   5113         gen_addr_fault(s);
   5114         return;
   5115     }
   5116 
   5117     tmp = tcg_temp_new();
   5118     if (mode & 0x1) {
   5119         /* Dynamic register list */
   5120         tcg_gen_ext8u_i32(tmp, DREG(ext, 4));
   5121     } else {
   5122         /* Static register list */
   5123         tcg_gen_movi_i32(tmp, ext & 0xff);
   5124     }
   5125 
   5126     if (!is_load && (mode & 2) == 0) {
   5127         /*
   5128          * predecrement addressing mode
   5129          * only available to store register to memory
   5130          */
   5131         if (opsize == OS_EXTENDED) {
   5132             gen_helper_fmovemx_st_predec(tmp, cpu_env, addr, tmp);
   5133         } else {
   5134             gen_helper_fmovemd_st_predec(tmp, cpu_env, addr, tmp);
   5135         }
   5136     } else {
   5137         /* postincrement addressing mode */
   5138         if (opsize == OS_EXTENDED) {
   5139             if (is_load) {
   5140                 gen_helper_fmovemx_ld_postinc(tmp, cpu_env, addr, tmp);
   5141             } else {
   5142                 gen_helper_fmovemx_st_postinc(tmp, cpu_env, addr, tmp);
   5143             }
   5144         } else {
   5145             if (is_load) {
   5146                 gen_helper_fmovemd_ld_postinc(tmp, cpu_env, addr, tmp);
   5147             } else {
   5148                 gen_helper_fmovemd_st_postinc(tmp, cpu_env, addr, tmp);
   5149             }
   5150         }
   5151     }
   5152     if ((insn & 070) == 030 || (insn & 070) == 040) {
   5153         tcg_gen_mov_i32(AREG(insn, 0), tmp);
   5154     }
   5155     tcg_temp_free(tmp);
   5156 }
   5157 
   5158 /*
   5159  * ??? FP exceptions are not implemented.  Most exceptions are deferred until
   5160  * immediately before the next FP instruction is executed.
   5161  */
   5162 DISAS_INSN(fpu)
   5163 {
   5164     uint16_t ext;
   5165     int opmode;
   5166     int opsize;
   5167     TCGv_ptr cpu_src, cpu_dest;
   5168 
   5169     ext = read_im16(env, s);
   5170     opmode = ext & 0x7f;
   5171     switch ((ext >> 13) & 7) {
   5172     case 0:
   5173         break;
   5174     case 1:
   5175         goto undef;
   5176     case 2:
   5177         if (insn == 0xf200 && (ext & 0xfc00) == 0x5c00) {
   5178             /* fmovecr */
   5179             TCGv rom_offset = tcg_const_i32(opmode);
   5180             cpu_dest = gen_fp_ptr(REG(ext, 7));
   5181             gen_helper_fconst(cpu_env, cpu_dest, rom_offset);
   5182             tcg_temp_free_ptr(cpu_dest);
   5183             tcg_temp_free(rom_offset);
   5184             return;
   5185         }
   5186         break;
   5187     case 3: /* fmove out */
   5188         cpu_src = gen_fp_ptr(REG(ext, 7));
   5189         opsize = ext_opsize(ext, 10);
   5190         if (gen_ea_fp(env, s, insn, opsize, cpu_src,
   5191                       EA_STORE, IS_USER(s)) == -1) {
   5192             gen_addr_fault(s);
   5193         }
   5194         gen_helper_ftst(cpu_env, cpu_src);
   5195         tcg_temp_free_ptr(cpu_src);
   5196         return;
   5197     case 4: /* fmove to control register.  */
   5198     case 5: /* fmove from control register.  */
   5199         gen_op_fmove_fcr(env, s, insn, ext);
   5200         return;
   5201     case 6: /* fmovem */
   5202     case 7:
   5203         if ((ext & 0x1000) == 0 && !m68k_feature(s->env, M68K_FEATURE_FPU)) {
   5204             goto undef;
   5205         }
   5206         gen_op_fmovem(env, s, insn, ext);
   5207         return;
   5208     }
   5209     if (ext & (1 << 14)) {
   5210         /* Source effective address.  */
   5211         opsize = ext_opsize(ext, 10);
   5212         cpu_src = gen_fp_result_ptr();
   5213         if (gen_ea_fp(env, s, insn, opsize, cpu_src,
   5214                       EA_LOADS, IS_USER(s)) == -1) {
   5215             gen_addr_fault(s);
   5216             return;
   5217         }
   5218     } else {
   5219         /* Source register.  */
   5220         opsize = OS_EXTENDED;
   5221         cpu_src = gen_fp_ptr(REG(ext, 10));
   5222     }
   5223     cpu_dest = gen_fp_ptr(REG(ext, 7));
   5224     switch (opmode) {
   5225     case 0: /* fmove */
   5226         gen_fp_move(cpu_dest, cpu_src);
   5227         break;
   5228     case 0x40: /* fsmove */
   5229         gen_helper_fsround(cpu_env, cpu_dest, cpu_src);
   5230         break;
   5231     case 0x44: /* fdmove */
   5232         gen_helper_fdround(cpu_env, cpu_dest, cpu_src);
   5233         break;
   5234     case 1: /* fint */
   5235         gen_helper_firound(cpu_env, cpu_dest, cpu_src);
   5236         break;
   5237     case 2: /* fsinh */
   5238         gen_helper_fsinh(cpu_env, cpu_dest, cpu_src);
   5239         break;
   5240     case 3: /* fintrz */
   5241         gen_helper_fitrunc(cpu_env, cpu_dest, cpu_src);
   5242         break;
   5243     case 4: /* fsqrt */
   5244         gen_helper_fsqrt(cpu_env, cpu_dest, cpu_src);
   5245         break;
   5246     case 0x41: /* fssqrt */
   5247         gen_helper_fssqrt(cpu_env, cpu_dest, cpu_src);
   5248         break;
   5249     case 0x45: /* fdsqrt */
   5250         gen_helper_fdsqrt(cpu_env, cpu_dest, cpu_src);
   5251         break;
   5252     case 0x06: /* flognp1 */
   5253         gen_helper_flognp1(cpu_env, cpu_dest, cpu_src);
   5254         break;
   5255     case 0x08: /* fetoxm1 */
   5256         gen_helper_fetoxm1(cpu_env, cpu_dest, cpu_src);
   5257         break;
   5258     case 0x09: /* ftanh */
   5259         gen_helper_ftanh(cpu_env, cpu_dest, cpu_src);
   5260         break;
   5261     case 0x0a: /* fatan */
   5262         gen_helper_fatan(cpu_env, cpu_dest, cpu_src);
   5263         break;
   5264     case 0x0c: /* fasin */
   5265         gen_helper_fasin(cpu_env, cpu_dest, cpu_src);
   5266         break;
   5267     case 0x0d: /* fatanh */
   5268         gen_helper_fatanh(cpu_env, cpu_dest, cpu_src);
   5269         break;
   5270     case 0x0e: /* fsin */
   5271         gen_helper_fsin(cpu_env, cpu_dest, cpu_src);
   5272         break;
   5273     case 0x0f: /* ftan */
   5274         gen_helper_ftan(cpu_env, cpu_dest, cpu_src);
   5275         break;
   5276     case 0x10: /* fetox */
   5277         gen_helper_fetox(cpu_env, cpu_dest, cpu_src);
   5278         break;
   5279     case 0x11: /* ftwotox */
   5280         gen_helper_ftwotox(cpu_env, cpu_dest, cpu_src);
   5281         break;
   5282     case 0x12: /* ftentox */
   5283         gen_helper_ftentox(cpu_env, cpu_dest, cpu_src);
   5284         break;
   5285     case 0x14: /* flogn */
   5286         gen_helper_flogn(cpu_env, cpu_dest, cpu_src);
   5287         break;
   5288     case 0x15: /* flog10 */
   5289         gen_helper_flog10(cpu_env, cpu_dest, cpu_src);
   5290         break;
   5291     case 0x16: /* flog2 */
   5292         gen_helper_flog2(cpu_env, cpu_dest, cpu_src);
   5293         break;
   5294     case 0x18: /* fabs */
   5295         gen_helper_fabs(cpu_env, cpu_dest, cpu_src);
   5296         break;
   5297     case 0x58: /* fsabs */
   5298         gen_helper_fsabs(cpu_env, cpu_dest, cpu_src);
   5299         break;
   5300     case 0x5c: /* fdabs */
   5301         gen_helper_fdabs(cpu_env, cpu_dest, cpu_src);
   5302         break;
   5303     case 0x19: /* fcosh */
   5304         gen_helper_fcosh(cpu_env, cpu_dest, cpu_src);
   5305         break;
   5306     case 0x1a: /* fneg */
   5307         gen_helper_fneg(cpu_env, cpu_dest, cpu_src);
   5308         break;
   5309     case 0x5a: /* fsneg */
   5310         gen_helper_fsneg(cpu_env, cpu_dest, cpu_src);
   5311         break;
   5312     case 0x5e: /* fdneg */
   5313         gen_helper_fdneg(cpu_env, cpu_dest, cpu_src);
   5314         break;
   5315     case 0x1c: /* facos */
   5316         gen_helper_facos(cpu_env, cpu_dest, cpu_src);
   5317         break;
   5318     case 0x1d: /* fcos */
   5319         gen_helper_fcos(cpu_env, cpu_dest, cpu_src);
   5320         break;
   5321     case 0x1e: /* fgetexp */
   5322         gen_helper_fgetexp(cpu_env, cpu_dest, cpu_src);
   5323         break;
   5324     case 0x1f: /* fgetman */
   5325         gen_helper_fgetman(cpu_env, cpu_dest, cpu_src);
   5326         break;
   5327     case 0x20: /* fdiv */
   5328         gen_helper_fdiv(cpu_env, cpu_dest, cpu_src, cpu_dest);
   5329         break;
   5330     case 0x60: /* fsdiv */
   5331         gen_helper_fsdiv(cpu_env, cpu_dest, cpu_src, cpu_dest);
   5332         break;
   5333     case 0x64: /* fddiv */
   5334         gen_helper_fddiv(cpu_env, cpu_dest, cpu_src, cpu_dest);
   5335         break;
   5336     case 0x21: /* fmod */
   5337         gen_helper_fmod(cpu_env, cpu_dest, cpu_src, cpu_dest);
   5338         break;
   5339     case 0x22: /* fadd */
   5340         gen_helper_fadd(cpu_env, cpu_dest, cpu_src, cpu_dest);
   5341         break;
   5342     case 0x62: /* fsadd */
   5343         gen_helper_fsadd(cpu_env, cpu_dest, cpu_src, cpu_dest);
   5344         break;
   5345     case 0x66: /* fdadd */
   5346         gen_helper_fdadd(cpu_env, cpu_dest, cpu_src, cpu_dest);
   5347         break;
   5348     case 0x23: /* fmul */
   5349         gen_helper_fmul(cpu_env, cpu_dest, cpu_src, cpu_dest);
   5350         break;
   5351     case 0x63: /* fsmul */
   5352         gen_helper_fsmul(cpu_env, cpu_dest, cpu_src, cpu_dest);
   5353         break;
   5354     case 0x67: /* fdmul */
   5355         gen_helper_fdmul(cpu_env, cpu_dest, cpu_src, cpu_dest);
   5356         break;
   5357     case 0x24: /* fsgldiv */
   5358         gen_helper_fsgldiv(cpu_env, cpu_dest, cpu_src, cpu_dest);
   5359         break;
   5360     case 0x25: /* frem */
   5361         gen_helper_frem(cpu_env, cpu_dest, cpu_src, cpu_dest);
   5362         break;
   5363     case 0x26: /* fscale */
   5364         gen_helper_fscale(cpu_env, cpu_dest, cpu_src, cpu_dest);
   5365         break;
   5366     case 0x27: /* fsglmul */
   5367         gen_helper_fsglmul(cpu_env, cpu_dest, cpu_src, cpu_dest);
   5368         break;
   5369     case 0x28: /* fsub */
   5370         gen_helper_fsub(cpu_env, cpu_dest, cpu_src, cpu_dest);
   5371         break;
   5372     case 0x68: /* fssub */
   5373         gen_helper_fssub(cpu_env, cpu_dest, cpu_src, cpu_dest);
   5374         break;
   5375     case 0x6c: /* fdsub */
   5376         gen_helper_fdsub(cpu_env, cpu_dest, cpu_src, cpu_dest);
   5377         break;
   5378     case 0x30: case 0x31: case 0x32:
   5379     case 0x33: case 0x34: case 0x35:
   5380     case 0x36: case 0x37: {
   5381             TCGv_ptr cpu_dest2 = gen_fp_ptr(REG(ext, 0));
   5382             gen_helper_fsincos(cpu_env, cpu_dest, cpu_dest2, cpu_src);
   5383             tcg_temp_free_ptr(cpu_dest2);
   5384         }
   5385         break;
   5386     case 0x38: /* fcmp */
   5387         gen_helper_fcmp(cpu_env, cpu_src, cpu_dest);
   5388         return;
   5389     case 0x3a: /* ftst */
   5390         gen_helper_ftst(cpu_env, cpu_src);
   5391         return;
   5392     default:
   5393         goto undef;
   5394     }
   5395     tcg_temp_free_ptr(cpu_src);
   5396     gen_helper_ftst(cpu_env, cpu_dest);
   5397     tcg_temp_free_ptr(cpu_dest);
   5398     return;
   5399 undef:
   5400     /* FIXME: Is this right for offset addressing modes?  */
   5401     s->pc -= 2;
   5402     disas_undef_fpu(env, s, insn);
   5403 }
   5404 
   5405 static void gen_fcc_cond(DisasCompare *c, DisasContext *s, int cond)
   5406 {
   5407     TCGv fpsr;
   5408 
   5409     c->g1 = 1;
   5410     c->v2 = tcg_const_i32(0);
   5411     c->g2 = 0;
   5412     /* TODO: Raise BSUN exception.  */
   5413     fpsr = tcg_temp_new();
   5414     gen_load_fcr(s, fpsr, M68K_FPSR);
   5415     switch (cond) {
   5416     case 0:  /* False */
   5417     case 16: /* Signaling False */
   5418         c->v1 = c->v2;
   5419         c->tcond = TCG_COND_NEVER;
   5420         break;
   5421     case 1:  /* EQual Z */
   5422     case 17: /* Signaling EQual Z */
   5423         c->v1 = tcg_temp_new();
   5424         c->g1 = 0;
   5425         tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_Z);
   5426         c->tcond = TCG_COND_NE;
   5427         break;
   5428     case 2:  /* Ordered Greater Than !(A || Z || N) */
   5429     case 18: /* Greater Than !(A || Z || N) */
   5430         c->v1 = tcg_temp_new();
   5431         c->g1 = 0;
   5432         tcg_gen_andi_i32(c->v1, fpsr,
   5433                          FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N);
   5434         c->tcond = TCG_COND_EQ;
   5435         break;
   5436     case 3:  /* Ordered Greater than or Equal Z || !(A || N) */
   5437     case 19: /* Greater than or Equal Z || !(A || N) */
   5438         c->v1 = tcg_temp_new();
   5439         c->g1 = 0;
   5440         tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A);
   5441         tcg_gen_shli_i32(c->v1, c->v1, ctz32(FPSR_CC_N) - ctz32(FPSR_CC_A));
   5442         tcg_gen_andi_i32(fpsr, fpsr, FPSR_CC_Z | FPSR_CC_N);
   5443         tcg_gen_or_i32(c->v1, c->v1, fpsr);
   5444         tcg_gen_xori_i32(c->v1, c->v1, FPSR_CC_N);
   5445         c->tcond = TCG_COND_NE;
   5446         break;
   5447     case 4:  /* Ordered Less Than !(!N || A || Z); */
   5448     case 20: /* Less Than !(!N || A || Z); */
   5449         c->v1 = tcg_temp_new();
   5450         c->g1 = 0;
   5451         tcg_gen_xori_i32(c->v1, fpsr, FPSR_CC_N);
   5452         tcg_gen_andi_i32(c->v1, c->v1, FPSR_CC_N | FPSR_CC_A | FPSR_CC_Z);
   5453         c->tcond = TCG_COND_EQ;
   5454         break;
   5455     case 5:  /* Ordered Less than or Equal Z || (N && !A) */
   5456     case 21: /* Less than or Equal Z || (N && !A) */
   5457         c->v1 = tcg_temp_new();
   5458         c->g1 = 0;
   5459         tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A);
   5460         tcg_gen_shli_i32(c->v1, c->v1, ctz32(FPSR_CC_N) - ctz32(FPSR_CC_A));
   5461         tcg_gen_andc_i32(c->v1, fpsr, c->v1);
   5462         tcg_gen_andi_i32(c->v1, c->v1, FPSR_CC_Z | FPSR_CC_N);
   5463         c->tcond = TCG_COND_NE;
   5464         break;
   5465     case 6:  /* Ordered Greater or Less than !(A || Z) */
   5466     case 22: /* Greater or Less than !(A || Z) */
   5467         c->v1 = tcg_temp_new();
   5468         c->g1 = 0;
   5469         tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A | FPSR_CC_Z);
   5470         c->tcond = TCG_COND_EQ;
   5471         break;
   5472     case 7:  /* Ordered !A */
   5473     case 23: /* Greater, Less or Equal !A */
   5474         c->v1 = tcg_temp_new();
   5475         c->g1 = 0;
   5476         tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A);
   5477         c->tcond = TCG_COND_EQ;
   5478         break;
   5479     case 8:  /* Unordered A */
   5480     case 24: /* Not Greater, Less or Equal A */
   5481         c->v1 = tcg_temp_new();
   5482         c->g1 = 0;
   5483         tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A);
   5484         c->tcond = TCG_COND_NE;
   5485         break;
   5486     case 9:  /* Unordered or Equal A || Z */
   5487     case 25: /* Not Greater or Less then A || Z */
   5488         c->v1 = tcg_temp_new();
   5489         c->g1 = 0;
   5490         tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A | FPSR_CC_Z);
   5491         c->tcond = TCG_COND_NE;
   5492         break;
   5493     case 10: /* Unordered or Greater Than A || !(N || Z)) */
   5494     case 26: /* Not Less or Equal A || !(N || Z)) */
   5495         c->v1 = tcg_temp_new();
   5496         c->g1 = 0;
   5497         tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_Z);
   5498         tcg_gen_shli_i32(c->v1, c->v1, ctz32(FPSR_CC_N) - ctz32(FPSR_CC_Z));
   5499         tcg_gen_andi_i32(fpsr, fpsr, FPSR_CC_A | FPSR_CC_N);
   5500         tcg_gen_or_i32(c->v1, c->v1, fpsr);
   5501         tcg_gen_xori_i32(c->v1, c->v1, FPSR_CC_N);
   5502         c->tcond = TCG_COND_NE;
   5503         break;
   5504     case 11: /* Unordered or Greater or Equal A || Z || !N */
   5505     case 27: /* Not Less Than A || Z || !N */
   5506         c->v1 = tcg_temp_new();
   5507         c->g1 = 0;
   5508         tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N);
   5509         tcg_gen_xori_i32(c->v1, c->v1, FPSR_CC_N);
   5510         c->tcond = TCG_COND_NE;
   5511         break;
   5512     case 12: /* Unordered or Less Than A || (N && !Z) */
   5513     case 28: /* Not Greater than or Equal A || (N && !Z) */
   5514         c->v1 = tcg_temp_new();
   5515         c->g1 = 0;
   5516         tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_Z);
   5517         tcg_gen_shli_i32(c->v1, c->v1, ctz32(FPSR_CC_N) - ctz32(FPSR_CC_Z));
   5518         tcg_gen_andc_i32(c->v1, fpsr, c->v1);
   5519         tcg_gen_andi_i32(c->v1, c->v1, FPSR_CC_A | FPSR_CC_N);
   5520         c->tcond = TCG_COND_NE;
   5521         break;
   5522     case 13: /* Unordered or Less or Equal A || Z || N */
   5523     case 29: /* Not Greater Than A || Z || N */
   5524         c->v1 = tcg_temp_new();
   5525         c->g1 = 0;
   5526         tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N);
   5527         c->tcond = TCG_COND_NE;
   5528         break;
   5529     case 14: /* Not Equal !Z */
   5530     case 30: /* Signaling Not Equal !Z */
   5531         c->v1 = tcg_temp_new();
   5532         c->g1 = 0;
   5533         tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_Z);
   5534         c->tcond = TCG_COND_EQ;
   5535         break;
   5536     case 15: /* True */
   5537     case 31: /* Signaling True */
   5538         c->v1 = c->v2;
   5539         c->tcond = TCG_COND_ALWAYS;
   5540         break;
   5541     }
   5542     tcg_temp_free(fpsr);
   5543 }
   5544 
   5545 static void gen_fjmpcc(DisasContext *s, int cond, TCGLabel *l1)
   5546 {
   5547     DisasCompare c;
   5548 
   5549     gen_fcc_cond(&c, s, cond);
   5550     update_cc_op(s);
   5551     tcg_gen_brcond_i32(c.tcond, c.v1, c.v2, l1);
   5552     free_cond(&c);
   5553 }
   5554 
   5555 DISAS_INSN(fbcc)
   5556 {
   5557     uint32_t offset;
   5558     uint32_t base;
   5559     TCGLabel *l1;
   5560 
   5561     base = s->pc;
   5562     offset = (int16_t)read_im16(env, s);
   5563     if (insn & (1 << 6)) {
   5564         offset = (offset << 16) | read_im16(env, s);
   5565     }
   5566 
   5567     l1 = gen_new_label();
   5568     update_cc_op(s);
   5569     gen_fjmpcc(s, insn & 0x3f, l1);
   5570     gen_jmp_tb(s, 0, s->pc, s->base.pc_next);
   5571     gen_set_label(l1);
   5572     gen_jmp_tb(s, 1, base + offset, s->base.pc_next);
   5573 }
   5574 
   5575 DISAS_INSN(fscc)
   5576 {
   5577     DisasCompare c;
   5578     int cond;
   5579     TCGv tmp;
   5580     uint16_t ext;
   5581 
   5582     ext = read_im16(env, s);
   5583     cond = ext & 0x3f;
   5584     gen_fcc_cond(&c, s, cond);
   5585 
   5586     tmp = tcg_temp_new();
   5587     tcg_gen_setcond_i32(c.tcond, tmp, c.v1, c.v2);
   5588     free_cond(&c);
   5589 
   5590     tcg_gen_neg_i32(tmp, tmp);
   5591     DEST_EA(env, insn, OS_BYTE, tmp, NULL);
   5592     tcg_temp_free(tmp);
   5593 }
   5594 
   5595 DISAS_INSN(ftrapcc)
   5596 {
   5597     DisasCompare c;
   5598     uint16_t ext;
   5599     int cond;
   5600 
   5601     ext = read_im16(env, s);
   5602     cond = ext & 0x3f;
   5603 
   5604     /* Consume and discard the immediate operand. */
   5605     switch (extract32(insn, 0, 3)) {
   5606     case 2: /* ftrapcc.w */
   5607         (void)read_im16(env, s);
   5608         break;
   5609     case 3: /* ftrapcc.l */
   5610         (void)read_im32(env, s);
   5611         break;
   5612     case 4: /* ftrapcc (no operand) */
   5613         break;
   5614     default:
   5615         /* ftrapcc registered with only valid opmodes */
   5616         g_assert_not_reached();
   5617     }
   5618 
   5619     gen_fcc_cond(&c, s, cond);
   5620     do_trapcc(s, &c);
   5621 }
   5622 
   5623 #if defined(CONFIG_SOFTMMU)
   5624 DISAS_INSN(frestore)
   5625 {
   5626     TCGv addr;
   5627 
   5628     if (IS_USER(s)) {
   5629         gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE);
   5630         return;
   5631     }
   5632     if (m68k_feature(s->env, M68K_FEATURE_M68040)) {
   5633         SRC_EA(env, addr, OS_LONG, 0, NULL);
   5634         /* FIXME: check the state frame */
   5635     } else {
   5636         disas_undef(env, s, insn);
   5637     }
   5638 }
   5639 
   5640 DISAS_INSN(fsave)
   5641 {
   5642     if (IS_USER(s)) {
   5643         gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE);
   5644         return;
   5645     }
   5646 
   5647     if (m68k_feature(s->env, M68K_FEATURE_M68040)) {
   5648         /* always write IDLE */
   5649         TCGv idle = tcg_const_i32(0x41000000);
   5650         DEST_EA(env, insn, OS_LONG, idle, NULL);
   5651         tcg_temp_free(idle);
   5652     } else {
   5653         disas_undef(env, s, insn);
   5654     }
   5655 }
   5656 #endif
   5657 
   5658 static inline TCGv gen_mac_extract_word(DisasContext *s, TCGv val, int upper)
   5659 {
   5660     TCGv tmp = tcg_temp_new();
   5661     if (s->env->macsr & MACSR_FI) {
   5662         if (upper)
   5663             tcg_gen_andi_i32(tmp, val, 0xffff0000);
   5664         else
   5665             tcg_gen_shli_i32(tmp, val, 16);
   5666     } else if (s->env->macsr & MACSR_SU) {
   5667         if (upper)
   5668             tcg_gen_sari_i32(tmp, val, 16);
   5669         else
   5670             tcg_gen_ext16s_i32(tmp, val);
   5671     } else {
   5672         if (upper)
   5673             tcg_gen_shri_i32(tmp, val, 16);
   5674         else
   5675             tcg_gen_ext16u_i32(tmp, val);
   5676     }
   5677     return tmp;
   5678 }
   5679 
   5680 static void gen_mac_clear_flags(void)
   5681 {
   5682     tcg_gen_andi_i32(QREG_MACSR, QREG_MACSR,
   5683                      ~(MACSR_V | MACSR_Z | MACSR_N | MACSR_EV));
   5684 }
   5685 
   5686 DISAS_INSN(mac)
   5687 {
   5688     TCGv rx;
   5689     TCGv ry;
   5690     uint16_t ext;
   5691     int acc;
   5692     TCGv tmp;
   5693     TCGv addr;
   5694     TCGv loadval;
   5695     int dual;
   5696     TCGv saved_flags;
   5697 
   5698     if (!s->done_mac) {
   5699         s->mactmp = tcg_temp_new_i64();
   5700         s->done_mac = 1;
   5701     }
   5702 
   5703     ext = read_im16(env, s);
   5704 
   5705     acc = ((insn >> 7) & 1) | ((ext >> 3) & 2);
   5706     dual = ((insn & 0x30) != 0 && (ext & 3) != 0);
   5707     if (dual && !m68k_feature(s->env, M68K_FEATURE_CF_EMAC_B)) {
   5708         disas_undef(env, s, insn);
   5709         return;
   5710     }
   5711     if (insn & 0x30) {
   5712         /* MAC with load.  */
   5713         tmp = gen_lea(env, s, insn, OS_LONG);
   5714         addr = tcg_temp_new();
   5715         tcg_gen_and_i32(addr, tmp, QREG_MAC_MASK);
   5716         /*
   5717          * Load the value now to ensure correct exception behavior.
   5718          * Perform writeback after reading the MAC inputs.
   5719          */
   5720         loadval = gen_load(s, OS_LONG, addr, 0, IS_USER(s));
   5721 
   5722         acc ^= 1;
   5723         rx = (ext & 0x8000) ? AREG(ext, 12) : DREG(insn, 12);
   5724         ry = (ext & 8) ? AREG(ext, 0) : DREG(ext, 0);
   5725     } else {
   5726         loadval = addr = NULL_QREG;
   5727         rx = (insn & 0x40) ? AREG(insn, 9) : DREG(insn, 9);
   5728         ry = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
   5729     }
   5730 
   5731     gen_mac_clear_flags();
   5732 #if 0
   5733     l1 = -1;
   5734     /* Disabled because conditional branches clobber temporary vars.  */
   5735     if ((s->env->macsr & MACSR_OMC) != 0 && !dual) {
   5736         /* Skip the multiply if we know we will ignore it.  */
   5737         l1 = gen_new_label();
   5738         tmp = tcg_temp_new();
   5739         tcg_gen_andi_i32(tmp, QREG_MACSR, 1 << (acc + 8));
   5740         gen_op_jmp_nz32(tmp, l1);
   5741     }
   5742 #endif
   5743 
   5744     if ((ext & 0x0800) == 0) {
   5745         /* Word.  */
   5746         rx = gen_mac_extract_word(s, rx, (ext & 0x80) != 0);
   5747         ry = gen_mac_extract_word(s, ry, (ext & 0x40) != 0);
   5748     }
   5749     if (s->env->macsr & MACSR_FI) {
   5750         gen_helper_macmulf(s->mactmp, cpu_env, rx, ry);
   5751     } else {
   5752         if (s->env->macsr & MACSR_SU)
   5753             gen_helper_macmuls(s->mactmp, cpu_env, rx, ry);
   5754         else
   5755             gen_helper_macmulu(s->mactmp, cpu_env, rx, ry);
   5756         switch ((ext >> 9) & 3) {
   5757         case 1:
   5758             tcg_gen_shli_i64(s->mactmp, s->mactmp, 1);
   5759             break;
   5760         case 3:
   5761             tcg_gen_shri_i64(s->mactmp, s->mactmp, 1);
   5762             break;
   5763         }
   5764     }
   5765 
   5766     if (dual) {
   5767         /* Save the overflow flag from the multiply.  */
   5768         saved_flags = tcg_temp_new();
   5769         tcg_gen_mov_i32(saved_flags, QREG_MACSR);
   5770     } else {
   5771         saved_flags = NULL_QREG;
   5772     }
   5773 
   5774 #if 0
   5775     /* Disabled because conditional branches clobber temporary vars.  */
   5776     if ((s->env->macsr & MACSR_OMC) != 0 && dual) {
   5777         /* Skip the accumulate if the value is already saturated.  */
   5778         l1 = gen_new_label();
   5779         tmp = tcg_temp_new();
   5780         gen_op_and32(tmp, QREG_MACSR, tcg_const_i32(MACSR_PAV0 << acc));
   5781         gen_op_jmp_nz32(tmp, l1);
   5782     }
   5783 #endif
   5784 
   5785     if (insn & 0x100)
   5786         tcg_gen_sub_i64(MACREG(acc), MACREG(acc), s->mactmp);
   5787     else
   5788         tcg_gen_add_i64(MACREG(acc), MACREG(acc), s->mactmp);
   5789 
   5790     if (s->env->macsr & MACSR_FI)
   5791         gen_helper_macsatf(cpu_env, tcg_const_i32(acc));
   5792     else if (s->env->macsr & MACSR_SU)
   5793         gen_helper_macsats(cpu_env, tcg_const_i32(acc));
   5794     else
   5795         gen_helper_macsatu(cpu_env, tcg_const_i32(acc));
   5796 
   5797 #if 0
   5798     /* Disabled because conditional branches clobber temporary vars.  */
   5799     if (l1 != -1)
   5800         gen_set_label(l1);
   5801 #endif
   5802 
   5803     if (dual) {
   5804         /* Dual accumulate variant.  */
   5805         acc = (ext >> 2) & 3;
   5806         /* Restore the overflow flag from the multiplier.  */
   5807         tcg_gen_mov_i32(QREG_MACSR, saved_flags);
   5808 #if 0
   5809         /* Disabled because conditional branches clobber temporary vars.  */
   5810         if ((s->env->macsr & MACSR_OMC) != 0) {
   5811             /* Skip the accumulate if the value is already saturated.  */
   5812             l1 = gen_new_label();
   5813             tmp = tcg_temp_new();
   5814             gen_op_and32(tmp, QREG_MACSR, tcg_const_i32(MACSR_PAV0 << acc));
   5815             gen_op_jmp_nz32(tmp, l1);
   5816         }
   5817 #endif
   5818         if (ext & 2)
   5819             tcg_gen_sub_i64(MACREG(acc), MACREG(acc), s->mactmp);
   5820         else
   5821             tcg_gen_add_i64(MACREG(acc), MACREG(acc), s->mactmp);
   5822         if (s->env->macsr & MACSR_FI)
   5823             gen_helper_macsatf(cpu_env, tcg_const_i32(acc));
   5824         else if (s->env->macsr & MACSR_SU)
   5825             gen_helper_macsats(cpu_env, tcg_const_i32(acc));
   5826         else
   5827             gen_helper_macsatu(cpu_env, tcg_const_i32(acc));
   5828 #if 0
   5829         /* Disabled because conditional branches clobber temporary vars.  */
   5830         if (l1 != -1)
   5831             gen_set_label(l1);
   5832 #endif
   5833     }
   5834     gen_helper_mac_set_flags(cpu_env, tcg_const_i32(acc));
   5835 
   5836     if (insn & 0x30) {
   5837         TCGv rw;
   5838         rw = (insn & 0x40) ? AREG(insn, 9) : DREG(insn, 9);
   5839         tcg_gen_mov_i32(rw, loadval);
   5840         /*
   5841          * FIXME: Should address writeback happen with the masked or
   5842          * unmasked value?
   5843          */
   5844         switch ((insn >> 3) & 7) {
   5845         case 3: /* Post-increment.  */
   5846             tcg_gen_addi_i32(AREG(insn, 0), addr, 4);
   5847             break;
   5848         case 4: /* Pre-decrement.  */
   5849             tcg_gen_mov_i32(AREG(insn, 0), addr);
   5850         }
   5851         tcg_temp_free(loadval);
   5852     }
   5853 }
   5854 
   5855 DISAS_INSN(from_mac)
   5856 {
   5857     TCGv rx;
   5858     TCGv_i64 acc;
   5859     int accnum;
   5860 
   5861     rx = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
   5862     accnum = (insn >> 9) & 3;
   5863     acc = MACREG(accnum);
   5864     if (s->env->macsr & MACSR_FI) {
   5865         gen_helper_get_macf(rx, cpu_env, acc);
   5866     } else if ((s->env->macsr & MACSR_OMC) == 0) {
   5867         tcg_gen_extrl_i64_i32(rx, acc);
   5868     } else if (s->env->macsr & MACSR_SU) {
   5869         gen_helper_get_macs(rx, acc);
   5870     } else {
   5871         gen_helper_get_macu(rx, acc);
   5872     }
   5873     if (insn & 0x40) {
   5874         tcg_gen_movi_i64(acc, 0);
   5875         tcg_gen_andi_i32(QREG_MACSR, QREG_MACSR, ~(MACSR_PAV0 << accnum));
   5876     }
   5877 }
   5878 
   5879 DISAS_INSN(move_mac)
   5880 {
   5881     /* FIXME: This can be done without a helper.  */
   5882     int src;
   5883     TCGv dest;
   5884     src = insn & 3;
   5885     dest = tcg_const_i32((insn >> 9) & 3);
   5886     gen_helper_mac_move(cpu_env, dest, tcg_const_i32(src));
   5887     gen_mac_clear_flags();
   5888     gen_helper_mac_set_flags(cpu_env, dest);
   5889 }
   5890 
   5891 DISAS_INSN(from_macsr)
   5892 {
   5893     TCGv reg;
   5894 
   5895     reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
   5896     tcg_gen_mov_i32(reg, QREG_MACSR);
   5897 }
   5898 
   5899 DISAS_INSN(from_mask)
   5900 {
   5901     TCGv reg;
   5902     reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
   5903     tcg_gen_mov_i32(reg, QREG_MAC_MASK);
   5904 }
   5905 
   5906 DISAS_INSN(from_mext)
   5907 {
   5908     TCGv reg;
   5909     TCGv acc;
   5910     reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
   5911     acc = tcg_const_i32((insn & 0x400) ? 2 : 0);
   5912     if (s->env->macsr & MACSR_FI)
   5913         gen_helper_get_mac_extf(reg, cpu_env, acc);
   5914     else
   5915         gen_helper_get_mac_exti(reg, cpu_env, acc);
   5916 }
   5917 
   5918 DISAS_INSN(macsr_to_ccr)
   5919 {
   5920     TCGv tmp = tcg_temp_new();
   5921 
   5922     /* Note that X and C are always cleared. */
   5923     tcg_gen_andi_i32(tmp, QREG_MACSR, CCF_N | CCF_Z | CCF_V);
   5924     gen_helper_set_ccr(cpu_env, tmp);
   5925     tcg_temp_free(tmp);
   5926     set_cc_op(s, CC_OP_FLAGS);
   5927 }
   5928 
   5929 DISAS_INSN(to_mac)
   5930 {
   5931     TCGv_i64 acc;
   5932     TCGv val;
   5933     int accnum;
   5934     accnum = (insn >> 9) & 3;
   5935     acc = MACREG(accnum);
   5936     SRC_EA(env, val, OS_LONG, 0, NULL);
   5937     if (s->env->macsr & MACSR_FI) {
   5938         tcg_gen_ext_i32_i64(acc, val);
   5939         tcg_gen_shli_i64(acc, acc, 8);
   5940     } else if (s->env->macsr & MACSR_SU) {
   5941         tcg_gen_ext_i32_i64(acc, val);
   5942     } else {
   5943         tcg_gen_extu_i32_i64(acc, val);
   5944     }
   5945     tcg_gen_andi_i32(QREG_MACSR, QREG_MACSR, ~(MACSR_PAV0 << accnum));
   5946     gen_mac_clear_flags();
   5947     gen_helper_mac_set_flags(cpu_env, tcg_const_i32(accnum));
   5948 }
   5949 
   5950 DISAS_INSN(to_macsr)
   5951 {
   5952     TCGv val;
   5953     SRC_EA(env, val, OS_LONG, 0, NULL);
   5954     gen_helper_set_macsr(cpu_env, val);
   5955     gen_exit_tb(s);
   5956 }
   5957 
   5958 DISAS_INSN(to_mask)
   5959 {
   5960     TCGv val;
   5961     SRC_EA(env, val, OS_LONG, 0, NULL);
   5962     tcg_gen_ori_i32(QREG_MAC_MASK, val, 0xffff0000);
   5963 }
   5964 
   5965 DISAS_INSN(to_mext)
   5966 {
   5967     TCGv val;
   5968     TCGv acc;
   5969     SRC_EA(env, val, OS_LONG, 0, NULL);
   5970     acc = tcg_const_i32((insn & 0x400) ? 2 : 0);
   5971     if (s->env->macsr & MACSR_FI)
   5972         gen_helper_set_mac_extf(cpu_env, val, acc);
   5973     else if (s->env->macsr & MACSR_SU)
   5974         gen_helper_set_mac_exts(cpu_env, val, acc);
   5975     else
   5976         gen_helper_set_mac_extu(cpu_env, val, acc);
   5977 }
   5978 
   5979 static disas_proc opcode_table[65536];
   5980 
   5981 static void
   5982 register_opcode (disas_proc proc, uint16_t opcode, uint16_t mask)
   5983 {
   5984   int i;
   5985   int from;
   5986   int to;
   5987 
   5988   /* Sanity check.  All set bits must be included in the mask.  */
   5989   if (opcode & ~mask) {
   5990       fprintf(stderr,
   5991               "qemu internal error: bogus opcode definition %04x/%04x\n",
   5992               opcode, mask);
   5993       abort();
   5994   }
   5995   /*
   5996    * This could probably be cleverer.  For now just optimize the case where
   5997    * the top bits are known.
   5998    */
   5999   /* Find the first zero bit in the mask.  */
   6000   i = 0x8000;
   6001   while ((i & mask) != 0)
   6002       i >>= 1;
   6003   /* Iterate over all combinations of this and lower bits.  */
   6004   if (i == 0)
   6005       i = 1;
   6006   else
   6007       i <<= 1;
   6008   from = opcode & ~(i - 1);
   6009   to = from + i;
   6010   for (i = from; i < to; i++) {
   6011       if ((i & mask) == opcode)
   6012           opcode_table[i] = proc;
   6013   }
   6014 }
   6015 
   6016 /*
   6017  * Register m68k opcode handlers.  Order is important.
   6018  * Later insn override earlier ones.
   6019  */
   6020 void register_m68k_insns (CPUM68KState *env)
   6021 {
   6022     /*
   6023      * Build the opcode table only once to avoid
   6024      * multithreading issues.
   6025      */
   6026     if (opcode_table[0] != NULL) {
   6027         return;
   6028     }
   6029 
   6030     /*
   6031      * use BASE() for instruction available
   6032      * for CF_ISA_A and M68000.
   6033      */
   6034 #define BASE(name, opcode, mask) \
   6035     register_opcode(disas_##name, 0x##opcode, 0x##mask)
   6036 #define INSN(name, opcode, mask, feature) do { \
   6037     if (m68k_feature(env, M68K_FEATURE_##feature)) \
   6038         BASE(name, opcode, mask); \
   6039     } while(0)
   6040     BASE(undef,     0000, 0000);
   6041     INSN(arith_im,  0080, fff8, CF_ISA_A);
   6042     INSN(arith_im,  0000, ff00, M68K);
   6043     INSN(chk2,      00c0, f9c0, CHK2);
   6044     INSN(bitrev,    00c0, fff8, CF_ISA_APLUSC);
   6045     BASE(bitop_reg, 0100, f1c0);
   6046     BASE(bitop_reg, 0140, f1c0);
   6047     BASE(bitop_reg, 0180, f1c0);
   6048     BASE(bitop_reg, 01c0, f1c0);
   6049     INSN(movep,     0108, f138, MOVEP);
   6050     INSN(arith_im,  0280, fff8, CF_ISA_A);
   6051     INSN(arith_im,  0200, ff00, M68K);
   6052     INSN(undef,     02c0, ffc0, M68K);
   6053     INSN(byterev,   02c0, fff8, CF_ISA_APLUSC);
   6054     INSN(arith_im,  0480, fff8, CF_ISA_A);
   6055     INSN(arith_im,  0400, ff00, M68K);
   6056     INSN(undef,     04c0, ffc0, M68K);
   6057     INSN(arith_im,  0600, ff00, M68K);
   6058     INSN(undef,     06c0, ffc0, M68K);
   6059     INSN(ff1,       04c0, fff8, CF_ISA_APLUSC);
   6060     INSN(arith_im,  0680, fff8, CF_ISA_A);
   6061     INSN(arith_im,  0c00, ff38, CF_ISA_A);
   6062     INSN(arith_im,  0c00, ff00, M68K);
   6063     BASE(bitop_im,  0800, ffc0);
   6064     BASE(bitop_im,  0840, ffc0);
   6065     BASE(bitop_im,  0880, ffc0);
   6066     BASE(bitop_im,  08c0, ffc0);
   6067     INSN(arith_im,  0a80, fff8, CF_ISA_A);
   6068     INSN(arith_im,  0a00, ff00, M68K);
   6069 #if defined(CONFIG_SOFTMMU)
   6070     INSN(moves,     0e00, ff00, M68K);
   6071 #endif
   6072     INSN(cas,       0ac0, ffc0, CAS);
   6073     INSN(cas,       0cc0, ffc0, CAS);
   6074     INSN(cas,       0ec0, ffc0, CAS);
   6075     INSN(cas2w,     0cfc, ffff, CAS);
   6076     INSN(cas2l,     0efc, ffff, CAS);
   6077     BASE(move,      1000, f000);
   6078     BASE(move,      2000, f000);
   6079     BASE(move,      3000, f000);
   6080     INSN(chk,       4000, f040, M68K);
   6081     INSN(strldsr,   40e7, ffff, CF_ISA_APLUSC);
   6082     INSN(negx,      4080, fff8, CF_ISA_A);
   6083     INSN(negx,      4000, ff00, M68K);
   6084     INSN(undef,     40c0, ffc0, M68K);
   6085     INSN(move_from_sr, 40c0, fff8, CF_ISA_A);
   6086     INSN(move_from_sr, 40c0, ffc0, M68K);
   6087     BASE(lea,       41c0, f1c0);
   6088     BASE(clr,       4200, ff00);
   6089     BASE(undef,     42c0, ffc0);
   6090     INSN(move_from_ccr, 42c0, fff8, CF_ISA_A);
   6091     INSN(move_from_ccr, 42c0, ffc0, M68K);
   6092     INSN(neg,       4480, fff8, CF_ISA_A);
   6093     INSN(neg,       4400, ff00, M68K);
   6094     INSN(undef,     44c0, ffc0, M68K);
   6095     BASE(move_to_ccr, 44c0, ffc0);
   6096     INSN(not,       4680, fff8, CF_ISA_A);
   6097     INSN(not,       4600, ff00, M68K);
   6098 #if defined(CONFIG_SOFTMMU)
   6099     BASE(move_to_sr, 46c0, ffc0);
   6100 #endif
   6101     INSN(nbcd,      4800, ffc0, M68K);
   6102     INSN(linkl,     4808, fff8, M68K);
   6103     BASE(pea,       4840, ffc0);
   6104     BASE(swap,      4840, fff8);
   6105     INSN(bkpt,      4848, fff8, BKPT);
   6106     INSN(movem,     48d0, fbf8, CF_ISA_A);
   6107     INSN(movem,     48e8, fbf8, CF_ISA_A);
   6108     INSN(movem,     4880, fb80, M68K);
   6109     BASE(ext,       4880, fff8);
   6110     BASE(ext,       48c0, fff8);
   6111     BASE(ext,       49c0, fff8);
   6112     BASE(tst,       4a00, ff00);
   6113     INSN(tas,       4ac0, ffc0, CF_ISA_B);
   6114     INSN(tas,       4ac0, ffc0, M68K);
   6115 #if defined(CONFIG_SOFTMMU)
   6116     INSN(halt,      4ac8, ffff, CF_ISA_A);
   6117     INSN(halt,      4ac8, ffff, M68K);
   6118 #endif
   6119     INSN(pulse,     4acc, ffff, CF_ISA_A);
   6120     BASE(illegal,   4afc, ffff);
   6121     INSN(mull,      4c00, ffc0, CF_ISA_A);
   6122     INSN(mull,      4c00, ffc0, LONG_MULDIV);
   6123     INSN(divl,      4c40, ffc0, CF_ISA_A);
   6124     INSN(divl,      4c40, ffc0, LONG_MULDIV);
   6125     INSN(sats,      4c80, fff8, CF_ISA_B);
   6126     BASE(trap,      4e40, fff0);
   6127     BASE(link,      4e50, fff8);
   6128     BASE(unlk,      4e58, fff8);
   6129 #if defined(CONFIG_SOFTMMU)
   6130     INSN(move_to_usp, 4e60, fff8, USP);
   6131     INSN(move_from_usp, 4e68, fff8, USP);
   6132     INSN(reset,     4e70, ffff, M68K);
   6133     BASE(stop,      4e72, ffff);
   6134     BASE(rte,       4e73, ffff);
   6135     INSN(cf_movec,  4e7b, ffff, CF_ISA_A);
   6136     INSN(m68k_movec, 4e7a, fffe, MOVEC);
   6137 #endif
   6138     BASE(nop,       4e71, ffff);
   6139     INSN(rtd,       4e74, ffff, RTD);
   6140     BASE(rts,       4e75, ffff);
   6141     INSN(trapv,     4e76, ffff, M68K);
   6142     INSN(rtr,       4e77, ffff, M68K);
   6143     BASE(jump,      4e80, ffc0);
   6144     BASE(jump,      4ec0, ffc0);
   6145     INSN(addsubq,   5000, f080, M68K);
   6146     BASE(addsubq,   5080, f0c0);
   6147     INSN(scc,       50c0, f0f8, CF_ISA_A); /* Scc.B Dx   */
   6148     INSN(scc,       50c0, f0c0, M68K);     /* Scc.B <EA> */
   6149     INSN(dbcc,      50c8, f0f8, M68K);
   6150     INSN(trapcc,    50fa, f0fe, TRAPCC);   /* opmode 010, 011 */
   6151     INSN(trapcc,    50fc, f0ff, TRAPCC);   /* opmode 100 */
   6152     INSN(trapcc,    51fa, fffe, CF_ISA_A); /* TPF (trapf) opmode 010, 011 */
   6153     INSN(trapcc,    51fc, ffff, CF_ISA_A); /* TPF (trapf) opmode 100 */
   6154 
   6155     /* Branch instructions.  */
   6156     BASE(branch,    6000, f000);
   6157     /* Disable long branch instructions, then add back the ones we want.  */
   6158     BASE(undef,     60ff, f0ff); /* All long branches.  */
   6159     INSN(branch,    60ff, f0ff, CF_ISA_B);
   6160     INSN(undef,     60ff, ffff, CF_ISA_B); /* bra.l */
   6161     INSN(branch,    60ff, ffff, BRAL);
   6162     INSN(branch,    60ff, f0ff, BCCL);
   6163 
   6164     BASE(moveq,     7000, f100);
   6165     INSN(mvzs,      7100, f100, CF_ISA_B);
   6166     BASE(or,        8000, f000);
   6167     BASE(divw,      80c0, f0c0);
   6168     INSN(sbcd_reg,  8100, f1f8, M68K);
   6169     INSN(sbcd_mem,  8108, f1f8, M68K);
   6170     BASE(addsub,    9000, f000);
   6171     INSN(undef,     90c0, f0c0, CF_ISA_A);
   6172     INSN(subx_reg,  9180, f1f8, CF_ISA_A);
   6173     INSN(subx_reg,  9100, f138, M68K);
   6174     INSN(subx_mem,  9108, f138, M68K);
   6175     INSN(suba,      91c0, f1c0, CF_ISA_A);
   6176     INSN(suba,      90c0, f0c0, M68K);
   6177 
   6178     BASE(undef_mac, a000, f000);
   6179     INSN(mac,       a000, f100, CF_EMAC);
   6180     INSN(from_mac,  a180, f9b0, CF_EMAC);
   6181     INSN(move_mac,  a110, f9fc, CF_EMAC);
   6182     INSN(from_macsr,a980, f9f0, CF_EMAC);
   6183     INSN(from_mask, ad80, fff0, CF_EMAC);
   6184     INSN(from_mext, ab80, fbf0, CF_EMAC);
   6185     INSN(macsr_to_ccr, a9c0, ffff, CF_EMAC);
   6186     INSN(to_mac,    a100, f9c0, CF_EMAC);
   6187     INSN(to_macsr,  a900, ffc0, CF_EMAC);
   6188     INSN(to_mext,   ab00, fbc0, CF_EMAC);
   6189     INSN(to_mask,   ad00, ffc0, CF_EMAC);
   6190 
   6191     INSN(mov3q,     a140, f1c0, CF_ISA_B);
   6192     INSN(cmp,       b000, f1c0, CF_ISA_B); /* cmp.b */
   6193     INSN(cmp,       b040, f1c0, CF_ISA_B); /* cmp.w */
   6194     INSN(cmpa,      b0c0, f1c0, CF_ISA_B); /* cmpa.w */
   6195     INSN(cmp,       b080, f1c0, CF_ISA_A);
   6196     INSN(cmpa,      b1c0, f1c0, CF_ISA_A);
   6197     INSN(cmp,       b000, f100, M68K);
   6198     INSN(eor,       b100, f100, M68K);
   6199     INSN(cmpm,      b108, f138, M68K);
   6200     INSN(cmpa,      b0c0, f0c0, M68K);
   6201     INSN(eor,       b180, f1c0, CF_ISA_A);
   6202     BASE(and,       c000, f000);
   6203     INSN(exg_dd,    c140, f1f8, M68K);
   6204     INSN(exg_aa,    c148, f1f8, M68K);
   6205     INSN(exg_da,    c188, f1f8, M68K);
   6206     BASE(mulw,      c0c0, f0c0);
   6207     INSN(abcd_reg,  c100, f1f8, M68K);
   6208     INSN(abcd_mem,  c108, f1f8, M68K);
   6209     BASE(addsub,    d000, f000);
   6210     INSN(undef,     d0c0, f0c0, CF_ISA_A);
   6211     INSN(addx_reg,      d180, f1f8, CF_ISA_A);
   6212     INSN(addx_reg,  d100, f138, M68K);
   6213     INSN(addx_mem,  d108, f138, M68K);
   6214     INSN(adda,      d1c0, f1c0, CF_ISA_A);
   6215     INSN(adda,      d0c0, f0c0, M68K);
   6216     INSN(shift_im,  e080, f0f0, CF_ISA_A);
   6217     INSN(shift_reg, e0a0, f0f0, CF_ISA_A);
   6218     INSN(shift8_im, e000, f0f0, M68K);
   6219     INSN(shift16_im, e040, f0f0, M68K);
   6220     INSN(shift_im,  e080, f0f0, M68K);
   6221     INSN(shift8_reg, e020, f0f0, M68K);
   6222     INSN(shift16_reg, e060, f0f0, M68K);
   6223     INSN(shift_reg, e0a0, f0f0, M68K);
   6224     INSN(shift_mem, e0c0, fcc0, M68K);
   6225     INSN(rotate_im, e090, f0f0, M68K);
   6226     INSN(rotate8_im, e010, f0f0, M68K);
   6227     INSN(rotate16_im, e050, f0f0, M68K);
   6228     INSN(rotate_reg, e0b0, f0f0, M68K);
   6229     INSN(rotate8_reg, e030, f0f0, M68K);
   6230     INSN(rotate16_reg, e070, f0f0, M68K);
   6231     INSN(rotate_mem, e4c0, fcc0, M68K);
   6232     INSN(bfext_mem, e9c0, fdc0, BITFIELD);  /* bfextu & bfexts */
   6233     INSN(bfext_reg, e9c0, fdf8, BITFIELD);
   6234     INSN(bfins_mem, efc0, ffc0, BITFIELD);
   6235     INSN(bfins_reg, efc0, fff8, BITFIELD);
   6236     INSN(bfop_mem, eac0, ffc0, BITFIELD);   /* bfchg */
   6237     INSN(bfop_reg, eac0, fff8, BITFIELD);   /* bfchg */
   6238     INSN(bfop_mem, ecc0, ffc0, BITFIELD);   /* bfclr */
   6239     INSN(bfop_reg, ecc0, fff8, BITFIELD);   /* bfclr */
   6240     INSN(bfop_mem, edc0, ffc0, BITFIELD);   /* bfffo */
   6241     INSN(bfop_reg, edc0, fff8, BITFIELD);   /* bfffo */
   6242     INSN(bfop_mem, eec0, ffc0, BITFIELD);   /* bfset */
   6243     INSN(bfop_reg, eec0, fff8, BITFIELD);   /* bfset */
   6244     INSN(bfop_mem, e8c0, ffc0, BITFIELD);   /* bftst */
   6245     INSN(bfop_reg, e8c0, fff8, BITFIELD);   /* bftst */
   6246     BASE(undef_fpu, f000, f000);
   6247     INSN(fpu,       f200, ffc0, CF_FPU);
   6248     INSN(fbcc,      f280, ffc0, CF_FPU);
   6249     INSN(fpu,       f200, ffc0, FPU);
   6250     INSN(fscc,      f240, ffc0, FPU);
   6251     INSN(ftrapcc,   f27a, fffe, FPU);       /* opmode 010, 011 */
   6252     INSN(ftrapcc,   f27c, ffff, FPU);       /* opmode 100 */
   6253     INSN(fbcc,      f280, ff80, FPU);
   6254 #if defined(CONFIG_SOFTMMU)
   6255     INSN(frestore,  f340, ffc0, CF_FPU);
   6256     INSN(fsave,     f300, ffc0, CF_FPU);
   6257     INSN(frestore,  f340, ffc0, FPU);
   6258     INSN(fsave,     f300, ffc0, FPU);
   6259     INSN(intouch,   f340, ffc0, CF_ISA_A);
   6260     INSN(cpushl,    f428, ff38, CF_ISA_A);
   6261     INSN(cpush,     f420, ff20, M68040);
   6262     INSN(cinv,      f400, ff20, M68040);
   6263     INSN(pflush,    f500, ffe0, M68040);
   6264     INSN(ptest,     f548, ffd8, M68040);
   6265     INSN(wddata,    fb00, ff00, CF_ISA_A);
   6266     INSN(wdebug,    fbc0, ffc0, CF_ISA_A);
   6267 #endif
   6268     INSN(move16_mem, f600, ffe0, M68040);
   6269     INSN(move16_reg, f620, fff8, M68040);
   6270 #undef INSN
   6271 }
   6272 
   6273 static void m68k_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
   6274 {
   6275     DisasContext *dc = container_of(dcbase, DisasContext, base);
   6276     CPUM68KState *env = cpu->env_ptr;
   6277 
   6278     dc->env = env;
   6279     dc->pc = dc->base.pc_first;
   6280     /* This value will always be filled in properly before m68k_tr_tb_stop. */
   6281     dc->pc_prev = 0xdeadbeef;
   6282     dc->cc_op = CC_OP_DYNAMIC;
   6283     dc->cc_op_synced = 1;
   6284     dc->done_mac = 0;
   6285     dc->writeback_mask = 0;
   6286     init_release_array(dc);
   6287 
   6288     dc->ss_active = (M68K_SR_TRACE(env->sr) == M68K_SR_TRACE_ANY_INS);
   6289     /* If architectural single step active, limit to 1 */
   6290     if (dc->ss_active) {
   6291         dc->base.max_insns = 1;
   6292     }
   6293 }
   6294 
   6295 static void m68k_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
   6296 {
   6297 }
   6298 
   6299 static void m68k_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
   6300 {
   6301     DisasContext *dc = container_of(dcbase, DisasContext, base);
   6302     tcg_gen_insn_start(dc->base.pc_next, dc->cc_op);
   6303 }
   6304 
   6305 static void m68k_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
   6306 {
   6307     DisasContext *dc = container_of(dcbase, DisasContext, base);
   6308     CPUM68KState *env = cpu->env_ptr;
   6309     uint16_t insn = read_im16(env, dc);
   6310 
   6311     opcode_table[insn](env, dc, insn);
   6312     do_writebacks(dc);
   6313     do_release(dc);
   6314 
   6315     dc->pc_prev = dc->base.pc_next;
   6316     dc->base.pc_next = dc->pc;
   6317 
   6318     if (dc->base.is_jmp == DISAS_NEXT) {
   6319         /*
   6320          * Stop translation when the next insn might touch a new page.
   6321          * This ensures that prefetch aborts at the right place.
   6322          *
   6323          * We cannot determine the size of the next insn without
   6324          * completely decoding it.  However, the maximum insn size
   6325          * is 32 bytes, so end if we do not have that much remaining.
   6326          * This may produce several small TBs at the end of each page,
   6327          * but they will all be linked with goto_tb.
   6328          *
   6329          * ??? ColdFire maximum is 4 bytes; MC68000's maximum is also
   6330          * smaller than MC68020's.
   6331          */
   6332         target_ulong start_page_offset
   6333             = dc->pc - (dc->base.pc_first & TARGET_PAGE_MASK);
   6334 
   6335         if (start_page_offset >= TARGET_PAGE_SIZE - 32) {
   6336             dc->base.is_jmp = DISAS_TOO_MANY;
   6337         }
   6338     }
   6339 }
   6340 
   6341 static void m68k_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
   6342 {
   6343     DisasContext *dc = container_of(dcbase, DisasContext, base);
   6344 
   6345     switch (dc->base.is_jmp) {
   6346     case DISAS_NORETURN:
   6347         break;
   6348     case DISAS_TOO_MANY:
   6349         update_cc_op(dc);
   6350         gen_jmp_tb(dc, 0, dc->pc, dc->pc_prev);
   6351         break;
   6352     case DISAS_JUMP:
   6353         /* We updated CC_OP and PC in gen_jmp/gen_jmp_im.  */
   6354         if (dc->ss_active) {
   6355             gen_raise_exception_format2(dc, EXCP_TRACE, dc->pc_prev);
   6356         } else {
   6357             tcg_gen_lookup_and_goto_ptr();
   6358         }
   6359         break;
   6360     case DISAS_EXIT:
   6361         /*
   6362          * We updated CC_OP and PC in gen_exit_tb, but also modified
   6363          * other state that may require returning to the main loop.
   6364          */
   6365         if (dc->ss_active) {
   6366             gen_raise_exception_format2(dc, EXCP_TRACE, dc->pc_prev);
   6367         } else {
   6368             tcg_gen_exit_tb(NULL, 0);
   6369         }
   6370         break;
   6371     default:
   6372         g_assert_not_reached();
   6373     }
   6374 }
   6375 
   6376 static void m68k_tr_disas_log(const DisasContextBase *dcbase,
   6377                               CPUState *cpu, FILE *logfile)
   6378 {
   6379     fprintf(logfile, "IN: %s\n", lookup_symbol(dcbase->pc_first));
   6380     target_disas(logfile, cpu, dcbase->pc_first, dcbase->tb->size);
   6381 }
   6382 
   6383 static const TranslatorOps m68k_tr_ops = {
   6384     .init_disas_context = m68k_tr_init_disas_context,
   6385     .tb_start           = m68k_tr_tb_start,
   6386     .insn_start         = m68k_tr_insn_start,
   6387     .translate_insn     = m68k_tr_translate_insn,
   6388     .tb_stop            = m68k_tr_tb_stop,
   6389     .disas_log          = m68k_tr_disas_log,
   6390 };
   6391 
   6392 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns,
   6393                            target_ulong pc, void *host_pc)
   6394 {
   6395     DisasContext dc;
   6396     translator_loop(cpu, tb, max_insns, pc, host_pc, &m68k_tr_ops, &dc.base);
   6397 }
   6398 
   6399 static double floatx80_to_double(CPUM68KState *env, uint16_t high, uint64_t low)
   6400 {
   6401     floatx80 a = { .high = high, .low = low };
   6402     union {
   6403         float64 f64;
   6404         double d;
   6405     } u;
   6406 
   6407     u.f64 = floatx80_to_float64(a, &env->fp_status);
   6408     return u.d;
   6409 }
   6410 
   6411 void m68k_cpu_dump_state(CPUState *cs, FILE *f, int flags)
   6412 {
   6413     M68kCPU *cpu = M68K_CPU(cs);
   6414     CPUM68KState *env = &cpu->env;
   6415     int i;
   6416     uint16_t sr;
   6417     for (i = 0; i < 8; i++) {
   6418         qemu_fprintf(f, "D%d = %08x   A%d = %08x   "
   6419                      "F%d = %04x %016"PRIx64"  (%12g)\n",
   6420                      i, env->dregs[i], i, env->aregs[i],
   6421                      i, env->fregs[i].l.upper, env->fregs[i].l.lower,
   6422                      floatx80_to_double(env, env->fregs[i].l.upper,
   6423                                         env->fregs[i].l.lower));
   6424     }
   6425     qemu_fprintf(f, "PC = %08x   ", env->pc);
   6426     sr = env->sr | cpu_m68k_get_ccr(env);
   6427     qemu_fprintf(f, "SR = %04x T:%x I:%x %c%c %c%c%c%c%c\n",
   6428                  sr, (sr & SR_T) >> SR_T_SHIFT, (sr & SR_I) >> SR_I_SHIFT,
   6429                  (sr & SR_S) ? 'S' : 'U', (sr & SR_M) ? '%' : 'I',
   6430                  (sr & CCF_X) ? 'X' : '-', (sr & CCF_N) ? 'N' : '-',
   6431                  (sr & CCF_Z) ? 'Z' : '-', (sr & CCF_V) ? 'V' : '-',
   6432                  (sr & CCF_C) ? 'C' : '-');
   6433     qemu_fprintf(f, "FPSR = %08x %c%c%c%c ", env->fpsr,
   6434                  (env->fpsr & FPSR_CC_A) ? 'A' : '-',
   6435                  (env->fpsr & FPSR_CC_I) ? 'I' : '-',
   6436                  (env->fpsr & FPSR_CC_Z) ? 'Z' : '-',
   6437                  (env->fpsr & FPSR_CC_N) ? 'N' : '-');
   6438     qemu_fprintf(f, "\n                                "
   6439                  "FPCR =     %04x ", env->fpcr);
   6440     switch (env->fpcr & FPCR_PREC_MASK) {
   6441     case FPCR_PREC_X:
   6442         qemu_fprintf(f, "X ");
   6443         break;
   6444     case FPCR_PREC_S:
   6445         qemu_fprintf(f, "S ");
   6446         break;
   6447     case FPCR_PREC_D:
   6448         qemu_fprintf(f, "D ");
   6449         break;
   6450     }
   6451     switch (env->fpcr & FPCR_RND_MASK) {
   6452     case FPCR_RND_N:
   6453         qemu_fprintf(f, "RN ");
   6454         break;
   6455     case FPCR_RND_Z:
   6456         qemu_fprintf(f, "RZ ");
   6457         break;
   6458     case FPCR_RND_M:
   6459         qemu_fprintf(f, "RM ");
   6460         break;
   6461     case FPCR_RND_P:
   6462         qemu_fprintf(f, "RP ");
   6463         break;
   6464     }
   6465     qemu_fprintf(f, "\n");
   6466 #ifdef CONFIG_SOFTMMU
   6467     qemu_fprintf(f, "%sA7(MSP) = %08x %sA7(USP) = %08x %sA7(ISP) = %08x\n",
   6468                  env->current_sp == M68K_SSP ? "->" : "  ", env->sp[M68K_SSP],
   6469                  env->current_sp == M68K_USP ? "->" : "  ", env->sp[M68K_USP],
   6470                  env->current_sp == M68K_ISP ? "->" : "  ", env->sp[M68K_ISP]);
   6471     qemu_fprintf(f, "VBR = 0x%08x\n", env->vbr);
   6472     qemu_fprintf(f, "SFC = %x DFC %x\n", env->sfc, env->dfc);
   6473     qemu_fprintf(f, "SSW %08x TCR %08x URP %08x SRP %08x\n",
   6474                  env->mmu.ssw, env->mmu.tcr, env->mmu.urp, env->mmu.srp);
   6475     qemu_fprintf(f, "DTTR0/1: %08x/%08x ITTR0/1: %08x/%08x\n",
   6476                  env->mmu.ttr[M68K_DTTR0], env->mmu.ttr[M68K_DTTR1],
   6477                  env->mmu.ttr[M68K_ITTR0], env->mmu.ttr[M68K_ITTR1]);
   6478     qemu_fprintf(f, "MMUSR %08x, fault at %08x\n",
   6479                  env->mmu.mmusr, env->mmu.ar);
   6480 #endif
   6481 }