filename | src/sh4/sh4x86.in |
changeset | 359:c588dce7ebde |
next | 361:be3de4ecd954 |
author | nkeynes |
date | Thu Aug 23 12:33:27 2007 +0000 (13 years ago) |
permissions | -rw-r--r-- |
last change | Commit decoder generator Translator work in progress Fix mac.l, mac.w in emu core |
view | annotate | diff | log | raw |
1 /**
2 * $Id: sh4x86.in,v 1.1 2007-08-23 12:33:27 nkeynes Exp $
3 *
4 * SH4 => x86 translation. This version does no real optimization, it just
5 * outputs straight-line x86 code - it mainly exists to provide a baseline
6 * to test the optimizing versions against.
7 *
8 * Copyright (c) 2007 Nathan Keynes.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 */
21 #include "sh4core.h"
22 #include "sh4trans.h"
23 #include "x86op.h"
25 /**
26 * Emit an instruction to load an SH4 reg into a real register
27 */
28 static inline void load_reg( int x86reg, int sh4reg )
29 {
30 /* mov [bp+n], reg */
31 OP(0x89);
32 OP(0x45 + x86reg<<3);
33 OP(REG_OFFSET(r[sh4reg]));
34 }
36 static inline void load_spreg( int x86reg, int regoffset )
37 {
38 /* mov [bp+n], reg */
39 OP(0x89);
40 OP(0x45 + x86reg<<3);
41 OP(regoffset);
42 }
44 #define UNDEF()
45 #define MEM_READ_BYTE( addr_reg, value_reg )
46 #define MEM_READ_WORD( addr_reg, value_reg )
47 #define MEM_READ_LONG( addr_reg, value_reg )
48 #define MEM_WRITE_BYTE( addr_reg, value_reg )
49 #define MEM_WRITE_WORD( addr_reg, value_reg )
50 #define MEM_WRITE_LONG( addr_reg, value_reg )
52 /**
53 * Emit an instruction to load an immediate value into a register
54 */
55 static inline void load_imm32( int x86reg, uint32_t value ) {
56 /* mov #value, reg */
57 OP(0xB8 + x86reg);
58 OP32(value);
59 }
61 /**
62 * Emit an instruction to store an SH4 reg (RN)
63 */
64 void static inline store_reg( int x86reg, int sh4reg ) {
65 /* mov reg, [bp+n] */
66 OP(0x8B);
67 OP(0x45 + x86reg<<3);
68 OP(REG_OFFSET(r[sh4reg]));
69 }
70 void static inline store_spreg( int x86reg, int regoffset ) {
71 /* mov reg, [bp+n] */
72 OP(0x8B);
73 OP(0x45 + x86reg<<3);
74 OP(regoffset);
75 }
78 /**
79 * Emit the 'start of block' assembly. Sets up the stack frame and save
80 * SI/DI as required
81 */
82 void sh4_translate_begin_block() {
83 /* push ebp */
84 *xlat_output++ = 0x50 + R_EBP;
86 /* mov &sh4r, ebp */
87 load_imm32( R_EBP, (uint32_t)&sh4r );
89 /* load carry from SR */
90 }
92 /**
93 * Flush any open regs back to memory, restore SI/DI/, update PC, etc
94 */
95 void sh4_translate_end_block( sh4addr_t pc ) {
96 /* pop ebp */
97 *xlat_output++ = 0x58 + R_EBP;
99 /* ret */
100 *xlat_output++ = 0xC3;
101 }
103 /**
104 * Translate a single instruction. Delayed branches are handled specially
105 * by translating both branch and delayed instruction as a single unit (as
106 *
107 *
108 * @return true if the instruction marks the end of a basic block
109 * (eg a branch or
110 */
111 uint32_t sh4_x86_translate_instruction( uint32_t pc )
112 {
113 uint16_t ir = 0;
115 %%
116 /* ALU operations */
117 ADD Rm, Rn {:
118 load_reg( R_EAX, Rm );
119 load_reg( R_ECX, Rn );
120 ADD_r32_r32( R_EAX, R_ECX );
121 store_reg( R_ECX, Rn );
122 :}
123 ADD #imm, Rn {:
124 load_reg( R_EAX, Rn );
125 ADD_imm8s_r32( imm, R_EAX );
126 store_reg( R_EAX, Rn );
127 :}
128 ADDC Rm, Rn {:
129 load_reg( R_EAX, Rm );
130 load_reg( R_ECX, Rn );
131 LDC_t();
132 ADC_r32_r32( R_EAX, R_ECX );
133 store_reg( R_ECX, Rn );
134 SETC_t();
135 :}
136 ADDV Rm, Rn {:
137 load_reg( R_EAX, Rm );
138 load_reg( R_ECX, Rn );
139 ADD_r32_r32( R_EAX, R_ECX );
140 store_reg( R_ECX, Rn );
141 SETO_t();
142 :}
143 AND Rm, Rn {:
144 load_reg( R_EAX, Rm );
145 load_reg( R_ECX, Rn );
146 AND_r32_r32( R_EAX, R_ECX );
147 store_reg( R_ECX, Rn );
148 :}
149 AND #imm, R0 {:
150 // Note: x86 AND imm8 sign-extends, SH4 version zero-extends. So
151 // need to use the imm32 version
152 load_reg( R_EAX, 0 );
153 AND_imm32_r32(imm, R_EAX);
154 store_reg( R_EAX, 0 );
155 :}
156 AND.B #imm, @(R0, GBR) {:
157 load_reg( R_EAX, 0 );
158 load_spreg( R_ECX, R_GBR );
159 ADD_r32_r32( R_EAX, R_EBX );
160 MEM_READ_BYTE( R_ECX, R_EAX );
161 AND_imm32_r32(imm, R_ECX );
162 MEM_WRITE_BYTE( R_ECX, R_EAX );
163 :}
164 CMP/EQ Rm, Rn {:
165 load_reg( R_EAX, Rm );
166 load_reg( R_ECX, Rn );
167 CMP_r32_r32( R_EAX, R_ECX );
168 SETE_t();
169 :}
170 CMP/EQ #imm, R0 {:
171 load_reg( R_EAX, 0 );
172 CMP_imm8s_r32(imm, R_EAX);
173 SETE_t();
174 :}
175 CMP/GE Rm, Rn {:
176 load_reg( R_EAX, Rm );
177 load_reg( R_ECX, Rn );
178 CMP_r32_r32( R_EAX, R_ECX );
179 SETGE_t();
180 :}
181 CMP/GT Rm, Rn {:
182 load_reg( R_EAX, Rm );
183 load_reg( R_ECX, Rn );
184 CMP_r32_r32( R_EAX, R_ECX );
185 SETG_t();
186 :}
187 CMP/HI Rm, Rn {:
188 load_reg( R_EAX, Rm );
189 load_reg( R_ECX, Rn );
190 CMP_r32_r32( R_EAX, R_ECX );
191 SETA_t();
192 :}
193 CMP/HS Rm, Rn {:
194 load_reg( R_EAX, Rm );
195 load_reg( R_ECX, Rn );
196 CMP_r32_r32( R_EAX, R_ECX );
197 SETAE_t();
198 :}
199 CMP/PL Rn {:
200 load_reg( R_EAX, Rn );
201 CMP_imm8s_r32( 0, R_EAX );
202 SETG_t();
203 :}
204 CMP/PZ Rn {:
205 load_reg( R_EAX, Rn );
206 CMP_imm8s_r32( 0, R_EAX );
207 SETGE_t();
208 :}
209 CMP/STR Rm, Rn {: :}
210 DIV0S Rm, Rn {: :}
211 DIV0U {: :}
212 DIV1 Rm, Rn {: :}
213 DMULS.L Rm, Rn {: :}
214 DMULU.L Rm, Rn {: :}
215 DT Rn {:
216 load_reg( R_EAX, Rn );
217 ADD_imm8s_r32( -1, Rn );
218 store_reg( R_EAX, Rn );
219 SETE_t();
220 :}
221 EXTS.B Rm, Rn {:
222 load_reg( R_EAX, Rm );
223 MOVSX_r8_r32( R_EAX, R_EAX );
224 store_reg( R_EAX, Rn );
225 :}
226 EXTS.W Rm, Rn {: :}
227 EXTU.B Rm, Rn {: :}
228 EXTU.W Rm, Rn {: :}
229 MAC.L @Rm+, @Rn+ {: :}
230 MAC.W @Rm+, @Rn+ {: :}
231 MOVT Rn {:
232 load_spreg( R_EAX, R_T );
233 store_reg( R_EAX, Rn );
234 :}
235 MUL.L Rm, Rn {: :}
236 MULS.W Rm, Rn {: :}
237 MULU.W Rm, Rn {: :}
238 NEG Rm, Rn {:
239 load_reg( R_EAX, Rm );
240 NEG_r32( R_EAX );
241 store_reg( R_EAX, Rn );
242 :}
243 NEGC Rm, Rn {:
244 load_reg( R_EAX, Rm );
245 XOR_r32_r32( R_ECX, R_ECX );
246 LDC_t();
247 SBB_r32_r32( R_EAX, R_ECX );
248 store_reg( R_ECX, Rn );
249 SETC_t();
250 :}
251 NOT Rm, Rn {:
252 load_reg( R_EAX, Rm );
253 NOT_r32( R_EAX );
254 store_reg( R_EAX, Rn );
255 :}
256 OR Rm, Rn {:
257 load_reg( R_EAX, Rm );
258 load_reg( R_ECX, Rn );
259 OR_r32_r32( R_EAX, R_ECX );
260 store_reg( R_ECX, Rn );
261 :}
262 OR #imm, R0 {:
263 load_reg( R_EAX, 0 );
264 OR_imm32_r32(imm, R_EAX);
265 store_reg( R_EAX, 0 );
266 :}
267 OR.B #imm, @(R0, GBR) {: :}
268 ROTCL Rn {:
269 load_reg( R_EAX, Rn );
270 LDC_t();
271 RCL1_r32( R_EAX );
272 store_reg( R_EAX, Rn );
273 SETC_t();
274 :}
275 ROTCR Rn {:
276 load_reg( R_EAX, Rn );
277 LDC_t();
278 RCR1_r32( R_EAX );
279 store_reg( R_EAX, Rn );
280 SETC_t();
281 :}
282 ROTL Rn {:
283 load_reg( R_EAX, Rn );
284 ROL1_r32( R_EAX );
285 store_reg( R_EAX, Rn );
286 SETC_t();
287 :}
288 ROTR Rn {:
289 load_reg( R_EAX, Rn );
290 ROR1_r32( R_EAX );
291 store_reg( R_EAX, Rn );
292 SETC_t();
293 :}
294 SHAD Rm, Rn {:
295 /* Annoyingly enough, not directly convertible */
296 :}
297 SHLD Rm, Rn {:
298 :}
299 SHAL Rn {:
300 load_reg( R_EAX, Rn );
301 SHL1_r32( R_EAX );
302 store_reg( R_EAX, Rn );
303 :}
304 SHAR Rn {:
305 load_reg( R_EAX, Rn );
306 SAR1_r32( R_EAX );
307 store_reg( R_EAX, Rn );
308 :}
309 SHLL Rn {:
310 load_reg( R_EAX, Rn );
311 SHL1_r32( R_EAX );
312 store_reg( R_EAX, Rn );
313 :}
314 SHLL2 Rn {:
315 load_reg( R_EAX, Rn );
316 SHL_imm8_r32( 2, R_EAX );
317 store_reg( R_EAX, Rn );
318 :}
319 SHLL8 Rn {:
320 load_reg( R_EAX, Rn );
321 SHL_imm8_r32( 8, R_EAX );
322 store_reg( R_EAX, Rn );
323 :}
324 SHLL16 Rn {:
325 load_reg( R_EAX, Rn );
326 SHL_imm8_r32( 16, R_EAX );
327 store_reg( R_EAX, Rn );
328 :}
329 SHLR Rn {:
330 load_reg( R_EAX, Rn );
331 SHR1_r32( R_EAX );
332 store_reg( R_EAX, Rn );
333 :}
334 SHLR2 Rn {:
335 load_reg( R_EAX, Rn );
336 SHR_imm8_r32( 2, R_EAX );
337 store_reg( R_EAX, Rn );
338 :}
339 SHLR8 Rn {:
340 load_reg( R_EAX, Rn );
341 SHR_imm8_r32( 8, R_EAX );
342 store_reg( R_EAX, Rn );
343 :}
344 SHLR16 Rn {:
345 load_reg( R_EAX, Rn );
346 SHR_imm8_r32( 16, R_EAX );
347 store_reg( R_EAX, Rn );
348 :}
349 SUB Rm, Rn {:
350 load_reg( R_EAX, Rm );
351 load_reg( R_ECX, Rn );
352 SUB_r32_r32( R_EAX, R_ECX );
353 store_reg( R_ECX, Rn );
354 :}
355 SUBC Rm, Rn {:
356 load_reg( R_EAX, Rm );
357 load_reg( R_ECX, Rn );
358 LDC_t();
359 SBB_r32_r32( R_EAX, R_ECX );
360 store_reg( R_ECX, Rn );
361 :}
362 SUBV Rm, Rn {:
363 load_reg( R_EAX, Rm );
364 load_reg( R_ECX, Rn );
365 SUB_r32_r32( R_EAX, R_ECX );
366 store_reg( R_ECX, Rn );
367 SETO_t();
368 :}
369 SWAP.B Rm, Rn {:
370 load_reg( R_EAX, Rm );
371 XCHG_r8_r8( R_AL, R_AH );
372 store_reg( R_EAX, Rn );
373 :}
374 SWAP.W Rm, Rn {:
375 load_reg( R_EAX, Rm );
376 MOV_r32_r32( R_EAX, R_ECX );
377 SHL_imm8_r32( 16, R_ECX );
378 SHR_imm8_r32( 16, R_EAX );
379 OR_r32_r32( R_EAX, R_ECX );
380 store_reg( R_ECX, Rn );
381 :}
382 TAS.B @Rn {: :}
383 TST Rm, Rn {: :}
384 TST #imm, R0 {: :}
385 TST.B #imm, @(R0, GBR) {: :}
386 XOR Rm, Rn {:
387 load_reg( R_EAX, Rm );
388 load_reg( R_ECX, Rn );
389 XOR_r32_r32( R_EAX, R_ECX );
390 store_reg( R_ECX, Rn );
391 :}
392 XOR #imm, R0 {:
393 load_reg( R_EAX, 0 );
394 XOR_imm32_r32( imm, R_EAX );
395 store_reg( R_EAX, 0 );
396 :}
397 XOR.B #imm, @(R0, GBR) {:
398 load_reg( R_EAX, 0 );
399 load_spreg( R_ECX, R_GBR );
400 ADD_r32_r32( R_EAX, R_ECX );
401 MEM_READ_BYTE( R_ECX, R_EAX );
402 XOR_imm32_r32( imm, R_EAX );
403 MEM_WRITE_BYTE( R_ECX, R_EAX );
404 :}
405 XTRCT Rm, Rn {:
406 :}
408 /* Data move instructions */
409 MOV Rm, Rn {:
410 load_reg( R_EAX, Rm );
411 store_reg( R_EAX, Rn );
412 :}
413 MOV #imm, Rn {:
414 load_imm32( R_EAX, imm );
415 store_reg( R_EAX, Rn );
416 :}
417 MOV.B Rm, @Rn {:
418 load_reg( R_EAX, Rm );
419 load_reg( R_ECX, Rn );
420 MEM_WRITE_BYTE( R_ECX, R_EAX );
421 :}
422 MOV.B Rm, @-Rn {:
423 load_reg( R_EAX, Rm );
424 load_reg( R_ECX, Rn );
425 ADD_imm8s_r32( -1, Rn );
426 store_reg( R_ECX, Rn );
427 MEM_WRITE_BYTE( R_ECX, R_EAX );
428 :}
429 MOV.B Rm, @(R0, Rn) {:
430 load_reg( R_EAX, 0 );
431 load_reg( R_ECX, Rn );
432 ADD_r32_r32( R_EAX, R_ECX );
433 load_reg( R_EAX, Rm );
434 MEM_WRITE_BYTE( R_ECX, R_EAX );
435 :}
436 MOV.B R0, @(disp, GBR) {:
437 load_reg( R_EAX, 0 );
438 load_spreg( R_ECX, R_GBR );
439 ADD_imm32_r32( disp, R_ECX );
440 MEM_WRITE_BYTE( R_ECX, R_EAX );
441 :}
442 MOV.B R0, @(disp, Rn) {:
443 load_reg( R_EAX, 0 );
444 load_reg( R_ECX, Rn );
445 ADD_imm32_r32( disp, R_ECX );
446 MEM_WRITE_BYTE( R_ECX, R_EAX );
447 :}
448 MOV.B @Rm, Rn {:
449 load_reg( R_ECX, Rm );
450 MEM_READ_BYTE( R_ECX, R_EAX );
451 store_reg( R_ECX, Rn );
452 :}
453 MOV.B @Rm+, Rn {:
454 load_reg( R_ECX, Rm );
455 MOV_r32_r32( R_ECX, R_EAX );
456 ADD_imm8s_r32( 1, R_EAX );
457 store_reg( R_EAX, Rm );
458 MEM_READ_BYTE( R_ECX, R_EAX );
459 store_reg( R_EAX, Rn );
460 :}
461 MOV.B @(R0, Rm), Rn {:
462 load_reg( R_EAX, 0 );
463 load_reg( R_ECX, Rm );
464 ADD_r32_r32( R_EAX, R_ECX );
465 MEM_READ_BYTE( R_ECX, R_EAX );
466 store_reg( R_EAX, Rn );
467 :}
468 MOV.B @(disp, GBR), R0 {:
469 load_spreg( R_ECX, R_GBR );
470 ADD_imm32_r32( disp, R_ECX );
471 MEM_READ_BYTE( R_ECX, R_EAX );
472 store_reg( R_EAX, 0 );
473 :}
474 MOV.B @(disp, Rm), R0 {:
475 load_reg( R_ECX, Rm );
476 ADD_imm32_r32( disp, R_ECX );
477 MEM_READ_BYTE( R_ECX, R_EAX );
478 store_reg( R_EAX, 0 );
479 :}
480 MOV.L Rm, @Rn {: :}
481 MOV.L Rm, @-Rn {: :}
482 MOV.L Rm, @(R0, Rn) {: :}
483 MOV.L R0, @(disp, GBR) {: :}
484 MOV.L Rm, @(disp, Rn) {: :}
485 MOV.L @Rm, Rn {: :}
486 MOV.L @Rm+, Rn {: :}
487 MOV.L @(R0, Rm), Rn {: :}
488 MOV.L @(disp, GBR), R0 {: :}
489 MOV.L @(disp, PC), Rn {: :}
490 MOV.L @(disp, Rm), Rn {: :}
491 MOV.W Rm, @Rn {: :}
492 MOV.W Rm, @-Rn {: :}
493 MOV.W Rm, @(R0, Rn) {: :}
494 MOV.W R0, @(disp, GBR) {: :}
495 MOV.W R0, @(disp, Rn) {: :}
496 MOV.W @Rm, Rn {: :}
497 MOV.W @Rm+, Rn {: :}
498 MOV.W @(R0, Rm), Rn {: :}
499 MOV.W @(disp, GBR), R0 {: :}
500 MOV.W @(disp, PC), Rn {: :}
501 MOV.W @(disp, Rm), R0 {: :}
502 MOVA @(disp, PC), R0 {: :}
503 MOVCA.L R0, @Rn {: :}
505 /* Control transfer instructions */
506 BF disp {: :}
507 BF/S disp {: :}
508 BRA disp {: :}
509 BRAF Rn {: :}
510 BSR disp {: :}
511 BSRF Rn {: :}
512 BT disp {: /* If true, result PC += 4 + disp. else result PC = pc+2 */
513 return pc + 2;
514 :}
515 BT/S disp {:
517 return pc + 4;
518 :}
519 JMP @Rn {: :}
520 JSR @Rn {: :}
521 RTE {: :}
522 RTS {: :}
523 TRAPA #imm {: :}
524 UNDEF {: :}
526 CLRMAC {: :}
527 CLRS {: :}
528 CLRT {: :}
529 SETS {: :}
530 SETT {: :}
532 /* Floating point instructions */
533 FABS FRn {: :}
534 FADD FRm, FRn {: :}
535 FCMP/EQ FRm, FRn {: :}
536 FCMP/GT FRm, FRn {: :}
537 FCNVDS FRm, FPUL {: :}
538 FCNVSD FPUL, FRn {: :}
539 FDIV FRm, FRn {: :}
540 FIPR FVm, FVn {: :}
541 FLDS FRm, FPUL {: :}
542 FLDI0 FRn {: :}
543 FLDI1 FRn {: :}
544 FLOAT FPUL, FRn {: :}
545 FMAC FR0, FRm, FRn {: :}
546 FMOV FRm, FRn {: :}
547 FMOV FRm, @Rn {: :}
548 FMOV FRm, @-Rn {: :}
549 FMOV FRm, @(R0, Rn) {: :}
550 FMOV @Rm, FRn {: :}
551 FMOV @Rm+, FRn {: :}
552 FMOV @(R0, Rm), FRn {: :}
553 FMUL FRm, FRn {: :}
554 FNEG FRn {: :}
555 FRCHG {: :}
556 FSCA FPUL, FRn {: :}
557 FSCHG {: :}
558 FSQRT FRn {: :}
559 FSRRA FRn {: :}
560 FSTS FPUL, FRn {: :}
561 FSUB FRm, FRn {: :}
562 FTRC FRm, FPUL {: :}
563 FTRV XMTRX, FVn {: :}
565 /* Processor control instructions */
566 LDC Rm, SR {: /* We need to be a little careful about SR */ :}
567 LDC Rm, GBR {:
568 load_reg( R_EAX, Rm );
569 store_spreg( R_EAX, R_GBR );
570 :}
571 LDC Rm, VBR {:
572 load_reg( R_EAX, Rm );
573 store_spreg( R_EAX, R_VBR );
574 :}
575 LDC Rm, SSR {:
576 load_reg( R_EAX, Rm );
577 store_spreg( R_EAX, R_SSR );
578 :}
579 LDC Rm, SGR {:
580 load_reg( R_EAX, Rm );
581 store_spreg( R_EAX, R_SGR );
582 :}
583 LDC Rm, SPC {:
584 load_reg( R_EAX, Rm );
585 store_spreg( R_EAX, R_SPC );
586 :}
587 LDC Rm, DBR {:
588 load_reg( R_EAX, Rm );
589 store_spreg( R_EAX, R_DBR );
590 :}
591 LDC Rm, Rn_BANK {: :}
592 LDC.L @Rm+, GBR {:
593 load_reg( R_EAX, Rm );
594 MOV_r32_r32( R_EAX, R_ECX );
595 ADD_imm8s_r32( 4, R_EAX );
596 store_reg( R_EAX, Rm );
597 MEM_READ_LONG( R_ECX, R_EAX );
598 store_spreg( R_EAX, R_GBR );
599 :}
600 LDC.L @Rm+, SR {:
601 :}
602 LDC.L @Rm+, VBR {:
603 load_reg( R_EAX, Rm );
604 MOV_r32_r32( R_EAX, R_ECX );
605 ADD_imm8s_r32( 4, R_EAX );
606 store_reg( R_EAX, Rm );
607 MEM_READ_LONG( R_ECX, R_EAX );
608 store_spreg( R_EAX, R_VBR );
609 :}
610 LDC.L @Rm+, SSR {:
611 load_reg( R_EAX, Rm );
612 MOV_r32_r32( R_EAX, R_ECX );
613 ADD_imm8s_r32( 4, R_EAX );
614 store_reg( R_EAX, Rm );
615 MEM_READ_LONG( R_ECX, R_EAX );
616 store_spreg( R_EAX, R_SSR );
617 :}
618 LDC.L @Rm+, SGR {:
619 load_reg( R_EAX, Rm );
620 MOV_r32_r32( R_EAX, R_ECX );
621 ADD_imm8s_r32( 4, R_EAX );
622 store_reg( R_EAX, Rm );
623 MEM_READ_LONG( R_ECX, R_EAX );
624 store_spreg( R_EAX, R_SGR );
625 :}
626 LDC.L @Rm+, SPC {:
627 load_reg( R_EAX, Rm );
628 MOV_r32_r32( R_EAX, R_ECX );
629 ADD_imm8s_r32( 4, R_EAX );
630 store_reg( R_EAX, Rm );
631 MEM_READ_LONG( R_ECX, R_EAX );
632 store_spreg( R_EAX, R_SPC );
633 :}
634 LDC.L @Rm+, DBR {:
635 load_reg( R_EAX, Rm );
636 MOV_r32_r32( R_EAX, R_ECX );
637 ADD_imm8s_r32( 4, R_EAX );
638 store_reg( R_EAX, Rm );
639 MEM_READ_LONG( R_ECX, R_EAX );
640 store_spreg( R_EAX, R_DBR );
641 :}
642 LDC.L @Rm+, Rn_BANK {:
643 :}
644 LDS Rm, FPSCR {:
645 load_reg( R_EAX, Rm );
646 store_spreg( R_EAX, R_FPSCR );
647 :}
648 LDS.L @Rm+, FPSCR {:
649 load_reg( R_EAX, Rm );
650 MOV_r32_r32( R_EAX, R_ECX );
651 ADD_imm8s_r32( 4, R_EAX );
652 store_reg( R_EAX, Rm );
653 MEM_READ_LONG( R_ECX, R_EAX );
654 store_spreg( R_EAX, R_FPSCR );
655 :}
656 LDS Rm, FPUL {:
657 load_reg( R_EAX, Rm );
658 store_spreg( R_EAX, R_FPUL );
659 :}
660 LDS.L @Rm+, FPUL {:
661 load_reg( R_EAX, Rm );
662 MOV_r32_r32( R_EAX, R_ECX );
663 ADD_imm8s_r32( 4, R_EAX );
664 store_reg( R_EAX, Rm );
665 MEM_READ_LONG( R_ECX, R_EAX );
666 store_spreg( R_EAX, R_FPUL );
667 :}
668 LDS Rm, MACH {:
669 load_reg( R_EAX, Rm );
670 store_spreg( R_EAX, R_MACH );
671 :}
672 LDS.L @Rm+, MACH {:
673 load_reg( R_EAX, Rm );
674 MOV_r32_r32( R_EAX, R_ECX );
675 ADD_imm8s_r32( 4, R_EAX );
676 store_reg( R_EAX, Rm );
677 MEM_READ_LONG( R_ECX, R_EAX );
678 store_spreg( R_EAX, R_MACH );
679 :}
680 LDS Rm, MACL {:
681 load_reg( R_EAX, Rm );
682 store_spreg( R_EAX, R_MACL );
683 :}
684 LDS.L @Rm+, MACL {:
685 load_reg( R_EAX, Rm );
686 MOV_r32_r32( R_EAX, R_ECX );
687 ADD_imm8s_r32( 4, R_EAX );
688 store_reg( R_EAX, Rm );
689 MEM_READ_LONG( R_ECX, R_EAX );
690 store_spreg( R_EAX, R_MACL );
691 :}
692 LDS Rm, PR {:
693 load_reg( R_EAX, Rm );
694 store_spreg( R_EAX, R_PR );
695 :}
696 LDS.L @Rm+, PR {:
697 load_reg( R_EAX, Rm );
698 MOV_r32_r32( R_EAX, R_ECX );
699 ADD_imm8s_r32( 4, R_EAX );
700 store_reg( R_EAX, Rm );
701 MEM_READ_LONG( R_ECX, R_EAX );
702 store_spreg( R_EAX, R_PR );
703 :}
704 LDTLB {: :}
705 OCBI @Rn {: :}
706 OCBP @Rn {: :}
707 OCBWB @Rn {: :}
708 PREF @Rn {: :}
709 SLEEP {: :}
710 STC SR, Rn {: /* TODO */
711 :}
712 STC GBR, Rn {:
713 load_spreg( R_EAX, R_GBR );
714 store_reg( R_EAX, Rn );
715 :}
716 STC VBR, Rn {:
717 load_spreg( R_EAX, R_VBR );
718 store_reg( R_EAX, Rn );
719 :}
720 STC SSR, Rn {:
721 load_spreg( R_EAX, R_SSR );
722 store_reg( R_EAX, Rn );
723 :}
724 STC SPC, Rn {:
725 load_spreg( R_EAX, R_SPC );
726 store_reg( R_EAX, Rn );
727 :}
728 STC SGR, Rn {:
729 load_spreg( R_EAX, R_SGR );
730 store_reg( R_EAX, Rn );
731 :}
732 STC DBR, Rn {:
733 load_spreg( R_EAX, R_DBR );
734 store_reg( R_EAX, Rn );
735 :}
736 STC Rm_BANK, Rn {: /* TODO */
737 :}
738 STC.L SR, @-Rn {: /* TODO */
739 :}
740 STC.L VBR, @-Rn {:
741 load_reg( R_ECX, Rn );
742 ADD_imm8s_r32( -4, Rn );
743 store_reg( R_ECX, Rn );
744 load_spreg( R_EAX, R_VBR );
745 MEM_WRITE_LONG( R_ECX, R_EAX );
746 :}
747 STC.L SSR, @-Rn {:
748 load_reg( R_ECX, Rn );
749 ADD_imm8s_r32( -4, Rn );
750 store_reg( R_ECX, Rn );
751 load_spreg( R_EAX, R_SSR );
752 MEM_WRITE_LONG( R_ECX, R_EAX );
753 :}
754 STC.L SPC, @-Rn {:
755 load_reg( R_ECX, Rn );
756 ADD_imm8s_r32( -4, Rn );
757 store_reg( R_ECX, Rn );
758 load_spreg( R_EAX, R_SPC );
759 MEM_WRITE_LONG( R_ECX, R_EAX );
760 :}
761 STC.L SGR, @-Rn {:
762 load_reg( R_ECX, Rn );
763 ADD_imm8s_r32( -4, Rn );
764 store_reg( R_ECX, Rn );
765 load_spreg( R_EAX, R_SGR );
766 MEM_WRITE_LONG( R_ECX, R_EAX );
767 :}
768 STC.L DBR, @-Rn {:
769 load_reg( R_ECX, Rn );
770 ADD_imm8s_r32( -4, Rn );
771 store_reg( R_ECX, Rn );
772 load_spreg( R_EAX, R_DBR );
773 MEM_WRITE_LONG( R_ECX, R_EAX );
774 :}
775 STC.L Rm_BANK, @-Rn {: :}
776 STC.L GBR, @-Rn {:
777 load_reg( R_ECX, Rn );
778 ADD_imm8s_r32( -4, Rn );
779 store_reg( R_ECX, Rn );
780 load_spreg( R_EAX, R_GBR );
781 MEM_WRITE_LONG( R_ECX, R_EAX );
782 :}
783 STS FPSCR, Rn {:
784 load_spreg( R_EAX, R_FPSCR );
785 store_reg( R_EAX, Rn );
786 :}
787 STS.L FPSCR, @-Rn {:
788 load_reg( R_ECX, Rn );
789 ADD_imm8s_r32( -4, Rn );
790 store_reg( R_ECX, Rn );
791 load_spreg( R_EAX, R_FPSCR );
792 MEM_WRITE_LONG( R_ECX, R_EAX );
793 :}
794 STS FPUL, Rn {:
795 load_spreg( R_EAX, R_FPUL );
796 store_reg( R_EAX, Rn );
797 :}
798 STS.L FPUL, @-Rn {:
799 load_reg( R_ECX, Rn );
800 ADD_imm8s_r32( -4, Rn );
801 store_reg( R_ECX, Rn );
802 load_spreg( R_EAX, R_FPUL );
803 MEM_WRITE_LONG( R_ECX, R_EAX );
804 :}
805 STS MACH, Rn {:
806 load_spreg( R_EAX, R_MACH );
807 store_reg( R_EAX, Rn );
808 :}
809 STS.L MACH, @-Rn {:
810 load_reg( R_ECX, Rn );
811 ADD_imm8s_r32( -4, Rn );
812 store_reg( R_ECX, Rn );
813 load_spreg( R_EAX, R_MACH );
814 MEM_WRITE_LONG( R_ECX, R_EAX );
815 :}
816 STS MACL, Rn {:
817 load_spreg( R_EAX, R_MACL );
818 store_reg( R_EAX, Rn );
819 :}
820 STS.L MACL, @-Rn {:
821 load_reg( R_ECX, Rn );
822 ADD_imm8s_r32( -4, Rn );
823 store_reg( R_ECX, Rn );
824 load_spreg( R_EAX, R_MACL );
825 MEM_WRITE_LONG( R_ECX, R_EAX );
826 :}
827 STS PR, Rn {:
828 load_spreg( R_EAX, R_PR );
829 store_reg( R_EAX, Rn );
830 :}
831 STS.L PR, @-Rn {:
832 load_reg( R_ECX, Rn );
833 ADD_imm8s_r32( -4, Rn );
834 store_reg( R_ECX, Rn );
835 load_spreg( R_EAX, R_PR );
836 MEM_WRITE_LONG( R_ECX, R_EAX );
837 :}
839 NOP {: /* Do nothing. Well, we could emit an 0x90, but what would really be the point? */ :}
840 %%
842 return 0;
843 }
.