Search
lxdream.org :: lxdream/src/sh4/sh4xir.in :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4xir.in
changeset 1006:3a169c224c12
next1011:fdd58619b760
author nkeynes
date Tue Apr 07 10:55:03 2009 +0000 (13 years ago)
branchxlat-refactor
permissions -rw-r--r--
last change Commit current work-in-progress to xlat-refactor branch
file annotate diff log raw
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/sh4/sh4xir.in Tue Apr 07 10:55:03 2009 +0000
1.3 @@ -0,0 +1,1409 @@
1.4 +/**
1.5 + * $Id: sh4xir.in 931 2008-10-31 02:57:59Z nkeynes $
1.6 + *
1.7 + * SH4 => IR conversion.
1.8 + *
1.9 + * Copyright (c) 2009 Nathan Keynes.
1.10 + *
1.11 + * This program is free software; you can redistribute it and/or modify
1.12 + * it under the terms of the GNU General Public License as published by
1.13 + * the Free Software Foundation; either version 2 of the License, or
1.14 + * (at your option) any later version.
1.15 + *
1.16 + * This program is distributed in the hope that it will be useful,
1.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.19 + * GNU General Public License for more details.
1.20 + */
1.21 +
1.22 +#include <assert.h>
1.23 +
1.24 +#include "sh4/sh4core.h"
1.25 +#include "sh4/mmu.h"
1.26 +#include "sh4/sh4xir.h"
1.27 +#include "xlat/xlat.h"
1.28 +#include "clock.h"
1.29 +
1.30 +#define REG_OFFSET(reg) (offsetof( struct sh4_registers, reg))
1.31 +
1.32 +#define R_R(rn) REG_OFFSET(r[rn])
1.33 +#define R_R0 R_R(0)
1.34 +#define R_SR REG_OFFSET(sr)
1.35 +#define R_PR REG_OFFSET(pr)
1.36 +#define R_PC REG_OFFSET(pc)
1.37 +#define R_FPUL REG_OFFSET(fpul)
1.38 +#define R_T REG_OFFSET(t)
1.39 +#define R_M REG_OFFSET(m)
1.40 +#define R_Q REG_OFFSET(q)
1.41 +#define R_S REG_OFFSET(s)
1.42 +#define R_FR(frn) REG_OFFSET(fr[0][(frn)^1])
1.43 +#define R_DR(frn) REG_OFFSET(fr[0][frn])
1.44 +#define R_DRL(f) REG_OFFSET(fr[(f)&1][(f)|0x01])
1.45 +#define R_DRH(f) REG_OFFSET(fr[(f)&1][(f)&0x0E])
1.46 +#define R_XF(frn) REG_OFFSET(fr[1][(frn)^1])
1.47 +#define R_XD(frn) REG_OFFSET(fr[1][frn^1])
1.48 +#define R_FV(fvn) REG_OFFSET(fr[0][fvn<<2])
1.49 +#define R_XMTRX R_XD(0)
1.50 +#define R_FPSCR REG_OFFSET(fpscr)
1.51 +#define R_MAC REG_OFFSET(mac)
1.52 +#define R_MACL REG_OFFSET(mac)
1.53 +#define R_MACH REG_OFFSET(mac)+4
1.54 +#define R_GBR REG_OFFSET(gbr)
1.55 +#define R_SSR REG_OFFSET(ssr)
1.56 +#define R_SPC REG_OFFSET(spc)
1.57 +#define R_SGR REG_OFFSET(sgr)
1.58 +#define R_DBR REG_OFFSET(dbr)
1.59 +#define R_VBR REG_OFFSET(vbr)
1.60 +#define R_BANK(rn) REG_OFFSET(r_bank[rn])
1.61 +#define R_NEW_PC REG_OFFSET(new_pc)
1.62 +#define R_DELAY_SLOT REG_OFFSET(in_delay_slot)
1.63 +#define R_SLICE_CYCLE REG_OFFSET(slice_cycle)
1.64 +#define R_SH4_MODE REG_OFFSET(xlat_sh4_mode)
1.65 +
1.66 +uint32_t sh4_decode_basic_block(xir_basic_block_t xbb);
1.67 +
1.68 +static const char *sh4_register_names[] =
1.69 + {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
1.70 + "sr", "pr", "pc", "fpul", "T", "M", "Q", "S",
1.71 + "fr1", "fr0", "fr3", "fr2", "fr5", "fr4", "fr7", "fr6", "fr9", "fr8", "fr11", "fr10", "fr13", "fr11", "fr15", "fr14",
1.72 + "xf1", "xf0", "xf3", "xf2", "xf5", "xf4", "xf7", "xf6", "xf9", "xf8", "xf11", "xf10", "xf13", "xf11", "xf15", "xf14",
1.73 + "fpscr", 0, "macl", "mach", "gbr", "ssr", "spc", "sgr", "dbr", "vbr",
1.74 + "r_bank0", "r_bank1", "r_bank2", "r_bank3", "r_bank4", "r_bank5", "r_bank6", "r_bank7",
1.75 + "store_queue", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1.76 + "new_pc", "event_pending", "event_type", "delay_slot", "slice_cycle", "bus_cycle", "state", "xlat_mode" };
1.77 +
1.78 +struct xlat_source_machine sh4_source_machine = { "sH4", &sh4r,
1.79 + sh4_register_names, R_PC, R_NEW_PC, R_T, R_M, R_Q, R_S,
1.80 + sh4_decode_basic_block };
1.81 +
1.82 + /**
1.83 + * Struct to manage internal translation state. This state is not saved -
1.84 + * it is only valid between calls to sh4_translate_begin_block() and
1.85 + * sh4_translate_end_block()
1.86 + */
1.87 +struct sh4_xir_state {
1.88 + gboolean fpuen_checked; /* true if we've already checked fpu enabled. */
1.89 + gboolean double_prec; /* true if FPU is in double-precision mode */
1.90 + gboolean double_size; /* true if FPU is in double-size mode */
1.91 +};
1.92 +
1.93 +static struct sh4_xir_state sh4_xir;
1.94 +
1.95 +#define XOP1E( op, arg0 ) do{ \
1.96 + xir_op_t ins = xir_append_op2(xbb, op, SOURCE_REGISTER_OPERAND, arg0, NO_OPERAND, 0); \
1.97 + ins->exc = write_postexc(xbb, (in_delay_slot ? pc-2 : pc) ); \
1.98 + ins->next = xbb->ir_ptr; \
1.99 + xbb->ir_ptr->prev = ins; \
1.100 + } while(0)
1.101 +#define XOP2E( op, arg0, arg1 ) do{ \
1.102 + xir_op_t ins = xir_append_op2(xbb, op, SOURCE_REGISTER_OPERAND, arg0, SOURCE_REGISTER_OPERAND, arg1); \
1.103 + ins->exc = write_postexc(xbb, (in_delay_slot ? pc-2 : pc) ); \
1.104 + ins->exc->prev = ins; \
1.105 + ins->next = xbb->ir_ptr; \
1.106 + xbb->ir_ptr->prev = ins; \
1.107 + } while(0)
1.108 +#define ALIGN(m,r,code) do { \
1.109 + xir_op_t ins = xir_append_op2(xbb, OP_RAISEMNE, INT_IMM_OPERAND, m, SOURCE_REGISTER_OPERAND, r); \
1.110 + ins->exc = write_exc(xbb, (in_delay_slot ? pc-2 : pc), code); \
1.111 + ins->exc->prev = ins; \
1.112 + ins->next = xbb->ir_ptr; \
1.113 + xbb->ir_ptr->prev = ins; \
1.114 + } while(0)
1.115 +
1.116 +#define SLOTILLEGAL() write_exc(xbb, pc, EXC_SLOT_ILLEGAL)
1.117 +#define ILLEGAL() write_exc(xbb, pc, EXC_ILLEGAL)
1.118 +
1.119 +#define UNDEF(ir) if( in_delay_slot ) { SLOTILLEGAL(); return 2; } else { ILLEGAL(); return 2; }
1.120 +#define CHECKFPUEN() if( !sh4_xir.fpuen_checked ) { \
1.121 + xir_op_t ins = XOP2I( OP_RAISEMNE, SR_FD, R_SR ); \
1.122 + if( in_delay_slot ) { \
1.123 + ins->exc = write_exc(xbb, pc-2, EXC_SLOT_FPU_DISABLED); \
1.124 + } else { \
1.125 + ins->exc = write_exc(xbb, pc, EXC_FPU_DISABLED); \
1.126 + } \
1.127 + ins->exc->prev = ins; \
1.128 + ins->next = xbb->ir_ptr; \
1.129 + xbb->ir_ptr->prev = ins; \
1.130 + sh4_xir.fpuen_checked = TRUE; \
1.131 + }
1.132 +#define CHECKPRIV() if( (sh4r.xlat_sh4_mode & SR_MD) == 0 ) { UNDEF(ir); }
1.133 +
1.134 +#define RALIGN16(r) ALIGN(0x01,r,EXC_DATA_ADDR_READ)
1.135 +#define RALIGN32(r) ALIGN(0x03,r,EXC_DATA_ADDR_READ)
1.136 +#define RALIGN64(r) ALIGN(0x07,r,EXC_DATA_ADDR_READ)
1.137 +#define WALIGN16(r) ALIGN(0x01,r,EXC_DATA_ADDR_WRITE)
1.138 +#define WALIGN32(r) ALIGN(0x03,r,EXC_DATA_ADDR_WRITE)
1.139 +#define WALIGN64(r) ALIGN(0x07,r,EXC_DATA_ADDR_WRITE)
1.140 +
1.141 +#define UNTRANSLATABLE(pc) !IS_IN_ICACHE(pc)
1.142 +
1.143 +#define EMU_DELAY_SLOT() do { \
1.144 + XOP2I( OP_ADD, (pc+2 - xbb->pc_begin), R_PC ); \
1.145 + XOP2I( OP_MOV, 1, R_DELAY_SLOT ); \
1.146 + XOP0( OP_BARRIER ); \
1.147 + XOPCALL0( sh4_execute_instruction ); \
1.148 + XOP1( OP_BR, R_PC ); \
1.149 + } while(0)
1.150 +
1.151 +
1.152 +/**
1.153 + * Create a standard post-exception stub sub-block (ie sh4_raise_exception or similar has
1.154 + * already been called - update SPC + slice_cycle and exit).
1.155 + * @return the first xir_op_t of the exception block.
1.156 + */
1.157 +static inline xir_op_t write_postexc( xir_basic_block_t xbb, sh4addr_t pc )
1.158 +{
1.159 + xir_op_t start = xbb->ir_ptr;
1.160 + if( pc != xbb->pc_begin ) {
1.161 + XOP2I( OP_ADD, pc - xbb->pc_begin, R_SPC );
1.162 + }
1.163 + XOP2I( OP_ADD, (pc+2 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
1.164 + XOP1( OP_BR, R_SPC )->next = NULL;
1.165 + start->prev = NULL;
1.166 + return start;
1.167 +}
1.168 +
1.169 +/**
1.170 + * Create a standard exception-taking stub sub-block - updates SPC, slice_cycle, and exits
1.171 + * @return the first xir_op_t of the exception block.
1.172 + */
1.173 +static inline xir_op_t write_exc( xir_basic_block_t xbb, sh4addr_t pc, int exc_code )
1.174 +{
1.175 + xir_op_t start = xbb->ir_ptr;
1.176 + XOPCALL1I( sh4_raise_exception, exc_code );
1.177 + if( pc != xbb->pc_begin ) {
1.178 + XOP2I( OP_ADD, pc - xbb->pc_begin, R_SPC );
1.179 + }
1.180 + XOP2I( OP_ADD, (pc+2 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
1.181 + XOP1( OP_BR, R_SPC )->next = NULL;
1.182 + start->prev = NULL;
1.183 + return start;
1.184 +}
1.185 +
1.186 +static sh4addr_t sh4_decode_instruction( xir_basic_block_t xbb, sh4addr_t pc, gboolean in_delay_slot )
1.187 +{
1.188 + assert( IS_IN_ICACHE(pc) );
1.189 + uint16_t ir = *(uint16_t *)GET_ICACHE_PTR(pc);
1.190 +
1.191 +%%
1.192 +ADD Rm, Rn {: XOP2( OP_ADD, R_R(Rm), R_R(Rn) ); :}
1.193 +ADD #imm, Rn {: XOP2I( OP_ADD, imm, R_R(Rn) ); :}
1.194 +ADDC Rm, Rn {:
1.195 + XOP1CC( OP_LD, CC_C, R_T );
1.196 + XOP2( OP_ADDCS, R_R(Rm), R_R(Rn) );
1.197 + XOP1CC( OP_ST, CC_C, R_T );
1.198 +:}
1.199 +ADDV Rm, Rn {: XOP2( OP_ADDS, R_R(Rm), R_R(Rn) ); XOP1CC( OP_ST, CC_OV, R_T ); :}
1.200 +AND Rm, Rn {: XOP2( OP_AND, R_R(Rm), R_R(Rn) ); :}
1.201 +AND #imm, R0 {: XOP2I( OP_AND, imm, R_R0 ); :}
1.202 +CMP/EQ Rm, Rn {: XOP2( OP_CMP, Rm, R_R(Rn) ); XOP1CC( OP_ST, CC_EQ, R_T ); :}
1.203 +CMP/EQ #imm, R0 {: XOP2I( OP_CMP, imm, R_R0 ); XOP1CC( OP_ST, CC_EQ, R_T ); :}
1.204 +CMP/GE Rm, Rn {: XOP2( OP_CMP, R_R(Rm), R_R(Rn) ); XOP1CC( OP_ST, CC_SGE, R_T ); :}
1.205 +CMP/GT Rm, Rn {: XOP2( OP_CMP, R_R(Rm), R_R(Rn) ); XOP1CC( OP_ST, CC_SGT, R_T ); :}
1.206 +CMP/HI Rm, Rn {: XOP2( OP_CMP, R_R(Rm), R_R(Rn) ); XOP1CC( OP_ST, CC_UGT, R_T ); :}
1.207 +CMP/HS Rm, Rn {: XOP2( OP_CMP, R_R(Rm), R_R(Rn) ); XOP1CC( OP_ST, CC_UGE, R_T ); :}
1.208 +CMP/PL Rn {: XOP2I( OP_CMP, 0, R_R(Rn) ); XOP1CC( OP_ST, CC_SGT, R_T ); :}
1.209 +CMP/PZ Rn {: XOP2I( OP_CMP, 0, R_R(Rn) ); XOP1CC( OP_ST, CC_SGE, R_T ); :}
1.210 +CMP/STR Rm, Rn {: XOP2( OP_CMPSTR, R_R(Rm), R_R(Rn) ); :}
1.211 +DIV0S Rm, Rn {:
1.212 + XOP2( OP_MOV, R_R(Rm), R_M );
1.213 + XOP2I( OP_SLR, 31, R_M );
1.214 + XOP2( OP_MOV, R_R(Rn), R_Q );
1.215 + XOP2I( OP_SLR, 31, R_Q );
1.216 + XOP2( OP_CMP, R_M, R_Q );
1.217 + XOP1CC( OP_ST, CC_NE, R_T );
1.218 +:}
1.219 +DIV0U {:
1.220 + XOP2I( OP_MOV, 0, R_M );
1.221 + XOP2I( OP_MOV, 0, R_Q );
1.222 + XOP2I( OP_MOV, 0, R_T );
1.223 +:}
1.224 +DIV1 Rm, Rn {: XOP2( OP_DIV1, R_R(Rm), R_R(Rn) ); :}
1.225 +DMULS.L Rm, Rn {:
1.226 + XOP2( OP_MOVSX32, R_R(Rm), R_MAC );
1.227 + XOP2( OP_MOVSX32, R_R(Rn), REG_TMP0 );
1.228 + XOP2( OP_MULQ, REG_TMPQ0, R_MAC );
1.229 +:}
1.230 +DMULU.L Rm, Rn {:
1.231 + XOP2( OP_MOVZX32, R_R(Rm), R_MAC );
1.232 + XOP2( OP_MOVZX32, R_R(Rn), REG_TMP0 ) ;
1.233 + XOP2( OP_MULQ, REG_TMP0, R_MAC );
1.234 +:}
1.235 +DT Rn {: XOP1( OP_DEC, R_R(Rn) ); :}
1.236 +EXTS.B Rm, Rn {: XOP2( OP_MOVSX8, R_R(Rm), R_R(Rn)); :}
1.237 +EXTS.W Rm, Rn {: XOP2( OP_MOVSX16, R_R(Rm), R_R(Rn)); :}
1.238 +EXTU.B Rm, Rn {: XOP2( OP_MOVZX8, R_R(Rm), R_R(Rn)); :}
1.239 +EXTU.W Rm, Rn {: XOP2( OP_MOVZX16, R_R(Rm), R_R(Rn)); :}
1.240 +MAC.L @Rm+, @Rn+ {:
1.241 + RALIGN32(R_R(Rm));
1.242 + if( Rm == Rn ) {
1.243 + XOP2E( OP_LOADL, R_R(Rm), REG_TMP0 );
1.244 + XOP2( OP_MOV, R_R(Rm), REG_TMP1 );
1.245 + XOP2I( OP_ADD, 4, REG_TMP1 );
1.246 + XOP2E( OP_LOADL, REG_TMP1, REG_TMP1 );
1.247 + XOP2I( OP_ADD, 8, R_R(Rm) );
1.248 + } else {
1.249 + RALIGN32(R_R(Rn));
1.250 + XOP2E( OP_LOADL, R_R(Rm), REG_TMP0 );
1.251 + XOP2E( OP_LOADL, R_R(Rn), REG_TMP1 );
1.252 + XOP2I( OP_ADD, 4, R_R(Rm) );
1.253 + XOP2I( OP_ADD, 4, R_R(Rn) );
1.254 + }
1.255 + XOP2( OP_MOVSX32, REG_TMP0, REG_TMPQ0 );
1.256 + XOP2( OP_MOVSX32, REG_TMP1, REG_TMPQ1 );
1.257 + XOP2( OP_MULQ, REG_TMPQ0, REG_TMPQ1 );
1.258 + XOP2( OP_ADDQSAT48, REG_TMPQ1, R_MAC );
1.259 +:}
1.260 +MAC.W @Rm+, @Rn+ {:
1.261 + RALIGN32(R_R(Rm));
1.262 + if( Rm == Rn ) {
1.263 + XOP2E( OP_LOADW, R_R(Rm), REG_TMP0 );
1.264 + XOP2( OP_MOV, R_R(Rm), REG_TMP1 );
1.265 + XOP2I( OP_ADD, 2, REG_TMP1 );
1.266 + XOP2E( OP_LOADW, REG_TMP1, REG_TMP1 );
1.267 + XOP2I( OP_ADD, 4, R_R(Rm) );
1.268 + } else {
1.269 + RALIGN32(Rn);
1.270 + XOP2E( OP_LOADW, R_R(Rm), REG_TMP0 );
1.271 + XOP2E( OP_LOADW, R_R(Rn), REG_TMP1 );
1.272 + XOP2I( OP_ADD, 2, R_R(Rm) );
1.273 + XOP2I( OP_ADD, 2, R_R(Rn) );
1.274 + }
1.275 + XOP2( OP_MOVSX32, REG_TMP0, REG_TMPQ0 );
1.276 + XOP2( OP_MOVSX32, REG_TMP1, REG_TMPQ1 );
1.277 + XOP2( OP_MULQ, REG_TMPQ0, REG_TMPQ1 );
1.278 + XOP2( OP_ADDQSAT32, REG_TMPQ1, R_MAC );
1.279 +:}
1.280 +MOVT Rn {: XOP2( OP_MOV, R_R(Rn), R_T ); :}
1.281 +MUL.L Rm, Rn {:
1.282 + XOP2( OP_MOV, R_R(Rm), R_MACL );
1.283 + XOP2( OP_MUL, R_R(Rn), R_MACL );
1.284 +:}
1.285 +MULS.W Rm, Rn {:
1.286 + XOP2( OP_MOVSX16, R_R(Rm), REG_TMP0 );
1.287 + XOP2( OP_MOVSX16, R_R(Rn), R_MACL );
1.288 + XOP2( OP_MUL, REG_TMP0, R_MACL );
1.289 +:}
1.290 +MULU.W Rm, Rn {:
1.291 + XOP2( OP_MOVZX16, R_R(Rm), REG_TMP0 );
1.292 + XOP2( OP_MOVZX16, R_R(Rn), R_MACL );
1.293 + XOP2( OP_MUL, REG_TMP0, R_MACL );
1.294 +:}
1.295 +NEG Rm, Rn {:
1.296 + XOP2( OP_NEG, R_R(Rm), R_R(Rn) );
1.297 +:}
1.298 +NEGC Rm, Rn {:
1.299 + XOP1CC( OP_LD, CC_C, R_T );
1.300 + if( Rm == Rn ) {
1.301 + XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1.302 + XOP2I(OP_MOV, 0, R_R(Rn) );
1.303 + XOP2( OP_SUBBS, REG_TMP0, R_R(Rn) );
1.304 + } else {
1.305 + XOP2I(OP_MOV, 0, R_R(Rn) );
1.306 + XOP2( OP_SUBBS, R_R(Rm), R_R(Rn) );
1.307 + }
1.308 + XOP1CC( OP_ST, CC_C, R_T );
1.309 +:}
1.310 +NOT Rm, Rn {:
1.311 + XOP2( OP_NOT, R_R(Rm), R_R(Rn) );
1.312 +:}
1.313 +OR Rm, Rn {: XOP2( OP_OR, R_R(Rm), R_R(Rn) ); :}
1.314 +OR #imm, R0 {: XOP2I( OP_OR, imm, R_R0 ); :}
1.315 +ROTCL Rn {: XOP1CC( OP_LD, CC_C, R_T ); XOP2I( OP_RCL, 1, R_R(Rn) ); XOP1CC( OP_ST, CC_C, R_T); :}
1.316 +ROTCR Rn {: XOP1CC( OP_LD, CC_C, R_T ); XOP2I( OP_RCR, 1, R_R(Rn) ); XOP1CC( OP_ST, CC_C, R_T); :}
1.317 +ROTL Rn {: XOP2I( OP_ROL, 1, R_R(Rn) ); :}
1.318 +ROTR Rn {: XOP2I( OP_ROR, 1, R_R(Rn) ); :}
1.319 +SHAD Rm, Rn {: XOP2( OP_SHAD, R_R(Rm), R_R(Rn) ); :}
1.320 +SHLD Rm, Rn {: XOP2( OP_SHLD, R_R(Rm), R_R(Rn) ); :}
1.321 +SHAL Rn {: XOP2I( OP_SLLS, 1, R_R(Rn) ); XOP1CC( OP_ST, CC_C, R_T); :}
1.322 +SHAR Rn {: XOP2I( OP_SARS, 1, R_R(Rn) ); XOP1CC( OP_ST, CC_C, R_T); :}
1.323 +SHLL Rn {: XOP2I( OP_SLLS, 1, R_R(Rn) ); XOP1CC( OP_ST, CC_C, R_T); :}
1.324 +SHLL2 Rn {: XOP2I( OP_SLL, 2, R_R(Rn) ); :}
1.325 +SHLL8 Rn {: XOP2I( OP_SLL, 8, R_R(Rn) ); :}
1.326 +SHLL16 Rn {: XOP2I( OP_SLL, 16, R_R(Rn) ); :}
1.327 +SHLR Rn {: XOP2I( OP_SLRS, 1, R_R(Rn) ); XOP1CC( OP_ST, CC_C, R_T); :}
1.328 +SHLR2 Rn {: XOP2I( OP_SLR, 2, R_R(Rn) ); :}
1.329 +SHLR8 Rn {: XOP2I( OP_SLR, 8, R_R(Rn) ); :}
1.330 +SHLR16 Rn {: XOP2I( OP_SLR, 16, R_R(Rn) ); :}
1.331 +SUB Rm, Rn {:
1.332 + if( Rm == Rn ) {
1.333 + /* Break false dependence */
1.334 + XOP2I( OP_MOV, 0, R_R(Rn) );
1.335 + } else {
1.336 + XOP2( OP_SUB, R_R(Rm), R_R(Rn) );
1.337 + }
1.338 +:}
1.339 +SUBC Rm, Rn {: XOP1CC( OP_LD, CC_C, R_T ); XOP2( OP_SUBBS, R_R(Rm), R_R(Rn) ); XOP1CC( OP_ST, CC_C, R_T ); :}
1.340 +SUBV Rm, Rn {: XOP2( OP_SUB, R_R(Rm), R_R(Rn) ); XOP1CC( OP_ST, CC_OV, R_T ); :}
1.341 +SWAP.B Rm, Rn {:
1.342 + if( Rm != Rn ) {
1.343 + XOP2( OP_MOV, R_R(Rm), R_R(Rn) );
1.344 + }
1.345 + XOP2I( OP_SHUFFLE, 0x1243, R_R(Rn) );
1.346 +:}
1.347 +SWAP.W Rm, Rn {:
1.348 + if( Rm != Rn ) {
1.349 + XOP2( OP_MOV, R_R(Rm), R_R(Rn) );
1.350 + }
1.351 + XOP2I( OP_SHUFFLE, 0x3412, R_R(Rn) );
1.352 +:}
1.353 +TST Rm, Rn {: XOP2( OP_TST, R_R(Rm), R_R(Rn) ); XOP1CC( OP_ST, CC_EQ, R_T ); :}
1.354 +TST #imm, R0 {: XOP2I( OP_TST, imm, R_R0 ); XOP1CC( OP_ST, CC_EQ, R_T ); :}
1.355 +XOR Rm, Rn {:
1.356 + if( Rm == Rn ) {
1.357 + /* Break false dependence */
1.358 + XOP2I( OP_MOV, 0, R_R(Rn) );
1.359 + } else {
1.360 + XOP2( OP_XOR, R_R(Rm), R_R(Rn) );
1.361 + }
1.362 +:}
1.363 +XOR #imm, R0 {: XOP2I( OP_XOR, imm, R_R0 ); :}
1.364 +XTRCT Rm, Rn {:
1.365 + XOP2( OP_MOV, R_R(Rm), REG_TMP0 );
1.366 + XOP2I( OP_SLL, 16, REG_TMP0 );
1.367 + XOP2I( OP_SLR, 16, R_R(Rn) );
1.368 + XOP2( OP_OR, REG_TMP0, R_R(Rn) );
1.369 +:}
1.370 +MOV Rm, Rn {: XOP2( OP_MOV, R_R(Rm), R_R(Rn) ); :}
1.371 +MOV #imm, Rn {: XOP2I( OP_MOV, imm, R_R(Rn) ); :}
1.372 +
1.373 +AND.B #imm, @(R0, GBR) {:
1.374 + XOP2( OP_MOV, R_R0, REG_TMP0 );
1.375 + XOP2( OP_ADD, R_GBR, REG_TMP0 );
1.376 + XOP2E( OP_LOADBFW, REG_TMP0, REG_TMP1 );
1.377 + XOP2I( OP_AND, imm, REG_TMP1 );
1.378 + XOP2E( OP_STOREB, REG_TMP0, REG_TMP1 );
1.379 +:}
1.380 +OR.B #imm, @(R0, GBR) {:
1.381 + XOP2( OP_MOV, R_R0, REG_TMP0 );
1.382 + XOP2( OP_ADD, R_GBR, REG_TMP0 );
1.383 + XOP2E( OP_LOADBFW, REG_TMP0, REG_TMP1 );
1.384 + XOP2I( OP_OR, imm, REG_TMP1 );
1.385 + XOP2E( OP_STOREB, REG_TMP0, REG_TMP1 );
1.386 +:}
1.387 +TAS.B @Rn {:
1.388 + XOP1( OP_OCBP, R_R(Rn) );
1.389 + XOP2E( OP_LOADBFW, R_R(Rn), REG_TMP0 );
1.390 + XOP2I( OP_CMP, 0, REG_TMP0 );
1.391 + XOP1CC(OP_ST, CC_EQ, R_T );
1.392 + XOP2I( OP_OR, 0x80, REG_TMP0 );
1.393 + XOP2E( OP_STOREB, R_R(Rn), REG_TMP0 );
1.394 +:}
1.395 +TST.B #imm, @(R0, GBR) {:
1.396 + XOP2( OP_MOV, R_R0, REG_TMP0 );
1.397 + XOP2( OP_ADD, R_GBR, REG_TMP0 );
1.398 + XOP2E( OP_LOADB, REG_TMP0, REG_TMP0 );
1.399 + XOP2I( OP_TST, imm, REG_TMP0 );
1.400 +:}
1.401 +XOR.B #imm, @(R0, GBR) {:
1.402 + XOP2( OP_MOV, R_R0, REG_TMP0 );
1.403 + XOP2( OP_ADD, R_GBR, REG_TMP0 );
1.404 + XOP2E( OP_LOADBFW, REG_TMP0, REG_TMP1 );
1.405 + XOP2I( OP_XOR, imm, REG_TMP1 );
1.406 + XOP2E( OP_STOREB, REG_TMP0, REG_TMP1 );
1.407 +:}
1.408 +
1.409 +MOV.B Rm, @Rn {:
1.410 + XOP2E( OP_STOREB, R_R(Rn), R_R(Rm) );
1.411 +:}
1.412 +MOV.B Rm, @-Rn {:
1.413 + XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1.414 + XOP2I( OP_ADD, -1, REG_TMP0 );
1.415 + XOP2E( OP_STOREB, REG_TMP0, R_R(Rm) );
1.416 + XOP2I( OP_ADD, -1, R_R(Rn) );
1.417 +:}
1.418 +MOV.B Rm, @(R0, Rn) {:
1.419 + XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1.420 + XOP2( OP_ADD, R_R0, REG_TMP0 );
1.421 + XOP2E( OP_STOREB, REG_TMP0, R_R(Rm) );
1.422 +:}
1.423 +MOV.B R0, @(disp, GBR) {:
1.424 + XOP2( OP_MOV, R_GBR, REG_TMP0 );
1.425 + XOP2I( OP_ADD, disp, REG_TMP0 );
1.426 + XOP2E( OP_STOREB, REG_TMP0, R_R0 );
1.427 +:}
1.428 +MOV.B R0, @(disp, Rn) {:
1.429 + XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1.430 + XOP2I( OP_ADD, disp, REG_TMP0 );
1.431 + XOP2E( OP_STOREB, REG_TMP0, R_R0 );
1.432 +:}
1.433 +MOV.B @Rm, Rn {:
1.434 + XOP2E( OP_LOADB, R_R(Rm), R_R(Rn) );
1.435 +:}
1.436 +MOV.B @Rm+, Rn {:
1.437 + XOP2E( OP_LOADB, R_R(Rm), R_R(Rn) );
1.438 + if( Rm != Rn ) {
1.439 + XOP2I( OP_ADD, 1, R_R(Rm) );
1.440 + }
1.441 +:}
1.442 +MOV.B @(R0, Rm), Rn {:
1.443 + XOP2( OP_MOV, R_R(Rm), REG_TMP0 );
1.444 + XOP2( OP_ADD, R_R0, REG_TMP0 );
1.445 + XOP2E(OP_LOADB, REG_TMP0, R_R(Rn) );
1.446 +:}
1.447 +MOV.B @(disp, GBR), R0 {:
1.448 + XOP2( OP_MOV, R_GBR, REG_TMP0 );
1.449 + XOP2I(OP_ADD, disp, REG_TMP0 );
1.450 + XOP2E(OP_LOADB, REG_TMP0, R_R0 );
1.451 +:}
1.452 +MOV.B @(disp, Rm), R0 {:
1.453 + XOP2( OP_MOV, R_R(Rm), REG_TMP0 );
1.454 + XOP2I(OP_ADD, disp, REG_TMP0 );
1.455 + XOP2E(OP_LOADB, REG_TMP0, R_R0 );
1.456 +:}
1.457 +MOV.L Rm, @Rn {:
1.458 + WALIGN32( R_R(Rn) );
1.459 + XOP2E( OP_STOREL, R_R(Rn), R_R(Rm) );
1.460 +:}
1.461 +MOV.L Rm, @-Rn {:
1.462 + WALIGN32( R_R(Rn) );
1.463 + XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1.464 + XOP2I(OP_ADD, -4, REG_TMP0 );
1.465 + XOP2( OP_STOREL, REG_TMP0, R_R(Rm) );
1.466 + XOP2I(OP_ADD, -4, R_R(Rn) );
1.467 +:}
1.468 +MOV.L Rm, @(R0, Rn) {:
1.469 + XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1.470 + XOP2( OP_ADD, R_R0, REG_TMP0 );
1.471 + WALIGN32( REG_TMP0 );
1.472 + XOP2E(OP_STOREL, REG_TMP0, R_R(Rm) );
1.473 +:}
1.474 +MOV.L R0, @(disp, GBR) {:
1.475 + XOP2( OP_MOV, R_GBR, REG_TMP0 );
1.476 + XOP2I(OP_ADD, disp, REG_TMP0 );
1.477 + WALIGN32( REG_TMP0 );
1.478 + XOP2E(OP_STOREL, REG_TMP0, R_R0 );
1.479 +:}
1.480 +MOV.L Rm, @(disp, Rn) {:
1.481 + XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1.482 + XOP2I(OP_ADD, disp, REG_TMP0 );
1.483 + WALIGN32( REG_TMP0 );
1.484 + XOP2E(OP_STOREL, REG_TMP0, R_R(Rm) );
1.485 +:}
1.486 +MOV.L @Rm, Rn {:
1.487 + RALIGN32( R_R(Rm) );
1.488 + XOP2E(OP_LOADL, R_R(Rm), R_R(Rn) );
1.489 +:}
1.490 +MOV.L @Rm+, Rn {:
1.491 + RALIGN32( R_R(Rm) );
1.492 + XOP2E( OP_LOADL, R_R(Rm), R_R(Rn) );
1.493 + if( R_R(Rm) != R_R(Rn) ) {
1.494 + XOP2I( OP_ADD, 4, R_R(Rm) );
1.495 + }
1.496 +:}
1.497 +MOV.L @(R0, Rm), Rn {:
1.498 + XOP2( OP_MOV, R_R0, REG_TMP0 );
1.499 + XOP2( OP_ADD, R_R(Rm), REG_TMP0 );
1.500 + RALIGN32( REG_TMP0 );
1.501 + XOP2E(OP_LOADL, REG_TMP0, R_R(Rn) );
1.502 +:}
1.503 +MOV.L @(disp, GBR), R0 {:
1.504 + XOP2( OP_MOV, R_GBR, REG_TMP0 );
1.505 + XOP2I(OP_ADD, disp, REG_TMP0 );
1.506 + RALIGN32( REG_TMP0 );
1.507 + XOP2E(OP_LOADL, REG_TMP0, R_R0 );
1.508 +:}
1.509 +MOV.L @(disp, PC), Rn {:
1.510 + if( in_delay_slot ) {
1.511 + SLOTILLEGAL();
1.512 + return 2;
1.513 + } else {
1.514 + uint32_t target = (pc & 0xFFFFFFFC) + disp + 4;
1.515 + if( IS_IN_ICACHE(target) ) {
1.516 + // If the target address is in the same page as the code, it's
1.517 + // pretty safe to just ref it directly and circumvent the whole
1.518 + // memory subsystem. (this is a big performance win)
1.519 +
1.520 + // FIXME: There's a corner-case that's not handled here when
1.521 + // the current code-page is in the ITLB but not in the UTLB.
1.522 + // (should generate a TLB miss although need to test SH4
1.523 + // behaviour to confirm) Unlikely to be anyone depending on this
1.524 + // behaviour though.
1.525 + sh4ptr_t ptr = GET_ICACHE_PTR(target);
1.526 + XOP2P( OP_MOV, ptr, R_R(Rn) );
1.527 + } else {
1.528 + // Note: we use sh4r.pc for the calc as we could be running at a
1.529 + // different virtual address than the translation was done with,
1.530 + // but we can safely assume that the low bits are the same.
1.531 + XOP2( OP_MOV, R_PC, REG_TMP0 );
1.532 + XOP2( OP_ADD, (pc-xbb->pc_begin) + disp + 4 - (pc&0x03), REG_TMP0 );
1.533 + XOP2E(OP_LOADL, REG_TMP0, R_R(Rn) );
1.534 + }
1.535 + }
1.536 +:}
1.537 +MOV.L @(disp, Rm), Rn {:
1.538 + XOP2( OP_MOV, R_R(Rm), REG_TMP0 );
1.539 + XOP2I(OP_ADD, disp, REG_TMP0 );
1.540 + RALIGN32( REG_TMP0 );
1.541 + XOP2E(OP_LOADL, REG_TMP0, R_R(Rn) );
1.542 +:}
1.543 +MOV.W Rm, @Rn {:
1.544 + WALIGN16( R_R(Rn) );
1.545 + XOP2E(OP_STOREW, R_R(Rn), R_R(Rm) );
1.546 +:}
1.547 +MOV.W Rm, @-Rn {:
1.548 + WALIGN16( R_R(Rn) );
1.549 + XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1.550 + XOP2I(OP_ADD, -2, REG_TMP0 );
1.551 + XOP2E(OP_STOREW, REG_TMP0, R_R(Rm) );
1.552 + XOP2I(OP_ADD, -2, R_R(Rn) );
1.553 +:}
1.554 +MOV.W Rm, @(R0, Rn) {:
1.555 + XOP2( OP_MOV, R_R0, REG_TMP0 );
1.556 + XOP2( OP_ADD, R_R(Rn), REG_TMP0 );
1.557 + WALIGN16( REG_TMP0 );
1.558 + XOP2E(OP_STOREW, REG_TMP0, R_R(Rm) );
1.559 +:}
1.560 +MOV.W R0, @(disp, GBR) {:
1.561 + XOP2( OP_MOV, R_GBR, REG_TMP0 );
1.562 + XOP2I(OP_ADD, disp, REG_TMP0 );
1.563 + WALIGN16( REG_TMP0 );
1.564 + XOP2( OP_STOREW, REG_TMP0, R_R0 );
1.565 +:}
1.566 +MOV.W R0, @(disp, Rn) {:
1.567 + XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1.568 + XOP2I(OP_ADD, disp, REG_TMP0 );
1.569 + WALIGN16( REG_TMP0 );
1.570 + XOP2E(OP_STOREW, REG_TMP0, R_R0 );
1.571 +:}
1.572 +MOV.W @Rm, Rn {:
1.573 + RALIGN16( R_R(Rm) );
1.574 + XOP2E(OP_LOADW, R_R(Rm), R_R(Rn) );
1.575 +:}
1.576 +MOV.W @Rm+, Rn {:
1.577 + RALIGN16( R_R(Rm) );
1.578 + XOP2E(OP_LOADW, R_R(Rm), R_R(Rn) );
1.579 + if( Rm != Rn ) {
1.580 + XOP2I( OP_ADD, 2, R_R(Rm) );
1.581 + }
1.582 +:}
1.583 +MOV.W @(R0, Rm), Rn {:
1.584 + XOP2( OP_MOV, R_R0, REG_TMP0 );
1.585 + XOP2( OP_ADD, R_R(Rm), REG_TMP0 );
1.586 + RALIGN16( REG_TMP0 );
1.587 + XOP2E(OP_LOADW, REG_TMP0, R_R(Rn) );
1.588 +:}
1.589 +MOV.W @(disp, GBR), R0 {:
1.590 + XOP2( OP_MOV, R_GBR, REG_TMP0 );
1.591 + XOP2I(OP_ADD, disp, REG_TMP0 );
1.592 + RALIGN16( REG_TMP0 );
1.593 + XOP2E(OP_LOADW, REG_TMP0, R_R0 );
1.594 +:}
1.595 +MOV.W @(disp, PC), Rn {:
1.596 + if( in_delay_slot ) {
1.597 + SLOTILLEGAL();
1.598 + return 2;
1.599 + } else {
1.600 + uint32_t target = pc + disp + 4;
1.601 + if( IS_IN_ICACHE(target) ) {
1.602 + // If the target address is in the same page as the code, it's
1.603 + // pretty safe to just ref it directly and circumvent the whole
1.604 + // memory subsystem. (this is a big performance win)
1.605 +
1.606 + // FIXME: There's a corner-case that's not handled here when
1.607 + // the current code-page is in the ITLB but not in the UTLB.
1.608 + // (should generate a TLB miss although need to test SH4
1.609 + // behaviour to confirm) Unlikely to be anyone depending on this
1.610 + // behaviour though.
1.611 + sh4ptr_t ptr = GET_ICACHE_PTR(target);
1.612 + XOP2P( OP_MOV, ptr, REG_TMP0 );
1.613 + XOP2( OP_MOVSX16, REG_TMP0, R_R(Rn) );
1.614 + } else {
1.615 + // Note: we use sh4r.pc for the calc as we could be running at a
1.616 + // different virtual address than the translation was done with,
1.617 + // but we can safely assume that the low bits are the same.
1.618 + XOP2( OP_MOV, R_PC, REG_TMP0 );
1.619 + XOP2( OP_ADD, (pc - xbb->pc_begin) + disp + 4, REG_TMP0 );
1.620 + XOP2E(OP_LOADW, REG_TMP0, R_R(Rn) );
1.621 + }
1.622 + }
1.623 +:}
1.624 +MOV.W @(disp, Rm), R0 {:
1.625 + XOP2( OP_MOV, R_R(Rm), REG_TMP0 );
1.626 + XOP2I(OP_ADD, disp, REG_TMP0 );
1.627 + RALIGN16( REG_TMP0 );
1.628 + XOP2E(OP_LOADW, REG_TMP0, R_R0 );
1.629 +:}
1.630 +MOVA @(disp, PC), R0 {:
1.631 + if( in_delay_slot ) {
1.632 + SLOTILLEGAL();
1.633 + return 2;
1.634 + } else {
1.635 + XOP2( OP_MOV, R_PC, R_R0 );
1.636 + XOP2I( OP_ADD, (pc - xbb->pc_begin) + disp + 4 - (pc&0x03), R_R0 );
1.637 + }
1.638 +:}
1.639 +MOVCA.L R0, @Rn {:
1.640 + XOP2E(OP_STORELCA, R_R(Rn), R_R0 );
1.641 +:}
1.642 +LDTLB {:
1.643 + CHECKPRIV();
1.644 + XOPCALL0( MMU_ldtlb );
1.645 +:}
1.646 +OCBI @Rn {: XOP1E( OP_OCBI, R_R(Rn) ); :}
1.647 +OCBP @Rn {: XOP1E( OP_OCBP, R_R(Rn) ); :}
1.648 +OCBWB @Rn {: XOP1E( OP_OCBWB, R_R(Rn) ); :}
1.649 +PREF @Rn {: XOP1E( OP_PREF, R_R(Rn) ); :}
1.650 +
1.651 +CLRMAC {:
1.652 + XOP2I( OP_MOV, 0, R_MACL );
1.653 + XOP2I( OP_MOV, 0, R_MACH );
1.654 +:}
1.655 +CLRS {: XOP2I( OP_MOV, 0, R_S ); :}
1.656 +CLRT {: XOP2I( OP_MOV, 0, R_T ); :}
1.657 +SETS {: XOP2I( OP_MOV, 1, R_S ); :}
1.658 +SETT {: XOP2I( OP_MOV, 1, R_T ); :}
1.659 +FMOV FRm, FRn {:
1.660 + CHECKFPUEN();
1.661 + if( sh4_xir.double_size ) {
1.662 + XOP2( OP_MOVQ, (FRm&1) ? R_XD(FRm) : R_DR(FRm), (FRn&1) ? R_XD(FRn) : R_DR(FRn) );
1.663 + } else {
1.664 + XOP2( OP_MOV, R_FR(FRm), R_FR(FRn) );
1.665 + }
1.666 +:}
1.667 +FMOV FRm, @Rn {:
1.668 + CHECKFPUEN();
1.669 + if( sh4_xir.double_size ) {
1.670 + WALIGN64( R_R(Rn) );
1.671 + XOP2E( OP_STOREQ, R_R(Rn), (FRm&1) ? R_XD(FRm) : R_DR(FRm) );
1.672 + } else {
1.673 + WALIGN32( R_R(Rn) );
1.674 + XOP2E( OP_STOREL, R_R(Rn), R_FR(FRm) );
1.675 + }
1.676 +:}
1.677 +FMOV @Rm, FRn {:
1.678 + CHECKFPUEN();
1.679 + if( sh4_xir.double_size ) {
1.680 + RALIGN64( R_R(Rm) );
1.681 + XOP2E( OP_LOADQ, R_R(Rm), (FRn&1) ? R_XD(FRn) : R_DR(FRn) );
1.682 + } else {
1.683 + RALIGN32( R_R(Rm) );
1.684 + XOP2E( OP_LOADL, R_R(Rm), R_FR(FRn) );
1.685 + }
1.686 +:}
1.687 +FMOV FRm, @-Rn {:
1.688 + CHECKFPUEN();
1.689 + if( sh4_xir.double_size ) {
1.690 + WALIGN64( R_R(Rn) );
1.691 + XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1.692 + XOP2I(OP_ADD, -8, REG_TMP0 );
1.693 + XOP2E(OP_STOREQ, REG_TMP0, (FRm&1) ? R_XD(FRm) : R_DR(FRm) );
1.694 + XOP2I(OP_ADD, -8, R_R(Rn) );
1.695 + } else {
1.696 + WALIGN32( R_R(Rn) );
1.697 + XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1.698 + XOP2I(OP_ADD, -4, REG_TMP0 );
1.699 + XOP2E(OP_STOREL, REG_TMP0, R_FR(FRm) );
1.700 + XOP2I(OP_ADD, -4, R_R(Rn) );
1.701 + }
1.702 +:}
1.703 +FMOV @Rm+, FRn {:
1.704 + CHECKFPUEN();
1.705 + if( sh4_xir.double_size ) {
1.706 + RALIGN64( R_R(Rm) );
1.707 + XOP2( OP_LOADQ, R_R(Rm), (FRn&1) ? R_XD(FRn) : R_DR(FRn) );
1.708 + XOP2I( OP_ADD, 8, R_R(Rm) );
1.709 + } else {
1.710 + RALIGN32( R_R(Rm) );
1.711 + XOP2( OP_LOADL, R_R(Rm), R_FR(FRn) );
1.712 + XOP2I( OP_ADD, 4, R_R(Rm) );
1.713 + }
1.714 +:}
1.715 +FMOV FRm, @(R0, Rn) {:
1.716 + CHECKFPUEN();
1.717 + XOP2( OP_MOV, R_R0, REG_TMP0 );
1.718 + XOP2( OP_ADD, R_R(Rn), REG_TMP0 );
1.719 + if( sh4_xir.double_size ) {
1.720 + WALIGN64( REG_TMP0 );
1.721 + XOP2E( OP_STOREQ, REG_TMP0, (FRm&1) ? R_XD(FRm) : R_DR(FRm) );
1.722 + } else {
1.723 + WALIGN32( REG_TMP0 );
1.724 + XOP2E( OP_STOREL, REG_TMP0, R_FR(FRm) );
1.725 + }
1.726 +:}
1.727 +FMOV @(R0, Rm), FRn {:
1.728 + CHECKFPUEN();
1.729 + XOP2( OP_MOV, R_R0, REG_TMP0 );
1.730 + XOP2( OP_ADD, R_R(Rm), REG_TMP0 );
1.731 + if( sh4_xir.double_size ) {
1.732 + RALIGN64( REG_TMP0 );
1.733 + XOP2E( OP_LOADQ, REG_TMP0, (FRn&1) ? R_XD(FRn) : R_DR(FRn) );
1.734 + } else {
1.735 + RALIGN32( REG_TMP0 );
1.736 + XOP2E( OP_LOADL, REG_TMP0, R_FR(FRn) );
1.737 + }
1.738 +:}
1.739 +FLDI0 FRn {: /* IFF PR=0 */
1.740 + CHECKFPUEN();
1.741 + if( sh4_xir.double_prec == 0 ) {
1.742 + XOP2F( OP_MOV, 0.0, R_FR(FRn) );
1.743 + }
1.744 +:}
1.745 +FLDI1 FRn {: /* IFF PR=0 */
1.746 + CHECKFPUEN();
1.747 + if( sh4_xir.double_prec == 0 ) {
1.748 + XOP2F( OP_MOV, 1.0, R_FR(FRn) );
1.749 + }
1.750 +:}
1.751 +FLOAT FPUL, FRn {:
1.752 + CHECKFPUEN();
1.753 + if( sh4_xir.double_prec ) {
1.754 + XOP2( OP_ITOD, R_FPUL, R_DR(FRn) );
1.755 + } else {
1.756 + XOP2( OP_ITOF, R_FPUL, R_FR(FRn) );
1.757 + }
1.758 +:}
1.759 +FTRC FRm, FPUL {:
1.760 + CHECKFPUEN();
1.761 + if( sh4_xir.double_prec ) {
1.762 + XOP2( OP_DTOI, R_DR(FRm), R_FPUL );
1.763 + } else {
1.764 + XOP2( OP_FTOI, R_FR(FRm), R_FPUL );
1.765 + }
1.766 +:}
1.767 +FLDS FRm, FPUL {:
1.768 + CHECKFPUEN();
1.769 + XOP2( OP_MOV, R_FR(FRm), R_FPUL );
1.770 +:}
1.771 +FSTS FPUL, FRn {:
1.772 + CHECKFPUEN();
1.773 + XOP2( OP_MOV, R_FPUL, R_FR(FRn) );
1.774 +:}
1.775 +FCNVDS FRm, FPUL {:
1.776 + CHECKFPUEN();
1.777 + if( sh4_xir.double_prec && !sh4_xir.double_size ) {
1.778 + XOP2( OP_DTOF, R_DR(FRm), R_FPUL );
1.779 + }
1.780 +:}
1.781 +FCNVSD FPUL, FRn {:
1.782 + CHECKFPUEN();
1.783 + if( sh4_xir.double_prec && !sh4_xir.double_size ) {
1.784 + XOP2( OP_FTOD, R_FPUL, R_DR(FRn) );
1.785 + }
1.786 +:}
1.787 +FABS FRn {:
1.788 + CHECKFPUEN();
1.789 + if( sh4_xir.double_prec ) {
1.790 + XOP1( OP_ABSD, R_DR(FRn) );
1.791 + } else {
1.792 + XOP1( OP_ABSF, R_FR(FRn) );
1.793 + }
1.794 +:}
1.795 +FADD FRm, FRn {:
1.796 + CHECKFPUEN();
1.797 + if( sh4_xir.double_prec ) {
1.798 + XOP2( OP_ADDD, R_DR(FRm), R_DR(FRn) );
1.799 + } else {
1.800 + XOP2( OP_ADDF, R_FR(FRm), R_FR(FRn) );
1.801 + }
1.802 +:}
1.803 +FDIV FRm, FRn {:
1.804 + CHECKFPUEN();
1.805 + if( sh4_xir.double_prec ) {
1.806 + XOP2( OP_DIVD, R_DR(FRm), R_DR(FRn) );
1.807 + } else {
1.808 + XOP2( OP_DIVF, R_FR(FRm), R_FR(FRn) );
1.809 + }
1.810 +:}
1.811 +FMAC FR0, FRm, FRn {:
1.812 + CHECKFPUEN();
1.813 + if( sh4_xir.double_prec == 0 ) {
1.814 + XOP2( OP_MOV, R_FR(0), REG_TMP0 );
1.815 + XOP2( OP_MULF, R_FR(FRm), REG_TMP0 );
1.816 + XOP2( OP_ADDF, REG_TMP0, R_FR(FRn) );
1.817 + }
1.818 +:}
1.819 +FMUL FRm, FRn {:
1.820 + CHECKFPUEN();
1.821 + if( sh4_xir.double_prec ) {
1.822 + XOP2( OP_MULD, R_DR(FRm), R_DR(FRn) );
1.823 + } else {
1.824 + XOP2( OP_MULF, R_FR(FRm), R_FR(FRn) );
1.825 + }
1.826 +:}
1.827 +FNEG FRn {:
1.828 + CHECKFPUEN();
1.829 + if( sh4_xir.double_prec ) {
1.830 + XOP1( OP_NEGD, R_DR(FRn) );
1.831 + } else {
1.832 + XOP1( OP_NEGF, R_FR(FRn) );
1.833 + }
1.834 +:}
1.835 +FSRRA FRn {:
1.836 + CHECKFPUEN();
1.837 + if( sh4_xir.double_prec == 0 ) {
1.838 + XOP1( OP_RSQRTF, R_FR(FRn) );
1.839 + }
1.840 +:}
1.841 +FSQRT FRn {:
1.842 + CHECKFPUEN();
1.843 + if( sh4_xir.double_prec ) {
1.844 + XOP1( OP_SQRTD, R_DR(FRn) );
1.845 + } else {
1.846 + XOP1( OP_SQRTF, R_FR(FRn) );
1.847 + }
1.848 +:}
1.849 +FSUB FRm, FRn {:
1.850 + CHECKFPUEN();
1.851 + if( sh4_xir.double_prec ) {
1.852 + XOP2( OP_SUBD, R_DR(FRm), R_DR(FRn) );
1.853 + } else {
1.854 + XOP2( OP_SUBF, R_FR(FRm), R_FR(FRn) );
1.855 + }
1.856 +:}
1.857 +FCMP/EQ FRm, FRn {:
1.858 + CHECKFPUEN();
1.859 + if( sh4_xir.double_prec ) {
1.860 + XOP2( OP_CMPD, R_DR(FRm), R_DR(FRn) );
1.861 + } else {
1.862 + XOP2( OP_CMPF, R_FR(FRm), R_FR(FRn) );
1.863 + }
1.864 + XOP1CC( OP_ST, CC_EQ, R_T );
1.865 +:}
1.866 +FCMP/GT FRm, FRn {:
1.867 + CHECKFPUEN();
1.868 + if( sh4_xir.double_prec ) {
1.869 + XOP2( OP_CMPD, R_DR(FRm), R_DR(FRn) );
1.870 + } else {
1.871 + XOP2( OP_CMPF, R_FR(FRm), R_FR(FRn) );
1.872 + }
1.873 + XOP1CC( OP_ST, CC_SGT, R_T );
1.874 +:}
1.875 +FSCA FPUL, FRn {:
1.876 + CHECKFPUEN();
1.877 + if( sh4_xir.double_prec == 0 ) {
1.878 + XOP2( OP_SINCOSF, R_FPUL, R_DR(FRn) );
1.879 + }
1.880 +:}
1.881 +FIPR FVm, FVn {:
1.882 + CHECKFPUEN();
1.883 + if( sh4_xir.double_prec == 0 ) {
1.884 + XOP2( OP_DOTPRODV, R_FV(FVm), R_FV(FVn) );
1.885 + }
1.886 +:}
1.887 +FTRV XMTRX, FVn {:
1.888 + CHECKFPUEN();
1.889 + if( sh4_xir.double_prec == 0 ) {
1.890 + XOP2( OP_MATMULV, R_XMTRX, R_FV(FVn) );
1.891 + }
1.892 +:}
1.893 +FRCHG {:
1.894 + CHECKFPUEN();
1.895 + XOP2I( OP_XOR, FPSCR_FR, R_FPSCR );
1.896 + XOPCALL0( sh4_switch_fr_banks );
1.897 +:}
1.898 +FSCHG {:
1.899 + CHECKFPUEN();
1.900 + XOP2I( OP_XOR, FPSCR_SZ, R_FPSCR );
1.901 + XOP2I( OP_XOR, FPSCR_SZ, R_SH4_MODE );
1.902 + sh4_xir.double_size = !sh4_xir.double_size;
1.903 +:}
1.904 +LDC Rm, SR {:
1.905 + if( in_delay_slot ) {
1.906 + SLOTILLEGAL();
1.907 + } else {
1.908 + CHECKPRIV();
1.909 + XOPCALL1( sh4_write_sr, R_R(Rm) );
1.910 + }
1.911 + return 2;
1.912 +:}
1.913 +LDC Rm, GBR {: XOP2( OP_MOV, R_R(Rm), R_GBR ); :}
1.914 +LDC Rm, VBR {: CHECKPRIV(); XOP2( OP_MOV, R_R(Rm), R_VBR ); :}
1.915 +LDC Rm, SSR {: CHECKPRIV(); XOP2( OP_MOV, R_R(Rm), R_SSR ); :}
1.916 +LDC Rm, SGR {: CHECKPRIV(); XOP2( OP_MOV, R_R(Rm), R_SGR ); :}
1.917 +LDC Rm, SPC {: CHECKPRIV(); XOP2( OP_MOV, R_R(Rm), R_SPC ); :}
1.918 +LDC Rm, DBR {: CHECKPRIV(); XOP2( OP_MOV, R_R(Rm), R_DBR ); :}
1.919 +LDC Rm, Rn_BANK {: CHECKPRIV(); XOP2( OP_MOV, R_R(Rm), R_BANK(Rn_BANK) ); :}
1.920 +LDC.L @Rm+, GBR {:
1.921 + XOP2E( OP_LOADL, R_R(Rm), R_GBR );
1.922 + XOP2I( OP_ADD, 4, R_R(Rm) );
1.923 +:}
1.924 +LDC.L @Rm+, SR {:
1.925 + if( in_delay_slot ) {
1.926 + SLOTILLEGAL();
1.927 + } else {
1.928 + CHECKPRIV();
1.929 + RALIGN32( R_R(Rm) );
1.930 + XOP2E( OP_LOADL, R_R(Rm), REG_TMP0 );
1.931 + XOP2I( OP_ADD, 4, R_R(Rm) );
1.932 + XOPCALL1( sh4_write_sr, REG_TMP0 );
1.933 + }
1.934 + return 2;
1.935 +:}
1.936 +LDC.L @Rm+, VBR {:
1.937 + CHECKPRIV();
1.938 + RALIGN32( R_R(Rm) );
1.939 + XOP2E( OP_LOADL, R_R(Rm), R_VBR );
1.940 + XOP2I( OP_ADD, 4, R_R(Rm) );
1.941 +:}
1.942 +LDC.L @Rm+, SSR {:
1.943 + CHECKPRIV();
1.944 + RALIGN32( R_R(Rm) );
1.945 + XOP2E( OP_LOADL, R_R(Rm), R_SSR );
1.946 + XOP2I( OP_ADD, 4, R_R(Rm) );
1.947 +:}
1.948 +LDC.L @Rm+, SGR {:
1.949 + CHECKPRIV();
1.950 + RALIGN32( R_R(Rm) );
1.951 + XOP2E( OP_LOADL, R_R(Rm), R_SGR );
1.952 + XOP2I( OP_ADD, 4, R_R(Rm) );
1.953 +:}
1.954 +LDC.L @Rm+, SPC {:
1.955 + CHECKPRIV();
1.956 + RALIGN32( R_R(Rm) );
1.957 + XOP2E( OP_LOADL, R_R(Rm), R_SPC );
1.958 + XOP2I( OP_ADD, 4, R_R(Rm) );
1.959 +:}
1.960 +LDC.L @Rm+, DBR {:
1.961 + CHECKPRIV();
1.962 + RALIGN32( R_R(Rm) );
1.963 + XOP2E( OP_LOADL, R_R(Rm), R_DBR );
1.964 + XOP2I( OP_ADD, 4, R_R(Rm) );
1.965 +:}
1.966 +LDC.L @Rm+, Rn_BANK {:
1.967 + CHECKPRIV();
1.968 + RALIGN32( R_R(Rm) );
1.969 + XOP2E( OP_LOADL, R_R(Rm), R_BANK(Rn_BANK) );
1.970 + XOP2I( OP_ADD, 4, R_R(Rm) );
1.971 +:}
1.972 +LDS Rm, FPSCR {:
1.973 + CHECKFPUEN();
1.974 + XOPCALL1( sh4_write_fpscr, R_R(Rm) );
1.975 + return 2;
1.976 +:}
1.977 +LDS Rm, FPUL {:
1.978 + CHECKFPUEN();
1.979 + XOP2( OP_MOV, R_R(Rm), R_FPUL );
1.980 +:}
1.981 +LDS Rm, MACH {: XOP2( OP_MOV, R_R(Rm), R_MACH ); :}
1.982 +LDS Rm, MACL {: XOP2( OP_MOV, R_R(Rm), R_MACL ); :}
1.983 +LDS Rm, PR {: XOP2( OP_MOV, R_R(Rm), R_PR ); :}
1.984 +LDS.L @Rm+, FPSCR {:
1.985 + CHECKFPUEN();
1.986 + RALIGN32( R_R(Rm) );
1.987 + XOP2E( OP_LOADL, R_R(Rm), REG_TMP0 );
1.988 + XOP2I( OP_ADD, 4, R_R(Rm) );
1.989 + XOPCALL1( sh4_write_fpscr, REG_TMP0 );
1.990 + return 2;
1.991 +:}
1.992 +LDS.L @Rm+, FPUL {:
1.993 + CHECKFPUEN();
1.994 + RALIGN32( R_R(Rm) );
1.995 + XOP2E( OP_LOADL, R_R(Rm), R_FPUL );
1.996 + XOP2I( OP_ADD, 4, R_R(Rm) );
1.997 +:}
1.998 +LDS.L @Rm+, MACH {:
1.999 + RALIGN32( R_R(Rm) );
1.1000 + XOP2E( OP_LOADL, R_R(Rm), R_MACH );
1.1001 + XOP2I( OP_ADD, 4, R_R(Rm) );
1.1002 +:}
1.1003 +LDS.L @Rm+, MACL {:
1.1004 + RALIGN32( R_R(Rm) );
1.1005 + XOP2E( OP_LOADL, R_R(Rm), R_MACL );
1.1006 + XOP2I( OP_ADD, 4, R_R(Rm) );
1.1007 +:}
1.1008 +LDS.L @Rm+, PR {:
1.1009 + RALIGN32( R_R(Rm) );
1.1010 + XOP2E( OP_LOADL, R_R(Rm), R_PR );
1.1011 + XOP2I( OP_ADD, 4, R_R(Rm) );
1.1012 +:}
1.1013 +STC SR, Rn {:
1.1014 + CHECKPRIV();
1.1015 + XOPCALLR( sh4_read_sr, R_R(Rn) );
1.1016 +:}
1.1017 +STC GBR, Rn {: XOP2( OP_MOV, R_GBR, R_R(Rn) ); :}
1.1018 +STC VBR, Rn {: CHECKPRIV(); XOP2( OP_MOV, R_VBR, R_R(Rn) ); :}
1.1019 +STC SSR, Rn {: CHECKPRIV(); XOP2( OP_MOV, R_SSR, R_R(Rn) ); :}
1.1020 +STC SPC, Rn {: CHECKPRIV(); XOP2( OP_MOV, R_SPC, R_R(Rn) ); :}
1.1021 +STC SGR, Rn {: CHECKPRIV(); XOP2( OP_MOV, R_SGR, R_R(Rn) ); :}
1.1022 +STC DBR, Rn {: CHECKPRIV(); XOP2( OP_MOV, R_DBR, R_R(Rn) ); :}
1.1023 +STC Rm_BANK, Rn {: CHECKPRIV(); XOP2( OP_MOV, R_BANK(Rm_BANK), R_R(Rn) ); :}
1.1024 +STC.L SR, @-Rn {:
1.1025 + CHECKPRIV();
1.1026 + XOPCALLR( sh4_read_sr, REG_TMP1 );
1.1027 + WALIGN32( R_R(Rn) );
1.1028 + XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1.1029 + XOP2I(OP_ADD, -4, REG_TMP0 );
1.1030 + XOP2E(OP_STOREL, REG_TMP0, REG_TMP1 );
1.1031 + XOP2I(OP_ADD, -4, R_R(Rn) );
1.1032 +:}
1.1033 +STC.L VBR, @-Rn {:
1.1034 + CHECKPRIV();
1.1035 + WALIGN32( R_R(Rn) );
1.1036 + XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1.1037 + XOP2I(OP_ADD, -4, REG_TMP0 );
1.1038 + XOP2E(OP_STOREL, REG_TMP0, R_VBR );
1.1039 + XOP2I(OP_ADD, -4, R_R(Rn) );
1.1040 +:}
1.1041 +STC.L SSR, @-Rn {:
1.1042 + CHECKPRIV();
1.1043 + WALIGN32( R_R(Rn) );
1.1044 + XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1.1045 + XOP2I(OP_ADD, -4, REG_TMP0 );
1.1046 + XOP2E(OP_STOREL, REG_TMP0, R_SSR );
1.1047 + XOP2I(OP_ADD, -4, R_R(Rn) );
1.1048 +:}
1.1049 +STC.L SPC, @-Rn {:
1.1050 + CHECKPRIV();
1.1051 + WALIGN32( R_R(Rn) );
1.1052 + XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1.1053 + XOP2I(OP_ADD, -4, REG_TMP0 );
1.1054 + XOP2E(OP_STOREL, REG_TMP0, R_SPC );
1.1055 + XOP2I(OP_ADD, -4, R_R(Rn) );
1.1056 +:}
1.1057 +STC.L SGR, @-Rn {:
1.1058 + CHECKPRIV();
1.1059 + WALIGN32( R_R(Rn) );
1.1060 + XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1.1061 + XOP2I(OP_ADD, -4, REG_TMP0 );
1.1062 + XOP2E(OP_STOREL, REG_TMP0, R_SGR );
1.1063 + XOP2I(OP_ADD, -4, R_R(Rn) );
1.1064 +:}
1.1065 +STC.L DBR, @-Rn {:
1.1066 + CHECKPRIV();
1.1067 + WALIGN32( R_R(Rn) );
1.1068 + XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1.1069 + XOP2I(OP_ADD, -4, REG_TMP0 );
1.1070 + XOP2E(OP_STOREL, REG_TMP0, R_DBR );
1.1071 + XOP2I(OP_ADD, -4, R_R(Rn) );
1.1072 +:}
1.1073 +STC.L Rm_BANK, @-Rn {:
1.1074 + CHECKPRIV();
1.1075 + WALIGN32( R_R(Rn) );
1.1076 + XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1.1077 + XOP2I(OP_ADD, -4, REG_TMP0 );
1.1078 + XOP2E(OP_STOREL, REG_TMP0, R_BANK(Rm_BANK) );
1.1079 + XOP2I(OP_ADD, -4, R_R(Rn) );
1.1080 +:}
1.1081 +STC.L GBR, @-Rn {:
1.1082 + WALIGN32( R_R(Rn) );
1.1083 + XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1.1084 + XOP2I(OP_ADD, -4, REG_TMP0 );
1.1085 + XOP2E(OP_STOREL, REG_TMP0, R_GBR );
1.1086 + XOP2I(OP_ADD, -4, R_R(Rn) );
1.1087 +:}
1.1088 +STS FPSCR, Rn {:
1.1089 + CHECKFPUEN();
1.1090 + XOP2( OP_MOV, R_FPSCR, R_R(Rn) );
1.1091 +:}
1.1092 +STS FPUL, Rn {:
1.1093 + CHECKFPUEN();
1.1094 + XOP2( OP_MOV, R_FPUL, R_R(Rn) );
1.1095 +:}
1.1096 +STS MACH, Rn {:
1.1097 + XOP2( OP_MOV, R_MACH, R_R(Rn) );
1.1098 +:}
1.1099 +STS MACL, Rn {:
1.1100 + XOP2( OP_MOV, R_MACL, R_R(Rn) );
1.1101 +:}
1.1102 +STS PR, Rn {:
1.1103 + XOP2( OP_MOV, R_PR, R_R(Rn) );
1.1104 +:}
1.1105 +STS.L FPSCR, @-Rn {:
1.1106 + CHECKFPUEN();
1.1107 + WALIGN32( R_R(Rn) );
1.1108 + XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1.1109 + XOP2I(OP_ADD, -4, REG_TMP0 );
1.1110 + XOP2E(OP_STOREL, REG_TMP0, R_FPSCR );
1.1111 + XOP2I(OP_ADD, -4, R_R(Rn) );
1.1112 +:}
1.1113 +STS.L FPUL, @-Rn {:
1.1114 + CHECKFPUEN();
1.1115 + WALIGN32( R_R(Rn) );
1.1116 + XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1.1117 + XOP2I(OP_ADD, -4, REG_TMP0 );
1.1118 + XOP2E(OP_STOREL, REG_TMP0, R_FPUL );
1.1119 + XOP2I(OP_ADD, -4, R_R(Rn) );
1.1120 +:}
1.1121 +STS.L MACH, @-Rn {:
1.1122 + WALIGN32( R_R(Rn) );
1.1123 + XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1.1124 + XOP2I(OP_ADD, -4, REG_TMP0 );
1.1125 + XOP2E(OP_STOREL, REG_TMP0, R_MACH );
1.1126 + XOP2I(OP_ADD, -4, R_R(Rn) );
1.1127 +:}
1.1128 +STS.L MACL, @-Rn {:
1.1129 + WALIGN32( R_R(Rn) );
1.1130 + XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1.1131 + XOP2I(OP_ADD, -4, REG_TMP0 );
1.1132 + XOP2E(OP_STOREL, REG_TMP0, R_MACL );
1.1133 + XOP2I(OP_ADD, -4, R_R(Rn) );
1.1134 +:}
1.1135 +STS.L PR, @-Rn {:
1.1136 + WALIGN32( R_R(Rn) );
1.1137 + XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1.1138 + XOP2I(OP_ADD, -4, REG_TMP0 );
1.1139 + XOP2E(OP_STOREL, REG_TMP0, R_PR );
1.1140 + XOP2I(OP_ADD, -4, R_R(Rn) );
1.1141 +:}
1.1142 +
1.1143 +BF disp {:
1.1144 + if( in_delay_slot ) {
1.1145 + SLOTILLEGAL();
1.1146 + } else {
1.1147 + XOP2I( OP_ADD, (pc+2 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
1.1148 + XOP2I( OP_CMP, 0, R_T );
1.1149 + XOP2IICC( OP_BRCOND, CC_EQ, disp+pc+4-xbb->pc_begin, pc+2-xbb->pc_begin );
1.1150 + }
1.1151 + return 2;
1.1152 +:}
1.1153 +BF/S disp {:
1.1154 + if( in_delay_slot ) {
1.1155 + SLOTILLEGAL();
1.1156 + return 2;
1.1157 + } else {
1.1158 + if( UNTRANSLATABLE(pc+2 ) ) {
1.1159 + XOP2I( OP_CMP, 0, R_T );
1.1160 + XOP2IICC( OP_BRCONDDEL, CC_EQ, disp+pc+4-xbb->pc_begin, pc+4-xbb->pc_begin );
1.1161 + EMU_DELAY_SLOT();
1.1162 + return 2;
1.1163 + } else {
1.1164 + XOP2( OP_MOV, R_T, REG_TMP2 );
1.1165 + sh4_decode_instruction( xbb, pc+2, TRUE );
1.1166 + if( !XOP_IS_TERMINATOR( xbb->ir_ptr->prev ) ) {
1.1167 + XOP2I( OP_ADD, (pc+4 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
1.1168 + XOP2I( OP_CMP, 0, REG_TMP2 );
1.1169 + XOP2IICC( OP_BRCOND, CC_EQ, disp+pc+4-xbb->pc_begin, pc+4-xbb->pc_begin );
1.1170 + }
1.1171 + return 4;
1.1172 + }
1.1173 + }
1.1174 +:}
1.1175 +BT disp {:
1.1176 + if( in_delay_slot ) {
1.1177 + SLOTILLEGAL();
1.1178 + } else {
1.1179 + XOP2I( OP_ADD, (pc+2 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
1.1180 + XOP2I( OP_CMP, 1, R_T );
1.1181 + XOP2IICC( OP_BRCOND, CC_EQ, disp+pc+4-xbb->pc_begin, pc+2-xbb->pc_begin );
1.1182 + }
1.1183 + return 2;
1.1184 +:}
1.1185 +BT/S disp {:
1.1186 + if( in_delay_slot ) {
1.1187 + SLOTILLEGAL();
1.1188 + return 2;
1.1189 + } else {
1.1190 + if( UNTRANSLATABLE(pc+2 ) ) {
1.1191 + XOP2I( OP_CMP, 1, R_T );
1.1192 + XOP2IICC( OP_BRCONDDEL, CC_EQ, disp+pc+4-xbb->pc_begin, pc+2-xbb->pc_begin );
1.1193 + EMU_DELAY_SLOT();
1.1194 + return 2;
1.1195 + } else {
1.1196 + XOP2( OP_MOV, R_T, REG_TMP2 );
1.1197 + sh4_decode_instruction( xbb, pc+2, TRUE );
1.1198 + if( !XOP_IS_TERMINATOR( xbb->ir_ptr->prev ) ) {
1.1199 + XOP2I( OP_ADD, (pc+4 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
1.1200 + XOP2I( OP_CMP, 1, REG_TMP2 );
1.1201 + XOP2IICC( OP_BRCOND, CC_EQ, disp+pc+4-xbb->pc_begin, pc+4-xbb->pc_begin );
1.1202 + }
1.1203 + return 4;
1.1204 + }
1.1205 + }
1.1206 +:}
1.1207 +BRA disp {:
1.1208 + if( in_delay_slot ) {
1.1209 + SLOTILLEGAL();
1.1210 + return 2;
1.1211 + } else {
1.1212 + if( UNTRANSLATABLE(pc+2) ) {
1.1213 + XOP2( OP_MOV, R_PC, R_NEW_PC );
1.1214 + XOP2I( OP_ADD, pc+disp+4-xbb->pc_begin, R_NEW_PC );
1.1215 + EMU_DELAY_SLOT();
1.1216 + return 2;
1.1217 + } else {
1.1218 + sh4_decode_instruction( xbb, pc+2, TRUE );
1.1219 + if( xbb->ir_ptr->prev == NULL || !XOP_IS_TERMINATOR( xbb->ir_ptr->prev ) ) {
1.1220 + XOP2I( OP_ADD, (pc+4 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
1.1221 + XOP1I( OP_BRREL, pc+disp+4-xbb->pc_begin );
1.1222 + }
1.1223 + return 4;
1.1224 + }
1.1225 + }
1.1226 +:}
1.1227 +BRAF Rn {:
1.1228 + if( in_delay_slot ) {
1.1229 + SLOTILLEGAL();
1.1230 + return 2;
1.1231 + } else {
1.1232 + XOP2( OP_MOV, R_R(Rn), REG_TMP2 );
1.1233 + XOP2( OP_ADD, R_PC, REG_TMP2 );
1.1234 + XOP2I( OP_ADD, pc - xbb->pc_begin + 4, REG_TMP2 );
1.1235 + if( UNTRANSLATABLE(pc+2) ) {
1.1236 + XOP2( OP_MOV, REG_TMP2, R_NEW_PC );
1.1237 + EMU_DELAY_SLOT();
1.1238 + return 2;
1.1239 + } else {
1.1240 + sh4_decode_instruction( xbb, pc + 2, TRUE );
1.1241 + if( !XOP_IS_TERMINATOR( xbb->ir_ptr->prev ) ) {
1.1242 + XOP2I( OP_ADD, (pc+4 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
1.1243 + XOP1( OP_BR, REG_TMP2 );
1.1244 + }
1.1245 + return 4;
1.1246 + }
1.1247 + }
1.1248 +:}
1.1249 +BSR disp {:
1.1250 + if( in_delay_slot ) {
1.1251 + SLOTILLEGAL();
1.1252 + return 2;
1.1253 + } else {
1.1254 + XOP2( OP_MOV, R_PC, R_PR );
1.1255 + XOP2I( OP_ADD, pc - xbb->pc_begin + 4, R_PR );
1.1256 + if( UNTRANSLATABLE(pc+2) ) {
1.1257 + XOP2( OP_MOV, R_PC, R_NEW_PC );
1.1258 + XOP2I( OP_ADD, pc+disp+4-xbb->pc_begin, R_NEW_PC );
1.1259 + EMU_DELAY_SLOT();
1.1260 + return 2;
1.1261 + } else {
1.1262 + sh4_decode_instruction( xbb, pc+2, TRUE );
1.1263 + if( !XOP_IS_TERMINATOR( xbb->ir_ptr->prev ) ) {
1.1264 + XOP2I( OP_ADD, (pc+4 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
1.1265 + XOP1I( OP_BRREL, pc+disp+4-xbb->pc_begin );
1.1266 + }
1.1267 + return 4;
1.1268 + }
1.1269 + }
1.1270 +:}
1.1271 +BSRF Rn {:
1.1272 + if( in_delay_slot ) {
1.1273 + SLOTILLEGAL();
1.1274 + return 2;
1.1275 + } else {
1.1276 + XOP2( OP_MOV, R_PC, R_PR );
1.1277 + XOP2I( OP_ADD, pc - xbb->pc_begin + 4, R_PR );
1.1278 + XOP2( OP_MOV, R_R(Rn), REG_TMP2 );
1.1279 + XOP2( OP_ADD, R_PC, REG_TMP2 );
1.1280 + XOP2I( OP_ADD, pc - xbb->pc_begin + 4, REG_TMP2 );
1.1281 + if( UNTRANSLATABLE(pc+2) ) {
1.1282 + XOP2( OP_MOV, REG_TMP2, R_NEW_PC );
1.1283 + EMU_DELAY_SLOT();
1.1284 + return 2;
1.1285 + } else {
1.1286 + sh4_decode_instruction( xbb, pc+2, TRUE );
1.1287 + if( !XOP_IS_TERMINATOR( xbb->ir_ptr->prev ) ) {
1.1288 + XOP2I( OP_ADD, (pc+4 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
1.1289 + XOP1( OP_BR, REG_TMP2 );
1.1290 + }
1.1291 + return 4;
1.1292 + }
1.1293 + }
1.1294 +:}
1.1295 +JMP @Rn {:
1.1296 + if( in_delay_slot ) {
1.1297 + SLOTILLEGAL();
1.1298 + return 2;
1.1299 + } else {
1.1300 + if( UNTRANSLATABLE(pc+2) ) {
1.1301 + XOP2( OP_MOV, R_R(Rn), R_NEW_PC );
1.1302 + EMU_DELAY_SLOT();
1.1303 + return 2;
1.1304 + } else {
1.1305 + XOP2( OP_MOV, R_R(Rn), REG_TMP2 );
1.1306 + sh4_decode_instruction( xbb, pc+2, TRUE );
1.1307 + if( !XOP_IS_TERMINATOR( xbb->ir_ptr->prev ) ) {
1.1308 + XOP2I( OP_ADD, (pc+4 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
1.1309 + XOP1( OP_BR, REG_TMP2 );
1.1310 + }
1.1311 + return 4;
1.1312 + }
1.1313 + }
1.1314 +:}
1.1315 +JSR @Rn {:
1.1316 + if( in_delay_slot ) {
1.1317 + SLOTILLEGAL();
1.1318 + return 2;
1.1319 + } else {
1.1320 + XOP2( OP_MOV, R_PC, R_PR );
1.1321 + XOP2I( OP_ADD, pc - xbb->pc_begin + 4, R_PR );
1.1322 + if( UNTRANSLATABLE(pc+2) ) {
1.1323 + XOP2( OP_MOV, R_R(Rn), R_NEW_PC );
1.1324 + EMU_DELAY_SLOT();
1.1325 + return 2;
1.1326 + } else {
1.1327 + XOP2( OP_MOV, R_R(Rn), REG_TMP2 );
1.1328 + sh4_decode_instruction( xbb, pc+2, TRUE );
1.1329 + if( !XOP_IS_TERMINATOR( xbb->ir_ptr->prev ) ) {
1.1330 + XOP2I( OP_ADD, (pc+4 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
1.1331 + XOP1( OP_BR, REG_TMP2 );
1.1332 + }
1.1333 + return 4;
1.1334 + }
1.1335 + }
1.1336 +:}
1.1337 +RTE {:
1.1338 + CHECKPRIV();
1.1339 + if( in_delay_slot ) {
1.1340 + SLOTILLEGAL();
1.1341 + return 2;
1.1342 + } else {
1.1343 + if( UNTRANSLATABLE(pc+2) ) {
1.1344 + XOP2( OP_MOV, R_SPC, R_NEW_PC );
1.1345 + EMU_DELAY_SLOT();
1.1346 + return 2;
1.1347 + } else {
1.1348 + XOP2( OP_MOV, R_SPC, REG_TMP2 );
1.1349 + XOPCALL1( sh4_write_sr, R_SSR );
1.1350 + sh4_decode_instruction( xbb, pc+2, TRUE );
1.1351 + if( !XOP_IS_TERMINATOR( xbb->ir_ptr->prev ) ) {
1.1352 + XOP2I( OP_ADD, (pc+4 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
1.1353 + XOP1( OP_BR, REG_TMP2 );
1.1354 + }
1.1355 + return 4;
1.1356 + }
1.1357 + }
1.1358 +:}
1.1359 +RTS {:
1.1360 + if( in_delay_slot ) {
1.1361 + SLOTILLEGAL();
1.1362 + return 2;
1.1363 + } else {
1.1364 + if( UNTRANSLATABLE(pc+2) ) {
1.1365 + XOP2( OP_MOV, R_PR, R_NEW_PC );
1.1366 + EMU_DELAY_SLOT();
1.1367 + return 2;
1.1368 + } else {
1.1369 + XOP2( OP_MOV, R_PR, REG_TMP2 );
1.1370 + sh4_decode_instruction( xbb, pc+2, TRUE );
1.1371 + if( !XOP_IS_TERMINATOR( xbb->ir_ptr->prev ) ) {
1.1372 + XOP2I( OP_ADD, (pc+4 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
1.1373 + XOP1( OP_BR, REG_TMP2 );
1.1374 + }
1.1375 + return 4;
1.1376 + }
1.1377 + }
1.1378 +:}
1.1379 +TRAPA #imm {: XOPCALL1I( sh4_raise_trap, imm ); return pc+2; :}
1.1380 +SLEEP {: XOPCALL0( sh4_sleep ); return pc+2; :}
1.1381 +UNDEF {: UNDEF(ir); :}
1.1382 +NOP {: /* Do nothing */ :}
1.1383 +
1.1384 +%%
1.1385 + return 0;
1.1386 +}
1.1387 +
1.1388 +
1.1389 +sh4addr_t sh4_decode_basic_block( xir_basic_block_t xbb )
1.1390 +{
1.1391 + sh4addr_t pc;
1.1392 +
1.1393 + sh4_xir.fpuen_checked = FALSE;
1.1394 + sh4_xir.double_prec = sh4r.fpscr & FPSCR_PR;
1.1395 + sh4_xir.double_size = sh4r.fpscr & FPSCR_SZ;
1.1396 + xbb->address_space = (sh4r.xlat_sh4_mode&SR_MD) ? sh4_address_space : sh4_user_address_space;
1.1397 +
1.1398 + xbb->ir_alloc_begin->prev = NULL;
1.1399 + XOP1I( OP_ENTER, 0 );
1.1400 + for( pc = xbb->pc_begin; pc < xbb->pc_end; pc += 2 ) {
1.1401 + int done = sh4_decode_instruction( xbb, pc, FALSE );
1.1402 + if( done ) {
1.1403 + pc += done;
1.1404 + break;
1.1405 + }
1.1406 + }
1.1407 + xbb->ir_end = xbb->ir_ptr-1;
1.1408 + xbb->ir_end->next = NULL;
1.1409 + xbb->pc_end = pc;
1.1410 + return pc;
1.1411 +}
1.1412 +
.