Search
lxdream.org :: lxdream/src/sh4/sh4x86.in
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4x86.in
changeset 359:c588dce7ebde
next361:be3de4ecd954
author nkeynes
date Thu Aug 23 12:33:27 2007 +0000 (12 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 }
.