nkeynes@359 | 1 | /**
|
nkeynes@368 | 2 | * $Id: sh4x86.in,v 1.3 2007-09-04 08:40:23 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@368 | 21 | #include <assert.h>
|
nkeynes@368 | 22 |
|
nkeynes@368 | 23 | #include "sh4/sh4core.h"
|
nkeynes@368 | 24 | #include "sh4/sh4trans.h"
|
nkeynes@368 | 25 | #include "sh4/x86op.h"
|
nkeynes@368 | 26 | #include "clock.h"
|
nkeynes@368 | 27 |
|
nkeynes@368 | 28 | #define DEFAULT_BACKPATCH_SIZE 4096
|
nkeynes@368 | 29 |
|
nkeynes@368 | 30 | /**
|
nkeynes@368 | 31 | * Struct to manage internal translation state. This state is not saved -
|
nkeynes@368 | 32 | * it is only valid between calls to sh4_translate_begin_block() and
|
nkeynes@368 | 33 | * sh4_translate_end_block()
|
nkeynes@368 | 34 | */
|
nkeynes@368 | 35 | struct sh4_x86_state {
|
nkeynes@368 | 36 | gboolean in_delay_slot;
|
nkeynes@368 | 37 | gboolean priv_checked; /* true if we've already checked the cpu mode. */
|
nkeynes@368 | 38 | gboolean fpuen_checked; /* true if we've already checked fpu enabled. */
|
nkeynes@368 | 39 |
|
nkeynes@368 | 40 | /* Allocated memory for the (block-wide) back-patch list */
|
nkeynes@368 | 41 | uint32_t **backpatch_list;
|
nkeynes@368 | 42 | uint32_t backpatch_posn;
|
nkeynes@368 | 43 | uint32_t backpatch_size;
|
nkeynes@368 | 44 | };
|
nkeynes@368 | 45 |
|
nkeynes@368 | 46 | #define EXIT_DATA_ADDR_READ 0
|
nkeynes@368 | 47 | #define EXIT_DATA_ADDR_WRITE 7
|
nkeynes@368 | 48 | #define EXIT_ILLEGAL 14
|
nkeynes@368 | 49 | #define EXIT_SLOT_ILLEGAL 21
|
nkeynes@368 | 50 | #define EXIT_FPU_DISABLED 28
|
nkeynes@368 | 51 | #define EXIT_SLOT_FPU_DISABLED 35
|
nkeynes@368 | 52 |
|
nkeynes@368 | 53 | static struct sh4_x86_state sh4_x86;
|
nkeynes@368 | 54 |
|
nkeynes@368 | 55 | void sh4_x86_init()
|
nkeynes@368 | 56 | {
|
nkeynes@368 | 57 | sh4_x86.backpatch_list = malloc(DEFAULT_BACKPATCH_SIZE);
|
nkeynes@368 | 58 | sh4_x86.backpatch_size = DEFAULT_BACKPATCH_SIZE / sizeof(uint32_t *);
|
nkeynes@368 | 59 | }
|
nkeynes@368 | 60 |
|
nkeynes@368 | 61 |
|
nkeynes@368 | 62 | static void sh4_x86_add_backpatch( uint8_t *ptr )
|
nkeynes@368 | 63 | {
|
nkeynes@368 | 64 | if( sh4_x86.backpatch_posn == sh4_x86.backpatch_size ) {
|
nkeynes@368 | 65 | sh4_x86.backpatch_size <<= 1;
|
nkeynes@368 | 66 | sh4_x86.backpatch_list = realloc( sh4_x86.backpatch_list, sh4_x86.backpatch_size * sizeof(uint32_t *) );
|
nkeynes@368 | 67 | assert( sh4_x86.backpatch_list != NULL );
|
nkeynes@368 | 68 | }
|
nkeynes@368 | 69 | sh4_x86.backpatch_list[sh4_x86.backpatch_posn++] = (uint32_t *)ptr;
|
nkeynes@368 | 70 | }
|
nkeynes@368 | 71 |
|
nkeynes@368 | 72 | static void sh4_x86_do_backpatch( uint8_t *reloc_base )
|
nkeynes@368 | 73 | {
|
nkeynes@368 | 74 | unsigned int i;
|
nkeynes@368 | 75 | for( i=0; i<sh4_x86.backpatch_posn; i++ ) {
|
nkeynes@368 | 76 | *sh4_x86.backpatch_list[i] += (reloc_base - ((uint8_t *)sh4_x86.backpatch_list[i]));
|
nkeynes@368 | 77 | }
|
nkeynes@368 | 78 | }
|
nkeynes@368 | 79 |
|
nkeynes@368 | 80 | #ifndef NDEBUG
|
nkeynes@368 | 81 | #define MARK_JMP(x,n) uint8_t *_mark_jmp_##x = xlat_output + n
|
nkeynes@368 | 82 | #define CHECK_JMP(x) assert( _mark_jmp_##x == xlat_output )
|
nkeynes@368 | 83 | #else
|
nkeynes@368 | 84 | #define MARK_JMP(x,n)
|
nkeynes@368 | 85 | #define CHECK_JMP(x)
|
nkeynes@368 | 86 | #endif
|
nkeynes@368 | 87 |
|
nkeynes@359 | 88 |
|
nkeynes@359 | 89 | /**
|
nkeynes@359 | 90 | * Emit an instruction to load an SH4 reg into a real register
|
nkeynes@359 | 91 | */
|
nkeynes@359 | 92 | static inline void load_reg( int x86reg, int sh4reg )
|
nkeynes@359 | 93 | {
|
nkeynes@359 | 94 | /* mov [bp+n], reg */
|
nkeynes@361 | 95 | OP(0x8B);
|
nkeynes@361 | 96 | OP(0x45 + (x86reg<<3));
|
nkeynes@359 | 97 | OP(REG_OFFSET(r[sh4reg]));
|
nkeynes@359 | 98 | }
|
nkeynes@359 | 99 |
|
nkeynes@368 | 100 | /**
|
nkeynes@368 | 101 | * Load the SR register into an x86 register
|
nkeynes@368 | 102 | */
|
nkeynes@368 | 103 | static inline void read_sr( int x86reg )
|
nkeynes@368 | 104 | {
|
nkeynes@368 | 105 | MOV_ebp_r32( R_M, x86reg );
|
nkeynes@368 | 106 | SHL1_r32( x86reg );
|
nkeynes@368 | 107 | OR_ebp_r32( R_Q, x86reg );
|
nkeynes@368 | 108 | SHL_imm8_r32( 7, x86reg );
|
nkeynes@368 | 109 | OR_ebp_r32( R_S, x86reg );
|
nkeynes@368 | 110 | SHL1_r32( x86reg );
|
nkeynes@368 | 111 | OR_ebp_r32( R_T, x86reg );
|
nkeynes@368 | 112 | OR_ebp_r32( R_SR, x86reg );
|
nkeynes@368 | 113 | }
|
nkeynes@368 | 114 |
|
nkeynes@368 | 115 | static inline void write_sr( int x86reg )
|
nkeynes@368 | 116 | {
|
nkeynes@368 | 117 | TEST_imm32_r32( SR_M, x86reg );
|
nkeynes@368 | 118 | SETNE_ebp(R_M);
|
nkeynes@368 | 119 | TEST_imm32_r32( SR_Q, x86reg );
|
nkeynes@368 | 120 | SETNE_ebp(R_Q);
|
nkeynes@368 | 121 | TEST_imm32_r32( SR_S, x86reg );
|
nkeynes@368 | 122 | SETNE_ebp(R_S);
|
nkeynes@368 | 123 | TEST_imm32_r32( SR_T, x86reg );
|
nkeynes@368 | 124 | SETNE_ebp(R_T);
|
nkeynes@368 | 125 | AND_imm32_r32( SR_MQSTMASK, x86reg );
|
nkeynes@368 | 126 | MOV_r32_ebp( x86reg, R_SR );
|
nkeynes@368 | 127 | }
|
nkeynes@368 | 128 |
|
nkeynes@368 | 129 |
|
nkeynes@359 | 130 | static inline void load_spreg( int x86reg, int regoffset )
|
nkeynes@359 | 131 | {
|
nkeynes@359 | 132 | /* mov [bp+n], reg */
|
nkeynes@361 | 133 | OP(0x8B);
|
nkeynes@361 | 134 | OP(0x45 + (x86reg<<3));
|
nkeynes@359 | 135 | OP(regoffset);
|
nkeynes@359 | 136 | }
|
nkeynes@359 | 137 |
|
nkeynes@359 | 138 | /**
|
nkeynes@359 | 139 | * Emit an instruction to load an immediate value into a register
|
nkeynes@359 | 140 | */
|
nkeynes@359 | 141 | static inline void load_imm32( int x86reg, uint32_t value ) {
|
nkeynes@359 | 142 | /* mov #value, reg */
|
nkeynes@359 | 143 | OP(0xB8 + x86reg);
|
nkeynes@359 | 144 | OP32(value);
|
nkeynes@359 | 145 | }
|
nkeynes@359 | 146 |
|
nkeynes@359 | 147 | /**
|
nkeynes@359 | 148 | * Emit an instruction to store an SH4 reg (RN)
|
nkeynes@359 | 149 | */
|
nkeynes@359 | 150 | void static inline store_reg( int x86reg, int sh4reg ) {
|
nkeynes@359 | 151 | /* mov reg, [bp+n] */
|
nkeynes@361 | 152 | OP(0x89);
|
nkeynes@361 | 153 | OP(0x45 + (x86reg<<3));
|
nkeynes@359 | 154 | OP(REG_OFFSET(r[sh4reg]));
|
nkeynes@359 | 155 | }
|
nkeynes@359 | 156 | void static inline store_spreg( int x86reg, int regoffset ) {
|
nkeynes@359 | 157 | /* mov reg, [bp+n] */
|
nkeynes@361 | 158 | OP(0x89);
|
nkeynes@361 | 159 | OP(0x45 + (x86reg<<3));
|
nkeynes@359 | 160 | OP(regoffset);
|
nkeynes@359 | 161 | }
|
nkeynes@359 | 162 |
|
nkeynes@361 | 163 | /**
|
nkeynes@361 | 164 | * Note: clobbers EAX to make the indirect call - this isn't usually
|
nkeynes@361 | 165 | * a problem since the callee will usually clobber it anyway.
|
nkeynes@361 | 166 | */
|
nkeynes@361 | 167 | static inline void call_func0( void *ptr )
|
nkeynes@361 | 168 | {
|
nkeynes@361 | 169 | load_imm32(R_EAX, (uint32_t)ptr);
|
nkeynes@368 | 170 | CALL_r32(R_EAX);
|
nkeynes@361 | 171 | }
|
nkeynes@361 | 172 |
|
nkeynes@361 | 173 | static inline void call_func1( void *ptr, int arg1 )
|
nkeynes@361 | 174 | {
|
nkeynes@361 | 175 | PUSH_r32(arg1);
|
nkeynes@361 | 176 | call_func0(ptr);
|
nkeynes@361 | 177 | ADD_imm8s_r32( -4, R_ESP );
|
nkeynes@361 | 178 | }
|
nkeynes@361 | 179 |
|
nkeynes@361 | 180 | static inline void call_func2( void *ptr, int arg1, int arg2 )
|
nkeynes@361 | 181 | {
|
nkeynes@361 | 182 | PUSH_r32(arg2);
|
nkeynes@361 | 183 | PUSH_r32(arg1);
|
nkeynes@361 | 184 | call_func0(ptr);
|
nkeynes@361 | 185 | ADD_imm8s_r32( -4, R_ESP );
|
nkeynes@361 | 186 | }
|
nkeynes@361 | 187 |
|
nkeynes@368 | 188 | /* Exception checks - Note that all exception checks will clobber EAX */
|
nkeynes@368 | 189 | static void check_priv( )
|
nkeynes@368 | 190 | {
|
nkeynes@368 | 191 | if( !sh4_x86.priv_checked ) {
|
nkeynes@368 | 192 | sh4_x86.priv_checked = TRUE;
|
nkeynes@368 | 193 | load_spreg( R_EAX, R_SR );
|
nkeynes@368 | 194 | AND_imm32_r32( SR_MD, R_EAX );
|
nkeynes@368 | 195 | if( sh4_x86.in_delay_slot ) {
|
nkeynes@368 | 196 | JE_exit( EXIT_SLOT_ILLEGAL );
|
nkeynes@368 | 197 | } else {
|
nkeynes@368 | 198 | JE_exit( EXIT_ILLEGAL );
|
nkeynes@368 | 199 | }
|
nkeynes@368 | 200 | }
|
nkeynes@368 | 201 | }
|
nkeynes@368 | 202 |
|
nkeynes@368 | 203 | static void check_fpuen( )
|
nkeynes@368 | 204 | {
|
nkeynes@368 | 205 | if( !sh4_x86.fpuen_checked ) {
|
nkeynes@368 | 206 | sh4_x86.fpuen_checked = TRUE;
|
nkeynes@368 | 207 | load_spreg( R_EAX, R_SR );
|
nkeynes@368 | 208 | AND_imm32_r32( SR_FD, R_EAX );
|
nkeynes@368 | 209 | if( sh4_x86.in_delay_slot ) {
|
nkeynes@368 | 210 | JNE_exit(EXIT_SLOT_FPU_DISABLED);
|
nkeynes@368 | 211 | } else {
|
nkeynes@368 | 212 | JNE_exit(EXIT_FPU_DISABLED);
|
nkeynes@368 | 213 | }
|
nkeynes@368 | 214 | }
|
nkeynes@368 | 215 | }
|
nkeynes@368 | 216 |
|
nkeynes@368 | 217 | static void check_ralign16( int x86reg )
|
nkeynes@368 | 218 | {
|
nkeynes@368 | 219 | TEST_imm32_r32( 0x00000001, x86reg );
|
nkeynes@368 | 220 | JNE_exit(EXIT_DATA_ADDR_READ);
|
nkeynes@368 | 221 | }
|
nkeynes@368 | 222 |
|
nkeynes@368 | 223 | static void check_walign16( int x86reg )
|
nkeynes@368 | 224 | {
|
nkeynes@368 | 225 | TEST_imm32_r32( 0x00000001, x86reg );
|
nkeynes@368 | 226 | JNE_exit(EXIT_DATA_ADDR_WRITE);
|
nkeynes@368 | 227 | }
|
nkeynes@368 | 228 |
|
nkeynes@368 | 229 | static void check_ralign32( int x86reg )
|
nkeynes@368 | 230 | {
|
nkeynes@368 | 231 | TEST_imm32_r32( 0x00000003, x86reg );
|
nkeynes@368 | 232 | JNE_exit(EXIT_DATA_ADDR_READ);
|
nkeynes@368 | 233 | }
|
nkeynes@368 | 234 | static void check_walign32( int x86reg )
|
nkeynes@368 | 235 | {
|
nkeynes@368 | 236 | TEST_imm32_r32( 0x00000003, x86reg );
|
nkeynes@368 | 237 | JNE_exit(EXIT_DATA_ADDR_WRITE);
|
nkeynes@368 | 238 | }
|
nkeynes@368 | 239 |
|
nkeynes@368 | 240 |
|
nkeynes@361 | 241 | #define UNDEF()
|
nkeynes@361 | 242 | #define MEM_RESULT(value_reg) if(value_reg != R_EAX) { MOV_r32_r32(R_EAX,value_reg); }
|
nkeynes@361 | 243 | #define MEM_READ_BYTE( addr_reg, value_reg ) call_func1(sh4_read_byte, addr_reg ); MEM_RESULT(value_reg)
|
nkeynes@361 | 244 | #define MEM_READ_WORD( addr_reg, value_reg ) call_func1(sh4_read_word, addr_reg ); MEM_RESULT(value_reg)
|
nkeynes@361 | 245 | #define MEM_READ_LONG( addr_reg, value_reg ) call_func1(sh4_read_long, addr_reg ); MEM_RESULT(value_reg)
|
nkeynes@361 | 246 | #define MEM_WRITE_BYTE( addr_reg, value_reg ) call_func2(sh4_write_byte, addr_reg, value_reg)
|
nkeynes@361 | 247 | #define MEM_WRITE_WORD( addr_reg, value_reg ) call_func2(sh4_write_word, addr_reg, value_reg)
|
nkeynes@361 | 248 | #define MEM_WRITE_LONG( addr_reg, value_reg ) call_func2(sh4_write_long, addr_reg, value_reg)
|
nkeynes@361 | 249 |
|
nkeynes@368 | 250 | #define RAISE_EXCEPTION( exc ) call_func1(sh4_raise_exception, exc);
|
nkeynes@368 | 251 | #define CHECKSLOTILLEGAL() if(sh4_x86.in_delay_slot) RAISE_EXCEPTION(EXC_SLOT_ILLEGAL)
|
nkeynes@368 | 252 |
|
nkeynes@368 | 253 |
|
nkeynes@359 | 254 |
|
nkeynes@359 | 255 | /**
|
nkeynes@359 | 256 | * Emit the 'start of block' assembly. Sets up the stack frame and save
|
nkeynes@359 | 257 | * SI/DI as required
|
nkeynes@359 | 258 | */
|
nkeynes@368 | 259 | void sh4_translate_begin_block()
|
nkeynes@368 | 260 | {
|
nkeynes@368 | 261 | PUSH_r32(R_EBP);
|
nkeynes@368 | 262 | PUSH_r32(R_ESI);
|
nkeynes@359 | 263 | /* mov &sh4r, ebp */
|
nkeynes@359 | 264 | load_imm32( R_EBP, (uint32_t)&sh4r );
|
nkeynes@368 | 265 | PUSH_r32(R_ESI);
|
nkeynes@368 | 266 |
|
nkeynes@368 | 267 | sh4_x86.in_delay_slot = FALSE;
|
nkeynes@368 | 268 | sh4_x86.priv_checked = FALSE;
|
nkeynes@368 | 269 | sh4_x86.fpuen_checked = FALSE;
|
nkeynes@368 | 270 | sh4_x86.backpatch_posn = 0;
|
nkeynes@368 | 271 | }
|
nkeynes@359 | 272 |
|
nkeynes@368 | 273 | /**
|
nkeynes@368 | 274 | * Exit the block early (ie branch out), conditionally or otherwise
|
nkeynes@368 | 275 | */
|
nkeynes@368 | 276 | void exit_block( uint32_t pc )
|
nkeynes@368 | 277 | {
|
nkeynes@368 | 278 | load_imm32( R_ECX, pc );
|
nkeynes@368 | 279 | store_spreg( R_ECX, REG_OFFSET(pc) );
|
nkeynes@368 | 280 | MOV_moff32_EAX( (uint32_t)&sh4_cpu_period );
|
nkeynes@368 | 281 | load_spreg( R_ECX, REG_OFFSET(slice_cycle) );
|
nkeynes@368 | 282 | MUL_r32( R_ESI );
|
nkeynes@368 | 283 | ADD_r32_r32( R_EAX, R_ECX );
|
nkeynes@368 | 284 | store_spreg( R_ECX, REG_OFFSET(slice_cycle) );
|
nkeynes@368 | 285 | XOR_r32_r32( R_EAX, R_EAX );
|
nkeynes@368 | 286 | RET();
|
nkeynes@359 | 287 | }
|
nkeynes@359 | 288 |
|
nkeynes@359 | 289 | /**
|
nkeynes@359 | 290 | * Flush any open regs back to memory, restore SI/DI/, update PC, etc
|
nkeynes@359 | 291 | */
|
nkeynes@359 | 292 | void sh4_translate_end_block( sh4addr_t pc ) {
|
nkeynes@368 | 293 | assert( !sh4_x86.in_delay_slot ); // should never stop here
|
nkeynes@368 | 294 | // Normal termination - save PC, cycle count
|
nkeynes@368 | 295 | exit_block( pc );
|
nkeynes@359 | 296 |
|
nkeynes@368 | 297 | uint8_t *end_ptr = xlat_output;
|
nkeynes@368 | 298 | // Exception termination. Jump block for various exception codes:
|
nkeynes@368 | 299 | PUSH_imm32( EXC_DATA_ADDR_READ );
|
nkeynes@368 | 300 | JMP_rel8( 33 );
|
nkeynes@368 | 301 | PUSH_imm32( EXC_DATA_ADDR_WRITE );
|
nkeynes@368 | 302 | JMP_rel8( 26 );
|
nkeynes@368 | 303 | PUSH_imm32( EXC_ILLEGAL );
|
nkeynes@368 | 304 | JMP_rel8( 19 );
|
nkeynes@368 | 305 | PUSH_imm32( EXC_SLOT_ILLEGAL );
|
nkeynes@368 | 306 | JMP_rel8( 12 );
|
nkeynes@368 | 307 | PUSH_imm32( EXC_FPU_DISABLED );
|
nkeynes@368 | 308 | JMP_rel8( 5 );
|
nkeynes@368 | 309 | PUSH_imm32( EXC_SLOT_FPU_DISABLED );
|
nkeynes@368 | 310 | // target
|
nkeynes@368 | 311 | load_spreg( R_ECX, REG_OFFSET(pc) );
|
nkeynes@368 | 312 | ADD_r32_r32( R_ESI, R_ECX );
|
nkeynes@368 | 313 | ADD_r32_r32( R_ESI, R_ECX );
|
nkeynes@368 | 314 | store_spreg( R_ECX, REG_OFFSET(pc) );
|
nkeynes@368 | 315 | MOV_moff32_EAX( (uint32_t)&sh4_cpu_period );
|
nkeynes@368 | 316 | load_spreg( R_ECX, REG_OFFSET(slice_cycle) );
|
nkeynes@368 | 317 | MUL_r32( R_ESI );
|
nkeynes@368 | 318 | ADD_r32_r32( R_EAX, R_ECX );
|
nkeynes@368 | 319 | store_spreg( R_ECX, REG_OFFSET(slice_cycle) );
|
nkeynes@368 | 320 |
|
nkeynes@368 | 321 | load_imm32( R_EAX, (uint32_t)sh4_raise_exception ); // 6
|
nkeynes@368 | 322 | CALL_r32( R_EAX ); // 2
|
nkeynes@368 | 323 | POP_r32(R_EBP);
|
nkeynes@368 | 324 | RET();
|
nkeynes@368 | 325 |
|
nkeynes@368 | 326 | sh4_x86_do_backpatch( end_ptr );
|
nkeynes@359 | 327 | }
|
nkeynes@359 | 328 |
|
nkeynes@359 | 329 | /**
|
nkeynes@359 | 330 | * Translate a single instruction. Delayed branches are handled specially
|
nkeynes@359 | 331 | * by translating both branch and delayed instruction as a single unit (as
|
nkeynes@359 | 332 | *
|
nkeynes@359 | 333 | *
|
nkeynes@359 | 334 | * @return true if the instruction marks the end of a basic block
|
nkeynes@359 | 335 | * (eg a branch or
|
nkeynes@359 | 336 | */
|
nkeynes@359 | 337 | uint32_t sh4_x86_translate_instruction( uint32_t pc )
|
nkeynes@359 | 338 | {
|
nkeynes@361 | 339 | uint16_t ir = sh4_read_word( pc );
|
nkeynes@368 | 340 |
|
nkeynes@359 | 341 | %%
|
nkeynes@359 | 342 | /* ALU operations */
|
nkeynes@359 | 343 | ADD Rm, Rn {:
|
nkeynes@359 | 344 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 345 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 346 | ADD_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 347 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 348 | :}
|
nkeynes@359 | 349 | ADD #imm, Rn {:
|
nkeynes@359 | 350 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 351 | ADD_imm8s_r32( imm, R_EAX );
|
nkeynes@359 | 352 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 353 | :}
|
nkeynes@359 | 354 | ADDC Rm, Rn {:
|
nkeynes@359 | 355 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 356 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 357 | LDC_t();
|
nkeynes@359 | 358 | ADC_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 359 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 360 | SETC_t();
|
nkeynes@359 | 361 | :}
|
nkeynes@359 | 362 | ADDV Rm, Rn {:
|
nkeynes@359 | 363 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 364 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 365 | ADD_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 | AND Rm, Rn {:
|
nkeynes@359 | 370 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 371 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 372 | AND_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 373 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 374 | :}
|
nkeynes@359 | 375 | AND #imm, R0 {:
|
nkeynes@359 | 376 | load_reg( R_EAX, 0 );
|
nkeynes@359 | 377 | AND_imm32_r32(imm, R_EAX);
|
nkeynes@359 | 378 | store_reg( R_EAX, 0 );
|
nkeynes@359 | 379 | :}
|
nkeynes@359 | 380 | AND.B #imm, @(R0, GBR) {:
|
nkeynes@359 | 381 | load_reg( R_EAX, 0 );
|
nkeynes@359 | 382 | load_spreg( R_ECX, R_GBR );
|
nkeynes@359 | 383 | ADD_r32_r32( R_EAX, R_EBX );
|
nkeynes@359 | 384 | MEM_READ_BYTE( R_ECX, R_EAX );
|
nkeynes@359 | 385 | AND_imm32_r32(imm, R_ECX );
|
nkeynes@359 | 386 | MEM_WRITE_BYTE( R_ECX, R_EAX );
|
nkeynes@359 | 387 | :}
|
nkeynes@359 | 388 | CMP/EQ Rm, Rn {:
|
nkeynes@359 | 389 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 390 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 391 | CMP_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 392 | SETE_t();
|
nkeynes@359 | 393 | :}
|
nkeynes@359 | 394 | CMP/EQ #imm, R0 {:
|
nkeynes@359 | 395 | load_reg( R_EAX, 0 );
|
nkeynes@359 | 396 | CMP_imm8s_r32(imm, R_EAX);
|
nkeynes@359 | 397 | SETE_t();
|
nkeynes@359 | 398 | :}
|
nkeynes@359 | 399 | CMP/GE Rm, Rn {:
|
nkeynes@359 | 400 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 401 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 402 | CMP_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 403 | SETGE_t();
|
nkeynes@359 | 404 | :}
|
nkeynes@359 | 405 | CMP/GT Rm, Rn {:
|
nkeynes@359 | 406 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 407 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 408 | CMP_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 409 | SETG_t();
|
nkeynes@359 | 410 | :}
|
nkeynes@359 | 411 | CMP/HI Rm, Rn {:
|
nkeynes@359 | 412 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 413 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 414 | CMP_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 415 | SETA_t();
|
nkeynes@359 | 416 | :}
|
nkeynes@359 | 417 | CMP/HS Rm, Rn {:
|
nkeynes@359 | 418 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 419 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 420 | CMP_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 421 | SETAE_t();
|
nkeynes@359 | 422 | :}
|
nkeynes@359 | 423 | CMP/PL Rn {:
|
nkeynes@359 | 424 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 425 | CMP_imm8s_r32( 0, R_EAX );
|
nkeynes@359 | 426 | SETG_t();
|
nkeynes@359 | 427 | :}
|
nkeynes@359 | 428 | CMP/PZ Rn {:
|
nkeynes@359 | 429 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 430 | CMP_imm8s_r32( 0, R_EAX );
|
nkeynes@359 | 431 | SETGE_t();
|
nkeynes@359 | 432 | :}
|
nkeynes@361 | 433 | CMP/STR Rm, Rn {:
|
nkeynes@368 | 434 | load_reg( R_EAX, Rm );
|
nkeynes@368 | 435 | load_reg( R_ECX, Rn );
|
nkeynes@368 | 436 | XOR_r32_r32( R_ECX, R_EAX );
|
nkeynes@368 | 437 | TEST_r8_r8( R_AL, R_AL );
|
nkeynes@368 | 438 | JE_rel8(13);
|
nkeynes@368 | 439 | TEST_r8_r8( R_AH, R_AH ); // 2
|
nkeynes@368 | 440 | JE_rel8(9);
|
nkeynes@368 | 441 | SHR_imm8_r32( 16, R_EAX ); // 3
|
nkeynes@368 | 442 | TEST_r8_r8( R_AL, R_AL ); // 2
|
nkeynes@368 | 443 | JE_rel8(2);
|
nkeynes@368 | 444 | TEST_r8_r8( R_AH, R_AH ); // 2
|
nkeynes@368 | 445 | SETE_t();
|
nkeynes@361 | 446 | :}
|
nkeynes@361 | 447 | DIV0S Rm, Rn {:
|
nkeynes@361 | 448 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 449 | load_reg( R_ECX, Rm );
|
nkeynes@361 | 450 | SHR_imm8_r32( 31, R_EAX );
|
nkeynes@361 | 451 | SHR_imm8_r32( 31, R_ECX );
|
nkeynes@361 | 452 | store_spreg( R_EAX, R_M );
|
nkeynes@361 | 453 | store_spreg( R_ECX, R_Q );
|
nkeynes@361 | 454 | CMP_r32_r32( R_EAX, R_ECX );
|
nkeynes@361 | 455 | SETE_t();
|
nkeynes@361 | 456 | :}
|
nkeynes@361 | 457 | DIV0U {:
|
nkeynes@361 | 458 | XOR_r32_r32( R_EAX, R_EAX );
|
nkeynes@361 | 459 | store_spreg( R_EAX, R_Q );
|
nkeynes@361 | 460 | store_spreg( R_EAX, R_M );
|
nkeynes@361 | 461 | store_spreg( R_EAX, R_T );
|
nkeynes@361 | 462 | :}
|
nkeynes@359 | 463 | DIV1 Rm, Rn {: :}
|
nkeynes@361 | 464 | DMULS.L Rm, Rn {:
|
nkeynes@361 | 465 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 466 | load_reg( R_ECX, Rn );
|
nkeynes@361 | 467 | IMUL_r32(R_ECX);
|
nkeynes@361 | 468 | store_spreg( R_EDX, R_MACH );
|
nkeynes@361 | 469 | store_spreg( R_EAX, R_MACL );
|
nkeynes@361 | 470 | :}
|
nkeynes@361 | 471 | DMULU.L Rm, Rn {:
|
nkeynes@361 | 472 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 473 | load_reg( R_ECX, Rn );
|
nkeynes@361 | 474 | MUL_r32(R_ECX);
|
nkeynes@361 | 475 | store_spreg( R_EDX, R_MACH );
|
nkeynes@361 | 476 | store_spreg( R_EAX, R_MACL );
|
nkeynes@361 | 477 | :}
|
nkeynes@359 | 478 | DT Rn {:
|
nkeynes@359 | 479 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 480 | ADD_imm8s_r32( -1, Rn );
|
nkeynes@359 | 481 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 482 | SETE_t();
|
nkeynes@359 | 483 | :}
|
nkeynes@359 | 484 | EXTS.B Rm, Rn {:
|
nkeynes@359 | 485 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 486 | MOVSX_r8_r32( R_EAX, R_EAX );
|
nkeynes@359 | 487 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 488 | :}
|
nkeynes@361 | 489 | EXTS.W Rm, Rn {:
|
nkeynes@361 | 490 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 491 | MOVSX_r16_r32( R_EAX, R_EAX );
|
nkeynes@361 | 492 | store_reg( R_EAX, Rn );
|
nkeynes@361 | 493 | :}
|
nkeynes@361 | 494 | EXTU.B Rm, Rn {:
|
nkeynes@361 | 495 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 496 | MOVZX_r8_r32( R_EAX, R_EAX );
|
nkeynes@361 | 497 | store_reg( R_EAX, Rn );
|
nkeynes@361 | 498 | :}
|
nkeynes@361 | 499 | EXTU.W Rm, Rn {:
|
nkeynes@361 | 500 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 501 | MOVZX_r16_r32( R_EAX, R_EAX );
|
nkeynes@361 | 502 | store_reg( R_EAX, Rn );
|
nkeynes@361 | 503 | :}
|
nkeynes@359 | 504 | MAC.L @Rm+, @Rn+ {: :}
|
nkeynes@359 | 505 | MAC.W @Rm+, @Rn+ {: :}
|
nkeynes@359 | 506 | MOVT Rn {:
|
nkeynes@359 | 507 | load_spreg( R_EAX, R_T );
|
nkeynes@359 | 508 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 509 | :}
|
nkeynes@361 | 510 | MUL.L Rm, Rn {:
|
nkeynes@361 | 511 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 512 | load_reg( R_ECX, Rn );
|
nkeynes@361 | 513 | MUL_r32( R_ECX );
|
nkeynes@361 | 514 | store_spreg( R_EAX, R_MACL );
|
nkeynes@361 | 515 | :}
|
nkeynes@361 | 516 | MULS.W Rm, Rn {:
|
nkeynes@361 | 517 | :}
|
nkeynes@359 | 518 | MULU.W Rm, Rn {: :}
|
nkeynes@359 | 519 | NEG Rm, Rn {:
|
nkeynes@359 | 520 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 521 | NEG_r32( R_EAX );
|
nkeynes@359 | 522 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 523 | :}
|
nkeynes@359 | 524 | NEGC Rm, Rn {:
|
nkeynes@359 | 525 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 526 | XOR_r32_r32( R_ECX, R_ECX );
|
nkeynes@359 | 527 | LDC_t();
|
nkeynes@359 | 528 | SBB_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 529 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 530 | SETC_t();
|
nkeynes@359 | 531 | :}
|
nkeynes@359 | 532 | NOT Rm, Rn {:
|
nkeynes@359 | 533 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 534 | NOT_r32( R_EAX );
|
nkeynes@359 | 535 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 536 | :}
|
nkeynes@359 | 537 | OR Rm, Rn {:
|
nkeynes@359 | 538 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 539 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 540 | OR_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 541 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 542 | :}
|
nkeynes@359 | 543 | OR #imm, R0 {:
|
nkeynes@359 | 544 | load_reg( R_EAX, 0 );
|
nkeynes@359 | 545 | OR_imm32_r32(imm, R_EAX);
|
nkeynes@359 | 546 | store_reg( R_EAX, 0 );
|
nkeynes@359 | 547 | :}
|
nkeynes@359 | 548 | OR.B #imm, @(R0, GBR) {: :}
|
nkeynes@359 | 549 | ROTCL Rn {:
|
nkeynes@359 | 550 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 551 | LDC_t();
|
nkeynes@359 | 552 | RCL1_r32( R_EAX );
|
nkeynes@359 | 553 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 554 | SETC_t();
|
nkeynes@359 | 555 | :}
|
nkeynes@359 | 556 | ROTCR Rn {:
|
nkeynes@359 | 557 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 558 | LDC_t();
|
nkeynes@359 | 559 | RCR1_r32( R_EAX );
|
nkeynes@359 | 560 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 561 | SETC_t();
|
nkeynes@359 | 562 | :}
|
nkeynes@359 | 563 | ROTL Rn {:
|
nkeynes@359 | 564 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 565 | ROL1_r32( R_EAX );
|
nkeynes@359 | 566 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 567 | SETC_t();
|
nkeynes@359 | 568 | :}
|
nkeynes@359 | 569 | ROTR Rn {:
|
nkeynes@359 | 570 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 571 | ROR1_r32( R_EAX );
|
nkeynes@359 | 572 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 573 | SETC_t();
|
nkeynes@359 | 574 | :}
|
nkeynes@359 | 575 | SHAD Rm, Rn {:
|
nkeynes@359 | 576 | /* Annoyingly enough, not directly convertible */
|
nkeynes@361 | 577 | load_reg( R_EAX, Rn );
|
nkeynes@361 | 578 | load_reg( R_ECX, Rm );
|
nkeynes@361 | 579 | CMP_imm32_r32( 0, R_ECX );
|
nkeynes@361 | 580 | JAE_rel8(9);
|
nkeynes@361 | 581 |
|
nkeynes@361 | 582 | NEG_r32( R_ECX ); // 2
|
nkeynes@361 | 583 | AND_imm8_r8( 0x1F, R_CL ); // 3
|
nkeynes@361 | 584 | SAR_r32_CL( R_EAX ); // 2
|
nkeynes@361 | 585 | JMP_rel8(5); // 2
|
nkeynes@361 | 586 |
|
nkeynes@361 | 587 | AND_imm8_r8( 0x1F, R_CL ); // 3
|
nkeynes@361 | 588 | SHL_r32_CL( R_EAX ); // 2
|
nkeynes@361 | 589 |
|
nkeynes@361 | 590 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 591 | :}
|
nkeynes@359 | 592 | SHLD Rm, Rn {:
|
nkeynes@368 | 593 | load_reg( R_EAX, Rn );
|
nkeynes@368 | 594 | load_reg( R_ECX, Rm );
|
nkeynes@368 | 595 |
|
nkeynes@368 | 596 | MOV_r32_r32( R_EAX, R_EDX );
|
nkeynes@368 | 597 | SHL_r32_CL( R_EAX );
|
nkeynes@368 | 598 | NEG_r32( R_ECX );
|
nkeynes@368 | 599 | SHR_r32_CL( R_EDX );
|
nkeynes@368 | 600 | CMP_imm8s_r32( 0, R_ECX );
|
nkeynes@368 | 601 | CMOVAE_r32_r32( R_EDX, R_EAX );
|
nkeynes@368 | 602 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 603 | :}
|
nkeynes@359 | 604 | SHAL Rn {:
|
nkeynes@359 | 605 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 606 | SHL1_r32( R_EAX );
|
nkeynes@359 | 607 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 608 | :}
|
nkeynes@359 | 609 | SHAR Rn {:
|
nkeynes@359 | 610 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 611 | SAR1_r32( R_EAX );
|
nkeynes@359 | 612 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 613 | :}
|
nkeynes@359 | 614 | SHLL Rn {:
|
nkeynes@359 | 615 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 616 | SHL1_r32( R_EAX );
|
nkeynes@359 | 617 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 618 | :}
|
nkeynes@359 | 619 | SHLL2 Rn {:
|
nkeynes@359 | 620 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 621 | SHL_imm8_r32( 2, R_EAX );
|
nkeynes@359 | 622 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 623 | :}
|
nkeynes@359 | 624 | SHLL8 Rn {:
|
nkeynes@359 | 625 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 626 | SHL_imm8_r32( 8, R_EAX );
|
nkeynes@359 | 627 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 628 | :}
|
nkeynes@359 | 629 | SHLL16 Rn {:
|
nkeynes@359 | 630 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 631 | SHL_imm8_r32( 16, R_EAX );
|
nkeynes@359 | 632 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 633 | :}
|
nkeynes@359 | 634 | SHLR Rn {:
|
nkeynes@359 | 635 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 636 | SHR1_r32( R_EAX );
|
nkeynes@359 | 637 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 638 | :}
|
nkeynes@359 | 639 | SHLR2 Rn {:
|
nkeynes@359 | 640 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 641 | SHR_imm8_r32( 2, R_EAX );
|
nkeynes@359 | 642 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 643 | :}
|
nkeynes@359 | 644 | SHLR8 Rn {:
|
nkeynes@359 | 645 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 646 | SHR_imm8_r32( 8, R_EAX );
|
nkeynes@359 | 647 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 648 | :}
|
nkeynes@359 | 649 | SHLR16 Rn {:
|
nkeynes@359 | 650 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 651 | SHR_imm8_r32( 16, R_EAX );
|
nkeynes@359 | 652 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 653 | :}
|
nkeynes@359 | 654 | SUB Rm, Rn {:
|
nkeynes@359 | 655 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 656 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 657 | SUB_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 658 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 659 | :}
|
nkeynes@359 | 660 | SUBC Rm, Rn {:
|
nkeynes@359 | 661 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 662 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 663 | LDC_t();
|
nkeynes@359 | 664 | SBB_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 665 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 666 | :}
|
nkeynes@359 | 667 | SUBV Rm, Rn {:
|
nkeynes@359 | 668 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 669 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 670 | SUB_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 671 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 672 | SETO_t();
|
nkeynes@359 | 673 | :}
|
nkeynes@359 | 674 | SWAP.B Rm, Rn {:
|
nkeynes@359 | 675 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 676 | XCHG_r8_r8( R_AL, R_AH );
|
nkeynes@359 | 677 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 678 | :}
|
nkeynes@359 | 679 | SWAP.W Rm, Rn {:
|
nkeynes@359 | 680 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 681 | MOV_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 682 | SHL_imm8_r32( 16, R_ECX );
|
nkeynes@359 | 683 | SHR_imm8_r32( 16, R_EAX );
|
nkeynes@359 | 684 | OR_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 685 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 686 | :}
|
nkeynes@361 | 687 | TAS.B @Rn {:
|
nkeynes@361 | 688 | load_reg( R_ECX, Rn );
|
nkeynes@361 | 689 | MEM_READ_BYTE( R_ECX, R_EAX );
|
nkeynes@361 | 690 | TEST_r8_r8( R_AL, R_AL );
|
nkeynes@361 | 691 | SETE_t();
|
nkeynes@361 | 692 | OR_imm8_r8( 0x80, R_AL );
|
nkeynes@361 | 693 | MEM_WRITE_BYTE( R_ECX, R_EAX );
|
nkeynes@361 | 694 | :}
|
nkeynes@361 | 695 | TST Rm, Rn {:
|
nkeynes@361 | 696 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 697 | load_reg( R_ECX, Rn );
|
nkeynes@361 | 698 | TEST_r32_r32( R_EAX, R_ECX );
|
nkeynes@361 | 699 | SETE_t();
|
nkeynes@361 | 700 | :}
|
nkeynes@368 | 701 | TST #imm, R0 {:
|
nkeynes@368 | 702 | load_reg( R_EAX, 0 );
|
nkeynes@368 | 703 | TEST_imm32_r32( imm, R_EAX );
|
nkeynes@368 | 704 | SETE_t();
|
nkeynes@368 | 705 | :}
|
nkeynes@368 | 706 | TST.B #imm, @(R0, GBR) {:
|
nkeynes@368 | 707 | load_reg( R_EAX, 0);
|
nkeynes@368 | 708 | load_reg( R_ECX, R_GBR);
|
nkeynes@368 | 709 | ADD_r32_r32( R_EAX, R_ECX );
|
nkeynes@368 | 710 | MEM_READ_BYTE( R_ECX, R_EAX );
|
nkeynes@368 | 711 | TEST_imm8_r8( imm, R_EAX );
|
nkeynes@368 | 712 | SETE_t();
|
nkeynes@368 | 713 | :}
|
nkeynes@359 | 714 | XOR Rm, Rn {:
|
nkeynes@359 | 715 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 716 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 717 | XOR_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 718 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 719 | :}
|
nkeynes@359 | 720 | XOR #imm, R0 {:
|
nkeynes@359 | 721 | load_reg( R_EAX, 0 );
|
nkeynes@359 | 722 | XOR_imm32_r32( imm, R_EAX );
|
nkeynes@359 | 723 | store_reg( R_EAX, 0 );
|
nkeynes@359 | 724 | :}
|
nkeynes@359 | 725 | XOR.B #imm, @(R0, GBR) {:
|
nkeynes@359 | 726 | load_reg( R_EAX, 0 );
|
nkeynes@359 | 727 | load_spreg( R_ECX, R_GBR );
|
nkeynes@359 | 728 | ADD_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 729 | MEM_READ_BYTE( R_ECX, R_EAX );
|
nkeynes@359 | 730 | XOR_imm32_r32( imm, R_EAX );
|
nkeynes@359 | 731 | MEM_WRITE_BYTE( R_ECX, R_EAX );
|
nkeynes@359 | 732 | :}
|
nkeynes@361 | 733 | XTRCT Rm, Rn {:
|
nkeynes@361 | 734 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 735 | MOV_r32_r32( R_EAX, R_ECX );
|
nkeynes@361 | 736 | SHR_imm8_r32( 16, R_EAX );
|
nkeynes@361 | 737 | SHL_imm8_r32( 16, R_ECX );
|
nkeynes@361 | 738 | OR_r32_r32( R_EAX, R_ECX );
|
nkeynes@361 | 739 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 740 | :}
|
nkeynes@359 | 741 |
|
nkeynes@359 | 742 | /* Data move instructions */
|
nkeynes@359 | 743 | MOV Rm, Rn {:
|
nkeynes@359 | 744 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 745 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 746 | :}
|
nkeynes@359 | 747 | MOV #imm, Rn {:
|
nkeynes@359 | 748 | load_imm32( R_EAX, imm );
|
nkeynes@359 | 749 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 750 | :}
|
nkeynes@359 | 751 | MOV.B Rm, @Rn {:
|
nkeynes@359 | 752 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 753 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 754 | MEM_WRITE_BYTE( R_ECX, R_EAX );
|
nkeynes@359 | 755 | :}
|
nkeynes@359 | 756 | MOV.B Rm, @-Rn {:
|
nkeynes@359 | 757 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 758 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 759 | ADD_imm8s_r32( -1, Rn );
|
nkeynes@359 | 760 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 761 | MEM_WRITE_BYTE( R_ECX, R_EAX );
|
nkeynes@359 | 762 | :}
|
nkeynes@359 | 763 | MOV.B Rm, @(R0, Rn) {:
|
nkeynes@359 | 764 | load_reg( R_EAX, 0 );
|
nkeynes@359 | 765 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 766 | ADD_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 767 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 768 | MEM_WRITE_BYTE( R_ECX, R_EAX );
|
nkeynes@359 | 769 | :}
|
nkeynes@359 | 770 | MOV.B R0, @(disp, GBR) {:
|
nkeynes@359 | 771 | load_reg( R_EAX, 0 );
|
nkeynes@359 | 772 | load_spreg( R_ECX, R_GBR );
|
nkeynes@359 | 773 | ADD_imm32_r32( disp, R_ECX );
|
nkeynes@359 | 774 | MEM_WRITE_BYTE( R_ECX, R_EAX );
|
nkeynes@359 | 775 | :}
|
nkeynes@359 | 776 | MOV.B R0, @(disp, Rn) {:
|
nkeynes@359 | 777 | load_reg( R_EAX, 0 );
|
nkeynes@359 | 778 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 779 | ADD_imm32_r32( disp, R_ECX );
|
nkeynes@359 | 780 | MEM_WRITE_BYTE( R_ECX, R_EAX );
|
nkeynes@359 | 781 | :}
|
nkeynes@359 | 782 | MOV.B @Rm, Rn {:
|
nkeynes@359 | 783 | load_reg( R_ECX, Rm );
|
nkeynes@359 | 784 | MEM_READ_BYTE( R_ECX, R_EAX );
|
nkeynes@359 | 785 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 786 | :}
|
nkeynes@359 | 787 | MOV.B @Rm+, Rn {:
|
nkeynes@359 | 788 | load_reg( R_ECX, Rm );
|
nkeynes@359 | 789 | MOV_r32_r32( R_ECX, R_EAX );
|
nkeynes@359 | 790 | ADD_imm8s_r32( 1, R_EAX );
|
nkeynes@359 | 791 | store_reg( R_EAX, Rm );
|
nkeynes@359 | 792 | MEM_READ_BYTE( R_ECX, R_EAX );
|
nkeynes@359 | 793 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 794 | :}
|
nkeynes@359 | 795 | MOV.B @(R0, Rm), Rn {:
|
nkeynes@359 | 796 | load_reg( R_EAX, 0 );
|
nkeynes@359 | 797 | load_reg( R_ECX, Rm );
|
nkeynes@359 | 798 | ADD_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 799 | MEM_READ_BYTE( R_ECX, R_EAX );
|
nkeynes@359 | 800 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 801 | :}
|
nkeynes@359 | 802 | MOV.B @(disp, GBR), R0 {:
|
nkeynes@359 | 803 | load_spreg( R_ECX, R_GBR );
|
nkeynes@359 | 804 | ADD_imm32_r32( disp, R_ECX );
|
nkeynes@359 | 805 | MEM_READ_BYTE( R_ECX, R_EAX );
|
nkeynes@359 | 806 | store_reg( R_EAX, 0 );
|
nkeynes@359 | 807 | :}
|
nkeynes@359 | 808 | MOV.B @(disp, Rm), R0 {:
|
nkeynes@359 | 809 | load_reg( R_ECX, Rm );
|
nkeynes@359 | 810 | ADD_imm32_r32( disp, R_ECX );
|
nkeynes@359 | 811 | MEM_READ_BYTE( R_ECX, R_EAX );
|
nkeynes@359 | 812 | store_reg( R_EAX, 0 );
|
nkeynes@359 | 813 | :}
|
nkeynes@361 | 814 | MOV.L Rm, @Rn {:
|
nkeynes@361 | 815 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 816 | load_reg( R_ECX, Rn );
|
nkeynes@361 | 817 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@361 | 818 | :}
|
nkeynes@361 | 819 | MOV.L Rm, @-Rn {:
|
nkeynes@361 | 820 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 821 | load_reg( R_ECX, Rn );
|
nkeynes@361 | 822 | ADD_imm8s_r32( -4, R_ECX );
|
nkeynes@361 | 823 | store_reg( R_ECX, Rn );
|
nkeynes@361 | 824 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@361 | 825 | :}
|
nkeynes@361 | 826 | MOV.L Rm, @(R0, Rn) {:
|
nkeynes@361 | 827 | load_reg( R_EAX, 0 );
|
nkeynes@361 | 828 | load_reg( R_ECX, Rn );
|
nkeynes@361 | 829 | ADD_r32_r32( R_EAX, R_ECX );
|
nkeynes@361 | 830 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 831 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@361 | 832 | :}
|
nkeynes@361 | 833 | MOV.L R0, @(disp, GBR) {:
|
nkeynes@361 | 834 | load_spreg( R_ECX, R_GBR );
|
nkeynes@361 | 835 | load_reg( R_EAX, 0 );
|
nkeynes@361 | 836 | ADD_imm32_r32( disp, R_ECX );
|
nkeynes@361 | 837 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@361 | 838 | :}
|
nkeynes@361 | 839 | MOV.L Rm, @(disp, Rn) {:
|
nkeynes@361 | 840 | load_reg( R_ECX, Rn );
|
nkeynes@361 | 841 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 842 | ADD_imm32_r32( disp, R_ECX );
|
nkeynes@361 | 843 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@361 | 844 | :}
|
nkeynes@361 | 845 | MOV.L @Rm, Rn {:
|
nkeynes@361 | 846 | load_reg( R_ECX, Rm );
|
nkeynes@361 | 847 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@361 | 848 | store_reg( R_EAX, Rn );
|
nkeynes@361 | 849 | :}
|
nkeynes@361 | 850 | MOV.L @Rm+, Rn {:
|
nkeynes@361 | 851 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 852 | MOV_r32_r32( R_EAX, R_ECX );
|
nkeynes@361 | 853 | ADD_imm8s_r32( 4, R_EAX );
|
nkeynes@361 | 854 | store_reg( R_EAX, Rm );
|
nkeynes@361 | 855 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@361 | 856 | store_reg( R_EAX, Rn );
|
nkeynes@361 | 857 | :}
|
nkeynes@361 | 858 | MOV.L @(R0, Rm), Rn {:
|
nkeynes@361 | 859 | load_reg( R_EAX, 0 );
|
nkeynes@361 | 860 | load_reg( R_ECX, Rm );
|
nkeynes@361 | 861 | ADD_r32_r32( R_EAX, R_ECX );
|
nkeynes@361 | 862 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@361 | 863 | store_reg( R_EAX, Rn );
|
nkeynes@361 | 864 | :}
|
nkeynes@361 | 865 | MOV.L @(disp, GBR), R0 {:
|
nkeynes@361 | 866 | load_spreg( R_ECX, R_GBR );
|
nkeynes@361 | 867 | ADD_imm32_r32( disp, R_ECX );
|
nkeynes@361 | 868 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@361 | 869 | store_reg( R_EAX, 0 );
|
nkeynes@361 | 870 | :}
|
nkeynes@361 | 871 | MOV.L @(disp, PC), Rn {:
|
nkeynes@361 | 872 | load_imm32( R_ECX, (pc & 0xFFFFFFFC) + disp + 4 );
|
nkeynes@361 | 873 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@361 | 874 | store_reg( R_EAX, 0 );
|
nkeynes@361 | 875 | :}
|
nkeynes@361 | 876 | MOV.L @(disp, Rm), Rn {:
|
nkeynes@361 | 877 | load_reg( R_ECX, Rm );
|
nkeynes@361 | 878 | ADD_imm8s_r32( disp, R_ECX );
|
nkeynes@361 | 879 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@361 | 880 | store_reg( R_EAX, Rn );
|
nkeynes@361 | 881 | :}
|
nkeynes@361 | 882 | MOV.W Rm, @Rn {:
|
nkeynes@361 | 883 | load_reg( R_ECX, Rn );
|
nkeynes@361 | 884 | MEM_READ_WORD( R_ECX, R_EAX );
|
nkeynes@361 | 885 | store_reg( R_EAX, Rn );
|
nkeynes@361 | 886 | :}
|
nkeynes@361 | 887 | MOV.W Rm, @-Rn {:
|
nkeynes@361 | 888 | load_reg( R_ECX, Rn );
|
nkeynes@361 | 889 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 890 | ADD_imm8s_r32( -2, R_ECX );
|
nkeynes@361 | 891 | MEM_WRITE_WORD( R_ECX, R_EAX );
|
nkeynes@361 | 892 | :}
|
nkeynes@361 | 893 | MOV.W Rm, @(R0, Rn) {:
|
nkeynes@361 | 894 | load_reg( R_EAX, 0 );
|
nkeynes@361 | 895 | load_reg( R_ECX, Rn );
|
nkeynes@361 | 896 | ADD_r32_r32( R_EAX, R_ECX );
|
nkeynes@361 | 897 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 898 | MEM_WRITE_WORD( R_ECX, R_EAX );
|
nkeynes@361 | 899 | :}
|
nkeynes@361 | 900 | MOV.W R0, @(disp, GBR) {:
|
nkeynes@361 | 901 | load_spreg( R_ECX, R_GBR );
|
nkeynes@361 | 902 | load_reg( R_EAX, 0 );
|
nkeynes@361 | 903 | ADD_imm32_r32( disp, R_ECX );
|
nkeynes@361 | 904 | MEM_WRITE_WORD( R_ECX, R_EAX );
|
nkeynes@361 | 905 | :}
|
nkeynes@361 | 906 | MOV.W R0, @(disp, Rn) {:
|
nkeynes@361 | 907 | load_reg( R_ECX, Rn );
|
nkeynes@361 | 908 | load_reg( R_EAX, 0 );
|
nkeynes@361 | 909 | ADD_imm32_r32( disp, R_ECX );
|
nkeynes@361 | 910 | MEM_WRITE_WORD( R_ECX, R_EAX );
|
nkeynes@361 | 911 | :}
|
nkeynes@361 | 912 | MOV.W @Rm, Rn {:
|
nkeynes@361 | 913 | load_reg( R_ECX, Rm );
|
nkeynes@361 | 914 | MEM_READ_WORD( R_ECX, R_EAX );
|
nkeynes@361 | 915 | store_reg( R_EAX, Rn );
|
nkeynes@361 | 916 | :}
|
nkeynes@361 | 917 | MOV.W @Rm+, Rn {:
|
nkeynes@361 | 918 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 919 | MOV_r32_r32( R_EAX, R_ECX );
|
nkeynes@361 | 920 | ADD_imm8s_r32( 2, R_EAX );
|
nkeynes@361 | 921 | store_reg( R_EAX, Rm );
|
nkeynes@361 | 922 | MEM_READ_WORD( R_ECX, R_EAX );
|
nkeynes@361 | 923 | store_reg( R_EAX, Rn );
|
nkeynes@361 | 924 | :}
|
nkeynes@361 | 925 | MOV.W @(R0, Rm), Rn {:
|
nkeynes@361 | 926 | load_reg( R_EAX, 0 );
|
nkeynes@361 | 927 | load_reg( R_ECX, Rm );
|
nkeynes@361 | 928 | ADD_r32_r32( R_EAX, R_ECX );
|
nkeynes@361 | 929 | MEM_READ_WORD( R_ECX, R_EAX );
|
nkeynes@361 | 930 | store_reg( R_EAX, Rn );
|
nkeynes@361 | 931 | :}
|
nkeynes@361 | 932 | MOV.W @(disp, GBR), R0 {:
|
nkeynes@361 | 933 | load_spreg( R_ECX, R_GBR );
|
nkeynes@361 | 934 | ADD_imm32_r32( disp, R_ECX );
|
nkeynes@361 | 935 | MEM_READ_WORD( R_ECX, R_EAX );
|
nkeynes@361 | 936 | store_reg( R_EAX, 0 );
|
nkeynes@361 | 937 | :}
|
nkeynes@361 | 938 | MOV.W @(disp, PC), Rn {:
|
nkeynes@361 | 939 | load_imm32( R_ECX, pc + disp + 4 );
|
nkeynes@361 | 940 | MEM_READ_WORD( R_ECX, R_EAX );
|
nkeynes@361 | 941 | store_reg( R_EAX, Rn );
|
nkeynes@361 | 942 | :}
|
nkeynes@361 | 943 | MOV.W @(disp, Rm), R0 {:
|
nkeynes@361 | 944 | load_reg( R_ECX, Rm );
|
nkeynes@361 | 945 | ADD_imm32_r32( disp, R_ECX );
|
nkeynes@361 | 946 | MEM_READ_WORD( R_ECX, R_EAX );
|
nkeynes@361 | 947 | store_reg( R_EAX, 0 );
|
nkeynes@361 | 948 | :}
|
nkeynes@361 | 949 | MOVA @(disp, PC), R0 {:
|
nkeynes@361 | 950 | load_imm32( R_ECX, (pc & 0xFFFFFFFC) + disp + 4 );
|
nkeynes@361 | 951 | store_reg( R_ECX, 0 );
|
nkeynes@361 | 952 | :}
|
nkeynes@361 | 953 | MOVCA.L R0, @Rn {:
|
nkeynes@361 | 954 | load_reg( R_EAX, 0 );
|
nkeynes@361 | 955 | load_reg( R_ECX, Rn );
|
nkeynes@361 | 956 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@361 | 957 | :}
|
nkeynes@359 | 958 |
|
nkeynes@359 | 959 | /* Control transfer instructions */
|
nkeynes@368 | 960 | BF disp {:
|
nkeynes@368 | 961 | CMP_imm8s_ebp( 0, R_T );
|
nkeynes@368 | 962 | JNE_rel8( 1 );
|
nkeynes@368 | 963 | exit_block( disp + pc + 4 );
|
nkeynes@368 | 964 | return 1;
|
nkeynes@368 | 965 | :}
|
nkeynes@368 | 966 | BF/S disp {:
|
nkeynes@368 | 967 | CMP_imm8s_ebp( 0, R_T );
|
nkeynes@368 | 968 | JNE_rel8( 1 );
|
nkeynes@368 | 969 | exit_block( disp + pc + 4 );
|
nkeynes@368 | 970 | sh4_x86.in_delay_slot = TRUE;
|
nkeynes@368 | 971 | :}
|
nkeynes@368 | 972 | BRA disp {:
|
nkeynes@368 | 973 | exit_block( disp + pc + 4 );
|
nkeynes@368 | 974 | :}
|
nkeynes@359 | 975 | BRAF Rn {: :}
|
nkeynes@359 | 976 | BSR disp {: :}
|
nkeynes@359 | 977 | BSRF Rn {: :}
|
nkeynes@359 | 978 | BT disp {: /* If true, result PC += 4 + disp. else result PC = pc+2 */
|
nkeynes@359 | 979 | return pc + 2;
|
nkeynes@359 | 980 | :}
|
nkeynes@359 | 981 | BT/S disp {:
|
nkeynes@359 | 982 |
|
nkeynes@359 | 983 | return pc + 4;
|
nkeynes@359 | 984 | :}
|
nkeynes@359 | 985 | JMP @Rn {: :}
|
nkeynes@359 | 986 | JSR @Rn {: :}
|
nkeynes@359 | 987 | RTE {: :}
|
nkeynes@359 | 988 | RTS {: :}
|
nkeynes@359 | 989 | TRAPA #imm {: :}
|
nkeynes@359 | 990 | UNDEF {: :}
|
nkeynes@359 | 991 |
|
nkeynes@359 | 992 | CLRMAC {: :}
|
nkeynes@359 | 993 | CLRS {: :}
|
nkeynes@359 | 994 | CLRT {: :}
|
nkeynes@359 | 995 | SETS {: :}
|
nkeynes@359 | 996 | SETT {: :}
|
nkeynes@359 | 997 |
|
nkeynes@359 | 998 | /* Floating point instructions */
|
nkeynes@359 | 999 | FABS FRn {: :}
|
nkeynes@359 | 1000 | FADD FRm, FRn {: :}
|
nkeynes@359 | 1001 | FCMP/EQ FRm, FRn {: :}
|
nkeynes@359 | 1002 | FCMP/GT FRm, FRn {: :}
|
nkeynes@359 | 1003 | FCNVDS FRm, FPUL {: :}
|
nkeynes@359 | 1004 | FCNVSD FPUL, FRn {: :}
|
nkeynes@359 | 1005 | FDIV FRm, FRn {: :}
|
nkeynes@359 | 1006 | FIPR FVm, FVn {: :}
|
nkeynes@359 | 1007 | FLDS FRm, FPUL {: :}
|
nkeynes@359 | 1008 | FLDI0 FRn {: :}
|
nkeynes@359 | 1009 | FLDI1 FRn {: :}
|
nkeynes@359 | 1010 | FLOAT FPUL, FRn {: :}
|
nkeynes@359 | 1011 | FMAC FR0, FRm, FRn {: :}
|
nkeynes@359 | 1012 | FMOV FRm, FRn {: :}
|
nkeynes@359 | 1013 | FMOV FRm, @Rn {: :}
|
nkeynes@359 | 1014 | FMOV FRm, @-Rn {: :}
|
nkeynes@359 | 1015 | FMOV FRm, @(R0, Rn) {: :}
|
nkeynes@359 | 1016 | FMOV @Rm, FRn {: :}
|
nkeynes@359 | 1017 | FMOV @Rm+, FRn {: :}
|
nkeynes@359 | 1018 | FMOV @(R0, Rm), FRn {: :}
|
nkeynes@359 | 1019 | FMUL FRm, FRn {: :}
|
nkeynes@359 | 1020 | FNEG FRn {: :}
|
nkeynes@359 | 1021 | FRCHG {: :}
|
nkeynes@359 | 1022 | FSCA FPUL, FRn {: :}
|
nkeynes@359 | 1023 | FSCHG {: :}
|
nkeynes@359 | 1024 | FSQRT FRn {: :}
|
nkeynes@359 | 1025 | FSRRA FRn {: :}
|
nkeynes@359 | 1026 | FSTS FPUL, FRn {: :}
|
nkeynes@359 | 1027 | FSUB FRm, FRn {: :}
|
nkeynes@359 | 1028 | FTRC FRm, FPUL {: :}
|
nkeynes@359 | 1029 | FTRV XMTRX, FVn {: :}
|
nkeynes@359 | 1030 |
|
nkeynes@359 | 1031 | /* Processor control instructions */
|
nkeynes@368 | 1032 | LDC Rm, SR {:
|
nkeynes@368 | 1033 | load_reg( R_EAX, Rm );
|
nkeynes@368 | 1034 | write_sr( R_EAX );
|
nkeynes@368 | 1035 | :}
|
nkeynes@359 | 1036 | LDC Rm, GBR {:
|
nkeynes@359 | 1037 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 1038 | store_spreg( R_EAX, R_GBR );
|
nkeynes@359 | 1039 | :}
|
nkeynes@359 | 1040 | LDC Rm, VBR {:
|
nkeynes@359 | 1041 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 1042 | store_spreg( R_EAX, R_VBR );
|
nkeynes@359 | 1043 | :}
|
nkeynes@359 | 1044 | LDC Rm, SSR {:
|
nkeynes@359 | 1045 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 1046 | store_spreg( R_EAX, R_SSR );
|
nkeynes@359 | 1047 | :}
|
nkeynes@359 | 1048 | LDC Rm, SGR {:
|
nkeynes@359 | 1049 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 1050 | store_spreg( R_EAX, R_SGR );
|
nkeynes@359 | 1051 | :}
|
nkeynes@359 | 1052 | LDC Rm, SPC {:
|
nkeynes@359 | 1053 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 1054 | store_spreg( R_EAX, R_SPC );
|
nkeynes@359 | 1055 | :}
|
nkeynes@359 | 1056 | LDC Rm, DBR {:
|
nkeynes@359 | 1057 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 1058 | store_spreg( R_EAX, R_DBR );
|
nkeynes@359 | 1059 | :}
|
nkeynes@359 | 1060 | LDC Rm, Rn_BANK {: :}
|
nkeynes@359 | 1061 | LDC.L @Rm+, GBR {:
|
nkeynes@359 | 1062 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 1063 | MOV_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 1064 | ADD_imm8s_r32( 4, R_EAX );
|
nkeynes@359 | 1065 | store_reg( R_EAX, Rm );
|
nkeynes@359 | 1066 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 1067 | store_spreg( R_EAX, R_GBR );
|
nkeynes@359 | 1068 | :}
|
nkeynes@368 | 1069 | LDC.L @Rm+, SR {:
|
nkeynes@368 | 1070 | load_reg( R_EAX, Rm );
|
nkeynes@368 | 1071 | MOV_r32_r32( R_EAX, R_ECX );
|
nkeynes@368 | 1072 | ADD_imm8s_r32( 4, R_EAX );
|
nkeynes@368 | 1073 | store_reg( R_EAX, Rm );
|
nkeynes@368 | 1074 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@368 | 1075 | write_sr( R_EAX );
|
nkeynes@359 | 1076 | :}
|
nkeynes@359 | 1077 | LDC.L @Rm+, VBR {:
|
nkeynes@359 | 1078 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 1079 | MOV_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 1080 | ADD_imm8s_r32( 4, R_EAX );
|
nkeynes@359 | 1081 | store_reg( R_EAX, Rm );
|
nkeynes@359 | 1082 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 1083 | store_spreg( R_EAX, R_VBR );
|
nkeynes@359 | 1084 | :}
|
nkeynes@359 | 1085 | LDC.L @Rm+, SSR {:
|
nkeynes@359 | 1086 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 1087 | MOV_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 1088 | ADD_imm8s_r32( 4, R_EAX );
|
nkeynes@359 | 1089 | store_reg( R_EAX, Rm );
|
nkeynes@359 | 1090 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 1091 | store_spreg( R_EAX, R_SSR );
|
nkeynes@359 | 1092 | :}
|
nkeynes@359 | 1093 | LDC.L @Rm+, SGR {:
|
nkeynes@359 | 1094 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 1095 | MOV_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 1096 | ADD_imm8s_r32( 4, R_EAX );
|
nkeynes@359 | 1097 | store_reg( R_EAX, Rm );
|
nkeynes@359 | 1098 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 1099 | store_spreg( R_EAX, R_SGR );
|
nkeynes@359 | 1100 | :}
|
nkeynes@359 | 1101 | LDC.L @Rm+, SPC {:
|
nkeynes@359 | 1102 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 1103 | MOV_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 1104 | ADD_imm8s_r32( 4, R_EAX );
|
nkeynes@359 | 1105 | store_reg( R_EAX, Rm );
|
nkeynes@359 | 1106 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 1107 | store_spreg( R_EAX, R_SPC );
|
nkeynes@359 | 1108 | :}
|
nkeynes@359 | 1109 | LDC.L @Rm+, DBR {:
|
nkeynes@359 | 1110 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 1111 | MOV_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 1112 | ADD_imm8s_r32( 4, R_EAX );
|
nkeynes@359 | 1113 | store_reg( R_EAX, Rm );
|
nkeynes@359 | 1114 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 1115 | store_spreg( R_EAX, R_DBR );
|
nkeynes@359 | 1116 | :}
|
nkeynes@359 | 1117 | LDC.L @Rm+, Rn_BANK {:
|
nkeynes@359 | 1118 | :}
|
nkeynes@359 | 1119 | LDS Rm, FPSCR {:
|
nkeynes@359 | 1120 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 1121 | store_spreg( R_EAX, R_FPSCR );
|
nkeynes@359 | 1122 | :}
|
nkeynes@359 | 1123 | LDS.L @Rm+, FPSCR {:
|
nkeynes@359 | 1124 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 1125 | MOV_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 1126 | ADD_imm8s_r32( 4, R_EAX );
|
nkeynes@359 | 1127 | store_reg( R_EAX, Rm );
|
nkeynes@359 | 1128 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 1129 | store_spreg( R_EAX, R_FPSCR );
|
nkeynes@359 | 1130 | :}
|
nkeynes@359 | 1131 | LDS Rm, FPUL {:
|
nkeynes@359 | 1132 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 1133 | store_spreg( R_EAX, R_FPUL );
|
nkeynes@359 | 1134 | :}
|
nkeynes@359 | 1135 | LDS.L @Rm+, FPUL {:
|
nkeynes@359 | 1136 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 1137 | MOV_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 1138 | ADD_imm8s_r32( 4, R_EAX );
|
nkeynes@359 | 1139 | store_reg( R_EAX, Rm );
|
nkeynes@359 | 1140 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 1141 | store_spreg( R_EAX, R_FPUL );
|
nkeynes@359 | 1142 | :}
|
nkeynes@359 | 1143 | LDS Rm, MACH {:
|
nkeynes@359 | 1144 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 1145 | store_spreg( R_EAX, R_MACH );
|
nkeynes@359 | 1146 | :}
|
nkeynes@359 | 1147 | LDS.L @Rm+, MACH {:
|
nkeynes@359 | 1148 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 1149 | MOV_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 1150 | ADD_imm8s_r32( 4, R_EAX );
|
nkeynes@359 | 1151 | store_reg( R_EAX, Rm );
|
nkeynes@359 | 1152 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 1153 | store_spreg( R_EAX, R_MACH );
|
nkeynes@359 | 1154 | :}
|
nkeynes@359 | 1155 | LDS Rm, MACL {:
|
nkeynes@359 | 1156 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 1157 | store_spreg( R_EAX, R_MACL );
|
nkeynes@359 | 1158 | :}
|
nkeynes@359 | 1159 | LDS.L @Rm+, MACL {:
|
nkeynes@359 | 1160 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 1161 | MOV_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 1162 | ADD_imm8s_r32( 4, R_EAX );
|
nkeynes@359 | 1163 | store_reg( R_EAX, Rm );
|
nkeynes@359 | 1164 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 1165 | store_spreg( R_EAX, R_MACL );
|
nkeynes@359 | 1166 | :}
|
nkeynes@359 | 1167 | LDS Rm, PR {:
|
nkeynes@359 | 1168 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 1169 | store_spreg( R_EAX, R_PR );
|
nkeynes@359 | 1170 | :}
|
nkeynes@359 | 1171 | LDS.L @Rm+, PR {:
|
nkeynes@359 | 1172 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 1173 | MOV_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 1174 | ADD_imm8s_r32( 4, R_EAX );
|
nkeynes@359 | 1175 | store_reg( R_EAX, Rm );
|
nkeynes@359 | 1176 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 1177 | store_spreg( R_EAX, R_PR );
|
nkeynes@359 | 1178 | :}
|
nkeynes@359 | 1179 | LDTLB {: :}
|
nkeynes@359 | 1180 | OCBI @Rn {: :}
|
nkeynes@359 | 1181 | OCBP @Rn {: :}
|
nkeynes@359 | 1182 | OCBWB @Rn {: :}
|
nkeynes@359 | 1183 | PREF @Rn {: :}
|
nkeynes@359 | 1184 | SLEEP {: :}
|
nkeynes@368 | 1185 | STC SR, Rn {:
|
nkeynes@368 | 1186 | read_sr( R_EAX );
|
nkeynes@368 | 1187 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 1188 | :}
|
nkeynes@359 | 1189 | STC GBR, Rn {:
|
nkeynes@359 | 1190 | load_spreg( R_EAX, R_GBR );
|
nkeynes@359 | 1191 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 1192 | :}
|
nkeynes@359 | 1193 | STC VBR, Rn {:
|
nkeynes@359 | 1194 | load_spreg( R_EAX, R_VBR );
|
nkeynes@359 | 1195 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 1196 | :}
|
nkeynes@359 | 1197 | STC SSR, Rn {:
|
nkeynes@359 | 1198 | load_spreg( R_EAX, R_SSR );
|
nkeynes@359 | 1199 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 1200 | :}
|
nkeynes@359 | 1201 | STC SPC, Rn {:
|
nkeynes@359 | 1202 | load_spreg( R_EAX, R_SPC );
|
nkeynes@359 | 1203 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 1204 | :}
|
nkeynes@359 | 1205 | STC SGR, Rn {:
|
nkeynes@359 | 1206 | load_spreg( R_EAX, R_SGR );
|
nkeynes@359 | 1207 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 1208 | :}
|
nkeynes@359 | 1209 | STC DBR, Rn {:
|
nkeynes@359 | 1210 | load_spreg( R_EAX, R_DBR );
|
nkeynes@359 | 1211 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 1212 | :}
|
nkeynes@368 | 1213 | STC Rm_BANK, Rn {: /* TODO */
|
nkeynes@359 | 1214 | :}
|
nkeynes@368 | 1215 | STC.L SR, @-Rn {: /* TODO */
|
nkeynes@368 | 1216 | load_reg( R_ECX, Rn );
|
nkeynes@368 | 1217 | ADD_imm8s_r32( -4, Rn );
|
nkeynes@368 | 1218 | store_reg( R_ECX, Rn );
|
nkeynes@368 | 1219 | read_sr( R_EAX );
|
nkeynes@368 | 1220 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 1221 | :}
|
nkeynes@359 | 1222 | STC.L VBR, @-Rn {:
|
nkeynes@359 | 1223 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 1224 | ADD_imm8s_r32( -4, Rn );
|
nkeynes@359 | 1225 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 1226 | load_spreg( R_EAX, R_VBR );
|
nkeynes@359 | 1227 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 1228 | :}
|
nkeynes@359 | 1229 | STC.L SSR, @-Rn {:
|
nkeynes@359 | 1230 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 1231 | ADD_imm8s_r32( -4, Rn );
|
nkeynes@359 | 1232 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 1233 | load_spreg( R_EAX, R_SSR );
|
nkeynes@359 | 1234 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 1235 | :}
|
nkeynes@359 | 1236 | STC.L SPC, @-Rn {:
|
nkeynes@359 | 1237 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 1238 | ADD_imm8s_r32( -4, Rn );
|
nkeynes@359 | 1239 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 1240 | load_spreg( R_EAX, R_SPC );
|
nkeynes@359 | 1241 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 1242 | :}
|
nkeynes@359 | 1243 | STC.L SGR, @-Rn {:
|
nkeynes@359 | 1244 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 1245 | ADD_imm8s_r32( -4, Rn );
|
nkeynes@359 | 1246 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 1247 | load_spreg( R_EAX, R_SGR );
|
nkeynes@359 | 1248 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 1249 | :}
|
nkeynes@359 | 1250 | STC.L DBR, @-Rn {:
|
nkeynes@359 | 1251 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 1252 | ADD_imm8s_r32( -4, Rn );
|
nkeynes@359 | 1253 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 1254 | load_spreg( R_EAX, R_DBR );
|
nkeynes@359 | 1255 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 1256 | :}
|
nkeynes@359 | 1257 | STC.L Rm_BANK, @-Rn {: :}
|
nkeynes@359 | 1258 | STC.L GBR, @-Rn {:
|
nkeynes@359 | 1259 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 1260 | ADD_imm8s_r32( -4, Rn );
|
nkeynes@359 | 1261 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 1262 | load_spreg( R_EAX, R_GBR );
|
nkeynes@359 | 1263 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 1264 | :}
|
nkeynes@359 | 1265 | STS FPSCR, Rn {:
|
nkeynes@359 | 1266 | load_spreg( R_EAX, R_FPSCR );
|
nkeynes@359 | 1267 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 1268 | :}
|
nkeynes@359 | 1269 | STS.L FPSCR, @-Rn {:
|
nkeynes@359 | 1270 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 1271 | ADD_imm8s_r32( -4, Rn );
|
nkeynes@359 | 1272 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 1273 | load_spreg( R_EAX, R_FPSCR );
|
nkeynes@359 | 1274 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 1275 | :}
|
nkeynes@359 | 1276 | STS FPUL, Rn {:
|
nkeynes@359 | 1277 | load_spreg( R_EAX, R_FPUL );
|
nkeynes@359 | 1278 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 1279 | :}
|
nkeynes@359 | 1280 | STS.L FPUL, @-Rn {:
|
nkeynes@359 | 1281 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 1282 | ADD_imm8s_r32( -4, Rn );
|
nkeynes@359 | 1283 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 1284 | load_spreg( R_EAX, R_FPUL );
|
nkeynes@359 | 1285 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 1286 | :}
|
nkeynes@359 | 1287 | STS MACH, Rn {:
|
nkeynes@359 | 1288 | load_spreg( R_EAX, R_MACH );
|
nkeynes@359 | 1289 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 1290 | :}
|
nkeynes@359 | 1291 | STS.L MACH, @-Rn {:
|
nkeynes@359 | 1292 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 1293 | ADD_imm8s_r32( -4, Rn );
|
nkeynes@359 | 1294 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 1295 | load_spreg( R_EAX, R_MACH );
|
nkeynes@359 | 1296 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 1297 | :}
|
nkeynes@359 | 1298 | STS MACL, Rn {:
|
nkeynes@359 | 1299 | load_spreg( R_EAX, R_MACL );
|
nkeynes@359 | 1300 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 1301 | :}
|
nkeynes@359 | 1302 | STS.L MACL, @-Rn {:
|
nkeynes@359 | 1303 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 1304 | ADD_imm8s_r32( -4, Rn );
|
nkeynes@359 | 1305 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 1306 | load_spreg( R_EAX, R_MACL );
|
nkeynes@359 | 1307 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 1308 | :}
|
nkeynes@359 | 1309 | STS PR, Rn {:
|
nkeynes@359 | 1310 | load_spreg( R_EAX, R_PR );
|
nkeynes@359 | 1311 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 1312 | :}
|
nkeynes@359 | 1313 | STS.L PR, @-Rn {:
|
nkeynes@359 | 1314 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 1315 | ADD_imm8s_r32( -4, Rn );
|
nkeynes@359 | 1316 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 1317 | load_spreg( R_EAX, R_PR );
|
nkeynes@359 | 1318 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 1319 | :}
|
nkeynes@359 | 1320 |
|
nkeynes@359 | 1321 | NOP {: /* Do nothing. Well, we could emit an 0x90, but what would really be the point? */ :}
|
nkeynes@359 | 1322 | %%
|
nkeynes@368 | 1323 | INC_r32(R_ESI);
|
nkeynes@359 | 1324 |
|
nkeynes@359 | 1325 | return 0;
|
nkeynes@359 | 1326 | }
|