sparc/disassembler.m

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2001, Sun Microsystems, Inc
00003  * Copyright (C) 2001, The University of Queensland
00004  *
00005  * See the file "LICENSE.TERMS" for information on usage and
00006  * redistribution of this file, and for a DISCLAIMER OF ALL
00007  * WARRANTIES.
00008  *
00009  */
00010 
00011 /*==============================================================================
00012  * FILE:       disassembler.m
00013  * OVERVIEW:   Skeleton file for a disassembler of SPARC instructions. 
00014  *============================================================================*/
00015 
00016 /*
00017  * $Revision: 1.1 $
00018  *
00019  *    Apr 01 - Cristina: Created
00020  * 18 May 01 - Mike: Slight mods to accomodate other disassemblers; moved
00021  *              default NJMCDecoder constructor to disasm.cc
00022  */
00023 
00024 #include "global.h"
00025 #include "decoder.h"
00026 #include "sparc-names.h"
00027 #include "BinaryFile.h"         // For SymbolByAddress()
00028 
00029 // Globals in driver disasm.cc file
00030 extern  char _assembly;
00031 
00032 
00033 // Need to provide the fetch routines for this machine (32-bits only
00034 // on SPARC)
00035 
00036 /*
00037  * FUNCTION:        getDword
00038  * OVERVIEW:        Returns the double starting at the given address.
00039  * PARAMETERS:      lc - address at which to decode the double
00040  * RETURNS:         the decoded double
00041  */
00042 
00043 DWord getDword(ADDRESS lc)
00044 {
00045   Byte* p = (Byte*)lc;
00046   return (p[0] << 24) + (p << 16) + (p[2] << 8) + p;
00047 }
00048 
00049 
00050 
00051 /* 
00052  * FUNCTION:        dis_RegImm
00053  * OVERVIEW:        decodes a register or an immediate value
00054  * PARAMETERS:      address pointer to be decoded
00055  * RETURNS:         string with information about register or immediate 
00056  */
00057 
00058 char *NJMCDecoder::dis_RegImm (ADDRESS pc)
00059 {
00060     static char _buffer; 
00061 
00062     match pc to
00063     | imode(i) =>   sprintf (_buffer, "%d", i); 
00064     | rmode(rs2) => sprintf (_buffer, "%s", DIS_RS2); 
00065     endmatch
00066     return _buffer;
00067 }
00068 
00069 
00070 /* 
00071  * FUNCTION:        dis_Eaddr
00072  * OVERVIEW:        decodes an effective address
00073  * PARAMETERS:      address pointer to be decoded
00074  * RETURNS:         string with effective address in assembly format
00075  */
00076 
00077 char* NJMCDecoder::dis_Eaddr (ADDRESS pc)
00078 {
00079     static char _buffer; 
00080 
00081     match pc to
00082     | indirectA(rs1) => sprintf (_buffer, "[%s]", DIS_RS1);
00083                         strcat(constrName, "indirectA ");
00084     | indexA(rs1, rs2) =>   sprintf (_buffer, "%s[%s]", DIS_RS1, DIS_RS2); 
00085                         strcat(constrName, "indexA ");
00086     | absoluteA(i) =>   sprintf (_buffer, "[0x%x]", i); 
00087                         strcat(constrName, "absoluteA ");
00088     | dispA(rs1,i) =>   sprintf (_buffer, "[%s+%d]", DIS_RS1, i); 
00089                         strcat(constrName, "dispA ");
00090     endmatch
00091     return _buffer;
00092 }
00093 
00094 /*==============================================================================
00095  * FUNCTION:       NJMCDecoder::decodeAssemblyInstruction
00096  * OVERVIEW:       Decodes a machine instruction and displays its assembly
00097  *                 representation onto the external array _assembly[].
00098  * PARAMETERS:     pc - the native address of the pc
00099  *                 delta - the difference between the native address and 
00100  *                  the host address of the pc
00101  * RETURNS:        number of bytes taken up by the decoded instruction 
00102  *                  (i.e. number of bytes processed)
00103  *============================================================================*/
00104 
00105 int NJMCDecoder::decodeAssemblyInstruction (ADDRESS pc, int delta)
00106 {
00107     ADDRESS hostPC = pc + delta; 
00108     ADDRESS nextPC;
00109 
00110     sprintf(_assembly, "%X: %08X  ", pc, getDword(hostPC) );
00111     char* str = _assembly + strlen(_assembly);
00112 
00113     match  hostPC to
00114  
00115     | NOP =>
00116         sprintf (str, "NOP");
00117 
00118     | sethi(imm22, rd) => 
00119         sprintf (str, "%s 0x%X,%s", "sethi", (imm22), DIS_RD);
00120 
00121     | restore_() =>
00122         sprintf (str, "restore");
00123 
00124     | ret() =>
00125         sprintf (str, "ret");
00126 
00127     | retl() =>
00128         sprintf (str, "retl");
00129 
00130     | save_ ()  =>
00131         sprintf (str, "%s %s,%s", name, "%g0", "%g0", "%g0");
00132 
00133     | load_greg(addr, rd)  => 
00134         sprintf (str, "%s %s,%s", name, DIS_ADDR, DIS_RD);
00135 
00136     | LDF (addr, fds)  => 
00137         sprintf (str, "%s %s,%s", name, DIS_ADDR, DIS_FDS);
00138 
00139     | LDDF (addr, fdd)  => 
00140         sprintf (str, "%s %s,%s", name, DIS_ADDR, DIS_FDD);
00141 
00142     | load_creg(addr, cd)  => 
00143         sprintf (str, "%s %s,%s", name, DIS_ADDR, DIS_CD);
00144         
00145     | load_asi (addr, asi, rd)  => 
00146         sprintf (str, "%s %s,%s", name, DIS_RD, DIS_ADDR);
00147 
00148     | sto_greg(rd, addr)  => 
00149         sprintf (str, "%s %s,%s", name, DIS_RD, DIS_ADDR);
00150 
00151     | STF (fds, addr)  => 
00152         sprintf (str, "%s %s,%s", name, DIS_FDS, DIS_ADDR);
00153 
00154     | STDF (fdd, addr)  => 
00155         sprintf (str, "%s %s,%s", name, DIS_FDD, DIS_ADDR);
00156 
00157     | sto_creg(cd, addr)  => 
00158         sprintf (str, "%s %s,%s", name, DIS_CD, DIS_ADDR);
00159 
00160     | sto_asi (rd, addr, asi)  => 
00161         sprintf (str, "%s %s,%s", name, DIS_RD, DIS_ADDR);
00162 
00163     | LDFSR(addr)  => 
00164         sprintf (str, "%s %s", name, DIS_ADDR);
00165 
00166     | LDCSR(addr)  => 
00167         sprintf (str, "%s %s", name, DIS_ADDR);
00168 
00169     | STFSR(addr)  => 
00170         sprintf (str, "%s %s", name, DIS_ADDR);
00171 
00172     | STCSR(addr)  => 
00173         sprintf (str, "%s %s", name, DIS_ADDR);
00174 
00175     | STDFQ(addr)  => 
00176         sprintf (str, "%s %s", name, DIS_ADDR);
00177 
00178     | STDCQ(addr)  => 
00179         sprintf (str, "%s %s", name, DIS_ADDR);
00180 
00181     | RDY(rd)  => 
00182         sprintf (str, "%s %s", name, DIS_RD);
00183 
00184     | RDPSR(rd)  => 
00185         sprintf (str, "%s %s", name, DIS_RD);
00186 
00187     | RDWIM(rd)  => 
00188         sprintf (str, "%s %s", name, DIS_RD);
00189 
00190     | RDTBR(rd)     => 
00191         sprintf (str, "%s %s", name, DIS_RD);
00192 
00193     | WRY(rs1,roi)  => 
00194         sprintf (str, "%s %s,%s", name, DIS_RS1, DIS_ROI);
00195 
00196     | WRPSR(rs1, roi)  => 
00197         sprintf (str, "%s %s,%s", name, DIS_RS1, DIS_ROI);
00198 
00199     | WRWIM(rs1, roi)  => 
00200         sprintf (str, "%s %s,%s", name, DIS_RS1, DIS_ROI);
00201 
00202     | WRTBR(rs1, roi)  => 
00203         sprintf (str, "%s %s,%s", name, DIS_RS1, DIS_ROI);
00204 
00205     | alu (rs1, roi, rd)  => 
00206         sprintf (str, "%s %s,%s,%s", name, DIS_RS1, DIS_ROI, DIS_RD);
00207 
00208     | branch^",a" (tgt) [name] => 
00209         sprintf (str, "%s %X", name, tgt-delta);
00210 
00211     | branch (tgt)  => 
00212         sprintf (str, "%s %X", name, tgt-delta);
00213 
00214     | call__ (tgt) => {
00215         // Get the actual destination
00216         ADDRESS dest = tgt - delta;
00217         // Get a symbol for it, if possible
00218         const char* dsym = pBF->SymbolByAddress(dest);
00219         char hexsym;
00220         if (dsym == 0)
00221             sprintf(hexsym, "0x%x", dest);
00222         sprintf (str, "%s %s", "call", (dsym ? dsym : hexsym));
00223     }
00224 
00225     | float2s (fs2s, fds)  => 
00226         sprintf (str, "%s %s,%s", name, DIS_FS2S, DIS_FDS);
00227 
00228     | float3s (fs1s, fs2s, fds)  => 
00229         sprintf (str, "%s %s,%s,%s", name, DIS_FS1S, DIS_FS2S, DIS_FDS);
00230  
00231     | float3d (fs1d, fs2d, fdd)  => 
00232         sprintf (str, "%s %s,%s,%s", name, DIS_FS1D, DIS_FS2D, DIS_FDD);
00233  
00234     | float3q (fs1q, fs2q, fdq)  => 
00235         sprintf (str, "%s %s,%s,%s", name, DIS_FS1Q, DIS_FS2Q, DIS_FDQ);
00236  
00237     | fcompares (fs1s, fs2s)  => 
00238         sprintf (str, "%s %s,%s", name, DIS_FS1S, DIS_FS2S);
00239 
00240     | fcompared (fs1d, fs2d)  => 
00241         sprintf (str, "%s %s,%s", name, DIS_FS1D, DIS_FS2D);
00242 
00243     | fcompareq (fs1q, fs2q)  => 
00244         sprintf (str, "%s %s,%s", name, DIS_FS1Q, DIS_FS2Q);
00245 
00246     | FTOs (fs2s, fds)  =>
00247         sprintf (str, "%s %s,%s", name, DIS_FS2S, DIS_FDS);
00248 
00249     | FiTOd (fs2s, fdd)  =>
00250         sprintf (str, "%s %s,%s", name, DIS_FS2S, DIS_FDD);
00251     | FdTOi (fs2d, fds)  =>
00252         sprintf (str, "%s %s,%s", name, DIS_FS2D, DIS_FDS);
00253 
00254     | FiTOq (fs2s, fdq)  =>
00255         sprintf (str, "%s %s,%s", name, DIS_FS2S, DIS_FDQ);
00256     | FqTOi (fs2q, fds)  =>
00257         sprintf (str, "%s %s,%s", name, DIS_FS2Q, DIS_FDS);
00258 
00259     | FsTOd (fs2s, fdd)  =>
00260         sprintf (str, "%s %s,%s", name, DIS_FS2S, DIS_FDD);
00261     | FdTOs (fs2d, fds)  =>
00262         sprintf (str, "%s %s,%s", name, DIS_FS2D, DIS_FDS);
00263 
00264     | FsTOq (fs2s, fdq)  =>
00265         sprintf (str, "%s %s,%s", name, DIS_FS2S, DIS_FDQ);
00266     | FqTOs (fs2q, fds)  =>
00267         sprintf (str, "%s %s,%s", name, DIS_FS2Q, DIS_FDS);
00268 
00269     | FdTOq (fs2d, fdq)  =>
00270         sprintf (str, "%s %s,%s", name, DIS_FS2D, DIS_FDQ);
00271     | FqTOd (fs2q, fdd)  =>
00272         sprintf (str, "%s %s,%s", name, DIS_FS2Q, DIS_FDD);
00273 
00274     | JMPL (addr, rd)  => 
00275         sprintf (str, "%s %s,%s", name, DIS_ADDR, DIS_RD);
00276 
00277     | RETT (addr)  => 
00278         sprintf (str, "%s", name);
00279 
00280     | trap (addr)  => 
00281         sprintf (str, "%s %s", name, DIS_ADDR);
00282 
00283     | UNIMP (n)  => 
00284         sprintf (str, "%s %d", name, n);
00285 
00286     | inst = n => 
00287         // What does this mean?
00288         NULL;
00289 
00290     else
00291         NULL;
00292 
00293     endmatch
00294 
00295     return (nextPC - hostPC);
00296 }
00297 

Generated on Tue Sep 19 21:18:22 2006 for Boomerang by  doxygen 1.4.6