2 * $Id: sh4x86.in,v 1.2 2007-08-28 08:46:14 nkeynes Exp $
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.
8 * Copyright (c) 2007 Nathan Keynes.
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.
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.
26 * Emit an instruction to load an SH4 reg into a real register
28 static inline void load_reg( int x86reg, int sh4reg )
32 OP(0x45 + (x86reg<<3));
33 OP(REG_OFFSET(r[sh4reg]));
36 static inline void load_spreg( int x86reg, int regoffset )
40 OP(0x45 + (x86reg<<3));
45 * Emit an instruction to load an immediate value into a register
47 static inline void load_imm32( int x86reg, uint32_t value ) {
54 * Emit an instruction to store an SH4 reg (RN)
56 void static inline store_reg( int x86reg, int sh4reg ) {
59 OP(0x45 + (x86reg<<3));
60 OP(REG_OFFSET(r[sh4reg]));
62 void static inline store_spreg( int x86reg, int regoffset ) {
65 OP(0x45 + (x86reg<<3));
70 * Note: clobbers EAX to make the indirect call - this isn't usually
71 * a problem since the callee will usually clobber it anyway.
73 static inline void call_func0( void *ptr )
75 load_imm32(R_EAX, (uint32_t)ptr);
77 MODRM_rm32_r32(R_EAX, 2);
80 static inline void call_func1( void *ptr, int arg1 )
84 ADD_imm8s_r32( -4, R_ESP );
87 static inline void call_func2( void *ptr, int arg1, int arg2 )
92 ADD_imm8s_r32( -4, R_ESP );
96 #define MEM_RESULT(value_reg) if(value_reg != R_EAX) { MOV_r32_r32(R_EAX,value_reg); }
97 #define MEM_READ_BYTE( addr_reg, value_reg ) call_func1(sh4_read_byte, addr_reg ); MEM_RESULT(value_reg)
98 #define MEM_READ_WORD( addr_reg, value_reg ) call_func1(sh4_read_word, addr_reg ); MEM_RESULT(value_reg)
99 #define MEM_READ_LONG( addr_reg, value_reg ) call_func1(sh4_read_long, addr_reg ); MEM_RESULT(value_reg)
100 #define MEM_WRITE_BYTE( addr_reg, value_reg ) call_func2(sh4_write_byte, addr_reg, value_reg)
101 #define MEM_WRITE_WORD( addr_reg, value_reg ) call_func2(sh4_write_word, addr_reg, value_reg)
102 #define MEM_WRITE_LONG( addr_reg, value_reg ) call_func2(sh4_write_long, addr_reg, value_reg)
106 * Emit the 'start of block' assembly. Sets up the stack frame and save
109 void sh4_translate_begin_block() {
111 *xlat_output++ = 0x50 + R_EBP;
114 load_imm32( R_EBP, (uint32_t)&sh4r );
116 /* load carry from SR */
120 * Flush any open regs back to memory, restore SI/DI/, update PC, etc
122 void sh4_translate_end_block( sh4addr_t pc ) {
124 *xlat_output++ = 0x58 + R_EBP;
127 *xlat_output++ = 0xC3;
131 * Translate a single instruction. Delayed branches are handled specially
132 * by translating both branch and delayed instruction as a single unit (as
135 * @return true if the instruction marks the end of a basic block
138 uint32_t sh4_x86_translate_instruction( uint32_t pc )
140 uint16_t ir = sh4_read_word( pc );
145 load_reg( R_EAX, Rm );
146 load_reg( R_ECX, Rn );
147 ADD_r32_r32( R_EAX, R_ECX );
148 store_reg( R_ECX, Rn );
151 load_reg( R_EAX, Rn );
152 ADD_imm8s_r32( imm, R_EAX );
153 store_reg( R_EAX, Rn );
156 load_reg( R_EAX, Rm );
157 load_reg( R_ECX, Rn );
159 ADC_r32_r32( R_EAX, R_ECX );
160 store_reg( R_ECX, Rn );
164 load_reg( R_EAX, Rm );
165 load_reg( R_ECX, Rn );
166 ADD_r32_r32( R_EAX, R_ECX );
167 store_reg( R_ECX, Rn );
171 load_reg( R_EAX, Rm );
172 load_reg( R_ECX, Rn );
173 AND_r32_r32( R_EAX, R_ECX );
174 store_reg( R_ECX, Rn );
177 load_reg( R_EAX, 0 );
178 AND_imm32_r32(imm, R_EAX);
179 store_reg( R_EAX, 0 );
181 AND.B #imm, @(R0, GBR) {:
182 load_reg( R_EAX, 0 );
183 load_spreg( R_ECX, R_GBR );
184 ADD_r32_r32( R_EAX, R_EBX );
185 MEM_READ_BYTE( R_ECX, R_EAX );
186 AND_imm32_r32(imm, R_ECX );
187 MEM_WRITE_BYTE( R_ECX, R_EAX );
190 load_reg( R_EAX, Rm );
191 load_reg( R_ECX, Rn );
192 CMP_r32_r32( R_EAX, R_ECX );
196 load_reg( R_EAX, 0 );
197 CMP_imm8s_r32(imm, R_EAX);
201 load_reg( R_EAX, Rm );
202 load_reg( R_ECX, Rn );
203 CMP_r32_r32( R_EAX, R_ECX );
207 load_reg( R_EAX, Rm );
208 load_reg( R_ECX, Rn );
209 CMP_r32_r32( R_EAX, R_ECX );
213 load_reg( R_EAX, Rm );
214 load_reg( R_ECX, Rn );
215 CMP_r32_r32( R_EAX, R_ECX );
219 load_reg( R_EAX, Rm );
220 load_reg( R_ECX, Rn );
221 CMP_r32_r32( R_EAX, R_ECX );
225 load_reg( R_EAX, Rn );
226 CMP_imm8s_r32( 0, R_EAX );
230 load_reg( R_EAX, Rn );
231 CMP_imm8s_r32( 0, R_EAX );
237 load_reg( R_EAX, Rm );
238 load_reg( R_ECX, Rm );
239 SHR_imm8_r32( 31, R_EAX );
240 SHR_imm8_r32( 31, R_ECX );
241 store_spreg( R_EAX, R_M );
242 store_spreg( R_ECX, R_Q );
243 CMP_r32_r32( R_EAX, R_ECX );
247 XOR_r32_r32( R_EAX, R_EAX );
248 store_spreg( R_EAX, R_Q );
249 store_spreg( R_EAX, R_M );
250 store_spreg( R_EAX, R_T );
254 load_reg( R_EAX, Rm );
255 load_reg( R_ECX, Rn );
257 store_spreg( R_EDX, R_MACH );
258 store_spreg( R_EAX, R_MACL );
261 load_reg( R_EAX, Rm );
262 load_reg( R_ECX, Rn );
264 store_spreg( R_EDX, R_MACH );
265 store_spreg( R_EAX, R_MACL );
268 load_reg( R_EAX, Rn );
269 ADD_imm8s_r32( -1, Rn );
270 store_reg( R_EAX, Rn );
274 load_reg( R_EAX, Rm );
275 MOVSX_r8_r32( R_EAX, R_EAX );
276 store_reg( R_EAX, Rn );
279 load_reg( R_EAX, Rm );
280 MOVSX_r16_r32( R_EAX, R_EAX );
281 store_reg( R_EAX, Rn );
284 load_reg( R_EAX, Rm );
285 MOVZX_r8_r32( R_EAX, R_EAX );
286 store_reg( R_EAX, Rn );
289 load_reg( R_EAX, Rm );
290 MOVZX_r16_r32( R_EAX, R_EAX );
291 store_reg( R_EAX, Rn );
293 MAC.L @Rm+, @Rn+ {: :}
294 MAC.W @Rm+, @Rn+ {: :}
296 load_spreg( R_EAX, R_T );
297 store_reg( R_EAX, Rn );
300 load_reg( R_EAX, Rm );
301 load_reg( R_ECX, Rn );
303 store_spreg( R_EAX, R_MACL );
309 load_reg( R_EAX, Rm );
311 store_reg( R_EAX, Rn );
314 load_reg( R_EAX, Rm );
315 XOR_r32_r32( R_ECX, R_ECX );
317 SBB_r32_r32( R_EAX, R_ECX );
318 store_reg( R_ECX, Rn );
322 load_reg( R_EAX, Rm );
324 store_reg( R_EAX, Rn );
327 load_reg( R_EAX, Rm );
328 load_reg( R_ECX, Rn );
329 OR_r32_r32( R_EAX, R_ECX );
330 store_reg( R_ECX, Rn );
333 load_reg( R_EAX, 0 );
334 OR_imm32_r32(imm, R_EAX);
335 store_reg( R_EAX, 0 );
337 OR.B #imm, @(R0, GBR) {: :}
339 load_reg( R_EAX, Rn );
342 store_reg( R_EAX, Rn );
346 load_reg( R_EAX, Rn );
349 store_reg( R_EAX, Rn );
353 load_reg( R_EAX, Rn );
355 store_reg( R_EAX, Rn );
359 load_reg( R_EAX, Rn );
361 store_reg( R_EAX, Rn );
365 /* Annoyingly enough, not directly convertible */
366 load_reg( R_EAX, Rn );
367 load_reg( R_ECX, Rm );
368 CMP_imm32_r32( 0, R_ECX );
371 NEG_r32( R_ECX ); // 2
372 AND_imm8_r8( 0x1F, R_CL ); // 3
373 SAR_r32_CL( R_EAX ); // 2
376 AND_imm8_r8( 0x1F, R_CL ); // 3
377 SHL_r32_CL( R_EAX ); // 2
379 store_reg( R_EAX, Rn );
384 load_reg( R_EAX, Rn );
386 store_reg( R_EAX, Rn );
389 load_reg( R_EAX, Rn );
391 store_reg( R_EAX, Rn );
394 load_reg( R_EAX, Rn );
396 store_reg( R_EAX, Rn );
399 load_reg( R_EAX, Rn );
400 SHL_imm8_r32( 2, R_EAX );
401 store_reg( R_EAX, Rn );
404 load_reg( R_EAX, Rn );
405 SHL_imm8_r32( 8, R_EAX );
406 store_reg( R_EAX, Rn );
409 load_reg( R_EAX, Rn );
410 SHL_imm8_r32( 16, R_EAX );
411 store_reg( R_EAX, Rn );
414 load_reg( R_EAX, Rn );
416 store_reg( R_EAX, Rn );
419 load_reg( R_EAX, Rn );
420 SHR_imm8_r32( 2, R_EAX );
421 store_reg( R_EAX, Rn );
424 load_reg( R_EAX, Rn );
425 SHR_imm8_r32( 8, R_EAX );
426 store_reg( R_EAX, Rn );
429 load_reg( R_EAX, Rn );
430 SHR_imm8_r32( 16, R_EAX );
431 store_reg( R_EAX, Rn );
434 load_reg( R_EAX, Rm );
435 load_reg( R_ECX, Rn );
436 SUB_r32_r32( R_EAX, R_ECX );
437 store_reg( R_ECX, Rn );
440 load_reg( R_EAX, Rm );
441 load_reg( R_ECX, Rn );
443 SBB_r32_r32( R_EAX, R_ECX );
444 store_reg( R_ECX, Rn );
447 load_reg( R_EAX, Rm );
448 load_reg( R_ECX, Rn );
449 SUB_r32_r32( R_EAX, R_ECX );
450 store_reg( R_ECX, Rn );
454 load_reg( R_EAX, Rm );
455 XCHG_r8_r8( R_AL, R_AH );
456 store_reg( R_EAX, Rn );
459 load_reg( R_EAX, Rm );
460 MOV_r32_r32( R_EAX, R_ECX );
461 SHL_imm8_r32( 16, R_ECX );
462 SHR_imm8_r32( 16, R_EAX );
463 OR_r32_r32( R_EAX, R_ECX );
464 store_reg( R_ECX, Rn );
467 load_reg( R_ECX, Rn );
468 MEM_READ_BYTE( R_ECX, R_EAX );
469 TEST_r8_r8( R_AL, R_AL );
471 OR_imm8_r8( 0x80, R_AL );
472 MEM_WRITE_BYTE( R_ECX, R_EAX );
475 load_reg( R_EAX, Rm );
476 load_reg( R_ECX, Rn );
477 TEST_r32_r32( R_EAX, R_ECX );
481 TST.B #imm, @(R0, GBR) {: :}
483 load_reg( R_EAX, Rm );
484 load_reg( R_ECX, Rn );
485 XOR_r32_r32( R_EAX, R_ECX );
486 store_reg( R_ECX, Rn );
489 load_reg( R_EAX, 0 );
490 XOR_imm32_r32( imm, R_EAX );
491 store_reg( R_EAX, 0 );
493 XOR.B #imm, @(R0, GBR) {:
494 load_reg( R_EAX, 0 );
495 load_spreg( R_ECX, R_GBR );
496 ADD_r32_r32( R_EAX, R_ECX );
497 MEM_READ_BYTE( R_ECX, R_EAX );
498 XOR_imm32_r32( imm, R_EAX );
499 MEM_WRITE_BYTE( R_ECX, R_EAX );
502 load_reg( R_EAX, Rm );
503 MOV_r32_r32( R_EAX, R_ECX );
504 SHR_imm8_r32( 16, R_EAX );
505 SHL_imm8_r32( 16, R_ECX );
506 OR_r32_r32( R_EAX, R_ECX );
507 store_reg( R_ECX, Rn );
510 /* Data move instructions */
512 load_reg( R_EAX, Rm );
513 store_reg( R_EAX, Rn );
516 load_imm32( R_EAX, imm );
517 store_reg( R_EAX, Rn );
520 load_reg( R_EAX, Rm );
521 load_reg( R_ECX, Rn );
522 MEM_WRITE_BYTE( R_ECX, R_EAX );
525 load_reg( R_EAX, Rm );
526 load_reg( R_ECX, Rn );
527 ADD_imm8s_r32( -1, Rn );
528 store_reg( R_ECX, Rn );
529 MEM_WRITE_BYTE( R_ECX, R_EAX );
531 MOV.B Rm, @(R0, Rn) {:
532 load_reg( R_EAX, 0 );
533 load_reg( R_ECX, Rn );
534 ADD_r32_r32( R_EAX, R_ECX );
535 load_reg( R_EAX, Rm );
536 MEM_WRITE_BYTE( R_ECX, R_EAX );
538 MOV.B R0, @(disp, GBR) {:
539 load_reg( R_EAX, 0 );
540 load_spreg( R_ECX, R_GBR );
541 ADD_imm32_r32( disp, R_ECX );
542 MEM_WRITE_BYTE( R_ECX, R_EAX );
544 MOV.B R0, @(disp, Rn) {:
545 load_reg( R_EAX, 0 );
546 load_reg( R_ECX, Rn );
547 ADD_imm32_r32( disp, R_ECX );
548 MEM_WRITE_BYTE( R_ECX, R_EAX );
551 load_reg( R_ECX, Rm );
552 MEM_READ_BYTE( R_ECX, R_EAX );
553 store_reg( R_ECX, Rn );
556 load_reg( R_ECX, Rm );
557 MOV_r32_r32( R_ECX, R_EAX );
558 ADD_imm8s_r32( 1, R_EAX );
559 store_reg( R_EAX, Rm );
560 MEM_READ_BYTE( R_ECX, R_EAX );
561 store_reg( R_EAX, Rn );
563 MOV.B @(R0, Rm), Rn {:
564 load_reg( R_EAX, 0 );
565 load_reg( R_ECX, Rm );
566 ADD_r32_r32( R_EAX, R_ECX );
567 MEM_READ_BYTE( R_ECX, R_EAX );
568 store_reg( R_EAX, Rn );
570 MOV.B @(disp, GBR), R0 {:
571 load_spreg( R_ECX, R_GBR );
572 ADD_imm32_r32( disp, R_ECX );
573 MEM_READ_BYTE( R_ECX, R_EAX );
574 store_reg( R_EAX, 0 );
576 MOV.B @(disp, Rm), R0 {:
577 load_reg( R_ECX, Rm );
578 ADD_imm32_r32( disp, R_ECX );
579 MEM_READ_BYTE( R_ECX, R_EAX );
580 store_reg( R_EAX, 0 );
583 load_reg( R_EAX, Rm );
584 load_reg( R_ECX, Rn );
585 MEM_WRITE_LONG( R_ECX, R_EAX );
588 load_reg( R_EAX, Rm );
589 load_reg( R_ECX, Rn );
590 ADD_imm8s_r32( -4, R_ECX );
591 store_reg( R_ECX, Rn );
592 MEM_WRITE_LONG( R_ECX, R_EAX );
594 MOV.L Rm, @(R0, Rn) {:
595 load_reg( R_EAX, 0 );
596 load_reg( R_ECX, Rn );
597 ADD_r32_r32( R_EAX, R_ECX );
598 load_reg( R_EAX, Rm );
599 MEM_WRITE_LONG( R_ECX, R_EAX );
601 MOV.L R0, @(disp, GBR) {:
602 load_spreg( R_ECX, R_GBR );
603 load_reg( R_EAX, 0 );
604 ADD_imm32_r32( disp, R_ECX );
605 MEM_WRITE_LONG( R_ECX, R_EAX );
607 MOV.L Rm, @(disp, Rn) {:
608 load_reg( R_ECX, Rn );
609 load_reg( R_EAX, Rm );
610 ADD_imm32_r32( disp, R_ECX );
611 MEM_WRITE_LONG( R_ECX, R_EAX );
614 load_reg( R_ECX, Rm );
615 MEM_READ_LONG( R_ECX, R_EAX );
616 store_reg( R_EAX, Rn );
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_reg( R_EAX, Rn );
626 MOV.L @(R0, Rm), Rn {:
627 load_reg( R_EAX, 0 );
628 load_reg( R_ECX, Rm );
629 ADD_r32_r32( R_EAX, R_ECX );
630 MEM_READ_LONG( R_ECX, R_EAX );
631 store_reg( R_EAX, Rn );
633 MOV.L @(disp, GBR), R0 {:
634 load_spreg( R_ECX, R_GBR );
635 ADD_imm32_r32( disp, R_ECX );
636 MEM_READ_LONG( R_ECX, R_EAX );
637 store_reg( R_EAX, 0 );
639 MOV.L @(disp, PC), Rn {:
640 load_imm32( R_ECX, (pc & 0xFFFFFFFC) + disp + 4 );
641 MEM_READ_LONG( R_ECX, R_EAX );
642 store_reg( R_EAX, 0 );
644 MOV.L @(disp, Rm), Rn {:
645 load_reg( R_ECX, Rm );
646 ADD_imm8s_r32( disp, R_ECX );
647 MEM_READ_LONG( R_ECX, R_EAX );
648 store_reg( R_EAX, Rn );
651 load_reg( R_ECX, Rn );
652 MEM_READ_WORD( R_ECX, R_EAX );
653 store_reg( R_EAX, Rn );
656 load_reg( R_ECX, Rn );
657 load_reg( R_EAX, Rm );
658 ADD_imm8s_r32( -2, R_ECX );
659 MEM_WRITE_WORD( R_ECX, R_EAX );
661 MOV.W Rm, @(R0, Rn) {:
662 load_reg( R_EAX, 0 );
663 load_reg( R_ECX, Rn );
664 ADD_r32_r32( R_EAX, R_ECX );
665 load_reg( R_EAX, Rm );
666 MEM_WRITE_WORD( R_ECX, R_EAX );
668 MOV.W R0, @(disp, GBR) {:
669 load_spreg( R_ECX, R_GBR );
670 load_reg( R_EAX, 0 );
671 ADD_imm32_r32( disp, R_ECX );
672 MEM_WRITE_WORD( R_ECX, R_EAX );
674 MOV.W R0, @(disp, Rn) {:
675 load_reg( R_ECX, Rn );
676 load_reg( R_EAX, 0 );
677 ADD_imm32_r32( disp, R_ECX );
678 MEM_WRITE_WORD( R_ECX, R_EAX );
681 load_reg( R_ECX, Rm );
682 MEM_READ_WORD( R_ECX, R_EAX );
683 store_reg( R_EAX, Rn );
686 load_reg( R_EAX, Rm );
687 MOV_r32_r32( R_EAX, R_ECX );
688 ADD_imm8s_r32( 2, R_EAX );
689 store_reg( R_EAX, Rm );
690 MEM_READ_WORD( R_ECX, R_EAX );
691 store_reg( R_EAX, Rn );
693 MOV.W @(R0, Rm), Rn {:
694 load_reg( R_EAX, 0 );
695 load_reg( R_ECX, Rm );
696 ADD_r32_r32( R_EAX, R_ECX );
697 MEM_READ_WORD( R_ECX, R_EAX );
698 store_reg( R_EAX, Rn );
700 MOV.W @(disp, GBR), R0 {:
701 load_spreg( R_ECX, R_GBR );
702 ADD_imm32_r32( disp, R_ECX );
703 MEM_READ_WORD( R_ECX, R_EAX );
704 store_reg( R_EAX, 0 );
706 MOV.W @(disp, PC), Rn {:
707 load_imm32( R_ECX, pc + disp + 4 );
708 MEM_READ_WORD( R_ECX, R_EAX );
709 store_reg( R_EAX, Rn );
711 MOV.W @(disp, Rm), R0 {:
712 load_reg( R_ECX, Rm );
713 ADD_imm32_r32( disp, R_ECX );
714 MEM_READ_WORD( R_ECX, R_EAX );
715 store_reg( R_EAX, 0 );
717 MOVA @(disp, PC), R0 {:
718 load_imm32( R_ECX, (pc & 0xFFFFFFFC) + disp + 4 );
719 store_reg( R_ECX, 0 );
722 load_reg( R_EAX, 0 );
723 load_reg( R_ECX, Rn );
724 MEM_WRITE_LONG( R_ECX, R_EAX );
727 /* Control transfer instructions */
734 BT disp {: /* If true, result PC += 4 + disp. else result PC = pc+2 */
754 /* Floating point instructions */
757 FCMP/EQ FRm, FRn {: :}
758 FCMP/GT FRm, FRn {: :}
759 FCNVDS FRm, FPUL {: :}
760 FCNVSD FPUL, FRn {: :}
766 FLOAT FPUL, FRn {: :}
767 FMAC FR0, FRm, FRn {: :}
771 FMOV FRm, @(R0, Rn) {: :}
774 FMOV @(R0, Rm), FRn {: :}
785 FTRV XMTRX, FVn {: :}
787 /* Processor control instructions */
788 LDC Rm, SR {: /* We need to be a little careful about SR */ :}
790 load_reg( R_EAX, Rm );
791 store_spreg( R_EAX, R_GBR );
794 load_reg( R_EAX, Rm );
795 store_spreg( R_EAX, R_VBR );
798 load_reg( R_EAX, Rm );
799 store_spreg( R_EAX, R_SSR );
802 load_reg( R_EAX, Rm );
803 store_spreg( R_EAX, R_SGR );
806 load_reg( R_EAX, Rm );
807 store_spreg( R_EAX, R_SPC );
810 load_reg( R_EAX, Rm );
811 store_spreg( R_EAX, R_DBR );
813 LDC Rm, Rn_BANK {: :}
815 load_reg( R_EAX, Rm );
816 MOV_r32_r32( R_EAX, R_ECX );
817 ADD_imm8s_r32( 4, R_EAX );
818 store_reg( R_EAX, Rm );
819 MEM_READ_LONG( R_ECX, R_EAX );
820 store_spreg( R_EAX, R_GBR );
825 load_reg( R_EAX, Rm );
826 MOV_r32_r32( R_EAX, R_ECX );
827 ADD_imm8s_r32( 4, R_EAX );
828 store_reg( R_EAX, Rm );
829 MEM_READ_LONG( R_ECX, R_EAX );
830 store_spreg( R_EAX, R_VBR );
833 load_reg( R_EAX, Rm );
834 MOV_r32_r32( R_EAX, R_ECX );
835 ADD_imm8s_r32( 4, R_EAX );
836 store_reg( R_EAX, Rm );
837 MEM_READ_LONG( R_ECX, R_EAX );
838 store_spreg( R_EAX, R_SSR );
841 load_reg( R_EAX, Rm );
842 MOV_r32_r32( R_EAX, R_ECX );
843 ADD_imm8s_r32( 4, R_EAX );
844 store_reg( R_EAX, Rm );
845 MEM_READ_LONG( R_ECX, R_EAX );
846 store_spreg( R_EAX, R_SGR );
849 load_reg( R_EAX, Rm );
850 MOV_r32_r32( R_EAX, R_ECX );
851 ADD_imm8s_r32( 4, R_EAX );
852 store_reg( R_EAX, Rm );
853 MEM_READ_LONG( R_ECX, R_EAX );
854 store_spreg( R_EAX, R_SPC );
857 load_reg( R_EAX, Rm );
858 MOV_r32_r32( R_EAX, R_ECX );
859 ADD_imm8s_r32( 4, R_EAX );
860 store_reg( R_EAX, Rm );
861 MEM_READ_LONG( R_ECX, R_EAX );
862 store_spreg( R_EAX, R_DBR );
864 LDC.L @Rm+, Rn_BANK {:
867 load_reg( R_EAX, Rm );
868 store_spreg( R_EAX, R_FPSCR );
871 load_reg( R_EAX, Rm );
872 MOV_r32_r32( R_EAX, R_ECX );
873 ADD_imm8s_r32( 4, R_EAX );
874 store_reg( R_EAX, Rm );
875 MEM_READ_LONG( R_ECX, R_EAX );
876 store_spreg( R_EAX, R_FPSCR );
879 load_reg( R_EAX, Rm );
880 store_spreg( R_EAX, R_FPUL );
883 load_reg( R_EAX, Rm );
884 MOV_r32_r32( R_EAX, R_ECX );
885 ADD_imm8s_r32( 4, R_EAX );
886 store_reg( R_EAX, Rm );
887 MEM_READ_LONG( R_ECX, R_EAX );
888 store_spreg( R_EAX, R_FPUL );
891 load_reg( R_EAX, Rm );
892 store_spreg( R_EAX, R_MACH );
895 load_reg( R_EAX, Rm );
896 MOV_r32_r32( R_EAX, R_ECX );
897 ADD_imm8s_r32( 4, R_EAX );
898 store_reg( R_EAX, Rm );
899 MEM_READ_LONG( R_ECX, R_EAX );
900 store_spreg( R_EAX, R_MACH );
903 load_reg( R_EAX, Rm );
904 store_spreg( R_EAX, R_MACL );
907 load_reg( R_EAX, Rm );
908 MOV_r32_r32( R_EAX, R_ECX );
909 ADD_imm8s_r32( 4, R_EAX );
910 store_reg( R_EAX, Rm );
911 MEM_READ_LONG( R_ECX, R_EAX );
912 store_spreg( R_EAX, R_MACL );
915 load_reg( R_EAX, Rm );
916 store_spreg( R_EAX, R_PR );
919 load_reg( R_EAX, Rm );
920 MOV_r32_r32( R_EAX, R_ECX );
921 ADD_imm8s_r32( 4, R_EAX );
922 store_reg( R_EAX, Rm );
923 MEM_READ_LONG( R_ECX, R_EAX );
924 store_spreg( R_EAX, R_PR );
932 STC SR, Rn {: /* TODO */
935 load_spreg( R_EAX, R_GBR );
936 store_reg( R_EAX, Rn );
939 load_spreg( R_EAX, R_VBR );
940 store_reg( R_EAX, Rn );
943 load_spreg( R_EAX, R_SSR );
944 store_reg( R_EAX, Rn );
947 load_spreg( R_EAX, R_SPC );
948 store_reg( R_EAX, Rn );
951 load_spreg( R_EAX, R_SGR );
952 store_reg( R_EAX, Rn );
955 load_spreg( R_EAX, R_DBR );
956 store_reg( R_EAX, Rn );
958 STC Rm_BANK, Rn {: /* TODO */
960 STC.L SR, @-Rn {: /* TODO */
963 load_reg( R_ECX, Rn );
964 ADD_imm8s_r32( -4, Rn );
965 store_reg( R_ECX, Rn );
966 load_spreg( R_EAX, R_VBR );
967 MEM_WRITE_LONG( R_ECX, R_EAX );
970 load_reg( R_ECX, Rn );
971 ADD_imm8s_r32( -4, Rn );
972 store_reg( R_ECX, Rn );
973 load_spreg( R_EAX, R_SSR );
974 MEM_WRITE_LONG( R_ECX, R_EAX );
977 load_reg( R_ECX, Rn );
978 ADD_imm8s_r32( -4, Rn );
979 store_reg( R_ECX, Rn );
980 load_spreg( R_EAX, R_SPC );
981 MEM_WRITE_LONG( R_ECX, R_EAX );
984 load_reg( R_ECX, Rn );
985 ADD_imm8s_r32( -4, Rn );
986 store_reg( R_ECX, Rn );
987 load_spreg( R_EAX, R_SGR );
988 MEM_WRITE_LONG( R_ECX, R_EAX );
991 load_reg( R_ECX, Rn );
992 ADD_imm8s_r32( -4, Rn );
993 store_reg( R_ECX, Rn );
994 load_spreg( R_EAX, R_DBR );
995 MEM_WRITE_LONG( R_ECX, R_EAX );
997 STC.L Rm_BANK, @-Rn {: :}
999 load_reg( R_ECX, Rn );
1000 ADD_imm8s_r32( -4, Rn );
1001 store_reg( R_ECX, Rn );
1002 load_spreg( R_EAX, R_GBR );
1003 MEM_WRITE_LONG( R_ECX, R_EAX );
1006 load_spreg( R_EAX, R_FPSCR );
1007 store_reg( R_EAX, Rn );
1009 STS.L FPSCR, @-Rn {:
1010 load_reg( R_ECX, Rn );
1011 ADD_imm8s_r32( -4, Rn );
1012 store_reg( R_ECX, Rn );
1013 load_spreg( R_EAX, R_FPSCR );
1014 MEM_WRITE_LONG( R_ECX, R_EAX );
1017 load_spreg( R_EAX, R_FPUL );
1018 store_reg( R_EAX, Rn );
1021 load_reg( R_ECX, Rn );
1022 ADD_imm8s_r32( -4, Rn );
1023 store_reg( R_ECX, Rn );
1024 load_spreg( R_EAX, R_FPUL );
1025 MEM_WRITE_LONG( R_ECX, R_EAX );
1028 load_spreg( R_EAX, R_MACH );
1029 store_reg( R_EAX, Rn );
1032 load_reg( R_ECX, Rn );
1033 ADD_imm8s_r32( -4, Rn );
1034 store_reg( R_ECX, Rn );
1035 load_spreg( R_EAX, R_MACH );
1036 MEM_WRITE_LONG( R_ECX, R_EAX );
1039 load_spreg( R_EAX, R_MACL );
1040 store_reg( R_EAX, Rn );
1043 load_reg( R_ECX, Rn );
1044 ADD_imm8s_r32( -4, Rn );
1045 store_reg( R_ECX, Rn );
1046 load_spreg( R_EAX, R_MACL );
1047 MEM_WRITE_LONG( R_ECX, R_EAX );
1050 load_spreg( R_EAX, R_PR );
1051 store_reg( R_EAX, Rn );
1054 load_reg( R_ECX, Rn );
1055 ADD_imm8s_r32( -4, Rn );
1056 store_reg( R_ECX, Rn );
1057 load_spreg( R_EAX, R_PR );
1058 MEM_WRITE_LONG( R_ECX, R_EAX );
1061 NOP {: /* Do nothing. Well, we could emit an 0x90, but what would really be the point? */ :}
.