2 * $Id: sh4xir.in 931 2008-10-31 02:57:59Z nkeynes $
4 * SH4 => IR conversion.
6 * Copyright (c) 2009 Nathan Keynes.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
21 #include "sh4/sh4core.h"
23 #include "sh4/sh4xir.h"
24 #include "xlat/xlat.h"
27 #define REG_OFFSET(reg) (offsetof( struct sh4_registers, reg))
29 #define R_R(rn) REG_OFFSET(r[rn])
31 #define R_SR REG_OFFSET(sr)
32 #define R_PR REG_OFFSET(pr)
33 #define R_PC REG_OFFSET(pc)
34 #define R_FPUL REG_OFFSET(fpul)
35 #define R_T REG_OFFSET(t)
36 #define R_M REG_OFFSET(m)
37 #define R_Q REG_OFFSET(q)
38 #define R_S REG_OFFSET(s)
39 #define R_FR(frn) REG_OFFSET(fr[0][(frn)^1])
40 #define R_DR(frn) REG_OFFSET(fr[0][frn])
41 #define R_DRL(f) REG_OFFSET(fr[(f)&1][(f)|0x01])
42 #define R_DRH(f) REG_OFFSET(fr[(f)&1][(f)&0x0E])
43 #define R_XF(frn) REG_OFFSET(fr[1][(frn)^1])
44 #define R_XD(frn) REG_OFFSET(fr[1][frn^1])
45 #define R_FV(fvn) REG_OFFSET(fr[0][fvn<<2])
46 #define R_XMTRX R_XD(0)
47 #define R_FPSCR REG_OFFSET(fpscr)
48 #define R_MAC REG_OFFSET(mac)
49 #define R_MACL REG_OFFSET(mac)
50 #define R_MACH REG_OFFSET(mac)+4
51 #define R_GBR REG_OFFSET(gbr)
52 #define R_SSR REG_OFFSET(ssr)
53 #define R_SPC REG_OFFSET(spc)
54 #define R_SGR REG_OFFSET(sgr)
55 #define R_DBR REG_OFFSET(dbr)
56 #define R_VBR REG_OFFSET(vbr)
57 #define R_BANK(rn) REG_OFFSET(r_bank[rn])
58 #define R_NEW_PC REG_OFFSET(new_pc)
59 #define R_DELAY_SLOT REG_OFFSET(in_delay_slot)
60 #define R_SLICE_CYCLE REG_OFFSET(slice_cycle)
61 #define R_SH4_MODE REG_OFFSET(xlat_sh4_mode)
63 uint32_t sh4_decode_basic_block(xir_basic_block_t xbb);
65 static const char *sh4_register_names[] =
66 {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
67 "sr", "pr", "pc", "fpul", "T", "M", "Q", "S",
68 "fr1", "fr0", "fr3", "fr2", "fr5", "fr4", "fr7", "fr6", "fr9", "fr8", "fr11", "fr10", "fr13", "fr11", "fr15", "fr14",
69 "xf1", "xf0", "xf3", "xf2", "xf5", "xf4", "xf7", "xf6", "xf9", "xf8", "xf11", "xf10", "xf13", "xf11", "xf15", "xf14",
70 "fpscr", 0, "macl", "mach", "gbr", "ssr", "spc", "sgr", "dbr", "vbr",
71 "r_bank0", "r_bank1", "r_bank2", "r_bank3", "r_bank4", "r_bank5", "r_bank6", "r_bank7",
72 "store_queue", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
73 "new_pc", "event_pending", "event_type", "delay_slot", "slice_cycle", "bus_cycle", "state", "xlat_mode" };
75 struct xlat_source_machine sh4_source_machine = { "sH4", &sh4r,
76 sh4_register_names, R_PC, R_NEW_PC, R_T, R_M, R_Q, R_S,
77 sh4_decode_basic_block };
80 * Struct to manage internal translation state. This state is not saved -
81 * it is only valid between calls to sh4_translate_begin_block() and
82 * sh4_translate_end_block()
84 struct sh4_xir_state {
85 gboolean fpuen_checked; /* true if we've already checked fpu enabled. */
86 gboolean double_prec; /* true if FPU is in double-precision mode */
87 gboolean double_size; /* true if FPU is in double-size mode */
90 static struct sh4_xir_state sh4_xir;
92 #define XOP1E( op, arg0 ) do{ \
93 xir_op_t ins = xir_append_op2(xbb, op, SOURCE_REGISTER_OPERAND, arg0, NO_OPERAND, 0); \
94 ins->exc = write_postexc(xbb, (in_delay_slot ? pc-2 : pc) ); \
95 ins->next = xbb->ir_ptr; \
96 xbb->ir_ptr->prev = ins; \
98 #define XOP2E( op, arg0, arg1 ) do{ \
99 xir_op_t ins = xir_append_op2(xbb, op, SOURCE_REGISTER_OPERAND, arg0, SOURCE_REGISTER_OPERAND, arg1); \
100 ins->exc = write_postexc(xbb, (in_delay_slot ? pc-2 : pc) ); \
101 ins->exc->prev = ins; \
102 ins->next = xbb->ir_ptr; \
103 xbb->ir_ptr->prev = ins; \
105 #define ALIGN(m,r,code) do { \
106 xir_op_t ins = xir_append_op2(xbb, OP_RAISEMNE, INT_IMM_OPERAND, m, SOURCE_REGISTER_OPERAND, r); \
107 ins->exc = write_exc(xbb, (in_delay_slot ? pc-2 : pc), code); \
108 ins->exc->prev = ins; \
109 ins->next = xbb->ir_ptr; \
110 xbb->ir_ptr->prev = ins; \
113 #define SLOTILLEGAL() write_exc(xbb, pc, EXC_SLOT_ILLEGAL)
114 #define ILLEGAL() write_exc(xbb, pc, EXC_ILLEGAL)
116 #define UNDEF(ir) if( in_delay_slot ) { SLOTILLEGAL(); return 2; } else { ILLEGAL(); return 2; }
117 #define CHECKFPUEN() if( !sh4_xir.fpuen_checked ) { \
118 xir_op_t ins = XOP2I( OP_RAISEMNE, SR_FD, R_SR ); \
119 if( in_delay_slot ) { \
120 ins->exc = write_exc(xbb, pc-2, EXC_SLOT_FPU_DISABLED); \
122 ins->exc = write_exc(xbb, pc, EXC_FPU_DISABLED); \
124 ins->exc->prev = ins; \
125 ins->next = xbb->ir_ptr; \
126 xbb->ir_ptr->prev = ins; \
127 sh4_xir.fpuen_checked = TRUE; \
129 #define CHECKPRIV() if( (sh4r.xlat_sh4_mode & SR_MD) == 0 ) { UNDEF(ir); }
131 #define RALIGN16(r) ALIGN(0x01,r,EXC_DATA_ADDR_READ)
132 #define RALIGN32(r) ALIGN(0x03,r,EXC_DATA_ADDR_READ)
133 #define RALIGN64(r) ALIGN(0x07,r,EXC_DATA_ADDR_READ)
134 #define WALIGN16(r) ALIGN(0x01,r,EXC_DATA_ADDR_WRITE)
135 #define WALIGN32(r) ALIGN(0x03,r,EXC_DATA_ADDR_WRITE)
136 #define WALIGN64(r) ALIGN(0x07,r,EXC_DATA_ADDR_WRITE)
138 #define UNTRANSLATABLE(pc) !IS_IN_ICACHE(pc)
140 #define EMU_DELAY_SLOT() do { \
141 XOP2I( OP_ADD, (pc+2 - xbb->pc_begin), R_PC ); \
142 XOP2I( OP_MOV, 1, R_DELAY_SLOT ); \
143 XOP0( OP_BARRIER ); \
144 XOPCALL0( sh4_execute_instruction ); \
145 XOP1( OP_BR, R_PC ); \
150 * Create a standard post-exception stub sub-block (ie sh4_raise_exception or similar has
151 * already been called - update SPC + slice_cycle and exit).
152 * @return the first xir_op_t of the exception block.
154 static inline xir_op_t write_postexc( xir_basic_block_t xbb, sh4addr_t pc )
156 xir_op_t start = xbb->ir_ptr;
157 if( pc != xbb->pc_begin ) {
158 XOP2I( OP_ADD, pc - xbb->pc_begin, R_SPC );
160 XOP2I( OP_ADD, (pc+2 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
161 XOP1( OP_BR, R_SPC )->next = NULL;
167 * Create a standard exception-taking stub sub-block - updates SPC, slice_cycle, and exits
168 * @return the first xir_op_t of the exception block.
170 static inline xir_op_t write_exc( xir_basic_block_t xbb, sh4addr_t pc, int exc_code )
172 xir_op_t start = xbb->ir_ptr;
173 XOPCALL1I( sh4_raise_exception, exc_code );
174 if( pc != xbb->pc_begin ) {
175 XOP2I( OP_ADD, pc - xbb->pc_begin, R_SPC );
177 XOP2I( OP_ADD, (pc+2 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
178 XOP1( OP_BR, R_SPC )->next = NULL;
183 static sh4addr_t sh4_decode_instruction( xir_basic_block_t xbb, sh4addr_t pc, gboolean in_delay_slot )
185 assert( IS_IN_ICACHE(pc) );
186 uint16_t ir = *(uint16_t *)GET_ICACHE_PTR(pc);
189 ADD Rm, Rn {: XOP2( OP_ADD, R_R(Rm), R_R(Rn) ); :}
190 ADD #imm, Rn {: XOP2I( OP_ADD, imm, R_R(Rn) ); :}
192 XOP1CC( OP_LD, CC_C, R_T );
193 XOP2( OP_ADDCS, R_R(Rm), R_R(Rn) );
194 XOP1CC( OP_ST, CC_C, R_T );
196 ADDV Rm, Rn {: XOP2( OP_ADDS, R_R(Rm), R_R(Rn) ); XOP1CC( OP_ST, CC_OV, R_T ); :}
197 AND Rm, Rn {: XOP2( OP_AND, R_R(Rm), R_R(Rn) ); :}
198 AND #imm, R0 {: XOP2I( OP_AND, imm, R_R0 ); :}
199 CMP/EQ Rm, Rn {: XOP2( OP_CMP, Rm, R_R(Rn) ); XOP1CC( OP_ST, CC_EQ, R_T ); :}
200 CMP/EQ #imm, R0 {: XOP2I( OP_CMP, imm, R_R0 ); XOP1CC( OP_ST, CC_EQ, R_T ); :}
201 CMP/GE Rm, Rn {: XOP2( OP_CMP, R_R(Rm), R_R(Rn) ); XOP1CC( OP_ST, CC_SGE, R_T ); :}
202 CMP/GT Rm, Rn {: XOP2( OP_CMP, R_R(Rm), R_R(Rn) ); XOP1CC( OP_ST, CC_SGT, R_T ); :}
203 CMP/HI Rm, Rn {: XOP2( OP_CMP, R_R(Rm), R_R(Rn) ); XOP1CC( OP_ST, CC_UGT, R_T ); :}
204 CMP/HS Rm, Rn {: XOP2( OP_CMP, R_R(Rm), R_R(Rn) ); XOP1CC( OP_ST, CC_UGE, R_T ); :}
205 CMP/PL Rn {: XOP2I( OP_CMP, 0, R_R(Rn) ); XOP1CC( OP_ST, CC_SGT, R_T ); :}
206 CMP/PZ Rn {: XOP2I( OP_CMP, 0, R_R(Rn) ); XOP1CC( OP_ST, CC_SGE, R_T ); :}
207 CMP/STR Rm, Rn {: XOP2( OP_CMPSTR, R_R(Rm), R_R(Rn) ); :}
209 XOP2( OP_MOV, R_R(Rm), R_M );
210 XOP2I( OP_SLR, 31, R_M );
211 XOP2( OP_MOV, R_R(Rn), R_Q );
212 XOP2I( OP_SLR, 31, R_Q );
213 XOP2( OP_CMP, R_M, R_Q );
214 XOP1CC( OP_ST, CC_NE, R_T );
217 XOP2I( OP_MOV, 0, R_M );
218 XOP2I( OP_MOV, 0, R_Q );
219 XOP2I( OP_MOV, 0, R_T );
221 DIV1 Rm, Rn {: XOP2( OP_DIV1, R_R(Rm), R_R(Rn) ); :}
223 XOP2( OP_MOVSX32, R_R(Rm), R_MAC );
224 XOP2( OP_MOVSX32, R_R(Rn), REG_TMP0 );
225 XOP2( OP_MULQ, REG_TMPQ0, R_MAC );
228 XOP2( OP_MOVZX32, R_R(Rm), R_MAC );
229 XOP2( OP_MOVZX32, R_R(Rn), REG_TMP0 ) ;
230 XOP2( OP_MULQ, REG_TMP0, R_MAC );
232 DT Rn {: XOP1( OP_DEC, R_R(Rn) ); :}
233 EXTS.B Rm, Rn {: XOP2( OP_MOVSX8, R_R(Rm), R_R(Rn)); :}
234 EXTS.W Rm, Rn {: XOP2( OP_MOVSX16, R_R(Rm), R_R(Rn)); :}
235 EXTU.B Rm, Rn {: XOP2( OP_MOVZX8, R_R(Rm), R_R(Rn)); :}
236 EXTU.W Rm, Rn {: XOP2( OP_MOVZX16, R_R(Rm), R_R(Rn)); :}
240 XOP2E( OP_LOADL, R_R(Rm), REG_TMP0 );
241 XOP2( OP_MOV, R_R(Rm), REG_TMP1 );
242 XOP2I( OP_ADD, 4, REG_TMP1 );
243 XOP2E( OP_LOADL, REG_TMP1, REG_TMP1 );
244 XOP2I( OP_ADD, 8, R_R(Rm) );
247 XOP2E( OP_LOADL, R_R(Rm), REG_TMP0 );
248 XOP2E( OP_LOADL, R_R(Rn), REG_TMP1 );
249 XOP2I( OP_ADD, 4, R_R(Rm) );
250 XOP2I( OP_ADD, 4, R_R(Rn) );
252 XOP2( OP_MOVSX32, REG_TMP0, REG_TMPQ0 );
253 XOP2( OP_MOVSX32, REG_TMP1, REG_TMPQ1 );
254 XOP2( OP_MULQ, REG_TMPQ0, REG_TMPQ1 );
255 XOP2( OP_ADDQSAT48, REG_TMPQ1, R_MAC );
260 XOP2E( OP_LOADW, R_R(Rm), REG_TMP0 );
261 XOP2( OP_MOV, R_R(Rm), REG_TMP1 );
262 XOP2I( OP_ADD, 2, REG_TMP1 );
263 XOP2E( OP_LOADW, REG_TMP1, REG_TMP1 );
264 XOP2I( OP_ADD, 4, R_R(Rm) );
267 XOP2E( OP_LOADW, R_R(Rm), REG_TMP0 );
268 XOP2E( OP_LOADW, R_R(Rn), REG_TMP1 );
269 XOP2I( OP_ADD, 2, R_R(Rm) );
270 XOP2I( OP_ADD, 2, R_R(Rn) );
272 XOP2( OP_MOVSX32, REG_TMP0, REG_TMPQ0 );
273 XOP2( OP_MOVSX32, REG_TMP1, REG_TMPQ1 );
274 XOP2( OP_MULQ, REG_TMPQ0, REG_TMPQ1 );
275 XOP2( OP_ADDQSAT32, REG_TMPQ1, R_MAC );
277 MOVT Rn {: XOP2( OP_MOV, R_R(Rn), R_T ); :}
279 XOP2( OP_MOV, R_R(Rm), R_MACL );
280 XOP2( OP_MUL, R_R(Rn), R_MACL );
283 XOP2( OP_MOVSX16, R_R(Rm), REG_TMP0 );
284 XOP2( OP_MOVSX16, R_R(Rn), R_MACL );
285 XOP2( OP_MUL, REG_TMP0, R_MACL );
288 XOP2( OP_MOVZX16, R_R(Rm), REG_TMP0 );
289 XOP2( OP_MOVZX16, R_R(Rn), R_MACL );
290 XOP2( OP_MUL, REG_TMP0, R_MACL );
293 XOP2( OP_NEG, R_R(Rm), R_R(Rn) );
296 XOP1CC( OP_LD, CC_C, R_T );
298 XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
299 XOP2I(OP_MOV, 0, R_R(Rn) );
300 XOP2( OP_SUBBS, REG_TMP0, R_R(Rn) );
302 XOP2I(OP_MOV, 0, R_R(Rn) );
303 XOP2( OP_SUBBS, R_R(Rm), R_R(Rn) );
305 XOP1CC( OP_ST, CC_C, R_T );
308 XOP2( OP_NOT, R_R(Rm), R_R(Rn) );
310 OR Rm, Rn {: XOP2( OP_OR, R_R(Rm), R_R(Rn) ); :}
311 OR #imm, R0 {: XOP2I( OP_OR, imm, R_R0 ); :}
312 ROTCL Rn {: XOP1CC( OP_LD, CC_C, R_T ); XOP2I( OP_RCL, 1, R_R(Rn) ); XOP1CC( OP_ST, CC_C, R_T); :}
313 ROTCR Rn {: XOP1CC( OP_LD, CC_C, R_T ); XOP2I( OP_RCR, 1, R_R(Rn) ); XOP1CC( OP_ST, CC_C, R_T); :}
314 ROTL Rn {: XOP2I( OP_ROL, 1, R_R(Rn) ); :}
315 ROTR Rn {: XOP2I( OP_ROR, 1, R_R(Rn) ); :}
316 SHAD Rm, Rn {: XOP2( OP_SHAD, R_R(Rm), R_R(Rn) ); :}
317 SHLD Rm, Rn {: XOP2( OP_SHLD, R_R(Rm), R_R(Rn) ); :}
318 SHAL Rn {: XOP2I( OP_SLLS, 1, R_R(Rn) ); XOP1CC( OP_ST, CC_C, R_T); :}
319 SHAR Rn {: XOP2I( OP_SARS, 1, R_R(Rn) ); XOP1CC( OP_ST, CC_C, R_T); :}
320 SHLL Rn {: XOP2I( OP_SLLS, 1, R_R(Rn) ); XOP1CC( OP_ST, CC_C, R_T); :}
321 SHLL2 Rn {: XOP2I( OP_SLL, 2, R_R(Rn) ); :}
322 SHLL8 Rn {: XOP2I( OP_SLL, 8, R_R(Rn) ); :}
323 SHLL16 Rn {: XOP2I( OP_SLL, 16, R_R(Rn) ); :}
324 SHLR Rn {: XOP2I( OP_SLRS, 1, R_R(Rn) ); XOP1CC( OP_ST, CC_C, R_T); :}
325 SHLR2 Rn {: XOP2I( OP_SLR, 2, R_R(Rn) ); :}
326 SHLR8 Rn {: XOP2I( OP_SLR, 8, R_R(Rn) ); :}
327 SHLR16 Rn {: XOP2I( OP_SLR, 16, R_R(Rn) ); :}
330 /* Break false dependence */
331 XOP2I( OP_MOV, 0, R_R(Rn) );
333 XOP2( OP_SUB, R_R(Rm), R_R(Rn) );
336 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 ); :}
337 SUBV Rm, Rn {: XOP2( OP_SUB, R_R(Rm), R_R(Rn) ); XOP1CC( OP_ST, CC_OV, R_T ); :}
340 XOP2( OP_MOV, R_R(Rm), R_R(Rn) );
342 XOP2I( OP_SHUFFLE, 0x1243, R_R(Rn) );
346 XOP2( OP_MOV, R_R(Rm), R_R(Rn) );
348 XOP2I( OP_SHUFFLE, 0x3412, R_R(Rn) );
350 TST Rm, Rn {: XOP2( OP_TST, R_R(Rm), R_R(Rn) ); XOP1CC( OP_ST, CC_EQ, R_T ); :}
351 TST #imm, R0 {: XOP2I( OP_TST, imm, R_R0 ); XOP1CC( OP_ST, CC_EQ, R_T ); :}
354 /* Break false dependence */
355 XOP2I( OP_MOV, 0, R_R(Rn) );
357 XOP2( OP_XOR, R_R(Rm), R_R(Rn) );
360 XOR #imm, R0 {: XOP2I( OP_XOR, imm, R_R0 ); :}
362 XOP2( OP_MOV, R_R(Rm), REG_TMP0 );
363 XOP2I( OP_SLL, 16, REG_TMP0 );
364 XOP2I( OP_SLR, 16, R_R(Rn) );
365 XOP2( OP_OR, REG_TMP0, R_R(Rn) );
367 MOV Rm, Rn {: XOP2( OP_MOV, R_R(Rm), R_R(Rn) ); :}
368 MOV #imm, Rn {: XOP2I( OP_MOV, imm, R_R(Rn) ); :}
370 AND.B #imm, @(R0, GBR) {:
371 XOP2( OP_MOV, R_R0, REG_TMP0 );
372 XOP2( OP_ADD, R_GBR, REG_TMP0 );
373 XOP2E( OP_LOADBFW, REG_TMP0, REG_TMP1 );
374 XOP2I( OP_AND, imm, REG_TMP1 );
375 XOP2E( OP_STOREB, REG_TMP0, REG_TMP1 );
377 OR.B #imm, @(R0, GBR) {:
378 XOP2( OP_MOV, R_R0, REG_TMP0 );
379 XOP2( OP_ADD, R_GBR, REG_TMP0 );
380 XOP2E( OP_LOADBFW, REG_TMP0, REG_TMP1 );
381 XOP2I( OP_OR, imm, REG_TMP1 );
382 XOP2E( OP_STOREB, REG_TMP0, REG_TMP1 );
385 XOP1( OP_OCBP, R_R(Rn) );
386 XOP2E( OP_LOADBFW, R_R(Rn), REG_TMP0 );
387 XOP2I( OP_CMP, 0, REG_TMP0 );
388 XOP1CC(OP_ST, CC_EQ, R_T );
389 XOP2I( OP_OR, 0x80, REG_TMP0 );
390 XOP2E( OP_STOREB, R_R(Rn), REG_TMP0 );
392 TST.B #imm, @(R0, GBR) {:
393 XOP2( OP_MOV, R_R0, REG_TMP0 );
394 XOP2( OP_ADD, R_GBR, REG_TMP0 );
395 XOP2E( OP_LOADB, REG_TMP0, REG_TMP0 );
396 XOP2I( OP_TST, imm, REG_TMP0 );
398 XOR.B #imm, @(R0, GBR) {:
399 XOP2( OP_MOV, R_R0, REG_TMP0 );
400 XOP2( OP_ADD, R_GBR, REG_TMP0 );
401 XOP2E( OP_LOADBFW, REG_TMP0, REG_TMP1 );
402 XOP2I( OP_XOR, imm, REG_TMP1 );
403 XOP2E( OP_STOREB, REG_TMP0, REG_TMP1 );
407 XOP2E( OP_STOREB, R_R(Rn), R_R(Rm) );
410 XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
411 XOP2I( OP_ADD, -1, REG_TMP0 );
412 XOP2E( OP_STOREB, REG_TMP0, R_R(Rm) );
413 XOP2I( OP_ADD, -1, R_R(Rn) );
415 MOV.B Rm, @(R0, Rn) {:
416 XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
417 XOP2( OP_ADD, R_R0, REG_TMP0 );
418 XOP2E( OP_STOREB, REG_TMP0, R_R(Rm) );
420 MOV.B R0, @(disp, GBR) {:
421 XOP2( OP_MOV, R_GBR, REG_TMP0 );
422 XOP2I( OP_ADD, disp, REG_TMP0 );
423 XOP2E( OP_STOREB, REG_TMP0, R_R0 );
425 MOV.B R0, @(disp, Rn) {:
426 XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
427 XOP2I( OP_ADD, disp, REG_TMP0 );
428 XOP2E( OP_STOREB, REG_TMP0, R_R0 );
431 XOP2E( OP_LOADB, R_R(Rm), R_R(Rn) );
434 XOP2E( OP_LOADB, R_R(Rm), R_R(Rn) );
436 XOP2I( OP_ADD, 1, R_R(Rm) );
439 MOV.B @(R0, Rm), Rn {:
440 XOP2( OP_MOV, R_R(Rm), REG_TMP0 );
441 XOP2( OP_ADD, R_R0, REG_TMP0 );
442 XOP2E(OP_LOADB, REG_TMP0, R_R(Rn) );
444 MOV.B @(disp, GBR), R0 {:
445 XOP2( OP_MOV, R_GBR, REG_TMP0 );
446 XOP2I(OP_ADD, disp, REG_TMP0 );
447 XOP2E(OP_LOADB, REG_TMP0, R_R0 );
449 MOV.B @(disp, Rm), R0 {:
450 XOP2( OP_MOV, R_R(Rm), REG_TMP0 );
451 XOP2I(OP_ADD, disp, REG_TMP0 );
452 XOP2E(OP_LOADB, REG_TMP0, R_R0 );
456 XOP2E( OP_STOREL, R_R(Rn), R_R(Rm) );
460 XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
461 XOP2I(OP_ADD, -4, REG_TMP0 );
462 XOP2( OP_STOREL, REG_TMP0, R_R(Rm) );
463 XOP2I(OP_ADD, -4, R_R(Rn) );
465 MOV.L Rm, @(R0, Rn) {:
466 XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
467 XOP2( OP_ADD, R_R0, REG_TMP0 );
468 WALIGN32( REG_TMP0 );
469 XOP2E(OP_STOREL, REG_TMP0, R_R(Rm) );
471 MOV.L R0, @(disp, GBR) {:
472 XOP2( OP_MOV, R_GBR, REG_TMP0 );
473 XOP2I(OP_ADD, disp, REG_TMP0 );
474 WALIGN32( REG_TMP0 );
475 XOP2E(OP_STOREL, REG_TMP0, R_R0 );
477 MOV.L Rm, @(disp, Rn) {:
478 XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
479 XOP2I(OP_ADD, disp, REG_TMP0 );
480 WALIGN32( REG_TMP0 );
481 XOP2E(OP_STOREL, REG_TMP0, R_R(Rm) );
485 XOP2E(OP_LOADL, R_R(Rm), R_R(Rn) );
489 XOP2E( OP_LOADL, R_R(Rm), R_R(Rn) );
490 if( R_R(Rm) != R_R(Rn) ) {
491 XOP2I( OP_ADD, 4, R_R(Rm) );
494 MOV.L @(R0, Rm), Rn {:
495 XOP2( OP_MOV, R_R0, REG_TMP0 );
496 XOP2( OP_ADD, R_R(Rm), REG_TMP0 );
497 RALIGN32( REG_TMP0 );
498 XOP2E(OP_LOADL, REG_TMP0, R_R(Rn) );
500 MOV.L @(disp, GBR), R0 {:
501 XOP2( OP_MOV, R_GBR, REG_TMP0 );
502 XOP2I(OP_ADD, disp, REG_TMP0 );
503 RALIGN32( REG_TMP0 );
504 XOP2E(OP_LOADL, REG_TMP0, R_R0 );
506 MOV.L @(disp, PC), Rn {:
507 if( in_delay_slot ) {
511 uint32_t target = (pc & 0xFFFFFFFC) + disp + 4;
512 if( IS_IN_ICACHE(target) ) {
513 // If the target address is in the same page as the code, it's
514 // pretty safe to just ref it directly and circumvent the whole
515 // memory subsystem. (this is a big performance win)
517 // FIXME: There's a corner-case that's not handled here when
518 // the current code-page is in the ITLB but not in the UTLB.
519 // (should generate a TLB miss although need to test SH4
520 // behaviour to confirm) Unlikely to be anyone depending on this
522 sh4ptr_t ptr = GET_ICACHE_PTR(target);
523 XOP2P( OP_MOV, ptr, R_R(Rn) );
525 // Note: we use sh4r.pc for the calc as we could be running at a
526 // different virtual address than the translation was done with,
527 // but we can safely assume that the low bits are the same.
528 XOP2( OP_MOV, R_PC, REG_TMP0 );
529 XOP2( OP_ADD, (pc-xbb->pc_begin) + disp + 4 - (pc&0x03), REG_TMP0 );
530 XOP2E(OP_LOADL, REG_TMP0, R_R(Rn) );
534 MOV.L @(disp, Rm), Rn {:
535 XOP2( OP_MOV, R_R(Rm), REG_TMP0 );
536 XOP2I(OP_ADD, disp, REG_TMP0 );
537 RALIGN32( REG_TMP0 );
538 XOP2E(OP_LOADL, REG_TMP0, R_R(Rn) );
542 XOP2E(OP_STOREW, R_R(Rn), R_R(Rm) );
546 XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
547 XOP2I(OP_ADD, -2, REG_TMP0 );
548 XOP2E(OP_STOREW, REG_TMP0, R_R(Rm) );
549 XOP2I(OP_ADD, -2, R_R(Rn) );
551 MOV.W Rm, @(R0, Rn) {:
552 XOP2( OP_MOV, R_R0, REG_TMP0 );
553 XOP2( OP_ADD, R_R(Rn), REG_TMP0 );
554 WALIGN16( REG_TMP0 );
555 XOP2E(OP_STOREW, REG_TMP0, R_R(Rm) );
557 MOV.W R0, @(disp, GBR) {:
558 XOP2( OP_MOV, R_GBR, REG_TMP0 );
559 XOP2I(OP_ADD, disp, REG_TMP0 );
560 WALIGN16( REG_TMP0 );
561 XOP2( OP_STOREW, REG_TMP0, R_R0 );
563 MOV.W R0, @(disp, Rn) {:
564 XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
565 XOP2I(OP_ADD, disp, REG_TMP0 );
566 WALIGN16( REG_TMP0 );
567 XOP2E(OP_STOREW, REG_TMP0, R_R0 );
571 XOP2E(OP_LOADW, R_R(Rm), R_R(Rn) );
575 XOP2E(OP_LOADW, R_R(Rm), R_R(Rn) );
577 XOP2I( OP_ADD, 2, R_R(Rm) );
580 MOV.W @(R0, Rm), Rn {:
581 XOP2( OP_MOV, R_R0, REG_TMP0 );
582 XOP2( OP_ADD, R_R(Rm), REG_TMP0 );
583 RALIGN16( REG_TMP0 );
584 XOP2E(OP_LOADW, REG_TMP0, R_R(Rn) );
586 MOV.W @(disp, GBR), R0 {:
587 XOP2( OP_MOV, R_GBR, REG_TMP0 );
588 XOP2I(OP_ADD, disp, REG_TMP0 );
589 RALIGN16( REG_TMP0 );
590 XOP2E(OP_LOADW, REG_TMP0, R_R0 );
592 MOV.W @(disp, PC), Rn {:
593 if( in_delay_slot ) {
597 uint32_t target = pc + disp + 4;
598 if( IS_IN_ICACHE(target) ) {
599 // If the target address is in the same page as the code, it's
600 // pretty safe to just ref it directly and circumvent the whole
601 // memory subsystem. (this is a big performance win)
603 // FIXME: There's a corner-case that's not handled here when
604 // the current code-page is in the ITLB but not in the UTLB.
605 // (should generate a TLB miss although need to test SH4
606 // behaviour to confirm) Unlikely to be anyone depending on this
608 sh4ptr_t ptr = GET_ICACHE_PTR(target);
609 XOP2P( OP_MOV, ptr, REG_TMP0 );
610 XOP2( OP_MOVSX16, REG_TMP0, R_R(Rn) );
612 // Note: we use sh4r.pc for the calc as we could be running at a
613 // different virtual address than the translation was done with,
614 // but we can safely assume that the low bits are the same.
615 XOP2( OP_MOV, R_PC, REG_TMP0 );
616 XOP2( OP_ADD, (pc - xbb->pc_begin) + disp + 4, REG_TMP0 );
617 XOP2E(OP_LOADW, REG_TMP0, R_R(Rn) );
621 MOV.W @(disp, Rm), R0 {:
622 XOP2( OP_MOV, R_R(Rm), REG_TMP0 );
623 XOP2I(OP_ADD, disp, REG_TMP0 );
624 RALIGN16( REG_TMP0 );
625 XOP2E(OP_LOADW, REG_TMP0, R_R0 );
627 MOVA @(disp, PC), R0 {:
628 if( in_delay_slot ) {
632 XOP2( OP_MOV, R_PC, R_R0 );
633 XOP2I( OP_ADD, (pc - xbb->pc_begin) + disp + 4 - (pc&0x03), R_R0 );
637 XOP2E(OP_STORELCA, R_R(Rn), R_R0 );
641 XOPCALL0( MMU_ldtlb );
643 OCBI @Rn {: XOP1E( OP_OCBI, R_R(Rn) ); :}
644 OCBP @Rn {: XOP1E( OP_OCBP, R_R(Rn) ); :}
645 OCBWB @Rn {: XOP1E( OP_OCBWB, R_R(Rn) ); :}
646 PREF @Rn {: XOP1E( OP_PREF, R_R(Rn) ); :}
649 XOP2I( OP_MOV, 0, R_MACL );
650 XOP2I( OP_MOV, 0, R_MACH );
652 CLRS {: XOP2I( OP_MOV, 0, R_S ); :}
653 CLRT {: XOP2I( OP_MOV, 0, R_T ); :}
654 SETS {: XOP2I( OP_MOV, 1, R_S ); :}
655 SETT {: XOP2I( OP_MOV, 1, R_T ); :}
658 if( sh4_xir.double_size ) {
659 XOP2( OP_MOVQ, (FRm&1) ? R_XD(FRm) : R_DR(FRm), (FRn&1) ? R_XD(FRn) : R_DR(FRn) );
661 XOP2( OP_MOV, R_FR(FRm), R_FR(FRn) );
666 if( sh4_xir.double_size ) {
668 XOP2E( OP_STOREQ, R_R(Rn), (FRm&1) ? R_XD(FRm) : R_DR(FRm) );
671 XOP2E( OP_STOREL, R_R(Rn), R_FR(FRm) );
676 if( sh4_xir.double_size ) {
678 XOP2E( OP_LOADQ, R_R(Rm), (FRn&1) ? R_XD(FRn) : R_DR(FRn) );
681 XOP2E( OP_LOADL, R_R(Rm), R_FR(FRn) );
686 if( sh4_xir.double_size ) {
688 XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
689 XOP2I(OP_ADD, -8, REG_TMP0 );
690 XOP2E(OP_STOREQ, REG_TMP0, (FRm&1) ? R_XD(FRm) : R_DR(FRm) );
691 XOP2I(OP_ADD, -8, R_R(Rn) );
694 XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
695 XOP2I(OP_ADD, -4, REG_TMP0 );
696 XOP2E(OP_STOREL, REG_TMP0, R_FR(FRm) );
697 XOP2I(OP_ADD, -4, R_R(Rn) );
702 if( sh4_xir.double_size ) {
704 XOP2( OP_LOADQ, R_R(Rm), (FRn&1) ? R_XD(FRn) : R_DR(FRn) );
705 XOP2I( OP_ADD, 8, R_R(Rm) );
708 XOP2( OP_LOADL, R_R(Rm), R_FR(FRn) );
709 XOP2I( OP_ADD, 4, R_R(Rm) );
712 FMOV FRm, @(R0, Rn) {:
714 XOP2( OP_MOV, R_R0, REG_TMP0 );
715 XOP2( OP_ADD, R_R(Rn), REG_TMP0 );
716 if( sh4_xir.double_size ) {
717 WALIGN64( REG_TMP0 );
718 XOP2E( OP_STOREQ, REG_TMP0, (FRm&1) ? R_XD(FRm) : R_DR(FRm) );
720 WALIGN32( REG_TMP0 );
721 XOP2E( OP_STOREL, REG_TMP0, R_FR(FRm) );
724 FMOV @(R0, Rm), FRn {:
726 XOP2( OP_MOV, R_R0, REG_TMP0 );
727 XOP2( OP_ADD, R_R(Rm), REG_TMP0 );
728 if( sh4_xir.double_size ) {
729 RALIGN64( REG_TMP0 );
730 XOP2E( OP_LOADQ, REG_TMP0, (FRn&1) ? R_XD(FRn) : R_DR(FRn) );
732 RALIGN32( REG_TMP0 );
733 XOP2E( OP_LOADL, REG_TMP0, R_FR(FRn) );
736 FLDI0 FRn {: /* IFF PR=0 */
738 if( sh4_xir.double_prec == 0 ) {
739 XOP2F( OP_MOV, 0.0, R_FR(FRn) );
742 FLDI1 FRn {: /* IFF PR=0 */
744 if( sh4_xir.double_prec == 0 ) {
745 XOP2F( OP_MOV, 1.0, R_FR(FRn) );
750 if( sh4_xir.double_prec ) {
751 XOP2( OP_ITOD, R_FPUL, R_DR(FRn) );
753 XOP2( OP_ITOF, R_FPUL, R_FR(FRn) );
758 if( sh4_xir.double_prec ) {
759 XOP2( OP_DTOI, R_DR(FRm), R_FPUL );
761 XOP2( OP_FTOI, R_FR(FRm), R_FPUL );
766 XOP2( OP_MOV, R_FR(FRm), R_FPUL );
770 XOP2( OP_MOV, R_FPUL, R_FR(FRn) );
774 if( sh4_xir.double_prec && !sh4_xir.double_size ) {
775 XOP2( OP_DTOF, R_DR(FRm), R_FPUL );
780 if( sh4_xir.double_prec && !sh4_xir.double_size ) {
781 XOP2( OP_FTOD, R_FPUL, R_DR(FRn) );
786 if( sh4_xir.double_prec ) {
787 XOP1( OP_ABSD, R_DR(FRn) );
789 XOP1( OP_ABSF, R_FR(FRn) );
794 if( sh4_xir.double_prec ) {
795 XOP2( OP_ADDD, R_DR(FRm), R_DR(FRn) );
797 XOP2( OP_ADDF, R_FR(FRm), R_FR(FRn) );
802 if( sh4_xir.double_prec ) {
803 XOP2( OP_DIVD, R_DR(FRm), R_DR(FRn) );
805 XOP2( OP_DIVF, R_FR(FRm), R_FR(FRn) );
808 FMAC FR0, FRm, FRn {:
810 if( sh4_xir.double_prec == 0 ) {
811 XOP2( OP_MOV, R_FR(0), REG_TMP0 );
812 XOP2( OP_MULF, R_FR(FRm), REG_TMP0 );
813 XOP2( OP_ADDF, REG_TMP0, R_FR(FRn) );
818 if( sh4_xir.double_prec ) {
819 XOP2( OP_MULD, R_DR(FRm), R_DR(FRn) );
821 XOP2( OP_MULF, R_FR(FRm), R_FR(FRn) );
826 if( sh4_xir.double_prec ) {
827 XOP1( OP_NEGD, R_DR(FRn) );
829 XOP1( OP_NEGF, R_FR(FRn) );
834 if( sh4_xir.double_prec == 0 ) {
835 XOP1( OP_RSQRTF, R_FR(FRn) );
840 if( sh4_xir.double_prec ) {
841 XOP1( OP_SQRTD, R_DR(FRn) );
843 XOP1( OP_SQRTF, R_FR(FRn) );
848 if( sh4_xir.double_prec ) {
849 XOP2( OP_SUBD, R_DR(FRm), R_DR(FRn) );
851 XOP2( OP_SUBF, R_FR(FRm), R_FR(FRn) );
856 if( sh4_xir.double_prec ) {
857 XOP2( OP_CMPD, R_DR(FRm), R_DR(FRn) );
859 XOP2( OP_CMPF, R_FR(FRm), R_FR(FRn) );
861 XOP1CC( OP_ST, CC_EQ, R_T );
865 if( sh4_xir.double_prec ) {
866 XOP2( OP_CMPD, R_DR(FRm), R_DR(FRn) );
868 XOP2( OP_CMPF, R_FR(FRm), R_FR(FRn) );
870 XOP1CC( OP_ST, CC_SGT, R_T );
874 if( sh4_xir.double_prec == 0 ) {
875 XOP2( OP_SINCOSF, R_FPUL, R_DR(FRn) );
880 if( sh4_xir.double_prec == 0 ) {
881 XOP2( OP_DOTPRODV, R_FV(FVm), R_FV(FVn) );
886 if( sh4_xir.double_prec == 0 ) {
887 XOP2( OP_MATMULV, R_XMTRX, R_FV(FVn) );
892 XOP2I( OP_XOR, FPSCR_FR, R_FPSCR );
893 XOPCALL0( sh4_switch_fr_banks );
897 XOP2I( OP_XOR, FPSCR_SZ, R_FPSCR );
898 XOP2I( OP_XOR, FPSCR_SZ, R_SH4_MODE );
899 sh4_xir.double_size = !sh4_xir.double_size;
902 if( in_delay_slot ) {
906 XOPCALL1( sh4_write_sr, R_R(Rm) );
910 LDC Rm, GBR {: XOP2( OP_MOV, R_R(Rm), R_GBR ); :}
911 LDC Rm, VBR {: CHECKPRIV(); XOP2( OP_MOV, R_R(Rm), R_VBR ); :}
912 LDC Rm, SSR {: CHECKPRIV(); XOP2( OP_MOV, R_R(Rm), R_SSR ); :}
913 LDC Rm, SGR {: CHECKPRIV(); XOP2( OP_MOV, R_R(Rm), R_SGR ); :}
914 LDC Rm, SPC {: CHECKPRIV(); XOP2( OP_MOV, R_R(Rm), R_SPC ); :}
915 LDC Rm, DBR {: CHECKPRIV(); XOP2( OP_MOV, R_R(Rm), R_DBR ); :}
916 LDC Rm, Rn_BANK {: CHECKPRIV(); XOP2( OP_MOV, R_R(Rm), R_BANK(Rn_BANK) ); :}
918 XOP2E( OP_LOADL, R_R(Rm), R_GBR );
919 XOP2I( OP_ADD, 4, R_R(Rm) );
922 if( in_delay_slot ) {
927 XOP2E( OP_LOADL, R_R(Rm), REG_TMP0 );
928 XOP2I( OP_ADD, 4, R_R(Rm) );
929 XOPCALL1( sh4_write_sr, REG_TMP0 );
936 XOP2E( OP_LOADL, R_R(Rm), R_VBR );
937 XOP2I( OP_ADD, 4, R_R(Rm) );
942 XOP2E( OP_LOADL, R_R(Rm), R_SSR );
943 XOP2I( OP_ADD, 4, R_R(Rm) );
948 XOP2E( OP_LOADL, R_R(Rm), R_SGR );
949 XOP2I( OP_ADD, 4, R_R(Rm) );
954 XOP2E( OP_LOADL, R_R(Rm), R_SPC );
955 XOP2I( OP_ADD, 4, R_R(Rm) );
960 XOP2E( OP_LOADL, R_R(Rm), R_DBR );
961 XOP2I( OP_ADD, 4, R_R(Rm) );
963 LDC.L @Rm+, Rn_BANK {:
966 XOP2E( OP_LOADL, R_R(Rm), R_BANK(Rn_BANK) );
967 XOP2I( OP_ADD, 4, R_R(Rm) );
971 XOPCALL1( sh4_write_fpscr, R_R(Rm) );
976 XOP2( OP_MOV, R_R(Rm), R_FPUL );
978 LDS Rm, MACH {: XOP2( OP_MOV, R_R(Rm), R_MACH ); :}
979 LDS Rm, MACL {: XOP2( OP_MOV, R_R(Rm), R_MACL ); :}
980 LDS Rm, PR {: XOP2( OP_MOV, R_R(Rm), R_PR ); :}
984 XOP2E( OP_LOADL, R_R(Rm), REG_TMP0 );
985 XOP2I( OP_ADD, 4, R_R(Rm) );
986 XOPCALL1( sh4_write_fpscr, REG_TMP0 );
992 XOP2E( OP_LOADL, R_R(Rm), R_FPUL );
993 XOP2I( OP_ADD, 4, R_R(Rm) );
997 XOP2E( OP_LOADL, R_R(Rm), R_MACH );
998 XOP2I( OP_ADD, 4, R_R(Rm) );
1001 RALIGN32( R_R(Rm) );
1002 XOP2E( OP_LOADL, R_R(Rm), R_MACL );
1003 XOP2I( OP_ADD, 4, R_R(Rm) );
1006 RALIGN32( R_R(Rm) );
1007 XOP2E( OP_LOADL, R_R(Rm), R_PR );
1008 XOP2I( OP_ADD, 4, R_R(Rm) );
1012 XOPCALLR( sh4_read_sr, R_R(Rn) );
1014 STC GBR, Rn {: XOP2( OP_MOV, R_GBR, R_R(Rn) ); :}
1015 STC VBR, Rn {: CHECKPRIV(); XOP2( OP_MOV, R_VBR, R_R(Rn) ); :}
1016 STC SSR, Rn {: CHECKPRIV(); XOP2( OP_MOV, R_SSR, R_R(Rn) ); :}
1017 STC SPC, Rn {: CHECKPRIV(); XOP2( OP_MOV, R_SPC, R_R(Rn) ); :}
1018 STC SGR, Rn {: CHECKPRIV(); XOP2( OP_MOV, R_SGR, R_R(Rn) ); :}
1019 STC DBR, Rn {: CHECKPRIV(); XOP2( OP_MOV, R_DBR, R_R(Rn) ); :}
1020 STC Rm_BANK, Rn {: CHECKPRIV(); XOP2( OP_MOV, R_BANK(Rm_BANK), R_R(Rn) ); :}
1023 XOPCALLR( sh4_read_sr, REG_TMP1 );
1024 WALIGN32( R_R(Rn) );
1025 XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1026 XOP2I(OP_ADD, -4, REG_TMP0 );
1027 XOP2E(OP_STOREL, REG_TMP0, REG_TMP1 );
1028 XOP2I(OP_ADD, -4, R_R(Rn) );
1032 WALIGN32( R_R(Rn) );
1033 XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1034 XOP2I(OP_ADD, -4, REG_TMP0 );
1035 XOP2E(OP_STOREL, REG_TMP0, R_VBR );
1036 XOP2I(OP_ADD, -4, R_R(Rn) );
1040 WALIGN32( R_R(Rn) );
1041 XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1042 XOP2I(OP_ADD, -4, REG_TMP0 );
1043 XOP2E(OP_STOREL, REG_TMP0, R_SSR );
1044 XOP2I(OP_ADD, -4, R_R(Rn) );
1048 WALIGN32( R_R(Rn) );
1049 XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1050 XOP2I(OP_ADD, -4, REG_TMP0 );
1051 XOP2E(OP_STOREL, REG_TMP0, R_SPC );
1052 XOP2I(OP_ADD, -4, R_R(Rn) );
1056 WALIGN32( R_R(Rn) );
1057 XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1058 XOP2I(OP_ADD, -4, REG_TMP0 );
1059 XOP2E(OP_STOREL, REG_TMP0, R_SGR );
1060 XOP2I(OP_ADD, -4, R_R(Rn) );
1064 WALIGN32( R_R(Rn) );
1065 XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1066 XOP2I(OP_ADD, -4, REG_TMP0 );
1067 XOP2E(OP_STOREL, REG_TMP0, R_DBR );
1068 XOP2I(OP_ADD, -4, R_R(Rn) );
1070 STC.L Rm_BANK, @-Rn {:
1072 WALIGN32( R_R(Rn) );
1073 XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1074 XOP2I(OP_ADD, -4, REG_TMP0 );
1075 XOP2E(OP_STOREL, REG_TMP0, R_BANK(Rm_BANK) );
1076 XOP2I(OP_ADD, -4, R_R(Rn) );
1079 WALIGN32( R_R(Rn) );
1080 XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1081 XOP2I(OP_ADD, -4, REG_TMP0 );
1082 XOP2E(OP_STOREL, REG_TMP0, R_GBR );
1083 XOP2I(OP_ADD, -4, R_R(Rn) );
1087 XOP2( OP_MOV, R_FPSCR, R_R(Rn) );
1091 XOP2( OP_MOV, R_FPUL, R_R(Rn) );
1094 XOP2( OP_MOV, R_MACH, R_R(Rn) );
1097 XOP2( OP_MOV, R_MACL, R_R(Rn) );
1100 XOP2( OP_MOV, R_PR, R_R(Rn) );
1102 STS.L FPSCR, @-Rn {:
1104 WALIGN32( R_R(Rn) );
1105 XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1106 XOP2I(OP_ADD, -4, REG_TMP0 );
1107 XOP2E(OP_STOREL, REG_TMP0, R_FPSCR );
1108 XOP2I(OP_ADD, -4, R_R(Rn) );
1112 WALIGN32( R_R(Rn) );
1113 XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1114 XOP2I(OP_ADD, -4, REG_TMP0 );
1115 XOP2E(OP_STOREL, REG_TMP0, R_FPUL );
1116 XOP2I(OP_ADD, -4, R_R(Rn) );
1119 WALIGN32( R_R(Rn) );
1120 XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1121 XOP2I(OP_ADD, -4, REG_TMP0 );
1122 XOP2E(OP_STOREL, REG_TMP0, R_MACH );
1123 XOP2I(OP_ADD, -4, R_R(Rn) );
1126 WALIGN32( R_R(Rn) );
1127 XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1128 XOP2I(OP_ADD, -4, REG_TMP0 );
1129 XOP2E(OP_STOREL, REG_TMP0, R_MACL );
1130 XOP2I(OP_ADD, -4, R_R(Rn) );
1133 WALIGN32( R_R(Rn) );
1134 XOP2( OP_MOV, R_R(Rn), REG_TMP0 );
1135 XOP2I(OP_ADD, -4, REG_TMP0 );
1136 XOP2E(OP_STOREL, REG_TMP0, R_PR );
1137 XOP2I(OP_ADD, -4, R_R(Rn) );
1141 if( in_delay_slot ) {
1144 XOP2I( OP_ADD, (pc+2 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
1145 XOP2I( OP_CMP, 0, R_T );
1146 XOP2IICC( OP_BRCOND, CC_EQ, disp+pc+4-xbb->pc_begin, pc+2-xbb->pc_begin );
1151 if( in_delay_slot ) {
1155 if( UNTRANSLATABLE(pc+2 ) ) {
1156 XOP2I( OP_CMP, 0, R_T );
1157 XOP2IICC( OP_BRCONDDEL, CC_EQ, disp+pc+4-xbb->pc_begin, pc+4-xbb->pc_begin );
1161 XOP2( OP_MOV, R_T, REG_TMP2 );
1162 sh4_decode_instruction( xbb, pc+2, TRUE );
1163 if( !XOP_IS_TERMINATOR( xbb->ir_ptr->prev ) ) {
1164 XOP2I( OP_ADD, (pc+4 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
1165 XOP2I( OP_CMP, 0, REG_TMP2 );
1166 XOP2IICC( OP_BRCOND, CC_EQ, disp+pc+4-xbb->pc_begin, pc+4-xbb->pc_begin );
1173 if( in_delay_slot ) {
1176 XOP2I( OP_ADD, (pc+2 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
1177 XOP2I( OP_CMP, 1, R_T );
1178 XOP2IICC( OP_BRCOND, CC_EQ, disp+pc+4-xbb->pc_begin, pc+2-xbb->pc_begin );
1183 if( in_delay_slot ) {
1187 if( UNTRANSLATABLE(pc+2 ) ) {
1188 XOP2I( OP_CMP, 1, R_T );
1189 XOP2IICC( OP_BRCONDDEL, CC_EQ, disp+pc+4-xbb->pc_begin, pc+2-xbb->pc_begin );
1193 XOP2( OP_MOV, R_T, REG_TMP2 );
1194 sh4_decode_instruction( xbb, pc+2, TRUE );
1195 if( !XOP_IS_TERMINATOR( xbb->ir_ptr->prev ) ) {
1196 XOP2I( OP_ADD, (pc+4 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
1197 XOP2I( OP_CMP, 1, REG_TMP2 );
1198 XOP2IICC( OP_BRCOND, CC_EQ, disp+pc+4-xbb->pc_begin, pc+4-xbb->pc_begin );
1205 if( in_delay_slot ) {
1209 if( UNTRANSLATABLE(pc+2) ) {
1210 XOP2( OP_MOV, R_PC, R_NEW_PC );
1211 XOP2I( OP_ADD, pc+disp+4-xbb->pc_begin, R_NEW_PC );
1215 sh4_decode_instruction( xbb, pc+2, TRUE );
1216 if( xbb->ir_ptr->prev == NULL || !XOP_IS_TERMINATOR( xbb->ir_ptr->prev ) ) {
1217 XOP2I( OP_ADD, (pc+4 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
1218 XOP1I( OP_BRREL, pc+disp+4-xbb->pc_begin );
1225 if( in_delay_slot ) {
1229 XOP2( OP_MOV, R_R(Rn), REG_TMP2 );
1230 XOP2( OP_ADD, R_PC, REG_TMP2 );
1231 XOP2I( OP_ADD, pc - xbb->pc_begin + 4, REG_TMP2 );
1232 if( UNTRANSLATABLE(pc+2) ) {
1233 XOP2( OP_MOV, REG_TMP2, R_NEW_PC );
1237 sh4_decode_instruction( xbb, pc + 2, TRUE );
1238 if( !XOP_IS_TERMINATOR( xbb->ir_ptr->prev ) ) {
1239 XOP2I( OP_ADD, (pc+4 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
1240 XOP1( OP_BR, REG_TMP2 );
1247 if( in_delay_slot ) {
1251 XOP2( OP_MOV, R_PC, R_PR );
1252 XOP2I( OP_ADD, pc - xbb->pc_begin + 4, R_PR );
1253 if( UNTRANSLATABLE(pc+2) ) {
1254 XOP2( OP_MOV, R_PC, R_NEW_PC );
1255 XOP2I( OP_ADD, pc+disp+4-xbb->pc_begin, R_NEW_PC );
1259 sh4_decode_instruction( xbb, pc+2, TRUE );
1260 if( !XOP_IS_TERMINATOR( xbb->ir_ptr->prev ) ) {
1261 XOP2I( OP_ADD, (pc+4 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
1262 XOP1I( OP_BRREL, pc+disp+4-xbb->pc_begin );
1269 if( in_delay_slot ) {
1273 XOP2( OP_MOV, R_PC, R_PR );
1274 XOP2I( OP_ADD, pc - xbb->pc_begin + 4, R_PR );
1275 XOP2( OP_MOV, R_R(Rn), REG_TMP2 );
1276 XOP2( OP_ADD, R_PC, REG_TMP2 );
1277 XOP2I( OP_ADD, pc - xbb->pc_begin + 4, REG_TMP2 );
1278 if( UNTRANSLATABLE(pc+2) ) {
1279 XOP2( OP_MOV, REG_TMP2, R_NEW_PC );
1283 sh4_decode_instruction( xbb, pc+2, TRUE );
1284 if( !XOP_IS_TERMINATOR( xbb->ir_ptr->prev ) ) {
1285 XOP2I( OP_ADD, (pc+4 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
1286 XOP1( OP_BR, REG_TMP2 );
1293 if( in_delay_slot ) {
1297 if( UNTRANSLATABLE(pc+2) ) {
1298 XOP2( OP_MOV, R_R(Rn), R_NEW_PC );
1302 XOP2( OP_MOV, R_R(Rn), REG_TMP2 );
1303 sh4_decode_instruction( xbb, pc+2, TRUE );
1304 if( !XOP_IS_TERMINATOR( xbb->ir_ptr->prev ) ) {
1305 XOP2I( OP_ADD, (pc+4 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
1306 XOP1( OP_BR, REG_TMP2 );
1313 if( in_delay_slot ) {
1317 XOP2( OP_MOV, R_PC, R_PR );
1318 XOP2I( OP_ADD, pc - xbb->pc_begin + 4, R_PR );
1319 if( UNTRANSLATABLE(pc+2) ) {
1320 XOP2( OP_MOV, R_R(Rn), R_NEW_PC );
1324 XOP2( OP_MOV, R_R(Rn), REG_TMP2 );
1325 sh4_decode_instruction( xbb, pc+2, TRUE );
1326 if( !XOP_IS_TERMINATOR( xbb->ir_ptr->prev ) ) {
1327 XOP2I( OP_ADD, (pc+4 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
1328 XOP1( OP_BR, REG_TMP2 );
1336 if( in_delay_slot ) {
1340 if( UNTRANSLATABLE(pc+2) ) {
1341 XOP2( OP_MOV, R_SPC, R_NEW_PC );
1345 XOP2( OP_MOV, R_SPC, REG_TMP2 );
1346 XOPCALL1( sh4_write_sr, R_SSR );
1347 sh4_decode_instruction( xbb, pc+2, TRUE );
1348 if( !XOP_IS_TERMINATOR( xbb->ir_ptr->prev ) ) {
1349 XOP2I( OP_ADD, (pc+4 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
1350 XOP1( OP_BR, REG_TMP2 );
1357 if( in_delay_slot ) {
1361 if( UNTRANSLATABLE(pc+2) ) {
1362 XOP2( OP_MOV, R_PR, R_NEW_PC );
1366 XOP2( OP_MOV, R_PR, REG_TMP2 );
1367 sh4_decode_instruction( xbb, pc+2, TRUE );
1368 if( !XOP_IS_TERMINATOR( xbb->ir_ptr->prev ) ) {
1369 XOP2I( OP_ADD, (pc+4 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
1370 XOP1( OP_BR, REG_TMP2 );
1376 TRAPA #imm {: XOPCALL1I( sh4_raise_trap, imm ); return pc+2; :}
1377 SLEEP {: XOPCALL0( sh4_sleep ); return pc+2; :}
1378 UNDEF {: UNDEF(ir); :}
1379 NOP {: /* Do nothing */ :}
1386 sh4addr_t sh4_decode_basic_block( xir_basic_block_t xbb )
1390 sh4_xir.fpuen_checked = FALSE;
1391 sh4_xir.double_prec = sh4r.fpscr & FPSCR_PR;
1392 sh4_xir.double_size = sh4r.fpscr & FPSCR_SZ;
1393 xbb->address_space = (sh4r.xlat_sh4_mode&SR_MD) ? sh4_address_space : sh4_user_address_space;
1395 xbb->ir_alloc_begin->prev = NULL;
1396 XOP1I( OP_ENTER, 0 );
1397 for( pc = xbb->pc_begin; pc < xbb->pc_end; pc += 2 ) {
1398 int done = sh4_decode_instruction( xbb, pc, FALSE );
1404 xbb->ir_end = xbb->ir_ptr-1;
1405 xbb->ir_end->next = NULL;
.