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