Search
lxdream.org :: lxdream/src/sh4/sh4dasm.in
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4dasm.in
changeset 1300:d18488c8668b
prev1190:2e66e9053037
author nkeynes
date Fri May 29 18:47:05 2015 +1000 (5 years ago)
permissions -rw-r--r--
last change Fix test case
view annotate diff log raw
     1 /**
     2  * $Id$
     3  * 
     4  * SH4 CPU definition and disassembly functions
     5  *
     6  * Copyright (c) 2005 Nathan Keynes.
     7  *
     8  * This program is free software; you can redistribute it and/or modify
     9  * it under the terms of the GNU General Public License as published by
    10  * the Free Software Foundation; either version 2 of the License, or
    11  * (at your option) any later version.
    12  *
    13  * This program is distributed in the hope that it will be useful,
    14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16  * GNU General Public License for more details.
    17  */
    19 #include "sh4/sh4core.h"
    20 #include "sh4/sh4dasm.h"
    21 #include "sh4/mmu.h"
    22 #include "mem.h"
    24 #include <string.h>
    26 #define UNIMP(ir) snprintf( buf, len, "???     " )
    28 uint32_t sh4_disasm_instruction( sh4vma_t pc, char *buf, int len, char *opcode )
    29 {
    30     sh4addr_t addr = mmu_vma_to_phys_disasm(pc);
    31     uint32_t tmp;
    33     if( addr == MMU_VMA_ERROR ) {
    34         sprintf( opcode, "?? ??" );
    35         snprintf( buf, len, "???" );
    36         return pc+2;
    37     }
    39     uint16_t ir = ext_address_space[addr>>12]->read_word(addr);
    41 #define UNDEF(ir) snprintf( buf, len, "????    " );
    42 #define RN(ir) ((ir&0x0F00)>>8)
    43 #define RN_BANK(ir) ((ir&0x0070)>>4)
    44 #define RM(ir) ((ir&0x00F0)>>4)
    45 #define DISP4(ir) (ir&0x000F) /* 4-bit displacements are *not* sign extended */
    46 #define DISP8(ir) (ir&0x00FF)
    47 #define PCDISP8(ir) SIGNEXT8(ir&0x00FF)
    48 #define UIMM8(ir) (ir&0x00FF)
    49 #define IMM8(ir) SIGNEXT8(ir&0x00FF)
    50 #define DISP12(ir) SIGNEXT12(ir&0x0FFF)
    51 #define FVN(ir) ((ir&0x0C00)>>10)
    52 #define FVM(ir) ((ir&0x0300)>>8)
    54     sprintf( opcode, "%02X %02X", ir&0xFF, ir>>8 );
    56 %%
    57 ADD Rm, Rn       {: snprintf( buf, len, "ADD     R%d, R%d", Rm, Rn ); :}
    58 ADD #imm, Rn     {: snprintf( buf, len, "ADD     #%d, R%d", imm, Rn ); :}
    59 ADDC Rm, Rn      {: snprintf( buf, len, "ADDC    R%d, R%d", Rm, Rn ); :}
    60 ADDV Rm, Rn      {: snprintf( buf, len, "ADDV    R%d, R%d", Rm, Rn ); :}
    61 AND Rm, Rn       {: snprintf( buf, len, "AND     R%d, R%d", Rm, Rn ); :}
    62 AND #imm, R0     {: snprintf( buf, len, "AND     #%d, R0", imm ); :}
    63 AND.B #imm, @(R0, GBR) {: snprintf( buf, len, "AND.B   #%d, @(R0, GBR)", imm ); :}
    64 BF disp          {: snprintf( buf, len, "BF      $%xh", disp+pc+4 ); :}
    65 BF/S disp        {: snprintf( buf, len, "BF/S    $%xh", disp+pc+4 ); :}
    66 BRA disp         {: snprintf( buf, len, "BRA     $%xh", disp+pc+4 ); :}
    67 BRAF Rn          {: snprintf( buf, len, "BRAF    R%d", Rn ); :}
    68 BSR disp         {: snprintf( buf, len, "BSR     $%xh", disp+pc+4 ); :}
    69 BSRF Rn          {: snprintf( buf, len, "BSRF    R%d", Rn ); :}
    70 BT disp          {: snprintf( buf, len, "BT      $%xh", disp+pc+4 ); :}
    71 BT/S disp        {: snprintf( buf, len, "BT/S    $%xh", disp+pc+4 ); :}
    72 CLRMAC           {: snprintf( buf, len, "CLRMAC  " ); :}
    73 CLRS             {: snprintf( buf, len, "CLRS    " ); :}
    74 CLRT             {: snprintf( buf, len, "CLRT    " ); :}
    75 CMP/EQ Rm, Rn    {: snprintf( buf, len, "CMP/EQ  R%d, R%d", Rm, Rn ); :}
    76 CMP/EQ #imm, R0  {: snprintf( buf, len, "CMP/EQ  #%d, R0", imm ); :}
    77 CMP/GE Rm, Rn    {: snprintf( buf, len, "CMP/GE  R%d, R%d", Rm, Rn ); :}
    78 CMP/GT Rm, Rn    {: snprintf( buf, len, "CMP/GT  R%d, R%d", Rm, Rn ); :}
    79 CMP/HI Rm, Rn    {: snprintf( buf, len, "CMP/HI  R%d, R%d", Rm, Rn ); :}
    80 CMP/HS Rm, Rn    {: snprintf( buf, len, "CMP/HS  R%d, R%d", Rm, Rn ); :}
    81 CMP/PL Rn        {: snprintf( buf, len, "CMP/PL  R%d", Rn ); :}
    82 CMP/PZ Rn        {: snprintf( buf, len, "CMP/PZ  R%d", Rn ); :}
    83 CMP/STR Rm, Rn   {: snprintf( buf, len, "CMP/STR R%d, R%d", Rm, Rn ); :}
    84 DIV0S Rm, Rn     {: snprintf( buf, len, "DIV0S   R%d, R%d", Rm, Rn ); :}
    85 DIV0U            {: snprintf( buf, len, "DIV0U   " ); :}
    86 DIV1 Rm, Rn      {: snprintf( buf, len, "DIV1    R%d, R%d", Rm, Rn ); :}
    87 DMULS.L Rm, Rn   {: snprintf( buf, len, "DMULS.L R%d, R%d", Rm, Rn ); :}
    88 DMULU.L RM, Rn   {: snprintf( buf, len, "DMULU.L R%d, R%d", Rm, Rn ); :}
    89 DT Rn            {: snprintf( buf, len, "DT      R%d", Rn ); :}
    90 EXTS.B Rm, Rn    {: snprintf( buf, len, "EXTS.B  R%d, R%d", Rm, Rn ); :}
    91 EXTS.W Rm, Rn    {: snprintf( buf, len, "EXTS.W  R%d, R%d", Rm, Rn ); :}
    92 EXTU.B Rm, Rn    {: snprintf( buf, len, "EXTU.B  R%d, R%d", Rm, Rn ); :}
    93 EXTU.W Rm, Rn    {: snprintf( buf, len, "EXTU.W  R%d, R%d", Rm, Rn ); :}
    94 FABS FRn         {: snprintf( buf, len, "FABS    FR%d", FRn ); :}
    95 FADD FRm, FRn    {: snprintf( buf, len, "FADD    FR%d, FR%d", FRm, FRn ); :}
    96 FCMP/EQ FRm, FRn {: snprintf( buf, len, "FCMP/EQ FR%d, FR%d", FRm, FRn ); :}
    97 FCMP/GT FRm, FRn {: snprintf( buf, len, "FCMP/GT FR%d, FR%d", FRm, FRn ); :}
    98 FCNVDS FRm, FPUL {: snprintf( buf, len, "FCNVDS  FR%d, FPUL", FRm ); :}
    99 FCNVSD FPUL, FRn {: snprintf( buf, len, "FCNVSD  FPUL, FR%d", FRn ); :}
   100 FDIV FRm, FRn    {: snprintf( buf, len, "FDIV    FR%d, FR%d", FRm, FRn ); :}
   101 FIPR FVm, FVn    {: snprintf( buf, len, "FIPR    FV%d, FV%d", FVm, FVn ); :}
   102 FLDS FRm, FPUL   {: snprintf( buf, len, "FLDS    FR%d, FPUL", FRm ); :}
   103 FLDI0 FRn        {: snprintf( buf, len, "FLDI0   FR%d", FRn ); :}
   104 FLDI1 FRn        {: snprintf( buf, len, "FLDI1   FR%d", FRn ); :}
   105 FLOAT FPUL, FRn  {: snprintf( buf, len, "FLOAT   FPUL, FR%d", FRn ); :}
   106 FMAC FR0, FRm, FRn {: snprintf( buf, len, "FMAC    FR0, FR%d, FR%d", FRm, FRn ); :}
   107 FMOV FRm, FRn    {: snprintf( buf, len, "FMOV    FR%d, FR%d", FRm, FRn ); :}
   108 FMOV FRm, @Rn    {: snprintf( buf, len, "FMOV    FR%d, @R%d", FRm, Rn ); :}
   109 FMOV FRm, @-Rn   {: snprintf( buf, len, "FMOV    FR%d, @-R%d", FRm, Rn ); :}
   110 FMOV FRm, @(R0, Rn) {: snprintf( buf, len, "FMOV    FR%d, @(R0, R%d)", FRm, Rn ); :}
   111 FMOV @Rm, FRn    {: snprintf( buf, len, "FMOV    @R%d, FR%d", Rm, FRn ); :}
   112 FMOV @Rm+, FRn   {: snprintf( buf, len, "FMOV    @R%d+, FR%d", Rm, FRn ); :}
   113 FMOV @(R0, Rm), FRn {: snprintf( buf, len, "FMOV    @(R0, R%d), FR%d", Rm, FRn ); :}
   114 FMUL FRm, FRn    {: snprintf( buf, len, "FMUL    FR%d, FR%d", FRm, FRn ); :}
   115 FNEG FRn         {: snprintf( buf, len, "FNEG    FR%d", FRn ); :}
   116 FRCHG            {: snprintf( buf, len, "FRCHG   " ); :}
   117 FSCA FPUL, FRn   {: snprintf( buf, len, "FSCA    FPUL, FR%d", FRn ); :}
   118 FSCHG            {: snprintf( buf, len, "FSCHG   " ); :}
   119 FSQRT FRn        {: snprintf( buf, len, "FSQRT   FR%d", FRn ); :}
   120 FSRRA FRn        {: snprintf( buf, len, "FSRRA   FR%d", FRn ); :}
   121 FSTS FPUL, FRn   {: snprintf( buf, len, "FSTS    FPUL, FR%d", FRn ); :}
   122 FSUB FRm, FRn    {: snprintf( buf, len, "FSUB    FR%d, FR%d", FRm, FRn ); :}
   123 FTRC FRm, FPUL   {: snprintf( buf, len, "FTRC    FR%d, FPUL", FRm ); :}
   124 FTRV XMTRX, FVn  {: snprintf( buf, len, "FTRV    XMTRX, FV%d", FVn ); :}
   125 JMP @Rn          {: snprintf( buf, len, "JMP     @R%d", Rn ); :}
   126 JSR @Rn          {: snprintf( buf, len, "JSR     @R%d", Rn ); :}
   127 LDC Rm, GBR      {: snprintf( buf, len, "LDC     R%d, GBR", Rm ); :}
   128 LDC Rm, SR       {: snprintf( buf, len, "LDC     R%d, SR", Rm ); :}
   129 LDC Rm, VBR      {: snprintf( buf, len, "LDC     R%d, VBR", Rm ); :}
   130 LDC Rm, SSR      {: snprintf( buf, len, "LDC     R%d, SSR", Rm ); :}
   131 LDC Rm, SGR      {: snprintf( buf, len, "LDC     R%d, SGR", Rm ); :}
   132 LDC Rm, SPC      {: snprintf( buf, len, "LDC     R%d, SPC", Rm ); :}
   133 LDC Rm, DBR      {: snprintf( buf, len, "LDC     R%d, DBR", Rm ); :}
   134 LDC Rm, Rn_BANK  {: snprintf( buf, len, "LDC     R%d, R%d_BANK", Rm, Rn_BANK ); :}
   135 LDS Rm, FPSCR    {: snprintf( buf, len, "LDS     R%d, FPSCR", Rm ); :}
   136 LDS Rm, FPUL     {: snprintf( buf, len, "LDS     R%d, FPUL", Rm ); :}
   137 LDS Rm, MACH     {: snprintf( buf, len, "LDS     R%d, MACH", Rm ); :}
   138 LDS Rm, MACL     {: snprintf( buf, len, "LDS     R%d, MACL", Rm ); :}
   139 LDS Rm, PR       {: snprintf( buf, len, "LDS     R%d, PR", Rm ); :}
   140 LDC.L @Rm+, GBR  {: snprintf( buf, len, "LDC.L   @R%d+, GBR", Rm ); :}
   141 LDC.L @Rm+, SR   {: snprintf( buf, len, "LDC.L   @R%d+, SR", Rm ); :}
   142 LDC.L @Rm+, VBR  {: snprintf( buf, len, "LDC.L   @R%d+, VBR", Rm ); :}
   143 LDC.L @Rm+, SSR  {: snprintf( buf, len, "LDC.L   @R%d+, SSR", Rm ); :}
   144 LDC.L @Rm+, SGR  {: snprintf( buf, len, "LDC.L   @R%d+, SGR", Rm ); :}
   145 LDC.L @Rm+, SPC  {: snprintf( buf, len, "LDC.L   @R%d+, SPC", Rm ); :}
   146 LDC.L @Rm+, DBR  {: snprintf( buf, len, "LDC.L   @R%d+, DBR", Rm ); :}
   147 LDC.L @Rm+, Rn_BANK{: snprintf( buf, len, "LDC.L   @R%d+, @R%d+_BANK", Rm, Rn_BANK ); :}
   148 LDS.L @Rm+, FPSCR{: snprintf( buf, len, "LDS.L   @R%d+, FPSCR", Rm ); :}
   149 LDS.L @Rm+, FPUL {: snprintf( buf, len, "LDS.L   @R%d+, FPUL", Rm ); :}
   150 LDS.L @Rm+, MACH {: snprintf( buf, len, "LDS.L   @R%d+, MACH", Rm ); :}
   151 LDS.L @Rm+, MACL {: snprintf( buf, len, "LDS.L   @R%d+, MACL", Rm ); :}
   152 LDS.L @Rm+, PR   {: snprintf( buf, len, "LDS.L   @R%d+, PR", Rm ); :}
   153 LDTLB            {: snprintf( buf, len, "LDTLB   " ); :}
   154 MAC.L @Rm+, @Rn+ {: snprintf( buf, len, "MAC.L   @R%d+, @R%d+", Rm, Rn ); :}
   155 MAC.W @Rm+, @Rn+ {: snprintf( buf, len, "MAC.W   @R%d+, @R%d+", Rm, Rn ); :}
   156 MOV Rm, Rn       {: snprintf( buf, len, "MOV     R%d, R%d", Rm, Rn ); :}
   157 MOV #imm, Rn     {: snprintf( buf, len, "MOV     #%d, R%d", imm, Rn ); :}
   158 MOV.B Rm, @Rn    {: snprintf( buf, len, "MOV.B   R%d, @R%d", Rm, Rn ); :}
   159 MOV.B Rm, @-Rn   {: snprintf( buf, len, "MOV.B   R%d, @-R%d", Rm, Rn ); :}
   160 MOV.B Rm, @(R0, Rn) {: snprintf( buf, len, "MOV.B   R%d, @(R0, R%d)", Rm, Rn ); :}
   161 MOV.B R0, @(disp, GBR) {: snprintf( buf, len, "MOV.B   R0, @(%d, GBR)", disp ); :}
   162 MOV.B R0, @(disp, Rn)  {: snprintf( buf, len, "MOV.B   R0, @(%d, R%d)", disp, Rn ); :}
   163 MOV.B @Rm, Rn    {: snprintf( buf, len, "MOV.B   @R%d, R%d", Rm, Rn ); :}
   164 MOV.B @Rm+, Rn   {: snprintf( buf, len, "MOV.B   @R%d+, R%d", Rm, Rn ); :}
   165 MOV.B @(R0, Rm), Rn {: snprintf( buf, len, "MOV.B   @(R0, R%d), R%d", Rm, Rn ); :}
   166 MOV.B @(disp, GBR), R0{: snprintf( buf, len, "MOV.B   @(%d, GBR), R0", disp ); :}
   167 MOV.B @(disp, Rm), R0 {: snprintf( buf, len, "MOV.B   @(%d, R%d), R0", disp, Rm ); :}
   168 MOV.L Rm, @Rn    {: snprintf( buf, len, "MOV.L   R%d, @R%d", Rm, Rn ); :}
   169 MOV.L Rm, @-Rn   {: snprintf( buf, len, "MOV.L   R%d, @-R%d", Rm, Rn ); :}
   170 MOV.L Rm, @(R0, Rn) {: snprintf( buf, len, "MOV.L   R%d, @(R0, R%d)", Rm, Rn ); :}
   171 MOV.L R0, @(disp, GBR) {: snprintf( buf, len, "MOV.L   R0, @(%d, GBR)", disp ); :}
   172 MOV.L Rm, @(disp, Rn) {: snprintf( buf, len, "MOV.L   R%d, @(%d, R%d)", Rm, disp, Rn ); :}
   173 MOV.L @Rm, Rn    {: snprintf( buf, len, "MOV.L   @R%d, R%d", Rm, Rn ); :}
   174 MOV.L @Rm+, Rn   {: snprintf( buf, len, "MOV.L   @R%d+, R%d", Rm, Rn ); :}
   175 MOV.L @(R0, Rm), Rn {: snprintf( buf, len, "MOV.L   @(R0, R%d), R%d", Rm, Rn ); :}
   176 MOV.L @(disp, GBR), R0 {: snprintf( buf, len, "MOV.L   @(%d, GBR), R0",disp ); :}
   177 MOV.L @(disp, PC), Rn  {:
   178     tmp = mmu_vma_to_phys_disasm(disp + (pc&0xFFFFFFFC) + 4); 
   179     snprintf( buf, len, "MOV.L   @($%xh), R%d ; <- #%08x", disp + (pc&0xFFFFFFFC)+4, Rn, ext_address_space[tmp>>12]->read_long(tmp) );
   180 :}
   181 MOV.L @(disp, Rm), Rn  {: snprintf( buf, len, "MOV.L   @(%d, R%d), R%d", disp, Rm, Rn ); :}
   182 MOV.W Rm, @Rn    {: snprintf( buf, len, "MOV.W   R%d, @R%d", Rm, Rn ); :}
   183 MOV.W Rm, @-Rn   {: snprintf( buf, len, "MOV.W   R%d, @-R%d", Rm, Rn ); :}
   184 MOV.W Rm, @(R0, Rn) {: snprintf( buf, len, "MOV.W   R%d, @(R0, R%d)", Rm, Rn ); :}
   185 MOV.W R0, @(disp, GBR) {: snprintf( buf, len, "MOV.W   R0, @(%d, GBR)", disp); :}
   186 MOV.W R0, @(disp, Rn)  {: snprintf( buf, len, "MOV.W   R0, @(%d, R%d)", disp, Rn ); :}
   187 MOV.W @Rm, Rn    {: snprintf( buf, len, "MOV.W   @R%d, R%d", Rm, Rn ); :}
   188 MOV.W @Rm+, Rn   {: snprintf( buf, len, "MOV.W   @R%d+, R%d", Rm, Rn ); :}
   189 MOV.W @(R0, Rm), Rn {: snprintf( buf, len, "MOV.W   @(R0, R%d), R%d", Rm, Rn ); :}
   190 MOV.W @(disp, GBR), R0 {: snprintf( buf, len, "MOV.W   @(%d, GBR), R0", disp ); :}
   191 MOV.W @(disp, PC), Rn  {:
   192     tmp = mmu_vma_to_phys_disasm(disp+pc+4);
   193     snprintf( buf, len, "MOV.W   @($%xh), R%d ; <- #%08x", disp+pc+4, Rn, ext_address_space[tmp>>12]->read_word(tmp) );
   194 :}
   195 MOV.W @(disp, Rm), R0  {: snprintf( buf, len, "MOV.W   @(%d, R%d), R0", disp, Rm ); :}
   196 MOVA @(disp, PC), R0   {: snprintf( buf, len, "MOVA    @($%xh), R0", disp + (pc&0xFFFFFFFC) + 4 ); :}
   197 MOVCA.L R0, @Rn  {: snprintf( buf, len, "MOVCA.L R0, @R%d", Rn ); :}
   198 MOVT Rn          {: snprintf( buf, len, "MOVT    R%d", Rn ); :}
   199 MUL.L Rm, Rn     {: snprintf( buf, len, "MUL.L   R%d, R%d", Rm, Rn ); :}
   200 MULS.W Rm, Rn    {: snprintf( buf, len, "MULS.W  R%d, R%d", Rm, Rn ); :}
   201 MULU.W Rm, Rn    {: snprintf( buf, len, "MULU.W  R%d, R%d", Rm, Rn ); :}
   202 NEG Rm, Rn       {: snprintf( buf, len, "NEG     R%d, R%d", Rm, Rn ); :}
   203 NEGC Rm, Rn      {: snprintf( buf, len, "NEGC    R%d, R%d", Rm, Rn ); :}
   204 NOP              {: snprintf( buf, len, "NOP     " ); :}
   205 NOT Rm, Rn       {: snprintf( buf, len, "NOT     R%d, R%d", Rm, Rn ); :}
   206 OCBI @Rn         {: snprintf( buf, len, "OCBI    @R%d", Rn ); :}
   207 OCBP @Rn         {: snprintf( buf, len, "OCBP    @R%d", Rn ); :}
   208 OCBWB @Rn        {: snprintf( buf, len, "OCBWB   @R%d", Rn ); :}
   209 OR Rm, Rn        {: snprintf( buf, len, "OR      R%d, R%d", Rm, Rn ); :}
   210 OR #imm, R0      {: snprintf( buf, len, "OR      #%d, R0", imm ); :}
   211 OR.B #imm, @(R0, GBR) {: snprintf( buf, len, "OR.B    #%d, @(R0, GBR)", imm ); :}
   212 PREF @Rn         {: snprintf( buf, len, "PREF    R%d", Rn ); :}
   213 ROTCL Rn         {: snprintf( buf, len, "ROTCL   R%d", Rn ); :}
   214 ROTCR Rn         {: snprintf( buf, len, "ROTCR   R%d", Rn ); :}
   215 ROTL Rn          {: snprintf( buf, len, "ROTL    R%d", Rn ); :}
   216 ROTR Rn          {: snprintf( buf, len, "ROTR    R%d", Rn ); :}
   217 RTE              {: snprintf( buf, len, "RTE     " ); :}
   218 RTS              {: snprintf( buf, len, "RTS     " ); :}
   219 SETS             {: snprintf( buf, len, "SETS    " ); :}
   220 SETT             {: snprintf( buf, len, "SETT    " ); :}
   221 SHAD Rm, Rn      {: snprintf( buf, len, "SHAD    R%d, R%d", Rm, Rn ); :}
   222 SHAL Rn          {: snprintf( buf, len, "SHAL    R%d", Rn ); :}
   223 SHAR Rn          {: snprintf( buf, len, "SHAR    R%d", Rn ); :}
   224 SHLD Rm, Rn      {: snprintf( buf, len, "SHLD    R%d, R%d", Rm, Rn ); :}
   225 SHLL Rn          {: snprintf( buf, len, "SHLL    R%d", Rn ); :}
   226 SHLL2 Rn         {: snprintf( buf, len, "SHLL2   R%d", Rn ); :}
   227 SHLL8 Rn         {: snprintf( buf, len, "SHLL8   R%d", Rn ); :}
   228 SHLL16 Rn        {: snprintf( buf, len, "SHLL16  R%d", Rn ); :}
   229 SHLR Rn          {: snprintf( buf, len, "SHLR    R%d", Rn ); :}
   230 SHLR2 Rn         {: snprintf( buf, len, "SHLR2   R%d", Rn ); :}
   231 SHLR8 Rn         {: snprintf( buf, len, "SHLR8   R%d", Rn ); :}
   232 SHLR16 Rn        {: snprintf( buf, len, "SHLR16  R%d", Rn ); :}
   233 SLEEP            {: snprintf( buf, len, "SLEEP   " ); :}
   234 STC SR, Rn       {: snprintf( buf, len, "STC     SR, R%d", Rn ); :}
   235 STC GBR, Rn      {: snprintf( buf, len, "STC     GBR, R%d", Rn ); :}
   236 STC VBR, Rn      {: snprintf( buf, len, "STC     VBR, R%d", Rn ); :}
   237 STC SSR, Rn      {: snprintf( buf, len, "STC     SSR, R%d", Rn ); :}
   238 STC SPC, Rn      {: snprintf( buf, len, "STC     SPC, R%d", Rn ); :}
   239 STC SGR, Rn      {: snprintf( buf, len, "STC     SGR, R%d", Rn ); :}
   240 STC DBR, Rn      {: snprintf( buf, len, "STC     DBR, R%d", Rn ); :}
   241 STC Rm_BANK, Rn  {: snprintf( buf, len, "STC     R%d_BANK, R%d", Rm_BANK, Rn ); :}
   242 STS FPSCR, Rn    {: snprintf( buf, len, "STS     FPSCR, R%d", Rn ); :}
   243 STS FPUL, Rn     {: snprintf( buf, len, "STS     FPUL, R%d", Rn ); :}
   244 STS MACH, Rn     {: snprintf( buf, len, "STS     MACH, R%d", Rn ); :}
   245 STS MACL, Rn     {: snprintf( buf, len, "STS     MACL, R%d", Rn ); :}
   246 STS PR, Rn       {: snprintf( buf, len, "STS     PR, R%d", Rn ); :}
   247 STC.L SR, @-Rn   {: snprintf( buf, len, "STC.L   SR, @-R%d", Rn ); :}
   248 STC.L GBR, @-Rn  {: snprintf( buf, len, "STC.L   GBR, @-R%d", Rn ); :}
   249 STC.L VBR, @-Rn  {: snprintf( buf, len, "STC.L   VBR, @-R%d", Rn ); :}
   250 STC.L SSR, @-Rn  {: snprintf( buf, len, "STC.L   SSR, @-R%d", Rn ); :}
   251 STC.L SPC, @-Rn  {: snprintf( buf, len, "STC.L   SPC, @-R%d", Rn ); :}
   252 STC.L SGR, @-Rn  {: snprintf( buf, len, "STC.L   SGR, @-R%d", Rn ); :}
   253 STC.L DBR, @-Rn  {: snprintf( buf, len, "STC.L    DBR, @-R%d", Rn ); :}
   254 STC.L Rm_BANK, @-Rn {: snprintf( buf, len, "STC.L   @-R%d_BANK, @-R%d", Rm_BANK, Rn ); :}
   255 STS.L FPSCR, @-Rn{: snprintf( buf, len, "STS.L   FPSCR, @-R%d", Rn ); :}
   256 STS.L FPUL, @-Rn {: snprintf( buf, len, "STS.L   FPUL, @-R%d", Rn ); :}
   257 STS.L MACH, @-Rn {: snprintf( buf, len, "STS.L   MACH, @-R%d", Rn ); :}
   258 STS.L MACL, @-Rn {: snprintf( buf, len, "STS.L   MACL, @-R%d", Rn ); :}
   259 STS.L PR, @-Rn   {: snprintf( buf, len, "STS.L   PR, @-R%d", Rn ); :}
   260 SUB Rm, Rn       {: snprintf( buf, len, "SUB     R%d, R%d", Rm, Rn ); :}
   261 SUBC Rm, Rn      {: snprintf( buf, len, "SUBC    R%d, R%d", Rm, Rn ); :}
   262 SUBV Rm, Rn      {: snprintf( buf, len, "SUBV    R%d, R%d", Rm, Rn ); :}
   263 SWAP.B Rm, Rn    {: snprintf( buf, len, "SWAP.B  R%d, R%d", Rm, Rn ); :}
   264 SWAP.W Rm, Rn    {: snprintf( buf, len, "SWAP.W  R%d, R%d", Rm, Rn ); :}
   265 TAS.B @Rn        {: snprintf( buf, len, "TAS.B   R%d", Rn ); :}
   266 TRAPA #imm       {: snprintf( buf, len, "TRAPA   #%d", imm ); :}
   267 TST Rm, Rn       {: snprintf( buf, len, "TST     R%d, R%d", Rm, Rn ); :}
   268 TST #imm, R0     {: snprintf( buf, len, "TST     #%d, R0", imm ); :}
   269 TST.B #imm, @(R0, GBR) {: snprintf( buf, len, "TST.B   #%d, @(R0, GBR)", imm ); :}
   270 XOR Rm, Rn       {: snprintf( buf, len, "XOR     R%d, R%d", Rm, Rn ); :}
   271 XOR #imm, R0     {: snprintf( buf, len, "XOR     #%d, R0", imm ); :}
   272 XOR.B #imm, @(R0, GBR) {: snprintf( buf, len, "XOR.B   #%d, @(R0, GBR)", imm ); :}
   273 XTRCT Rm, Rn     {: snprintf( buf, len, "XTRCT   R%d, R%d", Rm, Rn ); :}
   274 UNDEF            {: snprintf( buf, len, "UNDEF   " ); :}
   275 %%
   276     return pc+2;
   277 }
   280 static struct sh4_symbol *sh4_symbol_table = NULL;
   281 static unsigned sh4_symbol_table_size = 0;
   282 static sh4_symtab_destroy_cb sh4_symbol_table_cb = NULL;
   285 static void swap_symbol( struct sh4_symbol *a, struct sh4_symbol *b ) {
   286     struct sh4_symbol tmp;
   287     if( a == b )
   288         return;
   289     memcpy( &tmp, a, sizeof( struct sh4_symbol ) );
   290     memcpy( a, b, sizeof( struct sh4_symbol ) );
   291     memcpy( b, &tmp, sizeof( struct sh4_symbol ) );
   292 }
   294 static unsigned sort_symtab( struct sh4_symbol *table, unsigned numSymtabEntries ) {
   295     /* Implement via simple selection sort for now; usually we don't have very
   296      * large symbol tables.
   297      */
   298     for( unsigned i = 0; i < numSymtabEntries; i++ ) {
   299         struct sh4_symbol *next_entry = &table[i];
   300         for( unsigned j = i + 1; j < numSymtabEntries; ) {
   301             if( table[j].address < next_entry->address ) {
   302                 next_entry = &table[j];
   303                 j++;
   304             } else if( table[j].address == next_entry->address ) {
   305                 /* Duplicate - kill it */
   306                 swap_symbol( &table[j], &table[--numSymtabEntries] );
   307             } else {
   308                 j++;
   309             }
   310         }
   311         swap_symbol( &table[i], next_entry );
   312     }
   313     return numSymtabEntries;
   314 }
   316 const char *sh4_disasm_get_symbol( sh4addr_t addr )
   317 {
   318 	int l = 0, h = sh4_symbol_table_size;
   319 	while( l != h ) {
   320 	    int i = l + (h-l)/2;
   321 	    int iaddr = sh4_symbol_table[i].address;
   322 	    if( iaddr == addr ) {
   323 	        return sh4_symbol_table[i].name;
   324 	    } else if( iaddr > addr ) {
   325 	        h = i;
   326 	    } else { /* iaddr < addr */
   327 	        l = i+1;
   328 	    }
   329 	}
   330 	return NULL;
   331 }
   333 void sh4_set_symbol_table( struct sh4_symbol *table, unsigned size, sh4_symtab_destroy_cb callback )
   334 {
   335     if( sh4_symbol_table_cb != NULL ) {
   336         sh4_symbol_table_cb(sh4_symbol_table, sh4_symbol_table_size);
   337     }
   338     sh4_symbol_table = table;
   339     sh4_symbol_table_cb = callback;
   340     if( table == NULL ) {
   341         sh4_symbol_table_size = 0;
   342     } else {
   343         sh4_symbol_table_size = sort_symtab(table, size);
   344     }
   345 }
   348 void sh4_disasm_region( FILE *f, int from, int to )
   349 {
   350     int pc;
   351     char buf[80];
   352     char opcode[16];
   354     for( pc = from; pc < to; pc+=2 ) {
   355         buf[0] = '\0';
   356         sh4_disasm_instruction( pc,
   357                                 buf, sizeof(buf), opcode );
   358         const char *sym = sh4_disasm_get_symbol( pc );
   359         if( sym != 0 ) {
   360             fprintf( f, "%s:\n", sym );
   361         }
   362         fprintf( f, "  %08x:  %s  %s\n", pc, opcode, buf );
   363     }
   364 }
   366 void sh4_dump_region( int from, int to )
   367 {
   368     sh4_disasm_region( stdout, from, to );
   369 }
.