Search
lxdream.org :: lxdream/src/sh4/sh4x86.in :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4x86.in
changeset 359:c588dce7ebde
next361:be3de4ecd954
author nkeynes
date Thu Aug 23 12:33:27 2007 +0000 (13 years ago)
permissions -rw-r--r--
last change Commit decoder generator
Translator work in progress
Fix mac.l, mac.w in emu core
file annotate diff log raw
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/sh4/sh4x86.in Thu Aug 23 12:33:27 2007 +0000
1.3 @@ -0,0 +1,843 @@
1.4 +/**
1.5 + * $Id: sh4x86.in,v 1.1 2007-08-23 12:33:27 nkeynes Exp $
1.6 + *
1.7 + * SH4 => x86 translation. This version does no real optimization, it just
1.8 + * outputs straight-line x86 code - it mainly exists to provide a baseline
1.9 + * to test the optimizing versions against.
1.10 + *
1.11 + * Copyright (c) 2007 Nathan Keynes.
1.12 + *
1.13 + * This program is free software; you can redistribute it and/or modify
1.14 + * it under the terms of the GNU General Public License as published by
1.15 + * the Free Software Foundation; either version 2 of the License, or
1.16 + * (at your option) any later version.
1.17 + *
1.18 + * This program is distributed in the hope that it will be useful,
1.19 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.20 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.21 + * GNU General Public License for more details.
1.22 + */
1.23 +
1.24 +#include "sh4core.h"
1.25 +#include "sh4trans.h"
1.26 +#include "x86op.h"
1.27 +
1.28 +/**
1.29 + * Emit an instruction to load an SH4 reg into a real register
1.30 + */
1.31 +static inline void load_reg( int x86reg, int sh4reg )
1.32 +{
1.33 + /* mov [bp+n], reg */
1.34 + OP(0x89);
1.35 + OP(0x45 + x86reg<<3);
1.36 + OP(REG_OFFSET(r[sh4reg]));
1.37 +}
1.38 +
1.39 +static inline void load_spreg( int x86reg, int regoffset )
1.40 +{
1.41 + /* mov [bp+n], reg */
1.42 + OP(0x89);
1.43 + OP(0x45 + x86reg<<3);
1.44 + OP(regoffset);
1.45 +}
1.46 +
1.47 +#define UNDEF()
1.48 +#define MEM_READ_BYTE( addr_reg, value_reg )
1.49 +#define MEM_READ_WORD( addr_reg, value_reg )
1.50 +#define MEM_READ_LONG( addr_reg, value_reg )
1.51 +#define MEM_WRITE_BYTE( addr_reg, value_reg )
1.52 +#define MEM_WRITE_WORD( addr_reg, value_reg )
1.53 +#define MEM_WRITE_LONG( addr_reg, value_reg )
1.54 +
1.55 +/**
1.56 + * Emit an instruction to load an immediate value into a register
1.57 + */
1.58 +static inline void load_imm32( int x86reg, uint32_t value ) {
1.59 + /* mov #value, reg */
1.60 + OP(0xB8 + x86reg);
1.61 + OP32(value);
1.62 +}
1.63 +
1.64 +/**
1.65 + * Emit an instruction to store an SH4 reg (RN)
1.66 + */
1.67 +void static inline store_reg( int x86reg, int sh4reg ) {
1.68 + /* mov reg, [bp+n] */
1.69 + OP(0x8B);
1.70 + OP(0x45 + x86reg<<3);
1.71 + OP(REG_OFFSET(r[sh4reg]));
1.72 +}
1.73 +void static inline store_spreg( int x86reg, int regoffset ) {
1.74 + /* mov reg, [bp+n] */
1.75 + OP(0x8B);
1.76 + OP(0x45 + x86reg<<3);
1.77 + OP(regoffset);
1.78 +}
1.79 +
1.80 +
1.81 +/**
1.82 + * Emit the 'start of block' assembly. Sets up the stack frame and save
1.83 + * SI/DI as required
1.84 + */
1.85 +void sh4_translate_begin_block() {
1.86 + /* push ebp */
1.87 + *xlat_output++ = 0x50 + R_EBP;
1.88 +
1.89 + /* mov &sh4r, ebp */
1.90 + load_imm32( R_EBP, (uint32_t)&sh4r );
1.91 +
1.92 + /* load carry from SR */
1.93 +}
1.94 +
1.95 +/**
1.96 + * Flush any open regs back to memory, restore SI/DI/, update PC, etc
1.97 + */
1.98 +void sh4_translate_end_block( sh4addr_t pc ) {
1.99 + /* pop ebp */
1.100 + *xlat_output++ = 0x58 + R_EBP;
1.101 +
1.102 + /* ret */
1.103 + *xlat_output++ = 0xC3;
1.104 +}
1.105 +
1.106 +/**
1.107 + * Translate a single instruction. Delayed branches are handled specially
1.108 + * by translating both branch and delayed instruction as a single unit (as
1.109 + *
1.110 + *
1.111 + * @return true if the instruction marks the end of a basic block
1.112 + * (eg a branch or
1.113 + */
1.114 +uint32_t sh4_x86_translate_instruction( uint32_t pc )
1.115 +{
1.116 + uint16_t ir = 0;
1.117 +
1.118 +%%
1.119 +/* ALU operations */
1.120 +ADD Rm, Rn {:
1.121 + load_reg( R_EAX, Rm );
1.122 + load_reg( R_ECX, Rn );
1.123 + ADD_r32_r32( R_EAX, R_ECX );
1.124 + store_reg( R_ECX, Rn );
1.125 +:}
1.126 +ADD #imm, Rn {:
1.127 + load_reg( R_EAX, Rn );
1.128 + ADD_imm8s_r32( imm, R_EAX );
1.129 + store_reg( R_EAX, Rn );
1.130 +:}
1.131 +ADDC Rm, Rn {:
1.132 + load_reg( R_EAX, Rm );
1.133 + load_reg( R_ECX, Rn );
1.134 + LDC_t();
1.135 + ADC_r32_r32( R_EAX, R_ECX );
1.136 + store_reg( R_ECX, Rn );
1.137 + SETC_t();
1.138 +:}
1.139 +ADDV Rm, Rn {:
1.140 + load_reg( R_EAX, Rm );
1.141 + load_reg( R_ECX, Rn );
1.142 + ADD_r32_r32( R_EAX, R_ECX );
1.143 + store_reg( R_ECX, Rn );
1.144 + SETO_t();
1.145 +:}
1.146 +AND Rm, Rn {:
1.147 + load_reg( R_EAX, Rm );
1.148 + load_reg( R_ECX, Rn );
1.149 + AND_r32_r32( R_EAX, R_ECX );
1.150 + store_reg( R_ECX, Rn );
1.151 +:}
1.152 +AND #imm, R0 {:
1.153 + // Note: x86 AND imm8 sign-extends, SH4 version zero-extends. So
1.154 + // need to use the imm32 version
1.155 + load_reg( R_EAX, 0 );
1.156 + AND_imm32_r32(imm, R_EAX);
1.157 + store_reg( R_EAX, 0 );
1.158 +:}
1.159 +AND.B #imm, @(R0, GBR) {:
1.160 + load_reg( R_EAX, 0 );
1.161 + load_spreg( R_ECX, R_GBR );
1.162 + ADD_r32_r32( R_EAX, R_EBX );
1.163 + MEM_READ_BYTE( R_ECX, R_EAX );
1.164 + AND_imm32_r32(imm, R_ECX );
1.165 + MEM_WRITE_BYTE( R_ECX, R_EAX );
1.166 +:}
1.167 +CMP/EQ Rm, Rn {:
1.168 + load_reg( R_EAX, Rm );
1.169 + load_reg( R_ECX, Rn );
1.170 + CMP_r32_r32( R_EAX, R_ECX );
1.171 + SETE_t();
1.172 +:}
1.173 +CMP/EQ #imm, R0 {:
1.174 + load_reg( R_EAX, 0 );
1.175 + CMP_imm8s_r32(imm, R_EAX);
1.176 + SETE_t();
1.177 +:}
1.178 +CMP/GE Rm, Rn {:
1.179 + load_reg( R_EAX, Rm );
1.180 + load_reg( R_ECX, Rn );
1.181 + CMP_r32_r32( R_EAX, R_ECX );
1.182 + SETGE_t();
1.183 +:}
1.184 +CMP/GT Rm, Rn {:
1.185 + load_reg( R_EAX, Rm );
1.186 + load_reg( R_ECX, Rn );
1.187 + CMP_r32_r32( R_EAX, R_ECX );
1.188 + SETG_t();
1.189 +:}
1.190 +CMP/HI Rm, Rn {:
1.191 + load_reg( R_EAX, Rm );
1.192 + load_reg( R_ECX, Rn );
1.193 + CMP_r32_r32( R_EAX, R_ECX );
1.194 + SETA_t();
1.195 +:}
1.196 +CMP/HS Rm, Rn {:
1.197 + load_reg( R_EAX, Rm );
1.198 + load_reg( R_ECX, Rn );
1.199 + CMP_r32_r32( R_EAX, R_ECX );
1.200 + SETAE_t();
1.201 + :}
1.202 +CMP/PL Rn {:
1.203 + load_reg( R_EAX, Rn );
1.204 + CMP_imm8s_r32( 0, R_EAX );
1.205 + SETG_t();
1.206 +:}
1.207 +CMP/PZ Rn {:
1.208 + load_reg( R_EAX, Rn );
1.209 + CMP_imm8s_r32( 0, R_EAX );
1.210 + SETGE_t();
1.211 +:}
1.212 +CMP/STR Rm, Rn {: :}
1.213 +DIV0S Rm, Rn {: :}
1.214 +DIV0U {: :}
1.215 +DIV1 Rm, Rn {: :}
1.216 +DMULS.L Rm, Rn {: :}
1.217 +DMULU.L Rm, Rn {: :}
1.218 +DT Rn {:
1.219 + load_reg( R_EAX, Rn );
1.220 + ADD_imm8s_r32( -1, Rn );
1.221 + store_reg( R_EAX, Rn );
1.222 + SETE_t();
1.223 +:}
1.224 +EXTS.B Rm, Rn {:
1.225 + load_reg( R_EAX, Rm );
1.226 + MOVSX_r8_r32( R_EAX, R_EAX );
1.227 + store_reg( R_EAX, Rn );
1.228 +:}
1.229 +EXTS.W Rm, Rn {: :}
1.230 +EXTU.B Rm, Rn {: :}
1.231 +EXTU.W Rm, Rn {: :}
1.232 +MAC.L @Rm+, @Rn+ {: :}
1.233 +MAC.W @Rm+, @Rn+ {: :}
1.234 +MOVT Rn {:
1.235 + load_spreg( R_EAX, R_T );
1.236 + store_reg( R_EAX, Rn );
1.237 +:}
1.238 +MUL.L Rm, Rn {: :}
1.239 +MULS.W Rm, Rn {: :}
1.240 +MULU.W Rm, Rn {: :}
1.241 +NEG Rm, Rn {:
1.242 + load_reg( R_EAX, Rm );
1.243 + NEG_r32( R_EAX );
1.244 + store_reg( R_EAX, Rn );
1.245 +:}
1.246 +NEGC Rm, Rn {:
1.247 + load_reg( R_EAX, Rm );
1.248 + XOR_r32_r32( R_ECX, R_ECX );
1.249 + LDC_t();
1.250 + SBB_r32_r32( R_EAX, R_ECX );
1.251 + store_reg( R_ECX, Rn );
1.252 + SETC_t();
1.253 +:}
1.254 +NOT Rm, Rn {:
1.255 + load_reg( R_EAX, Rm );
1.256 + NOT_r32( R_EAX );
1.257 + store_reg( R_EAX, Rn );
1.258 +:}
1.259 +OR Rm, Rn {:
1.260 + load_reg( R_EAX, Rm );
1.261 + load_reg( R_ECX, Rn );
1.262 + OR_r32_r32( R_EAX, R_ECX );
1.263 + store_reg( R_ECX, Rn );
1.264 +:}
1.265 +OR #imm, R0 {:
1.266 + load_reg( R_EAX, 0 );
1.267 + OR_imm32_r32(imm, R_EAX);
1.268 + store_reg( R_EAX, 0 );
1.269 +:}
1.270 +OR.B #imm, @(R0, GBR) {: :}
1.271 +ROTCL Rn {:
1.272 + load_reg( R_EAX, Rn );
1.273 + LDC_t();
1.274 + RCL1_r32( R_EAX );
1.275 + store_reg( R_EAX, Rn );
1.276 + SETC_t();
1.277 +:}
1.278 +ROTCR Rn {:
1.279 + load_reg( R_EAX, Rn );
1.280 + LDC_t();
1.281 + RCR1_r32( R_EAX );
1.282 + store_reg( R_EAX, Rn );
1.283 + SETC_t();
1.284 +:}
1.285 +ROTL Rn {:
1.286 + load_reg( R_EAX, Rn );
1.287 + ROL1_r32( R_EAX );
1.288 + store_reg( R_EAX, Rn );
1.289 + SETC_t();
1.290 +:}
1.291 +ROTR Rn {:
1.292 + load_reg( R_EAX, Rn );
1.293 + ROR1_r32( R_EAX );
1.294 + store_reg( R_EAX, Rn );
1.295 + SETC_t();
1.296 +:}
1.297 +SHAD Rm, Rn {:
1.298 + /* Annoyingly enough, not directly convertible */
1.299 +:}
1.300 +SHLD Rm, Rn {:
1.301 +:}
1.302 +SHAL Rn {:
1.303 + load_reg( R_EAX, Rn );
1.304 + SHL1_r32( R_EAX );
1.305 + store_reg( R_EAX, Rn );
1.306 +:}
1.307 +SHAR Rn {:
1.308 + load_reg( R_EAX, Rn );
1.309 + SAR1_r32( R_EAX );
1.310 + store_reg( R_EAX, Rn );
1.311 +:}
1.312 +SHLL Rn {:
1.313 + load_reg( R_EAX, Rn );
1.314 + SHL1_r32( R_EAX );
1.315 + store_reg( R_EAX, Rn );
1.316 +:}
1.317 +SHLL2 Rn {:
1.318 + load_reg( R_EAX, Rn );
1.319 + SHL_imm8_r32( 2, R_EAX );
1.320 + store_reg( R_EAX, Rn );
1.321 +:}
1.322 +SHLL8 Rn {:
1.323 + load_reg( R_EAX, Rn );
1.324 + SHL_imm8_r32( 8, R_EAX );
1.325 + store_reg( R_EAX, Rn );
1.326 +:}
1.327 +SHLL16 Rn {:
1.328 + load_reg( R_EAX, Rn );
1.329 + SHL_imm8_r32( 16, R_EAX );
1.330 + store_reg( R_EAX, Rn );
1.331 +:}
1.332 +SHLR Rn {:
1.333 + load_reg( R_EAX, Rn );
1.334 + SHR1_r32( R_EAX );
1.335 + store_reg( R_EAX, Rn );
1.336 +:}
1.337 +SHLR2 Rn {:
1.338 + load_reg( R_EAX, Rn );
1.339 + SHR_imm8_r32( 2, R_EAX );
1.340 + store_reg( R_EAX, Rn );
1.341 +:}
1.342 +SHLR8 Rn {:
1.343 + load_reg( R_EAX, Rn );
1.344 + SHR_imm8_r32( 8, R_EAX );
1.345 + store_reg( R_EAX, Rn );
1.346 +:}
1.347 +SHLR16 Rn {:
1.348 + load_reg( R_EAX, Rn );
1.349 + SHR_imm8_r32( 16, R_EAX );
1.350 + store_reg( R_EAX, Rn );
1.351 +:}
1.352 +SUB Rm, Rn {:
1.353 + load_reg( R_EAX, Rm );
1.354 + load_reg( R_ECX, Rn );
1.355 + SUB_r32_r32( R_EAX, R_ECX );
1.356 + store_reg( R_ECX, Rn );
1.357 +:}
1.358 +SUBC Rm, Rn {:
1.359 + load_reg( R_EAX, Rm );
1.360 + load_reg( R_ECX, Rn );
1.361 + LDC_t();
1.362 + SBB_r32_r32( R_EAX, R_ECX );
1.363 + store_reg( R_ECX, Rn );
1.364 +:}
1.365 +SUBV Rm, Rn {:
1.366 + load_reg( R_EAX, Rm );
1.367 + load_reg( R_ECX, Rn );
1.368 + SUB_r32_r32( R_EAX, R_ECX );
1.369 + store_reg( R_ECX, Rn );
1.370 + SETO_t();
1.371 +:}
1.372 +SWAP.B Rm, Rn {:
1.373 + load_reg( R_EAX, Rm );
1.374 + XCHG_r8_r8( R_AL, R_AH );
1.375 + store_reg( R_EAX, Rn );
1.376 +:}
1.377 +SWAP.W Rm, Rn {:
1.378 + load_reg( R_EAX, Rm );
1.379 + MOV_r32_r32( R_EAX, R_ECX );
1.380 + SHL_imm8_r32( 16, R_ECX );
1.381 + SHR_imm8_r32( 16, R_EAX );
1.382 + OR_r32_r32( R_EAX, R_ECX );
1.383 + store_reg( R_ECX, Rn );
1.384 +:}
1.385 +TAS.B @Rn {: :}
1.386 +TST Rm, Rn {: :}
1.387 +TST #imm, R0 {: :}
1.388 +TST.B #imm, @(R0, GBR) {: :}
1.389 +XOR Rm, Rn {:
1.390 + load_reg( R_EAX, Rm );
1.391 + load_reg( R_ECX, Rn );
1.392 + XOR_r32_r32( R_EAX, R_ECX );
1.393 + store_reg( R_ECX, Rn );
1.394 +:}
1.395 +XOR #imm, R0 {:
1.396 + load_reg( R_EAX, 0 );
1.397 + XOR_imm32_r32( imm, R_EAX );
1.398 + store_reg( R_EAX, 0 );
1.399 +:}
1.400 +XOR.B #imm, @(R0, GBR) {:
1.401 + load_reg( R_EAX, 0 );
1.402 + load_spreg( R_ECX, R_GBR );
1.403 + ADD_r32_r32( R_EAX, R_ECX );
1.404 + MEM_READ_BYTE( R_ECX, R_EAX );
1.405 + XOR_imm32_r32( imm, R_EAX );
1.406 + MEM_WRITE_BYTE( R_ECX, R_EAX );
1.407 +:}
1.408 +XTRCT Rm, Rn {:
1.409 +:}
1.410 +
1.411 +/* Data move instructions */
1.412 +MOV Rm, Rn {:
1.413 + load_reg( R_EAX, Rm );
1.414 + store_reg( R_EAX, Rn );
1.415 +:}
1.416 +MOV #imm, Rn {:
1.417 + load_imm32( R_EAX, imm );
1.418 + store_reg( R_EAX, Rn );
1.419 +:}
1.420 +MOV.B Rm, @Rn {:
1.421 + load_reg( R_EAX, Rm );
1.422 + load_reg( R_ECX, Rn );
1.423 + MEM_WRITE_BYTE( R_ECX, R_EAX );
1.424 +:}
1.425 +MOV.B Rm, @-Rn {:
1.426 + load_reg( R_EAX, Rm );
1.427 + load_reg( R_ECX, Rn );
1.428 + ADD_imm8s_r32( -1, Rn );
1.429 + store_reg( R_ECX, Rn );
1.430 + MEM_WRITE_BYTE( R_ECX, R_EAX );
1.431 +:}
1.432 +MOV.B Rm, @(R0, Rn) {:
1.433 + load_reg( R_EAX, 0 );
1.434 + load_reg( R_ECX, Rn );
1.435 + ADD_r32_r32( R_EAX, R_ECX );
1.436 + load_reg( R_EAX, Rm );
1.437 + MEM_WRITE_BYTE( R_ECX, R_EAX );
1.438 +:}
1.439 +MOV.B R0, @(disp, GBR) {:
1.440 + load_reg( R_EAX, 0 );
1.441 + load_spreg( R_ECX, R_GBR );
1.442 + ADD_imm32_r32( disp, R_ECX );
1.443 + MEM_WRITE_BYTE( R_ECX, R_EAX );
1.444 +:}
1.445 +MOV.B R0, @(disp, Rn) {:
1.446 + load_reg( R_EAX, 0 );
1.447 + load_reg( R_ECX, Rn );
1.448 + ADD_imm32_r32( disp, R_ECX );
1.449 + MEM_WRITE_BYTE( R_ECX, R_EAX );
1.450 +:}
1.451 +MOV.B @Rm, Rn {:
1.452 + load_reg( R_ECX, Rm );
1.453 + MEM_READ_BYTE( R_ECX, R_EAX );
1.454 + store_reg( R_ECX, Rn );
1.455 +:}
1.456 +MOV.B @Rm+, Rn {:
1.457 + load_reg( R_ECX, Rm );
1.458 + MOV_r32_r32( R_ECX, R_EAX );
1.459 + ADD_imm8s_r32( 1, R_EAX );
1.460 + store_reg( R_EAX, Rm );
1.461 + MEM_READ_BYTE( R_ECX, R_EAX );
1.462 + store_reg( R_EAX, Rn );
1.463 +:}
1.464 +MOV.B @(R0, Rm), Rn {:
1.465 + load_reg( R_EAX, 0 );
1.466 + load_reg( R_ECX, Rm );
1.467 + ADD_r32_r32( R_EAX, R_ECX );
1.468 + MEM_READ_BYTE( R_ECX, R_EAX );
1.469 + store_reg( R_EAX, Rn );
1.470 +:}
1.471 +MOV.B @(disp, GBR), R0 {:
1.472 + load_spreg( R_ECX, R_GBR );
1.473 + ADD_imm32_r32( disp, R_ECX );
1.474 + MEM_READ_BYTE( R_ECX, R_EAX );
1.475 + store_reg( R_EAX, 0 );
1.476 +:}
1.477 +MOV.B @(disp, Rm), R0 {:
1.478 + load_reg( R_ECX, Rm );
1.479 + ADD_imm32_r32( disp, R_ECX );
1.480 + MEM_READ_BYTE( R_ECX, R_EAX );
1.481 + store_reg( R_EAX, 0 );
1.482 +:}
1.483 +MOV.L Rm, @Rn {: :}
1.484 +MOV.L Rm, @-Rn {: :}
1.485 +MOV.L Rm, @(R0, Rn) {: :}
1.486 +MOV.L R0, @(disp, GBR) {: :}
1.487 +MOV.L Rm, @(disp, Rn) {: :}
1.488 +MOV.L @Rm, Rn {: :}
1.489 +MOV.L @Rm+, Rn {: :}
1.490 +MOV.L @(R0, Rm), Rn {: :}
1.491 +MOV.L @(disp, GBR), R0 {: :}
1.492 +MOV.L @(disp, PC), Rn {: :}
1.493 +MOV.L @(disp, Rm), Rn {: :}
1.494 +MOV.W Rm, @Rn {: :}
1.495 +MOV.W Rm, @-Rn {: :}
1.496 +MOV.W Rm, @(R0, Rn) {: :}
1.497 +MOV.W R0, @(disp, GBR) {: :}
1.498 +MOV.W R0, @(disp, Rn) {: :}
1.499 +MOV.W @Rm, Rn {: :}
1.500 +MOV.W @Rm+, Rn {: :}
1.501 +MOV.W @(R0, Rm), Rn {: :}
1.502 +MOV.W @(disp, GBR), R0 {: :}
1.503 +MOV.W @(disp, PC), Rn {: :}
1.504 +MOV.W @(disp, Rm), R0 {: :}
1.505 +MOVA @(disp, PC), R0 {: :}
1.506 +MOVCA.L R0, @Rn {: :}
1.507 +
1.508 +/* Control transfer instructions */
1.509 +BF disp {: :}
1.510 +BF/S disp {: :}
1.511 +BRA disp {: :}
1.512 +BRAF Rn {: :}
1.513 +BSR disp {: :}
1.514 +BSRF Rn {: :}
1.515 +BT disp {: /* If true, result PC += 4 + disp. else result PC = pc+2 */
1.516 + return pc + 2;
1.517 +:}
1.518 +BT/S disp {:
1.519 +
1.520 + return pc + 4;
1.521 +:}
1.522 +JMP @Rn {: :}
1.523 +JSR @Rn {: :}
1.524 +RTE {: :}
1.525 +RTS {: :}
1.526 +TRAPA #imm {: :}
1.527 +UNDEF {: :}
1.528 +
1.529 +CLRMAC {: :}
1.530 +CLRS {: :}
1.531 +CLRT {: :}
1.532 +SETS {: :}
1.533 +SETT {: :}
1.534 +
1.535 +/* Floating point instructions */
1.536 +FABS FRn {: :}
1.537 +FADD FRm, FRn {: :}
1.538 +FCMP/EQ FRm, FRn {: :}
1.539 +FCMP/GT FRm, FRn {: :}
1.540 +FCNVDS FRm, FPUL {: :}
1.541 +FCNVSD FPUL, FRn {: :}
1.542 +FDIV FRm, FRn {: :}
1.543 +FIPR FVm, FVn {: :}
1.544 +FLDS FRm, FPUL {: :}
1.545 +FLDI0 FRn {: :}
1.546 +FLDI1 FRn {: :}
1.547 +FLOAT FPUL, FRn {: :}
1.548 +FMAC FR0, FRm, FRn {: :}
1.549 +FMOV FRm, FRn {: :}
1.550 +FMOV FRm, @Rn {: :}
1.551 +FMOV FRm, @-Rn {: :}
1.552 +FMOV FRm, @(R0, Rn) {: :}
1.553 +FMOV @Rm, FRn {: :}
1.554 +FMOV @Rm+, FRn {: :}
1.555 +FMOV @(R0, Rm), FRn {: :}
1.556 +FMUL FRm, FRn {: :}
1.557 +FNEG FRn {: :}
1.558 +FRCHG {: :}
1.559 +FSCA FPUL, FRn {: :}
1.560 +FSCHG {: :}
1.561 +FSQRT FRn {: :}
1.562 +FSRRA FRn {: :}
1.563 +FSTS FPUL, FRn {: :}
1.564 +FSUB FRm, FRn {: :}
1.565 +FTRC FRm, FPUL {: :}
1.566 +FTRV XMTRX, FVn {: :}
1.567 +
1.568 +/* Processor control instructions */
1.569 +LDC Rm, SR {: /* We need to be a little careful about SR */ :}
1.570 +LDC Rm, GBR {:
1.571 + load_reg( R_EAX, Rm );
1.572 + store_spreg( R_EAX, R_GBR );
1.573 +:}
1.574 +LDC Rm, VBR {:
1.575 + load_reg( R_EAX, Rm );
1.576 + store_spreg( R_EAX, R_VBR );
1.577 +:}
1.578 +LDC Rm, SSR {:
1.579 + load_reg( R_EAX, Rm );
1.580 + store_spreg( R_EAX, R_SSR );
1.581 +:}
1.582 +LDC Rm, SGR {:
1.583 + load_reg( R_EAX, Rm );
1.584 + store_spreg( R_EAX, R_SGR );
1.585 +:}
1.586 +LDC Rm, SPC {:
1.587 + load_reg( R_EAX, Rm );
1.588 + store_spreg( R_EAX, R_SPC );
1.589 +:}
1.590 +LDC Rm, DBR {:
1.591 + load_reg( R_EAX, Rm );
1.592 + store_spreg( R_EAX, R_DBR );
1.593 +:}
1.594 +LDC Rm, Rn_BANK {: :}
1.595 +LDC.L @Rm+, GBR {:
1.596 + load_reg( R_EAX, Rm );
1.597 + MOV_r32_r32( R_EAX, R_ECX );
1.598 + ADD_imm8s_r32( 4, R_EAX );
1.599 + store_reg( R_EAX, Rm );
1.600 + MEM_READ_LONG( R_ECX, R_EAX );
1.601 + store_spreg( R_EAX, R_GBR );
1.602 +:}
1.603 +LDC.L @Rm+, SR {:
1.604 +:}
1.605 +LDC.L @Rm+, VBR {:
1.606 + load_reg( R_EAX, Rm );
1.607 + MOV_r32_r32( R_EAX, R_ECX );
1.608 + ADD_imm8s_r32( 4, R_EAX );
1.609 + store_reg( R_EAX, Rm );
1.610 + MEM_READ_LONG( R_ECX, R_EAX );
1.611 + store_spreg( R_EAX, R_VBR );
1.612 +:}
1.613 +LDC.L @Rm+, SSR {:
1.614 + load_reg( R_EAX, Rm );
1.615 + MOV_r32_r32( R_EAX, R_ECX );
1.616 + ADD_imm8s_r32( 4, R_EAX );
1.617 + store_reg( R_EAX, Rm );
1.618 + MEM_READ_LONG( R_ECX, R_EAX );
1.619 + store_spreg( R_EAX, R_SSR );
1.620 +:}
1.621 +LDC.L @Rm+, SGR {:
1.622 + load_reg( R_EAX, Rm );
1.623 + MOV_r32_r32( R_EAX, R_ECX );
1.624 + ADD_imm8s_r32( 4, R_EAX );
1.625 + store_reg( R_EAX, Rm );
1.626 + MEM_READ_LONG( R_ECX, R_EAX );
1.627 + store_spreg( R_EAX, R_SGR );
1.628 +:}
1.629 +LDC.L @Rm+, SPC {:
1.630 + load_reg( R_EAX, Rm );
1.631 + MOV_r32_r32( R_EAX, R_ECX );
1.632 + ADD_imm8s_r32( 4, R_EAX );
1.633 + store_reg( R_EAX, Rm );
1.634 + MEM_READ_LONG( R_ECX, R_EAX );
1.635 + store_spreg( R_EAX, R_SPC );
1.636 +:}
1.637 +LDC.L @Rm+, DBR {:
1.638 + load_reg( R_EAX, Rm );
1.639 + MOV_r32_r32( R_EAX, R_ECX );
1.640 + ADD_imm8s_r32( 4, R_EAX );
1.641 + store_reg( R_EAX, Rm );
1.642 + MEM_READ_LONG( R_ECX, R_EAX );
1.643 + store_spreg( R_EAX, R_DBR );
1.644 +:}
1.645 +LDC.L @Rm+, Rn_BANK {:
1.646 +:}
1.647 +LDS Rm, FPSCR {:
1.648 + load_reg( R_EAX, Rm );
1.649 + store_spreg( R_EAX, R_FPSCR );
1.650 +:}
1.651 +LDS.L @Rm+, FPSCR {:
1.652 + load_reg( R_EAX, Rm );
1.653 + MOV_r32_r32( R_EAX, R_ECX );
1.654 + ADD_imm8s_r32( 4, R_EAX );
1.655 + store_reg( R_EAX, Rm );
1.656 + MEM_READ_LONG( R_ECX, R_EAX );
1.657 + store_spreg( R_EAX, R_FPSCR );
1.658 +:}
1.659 +LDS Rm, FPUL {:
1.660 + load_reg( R_EAX, Rm );
1.661 + store_spreg( R_EAX, R_FPUL );
1.662 +:}
1.663 +LDS.L @Rm+, FPUL {:
1.664 + load_reg( R_EAX, Rm );
1.665 + MOV_r32_r32( R_EAX, R_ECX );
1.666 + ADD_imm8s_r32( 4, R_EAX );
1.667 + store_reg( R_EAX, Rm );
1.668 + MEM_READ_LONG( R_ECX, R_EAX );
1.669 + store_spreg( R_EAX, R_FPUL );
1.670 +:}
1.671 +LDS Rm, MACH {:
1.672 + load_reg( R_EAX, Rm );
1.673 + store_spreg( R_EAX, R_MACH );
1.674 +:}
1.675 +LDS.L @Rm+, MACH {:
1.676 + load_reg( R_EAX, Rm );
1.677 + MOV_r32_r32( R_EAX, R_ECX );
1.678 + ADD_imm8s_r32( 4, R_EAX );
1.679 + store_reg( R_EAX, Rm );
1.680 + MEM_READ_LONG( R_ECX, R_EAX );
1.681 + store_spreg( R_EAX, R_MACH );
1.682 +:}
1.683 +LDS Rm, MACL {:
1.684 + load_reg( R_EAX, Rm );
1.685 + store_spreg( R_EAX, R_MACL );
1.686 +:}
1.687 +LDS.L @Rm+, MACL {:
1.688 + load_reg( R_EAX, Rm );
1.689 + MOV_r32_r32( R_EAX, R_ECX );
1.690 + ADD_imm8s_r32( 4, R_EAX );
1.691 + store_reg( R_EAX, Rm );
1.692 + MEM_READ_LONG( R_ECX, R_EAX );
1.693 + store_spreg( R_EAX, R_MACL );
1.694 +:}
1.695 +LDS Rm, PR {:
1.696 + load_reg( R_EAX, Rm );
1.697 + store_spreg( R_EAX, R_PR );
1.698 +:}
1.699 +LDS.L @Rm+, PR {:
1.700 + load_reg( R_EAX, Rm );
1.701 + MOV_r32_r32( R_EAX, R_ECX );
1.702 + ADD_imm8s_r32( 4, R_EAX );
1.703 + store_reg( R_EAX, Rm );
1.704 + MEM_READ_LONG( R_ECX, R_EAX );
1.705 + store_spreg( R_EAX, R_PR );
1.706 +:}
1.707 +LDTLB {: :}
1.708 +OCBI @Rn {: :}
1.709 +OCBP @Rn {: :}
1.710 +OCBWB @Rn {: :}
1.711 +PREF @Rn {: :}
1.712 +SLEEP {: :}
1.713 + STC SR, Rn {: /* TODO */
1.714 +:}
1.715 +STC GBR, Rn {:
1.716 + load_spreg( R_EAX, R_GBR );
1.717 + store_reg( R_EAX, Rn );
1.718 +:}
1.719 +STC VBR, Rn {:
1.720 + load_spreg( R_EAX, R_VBR );
1.721 + store_reg( R_EAX, Rn );
1.722 +:}
1.723 +STC SSR, Rn {:
1.724 + load_spreg( R_EAX, R_SSR );
1.725 + store_reg( R_EAX, Rn );
1.726 +:}
1.727 +STC SPC, Rn {:
1.728 + load_spreg( R_EAX, R_SPC );
1.729 + store_reg( R_EAX, Rn );
1.730 +:}
1.731 +STC SGR, Rn {:
1.732 + load_spreg( R_EAX, R_SGR );
1.733 + store_reg( R_EAX, Rn );
1.734 +:}
1.735 +STC DBR, Rn {:
1.736 + load_spreg( R_EAX, R_DBR );
1.737 + store_reg( R_EAX, Rn );
1.738 +:}
1.739 + STC Rm_BANK, Rn {: /* TODO */
1.740 +:}
1.741 + STC.L SR, @-Rn {: /* TODO */
1.742 +:}
1.743 +STC.L VBR, @-Rn {:
1.744 + load_reg( R_ECX, Rn );
1.745 + ADD_imm8s_r32( -4, Rn );
1.746 + store_reg( R_ECX, Rn );
1.747 + load_spreg( R_EAX, R_VBR );
1.748 + MEM_WRITE_LONG( R_ECX, R_EAX );
1.749 +:}
1.750 +STC.L SSR, @-Rn {:
1.751 + load_reg( R_ECX, Rn );
1.752 + ADD_imm8s_r32( -4, Rn );
1.753 + store_reg( R_ECX, Rn );
1.754 + load_spreg( R_EAX, R_SSR );
1.755 + MEM_WRITE_LONG( R_ECX, R_EAX );
1.756 +:}
1.757 +STC.L SPC, @-Rn {:
1.758 + load_reg( R_ECX, Rn );
1.759 + ADD_imm8s_r32( -4, Rn );
1.760 + store_reg( R_ECX, Rn );
1.761 + load_spreg( R_EAX, R_SPC );
1.762 + MEM_WRITE_LONG( R_ECX, R_EAX );
1.763 +:}
1.764 +STC.L SGR, @-Rn {:
1.765 + load_reg( R_ECX, Rn );
1.766 + ADD_imm8s_r32( -4, Rn );
1.767 + store_reg( R_ECX, Rn );
1.768 + load_spreg( R_EAX, R_SGR );
1.769 + MEM_WRITE_LONG( R_ECX, R_EAX );
1.770 +:}
1.771 +STC.L DBR, @-Rn {:
1.772 + load_reg( R_ECX, Rn );
1.773 + ADD_imm8s_r32( -4, Rn );
1.774 + store_reg( R_ECX, Rn );
1.775 + load_spreg( R_EAX, R_DBR );
1.776 + MEM_WRITE_LONG( R_ECX, R_EAX );
1.777 +:}
1.778 +STC.L Rm_BANK, @-Rn {: :}
1.779 +STC.L GBR, @-Rn {:
1.780 + load_reg( R_ECX, Rn );
1.781 + ADD_imm8s_r32( -4, Rn );
1.782 + store_reg( R_ECX, Rn );
1.783 + load_spreg( R_EAX, R_GBR );
1.784 + MEM_WRITE_LONG( R_ECX, R_EAX );
1.785 +:}
1.786 +STS FPSCR, Rn {:
1.787 + load_spreg( R_EAX, R_FPSCR );
1.788 + store_reg( R_EAX, Rn );
1.789 +:}
1.790 +STS.L FPSCR, @-Rn {:
1.791 + load_reg( R_ECX, Rn );
1.792 + ADD_imm8s_r32( -4, Rn );
1.793 + store_reg( R_ECX, Rn );
1.794 + load_spreg( R_EAX, R_FPSCR );
1.795 + MEM_WRITE_LONG( R_ECX, R_EAX );
1.796 +:}
1.797 +STS FPUL, Rn {:
1.798 + load_spreg( R_EAX, R_FPUL );
1.799 + store_reg( R_EAX, Rn );
1.800 +:}
1.801 +STS.L FPUL, @-Rn {:
1.802 + load_reg( R_ECX, Rn );
1.803 + ADD_imm8s_r32( -4, Rn );
1.804 + store_reg( R_ECX, Rn );
1.805 + load_spreg( R_EAX, R_FPUL );
1.806 + MEM_WRITE_LONG( R_ECX, R_EAX );
1.807 +:}
1.808 +STS MACH, Rn {:
1.809 + load_spreg( R_EAX, R_MACH );
1.810 + store_reg( R_EAX, Rn );
1.811 +:}
1.812 +STS.L MACH, @-Rn {:
1.813 + load_reg( R_ECX, Rn );
1.814 + ADD_imm8s_r32( -4, Rn );
1.815 + store_reg( R_ECX, Rn );
1.816 + load_spreg( R_EAX, R_MACH );
1.817 + MEM_WRITE_LONG( R_ECX, R_EAX );
1.818 +:}
1.819 +STS MACL, Rn {:
1.820 + load_spreg( R_EAX, R_MACL );
1.821 + store_reg( R_EAX, Rn );
1.822 +:}
1.823 +STS.L MACL, @-Rn {:
1.824 + load_reg( R_ECX, Rn );
1.825 + ADD_imm8s_r32( -4, Rn );
1.826 + store_reg( R_ECX, Rn );
1.827 + load_spreg( R_EAX, R_MACL );
1.828 + MEM_WRITE_LONG( R_ECX, R_EAX );
1.829 +:}
1.830 +STS PR, Rn {:
1.831 + load_spreg( R_EAX, R_PR );
1.832 + store_reg( R_EAX, Rn );
1.833 +:}
1.834 +STS.L PR, @-Rn {:
1.835 + load_reg( R_ECX, Rn );
1.836 + ADD_imm8s_r32( -4, Rn );
1.837 + store_reg( R_ECX, Rn );
1.838 + load_spreg( R_EAX, R_PR );
1.839 + MEM_WRITE_LONG( R_ECX, R_EAX );
1.840 +:}
1.841 +
1.842 +NOP {: /* Do nothing. Well, we could emit an 0x90, but what would really be the point? */ :}
1.843 +%%
1.844 +
1.845 + return 0;
1.846 +}
.