Lines Matching +full:0 +full:- +full:9 +full:a +full:- +full:z

4  *  Copyright (c) 2005-2007 CodeSourcery
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * You should have received a copy of the GNU Lesser General Public
23 #include "exec/translation-block.h"
25 #include "tcg/tcg-op.h"
27 #include "qemu/qemu-print.h"
29 #include "exec/helper-proto.h"
30 #include "exec/helper-gen.h"
36 #include "exec/helper-info.c.inc"
82 -offsetof(M68kCPU, env) + in m68k_tcg_init()
85 -offsetof(M68kCPU, env) + in m68k_tcg_init()
90 for (i = 0; i < 8; i++) { in m68k_tcg_init()
95 sprintf(p, "A%d", i); in m68k_tcg_init()
100 for (i = 0; i < 4; i++) { in m68k_tcg_init()
107 NULL_QREG = tcg_global_mem_new(tcg_env, -4, "NULL"); in m68k_tcg_init()
108 store_dummy = tcg_global_mem_new(tcg_env, -8, "NULL"); in m68k_tcg_init()
128 if (s->writeback_mask & (1 << regno)) { in get_areg()
129 return s->writeback[regno]; in get_areg()
138 if (s->writeback_mask & (1 << regno)) { in delay_set_areg()
140 s->writeback[regno] = val; in delay_set_areg()
142 tcg_gen_mov_i32(s->writeback[regno], val); in delay_set_areg()
145 s->writeback_mask |= 1 << regno; in delay_set_areg()
147 s->writeback[regno] = val; in delay_set_areg()
150 s->writeback[regno] = tmp; in delay_set_areg()
158 unsigned mask = s->writeback_mask; in do_writebacks()
160 s->writeback_mask = 0; in do_writebacks()
163 tcg_gen_mov_i32(cpu_aregs[regno], s->writeback[regno]); in do_writebacks()
164 mask &= mask - 1; in do_writebacks()
176 #define IS_USER(s) (!(s->base.tb->flags & TB_FLAGS_MSR_S))
177 #define SFC_INDEX(s) ((s->base.tb->flags & TB_FLAGS_SFC_S) ? \
179 #define DFC_INDEX(s) ((s->base.tb->flags & TB_FLAGS_DFC_S) ? \
214 CCOp old_op = s->cc_op; in set_cc_op()
220 s->cc_op = op; in set_cc_op()
221 s->cc_op_synced = 0; in set_cc_op()
242 if (!s->cc_op_synced) { in update_cc_op()
243 s->cc_op_synced = 1; in update_cc_op()
244 tcg_gen_movi_i32(QREG_CC_OP, s->cc_op); in update_cc_op()
248 /* Generate a jump to an immediate address. */
253 s->base.is_jmp = DISAS_JUMP; in gen_jmp_im()
256 /* Generate a jump to the address in qreg DEST. */
261 s->base.is_jmp = DISAS_JUMP; in gen_jmp()
274 * for recording in the Format $2 (6-word) stack frame. in gen_raise_exception_format2()
275 * Re-use mmu.ar for the purpose, since that's only valid in gen_raise_exception_format2()
281 s->base.is_jmp = DISAS_NORETURN; in gen_raise_exception_format2()
291 s->base.is_jmp = DISAS_NORETURN; in gen_exception()
296 gen_exception(s, s->base.pc_next, EXCP_ADDRESS); in gen_addr_fault()
300 * Generate a load from the specified address. Narrow values are
313 opsize | (sign ? MO_SIGN : 0) | MO_TE); in gen_load()
321 /* Generate a store. */
343 * Generate an unsigned load if VAL is 0 a signed load if val is -1,
344 * otherwise generate a store.
357 /* Read a 16-bit immediate constant */
361 im = translator_lduw(env, &s->base, s->pc); in read_im16()
362 s->pc += 2; in read_im16()
366 /* Read an 8-bit immediate constant */
372 /* Read a 32-bit immediate constant. */
377 im |= 0xffff & read_im16(env, s); in read_im32()
381 /* Read a 64-bit immediate constant. */
396 add = (ext & 0x8000) ? AREG(ext, 12) : DREG(ext, 12); in gen_addr_index()
397 if ((ext & 0x800) == 0) { in gen_addr_index()
401 scale = (ext >> 9) & 3; in gen_addr_index()
402 if (scale != 0) { in gen_addr_index()
410 * Handle a base + index + displacement effective address.
411 * A NULL_QREG base means pc-relative.
421 offset = s->pc; in gen_lea_indexed()
424 if ((ext & 0x800) == 0 && !m68k_feature(s->env, M68K_FEATURE_WORD_INDEX)) in gen_lea_indexed()
427 if (m68k_feature(s->env, M68K_FEATURE_M68K) && in gen_lea_indexed()
428 !m68k_feature(s->env, M68K_FEATURE_SCALED_INDEX)) { in gen_lea_indexed()
429 ext &= ~(3 << 9); in gen_lea_indexed()
432 if (ext & 0x100) { in gen_lea_indexed()
434 if (!m68k_feature(s->env, M68K_FEATURE_EXT_FULL)) in gen_lea_indexed()
437 if ((ext & 0x30) > 0x10) { in gen_lea_indexed()
439 if ((ext & 0x30) == 0x20) { in gen_lea_indexed()
445 bd = 0; in gen_lea_indexed()
448 if ((ext & 0x44) == 0) { in gen_lea_indexed()
449 /* pre-index */ in gen_lea_indexed()
454 if ((ext & 0x80) == 0) { in gen_lea_indexed()
458 bd = 0; in gen_lea_indexed()
468 if (bd != 0) { in gen_lea_indexed()
475 if ((ext & 3) != 0) { in gen_lea_indexed()
477 base = gen_load(s, OS_LONG, add, 0, IS_USER(s)); in gen_lea_indexed()
478 if ((ext & 0x44) == 4) { in gen_lea_indexed()
493 od = 0; in gen_lea_indexed()
495 if (od != 0) { in gen_lea_indexed()
516 /* Sign or zero extend a value. */
524 tcg_gen_ext_i32(res, val, opsize | (sign ? MO_SIGN : 0)); in gen_ext()
537 switch (s->cc_op) { in gen_flush_flags()
550 gen_ext(t0, t0, s->cc_op - CC_OP_ADDB, 1); in gen_flush_flags()
565 gen_ext(t0, t0, s->cc_op - CC_OP_SUBB, 1); in gen_flush_flags()
576 gen_ext(QREG_CC_Z, QREG_CC_Z, s->cc_op - CC_OP_CMPB, 1); in gen_flush_flags()
587 tcg_gen_movi_i32(QREG_CC_C, 0); in gen_flush_flags()
588 tcg_gen_movi_i32(QREG_CC_V, 0); in gen_flush_flags()
593 s->cc_op_synced = 1; in gen_flush_flags()
597 gen_helper_flush_flags(tcg_env, tcg_constant_i32(s->cc_op)); in gen_flush_flags()
598 s->cc_op_synced = 1; in gen_flush_flags()
602 /* Note that flush_flags also assigned to env->cc_op. */ in gen_flush_flags()
603 s->cc_op = CC_OP_FLAGS; in gen_flush_flags()
657 case 0: return OS_BYTE; in insn_opsize()
668 case 0: return OS_LONG; in ext_opsize()
681 * Assign value to a register. If the width is less than the register width
688 tcg_gen_deposit_i32(reg, reg, val, 0, 8); in gen_partset_reg()
691 tcg_gen_deposit_i32(reg, reg, val, 0, 16); in gen_partset_reg()
715 case 0: /* Data register direct. */ in gen_lea_mode()
734 m68k_feature(s->env, M68K_FEATURE_M68K)) { in gen_lea_mode()
751 case 0: /* Absolute short. */ in gen_lea_mode()
758 offset = s->pc; in gen_lea_mode()
779 int reg0 = REG(insn, 0); in gen_lea()
784 * Generate code to load/store a value from/into an EA. If WHAT > 0 this is
785 * a write otherwise it is a read (0 == sign extend, -1 == zero extend).
786 * ADDRP is non-null for readwrite operands.
796 case 0: /* Data register direct. */ in gen_ea_mode()
821 m68k_feature(s->env, M68K_FEATURE_M68K)) { in gen_ea_mode()
863 case 0: /* Absolute short. */ in gen_ea_mode()
904 int reg0 = REG(insn, 0); in gen_ea()
960 if (m68k_feature(s->env, M68K_FEATURE_CF_FPU)) { in gen_load_fp()
961 gen_exception(s, s->base.pc_next, EXCP_FP_UNIMP); in gen_load_fp()
976 gen_exception(s, s->base.pc_next, EXCP_FP_UNIMP); in gen_load_fp()
1007 if (m68k_feature(s->env, M68K_FEATURE_CF_FPU)) { in gen_store_fp()
1008 gen_exception(s, s->base.pc_next, EXCP_FP_UNIMP); in gen_store_fp()
1023 gen_exception(s, s->base.pc_next, EXCP_FP_UNIMP); in gen_store_fp()
1048 case 0: /* Data register direct. */ in gen_ea_mode_fp()
1079 return 0; in gen_ea_mode_fp()
1081 return -1; in gen_ea_mode_fp()
1085 return 0; in gen_ea_mode_fp()
1090 return 0; in gen_ea_mode_fp()
1094 return -1; in gen_ea_mode_fp()
1098 return 0; in gen_ea_mode_fp()
1104 return -1; in gen_ea_mode_fp()
1107 return 0; in gen_ea_mode_fp()
1110 case 0: /* Absolute short. */ in gen_ea_mode_fp()
1117 return -1; in gen_ea_mode_fp()
1141 if (m68k_feature(s->env, M68K_FEATURE_CF_FPU)) { in gen_ea_mode_fp()
1142 gen_exception(s, s->base.pc_next, EXCP_FP_UNIMP); in gen_ea_mode_fp()
1155 gen_exception(s, s->base.pc_next, EXCP_FP_UNIMP); in gen_ea_mode_fp()
1160 return 0; in gen_ea_mode_fp()
1162 return -1; in gen_ea_mode_fp()
1165 return -1; in gen_ea_mode_fp()
1172 int reg0 = REG(insn, 0); in gen_ea_fp()
1186 CCOp op = s->cc_op; in gen_cc_cond()
1190 c->v1 = QREG_CC_N; in gen_cc_cond()
1191 c->v2 = QREG_CC_V; in gen_cc_cond()
1207 c->v2 = tcg_constant_i32(0); in gen_cc_cond()
1208 c->v1 = tmp = tcg_temp_new(); in gen_cc_cond()
1210 gen_ext(tmp, tmp, op - CC_OP_CMPB, 1); in gen_cc_cond()
1223 c->v2 = tcg_constant_i32(0); in gen_cc_cond()
1226 case 0: /* T */ in gen_cc_cond()
1228 c->v1 = c->v2; in gen_cc_cond()
1231 case 14: /* GT (!(Z || (N ^ V))) */ in gen_cc_cond()
1232 case 15: /* LE (Z || (N ^ V)) */ in gen_cc_cond()
1234 * Logic operations clear V, which simplifies LE to (Z || N), in gen_cc_cond()
1235 * and since Z and N are co-located, this becomes a normal in gen_cc_cond()
1239 c->v1 = QREG_CC_N; in gen_cc_cond()
1257 c->v1 = QREG_CC_N; in gen_cc_cond()
1262 case 6: /* NE (!Z) */ in gen_cc_cond()
1263 case 7: /* EQ (Z) */ in gen_cc_cond()
1264 /* Some cases fold Z into N. */ in gen_cc_cond()
1269 c->v1 = QREG_CC_N; in gen_cc_cond()
1279 c->v1 = QREG_CC_X; in gen_cc_cond()
1284 case 9: /* VS (V) */ in gen_cc_cond()
1288 c->v1 = c->v2; in gen_cc_cond()
1298 case 0: /* T */ in gen_cc_cond()
1303 case 2: /* HI (!C && !Z) -> !(C || Z)*/ in gen_cc_cond()
1304 case 3: /* LS (C || Z) */ in gen_cc_cond()
1305 c->v1 = tmp = tcg_temp_new(); in gen_cc_cond()
1306 tcg_gen_setcond_i32(TCG_COND_EQ, tmp, QREG_CC_Z, c->v2); in gen_cc_cond()
1312 c->v1 = QREG_CC_C; in gen_cc_cond()
1315 case 6: /* NE (!Z) */ in gen_cc_cond()
1316 case 7: /* EQ (Z) */ in gen_cc_cond()
1317 c->v1 = QREG_CC_Z; in gen_cc_cond()
1321 case 9: /* VS (V) */ in gen_cc_cond()
1322 c->v1 = QREG_CC_V; in gen_cc_cond()
1327 c->v1 = QREG_CC_N; in gen_cc_cond()
1332 c->v1 = tmp = tcg_temp_new(); in gen_cc_cond()
1336 case 14: /* GT (!(Z || (N ^ V))) */ in gen_cc_cond()
1337 case 15: /* LE (Z || (N ^ V)) */ in gen_cc_cond()
1338 c->v1 = tmp = tcg_temp_new(); in gen_cc_cond()
1339 tcg_gen_negsetcond_i32(TCG_COND_EQ, tmp, QREG_CC_Z, c->v2); in gen_cc_cond()
1348 if ((cond & 1) == 0) { in gen_cc_cond()
1351 c->tcond = tcond; in gen_cc_cond()
1363 /* Force a TB lookup after an instruction that changes the CPU state. */
1367 tcg_gen_movi_i32(QREG_PC, s->pc); in gen_exit_tb()
1368 s->base.is_jmp = DISAS_EXIT; in gen_exit_tb()
1378 } while (0)
1387 } while (0)
1389 /* Generate a jump to an immediate address. */
1393 if (unlikely(s->ss_active)) { in gen_jmp_tb()
1397 } else if (translator_use_goto_tb(&s->base, dest)) { in gen_jmp_tb()
1400 tcg_gen_exit_tb(s->base.tb, n); in gen_jmp_tb()
1403 tcg_gen_exit_tb(NULL, 0); in gen_jmp_tb()
1405 s->base.is_jmp = DISAS_NORETURN; in gen_jmp_tb()
1418 * "The semihosting instruction is immediately preceded by a in semihosting_test()
1419 * nop aligned to a 4-byte boundary..." in semihosting_test()
1420 * The preceding 2-byte (aligned) nop plus the 2-byte halt/bkpt in semihosting_test()
1423 if (s->pc % 4 != 0) { in semihosting_test()
1426 test = translator_lduw(s->env, &s->base, s->pc - 4); in semihosting_test()
1427 if (test != 0x4e71) { in semihosting_test()
1430 /* "... and followed by an invalid sentinel instruction movec %sp,0." */ in semihosting_test()
1431 test = translator_ldl(s->env, &s->base, s->pc); in semihosting_test()
1432 if (test != 0x4e7bf000) { in semihosting_test()
1437 s->pc += 4; in semihosting_test()
1448 cond = (insn >> 8) & 0xf; in DISAS_INSN()
1465 reg = DREG(insn, 0); in DISAS_INSN()
1466 base = s->pc; in DISAS_INSN()
1469 gen_jmpcc(s, (insn >> 8) & 0xf, l1); in DISAS_INSN()
1473 tcg_gen_addi_i32(tmp, tmp, -1); in DISAS_INSN()
1475 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, -1, l1); in DISAS_INSN()
1476 gen_jmp_tb(s, 1, base + offset, s->base.pc_next); in DISAS_INSN()
1478 gen_jmp_tb(s, 0, s->pc, s->base.pc_next); in DISAS_INSN()
1483 gen_exception(s, s->base.pc_next, EXCP_LINEA); in DISAS_INSN()
1488 gen_exception(s, s->base.pc_next, EXCP_LINEF); in DISAS_INSN()
1496 * but actually illegal for CPU32 or pre-68020. in DISAS_INSN()
1499 insn, s->base.pc_next); in DISAS_INSN()
1500 gen_exception(s, s->base.pc_next, EXCP_ILLEGAL); in DISAS_INSN()
1510 sign = (insn & 0x100) != 0; in DISAS_INSN()
1511 reg = DREG(insn, 9); in DISAS_INSN()
1530 /* divX.w <EA>,Dn 32/16 -> 16r:16q */ in DISAS_INSN()
1532 sign = (insn & 0x100) != 0; in DISAS_INSN()
1537 destr = tcg_constant_i32(REG(insn, 9)); in DISAS_INSN()
1538 ilen = tcg_constant_i32(s->pc - s->base.pc_next); in DISAS_INSN()
1556 sign = (ext & 0x0800) != 0; in DISAS_INSN()
1558 if (ext & 0x400) { in DISAS_INSN()
1559 if (!m68k_feature(s->env, M68K_FEATURE_QUAD_MULDIV)) { in DISAS_INSN()
1560 gen_exception(s, s->base.pc_next, EXCP_ILLEGAL); in DISAS_INSN()
1564 /* divX.l <EA>, Dr:Dq 64/32 -> 32r:32q */ in DISAS_INSN()
1566 SRC_EA(env, den, OS_LONG, 0, NULL); in DISAS_INSN()
1568 reg = tcg_constant_i32(REG(ext, 0)); in DISAS_INSN()
1569 ilen = tcg_constant_i32(s->pc - s->base.pc_next); in DISAS_INSN()
1579 /* divX.l <EA>, Dq 32/32 -> 32q */ in DISAS_INSN()
1580 /* divXl.l <EA>, Dr:Dq 32/32 -> 32r:32q */ in DISAS_INSN()
1582 SRC_EA(env, den, OS_LONG, 0, NULL); in DISAS_INSN()
1584 reg = tcg_constant_i32(REG(ext, 0)); in DISAS_INSN()
1585 ilen = tcg_constant_i32(s->pc - s->base.pc_next); in DISAS_INSN()
1603 * t2 = t1 + 0x066 in bcd_add()
1607 * t6 = ~t5 & 0x110 in bcd_add()
1609 * return t3 - t7 in bcd_add()
1613 * t1 = (src + 0x066) + dest + X in bcd_add()
1614 * = result with some possible exceeding 0x6 in bcd_add()
1618 tcg_gen_addi_i32(t0, src, 0x066); in bcd_add()
1624 /* we will remove exceeding 0x6 where there is no carry */ in bcd_add()
1627 * t0 = (src + 0x0066) ^ dest in bcd_add()
1642 * generate 0x1 where there is no carry in bcd_add()
1643 * and for each 0x10, generate a 0x6 in bcd_add()
1648 tcg_gen_andi_i32(t0, t0, 0x22); in bcd_add()
1653 * remove the exceeding 0x6 in bcd_add()
1654 * for digits that have not generated a carry in bcd_add()
1665 * dest10 = dest10 - src10 - X in bcd_sub()
1666 * = bcd_add(dest + 1 - X, 0x199 - src) in bcd_sub()
1669 /* t0 = 0x066 + (0x199 - src) */ in bcd_sub()
1672 tcg_gen_subfi_i32(t0, 0x1ff, src); in bcd_sub()
1674 /* t1 = t0 + dest + 1 - X*/ in bcd_sub()
1691 * t2 = ~t0 & 0x110 in bcd_sub()
1696 * t2 = ~(t0 >> 3) & 0x22 in bcd_sub()
1703 tcg_gen_andi_i32(t2, t2, 0x22); in bcd_sub()
1707 /* return t1 - t0 */ in bcd_sub()
1714 tcg_gen_andi_i32(QREG_CC_C, val, 0x0ff); in bcd_flags()
1727 gen_flush_flags(s); /* !Z is sticky */ in DISAS_INSN()
1729 src = gen_extend(s, DREG(insn, 0), OS_BYTE, 0); in DISAS_INSN()
1730 dest = gen_extend(s, DREG(insn, 9), OS_BYTE, 0); in DISAS_INSN()
1732 gen_partset_reg(OS_BYTE, DREG(insn, 9), dest); in DISAS_INSN()
1741 gen_flush_flags(s); /* !Z is sticky */ in DISAS_INSN()
1743 /* Indirect pre-decrement load (mode 4) */ in DISAS_INSN()
1745 src = gen_ea_mode(env, s, 4, REG(insn, 0), OS_BYTE, in DISAS_INSN()
1747 dest = gen_ea_mode(env, s, 4, REG(insn, 9), OS_BYTE, in DISAS_INSN()
1752 gen_ea_mode(env, s, 4, REG(insn, 9), OS_BYTE, dest, &addr, in DISAS_INSN()
1762 gen_flush_flags(s); /* !Z is sticky */ in DISAS_INSN()
1764 src = gen_extend(s, DREG(insn, 0), OS_BYTE, 0); in DISAS_INSN()
1765 dest = gen_extend(s, DREG(insn, 9), OS_BYTE, 0); in DISAS_INSN()
1769 gen_partset_reg(OS_BYTE, DREG(insn, 9), dest); in DISAS_INSN()
1778 gen_flush_flags(s); /* !Z is sticky */ in DISAS_INSN()
1780 /* Indirect pre-decrement load (mode 4) */ in DISAS_INSN()
1782 src = gen_ea_mode(env, s, 4, REG(insn, 0), OS_BYTE, in DISAS_INSN()
1784 dest = gen_ea_mode(env, s, 4, REG(insn, 9), OS_BYTE, in DISAS_INSN()
1789 gen_ea_mode(env, s, 4, REG(insn, 9), OS_BYTE, dest, &addr, in DISAS_INSN()
1800 gen_flush_flags(s); /* !Z is sticky */ in DISAS_INSN()
1802 SRC_EA(env, src, OS_BYTE, 0, &addr); in DISAS_INSN()
1805 tcg_gen_movi_i32(dest, 0); in DISAS_INSN()
1823 add = (insn & 0x4000) != 0; in DISAS_INSN()
1825 reg = gen_extend(s, DREG(insn, 9), opsize, 1); in DISAS_INSN()
1827 if (insn & 0x100) { in DISAS_INSN()
1844 if (insn & 0x100) { in DISAS_INSN()
1847 gen_partset_reg(opsize, DREG(insn, 9), dest); in DISAS_INSN()
1855 reg = DREG(insn, 0); in DISAS_INSN()
1869 if ((insn & 0x38) != 0) in DISAS_INSN()
1874 SRC_EA(env, src1, opsize, 0, op ? &addr: NULL); in DISAS_INSN()
1879 tcg_gen_andi_i32(src2, DREG(insn, 9), 7); in DISAS_INSN()
1881 tcg_gen_andi_i32(src2, DREG(insn, 9), 31); in DISAS_INSN()
1910 reg = DREG(insn, 0); in DISAS_INSN()
1939 int is_load = (insn & 0x0400) != 0; in DISAS_INSN()
1940 int opsize = (insn & 0x40) != 0 ? OS_LONG : OS_WORD; in DISAS_INSN()
1943 int reg0 = REG(insn, 0); in DISAS_INSN()
1949 case 0: /* data register direct */ in DISAS_INSN()
1958 case 3: /* indirect post-increment */ in DISAS_INSN()
1960 /* post-increment is not allowed */ in DISAS_INSN()
1965 case 4: /* indirect pre-decrement */ in DISAS_INSN()
1967 /* pre-decrement is not allowed */ in DISAS_INSN()
1971 * We want a bare copy of the address reg, without any pre-decrement in DISAS_INSN()
1990 for (i = 0; i < 16; i++) { in DISAS_INSN()
1996 for (i = 0; i < 16; i++) { in DISAS_INSN()
2002 /* post-increment: movem (An)+,X */ in DISAS_INSN()
2008 /* pre-decrement: movem X,-(An) */ in DISAS_INSN()
2009 for (i = 15; i >= 0; i--) { in DISAS_INSN()
2010 if ((mask << i) & 0x8000) { in DISAS_INSN()
2013 m68k_feature(s->env, M68K_FEATURE_EXT_FULL)) { in DISAS_INSN()
2032 for (i = 0; i < 16; i++) { in DISAS_INSN()
2053 addr = AREG(insn, 0); in DISAS_INSN()
2054 reg = DREG(insn, 9); in DISAS_INSN()
2060 if (insn & 0x40) { in DISAS_INSN()
2066 if (insn & 0x80) { in DISAS_INSN()
2067 for ( ; i > 0 ; i--) { in DISAS_INSN()
2068 tcg_gen_shri_i32(dbuf, reg, (i - 1) * 8); in DISAS_INSN()
2075 for ( ; i > 0 ; i--) { in DISAS_INSN()
2077 tcg_gen_deposit_i32(reg, reg, dbuf, (i - 1) * 8, 8); in DISAS_INSN()
2095 if ((insn & 0x38) != 0) in DISAS_INSN()
2102 if (m68k_feature(s->env, M68K_FEATURE_M68K)) { in DISAS_INSN()
2103 if (bitnum & 0xfe00) { in DISAS_INSN()
2108 if (bitnum & 0xff00) { in DISAS_INSN()
2114 SRC_EA(env, src1, opsize, 0, op ? &addr: NULL); in DISAS_INSN()
2161 tcg_gen_andi_i32(sr, QREG_SR, 0xffe0); in gen_get_sr()
2169 tcg_gen_movi_i32(QREG_CC_C, val & CCF_C ? 1 : 0); in gen_set_sr_im()
2170 tcg_gen_movi_i32(QREG_CC_V, val & CCF_V ? -1 : 0); in gen_set_sr_im()
2171 tcg_gen_movi_i32(QREG_CC_Z, val & CCF_Z ? 0 : 1); in gen_set_sr_im()
2172 tcg_gen_movi_i32(QREG_CC_N, val & CCF_N ? -1 : 0); in gen_set_sr_im()
2173 tcg_gen_movi_i32(QREG_CC_X, val & CCF_X ? 1 : 0); in gen_set_sr_im()
2197 if ((insn & 0x3f) == 0x3c) { in gen_move_to_sr()
2203 SRC_EA(env, src, OS_WORD, 0, NULL); in gen_move_to_sr()
2216 bool with_SR = ((insn & 0x3f) == 0x3c); in DISAS_INSN()
2218 op = (insn >> 9) & 7; in DISAS_INSN()
2246 gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE); in DISAS_INSN()
2261 case 0: /* ori */ in DISAS_INSN()
2322 switch ((insn >> 9) & 3) { in DISAS_INSN()
2349 cmp = gen_extend(s, DREG(ext, 0), opsize, 1); in DISAS_INSN()
2364 gen_partset_reg(opsize, DREG(ext, 0), load); in DISAS_INSN()
2368 tcg_gen_addi_i32(AREG(insn, 0), addr, opsize_bytes(opsize)); in DISAS_INSN()
2371 tcg_gen_mov_i32(AREG(insn, 0), addr); in DISAS_INSN()
2385 if (ext1 & 0x8000) { in DISAS_INSN()
2394 if (ext2 & 0x8000) { in DISAS_INSN()
2411 if (tb_cflags(s->base.tb) & CF_PARALLEL) { in DISAS_INSN()
2416 (REG(ext2, 0) << 6) | in DISAS_INSN()
2417 (REG(ext1, 0) << 9)); in DISAS_INSN()
2421 /* Note that cas2w also assigned to env->cc_op. */ in DISAS_INSN()
2422 s->cc_op = CC_OP_CMPW; in DISAS_INSN()
2423 s->cc_op_synced = 1; in DISAS_INSN()
2435 if (ext1 & 0x8000) { in DISAS_INSN()
2444 if (ext2 & 0x8000) { in DISAS_INSN()
2463 (REG(ext2, 0) << 6) | in DISAS_INSN()
2464 (REG(ext1, 0) << 9)); in DISAS_INSN()
2465 if (tb_cflags(s->base.tb) & CF_PARALLEL) { in DISAS_INSN()
2471 /* Note that cas2l also assigned to env->cc_op. */ in DISAS_INSN()
2472 s->cc_op = CC_OP_CMPL; in DISAS_INSN()
2473 s->cc_op_synced = 1; in DISAS_INSN()
2480 reg = DREG(insn, 0); in DISAS_INSN()
2509 dest = AREG(insn, 9); in DISAS_INSN()
2514 dest_ea = ((insn >> 9) & 7) | (op << 3); in DISAS_INSN()
2523 TCGv z; in DISAS_INSN() local
2531 gen_flush_flags(s); /* compute old Z */ in DISAS_INSN()
2535 * (X, N) = -(src + X); in DISAS_INSN()
2538 z = tcg_constant_i32(0); in DISAS_INSN()
2539 tcg_gen_add2_i32(QREG_CC_N, QREG_CC_X, src, z, QREG_CC_X, z); in DISAS_INSN()
2540 tcg_gen_sub2_i32(QREG_CC_N, QREG_CC_X, z, z, QREG_CC_N, QREG_CC_X); in DISAS_INSN()
2546 * Compute signed-overflow for negation. The normal formula for in DISAS_INSN()
2547 * subtraction is (res ^ src) & (src ^ dest), but with dest==0 in DISAS_INSN()
2554 tcg_gen_or_i32(QREG_CC_Z, QREG_CC_Z, QREG_CC_N); /* !Z is sticky */ in DISAS_INSN()
2569 reg = AREG(insn, 9); in DISAS_INSN()
2583 zero = tcg_constant_i32(0); in DISAS_INSN()
2610 tcg_gen_setcondi_i32(TCG_COND_NE, QREG_CC_X, dest, 0); in DISAS_INSN()
2642 reg = DREG(insn, 0); in DISAS_INSN()
2652 gen_exception(s, s->base.pc_next, EXCP_DEBUG); in DISAS_INSN()
2654 /* BKPT #0 is the alternate semihosting instruction. */ in DISAS_INSN()
2655 if ((insn & 7) == 0 && semihosting_test(s)) { in DISAS_INSN()
2656 gen_exception(s, s->pc, EXCP_SEMIHOSTING); in DISAS_INSN()
2659 gen_exception(s, s->base.pc_next, EXCP_ILLEGAL); in DISAS_INSN()
2681 reg = DREG(insn, 0); in DISAS_INSN()
2707 /* Implemented as a NOP. */ in DISAS_INSN()
2712 gen_exception(s, s->base.pc_next, EXCP_ILLEGAL); in DISAS_INSN()
2718 int reg0 = REG(insn, 0); in DISAS_INSN()
2720 if (mode == 0) { in DISAS_INSN()
2724 tcg_gen_ori_tl(dest, dest, 0x80); in DISAS_INSN()
2734 tcg_gen_atomic_fetch_or_tl(src1, addr, tcg_constant_tl(0x80), in DISAS_INSN()
2740 tcg_gen_addi_i32(AREG(insn, 0), addr, 1); in DISAS_INSN()
2743 tcg_gen_mov_i32(AREG(insn, 0), addr); in DISAS_INSN()
2757 sign = ext & 0x800; in DISAS_INSN()
2759 if (ext & 0x400) { in DISAS_INSN()
2760 if (!m68k_feature(s->env, M68K_FEATURE_QUAD_MULDIV)) { in DISAS_INSN()
2761 gen_exception(s, s->base.pc_next, EXCP_ILLEGAL); in DISAS_INSN()
2765 SRC_EA(env, src1, OS_LONG, 0, NULL); in DISAS_INSN()
2773 tcg_gen_mov_i32(DREG(ext, 0), QREG_CC_N); in DISAS_INSN()
2777 tcg_gen_movi_i32(QREG_CC_V, 0); in DISAS_INSN()
2778 tcg_gen_movi_i32(QREG_CC_C, 0); in DISAS_INSN()
2783 SRC_EA(env, src1, OS_LONG, 0, NULL); in DISAS_INSN()
2784 if (m68k_feature(s->env, M68K_FEATURE_M68K)) { in DISAS_INSN()
2785 tcg_gen_movi_i32(QREG_CC_C, 0); in DISAS_INSN()
2788 /* QREG_CC_V is -(QREG_CC_V != (QREG_CC_N >> 31)) */ in DISAS_INSN()
2794 /* QREG_CC_V is -(QREG_CC_V != 0), use QREG_CC_C as 0 */ in DISAS_INSN()
2818 reg = AREG(insn, 0); in gen_link()
2851 reg = AREG(insn, 0); in DISAS_INSN()
2853 tmp = gen_load(s, OS_LONG, src, 0, IS_USER(s)); in DISAS_INSN()
2862 gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE); in DISAS_INSN()
2879 tmp = gen_load(s, OS_LONG, QREG_SP, 0, IS_USER(s)); in DISAS_INSN()
2891 ccr = gen_load(s, OS_WORD, QREG_SP, 0, IS_USER(s)); in DISAS_INSN()
2893 tmp = gen_load(s, OS_LONG, sp, 0, IS_USER(s)); in DISAS_INSN()
2905 tmp = gen_load(s, OS_LONG, QREG_SP, 0, IS_USER(s)); in DISAS_INSN()
2923 if ((insn & 0x40) == 0) { in DISAS_INSN()
2925 gen_push(s, tcg_constant_i32(s->pc)); in DISAS_INSN()
2946 imm = (insn >> 9) & 7; in DISAS_INSN()
2947 if (imm == 0) { in DISAS_INSN()
2953 if ((insn & 0x38) == 0x08) { in DISAS_INSN()
2958 if (insn & 0x0100) { in DISAS_INSN()
2964 if (insn & 0x0100) { in DISAS_INSN()
2984 base = s->pc; in DISAS_INSN()
2985 op = (insn >> 8) & 0xf; in DISAS_INSN()
2987 if (offset == 0) { in DISAS_INSN()
2989 } else if (offset == -1) { in DISAS_INSN()
2994 gen_push(s, tcg_constant_i32(s->pc)); in DISAS_INSN()
2999 gen_jmpcc(s, ((insn >> 8) & 0xf) ^ 1, l1); in DISAS_INSN()
3000 gen_jmp_tb(s, 1, base + offset, s->base.pc_next); in DISAS_INSN()
3002 gen_jmp_tb(s, 0, s->pc, s->base.pc_next); in DISAS_INSN()
3006 gen_jmp_tb(s, 0, base + offset, s->base.pc_next); in DISAS_INSN()
3012 tcg_gen_movi_i32(DREG(insn, 9), (int8_t)insn); in DISAS_INSN()
3013 gen_logic_cc(s, DREG(insn, 9), OS_LONG); in DISAS_INSN()
3022 if (insn & 0x40) in DISAS_INSN()
3026 SRC_EA(env, src, opsize, (insn & 0x80) == 0, NULL); in DISAS_INSN()
3027 reg = DREG(insn, 9); in DISAS_INSN()
3041 reg = gen_extend(s, DREG(insn, 9), opsize, 0); in DISAS_INSN()
3043 if (insn & 0x100) { in DISAS_INSN()
3044 SRC_EA(env, src, opsize, 0, &addr); in DISAS_INSN()
3048 SRC_EA(env, src, opsize, 0, NULL); in DISAS_INSN()
3050 gen_partset_reg(opsize, DREG(insn, 9), dest); in DISAS_INSN()
3060 SRC_EA(env, src, (insn & 0x100) ? OS_LONG : OS_WORD, 1, NULL); in DISAS_INSN()
3061 reg = AREG(insn, 9); in DISAS_INSN()
3069 gen_flush_flags(s); /* compute old Z */ in gen_subx()
3073 * (X, N) = dest - (src + X); in gen_subx()
3076 zero = tcg_constant_i32(0); in gen_subx()
3082 /* Compute signed-overflow for subtract. */ in gen_subx()
3090 tcg_gen_or_i32(QREG_CC_Z, QREG_CC_Z, QREG_CC_N); /* !Z is sticky */ in gen_subx()
3106 src = gen_extend(s, DREG(insn, 0), opsize, 1); in DISAS_INSN()
3107 dest = gen_extend(s, DREG(insn, 9), opsize, 1); in DISAS_INSN()
3111 gen_partset_reg(opsize, DREG(insn, 9), QREG_CC_N); in DISAS_INSN()
3124 addr_src = AREG(insn, 0); in DISAS_INSN()
3128 addr_dest = AREG(insn, 9); in DISAS_INSN()
3142 val = (insn >> 9) & 7; in DISAS_INSN()
3143 if (val == 0) { in DISAS_INSN()
3144 val = -1; in DISAS_INSN()
3159 reg = gen_extend(s, DREG(insn, 9), opsize, 1); in DISAS_INSN()
3169 if (insn & 0x100) { in DISAS_INSN()
3175 reg = AREG(insn, 9); in DISAS_INSN()
3184 /* Post-increment load (mode 3) from Ay. */ in DISAS_INSN()
3185 src = gen_ea_mode(env, s, 3, REG(insn, 0), opsize, in DISAS_INSN()
3187 /* Post-increment load (mode 3) from Ax. */ in DISAS_INSN()
3188 dst = gen_ea_mode(env, s, 3, REG(insn, 9), opsize, in DISAS_INSN()
3203 SRC_EA(env, src, opsize, 0, &addr); in DISAS_INSN()
3205 tcg_gen_xor_i32(dest, src, DREG(insn, 9)); in DISAS_INSN()
3221 do_exg(DREG(insn, 9), DREG(insn, 0)); in DISAS_INSN()
3227 do_exg(AREG(insn, 9), AREG(insn, 0)); in DISAS_INSN()
3233 do_exg(DREG(insn, 9), AREG(insn, 0)); in DISAS_INSN()
3247 reg = DREG(insn, 9); in DISAS_INSN()
3248 if (insn & 0x100) { in DISAS_INSN()
3249 SRC_EA(env, src, opsize, 0, &addr); in DISAS_INSN()
3253 SRC_EA(env, src, opsize, 0, NULL); in DISAS_INSN()
3265 SRC_EA(env, src, (insn & 0x100) ? OS_LONG : OS_WORD, 1, NULL); in DISAS_INSN()
3266 reg = AREG(insn, 9); in DISAS_INSN()
3274 gen_flush_flags(s); /* compute old Z */ in gen_addx()
3281 zero = tcg_constant_i32(0); in gen_addx()
3286 /* Compute signed-overflow for addition. */ in gen_addx()
3294 tcg_gen_or_i32(QREG_CC_Z, QREG_CC_Z, QREG_CC_N); /* !Z is sticky */ in gen_addx()
3310 dest = gen_extend(s, DREG(insn, 9), opsize, 1); in DISAS_INSN()
3311 src = gen_extend(s, DREG(insn, 0), opsize, 1); in DISAS_INSN()
3315 gen_partset_reg(opsize, DREG(insn, 9), QREG_CC_N); in DISAS_INSN()
3328 addr_src = AREG(insn, 0); in DISAS_INSN()
3332 addr_dest = AREG(insn, 9); in DISAS_INSN()
3343 int count = (insn >> 9) & 7; in shift_im()
3345 int left = insn & 0x100; in shift_im()
3347 TCGv reg = gen_extend(s, DREG(insn, 0), opsize, !logical); in shift_im()
3349 if (count == 0) { in shift_im()
3353 tcg_gen_movi_i32(QREG_CC_V, 0); in shift_im()
3355 tcg_gen_shri_i32(QREG_CC_C, reg, bits - count); in shift_im()
3363 if (!logical && m68k_feature(s->env, M68K_FEATURE_M68K)) { in shift_im()
3364 /* if shift count >= bits, V is (reg != 0) */ in shift_im()
3369 tcg_gen_sari_i32(QREG_CC_V, reg, bits - 1); in shift_im()
3370 tcg_gen_sari_i32(t0, reg, bits - count - 1); in shift_im()
3375 tcg_gen_shri_i32(QREG_CC_C, reg, count - 1); in shift_im()
3388 gen_partset_reg(opsize, DREG(insn, 0), QREG_CC_N); in shift_im()
3395 int left = insn & 0x100; in shift_reg()
3397 TCGv reg = gen_extend(s, DREG(insn, 0), opsize, !logical); in shift_reg()
3407 * In addition, a 64-bit shift makes it easy to find "the last in shift_reg()
3410 tcg_gen_andi_i32(s32, DREG(insn, 9), 63); in shift_reg()
3414 /* Optimistically set V=0. Also used as a zero source below. */ in shift_reg()
3415 tcg_gen_movi_i32(QREG_CC_V, 0); in shift_reg()
3421 /* Note that C=0 if shift count is 0, and we get that for free. */ in shift_reg()
3423 TCGv zero = tcg_constant_i32(0); in shift_reg()
3431 /* X = C, but only if the shift count was non-zero. */ in shift_reg()
3442 * V = ((s ^ t) & (-1 << (bits - 1))) != 0 in shift_reg()
3444 if (!logical && m68k_feature(s->env, M68K_FEATURE_M68K)) { in shift_reg()
3448 /* Sign extend the input to 64 bits; re-do the shift. */ in shift_reg()
3454 tcg_gen_andi_i64(t64, t64, -1ULL << (bits - 1)); in shift_reg()
3456 tcg_gen_negsetcond_i64(TCG_COND_NE, t64, t64, tcg_constant_i64(0)); in shift_reg()
3468 /* Note that C=0 if shift count is 0, and we get that for free. */ in shift_reg()
3471 /* X = C, but only if the shift count was non-zero. */ in shift_reg()
3479 gen_partset_reg(opsize, DREG(insn, 0), QREG_CC_N); in shift_reg()
3516 int left = insn & 0x100; in DISAS_INSN()
3521 tcg_gen_movi_i32(QREG_CC_V, 0); in DISAS_INSN()
3531 if (!logical && m68k_feature(s->env, M68K_FEATURE_M68K)) { in DISAS_INSN()
3557 /* Replicate the 8-bit input so that a 32-bit rotate works. */ in rotate()
3559 tcg_gen_muli_i32(reg, reg, 0x01010101); in rotate()
3562 /* Replicate the 16-bit input so that a 32-bit rotate works. */ in rotate()
3598 tcg_gen_movi_i32(QREG_CC_V, 0); /* always cleared */ in rotate()
3617 tcg_gen_movi_i32(QREG_CC_V, 0); in rotate_x_flags()
3620 /* Result of rotate_x() is valid if 0 <= shift <= size */
3633 tcg_gen_sub_i32(shr, shr, shift); /* shr = size + 1 - shift */ in rotate_x()
3634 tcg_gen_subi_i32(shx, shift, 1); /* shx = shift - 1 */ in rotate_x()
3635 /* shx = shx < 0 ? size : shx; */ in rotate_x()
3636 zero = tcg_constant_i32(0); in rotate_x()
3641 tcg_gen_sub_i32(shl, shl, shift); /* shl = size + 1 - shift */ in rotate_x()
3642 tcg_gen_sub_i32(shx, sz, shift); /* shx = size - shift */ in rotate_x()
3661 /* Result of rotate32_x() is valid if 0 <= shift < 33 */
3713 /* if shift == 0, register and X are not affected */ in rotate32_x()
3715 zero = tcg_constant_i32(0); in rotate32_x()
3726 int left = (insn & 0x100); in DISAS_INSN()
3728 tmp = (insn >> 9) & 7; in DISAS_INSN()
3729 if (tmp == 0) { in DISAS_INSN()
3735 rotate(DREG(insn, 0), shift, left, 32); in DISAS_INSN()
3737 TCGv X = rotate32_x(DREG(insn, 0), shift, left); in DISAS_INSN()
3738 rotate_x_flags(DREG(insn, 0), X, 32); in DISAS_INSN()
3746 int left = (insn & 0x100); in DISAS_INSN()
3751 reg = gen_extend(s, DREG(insn, 0), OS_BYTE, 0); in DISAS_INSN()
3753 tmp = (insn >> 9) & 7; in DISAS_INSN()
3754 if (tmp == 0) { in DISAS_INSN()
3765 gen_partset_reg(OS_BYTE, DREG(insn, 0), reg); in DISAS_INSN()
3771 int left = (insn & 0x100); in DISAS_INSN()
3776 reg = gen_extend(s, DREG(insn, 0), OS_WORD, 0); in DISAS_INSN()
3777 tmp = (insn >> 9) & 7; in DISAS_INSN()
3778 if (tmp == 0) { in DISAS_INSN()
3789 gen_partset_reg(OS_WORD, DREG(insn, 0), reg); in DISAS_INSN()
3798 int left = (insn & 0x100); in DISAS_INSN()
3800 reg = DREG(insn, 0); in DISAS_INSN()
3801 src = DREG(insn, 9); in DISAS_INSN()
3802 /* shift in [0..63] */ in DISAS_INSN()
3809 /* if shift == 0, clear C */ in DISAS_INSN()
3811 t0, QREG_CC_V /* 0 */, in DISAS_INSN()
3812 QREG_CC_V /* 0 */, QREG_CC_C); in DISAS_INSN()
3818 X = rotate32_x(DREG(insn, 0), t1, left); in DISAS_INSN()
3819 rotate_x_flags(DREG(insn, 0), X, 32); in DISAS_INSN()
3829 int left = (insn & 0x100); in DISAS_INSN()
3831 reg = gen_extend(s, DREG(insn, 0), OS_BYTE, 0); in DISAS_INSN()
3832 src = DREG(insn, 9); in DISAS_INSN()
3833 /* shift in [0..63] */ in DISAS_INSN()
3840 /* if shift == 0, clear C */ in DISAS_INSN()
3842 t0, QREG_CC_V /* 0 */, in DISAS_INSN()
3843 QREG_CC_V /* 0 */, QREG_CC_C); in DISAS_INSN()
3846 /* modulo 9 */ in DISAS_INSN()
3847 tcg_gen_movi_i32(t1, 9); in DISAS_INSN()
3852 gen_partset_reg(OS_BYTE, DREG(insn, 0), reg); in DISAS_INSN()
3861 int left = (insn & 0x100); in DISAS_INSN()
3863 reg = gen_extend(s, DREG(insn, 0), OS_WORD, 0); in DISAS_INSN()
3864 src = DREG(insn, 9); in DISAS_INSN()
3865 /* shift in [0..63] */ in DISAS_INSN()
3872 /* if shift == 0, clear C */ in DISAS_INSN()
3874 t0, QREG_CC_V /* 0 */, in DISAS_INSN()
3875 QREG_CC_V /* 0 */, QREG_CC_C); in DISAS_INSN()
3884 gen_partset_reg(OS_WORD, DREG(insn, 0), reg); in DISAS_INSN()
3893 int left = (insn & 0x100); in DISAS_INSN()
3895 SRC_EA(env, src, OS_WORD, 0, &addr); in DISAS_INSN()
3898 if (insn & 0x0200) { in DISAS_INSN()
3911 int is_sign = insn & 0x200; in DISAS_INSN()
3912 TCGv src = DREG(insn, 0); in DISAS_INSN()
3914 int len = ((extract32(ext, 0, 5) - 1) & 31) + 1; in DISAS_INSN()
3915 int ofs = extract32(ext, 6, 5); /* big bit-endian */ in DISAS_INSN()
3916 int pos = 32 - ofs - len; /* little bit-endian */ in DISAS_INSN()
3922 * top of the word and then right-shift by the complement of the in DISAS_INSN()
3925 if (ext & 0x20) { in DISAS_INSN()
3927 if (ext & 0x800) { in DISAS_INSN()
3936 tcg_gen_neg_i32(shift, DREG(ext, 0)); in DISAS_INSN()
3946 if (ext & 0x800) { in DISAS_INSN()
3951 pos = 32 - len; in DISAS_INSN()
3957 if (pos < 0) { in DISAS_INSN()
3960 pos = 32 - len; in DISAS_INSN()
3978 int is_sign = insn & 0x200; in DISAS_INSN()
3988 if (ext & 0x20) { in DISAS_INSN()
3989 len = DREG(ext, 0); in DISAS_INSN()
3991 len = tcg_constant_i32(extract32(ext, 0, 5)); in DISAS_INSN()
3993 if (ext & 0x800) { in DISAS_INSN()
4013 TCGv src = DREG(insn, 0); in DISAS_INSN()
4014 int len = ((extract32(ext, 0, 5) - 1) & 31) + 1; in DISAS_INSN()
4015 int ofs = extract32(ext, 6, 5); /* big bit-endian */ in DISAS_INSN()
4017 bool is_bfffo = (insn & 0x0f00) == 0x0d00; in DISAS_INSN()
4019 if ((ext & 0x820) == 0) { in DISAS_INSN()
4021 uint32_t maski = 0x7fffffffu >> (len - 1); in DISAS_INSN()
4038 if (ext & 0x20) { in DISAS_INSN()
4040 tcg_gen_subi_i32(tmp, DREG(ext, 0), 1); in DISAS_INSN()
4042 tcg_gen_shr_i32(mask, tcg_constant_i32(0x7fffffffu), tmp); in DISAS_INSN()
4049 tcg_gen_movi_i32(mask, 0x7fffffffu >> (len - 1)); in DISAS_INSN()
4055 if (ext & 0x800) { in DISAS_INSN()
4076 switch (insn & 0x0f00) { in DISAS_INSN()
4077 case 0x0a00: /* bfchg */ in DISAS_INSN()
4080 case 0x0c00: /* bfclr */ in DISAS_INSN()
4083 case 0x0d00: /* bfffo */ in DISAS_INSN()
4086 case 0x0e00: /* bfset */ in DISAS_INSN()
4089 case 0x0800: /* bftst */ in DISAS_INSN()
4109 if (ext & 0x20) { in DISAS_INSN()
4110 len = DREG(ext, 0); in DISAS_INSN()
4112 len = tcg_constant_i32(extract32(ext, 0, 5)); in DISAS_INSN()
4114 if (ext & 0x800) { in DISAS_INSN()
4120 switch (insn & 0x0f00) { in DISAS_INSN()
4121 case 0x0a00: /* bfchg */ in DISAS_INSN()
4124 case 0x0c00: /* bfclr */ in DISAS_INSN()
4127 case 0x0d00: /* bfffo */ in DISAS_INSN()
4132 case 0x0e00: /* bfset */ in DISAS_INSN()
4135 case 0x0800: /* bftst */ in DISAS_INSN()
4147 TCGv dst = DREG(insn, 0); in DISAS_INSN()
4149 int len = ((extract32(ext, 0, 5) - 1) & 31) + 1; in DISAS_INSN()
4150 int ofs = extract32(ext, 6, 5); /* big bit-endian */ in DISAS_INSN()
4151 int pos = 32 - ofs - len; /* little bit-endian */ in DISAS_INSN()
4156 if (ext & 0x20) { in DISAS_INSN()
4158 tcg_gen_neg_i32(tmp, DREG(ext, 0)); in DISAS_INSN()
4163 tcg_gen_shli_i32(QREG_CC_N, src, 32 - len); in DISAS_INSN()
4168 if ((ext & 0x820) == 0) { in DISAS_INSN()
4170 if (pos >= 0) { in DISAS_INSN()
4173 uint32_t maski = -2U << (len - 1); in DISAS_INSN()
4184 if (ext & 0x20) { in DISAS_INSN()
4186 tcg_gen_subi_i32(rot, DREG(ext, 0), 1); in DISAS_INSN()
4188 tcg_gen_movi_i32(mask, -2); in DISAS_INSN()
4190 tcg_gen_mov_i32(rot, DREG(ext, 0)); in DISAS_INSN()
4194 uint32_t maski = -2U << (len - 1); in DISAS_INSN()
4199 if (ext & 0x800) { in DISAS_INSN()
4226 if (ext & 0x20) { in DISAS_INSN()
4227 len = DREG(ext, 0); in DISAS_INSN()
4229 len = tcg_constant_i32(extract32(ext, 0, 5)); in DISAS_INSN()
4231 if (ext & 0x800) { in DISAS_INSN()
4244 reg = DREG(insn, 0); in DISAS_INSN()
4265 gen_exception(s, s->base.pc_next, EXCP_ILLEGAL); in DISAS_INSN()
4269 reg = gen_extend(s, DREG(insn, 9), opsize, 1); in DISAS_INSN()
4281 switch ((insn >> 9) & 3) { in DISAS_INSN()
4282 case 0: in DISAS_INSN()
4292 gen_exception(s, s->base.pc_next, EXCP_ILLEGAL); in DISAS_INSN()
4297 if ((ext & 0x0800) == 0) { in DISAS_INSN()
4298 gen_exception(s, s->base.pc_next, EXCP_ILLEGAL); in DISAS_INSN()
4310 if (ext & 0x8000) { in DISAS_INSN()
4348 if ((ext & (1 << 15)) == 0) { in DISAS_INSN()
4349 gen_exception(s, s->base.pc_next, EXCP_ILLEGAL); in DISAS_INSN()
4352 m68k_copy_line(AREG(ext, 12), AREG(insn, 0), index); in DISAS_INSN()
4357 tcg_gen_addi_i32(AREG(insn, 0), AREG(insn, 0), 16); in DISAS_INSN()
4366 reg = AREG(insn, 0); in DISAS_INSN()
4377 if (((insn >> 3) & 2) == 0) { in DISAS_INSN()
4388 addr = s->pc - 2; in DISAS_INSN()
4390 if (ext != 0x46FC) { in DISAS_INSN()
4395 if (IS_USER(s) || (ext & SR_S) == 0) { in DISAS_INSN()
4400 gen_set_sr_im(s, ext, 0); in DISAS_INSN()
4409 gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE); in DISAS_INSN()
4426 gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE); in DISAS_INSN()
4434 if (ext & 0x8000) { in DISAS_INSN()
4441 extend = 0; in DISAS_INSN()
4450 if (ext & 0x0800) { in DISAS_INSN()
4455 TCGv tmp = gen_load(s, opsize, addr, 0, SFC_INDEX(s)); in DISAS_INSN()
4464 tcg_gen_addi_i32(AREG(insn, 0), addr, in DISAS_INSN()
4465 REG(insn, 0) == 7 && opsize == OS_BYTE in DISAS_INSN()
4470 tcg_gen_mov_i32(AREG(insn, 0), addr); in DISAS_INSN()
4478 gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE); in DISAS_INSN()
4488 gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE); in DISAS_INSN()
4491 tcg_gen_ld_i32(AREG(insn, 0), tcg_env, in DISAS_INSN()
4498 gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE); in DISAS_INSN()
4501 tcg_gen_st_i32(AREG(insn, 0), tcg_env, in DISAS_INSN()
4508 gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE); in DISAS_INSN()
4512 gen_exception(s, s->pc, EXCP_SEMIHOSTING); in DISAS_INSN()
4516 gen_exception(s, s->pc, EXCP_HLT); in DISAS_INSN()
4524 gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE); in DISAS_INSN()
4530 gen_set_sr_im(s, ext, 0); in DISAS_INSN()
4532 gen_exception(s, s->pc, EXCP_HLT); in DISAS_INSN()
4538 gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE); in DISAS_INSN()
4541 gen_exception(s, s->base.pc_next, EXCP_RTE); in DISAS_INSN()
4550 gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE); in DISAS_INSN()
4556 if (ext & 0x8000) { in DISAS_INSN()
4561 gen_helper_cf_movec_to(tcg_env, tcg_constant_i32(ext & 0xfff), reg); in DISAS_INSN()
4571 gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE); in DISAS_INSN()
4577 if (ext & 0x8000) { in DISAS_INSN()
4582 creg = tcg_constant_i32(ext & 0xfff); in DISAS_INSN()
4594 gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE); in DISAS_INSN()
4597 /* ICache fetch. Implement as no-op. */ in DISAS_INSN()
4603 gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE); in DISAS_INSN()
4606 /* Cache push/invalidate. Implement as no-op. */ in DISAS_INSN()
4612 gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE); in DISAS_INSN()
4615 /* Cache push/invalidate. Implement as no-op. */ in DISAS_INSN()
4621 gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE); in DISAS_INSN()
4624 /* Invalidate cache line. Implement as no-op. */ in DISAS_INSN()
4633 gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE); in DISAS_INSN()
4638 gen_helper_pflush(tcg_env, AREG(insn, 0), opmode); in DISAS_INSN()
4646 gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE); in DISAS_INSN()
4650 gen_helper_ptest(tcg_env, AREG(insn, 0), is_read); in DISAS_INSN()
4656 gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE); in DISAS_INSN()
4662 gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE); in DISAS_INSN()
4672 gen_exception(s, s->pc, EXCP_TRAP0 + (insn & 0xf)); in DISAS_INSN()
4677 if (c->tcond != TCG_COND_NEVER) { in do_trapcc()
4682 if (c->tcond != TCG_COND_ALWAYS) { in do_trapcc()
4685 tcg_gen_brcond_i32(tcg_invert_cond(c->tcond), c->v1, c->v2, over); in do_trapcc()
4688 tcg_gen_movi_i32(QREG_PC, s->pc); in do_trapcc()
4689 gen_raise_exception_format2(s, EXCP_TRAPCC, s->base.pc_next); in do_trapcc()
4693 s->base.is_jmp = DISAS_NEXT; in do_trapcc()
4703 switch (extract32(insn, 0, 3)) { in DISAS_INSN()
4725 gen_cc_cond(&c, s, 9); /* V set */ in DISAS_INSN()
4733 tcg_gen_movi_i32(res, 0); in gen_load_fcr()
4789 case 0: /* Dn */ in gen_op_fmove_fcr()
4791 gen_exception(s, s->base.pc_next, EXCP_ILLEGAL); in gen_op_fmove_fcr()
4795 gen_load_fcr(s, DREG(insn, 0), mask); in gen_op_fmove_fcr()
4797 gen_store_fcr(s, DREG(insn, 0), mask); in gen_op_fmove_fcr()
4802 gen_exception(s, s->base.pc_next, EXCP_ILLEGAL); in gen_op_fmove_fcr()
4806 gen_load_fcr(s, AREG(insn, 0), mask); in gen_op_fmove_fcr()
4808 gen_store_fcr(s, AREG(insn, 0), mask); in gen_op_fmove_fcr()
4812 if (REG(insn, 0) == 4) { in gen_op_fmove_fcr()
4816 gen_exception(s, s->base.pc_next, EXCP_ILLEGAL); in gen_op_fmove_fcr()
4840 * 0b100 Floating-Point Control Register in gen_op_fmove_fcr()
4841 * 0b010 Floating-Point Status Register in gen_op_fmove_fcr()
4842 * 0b001 Floating-Point Instruction Address Register in gen_op_fmove_fcr()
4847 for (i = 2; i >= 0; i--, mask >>= 1) { in gen_op_fmove_fcr()
4855 tcg_gen_mov_i32(AREG(insn, 0), addr); in gen_op_fmove_fcr()
4857 for (i = 0; i < 3; i++, mask >>= 1) { in gen_op_fmove_fcr()
4870 tcg_gen_mov_i32(AREG(insn, 0), addr); in gen_op_fmove_fcr()
4880 int mode = (ext >> 11) & 0x3; in gen_op_fmovem()
4881 int is_load = ((ext & 0x2000) == 0); in gen_op_fmovem()
4883 if (m68k_feature(s->env, M68K_FEATURE_FPU)) { in gen_op_fmovem()
4896 if (mode & 0x1) { in gen_op_fmovem()
4901 tcg_gen_movi_i32(tmp, ext & 0xff); in gen_op_fmovem()
4904 if (!is_load && (mode & 2) == 0) { in gen_op_fmovem()
4931 tcg_gen_mov_i32(AREG(insn, 0), tmp); in gen_op_fmovem()
4947 opmode = ext & 0x7f; in DISAS_INSN()
4949 case 0: in DISAS_INSN()
4954 if (insn == 0xf200 && (ext & 0xfc00) == 0x5c00) { in DISAS_INSN()
4966 EA_STORE, IS_USER(s)) == -1) { in DISAS_INSN()
4977 if ((ext & 0x1000) == 0 && !m68k_feature(s->env, M68K_FEATURE_FPU)) { in DISAS_INSN()
4988 EA_LOADS, IS_USER(s)) == -1) { in DISAS_INSN()
4999 case 0: /* fmove */ in DISAS_INSN()
5002 case 0x40: /* fsmove */ in DISAS_INSN()
5005 case 0x44: /* fdmove */ in DISAS_INSN()
5020 case 0x41: /* fssqrt */ in DISAS_INSN()
5023 case 0x45: /* fdsqrt */ in DISAS_INSN()
5026 case 0x06: /* flognp1 */ in DISAS_INSN()
5029 case 0x08: /* fetoxm1 */ in DISAS_INSN()
5032 case 0x09: /* ftanh */ in DISAS_INSN()
5035 case 0x0a: /* fatan */ in DISAS_INSN()
5038 case 0x0c: /* fasin */ in DISAS_INSN()
5041 case 0x0d: /* fatanh */ in DISAS_INSN()
5044 case 0x0e: /* fsin */ in DISAS_INSN()
5047 case 0x0f: /* ftan */ in DISAS_INSN()
5050 case 0x10: /* fetox */ in DISAS_INSN()
5053 case 0x11: /* ftwotox */ in DISAS_INSN()
5056 case 0x12: /* ftentox */ in DISAS_INSN()
5059 case 0x14: /* flogn */ in DISAS_INSN()
5062 case 0x15: /* flog10 */ in DISAS_INSN()
5065 case 0x16: /* flog2 */ in DISAS_INSN()
5068 case 0x18: /* fabs */ in DISAS_INSN()
5071 case 0x58: /* fsabs */ in DISAS_INSN()
5074 case 0x5c: /* fdabs */ in DISAS_INSN()
5077 case 0x19: /* fcosh */ in DISAS_INSN()
5080 case 0x1a: /* fneg */ in DISAS_INSN()
5083 case 0x5a: /* fsneg */ in DISAS_INSN()
5086 case 0x5e: /* fdneg */ in DISAS_INSN()
5089 case 0x1c: /* facos */ in DISAS_INSN()
5092 case 0x1d: /* fcos */ in DISAS_INSN()
5095 case 0x1e: /* fgetexp */ in DISAS_INSN()
5098 case 0x1f: /* fgetman */ in DISAS_INSN()
5101 case 0x20: /* fdiv */ in DISAS_INSN()
5104 case 0x60: /* fsdiv */ in DISAS_INSN()
5107 case 0x64: /* fddiv */ in DISAS_INSN()
5110 case 0x21: /* fmod */ in DISAS_INSN()
5113 case 0x22: /* fadd */ in DISAS_INSN()
5116 case 0x62: /* fsadd */ in DISAS_INSN()
5119 case 0x66: /* fdadd */ in DISAS_INSN()
5122 case 0x23: /* fmul */ in DISAS_INSN()
5125 case 0x63: /* fsmul */ in DISAS_INSN()
5128 case 0x67: /* fdmul */ in DISAS_INSN()
5131 case 0x24: /* fsgldiv */ in DISAS_INSN()
5134 case 0x25: /* frem */ in DISAS_INSN()
5137 case 0x26: /* fscale */ in DISAS_INSN()
5140 case 0x27: /* fsglmul */ in DISAS_INSN()
5143 case 0x28: /* fsub */ in DISAS_INSN()
5146 case 0x68: /* fssub */ in DISAS_INSN()
5149 case 0x6c: /* fdsub */ in DISAS_INSN()
5152 case 0x30: case 0x31: case 0x32: in DISAS_INSN()
5153 case 0x33: case 0x34: case 0x35: in DISAS_INSN()
5154 case 0x36: case 0x37: { in DISAS_INSN()
5155 TCGv_ptr cpu_dest2 = gen_fp_ptr(REG(ext, 0)); in DISAS_INSN()
5159 case 0x38: /* fcmp */ in DISAS_INSN()
5162 case 0x3a: /* ftst */ in DISAS_INSN()
5172 s->pc -= 2; in DISAS_INSN()
5179 int imm = 0; in gen_fcc_cond()
5184 c->v1 = fpsr; in gen_fcc_cond()
5187 case 0: /* False */ in gen_fcc_cond()
5189 c->tcond = TCG_COND_NEVER; in gen_fcc_cond()
5191 case 1: /* EQual Z */ in gen_fcc_cond()
5192 case 17: /* Signaling EQual Z */ in gen_fcc_cond()
5194 c->tcond = TCG_COND_TSTNE; in gen_fcc_cond()
5196 case 2: /* Ordered Greater Than !(A || Z || N) */ in gen_fcc_cond()
5197 case 18: /* Greater Than !(A || Z || N) */ in gen_fcc_cond()
5199 c->tcond = TCG_COND_TSTEQ; in gen_fcc_cond()
5201 case 3: /* Ordered Greater than or Equal Z || !(A || N) */ in gen_fcc_cond()
5202 case 19: /* Greater than or Equal Z || !(A || N) */ in gen_fcc_cond()
5203 c->v1 = tcg_temp_new(); in gen_fcc_cond()
5204 tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A); in gen_fcc_cond()
5205 tcg_gen_shli_i32(c->v1, c->v1, ctz32(FPSR_CC_N) - ctz32(FPSR_CC_A)); in gen_fcc_cond()
5206 tcg_gen_or_i32(c->v1, c->v1, fpsr); in gen_fcc_cond()
5207 tcg_gen_xori_i32(c->v1, c->v1, FPSR_CC_N); in gen_fcc_cond()
5209 c->tcond = TCG_COND_TSTNE; in gen_fcc_cond()
5211 case 4: /* Ordered Less Than !(!N || A || Z); */ in gen_fcc_cond()
5212 case 20: /* Less Than !(!N || A || Z); */ in gen_fcc_cond()
5213 c->v1 = tcg_temp_new(); in gen_fcc_cond()
5214 tcg_gen_xori_i32(c->v1, fpsr, FPSR_CC_N); in gen_fcc_cond()
5216 c->tcond = TCG_COND_TSTEQ; in gen_fcc_cond()
5218 case 5: /* Ordered Less than or Equal Z || (N && !A) */ in gen_fcc_cond()
5219 case 21: /* Less than or Equal Z || (N && !A) */ in gen_fcc_cond()
5220 c->v1 = tcg_temp_new(); in gen_fcc_cond()
5221 tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A); in gen_fcc_cond()
5222 tcg_gen_shli_i32(c->v1, c->v1, ctz32(FPSR_CC_N) - ctz32(FPSR_CC_A)); in gen_fcc_cond()
5223 tcg_gen_andc_i32(c->v1, fpsr, c->v1); in gen_fcc_cond()
5225 c->tcond = TCG_COND_TSTNE; in gen_fcc_cond()
5227 case 6: /* Ordered Greater or Less than !(A || Z) */ in gen_fcc_cond()
5228 case 22: /* Greater or Less than !(A || Z) */ in gen_fcc_cond()
5230 c->tcond = TCG_COND_TSTEQ; in gen_fcc_cond()
5232 case 7: /* Ordered !A */ in gen_fcc_cond()
5233 case 23: /* Greater, Less or Equal !A */ in gen_fcc_cond()
5235 c->tcond = TCG_COND_TSTEQ; in gen_fcc_cond()
5237 case 8: /* Unordered A */ in gen_fcc_cond()
5238 case 24: /* Not Greater, Less or Equal A */ in gen_fcc_cond()
5240 c->tcond = TCG_COND_TSTNE; in gen_fcc_cond()
5242 case 9: /* Unordered or Equal A || Z */ in gen_fcc_cond()
5243 case 25: /* Not Greater or Less then A || Z */ in gen_fcc_cond()
5245 c->tcond = TCG_COND_TSTNE; in gen_fcc_cond()
5247 case 10: /* Unordered or Greater Than A || !(N || Z)) */ in gen_fcc_cond()
5248 case 26: /* Not Less or Equal A || !(N || Z)) */ in gen_fcc_cond()
5249 c->v1 = tcg_temp_new(); in gen_fcc_cond()
5250 tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_Z); in gen_fcc_cond()
5251 tcg_gen_shli_i32(c->v1, c->v1, ctz32(FPSR_CC_N) - ctz32(FPSR_CC_Z)); in gen_fcc_cond()
5252 tcg_gen_or_i32(c->v1, c->v1, fpsr); in gen_fcc_cond()
5253 tcg_gen_xori_i32(c->v1, c->v1, FPSR_CC_N); in gen_fcc_cond()
5255 c->tcond = TCG_COND_TSTNE; in gen_fcc_cond()
5257 case 11: /* Unordered or Greater or Equal A || Z || !N */ in gen_fcc_cond()
5258 case 27: /* Not Less Than A || Z || !N */ in gen_fcc_cond()
5259 c->v1 = tcg_temp_new(); in gen_fcc_cond()
5260 tcg_gen_xori_i32(c->v1, fpsr, FPSR_CC_N); in gen_fcc_cond()
5262 c->tcond = TCG_COND_TSTNE; in gen_fcc_cond()
5264 case 12: /* Unordered or Less Than A || (N && !Z) */ in gen_fcc_cond()
5265 case 28: /* Not Greater than or Equal A || (N && !Z) */ in gen_fcc_cond()
5266 c->v1 = tcg_temp_new(); in gen_fcc_cond()
5267 tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_Z); in gen_fcc_cond()
5268 tcg_gen_shli_i32(c->v1, c->v1, ctz32(FPSR_CC_N) - ctz32(FPSR_CC_Z)); in gen_fcc_cond()
5269 tcg_gen_andc_i32(c->v1, fpsr, c->v1); in gen_fcc_cond()
5271 c->tcond = TCG_COND_TSTNE; in gen_fcc_cond()
5273 case 13: /* Unordered or Less or Equal A || Z || N */ in gen_fcc_cond()
5274 case 29: /* Not Greater Than A || Z || N */ in gen_fcc_cond()
5276 c->tcond = TCG_COND_TSTNE; in gen_fcc_cond()
5278 case 14: /* Not Equal !Z */ in gen_fcc_cond()
5279 case 30: /* Signaling Not Equal !Z */ in gen_fcc_cond()
5281 c->tcond = TCG_COND_TSTEQ; in gen_fcc_cond()
5285 c->tcond = TCG_COND_ALWAYS; in gen_fcc_cond()
5288 c->v2 = tcg_constant_i32(imm); in gen_fcc_cond()
5306 base = s->pc; in DISAS_INSN()
5314 gen_fjmpcc(s, insn & 0x3f, l1); in DISAS_INSN()
5315 gen_jmp_tb(s, 0, s->pc, s->base.pc_next); in DISAS_INSN()
5317 gen_jmp_tb(s, 1, base + offset, s->base.pc_next); in DISAS_INSN()
5328 cond = ext & 0x3f; in DISAS_INSN()
5344 cond = ext & 0x3f; in DISAS_INSN()
5347 switch (extract32(insn, 0, 3)) { in DISAS_INSN()
5371 gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE); in DISAS_INSN()
5374 if (m68k_feature(s->env, M68K_FEATURE_M68040)) { in DISAS_INSN()
5375 SRC_EA(env, addr, OS_LONG, 0, NULL); in DISAS_INSN()
5385 gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE); in DISAS_INSN()
5389 if (m68k_feature(s->env, M68K_FEATURE_M68040)) { in DISAS_INSN()
5391 TCGv idle = tcg_constant_i32(0x41000000); in DISAS_INSN()
5402 if (s->env->macsr & MACSR_FI) { in gen_mac_extract_word()
5404 tcg_gen_andi_i32(tmp, val, 0xffff0000); in gen_mac_extract_word()
5407 } else if (s->env->macsr & MACSR_SU) { in gen_mac_extract_word()
5439 if (!s->done_mac) { in DISAS_INSN()
5440 s->mactmp = tcg_temp_new_i64(); in DISAS_INSN()
5441 s->done_mac = 1; in DISAS_INSN()
5447 dual = ((insn & 0x30) != 0 && (ext & 3) != 0); in DISAS_INSN()
5448 if (dual && !m68k_feature(s->env, M68K_FEATURE_CF_EMAC_B)) { in DISAS_INSN()
5452 if (insn & 0x30) { in DISAS_INSN()
5461 loadval = gen_load(s, OS_LONG, addr, 0, IS_USER(s)); in DISAS_INSN()
5464 rx = (ext & 0x8000) ? AREG(ext, 12) : DREG(insn, 12); in DISAS_INSN()
5465 ry = (ext & 8) ? AREG(ext, 0) : DREG(ext, 0); in DISAS_INSN()
5468 rx = (insn & 0x40) ? AREG(insn, 9) : DREG(insn, 9); in DISAS_INSN()
5469 ry = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0); in DISAS_INSN()
5473 #if 0 in DISAS_INSN()
5474 l1 = -1; in DISAS_INSN()
5476 if ((s->env->macsr & MACSR_OMC) != 0 && !dual) { in DISAS_INSN()
5485 if ((ext & 0x0800) == 0) { in DISAS_INSN()
5487 rx = gen_mac_extract_word(s, rx, (ext & 0x80) != 0); in DISAS_INSN()
5488 ry = gen_mac_extract_word(s, ry, (ext & 0x40) != 0); in DISAS_INSN()
5490 if (s->env->macsr & MACSR_FI) { in DISAS_INSN()
5491 gen_helper_macmulf(s->mactmp, tcg_env, rx, ry); in DISAS_INSN()
5493 if (s->env->macsr & MACSR_SU) in DISAS_INSN()
5494 gen_helper_macmuls(s->mactmp, tcg_env, rx, ry); in DISAS_INSN()
5496 gen_helper_macmulu(s->mactmp, tcg_env, rx, ry); in DISAS_INSN()
5497 switch ((ext >> 9) & 3) { in DISAS_INSN()
5499 tcg_gen_shli_i64(s->mactmp, s->mactmp, 1); in DISAS_INSN()
5502 tcg_gen_shri_i64(s->mactmp, s->mactmp, 1); in DISAS_INSN()
5515 #if 0 in DISAS_INSN()
5517 if ((s->env->macsr & MACSR_OMC) != 0 && dual) { in DISAS_INSN()
5526 if (insn & 0x100) in DISAS_INSN()
5527 tcg_gen_sub_i64(MACREG(acc), MACREG(acc), s->mactmp); in DISAS_INSN()
5529 tcg_gen_add_i64(MACREG(acc), MACREG(acc), s->mactmp); in DISAS_INSN()
5531 if (s->env->macsr & MACSR_FI) in DISAS_INSN()
5533 else if (s->env->macsr & MACSR_SU) in DISAS_INSN()
5538 #if 0 in DISAS_INSN()
5540 if (l1 != -1) in DISAS_INSN()
5549 #if 0 in DISAS_INSN()
5551 if ((s->env->macsr & MACSR_OMC) != 0) { in DISAS_INSN()
5560 tcg_gen_sub_i64(MACREG(acc), MACREG(acc), s->mactmp); in DISAS_INSN()
5562 tcg_gen_add_i64(MACREG(acc), MACREG(acc), s->mactmp); in DISAS_INSN()
5563 if (s->env->macsr & MACSR_FI) in DISAS_INSN()
5565 else if (s->env->macsr & MACSR_SU) in DISAS_INSN()
5569 #if 0 in DISAS_INSN()
5571 if (l1 != -1) in DISAS_INSN()
5577 if (insn & 0x30) { in DISAS_INSN()
5579 rw = (insn & 0x40) ? AREG(insn, 9) : DREG(insn, 9); in DISAS_INSN()
5586 case 3: /* Post-increment. */ in DISAS_INSN()
5587 tcg_gen_addi_i32(AREG(insn, 0), addr, 4); in DISAS_INSN()
5589 case 4: /* Pre-decrement. */ in DISAS_INSN()
5590 tcg_gen_mov_i32(AREG(insn, 0), addr); in DISAS_INSN()
5601 rx = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0); in DISAS_INSN()
5602 accnum = (insn >> 9) & 3; in DISAS_INSN()
5604 if (s->env->macsr & MACSR_FI) { in DISAS_INSN()
5606 } else if ((s->env->macsr & MACSR_OMC) == 0) { in DISAS_INSN()
5608 } else if (s->env->macsr & MACSR_SU) { in DISAS_INSN()
5613 if (insn & 0x40) { in DISAS_INSN()
5614 tcg_gen_movi_i64(acc, 0); in DISAS_INSN()
5621 /* FIXME: This can be done without a helper. */ in DISAS_INSN()
5625 dest = tcg_constant_i32((insn >> 9) & 3); in DISAS_INSN()
5635 reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0); in DISAS_INSN()
5642 reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0); in DISAS_INSN()
5650 reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0); in DISAS_INSN()
5651 acc = tcg_constant_i32((insn & 0x400) ? 2 : 0); in DISAS_INSN()
5652 if (s->env->macsr & MACSR_FI) in DISAS_INSN()
5673 accnum = (insn >> 9) & 3; in DISAS_INSN()
5675 SRC_EA(env, val, OS_LONG, 0, NULL); in DISAS_INSN()
5676 if (s->env->macsr & MACSR_FI) { in DISAS_INSN()
5679 } else if (s->env->macsr & MACSR_SU) { in DISAS_INSN()
5692 SRC_EA(env, val, OS_LONG, 0, NULL); in DISAS_INSN()
5700 SRC_EA(env, val, OS_LONG, 0, NULL); in DISAS_INSN()
5701 tcg_gen_ori_i32(QREG_MAC_MASK, val, 0xffff0000); in DISAS_INSN()
5708 SRC_EA(env, val, OS_LONG, 0, NULL); in DISAS_INSN()
5709 acc = tcg_constant_i32((insn & 0x400) ? 2 : 0); in DISAS_INSN()
5710 if (s->env->macsr & MACSR_FI) in DISAS_INSN()
5712 else if (s->env->macsr & MACSR_SU) in DISAS_INSN()
5739 i = 0x8000; in register_opcode()
5740 while ((i & mask) != 0) in register_opcode()
5743 if (i == 0) in register_opcode()
5747 from = opcode & ~(i - 1); in register_opcode()
5765 if (opcode_table[0] != NULL) { in register_m68k_insns()
5774 register_opcode(disas_##name, 0x##opcode, 0x##mask) in register_m68k_insns()
5778 } while(0) in register_m68k_insns()
5800 INSN(arith_im, 0c00, ff38, CF_ISA_A); in register_m68k_insns()
5801 INSN(arith_im, 0c00, ff00, M68K); in register_m68k_insns()
5806 INSN(arith_im, 0a80, fff8, CF_ISA_A); in register_m68k_insns()
5807 INSN(arith_im, 0a00, ff00, M68K); in register_m68k_insns()
5809 INSN(moves, 0e00, ff00, M68K); in register_m68k_insns()
5811 INSN(cas, 0ac0, ffc0, CAS); in register_m68k_insns()
5812 INSN(cas, 0cc0, ffc0, CAS); in register_m68k_insns()
5813 INSN(cas, 0ec0, ffc0, CAS); in register_m68k_insns()
5814 INSN(cas2w, 0cfc, ffff, CAS); in register_m68k_insns()
5815 INSN(cas2l, 0efc, ffff, CAS); in register_m68k_insns()
6017 dc->env = env; in m68k_tr_init_disas_context()
6018 dc->pc = dc->base.pc_first; in m68k_tr_init_disas_context()
6020 dc->pc_prev = 0xdeadbeef; in m68k_tr_init_disas_context()
6021 dc->cc_op = CC_OP_DYNAMIC; in m68k_tr_init_disas_context()
6022 dc->cc_op_synced = 1; in m68k_tr_init_disas_context()
6023 dc->done_mac = 0; in m68k_tr_init_disas_context()
6024 dc->writeback_mask = 0; in m68k_tr_init_disas_context()
6026 dc->ss_active = (M68K_SR_TRACE(env->sr) == M68K_SR_TRACE_ANY_INS); in m68k_tr_init_disas_context()
6028 if (dc->ss_active) { in m68k_tr_init_disas_context()
6029 dc->base.max_insns = 1; in m68k_tr_init_disas_context()
6040 tcg_gen_insn_start(dc->base.pc_next, dc->cc_op); in m68k_tr_insn_start()
6052 dc->pc_prev = dc->base.pc_next; in m68k_tr_translate_insn()
6053 dc->base.pc_next = dc->pc; in m68k_tr_translate_insn()
6055 if (dc->base.is_jmp == DISAS_NEXT) { in m68k_tr_translate_insn()
6057 * Stop translation when the next insn might touch a new page. in m68k_tr_translate_insn()
6070 = dc->pc - (dc->base.pc_first & TARGET_PAGE_MASK); in m68k_tr_translate_insn()
6072 if (start_page_offset >= TARGET_PAGE_SIZE - 32) { in m68k_tr_translate_insn()
6073 dc->base.is_jmp = DISAS_TOO_MANY; in m68k_tr_translate_insn()
6082 switch (dc->base.is_jmp) { in m68k_tr_tb_stop()
6087 gen_jmp_tb(dc, 0, dc->pc, dc->pc_prev); in m68k_tr_tb_stop()
6091 if (dc->ss_active) { in m68k_tr_tb_stop()
6092 gen_raise_exception_format2(dc, EXCP_TRACE, dc->pc_prev); in m68k_tr_tb_stop()
6102 if (dc->ss_active) { in m68k_tr_tb_stop()
6103 gen_raise_exception_format2(dc, EXCP_TRACE, dc->pc_prev); in m68k_tr_tb_stop()
6105 tcg_gen_exit_tb(NULL, 0); in m68k_tr_tb_stop()
6130 floatx80 a = { .high = high, .low = low }; in floatx80_to_double() local
6136 u.f64 = floatx80_to_float64(a, &env->fp_status); in floatx80_to_double()
6145 for (i = 0; i < 8; i++) { in m68k_cpu_dump_state()
6146 qemu_fprintf(f, "D%d = %08x A%d = %08x " in m68k_cpu_dump_state()
6148 i, env->dregs[i], i, env->aregs[i], in m68k_cpu_dump_state()
6149 i, env->fregs[i].l.upper, env->fregs[i].l.lower, in m68k_cpu_dump_state()
6150 floatx80_to_double(env, env->fregs[i].l.upper, in m68k_cpu_dump_state()
6151 env->fregs[i].l.lower)); in m68k_cpu_dump_state()
6153 qemu_fprintf(f, "PC = %08x ", env->pc); in m68k_cpu_dump_state()
6154 sr = env->sr | cpu_m68k_get_ccr(env); in m68k_cpu_dump_state()
6158 (sr & CCF_X) ? 'X' : '-', (sr & CCF_N) ? 'N' : '-', in m68k_cpu_dump_state()
6159 (sr & CCF_Z) ? 'Z' : '-', (sr & CCF_V) ? 'V' : '-', in m68k_cpu_dump_state()
6160 (sr & CCF_C) ? 'C' : '-'); in m68k_cpu_dump_state()
6161 qemu_fprintf(f, "FPSR = %08x %c%c%c%c ", env->fpsr, in m68k_cpu_dump_state()
6162 (env->fpsr & FPSR_CC_A) ? 'A' : '-', in m68k_cpu_dump_state()
6163 (env->fpsr & FPSR_CC_I) ? 'I' : '-', in m68k_cpu_dump_state()
6164 (env->fpsr & FPSR_CC_Z) ? 'Z' : '-', in m68k_cpu_dump_state()
6165 (env->fpsr & FPSR_CC_N) ? 'N' : '-'); in m68k_cpu_dump_state()
6167 "FPCR = %04x ", env->fpcr); in m68k_cpu_dump_state()
6168 switch (env->fpcr & FPCR_PREC_MASK) { in m68k_cpu_dump_state()
6179 switch (env->fpcr & FPCR_RND_MASK) { in m68k_cpu_dump_state()
6196 env->current_sp == M68K_SSP ? "->" : " ", env->sp[M68K_SSP], in m68k_cpu_dump_state()
6197 env->current_sp == M68K_USP ? "->" : " ", env->sp[M68K_USP], in m68k_cpu_dump_state()
6198 env->current_sp == M68K_ISP ? "->" : " ", env->sp[M68K_ISP]); in m68k_cpu_dump_state()
6199 qemu_fprintf(f, "VBR = 0x%08x\n", env->vbr); in m68k_cpu_dump_state()
6200 qemu_fprintf(f, "SFC = %x DFC %x\n", env->sfc, env->dfc); in m68k_cpu_dump_state()
6202 env->mmu.ssw, env->mmu.tcr, env->mmu.urp, env->mmu.srp); in m68k_cpu_dump_state()
6204 env->mmu.ttr[M68K_DTTR0], env->mmu.ttr[M68K_DTTR1], in m68k_cpu_dump_state()
6205 env->mmu.ttr[M68K_ITTR0], env->mmu.ttr[M68K_ITTR1]); in m68k_cpu_dump_state()
6207 env->mmu.mmusr, env->mmu.ar); in m68k_cpu_dump_state()