nkeynes@359 | 1 | /**
|
nkeynes@361 | 2 | * $Id: sh4x86.in,v 1.2 2007-08-28 08:46:14 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@361 | 31 | OP(0x8B);
|
nkeynes@361 | 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@361 | 39 | OP(0x8B);
|
nkeynes@361 | 40 | OP(0x45 + (x86reg<<3));
|
nkeynes@359 | 41 | OP(regoffset);
|
nkeynes@359 | 42 | }
|
nkeynes@359 | 43 |
|
nkeynes@359 | 44 | /**
|
nkeynes@359 | 45 | * Emit an instruction to load an immediate value into a register
|
nkeynes@359 | 46 | */
|
nkeynes@359 | 47 | static inline void load_imm32( int x86reg, uint32_t value ) {
|
nkeynes@359 | 48 | /* mov #value, reg */
|
nkeynes@359 | 49 | OP(0xB8 + x86reg);
|
nkeynes@359 | 50 | OP32(value);
|
nkeynes@359 | 51 | }
|
nkeynes@359 | 52 |
|
nkeynes@359 | 53 | /**
|
nkeynes@359 | 54 | * Emit an instruction to store an SH4 reg (RN)
|
nkeynes@359 | 55 | */
|
nkeynes@359 | 56 | void static inline store_reg( int x86reg, int sh4reg ) {
|
nkeynes@359 | 57 | /* mov reg, [bp+n] */
|
nkeynes@361 | 58 | OP(0x89);
|
nkeynes@361 | 59 | OP(0x45 + (x86reg<<3));
|
nkeynes@359 | 60 | OP(REG_OFFSET(r[sh4reg]));
|
nkeynes@359 | 61 | }
|
nkeynes@359 | 62 | void static inline store_spreg( int x86reg, int regoffset ) {
|
nkeynes@359 | 63 | /* mov reg, [bp+n] */
|
nkeynes@361 | 64 | OP(0x89);
|
nkeynes@361 | 65 | OP(0x45 + (x86reg<<3));
|
nkeynes@359 | 66 | OP(regoffset);
|
nkeynes@359 | 67 | }
|
nkeynes@359 | 68 |
|
nkeynes@361 | 69 | /**
|
nkeynes@361 | 70 | * Note: clobbers EAX to make the indirect call - this isn't usually
|
nkeynes@361 | 71 | * a problem since the callee will usually clobber it anyway.
|
nkeynes@361 | 72 | */
|
nkeynes@361 | 73 | static inline void call_func0( void *ptr )
|
nkeynes@361 | 74 | {
|
nkeynes@361 | 75 | load_imm32(R_EAX, (uint32_t)ptr);
|
nkeynes@361 | 76 | OP(0xFF);
|
nkeynes@361 | 77 | MODRM_rm32_r32(R_EAX, 2);
|
nkeynes@361 | 78 | }
|
nkeynes@361 | 79 |
|
nkeynes@361 | 80 | static inline void call_func1( void *ptr, int arg1 )
|
nkeynes@361 | 81 | {
|
nkeynes@361 | 82 | PUSH_r32(arg1);
|
nkeynes@361 | 83 | call_func0(ptr);
|
nkeynes@361 | 84 | ADD_imm8s_r32( -4, R_ESP );
|
nkeynes@361 | 85 | }
|
nkeynes@361 | 86 |
|
nkeynes@361 | 87 | static inline void call_func2( void *ptr, int arg1, int arg2 )
|
nkeynes@361 | 88 | {
|
nkeynes@361 | 89 | PUSH_r32(arg2);
|
nkeynes@361 | 90 | PUSH_r32(arg1);
|
nkeynes@361 | 91 | call_func0(ptr);
|
nkeynes@361 | 92 | ADD_imm8s_r32( -4, R_ESP );
|
nkeynes@361 | 93 | }
|
nkeynes@361 | 94 |
|
nkeynes@361 | 95 | #define UNDEF()
|
nkeynes@361 | 96 | #define MEM_RESULT(value_reg) if(value_reg != R_EAX) { MOV_r32_r32(R_EAX,value_reg); }
|
nkeynes@361 | 97 | #define MEM_READ_BYTE( addr_reg, value_reg ) call_func1(sh4_read_byte, addr_reg ); MEM_RESULT(value_reg)
|
nkeynes@361 | 98 | #define MEM_READ_WORD( addr_reg, value_reg ) call_func1(sh4_read_word, addr_reg ); MEM_RESULT(value_reg)
|
nkeynes@361 | 99 | #define MEM_READ_LONG( addr_reg, value_reg ) call_func1(sh4_read_long, addr_reg ); MEM_RESULT(value_reg)
|
nkeynes@361 | 100 | #define MEM_WRITE_BYTE( addr_reg, value_reg ) call_func2(sh4_write_byte, addr_reg, value_reg)
|
nkeynes@361 | 101 | #define MEM_WRITE_WORD( addr_reg, value_reg ) call_func2(sh4_write_word, addr_reg, value_reg)
|
nkeynes@361 | 102 | #define MEM_WRITE_LONG( addr_reg, value_reg ) call_func2(sh4_write_long, addr_reg, value_reg)
|
nkeynes@361 | 103 |
|
nkeynes@359 | 104 |
|
nkeynes@359 | 105 | /**
|
nkeynes@359 | 106 | * Emit the 'start of block' assembly. Sets up the stack frame and save
|
nkeynes@359 | 107 | * SI/DI as required
|
nkeynes@359 | 108 | */
|
nkeynes@359 | 109 | void sh4_translate_begin_block() {
|
nkeynes@359 | 110 | /* push ebp */
|
nkeynes@359 | 111 | *xlat_output++ = 0x50 + R_EBP;
|
nkeynes@359 | 112 |
|
nkeynes@359 | 113 | /* mov &sh4r, ebp */
|
nkeynes@359 | 114 | load_imm32( R_EBP, (uint32_t)&sh4r );
|
nkeynes@359 | 115 |
|
nkeynes@359 | 116 | /* load carry from SR */
|
nkeynes@359 | 117 | }
|
nkeynes@359 | 118 |
|
nkeynes@359 | 119 | /**
|
nkeynes@359 | 120 | * Flush any open regs back to memory, restore SI/DI/, update PC, etc
|
nkeynes@359 | 121 | */
|
nkeynes@359 | 122 | void sh4_translate_end_block( sh4addr_t pc ) {
|
nkeynes@359 | 123 | /* pop ebp */
|
nkeynes@359 | 124 | *xlat_output++ = 0x58 + R_EBP;
|
nkeynes@359 | 125 |
|
nkeynes@359 | 126 | /* ret */
|
nkeynes@359 | 127 | *xlat_output++ = 0xC3;
|
nkeynes@359 | 128 | }
|
nkeynes@359 | 129 |
|
nkeynes@359 | 130 | /**
|
nkeynes@359 | 131 | * Translate a single instruction. Delayed branches are handled specially
|
nkeynes@359 | 132 | * by translating both branch and delayed instruction as a single unit (as
|
nkeynes@359 | 133 | *
|
nkeynes@359 | 134 | *
|
nkeynes@359 | 135 | * @return true if the instruction marks the end of a basic block
|
nkeynes@359 | 136 | * (eg a branch or
|
nkeynes@359 | 137 | */
|
nkeynes@359 | 138 | uint32_t sh4_x86_translate_instruction( uint32_t pc )
|
nkeynes@359 | 139 | {
|
nkeynes@361 | 140 | uint16_t ir = sh4_read_word( pc );
|
nkeynes@359 | 141 |
|
nkeynes@359 | 142 | %%
|
nkeynes@359 | 143 | /* ALU operations */
|
nkeynes@359 | 144 | ADD Rm, Rn {:
|
nkeynes@359 | 145 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 146 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 147 | ADD_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 148 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 149 | :}
|
nkeynes@359 | 150 | ADD #imm, Rn {:
|
nkeynes@359 | 151 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 152 | ADD_imm8s_r32( imm, R_EAX );
|
nkeynes@359 | 153 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 154 | :}
|
nkeynes@359 | 155 | ADDC Rm, Rn {:
|
nkeynes@359 | 156 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 157 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 158 | LDC_t();
|
nkeynes@359 | 159 | ADC_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 160 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 161 | SETC_t();
|
nkeynes@359 | 162 | :}
|
nkeynes@359 | 163 | ADDV Rm, Rn {:
|
nkeynes@359 | 164 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 165 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 166 | ADD_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 167 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 168 | SETO_t();
|
nkeynes@359 | 169 | :}
|
nkeynes@359 | 170 | AND Rm, Rn {:
|
nkeynes@359 | 171 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 172 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 173 | AND_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 174 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 175 | :}
|
nkeynes@359 | 176 | AND #imm, R0 {:
|
nkeynes@359 | 177 | load_reg( R_EAX, 0 );
|
nkeynes@359 | 178 | AND_imm32_r32(imm, R_EAX);
|
nkeynes@359 | 179 | store_reg( R_EAX, 0 );
|
nkeynes@359 | 180 | :}
|
nkeynes@359 | 181 | AND.B #imm, @(R0, GBR) {:
|
nkeynes@359 | 182 | load_reg( R_EAX, 0 );
|
nkeynes@359 | 183 | load_spreg( R_ECX, R_GBR );
|
nkeynes@359 | 184 | ADD_r32_r32( R_EAX, R_EBX );
|
nkeynes@359 | 185 | MEM_READ_BYTE( R_ECX, R_EAX );
|
nkeynes@359 | 186 | AND_imm32_r32(imm, R_ECX );
|
nkeynes@359 | 187 | MEM_WRITE_BYTE( R_ECX, R_EAX );
|
nkeynes@359 | 188 | :}
|
nkeynes@359 | 189 | CMP/EQ Rm, Rn {:
|
nkeynes@359 | 190 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 191 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 192 | CMP_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 193 | SETE_t();
|
nkeynes@359 | 194 | :}
|
nkeynes@359 | 195 | CMP/EQ #imm, R0 {:
|
nkeynes@359 | 196 | load_reg( R_EAX, 0 );
|
nkeynes@359 | 197 | CMP_imm8s_r32(imm, R_EAX);
|
nkeynes@359 | 198 | SETE_t();
|
nkeynes@359 | 199 | :}
|
nkeynes@359 | 200 | CMP/GE Rm, Rn {:
|
nkeynes@359 | 201 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 202 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 203 | CMP_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 204 | SETGE_t();
|
nkeynes@359 | 205 | :}
|
nkeynes@359 | 206 | CMP/GT Rm, Rn {:
|
nkeynes@359 | 207 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 208 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 209 | CMP_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 210 | SETG_t();
|
nkeynes@359 | 211 | :}
|
nkeynes@359 | 212 | CMP/HI Rm, Rn {:
|
nkeynes@359 | 213 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 214 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 215 | CMP_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 216 | SETA_t();
|
nkeynes@359 | 217 | :}
|
nkeynes@359 | 218 | CMP/HS Rm, Rn {:
|
nkeynes@359 | 219 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 220 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 221 | CMP_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 222 | SETAE_t();
|
nkeynes@359 | 223 | :}
|
nkeynes@359 | 224 | CMP/PL Rn {:
|
nkeynes@359 | 225 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 226 | CMP_imm8s_r32( 0, R_EAX );
|
nkeynes@359 | 227 | SETG_t();
|
nkeynes@359 | 228 | :}
|
nkeynes@359 | 229 | CMP/PZ Rn {:
|
nkeynes@359 | 230 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 231 | CMP_imm8s_r32( 0, R_EAX );
|
nkeynes@359 | 232 | SETGE_t();
|
nkeynes@359 | 233 | :}
|
nkeynes@361 | 234 | CMP/STR Rm, Rn {:
|
nkeynes@361 | 235 | :}
|
nkeynes@361 | 236 | DIV0S Rm, Rn {:
|
nkeynes@361 | 237 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 238 | load_reg( R_ECX, Rm );
|
nkeynes@361 | 239 | SHR_imm8_r32( 31, R_EAX );
|
nkeynes@361 | 240 | SHR_imm8_r32( 31, R_ECX );
|
nkeynes@361 | 241 | store_spreg( R_EAX, R_M );
|
nkeynes@361 | 242 | store_spreg( R_ECX, R_Q );
|
nkeynes@361 | 243 | CMP_r32_r32( R_EAX, R_ECX );
|
nkeynes@361 | 244 | SETE_t();
|
nkeynes@361 | 245 | :}
|
nkeynes@361 | 246 | DIV0U {:
|
nkeynes@361 | 247 | XOR_r32_r32( R_EAX, R_EAX );
|
nkeynes@361 | 248 | store_spreg( R_EAX, R_Q );
|
nkeynes@361 | 249 | store_spreg( R_EAX, R_M );
|
nkeynes@361 | 250 | store_spreg( R_EAX, R_T );
|
nkeynes@361 | 251 | :}
|
nkeynes@359 | 252 | DIV1 Rm, Rn {: :}
|
nkeynes@361 | 253 | DMULS.L Rm, Rn {:
|
nkeynes@361 | 254 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 255 | load_reg( R_ECX, Rn );
|
nkeynes@361 | 256 | IMUL_r32(R_ECX);
|
nkeynes@361 | 257 | store_spreg( R_EDX, R_MACH );
|
nkeynes@361 | 258 | store_spreg( R_EAX, R_MACL );
|
nkeynes@361 | 259 | :}
|
nkeynes@361 | 260 | DMULU.L Rm, Rn {:
|
nkeynes@361 | 261 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 262 | load_reg( R_ECX, Rn );
|
nkeynes@361 | 263 | MUL_r32(R_ECX);
|
nkeynes@361 | 264 | store_spreg( R_EDX, R_MACH );
|
nkeynes@361 | 265 | store_spreg( R_EAX, R_MACL );
|
nkeynes@361 | 266 | :}
|
nkeynes@359 | 267 | DT Rn {:
|
nkeynes@359 | 268 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 269 | ADD_imm8s_r32( -1, Rn );
|
nkeynes@359 | 270 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 271 | SETE_t();
|
nkeynes@359 | 272 | :}
|
nkeynes@359 | 273 | EXTS.B Rm, Rn {:
|
nkeynes@359 | 274 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 275 | MOVSX_r8_r32( R_EAX, R_EAX );
|
nkeynes@359 | 276 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 277 | :}
|
nkeynes@361 | 278 | EXTS.W Rm, Rn {:
|
nkeynes@361 | 279 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 280 | MOVSX_r16_r32( R_EAX, R_EAX );
|
nkeynes@361 | 281 | store_reg( R_EAX, Rn );
|
nkeynes@361 | 282 | :}
|
nkeynes@361 | 283 | EXTU.B Rm, Rn {:
|
nkeynes@361 | 284 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 285 | MOVZX_r8_r32( R_EAX, R_EAX );
|
nkeynes@361 | 286 | store_reg( R_EAX, Rn );
|
nkeynes@361 | 287 | :}
|
nkeynes@361 | 288 | EXTU.W Rm, Rn {:
|
nkeynes@361 | 289 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 290 | MOVZX_r16_r32( R_EAX, R_EAX );
|
nkeynes@361 | 291 | store_reg( R_EAX, Rn );
|
nkeynes@361 | 292 | :}
|
nkeynes@359 | 293 | MAC.L @Rm+, @Rn+ {: :}
|
nkeynes@359 | 294 | MAC.W @Rm+, @Rn+ {: :}
|
nkeynes@359 | 295 | MOVT Rn {:
|
nkeynes@359 | 296 | load_spreg( R_EAX, R_T );
|
nkeynes@359 | 297 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 298 | :}
|
nkeynes@361 | 299 | MUL.L Rm, Rn {:
|
nkeynes@361 | 300 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 301 | load_reg( R_ECX, Rn );
|
nkeynes@361 | 302 | MUL_r32( R_ECX );
|
nkeynes@361 | 303 | store_spreg( R_EAX, R_MACL );
|
nkeynes@361 | 304 | :}
|
nkeynes@361 | 305 | MULS.W Rm, Rn {:
|
nkeynes@361 | 306 | :}
|
nkeynes@359 | 307 | MULU.W Rm, Rn {: :}
|
nkeynes@359 | 308 | NEG Rm, Rn {:
|
nkeynes@359 | 309 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 310 | NEG_r32( R_EAX );
|
nkeynes@359 | 311 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 312 | :}
|
nkeynes@359 | 313 | NEGC Rm, Rn {:
|
nkeynes@359 | 314 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 315 | XOR_r32_r32( R_ECX, R_ECX );
|
nkeynes@359 | 316 | LDC_t();
|
nkeynes@359 | 317 | SBB_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 318 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 319 | SETC_t();
|
nkeynes@359 | 320 | :}
|
nkeynes@359 | 321 | NOT Rm, Rn {:
|
nkeynes@359 | 322 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 323 | NOT_r32( R_EAX );
|
nkeynes@359 | 324 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 325 | :}
|
nkeynes@359 | 326 | OR Rm, Rn {:
|
nkeynes@359 | 327 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 328 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 329 | OR_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 330 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 331 | :}
|
nkeynes@359 | 332 | OR #imm, R0 {:
|
nkeynes@359 | 333 | load_reg( R_EAX, 0 );
|
nkeynes@359 | 334 | OR_imm32_r32(imm, R_EAX);
|
nkeynes@359 | 335 | store_reg( R_EAX, 0 );
|
nkeynes@359 | 336 | :}
|
nkeynes@359 | 337 | OR.B #imm, @(R0, GBR) {: :}
|
nkeynes@359 | 338 | ROTCL Rn {:
|
nkeynes@359 | 339 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 340 | LDC_t();
|
nkeynes@359 | 341 | RCL1_r32( R_EAX );
|
nkeynes@359 | 342 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 343 | SETC_t();
|
nkeynes@359 | 344 | :}
|
nkeynes@359 | 345 | ROTCR Rn {:
|
nkeynes@359 | 346 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 347 | LDC_t();
|
nkeynes@359 | 348 | RCR1_r32( R_EAX );
|
nkeynes@359 | 349 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 350 | SETC_t();
|
nkeynes@359 | 351 | :}
|
nkeynes@359 | 352 | ROTL Rn {:
|
nkeynes@359 | 353 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 354 | ROL1_r32( R_EAX );
|
nkeynes@359 | 355 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 356 | SETC_t();
|
nkeynes@359 | 357 | :}
|
nkeynes@359 | 358 | ROTR Rn {:
|
nkeynes@359 | 359 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 360 | ROR1_r32( R_EAX );
|
nkeynes@359 | 361 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 362 | SETC_t();
|
nkeynes@359 | 363 | :}
|
nkeynes@359 | 364 | SHAD Rm, Rn {:
|
nkeynes@359 | 365 | /* Annoyingly enough, not directly convertible */
|
nkeynes@361 | 366 | load_reg( R_EAX, Rn );
|
nkeynes@361 | 367 | load_reg( R_ECX, Rm );
|
nkeynes@361 | 368 | CMP_imm32_r32( 0, R_ECX );
|
nkeynes@361 | 369 | JAE_rel8(9);
|
nkeynes@361 | 370 |
|
nkeynes@361 | 371 | NEG_r32( R_ECX ); // 2
|
nkeynes@361 | 372 | AND_imm8_r8( 0x1F, R_CL ); // 3
|
nkeynes@361 | 373 | SAR_r32_CL( R_EAX ); // 2
|
nkeynes@361 | 374 | JMP_rel8(5); // 2
|
nkeynes@361 | 375 |
|
nkeynes@361 | 376 | AND_imm8_r8( 0x1F, R_CL ); // 3
|
nkeynes@361 | 377 | SHL_r32_CL( R_EAX ); // 2
|
nkeynes@361 | 378 |
|
nkeynes@361 | 379 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 380 | :}
|
nkeynes@359 | 381 | SHLD Rm, Rn {:
|
nkeynes@359 | 382 | :}
|
nkeynes@359 | 383 | SHAL Rn {:
|
nkeynes@359 | 384 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 385 | SHL1_r32( R_EAX );
|
nkeynes@359 | 386 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 387 | :}
|
nkeynes@359 | 388 | SHAR Rn {:
|
nkeynes@359 | 389 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 390 | SAR1_r32( R_EAX );
|
nkeynes@359 | 391 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 392 | :}
|
nkeynes@359 | 393 | SHLL Rn {:
|
nkeynes@359 | 394 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 395 | SHL1_r32( R_EAX );
|
nkeynes@359 | 396 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 397 | :}
|
nkeynes@359 | 398 | SHLL2 Rn {:
|
nkeynes@359 | 399 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 400 | SHL_imm8_r32( 2, R_EAX );
|
nkeynes@359 | 401 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 402 | :}
|
nkeynes@359 | 403 | SHLL8 Rn {:
|
nkeynes@359 | 404 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 405 | SHL_imm8_r32( 8, R_EAX );
|
nkeynes@359 | 406 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 407 | :}
|
nkeynes@359 | 408 | SHLL16 Rn {:
|
nkeynes@359 | 409 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 410 | SHL_imm8_r32( 16, R_EAX );
|
nkeynes@359 | 411 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 412 | :}
|
nkeynes@359 | 413 | SHLR Rn {:
|
nkeynes@359 | 414 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 415 | SHR1_r32( R_EAX );
|
nkeynes@359 | 416 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 417 | :}
|
nkeynes@359 | 418 | SHLR2 Rn {:
|
nkeynes@359 | 419 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 420 | SHR_imm8_r32( 2, R_EAX );
|
nkeynes@359 | 421 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 422 | :}
|
nkeynes@359 | 423 | SHLR8 Rn {:
|
nkeynes@359 | 424 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 425 | SHR_imm8_r32( 8, R_EAX );
|
nkeynes@359 | 426 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 427 | :}
|
nkeynes@359 | 428 | SHLR16 Rn {:
|
nkeynes@359 | 429 | load_reg( R_EAX, Rn );
|
nkeynes@359 | 430 | SHR_imm8_r32( 16, R_EAX );
|
nkeynes@359 | 431 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 432 | :}
|
nkeynes@359 | 433 | SUB Rm, Rn {:
|
nkeynes@359 | 434 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 435 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 436 | SUB_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 437 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 438 | :}
|
nkeynes@359 | 439 | SUBC Rm, Rn {:
|
nkeynes@359 | 440 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 441 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 442 | LDC_t();
|
nkeynes@359 | 443 | SBB_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 444 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 445 | :}
|
nkeynes@359 | 446 | SUBV Rm, Rn {:
|
nkeynes@359 | 447 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 448 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 449 | SUB_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 450 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 451 | SETO_t();
|
nkeynes@359 | 452 | :}
|
nkeynes@359 | 453 | SWAP.B Rm, Rn {:
|
nkeynes@359 | 454 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 455 | XCHG_r8_r8( R_AL, R_AH );
|
nkeynes@359 | 456 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 457 | :}
|
nkeynes@359 | 458 | SWAP.W Rm, Rn {:
|
nkeynes@359 | 459 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 460 | MOV_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 461 | SHL_imm8_r32( 16, R_ECX );
|
nkeynes@359 | 462 | SHR_imm8_r32( 16, R_EAX );
|
nkeynes@359 | 463 | OR_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 464 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 465 | :}
|
nkeynes@361 | 466 | TAS.B @Rn {:
|
nkeynes@361 | 467 | load_reg( R_ECX, Rn );
|
nkeynes@361 | 468 | MEM_READ_BYTE( R_ECX, R_EAX );
|
nkeynes@361 | 469 | TEST_r8_r8( R_AL, R_AL );
|
nkeynes@361 | 470 | SETE_t();
|
nkeynes@361 | 471 | OR_imm8_r8( 0x80, R_AL );
|
nkeynes@361 | 472 | MEM_WRITE_BYTE( R_ECX, R_EAX );
|
nkeynes@361 | 473 | :}
|
nkeynes@361 | 474 | TST Rm, Rn {:
|
nkeynes@361 | 475 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 476 | load_reg( R_ECX, Rn );
|
nkeynes@361 | 477 | TEST_r32_r32( R_EAX, R_ECX );
|
nkeynes@361 | 478 | SETE_t();
|
nkeynes@361 | 479 | :}
|
nkeynes@359 | 480 | TST #imm, R0 {: :}
|
nkeynes@359 | 481 | TST.B #imm, @(R0, GBR) {: :}
|
nkeynes@359 | 482 | XOR Rm, Rn {:
|
nkeynes@359 | 483 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 484 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 485 | XOR_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 486 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 487 | :}
|
nkeynes@359 | 488 | XOR #imm, R0 {:
|
nkeynes@359 | 489 | load_reg( R_EAX, 0 );
|
nkeynes@359 | 490 | XOR_imm32_r32( imm, R_EAX );
|
nkeynes@359 | 491 | store_reg( R_EAX, 0 );
|
nkeynes@359 | 492 | :}
|
nkeynes@359 | 493 | XOR.B #imm, @(R0, GBR) {:
|
nkeynes@359 | 494 | load_reg( R_EAX, 0 );
|
nkeynes@359 | 495 | load_spreg( R_ECX, R_GBR );
|
nkeynes@359 | 496 | ADD_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 497 | MEM_READ_BYTE( R_ECX, R_EAX );
|
nkeynes@359 | 498 | XOR_imm32_r32( imm, R_EAX );
|
nkeynes@359 | 499 | MEM_WRITE_BYTE( R_ECX, R_EAX );
|
nkeynes@359 | 500 | :}
|
nkeynes@361 | 501 | XTRCT Rm, Rn {:
|
nkeynes@361 | 502 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 503 | MOV_r32_r32( R_EAX, R_ECX );
|
nkeynes@361 | 504 | SHR_imm8_r32( 16, R_EAX );
|
nkeynes@361 | 505 | SHL_imm8_r32( 16, R_ECX );
|
nkeynes@361 | 506 | OR_r32_r32( R_EAX, R_ECX );
|
nkeynes@361 | 507 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 508 | :}
|
nkeynes@359 | 509 |
|
nkeynes@359 | 510 | /* Data move instructions */
|
nkeynes@359 | 511 | MOV Rm, Rn {:
|
nkeynes@359 | 512 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 513 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 514 | :}
|
nkeynes@359 | 515 | MOV #imm, Rn {:
|
nkeynes@359 | 516 | load_imm32( R_EAX, imm );
|
nkeynes@359 | 517 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 518 | :}
|
nkeynes@359 | 519 | MOV.B Rm, @Rn {:
|
nkeynes@359 | 520 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 521 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 522 | MEM_WRITE_BYTE( R_ECX, R_EAX );
|
nkeynes@359 | 523 | :}
|
nkeynes@359 | 524 | MOV.B Rm, @-Rn {:
|
nkeynes@359 | 525 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 526 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 527 | ADD_imm8s_r32( -1, Rn );
|
nkeynes@359 | 528 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 529 | MEM_WRITE_BYTE( R_ECX, R_EAX );
|
nkeynes@359 | 530 | :}
|
nkeynes@359 | 531 | MOV.B Rm, @(R0, Rn) {:
|
nkeynes@359 | 532 | load_reg( R_EAX, 0 );
|
nkeynes@359 | 533 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 534 | ADD_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 535 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 536 | MEM_WRITE_BYTE( R_ECX, R_EAX );
|
nkeynes@359 | 537 | :}
|
nkeynes@359 | 538 | MOV.B R0, @(disp, GBR) {:
|
nkeynes@359 | 539 | load_reg( R_EAX, 0 );
|
nkeynes@359 | 540 | load_spreg( R_ECX, R_GBR );
|
nkeynes@359 | 541 | ADD_imm32_r32( disp, R_ECX );
|
nkeynes@359 | 542 | MEM_WRITE_BYTE( R_ECX, R_EAX );
|
nkeynes@359 | 543 | :}
|
nkeynes@359 | 544 | MOV.B R0, @(disp, Rn) {:
|
nkeynes@359 | 545 | load_reg( R_EAX, 0 );
|
nkeynes@359 | 546 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 547 | ADD_imm32_r32( disp, R_ECX );
|
nkeynes@359 | 548 | MEM_WRITE_BYTE( R_ECX, R_EAX );
|
nkeynes@359 | 549 | :}
|
nkeynes@359 | 550 | MOV.B @Rm, Rn {:
|
nkeynes@359 | 551 | load_reg( R_ECX, Rm );
|
nkeynes@359 | 552 | MEM_READ_BYTE( R_ECX, R_EAX );
|
nkeynes@359 | 553 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 554 | :}
|
nkeynes@359 | 555 | MOV.B @Rm+, Rn {:
|
nkeynes@359 | 556 | load_reg( R_ECX, Rm );
|
nkeynes@359 | 557 | MOV_r32_r32( R_ECX, R_EAX );
|
nkeynes@359 | 558 | ADD_imm8s_r32( 1, R_EAX );
|
nkeynes@359 | 559 | store_reg( R_EAX, Rm );
|
nkeynes@359 | 560 | MEM_READ_BYTE( R_ECX, R_EAX );
|
nkeynes@359 | 561 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 562 | :}
|
nkeynes@359 | 563 | MOV.B @(R0, Rm), Rn {:
|
nkeynes@359 | 564 | load_reg( R_EAX, 0 );
|
nkeynes@359 | 565 | load_reg( R_ECX, Rm );
|
nkeynes@359 | 566 | ADD_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 567 | MEM_READ_BYTE( R_ECX, R_EAX );
|
nkeynes@359 | 568 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 569 | :}
|
nkeynes@359 | 570 | MOV.B @(disp, GBR), R0 {:
|
nkeynes@359 | 571 | load_spreg( R_ECX, R_GBR );
|
nkeynes@359 | 572 | ADD_imm32_r32( disp, R_ECX );
|
nkeynes@359 | 573 | MEM_READ_BYTE( R_ECX, R_EAX );
|
nkeynes@359 | 574 | store_reg( R_EAX, 0 );
|
nkeynes@359 | 575 | :}
|
nkeynes@359 | 576 | MOV.B @(disp, Rm), R0 {:
|
nkeynes@359 | 577 | load_reg( R_ECX, Rm );
|
nkeynes@359 | 578 | ADD_imm32_r32( disp, R_ECX );
|
nkeynes@359 | 579 | MEM_READ_BYTE( R_ECX, R_EAX );
|
nkeynes@359 | 580 | store_reg( R_EAX, 0 );
|
nkeynes@359 | 581 | :}
|
nkeynes@361 | 582 | MOV.L Rm, @Rn {:
|
nkeynes@361 | 583 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 584 | load_reg( R_ECX, Rn );
|
nkeynes@361 | 585 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@361 | 586 | :}
|
nkeynes@361 | 587 | MOV.L Rm, @-Rn {:
|
nkeynes@361 | 588 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 589 | load_reg( R_ECX, Rn );
|
nkeynes@361 | 590 | ADD_imm8s_r32( -4, R_ECX );
|
nkeynes@361 | 591 | store_reg( R_ECX, Rn );
|
nkeynes@361 | 592 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@361 | 593 | :}
|
nkeynes@361 | 594 | MOV.L Rm, @(R0, Rn) {:
|
nkeynes@361 | 595 | load_reg( R_EAX, 0 );
|
nkeynes@361 | 596 | load_reg( R_ECX, Rn );
|
nkeynes@361 | 597 | ADD_r32_r32( R_EAX, R_ECX );
|
nkeynes@361 | 598 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 599 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@361 | 600 | :}
|
nkeynes@361 | 601 | MOV.L R0, @(disp, GBR) {:
|
nkeynes@361 | 602 | load_spreg( R_ECX, R_GBR );
|
nkeynes@361 | 603 | load_reg( R_EAX, 0 );
|
nkeynes@361 | 604 | ADD_imm32_r32( disp, R_ECX );
|
nkeynes@361 | 605 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@361 | 606 | :}
|
nkeynes@361 | 607 | MOV.L Rm, @(disp, Rn) {:
|
nkeynes@361 | 608 | load_reg( R_ECX, Rn );
|
nkeynes@361 | 609 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 610 | ADD_imm32_r32( disp, R_ECX );
|
nkeynes@361 | 611 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@361 | 612 | :}
|
nkeynes@361 | 613 | MOV.L @Rm, Rn {:
|
nkeynes@361 | 614 | load_reg( R_ECX, Rm );
|
nkeynes@361 | 615 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@361 | 616 | store_reg( R_EAX, Rn );
|
nkeynes@361 | 617 | :}
|
nkeynes@361 | 618 | MOV.L @Rm+, Rn {:
|
nkeynes@361 | 619 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 620 | MOV_r32_r32( R_EAX, R_ECX );
|
nkeynes@361 | 621 | ADD_imm8s_r32( 4, R_EAX );
|
nkeynes@361 | 622 | store_reg( R_EAX, Rm );
|
nkeynes@361 | 623 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@361 | 624 | store_reg( R_EAX, Rn );
|
nkeynes@361 | 625 | :}
|
nkeynes@361 | 626 | MOV.L @(R0, Rm), Rn {:
|
nkeynes@361 | 627 | load_reg( R_EAX, 0 );
|
nkeynes@361 | 628 | load_reg( R_ECX, Rm );
|
nkeynes@361 | 629 | ADD_r32_r32( R_EAX, R_ECX );
|
nkeynes@361 | 630 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@361 | 631 | store_reg( R_EAX, Rn );
|
nkeynes@361 | 632 | :}
|
nkeynes@361 | 633 | MOV.L @(disp, GBR), R0 {:
|
nkeynes@361 | 634 | load_spreg( R_ECX, R_GBR );
|
nkeynes@361 | 635 | ADD_imm32_r32( disp, R_ECX );
|
nkeynes@361 | 636 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@361 | 637 | store_reg( R_EAX, 0 );
|
nkeynes@361 | 638 | :}
|
nkeynes@361 | 639 | MOV.L @(disp, PC), Rn {:
|
nkeynes@361 | 640 | load_imm32( R_ECX, (pc & 0xFFFFFFFC) + disp + 4 );
|
nkeynes@361 | 641 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@361 | 642 | store_reg( R_EAX, 0 );
|
nkeynes@361 | 643 | :}
|
nkeynes@361 | 644 | MOV.L @(disp, Rm), Rn {:
|
nkeynes@361 | 645 | load_reg( R_ECX, Rm );
|
nkeynes@361 | 646 | ADD_imm8s_r32( disp, R_ECX );
|
nkeynes@361 | 647 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@361 | 648 | store_reg( R_EAX, Rn );
|
nkeynes@361 | 649 | :}
|
nkeynes@361 | 650 | MOV.W Rm, @Rn {:
|
nkeynes@361 | 651 | load_reg( R_ECX, Rn );
|
nkeynes@361 | 652 | MEM_READ_WORD( R_ECX, R_EAX );
|
nkeynes@361 | 653 | store_reg( R_EAX, Rn );
|
nkeynes@361 | 654 | :}
|
nkeynes@361 | 655 | MOV.W Rm, @-Rn {:
|
nkeynes@361 | 656 | load_reg( R_ECX, Rn );
|
nkeynes@361 | 657 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 658 | ADD_imm8s_r32( -2, R_ECX );
|
nkeynes@361 | 659 | MEM_WRITE_WORD( R_ECX, R_EAX );
|
nkeynes@361 | 660 | :}
|
nkeynes@361 | 661 | MOV.W Rm, @(R0, Rn) {:
|
nkeynes@361 | 662 | load_reg( R_EAX, 0 );
|
nkeynes@361 | 663 | load_reg( R_ECX, Rn );
|
nkeynes@361 | 664 | ADD_r32_r32( R_EAX, R_ECX );
|
nkeynes@361 | 665 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 666 | MEM_WRITE_WORD( R_ECX, R_EAX );
|
nkeynes@361 | 667 | :}
|
nkeynes@361 | 668 | MOV.W R0, @(disp, GBR) {:
|
nkeynes@361 | 669 | load_spreg( R_ECX, R_GBR );
|
nkeynes@361 | 670 | load_reg( R_EAX, 0 );
|
nkeynes@361 | 671 | ADD_imm32_r32( disp, R_ECX );
|
nkeynes@361 | 672 | MEM_WRITE_WORD( R_ECX, R_EAX );
|
nkeynes@361 | 673 | :}
|
nkeynes@361 | 674 | MOV.W R0, @(disp, Rn) {:
|
nkeynes@361 | 675 | load_reg( R_ECX, Rn );
|
nkeynes@361 | 676 | load_reg( R_EAX, 0 );
|
nkeynes@361 | 677 | ADD_imm32_r32( disp, R_ECX );
|
nkeynes@361 | 678 | MEM_WRITE_WORD( R_ECX, R_EAX );
|
nkeynes@361 | 679 | :}
|
nkeynes@361 | 680 | MOV.W @Rm, Rn {:
|
nkeynes@361 | 681 | load_reg( R_ECX, Rm );
|
nkeynes@361 | 682 | MEM_READ_WORD( R_ECX, R_EAX );
|
nkeynes@361 | 683 | store_reg( R_EAX, Rn );
|
nkeynes@361 | 684 | :}
|
nkeynes@361 | 685 | MOV.W @Rm+, Rn {:
|
nkeynes@361 | 686 | load_reg( R_EAX, Rm );
|
nkeynes@361 | 687 | MOV_r32_r32( R_EAX, R_ECX );
|
nkeynes@361 | 688 | ADD_imm8s_r32( 2, R_EAX );
|
nkeynes@361 | 689 | store_reg( R_EAX, Rm );
|
nkeynes@361 | 690 | MEM_READ_WORD( R_ECX, R_EAX );
|
nkeynes@361 | 691 | store_reg( R_EAX, Rn );
|
nkeynes@361 | 692 | :}
|
nkeynes@361 | 693 | MOV.W @(R0, Rm), Rn {:
|
nkeynes@361 | 694 | load_reg( R_EAX, 0 );
|
nkeynes@361 | 695 | load_reg( R_ECX, Rm );
|
nkeynes@361 | 696 | ADD_r32_r32( R_EAX, R_ECX );
|
nkeynes@361 | 697 | MEM_READ_WORD( R_ECX, R_EAX );
|
nkeynes@361 | 698 | store_reg( R_EAX, Rn );
|
nkeynes@361 | 699 | :}
|
nkeynes@361 | 700 | MOV.W @(disp, GBR), R0 {:
|
nkeynes@361 | 701 | load_spreg( R_ECX, R_GBR );
|
nkeynes@361 | 702 | ADD_imm32_r32( disp, R_ECX );
|
nkeynes@361 | 703 | MEM_READ_WORD( R_ECX, R_EAX );
|
nkeynes@361 | 704 | store_reg( R_EAX, 0 );
|
nkeynes@361 | 705 | :}
|
nkeynes@361 | 706 | MOV.W @(disp, PC), Rn {:
|
nkeynes@361 | 707 | load_imm32( R_ECX, pc + disp + 4 );
|
nkeynes@361 | 708 | MEM_READ_WORD( R_ECX, R_EAX );
|
nkeynes@361 | 709 | store_reg( R_EAX, Rn );
|
nkeynes@361 | 710 | :}
|
nkeynes@361 | 711 | MOV.W @(disp, Rm), R0 {:
|
nkeynes@361 | 712 | load_reg( R_ECX, Rm );
|
nkeynes@361 | 713 | ADD_imm32_r32( disp, R_ECX );
|
nkeynes@361 | 714 | MEM_READ_WORD( R_ECX, R_EAX );
|
nkeynes@361 | 715 | store_reg( R_EAX, 0 );
|
nkeynes@361 | 716 | :}
|
nkeynes@361 | 717 | MOVA @(disp, PC), R0 {:
|
nkeynes@361 | 718 | load_imm32( R_ECX, (pc & 0xFFFFFFFC) + disp + 4 );
|
nkeynes@361 | 719 | store_reg( R_ECX, 0 );
|
nkeynes@361 | 720 | :}
|
nkeynes@361 | 721 | MOVCA.L R0, @Rn {:
|
nkeynes@361 | 722 | load_reg( R_EAX, 0 );
|
nkeynes@361 | 723 | load_reg( R_ECX, Rn );
|
nkeynes@361 | 724 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@361 | 725 | :}
|
nkeynes@359 | 726 |
|
nkeynes@359 | 727 | /* Control transfer instructions */
|
nkeynes@359 | 728 | BF disp {: :}
|
nkeynes@359 | 729 | BF/S disp {: :}
|
nkeynes@359 | 730 | BRA disp {: :}
|
nkeynes@359 | 731 | BRAF Rn {: :}
|
nkeynes@359 | 732 | BSR disp {: :}
|
nkeynes@359 | 733 | BSRF Rn {: :}
|
nkeynes@359 | 734 | BT disp {: /* If true, result PC += 4 + disp. else result PC = pc+2 */
|
nkeynes@359 | 735 | return pc + 2;
|
nkeynes@359 | 736 | :}
|
nkeynes@359 | 737 | BT/S disp {:
|
nkeynes@359 | 738 |
|
nkeynes@359 | 739 | return pc + 4;
|
nkeynes@359 | 740 | :}
|
nkeynes@359 | 741 | JMP @Rn {: :}
|
nkeynes@359 | 742 | JSR @Rn {: :}
|
nkeynes@359 | 743 | RTE {: :}
|
nkeynes@359 | 744 | RTS {: :}
|
nkeynes@359 | 745 | TRAPA #imm {: :}
|
nkeynes@359 | 746 | UNDEF {: :}
|
nkeynes@359 | 747 |
|
nkeynes@359 | 748 | CLRMAC {: :}
|
nkeynes@359 | 749 | CLRS {: :}
|
nkeynes@359 | 750 | CLRT {: :}
|
nkeynes@359 | 751 | SETS {: :}
|
nkeynes@359 | 752 | SETT {: :}
|
nkeynes@359 | 753 |
|
nkeynes@359 | 754 | /* Floating point instructions */
|
nkeynes@359 | 755 | FABS FRn {: :}
|
nkeynes@359 | 756 | FADD FRm, FRn {: :}
|
nkeynes@359 | 757 | FCMP/EQ FRm, FRn {: :}
|
nkeynes@359 | 758 | FCMP/GT FRm, FRn {: :}
|
nkeynes@359 | 759 | FCNVDS FRm, FPUL {: :}
|
nkeynes@359 | 760 | FCNVSD FPUL, FRn {: :}
|
nkeynes@359 | 761 | FDIV FRm, FRn {: :}
|
nkeynes@359 | 762 | FIPR FVm, FVn {: :}
|
nkeynes@359 | 763 | FLDS FRm, FPUL {: :}
|
nkeynes@359 | 764 | FLDI0 FRn {: :}
|
nkeynes@359 | 765 | FLDI1 FRn {: :}
|
nkeynes@359 | 766 | FLOAT FPUL, FRn {: :}
|
nkeynes@359 | 767 | FMAC FR0, FRm, FRn {: :}
|
nkeynes@359 | 768 | FMOV FRm, FRn {: :}
|
nkeynes@359 | 769 | FMOV FRm, @Rn {: :}
|
nkeynes@359 | 770 | FMOV FRm, @-Rn {: :}
|
nkeynes@359 | 771 | FMOV FRm, @(R0, Rn) {: :}
|
nkeynes@359 | 772 | FMOV @Rm, FRn {: :}
|
nkeynes@359 | 773 | FMOV @Rm+, FRn {: :}
|
nkeynes@359 | 774 | FMOV @(R0, Rm), FRn {: :}
|
nkeynes@359 | 775 | FMUL FRm, FRn {: :}
|
nkeynes@359 | 776 | FNEG FRn {: :}
|
nkeynes@359 | 777 | FRCHG {: :}
|
nkeynes@359 | 778 | FSCA FPUL, FRn {: :}
|
nkeynes@359 | 779 | FSCHG {: :}
|
nkeynes@359 | 780 | FSQRT FRn {: :}
|
nkeynes@359 | 781 | FSRRA FRn {: :}
|
nkeynes@359 | 782 | FSTS FPUL, FRn {: :}
|
nkeynes@359 | 783 | FSUB FRm, FRn {: :}
|
nkeynes@359 | 784 | FTRC FRm, FPUL {: :}
|
nkeynes@359 | 785 | FTRV XMTRX, FVn {: :}
|
nkeynes@359 | 786 |
|
nkeynes@359 | 787 | /* Processor control instructions */
|
nkeynes@359 | 788 | LDC Rm, SR {: /* We need to be a little careful about SR */ :}
|
nkeynes@359 | 789 | LDC Rm, GBR {:
|
nkeynes@359 | 790 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 791 | store_spreg( R_EAX, R_GBR );
|
nkeynes@359 | 792 | :}
|
nkeynes@359 | 793 | LDC Rm, VBR {:
|
nkeynes@359 | 794 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 795 | store_spreg( R_EAX, R_VBR );
|
nkeynes@359 | 796 | :}
|
nkeynes@359 | 797 | LDC Rm, SSR {:
|
nkeynes@359 | 798 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 799 | store_spreg( R_EAX, R_SSR );
|
nkeynes@359 | 800 | :}
|
nkeynes@359 | 801 | LDC Rm, SGR {:
|
nkeynes@359 | 802 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 803 | store_spreg( R_EAX, R_SGR );
|
nkeynes@359 | 804 | :}
|
nkeynes@359 | 805 | LDC Rm, SPC {:
|
nkeynes@359 | 806 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 807 | store_spreg( R_EAX, R_SPC );
|
nkeynes@359 | 808 | :}
|
nkeynes@359 | 809 | LDC Rm, DBR {:
|
nkeynes@359 | 810 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 811 | store_spreg( R_EAX, R_DBR );
|
nkeynes@359 | 812 | :}
|
nkeynes@359 | 813 | LDC Rm, Rn_BANK {: :}
|
nkeynes@359 | 814 | LDC.L @Rm+, GBR {:
|
nkeynes@359 | 815 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 816 | MOV_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 817 | ADD_imm8s_r32( 4, R_EAX );
|
nkeynes@359 | 818 | store_reg( R_EAX, Rm );
|
nkeynes@359 | 819 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 820 | store_spreg( R_EAX, R_GBR );
|
nkeynes@359 | 821 | :}
|
nkeynes@359 | 822 | LDC.L @Rm+, SR {:
|
nkeynes@359 | 823 | :}
|
nkeynes@359 | 824 | LDC.L @Rm+, VBR {:
|
nkeynes@359 | 825 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 826 | MOV_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 827 | ADD_imm8s_r32( 4, R_EAX );
|
nkeynes@359 | 828 | store_reg( R_EAX, Rm );
|
nkeynes@359 | 829 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 830 | store_spreg( R_EAX, R_VBR );
|
nkeynes@359 | 831 | :}
|
nkeynes@359 | 832 | LDC.L @Rm+, SSR {:
|
nkeynes@359 | 833 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 834 | MOV_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 835 | ADD_imm8s_r32( 4, R_EAX );
|
nkeynes@359 | 836 | store_reg( R_EAX, Rm );
|
nkeynes@359 | 837 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 838 | store_spreg( R_EAX, R_SSR );
|
nkeynes@359 | 839 | :}
|
nkeynes@359 | 840 | LDC.L @Rm+, SGR {:
|
nkeynes@359 | 841 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 842 | MOV_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 843 | ADD_imm8s_r32( 4, R_EAX );
|
nkeynes@359 | 844 | store_reg( R_EAX, Rm );
|
nkeynes@359 | 845 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 846 | store_spreg( R_EAX, R_SGR );
|
nkeynes@359 | 847 | :}
|
nkeynes@359 | 848 | LDC.L @Rm+, SPC {:
|
nkeynes@359 | 849 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 850 | MOV_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 851 | ADD_imm8s_r32( 4, R_EAX );
|
nkeynes@359 | 852 | store_reg( R_EAX, Rm );
|
nkeynes@359 | 853 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 854 | store_spreg( R_EAX, R_SPC );
|
nkeynes@359 | 855 | :}
|
nkeynes@359 | 856 | LDC.L @Rm+, DBR {:
|
nkeynes@359 | 857 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 858 | MOV_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 859 | ADD_imm8s_r32( 4, R_EAX );
|
nkeynes@359 | 860 | store_reg( R_EAX, Rm );
|
nkeynes@359 | 861 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 862 | store_spreg( R_EAX, R_DBR );
|
nkeynes@359 | 863 | :}
|
nkeynes@359 | 864 | LDC.L @Rm+, Rn_BANK {:
|
nkeynes@359 | 865 | :}
|
nkeynes@359 | 866 | LDS Rm, FPSCR {:
|
nkeynes@359 | 867 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 868 | store_spreg( R_EAX, R_FPSCR );
|
nkeynes@359 | 869 | :}
|
nkeynes@359 | 870 | LDS.L @Rm+, FPSCR {:
|
nkeynes@359 | 871 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 872 | MOV_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 873 | ADD_imm8s_r32( 4, R_EAX );
|
nkeynes@359 | 874 | store_reg( R_EAX, Rm );
|
nkeynes@359 | 875 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 876 | store_spreg( R_EAX, R_FPSCR );
|
nkeynes@359 | 877 | :}
|
nkeynes@359 | 878 | LDS Rm, FPUL {:
|
nkeynes@359 | 879 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 880 | store_spreg( R_EAX, R_FPUL );
|
nkeynes@359 | 881 | :}
|
nkeynes@359 | 882 | LDS.L @Rm+, FPUL {:
|
nkeynes@359 | 883 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 884 | MOV_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 885 | ADD_imm8s_r32( 4, R_EAX );
|
nkeynes@359 | 886 | store_reg( R_EAX, Rm );
|
nkeynes@359 | 887 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 888 | store_spreg( R_EAX, R_FPUL );
|
nkeynes@359 | 889 | :}
|
nkeynes@359 | 890 | LDS Rm, MACH {:
|
nkeynes@359 | 891 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 892 | store_spreg( R_EAX, R_MACH );
|
nkeynes@359 | 893 | :}
|
nkeynes@359 | 894 | LDS.L @Rm+, MACH {:
|
nkeynes@359 | 895 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 896 | MOV_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 897 | ADD_imm8s_r32( 4, R_EAX );
|
nkeynes@359 | 898 | store_reg( R_EAX, Rm );
|
nkeynes@359 | 899 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 900 | store_spreg( R_EAX, R_MACH );
|
nkeynes@359 | 901 | :}
|
nkeynes@359 | 902 | LDS Rm, MACL {:
|
nkeynes@359 | 903 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 904 | store_spreg( R_EAX, R_MACL );
|
nkeynes@359 | 905 | :}
|
nkeynes@359 | 906 | LDS.L @Rm+, MACL {:
|
nkeynes@359 | 907 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 908 | MOV_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 909 | ADD_imm8s_r32( 4, R_EAX );
|
nkeynes@359 | 910 | store_reg( R_EAX, Rm );
|
nkeynes@359 | 911 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 912 | store_spreg( R_EAX, R_MACL );
|
nkeynes@359 | 913 | :}
|
nkeynes@359 | 914 | LDS Rm, PR {:
|
nkeynes@359 | 915 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 916 | store_spreg( R_EAX, R_PR );
|
nkeynes@359 | 917 | :}
|
nkeynes@359 | 918 | LDS.L @Rm+, PR {:
|
nkeynes@359 | 919 | load_reg( R_EAX, Rm );
|
nkeynes@359 | 920 | MOV_r32_r32( R_EAX, R_ECX );
|
nkeynes@359 | 921 | ADD_imm8s_r32( 4, R_EAX );
|
nkeynes@359 | 922 | store_reg( R_EAX, Rm );
|
nkeynes@359 | 923 | MEM_READ_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 924 | store_spreg( R_EAX, R_PR );
|
nkeynes@359 | 925 | :}
|
nkeynes@359 | 926 | LDTLB {: :}
|
nkeynes@359 | 927 | OCBI @Rn {: :}
|
nkeynes@359 | 928 | OCBP @Rn {: :}
|
nkeynes@359 | 929 | OCBWB @Rn {: :}
|
nkeynes@359 | 930 | PREF @Rn {: :}
|
nkeynes@359 | 931 | SLEEP {: :}
|
nkeynes@359 | 932 | STC SR, Rn {: /* TODO */
|
nkeynes@359 | 933 | :}
|
nkeynes@359 | 934 | STC GBR, Rn {:
|
nkeynes@359 | 935 | load_spreg( R_EAX, R_GBR );
|
nkeynes@359 | 936 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 937 | :}
|
nkeynes@359 | 938 | STC VBR, Rn {:
|
nkeynes@359 | 939 | load_spreg( R_EAX, R_VBR );
|
nkeynes@359 | 940 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 941 | :}
|
nkeynes@359 | 942 | STC SSR, Rn {:
|
nkeynes@359 | 943 | load_spreg( R_EAX, R_SSR );
|
nkeynes@359 | 944 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 945 | :}
|
nkeynes@359 | 946 | STC SPC, Rn {:
|
nkeynes@359 | 947 | load_spreg( R_EAX, R_SPC );
|
nkeynes@359 | 948 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 949 | :}
|
nkeynes@359 | 950 | STC SGR, Rn {:
|
nkeynes@359 | 951 | load_spreg( R_EAX, R_SGR );
|
nkeynes@359 | 952 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 953 | :}
|
nkeynes@359 | 954 | STC DBR, Rn {:
|
nkeynes@359 | 955 | load_spreg( R_EAX, R_DBR );
|
nkeynes@359 | 956 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 957 | :}
|
nkeynes@359 | 958 | STC Rm_BANK, Rn {: /* TODO */
|
nkeynes@359 | 959 | :}
|
nkeynes@359 | 960 | STC.L SR, @-Rn {: /* TODO */
|
nkeynes@359 | 961 | :}
|
nkeynes@359 | 962 | STC.L VBR, @-Rn {:
|
nkeynes@359 | 963 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 964 | ADD_imm8s_r32( -4, Rn );
|
nkeynes@359 | 965 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 966 | load_spreg( R_EAX, R_VBR );
|
nkeynes@359 | 967 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 968 | :}
|
nkeynes@359 | 969 | STC.L SSR, @-Rn {:
|
nkeynes@359 | 970 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 971 | ADD_imm8s_r32( -4, Rn );
|
nkeynes@359 | 972 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 973 | load_spreg( R_EAX, R_SSR );
|
nkeynes@359 | 974 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 975 | :}
|
nkeynes@359 | 976 | STC.L SPC, @-Rn {:
|
nkeynes@359 | 977 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 978 | ADD_imm8s_r32( -4, Rn );
|
nkeynes@359 | 979 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 980 | load_spreg( R_EAX, R_SPC );
|
nkeynes@359 | 981 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 982 | :}
|
nkeynes@359 | 983 | STC.L SGR, @-Rn {:
|
nkeynes@359 | 984 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 985 | ADD_imm8s_r32( -4, Rn );
|
nkeynes@359 | 986 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 987 | load_spreg( R_EAX, R_SGR );
|
nkeynes@359 | 988 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 989 | :}
|
nkeynes@359 | 990 | STC.L DBR, @-Rn {:
|
nkeynes@359 | 991 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 992 | ADD_imm8s_r32( -4, Rn );
|
nkeynes@359 | 993 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 994 | load_spreg( R_EAX, R_DBR );
|
nkeynes@359 | 995 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 996 | :}
|
nkeynes@359 | 997 | STC.L Rm_BANK, @-Rn {: :}
|
nkeynes@359 | 998 | STC.L GBR, @-Rn {:
|
nkeynes@359 | 999 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 1000 | ADD_imm8s_r32( -4, Rn );
|
nkeynes@359 | 1001 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 1002 | load_spreg( R_EAX, R_GBR );
|
nkeynes@359 | 1003 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 1004 | :}
|
nkeynes@359 | 1005 | STS FPSCR, Rn {:
|
nkeynes@359 | 1006 | load_spreg( R_EAX, R_FPSCR );
|
nkeynes@359 | 1007 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 1008 | :}
|
nkeynes@359 | 1009 | STS.L FPSCR, @-Rn {:
|
nkeynes@359 | 1010 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 1011 | ADD_imm8s_r32( -4, Rn );
|
nkeynes@359 | 1012 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 1013 | load_spreg( R_EAX, R_FPSCR );
|
nkeynes@359 | 1014 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 1015 | :}
|
nkeynes@359 | 1016 | STS FPUL, Rn {:
|
nkeynes@359 | 1017 | load_spreg( R_EAX, R_FPUL );
|
nkeynes@359 | 1018 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 1019 | :}
|
nkeynes@359 | 1020 | STS.L FPUL, @-Rn {:
|
nkeynes@359 | 1021 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 1022 | ADD_imm8s_r32( -4, Rn );
|
nkeynes@359 | 1023 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 1024 | load_spreg( R_EAX, R_FPUL );
|
nkeynes@359 | 1025 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 1026 | :}
|
nkeynes@359 | 1027 | STS MACH, Rn {:
|
nkeynes@359 | 1028 | load_spreg( R_EAX, R_MACH );
|
nkeynes@359 | 1029 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 1030 | :}
|
nkeynes@359 | 1031 | STS.L MACH, @-Rn {:
|
nkeynes@359 | 1032 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 1033 | ADD_imm8s_r32( -4, Rn );
|
nkeynes@359 | 1034 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 1035 | load_spreg( R_EAX, R_MACH );
|
nkeynes@359 | 1036 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 1037 | :}
|
nkeynes@359 | 1038 | STS MACL, Rn {:
|
nkeynes@359 | 1039 | load_spreg( R_EAX, R_MACL );
|
nkeynes@359 | 1040 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 1041 | :}
|
nkeynes@359 | 1042 | STS.L MACL, @-Rn {:
|
nkeynes@359 | 1043 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 1044 | ADD_imm8s_r32( -4, Rn );
|
nkeynes@359 | 1045 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 1046 | load_spreg( R_EAX, R_MACL );
|
nkeynes@359 | 1047 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 1048 | :}
|
nkeynes@359 | 1049 | STS PR, Rn {:
|
nkeynes@359 | 1050 | load_spreg( R_EAX, R_PR );
|
nkeynes@359 | 1051 | store_reg( R_EAX, Rn );
|
nkeynes@359 | 1052 | :}
|
nkeynes@359 | 1053 | STS.L PR, @-Rn {:
|
nkeynes@359 | 1054 | load_reg( R_ECX, Rn );
|
nkeynes@359 | 1055 | ADD_imm8s_r32( -4, Rn );
|
nkeynes@359 | 1056 | store_reg( R_ECX, Rn );
|
nkeynes@359 | 1057 | load_spreg( R_EAX, R_PR );
|
nkeynes@359 | 1058 | MEM_WRITE_LONG( R_ECX, R_EAX );
|
nkeynes@359 | 1059 | :}
|
nkeynes@359 | 1060 |
|
nkeynes@359 | 1061 | NOP {: /* Do nothing. Well, we could emit an 0x90, but what would really be the point? */ :}
|
nkeynes@359 | 1062 | %%
|
nkeynes@359 | 1063 |
|
nkeynes@359 | 1064 | return 0;
|
nkeynes@359 | 1065 | }
|