mc68k/decoder_low.m

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 1996, Princeton University or Owen Braun ??????
00003  * Copyright (C) 2000, Sun Microsystems, Inc
00004  * Copyright (C) 2000, The University of Queensland
00005  *
00006  * See the file "LICENSE.TERMS" for information on usage and
00007  * redistribution of this file, and for a DISCLAIMER OF ALL
00008  * WARRANTIES.
00009  *
00010  */
00011 
00012 /*==============================================================================
00013  * FILE:       decoder_low.m
00014  * OVERVIEW:   Implementation of the low level mc68000 specific parts of the
00015  *             NJMCDecoder class.
00016  *============================================================================*/
00017 
00018 /* $Revision: 1.2 $
00019  * $Id: decoder_low.m,v 1.2 2004/06/24 05:41:02 emmerik Exp $
00020  * Created by Cristina 04 Feb 2000
00021  *
00022  * Based on: 
00023  *  m68k__assembly.m
00024  *  written by Owen Braun
00025  *  ocbraun@princeton.edu
00026  *  created 4/8/96 3:57 am
00027  *
00028  *  M68kInstr method decodeInstr which uses Toolkit matching statement
00029  *  to decode instruction and generate _assembly-language representation
00030  *
00031  * 04 Feb 00 - Integration with UQBT's .prc loader (PalmBinaryFile)
00032  * 07 Feb 00 - Mike: Made numInstrWords a reference, and initialised to 1
00033  * 09 Feb 00 - Cristina: changed register display syntax to conform to 
00034  *      Motorola's assembly syntax.
00035  *      unlk is now a non factored constructor
00036  *      Added system trap function name support 
00037  * 11 Feb 00 - Mike: started making RTL version from disassembler
00038  * 13 Feb 00 - Cristina: continued 
00039  * 15 Feb 00 - Mike: inserted addressing mode code
00040  * 21 Feb 00 - Mike: support for -(an) and (an)+ (bump and bumpr)
00041  * 22 Feb 00 - Cristina: for ADDQ and SUBQ we need 5 chars to match SSL name
00042  * 25 Feb 00 - Mike: Fixed move (a7)+,d3 (was faulting)
00043  * 24 Mar 00 - Mike: Converted sizes to bits
00044  * 27 Mar 00 - Mike: Fixed instructions like addaw.ex that were not having
00045  *                the .ex removed before 2nd last char (using chopBoth())
00046  * 07 Apr 00 - Mike: Fixed semantics of movew d3, a0 (sign extends)
00047  * 13 Apr 00 - Mike: Fixed side effects of the above; was putting the BUMP
00048  *                at the wrong place
00049  * 22 Mar 01 - Mike: Fixed a fault when decoding mem to mem move; initialisation
00050  *                of RTs to an empty list was in the wrong place
00051  * 01 Aug 01 - Mike: Added some #includes; would not compile without these
00052  */
00053 
00054 #include <assert.h>
00055 #include <stdio.h>
00056 #include "global.h" 
00057 #include "decoder.h"
00058 #include "ss.h"
00059 #include "rtl.h"
00060 
00061 // File scope globals
00062 static bool IsTrap = false;
00063 static bool prevIsTrap = false;
00064 static char sslName;            // Modifiable; [name] from the toolkit is
00065                                     // in the text section and read-only
00066 static int temp1 = 0;               // id of a temp; initialised on first use
00067 
00068 /*==============================================================================
00069  * FUNCTION:        getWord
00070  * OVERVIEW:        Returns the word starting at the given address.
00071  * PARAMETERS:      lc - host address at which to decode 
00072  * RETURNS:         the decoded double
00073  *============================================================================*/
00074 SWord getWord (unsigned lc)
00075 /* get2Bytes - returns next 2-Byte from image pointed to by lc.
00076    Fetch in a big-endian manner  */
00077 {
00078     return (SWord)((*(Byte *)lc << 8) + *(Byte *)(lc+1));
00079 }
00080 
00081 
00082 /*==============================================================================
00083  * FUNCTION:        decodeTrapName
00084  * OVERVIEW:        Places the name of the system call in _assembly.
00085  * PARAMETERS:      pc - address at which to decode 
00086  * RETURNS:         nil
00087  *============================================================================*/
00088 void decodeTrapName (ADDRESS pc)
00089 {
00090 // Need to think about what to do here
00091     //fprintf (stderr, "dc.w #%d\t// ", (SWord)(*(SWord *)pc));  
00092     //fprintf (stderr, "%s", trapNames[*(SWord *)pc - sysTrapBase]); 
00093 }
00094 
00095 // Convert names like addb.ex, orl, mulu to appropriate SSL form
00096 // Puts resultant name into static (file scope) global sslName
00097 void chopDotex(char* name)
00098 {
00099     int l = strlen(name);
00100     strcpy(sslName, name);
00101     if (name[l-3] == '.')           // Has .ex
00102         l -= 3;                     // Discard the .ex
00103     sslName = '\0';
00104 }
00105 
00106 // Chop 2nd last character from a name, e.g. roxrib -> roxrb
00107 void chop2ndLast(char* name)
00108 {
00109     int l = strlen(name);
00110     strcpy(sslName, name);
00111     sslName = name;
00112     sslName = '\0';
00113 }
00114 
00115 // Chop .ex (if present) AND 2nd last character from a name
00116 // e.g. roxrib.ex -> roxrb
00117 void chopBoth(char* name)
00118 {
00119     int l = strlen(name);
00120     strcpy(sslName, name);
00121     if (name[l-3] == '.')           // Has .ex
00122         l -= 3;                     // Discard the .ex
00123     sslName = '\0';
00124     sslName = name;
00125     sslName = '\0';
00126 }
00127 
00128 /*==============================================================================
00129  * FUNCTION:       bumpRegister
00130  * OVERVIEW:       Add an RTAssgn to bump a register by an amount
00131  * PARAMETERS:     RTs: list of RTs to add this RTAssgn to
00132  *                 bump: amount to add to the register
00133  *                 bumpr: register to bump
00134  * RETURNS:        <nothing>
00135  *============================================================================*/
00136 void bumpRegister(list<RT*>* RTs, int bump, int bumpr)
00137 {
00138     // Lhs: r[bumpr]
00139     SemStr* lhs = new SemStr(32);
00140     lhs->push(idRegOf); lhs->push(idIntConst); lhs->push(bumpr);
00141     // Rhs: r[bumpr] + bump
00142     SemStr* rhs = new SemStr(32);
00143     rhs->push(idPlus);
00144     rhs->push(idRegOf); rhs->push(idIntConst); rhs->push(bumpr);
00145     rhs->push(idIntConst); rhs->push(bump);
00146     RTAssgn* pRT = new RTAssgn(lhs, rhs, 32);
00147     RTs->push_back(pRT);
00148 }
00149 
00150 /*==============================================================================
00151  * FUNCTION:       assignTemp
00152  * OVERVIEW:       Add an RTAssgn to assign src to temp1
00153  * PARAMETERS:     src: Pointer to SemStr for src
00154  *                 size: size of the assignment, in bits
00155  *                 temp: this function sets this parameter to point to a copy
00156  *                  of a SemStr that represents "temp1"
00157  * RETURNS:        Pointer to the assignment RT
00158  *============================================================================*/
00159 RT* assignTemp(SemStr* src, int size, SemStr*& temp)
00160 {
00161     if (temp1 == 0) temp1 = theSemTable.addItem("temp1");
00162     // Lhs: r[temp1]
00163     SemStr* lhs = new SemStr(size);
00164     lhs->push(idRegOf); lhs->push(idTemp); lhs->push(temp1);
00165     // Rhs is just src
00166     RTAssgn* pRT = new RTAssgn(lhs, src, size);
00167     temp = new SemStr(*lhs);
00168     return pRT;
00169 }
00170 
00171 /*==============================================================================
00172  * FUNCTION:       sgnExTemp
00173  * OVERVIEW:       Add an RTAssgn to sign extend src to temp1
00174  * PARAMETERS:     dest: Pointer to SemStr for dest
00175  *                 size: size of the source, in bits
00176  *                 size2: size of the destination, in bits
00177  *                 temp: this function sets this parameter to point to a copy
00178  *                  of a SemStr that represents "temp1"
00179  * RETURNS:        Pointer to the assignment RT
00180  *============================================================================*/
00181 RT* sgnExTemp(SemStr* src, int size, int size2, SemStr*& temp)
00182 {
00183     if (temp1 == 0) temp1 = theSemTable.addItem("temp1");
00184     // Lhs: r[temp1]
00185     SemStr* lhs = new SemStr(size2);
00186     lhs->push(idRegOf); lhs->push(idTemp); lhs->push(temp1);
00187     // Rhs is just sgnex(size, size2, src)
00188     src->prep(size2);
00189     src->prep(size);
00190     src->prep(idSgnEx);
00191     RTAssgn* pRT = new RTAssgn(lhs, src, size2);
00192     temp = new SemStr(*lhs);
00193     return pRT;
00194 }
00195 
00196 // Macro to handle bumping register if reqd
00197 #define ADDBUMP {if (bump) bumpRegister(RTs, bump, bumpr);}
00198 
00199 /*==============================================================================
00200  * FUNCTION:       NJMCDecoder::decodeLowLevelInstruction
00201  * OVERVIEW:       Decodes a machine instruction and returns an instantiated
00202  *                 list of RTs.
00203  * PARAMETERS:     hostPC - the address of the pc in the loaded Elf object
00204  *                 pc - the virtual address of the pc
00205  *                 result - a reference parameter that has a field that will be
00206  *                   set to false if an invalid or UNIMP instruction was decoded
00207  * RETURNS:        the instantiated list of RTs
00208  *============================================================================*/
00209 list<RT*>* NJMCDecoder::decodeLowLevelInstruction (ADDRESS hostPC, ADDRESS pc,
00210     DecodeResult& result) 
00211 {
00212   //  This uses both patterned and non-patterned constructors in
00213   //  its matching statement. For the non-patterened constructors,
00214   //  all decoding variables are set here. For the patterned constructors,
00215   //  the name of the opcode is copied into the opcodeStr variable and
00216   //  the decoding variables are set by a "second round" decoding method.
00217 
00218     result.numBytes = 0;
00219     prevIsTrap = IsTrap;            // Remember if last instr was a trap
00220     IsTrap = false;
00221     int delta = hostPC - pc;
00222 
00223     // The list of instantiated RTs.
00224     list<RT*>* RTs = NULL;
00225 
00226   match hostPC to
00227 
00228     | _toCCR (i8)   => {
00229     // _toCCR   is  andiToCCR | eoriToCCR | oriToCCR
00230                         RTs = instantiate(pc, name, DIS_I8);
00231                     }
00232 
00233 
00234 
00235     | _immEAb (i8, ea)              => {
00236     // _toSR (i16) [names] is privileged (we should never see it)
00237     // _immEAb  is  addib | andib | cmpib | eorib | orib | subib
00238                         int bump = 0, bumpr;
00239                         chop2ndLast(name);
00240                         RTs = instantiate(pc, sslName, DIS_I8, daEA(ea, pc,
00241                             bump, bumpr, 8));
00242                         ADDBUMP;
00243                         result.numBytes += 2;
00244                     }
00245 
00246 
00247     | _immEAb^".ex" (i8, eax, x) [name]   => {
00248                         chopBoth(name);
00249                         RTs = instantiate(pc, sslName, DIS_I8,
00250                             daEAX(eax, x, result, pc, 8));
00251                         result.numBytes += 2;
00252                     }
00253     
00254     | _immEAw (i16, ea)             => {
00255                         int bump = 0, bumpr;
00256                         chop2ndLast(name);
00257                         RTs = instantiate(pc, sslName, DIS_I16, daEA(ea, pc,
00258                             bump, bumpr, 16));
00259                         ADDBUMP;
00260                         result.numBytes += 2;
00261                     }
00262 
00263 
00264     | _immEAw^".ex" (i16, eax, x) [name]  => {
00265                         chopBoth(name);
00266                         RTs = instantiate(pc, sslName, DIS_I16,
00267                             daEAX(eax, x, result, pc, 16));
00268                         result.numBytes += 2;
00269                     }
00270     
00271     | _immEAl (i32, ea)             => {
00272                         int bump = 0, bumpr;
00273                         chop2ndLast(name);
00274                         RTs = instantiate(pc, sslName, DIS_I32, daEA(ea, pc,
00275                             bump, bumpr, 32));
00276                         ADDBUMP;
00277                         result.numBytes += 4;
00278                     }
00279 
00280     | _immEAl^".ex" (i32, eax, x) [name]  => {
00281                         chopBoth(name);
00282                         RTs = instantiate(pc, sslName, DIS_I32,
00283                             daEAX(eax, x, result, pc, 32));
00284                         result.numBytes += 4;
00285                     }
00286 
00287     
00288     | _bits (n, ea)  => {
00289         // _bits    is  bchg  | bclr  | bset
00290         // _bitsi   is  bchgi | bclri | bseti
00291         // This series are assumed to be 8 bits where memory is involved,
00292         // or 32 for registers
00293                         int bump = 0, bumpr;
00294                         RTs = instantiate(pc, name, DIS_DN(32), daEA(ea, pc,
00295                             bump, bumpr, 8));
00296                         ADDBUMP;
00297                     }
00298 
00299     | _bits^".ex" (n, eax, x) [name] => {
00300                         chopDotex(name);
00301                         RTs = instantiate(pc, sslName, DIS_DN(32),
00302                             daEAX(eax, x, result, pc, 8));
00303                     }
00304 
00305     | _bitsi (i8, ea)  => {
00306                         int bump = 0, bumpr;
00307                         strcpy(sslName, name);
00308                         sslName = '\0';         // Truncate name
00309                         RTs = instantiate(pc, sslName, DIS_I8, daEA(ea, pc,
00310                             bump, bumpr, 8));
00311                         ADDBUMP;
00312                         result.numBytes += 2;
00313                     }
00314 
00315     | _bitsi^".ex" (i8, eax, x) [name]  => {
00316                         strcpy(sslName, name);
00317                         sslName = '\0';         // Truncate name
00318                         RTs = instantiate(pc, sslName, DIS_I8,
00319                             daEAX(eax, x, result, pc, 8));
00320                         result.numBytes += 2;
00321                     }
00322     
00323     | btst (n, ea) => {
00324         // btst, btsti
00325             int bump = 0, bumpr;
00326             RTs = instantiate(pc, "btst", DIS_DN(32), dBEA(ea, pc, bump, bumpr, 8));
00327             ADDBUMP;
00328         }
00329    
00330 
00331     | btst^".ex" (n, eax, x) => { 
00332             RTs = instantiate (pc, "btst", DIS_DN(32),
00333                 dBEAX (eax, x, result, pc, delta, 8));
00334         }
00335 
00336     | btsti (i8, ea) => { 
00337             int bump = 0, bumpr;
00338             RTs = instantiate (pc, "btst", DIS_I8, dBEA (ea, pc, bump, bumpr, 8)); 
00339             ADDBUMP;
00340             result.numBytes += 2; 
00341         }
00342 
00343     | btsti.ex (i8, eax, x) => { 
00344             RTs = instantiate (pc, "btst", DIS_I8,
00345                 dBEAX (eax, x, result, pc, delta, 8));
00346             result.numBytes += 2; 
00347         // MOVEP: privileged (and uncommon as well)
00348         }
00349 
00350     | _move (ea, ea2)  => { 
00351         // MOVE
00352         // _move is  moveb | movew | movel
00353         // check b|w|l
00354             int bump = 0, bumpr, siz=32;
00355             SemStr* t1;     // Ptr to SemStr with src
00356             SemStr* t2;     // Ptr to SemStr with dest
00357             SemStr* t3;     // Ptr to SemStr with "temp1"
00358             strcpy(sslName, name);
00359             sslName = '\0';  // truncate name
00360             if (name[4] == 'b') siz = 8;
00361             if (name[4] == 'w') siz = 16;
00362             t1 = msEA(ea, pc, bump, bumpr, siz);
00363             RTs = new list<RT*>;    // Empty list of RTs
00364             ADDBUMP;                // Src may cause a bump
00365             bump = 0;
00366             t2 = mdEA(ea2, pc, bump, bumpr, siz);
00367             ADDBUMP;                // Dest may cause a bump as well
00368             // Check for An as a dest, and not 32 bits size
00369             RT* rt;
00370             bool sgnex = ((siz != 32) && (t2->getFirstIdx() == idRegOf) &&
00371               (t2->getThirdIdx() >= 8));
00372             if (sgnex) {
00373                 // Yes, therefore this is a sign extent to 32 bits
00374                 rt = sgnExTemp(t1, siz, 32, t3);
00375                 siz = 32;
00376                 t2->getType().setSize(32);
00377                 sslName = 'l';       // So the second assignment will be long
00378             }
00379             if (!sgnex)     // else
00380                 // Just assign the source to temp1
00381                 rt = assignTemp(t1, siz, t3); 
00382             // We instantiate RTs2 to be dest = temp1
00383             list<RT*>* RTs2 = (instantiate (pc, sslName, t3, t2));
00384             // RTs has 0-2 bumps (in the correct order). We must insert
00385             // before that dest = temp1, and before that rt (temp1 = src etc)
00386             RTs->insert(RTs->begin(), RTs2->begin(), RTs2->end());
00387             RTs->insert(RTs->begin(), rt);
00388             delete RTs2;
00389         }
00390 
00391     | _move^".ex" (eax, x, ea2) [name] => { 
00392             int bump = 0, bumpr, siz=32;
00393             if (name[4] == 'b') siz = 8;
00394             if (name[4] == 'w') siz = 16;
00395             strcpy(sslName, name);
00396             sslName = '\0';  // truncate name
00397             RTs = instantiate (pc, sslName,
00398                 msEAX (eax, x, result, pc, delta, siz),
00399                 mdEA (ea2, pc, bump, bumpr, siz));
00400             ADDBUMP;
00401         }
00402 
00403     | _move^".exl" (eaxl, d32, ea2) [name] => { 
00404             int bump = 0, bumpr;
00405             int siz = 32;
00406             if (name[4] == 'b') siz = 8;
00407             if (name[4] == 'w') siz = 16;
00408             strcpy(sslName, name);
00409             sslName = '\0';  // truncate name
00410             RTs = instantiate (pc, sslName,
00411                 msEAXL (eaxl, d32, result, pc, siz),
00412                 mdEA (ea2, pc, bump, bumpr, siz)); 
00413             ADDBUMP;
00414         }
00415 
00416     | _move^".mx" (ea, eax2, x2) [name] => { 
00417             int bump = 0, bumpr;
00418             int siz = 32;
00419             if (name[4] == 'b') siz = 8;
00420             if (name[4] == 'w') siz = 16;
00421             strcpy(sslName, name);
00422             sslName = '\0';  // truncate name
00423             RTs = instantiate (pc, sslName,
00424                 msEA (ea, pc, bump, bumpr, siz), 
00425                 mdEAX (eax2, x2, result, pc, siz)); 
00426             ADDBUMP;
00427         }
00428 
00429     | _move^".emx" (eax, x, eax2, x2) [name]      => { 
00430             int siz = 32;
00431             if (name[4] == 'b') siz = 8;
00432             if (name[4] == 'w') siz = 16;
00433             strcpy(sslName, name);
00434             sslName = '\0';  // truncate name
00435             RTs = instantiate (pc, sslName,
00436                 msEAX (eax, x, result, pc, delta, siz),
00437                 mdEAX (eax2, x2, result, pc, siz)); 
00438         }
00439 
00440     | _move^".emxl" (eaxl, d32, eax2, x2) [name]  => { 
00441             int siz = 32;
00442             if (name[4] == 'b') siz = 8;
00443             if (name[4] == 'w') siz = 16;
00444             strcpy(sslName, name);
00445             sslName = '\0';  // truncate name
00446             RTs = instantiate (pc, sslName,
00447                 msEAXL (eaxl, d32, result, pc, siz),
00448                 mdEAX (eax2, x2, result, pc, siz)); 
00449         }
00450 
00451 
00452     | _oneEAdaB (ea)             => { 
00453         // One operand instructions 
00454         //  _oneEAdaB is  clrb | negb | negxb | notb | tstb | nbcd | tas
00455         //  _oneEAdaW is  clrw | negw | negxw | notw | tstw
00456         //  _oneEAdaL is  clrl | negl | negxl | notl | tstl
00457             int bump = 0, bumpr;
00458             chopDotex(name);
00459             RTs = instantiate (pc, sslName, daEA (ea, pc, bump, bumpr, 8)); 
00460             ADDBUMP;
00461         }  
00462 
00463     | _oneEAdaB^".ex" (eax, x) [name]  => { 
00464             chopDotex(name);
00465             RTs = instantiate (pc, sslName, daEAX (eax, x, result, pc, 8)); 
00466         }
00467 
00468     | _oneEAdaW (ea)             => { 
00469             int bump = 0, bumpr;
00470             chopDotex(name);
00471             RTs = instantiate (pc, sslName, daEA (ea, pc, bump, bumpr, 16)); 
00472             ADDBUMP;
00473         }
00474 
00475     | _oneEAdaW^".ex" (eax, x) [name]  => { 
00476             chopDotex(name);
00477             RTs = instantiate (pc, sslName, daEAX (eax, x, result, pc, 16)); 
00478         }
00479 
00480     | _oneEAdaL (ea)             => { 
00481             int bump = 0, bumpr;
00482             chopDotex(name);
00483             RTs = instantiate (pc, sslName, daEA (ea, pc, bump, bumpr, 32));
00484             ADDBUMP;
00485         }
00486 
00487     | _oneEAdaL^".ex" (eax, x) [name]  => { 
00488             chopDotex(name);
00489             RTs = instantiate (pc, sslName,
00490                 daEAX (eax, x, result, pc, 32));
00491         }
00492 
00493     | _oneEAc (ea)             => { 
00494         // _oneEAc   is  jsr | jmp | pea    
00495             strcpy(sslName, name);
00496             sslName = '\0'; 
00497             RTs = instantiate (pc, sslName, cEA (ea, pc, 32)); 
00498         }
00499 
00500     | _oneEAc^".ex" (eax, x) [name]  => { 
00501             strcpy(sslName, name);
00502             sslName = '\0';
00503             RTs = instantiate (pc, sslName,
00504                 cEAX (eax, x, result, pc, delta, 32)); 
00505         } 
00506 
00507     | unlk (n)        => { 
00508         // unlk
00509             RTs = instantiate (pc, name, DIS_AN); 
00510         }
00511     
00512     | _reg2only (n)            => { 
00513         // _reg2only is  extw | extl | swap
00514         // extbl is 68020 specific
00515             chopDotex(name);
00516             int siz = 16;
00517             if (sslName[3] == 'l') siz = 32;
00518             RTs = instantiate (pc, sslName, DIS_DN(siz)); 
00519         }
00520 
00521     | _noArg ()                => { 
00522         // _noArg is illegal | reset | nop | rte | rts | trapv | rtr
00523             RTs = instantiate (pc, name); 
00524         // MOVE to/from SR is priveleged
00525         } 
00526 
00527     | moveToCCR (ea)          => {
00528         // MOVE to/from CCR
00529             int bump = 0, bumpr;
00530             RTs = instantiate (pc, name, dWEA(ea, pc, bump, bumpr, 16));
00531             ADDBUMP;
00532         }
00533 
00534     | moveToCCR.ex (eax, x)   => {
00535             RTs = instantiate (pc, name,
00536                 dWEAX(eax, x, result, pc, delta, 16));
00537         }
00538 
00539     | moveFromCCR (ea)        => {
00540             int bump = 0, bumpr;
00541             RTs = instantiate (pc, name, daEA(ea, pc, bump, bumpr, 16));
00542             ADDBUMP;
00543         }
00544 
00545     | moveFromCCR.ex (eax, x)  => {
00546             RTs = instantiate (pc, name, daEAX(eax, x, result, pc, 16));
00547         }
00548 
00549     | trap (d4) => {
00550         // Trap: as far as Palm Pilots are concerned, these are NOPs, except
00551         // that an A-line instruction can then legally follow
00552             RTs = instantiate(pc, "NOP");
00553             IsTrap = true;
00554             assert(d4 == d4);       // Suppress unused var warning
00555         }
00556 
00557     | link (n, i16)           => { 
00558         // link
00559             RTs = instantiate (pc, name, DIS_AN, DIS_I16); 
00560             result.numBytes += 2; 
00561         // moveFromUSP, moveToUSP privileged
00562                     }
00563     
00564     | movermw (i16, ea)             => { 
00565         // MOVEA -- These are any moves where the destination is an address reg
00566         // MOVEM rm means registers to memory
00567         // HACK! This requires work! Need to bump after EACH register has been
00568         // moved! Mostly, these will be in prologues/epilogues
00569             int bump = 0, bumpr;
00570             RTs = instantiate (pc, "storem.w", DIS_I16,
00571                 rmEA (ea, pc, bump, bumpr, 16));
00572             result.numBytes += 2; 
00573             ADDBUMP;
00574         }   
00575 
00576     | movermw.ex (i16, eax, x) => { 
00577             RTs = instantiate (pc, "storem.w", DIS_I16, 
00578                 rmEAX (eax, x, result, pc, 16)); 
00579             result.numBytes += 2; 
00580         }  
00581 
00582     | movemrw (ea, i16)        => {
00583         // HACK! Requires work
00584             int bump = 0, bumpr;
00585             RTs = instantiate (pc, "loadm.w", DIS_I16,
00586                 mrEA (ea, pc, bump, bumpr, 16));
00587             result.numBytes += 2;
00588             ADDBUMP;
00589         }
00590 
00591     | movemrw.ex (eax, x, i16) => {
00592             RTs = instantiate (pc, "loadm.w", DIS_I16, 
00593                 mrEAX (eax, x, result, pc, delta, 16)); 
00594             result.numBytes += 2; 
00595         }  
00596 
00597     | moverml (i16, ea)        => { 
00598             // HACK! Needs work
00599             int bump = 0, bumpr;
00600             RTs = instantiate (pc, "storem.l", DIS_I16,
00601                 rmEA (ea, pc, bump, bumpr, 32));
00602             result.numBytes += 2; 
00603             ADDBUMP;
00604         } 
00605 
00606     | moverml.ex (i16, eax, x) => { 
00607             RTs = instantiate (pc, "storem.l", DIS_I16, 
00608                 rmEAX(eax, x, result, pc, 32));
00609             result.numBytes += 2; 
00610         }   
00611 
00612     | movemrl (ea, i16)        => {
00613         // HACK! Requires work
00614             int bump = 0, bumpr;
00615             RTs = instantiate (pc, "loadm.l", DIS_I16,
00616                 mrEA (ea, pc, bump, bumpr, 32));
00617             result.numBytes += 2; 
00618             ADDBUMP;
00619         } 
00620 
00621     | movemrl.ex (eax, x, i16) => {
00622             RTs = instantiate (pc, "loadm.l", DIS_I16, 
00623                     mrEAX(eax, x, result, pc, delta, 32));
00624             result.numBytes += 2; 
00625         }   
00626 
00627     | lea (ea, n)            => { 
00628         // lea    
00629             RTs = instantiate (pc, "lea", cEA (ea, pc, 32), DIS_AN); 
00630         }  
00631 
00632     | lea.ex (eax, x, n)     => { 
00633             RTs = instantiate (pc, "lea",
00634                 cEAX (eax, x, result, pc, delta, 32), DIS_AN); 
00635         }
00636 
00637     | _aluqB (i8, ea)             => { 
00638         // ADDQ, SUBQ     
00639         // The data parameter is 3 bits (d3) but a byte will be returned anyway
00640             int bump = 0, bumpr;
00641             chop2ndLast(name);          // addqb -> addb
00642             if (i8 == 0) i8 = 8;        // Quirk of the addq/subq instr
00643             RTs = instantiate (pc, sslName, DIS_I8, alEA (ea, pc, bump, bumpr, 8)); 
00644             ADDBUMP;
00645         }
00646 
00647     | _aluqB^".ex" (i8, eax, x) [name]  => { 
00648             chopBoth(name);             // addqb.ex -> addb
00649             sslName = '\0'; 
00650             if (i8 == 0) i8 = 8;        // Quirk of the addq/subq instr
00651             RTs = instantiate (pc, sslName, DIS_I8, alEAX (eax, x, result, pc, 8));
00652         }
00653 
00654     | _aluqW (i8, ea)             => { 
00655             int bump = 0, bumpr;
00656             if (i8 == 0) i8 = 8;        // Quirk of the addq/subq instr
00657             SemStr* dst = alEA (ea, pc, bump, bumpr, 16);
00658             bool b = (dst->getFirstIdx() == idRegOf) && 
00659                 (dst->getSecondIdx() == idIntConst) && 
00660                 (dst->getThirdIdx() >= 8);
00661             if (b) {
00662                 // We have addq/subq to an address register. These do not
00663                 // affect the flags (all others do). Also, the instruction
00664                 // is always 32 bits. So we give it a different SSL name
00665                 strcpy(sslName, name);
00666                 sslName = '\0';
00667                 strcat(sslName, "qa");     // addqw -> addqa
00668             }
00669             //if (!b)                       // Can't use else
00670             } else {                        // Can use else if not at start
00671                 chop2ndLast(name);          // addqw -> addw
00672             }
00673             RTs = instantiate (pc, sslName, DIS_I8, dst); 
00674             ADDBUMP;
00675         } 
00676 
00677     | _aluqW^".ex" (i8, eax, x) [name]  => { 
00678             chopBoth(name);             // addqb.ex -> addb
00679             if (i8 == 0) i8 = 8;        // Quirk of the addq/subq instr
00680             RTs = instantiate (pc, sslName, DIS_I8,
00681                 alEAX (eax, x, result, pc, 16)); 
00682         } 
00683 
00684     | _aluqL (i8, ea)             => { 
00685             int bump = 0, bumpr;
00686             if (i8 == 0) i8 = 8;        // Quirk of the addq/subq instr
00687             SemStr* dst = alEA (ea, pc, bump, bumpr, 32);
00688             bool b = (dst->getFirstIdx() == idRegOf) && 
00689                 (dst->getSecondIdx() == idIntConst) && 
00690                 (dst->getThirdIdx() >= 8);
00691             if (b) {
00692                 // We have addq/subq to an address register. These do not
00693                 // affect the flags (all others do). So we give it a different
00694                 // SSL name
00695                 strcpy(sslName, name);
00696                 sslName = '\0';
00697                 strcat(sslName, "qa");      // subl -> subqa
00698             }
00699             //if (!b)                         // Can't use else
00700             } else {
00701                 chop2ndLast(name);          // addqw -> addw
00702             }
00703             RTs = instantiate (pc, sslName, DIS_I8, dst); 
00704             ADDBUMP;
00705         }   
00706 
00707     | _aluqL^".ex" (i8, eax, x) [name]  => { 
00708             chopBoth(name);             // addql.ex -> addl
00709             if (i8 == 0) i8 = 8;        // Quirk of the addq/subq instr
00710             RTs = instantiate (pc, sslName, DIS_I8, alEAX (eax, x, result, pc, 32));
00711         }   
00712 
00713     | _dbcc (n, i16)   => { 
00714         // DBcc     
00715             RTs = instantiate (pc, name, DIS_DN(32), DIS_I16); 
00716             result.numBytes += 2; 
00717         }
00718     
00719     | _s (ea)            => { 
00720         // Scc
00721         // I assume that these are 8 bits where memory is involved, but
00722         // 32 where registers are involved
00723             int bump = 0, bumpr;
00724             RTs = instantiate (pc, name, daEA (ea, pc, bump, bumpr, 8));
00725             ADDBUMP;
00726         }
00727 
00728     | _s^".ex" (eax, x) [name] => { 
00729             RTs = instantiate (pc, name, daEAX (eax, x, result, pc, 8));
00730         } 
00731 
00732     
00733     | _uBranch (a)   => { 
00734         // _uBranch is  bra | bsr
00735             strcpy(sslName, name);
00736             if (strcmp (sslName, "bsr") == 0)
00737                 strcpy (sslName, "jsr"); 
00738             RTs = instantiate (pc, sslName, BTA (a, result, pc)); 
00739         }
00740 
00741     | _br(a)   => { 
00742         // Bcc
00743             RTs = instantiate (pc, name, BTA (a, result, pc)); 
00744         }
00745 
00746     | moveq (i8, n)  => { 
00747         // moveq (semantics of move immediate long)
00748             RTs = instantiate (pc, "movel", DIS_I8, DIS_DN(32)); 
00749         } 
00750 
00751     | _alurdw (ea, n)             => { 
00752         // _alurdw is divs | divu | muls | mulu
00753         //// in order for this to match, the 'w' needs to be dropped off the
00754         //// SSL names DIVUw and MUL[idx]w
00755             int bump = 0, bumpr;
00756             RTs = instantiate (pc, name, dWEA (ea, pc, bump, bumpr, 16), DIS_DN(16)); 
00757             ADDBUMP;
00758         }   
00759 
00760     | _alurdw^".ex" (eax, x, n) [name]  => { 
00761             RTs = instantiate (pc, name,
00762                 dWEAX (eax, x, result, pc, delta, 16), DIS_DN(16)); 
00763         }
00764 
00765     | _twoRegRB (n, n2)   => {
00766         // _twoReg** (addx | subx | abcd | sbcd | cmp) 
00767             strcpy(sslName, name);
00768             if (strncmp(sslName, "cmp", 3) == 0) sslName = '\0';
00769             sslName = '\0';
00770             strcat(sslName, "b");         // Force 8 bit size
00771             RTs = instantiate (pc, sslName, DIS_DN(8), DIS_DN2(8));
00772         } 
00773 
00774     | _twoRegMB (n, n2)   => {
00775             int bump = 0, bumpr;
00776             strcpy(sslName, name);
00777             if (strncmp(sslName, "cmp", 3) == 0) sslName = '\0';
00778             sslName = '\0';
00779             strcat(sslName, "b");         // Force 8 bit size
00780             SemStr* t1;
00781             RT* rt = assignTemp(pPreDec(n, bump, bumpr, 8), 8, t1);
00782             ADDBUMP;
00783             bump = 0;
00784             RTs = instantiate (pc, sslName, t1, pPreDec(n2, bump, bumpr, 8));
00785             RTs->insert(RTs->begin(), rt);
00786             ADDBUMP;
00787         } 
00788 
00789     | _twoRegRW (n, n2)   => {
00790             strcpy(sslName, name);
00791             if (strncmp(sslName, "cmp", 3) == 0) sslName = '\0';
00792             sslName = '\0';
00793             strcat(name, "w");         // Force 16 bit size
00794             RTs = instantiate (pc, sslName, DIS_DN(16), DIS_DN2(16));
00795         } 
00796 
00797     | _twoRegMW (n, n2)   => {
00798             int bump = 0, bumpr;
00799             strcpy(sslName, name);
00800             if (strncmp(sslName, "cmp", 3) == 0) sslName = '\0';
00801             sslName = '\0';
00802             strcat(sslName, "w");         // Force 16 bit size
00803             SemStr* t1;
00804             RT* rt = assignTemp(pPreDec(n, bump, bumpr, 16), 16, t1);
00805             ADDBUMP;
00806             bump = 0;
00807             RTs = instantiate (pc, sslName, t1, pPreDec(n2, bump, bumpr, 16));
00808             RTs->insert(RTs->begin(), rt);
00809             ADDBUMP;
00810         } 
00811 
00812     | _twoRegRL (n, n2)   => {
00813             strcpy(sslName, name);
00814             if (strncmp(sslName, "cmp", 3) == 0) sslName = '\0';
00815             sslName = '\0';
00816             strcat(sslName, "l");         // Force 32 bit size
00817             RTs = instantiate (pc, sslName, DIS_DN(32), DIS_DN2(32));
00818         } 
00819 
00820     | _twoRegML (n, n2)   => {
00821             int bump = 0, bumpr;
00822             strcpy(sslName, name);
00823             if (strncmp(sslName, "cmp", 3) == 0) sslName = '\0';
00824             sslName = '\0';
00825             strcat(sslName, "l");         // Force 32 bit size
00826             SemStr* t1;
00827             RT* rt = assignTemp(pPreDec(n, bump, bumpr, 32), 32, t1);
00828             ADDBUMP;
00829             bump = 0;
00830             RTs = instantiate (pc, sslName, t1, pPreDec(n2, bump, bumpr, 32));
00831             RTs->insert(RTs->begin(), rt);
00832             ADDBUMP;
00833         } 
00834 
00835     | _alurdB (ea, n)             => {
00836         // _alurdB  is  andrb | orrb
00837             int bump = 0, bumpr;
00838             chop2ndLast(name);
00839             RTs = instantiate (pc, sslName, dEA(ea, pc, bump, bumpr, 8), DIS_DN(8));
00840             ADDBUMP;
00841         }
00842 
00843     | _alurdB^".ex" (eax, x, n) [name]  => {
00844             chopBoth(name);
00845             RTs = instantiate (pc, sslName,
00846                 dEAX(eax, x, result, pc, delta, 8), DIS_DN(8));
00847         }
00848 
00849     | _alurdW (ea, n)             => {
00850             int bump = 0, bumpr;
00851             chop2ndLast(name);
00852             RTs = instantiate (pc, sslName, dEA(ea, pc, bump, bumpr, 16),
00853                 DIS_DN(16));
00854             ADDBUMP;
00855         }
00856 
00857     | _alurdW^".ex" (eax, x, n) [name]  => {
00858             chopBoth(name);
00859             RTs = instantiate (pc, sslName,
00860                 dEAX(eax, x, result, pc, delta, 16), DIS_DN(16));
00861         }
00862 
00863     | _alurdL (ea, n)             => {
00864             int bump = 0, bumpr;
00865             chop2ndLast(name);
00866             RTs = instantiate (pc, sslName, dEA(ea, pc, bump, bumpr, 32), DIS_DN(32));
00867             ADDBUMP;
00868         }
00869 
00870     | _alurdL^".ex" (eax, x, n) [name]  => {
00871             chopBoth(name);
00872             RTs = instantiate (pc, sslName,
00873                 dEAX(eax, x, result, pc, delta, 32), DIS_DN(32));
00874         }
00875 
00876 
00877     | _alumB (n, ea)              => {
00878         // _alumB   is  addmb | andmb | ormb  | submb
00879             int bump = 0, bumpr;
00880             chop2ndLast(name);
00881             RTs = instantiate (pc, sslName, DIS_DN(8), maEA(ea, pc, bump, bumpr, 8));
00882             ADDBUMP;
00883         }
00884 
00885     | _alumB^".ex" (n, eax, x) [name]   => {
00886             chopBoth(name);
00887             RTs = instantiate (pc, sslName, DIS_DN(8),
00888                 maEAX(eax, x, result, pc, 8));
00889         }
00890 
00891     | _alumW (n, ea)              => {
00892             int bump = 0, bumpr;
00893             chop2ndLast(name);
00894             RTs = instantiate (pc, sslName, DIS_DN(16), maEA(ea, pc, bump, bumpr,
00895                 16));
00896             ADDBUMP;
00897         }
00898 
00899     | _alumW^".ex" (n, eax, x) [name]   => {
00900             chopBoth(name);
00901             RTs = instantiate (pc, sslName, DIS_DN(16),
00902                 maEAX(eax, x, result, pc, 16));
00903         }
00904 
00905     | _alumL (n, ea)              => {
00906             int bump = 0, bumpr;
00907             chop2ndLast(name);
00908             RTs = instantiate (pc, sslName, DIS_DN(32), maEA(ea, pc, bump, bumpr,
00909                 32));
00910             ADDBUMP;
00911         }
00912 
00913     | _alumL^".ex" (n, eax, x) [name]   => {
00914             chopBoth(name);
00915             RTs = instantiate (pc, sslName, DIS_DN(32),
00916                 maEAX(eax, x, result, pc, 32));
00917         }
00918 
00919 
00920 
00921     | _aluaW (ea, n)              => {
00922         // _aluaW   is  addaw | cmpaw | subaw 
00923             int bump = 0, bumpr;
00924             chop2ndLast(name);
00925             RTs = instantiate (pc, sslName, awlEA(ea, pc, bump, bumpr, 16), DIS_AN);
00926             ADDBUMP;
00927         }
00928 
00929     | _aluaW^".ex" (eax, x, n) [name]   => {
00930             chopBoth(name);
00931             RTs = instantiate(pc, sslName,
00932                 awlEAX(eax, x, result, pc, delta, 16), DIS_AN);
00933         }
00934 
00935     | _aluaL (ea, n)              => {
00936             int bump = 0, bumpr;
00937             chop2ndLast(name);
00938             RTs = instantiate (pc, sslName, awlEA(ea, pc, bump, bumpr, 32), DIS_AN);
00939             ADDBUMP;
00940         }
00941 
00942     | _aluaL^".ex" (eax, x, n) [name]   => {
00943             chopBoth(name);
00944             RTs = instantiate(pc, sslName,
00945                 awlEAX(eax, x, result, pc, delta, 32), DIS_AN);
00946         }
00947 
00948     | eorb (n, ea)  => {
00949             int bump = 0, bumpr;
00950             RTs = instantiate (pc, name, DIS_DN(8), daEA(ea, pc, bump, bumpr, 8));
00951             ADDBUMP;
00952         }
00953 
00954     | eorb.ex (n, eax, x)  => {
00955             RTs = instantiate (pc, name, DIS_DN(8),
00956                 daEAX(eax, x, result, pc, 8));
00957         }
00958 
00959     | eorw (n, ea)  => {
00960             int bump = 0, bumpr;
00961             RTs = instantiate (pc, name, DIS_DN(16), daEA(ea, pc, bump, bumpr, 16));
00962             ADDBUMP;
00963         }
00964 
00965     | eorw.ex (n, eax, x)  => {
00966             RTs = instantiate (pc, name, DIS_DN(16),
00967                 daEAX(eax, x, result, pc, 16));
00968         }
00969 
00970     | eorl (n, ea)  => {
00971             int bump = 0, bumpr;
00972             RTs = instantiate (pc, name, DIS_DN(32), daEA(ea, pc, bump, bumpr, 32));
00973             ADDBUMP;
00974         }
00975 
00976     | eorl.ex (n, eax, x)  => {
00977             RTs = instantiate (pc, name, DIS_DN(32),
00978                 daEAX(eax, x, result, pc, 32));
00979         }
00980 
00981     
00982     | exgdd (n, n2)  => {
00983             RTs = instantiate (pc, name, DIS_DN(32), DIS_DN2(32));
00984         }
00985 
00986     | exgaa (n, n2)  => {
00987             RTs = instantiate (pc, name, DIS_AN, DIS_AN2);
00988         }
00989 
00990     | exgda (n, n2)  => {
00991             RTs = instantiate (pc, name, DIS_DN(32), DIS_AN2);
00992         }
00993 
00994     
00995     | _alurB (ea, n)   => {
00996         // ADD, AND, CHK, CMP, CMPA, DIVS, DIVU, MULS, MULU, OR, SUB, SUBA
00997             int bump = 0, bumpr;
00998             chopDotex(name);           // Fix the name
00999             RTs = instantiate (pc, sslName, amEA(ea, pc, bump, bumpr, 8), DIS_DN(8));
01000             ADDBUMP;
01001         }
01002 
01003     | _alurB^".ex" (eax, x, n) [name]   => {
01004             chopDotex(name);           // Fix the name
01005             RTs = instantiate (pc, sslName,
01006                 amEAX(eax, x, result, pc, delta, 8), DIS_DN(8));
01007         }
01008     
01009     | _alurW (ea, n)   => {
01010             int bump = 0, bumpr;
01011             chopDotex(name);           // Fix the name
01012             RTs = instantiate (pc, sslName, amEA(ea, pc, bump, bumpr, 16),
01013                 DIS_DN(16));
01014             ADDBUMP;
01015         }
01016 
01017     | _alurW^".ex" (eax, x, n) [name]   => {
01018             chopDotex(name);           // Fix the name
01019             RTs = instantiate (pc, sslName,
01020                 amEAX(eax, x, result, pc, delta, 16), DIS_DN(16));
01021         }
01022 
01023     | _alurL (ea, n)   => {
01024             int bump = 0, bumpr;
01025             chopDotex(name);           // Fix the name
01026             RTs = instantiate (pc, sslName, amEA(ea, pc, bump, bumpr, 32),
01027                 DIS_DN(32));
01028             ADDBUMP;
01029         }
01030 
01031     | _alurL^".ex" (eax, x, n) [name]  => {
01032             chopDotex(name);           // Fix the name
01033             RTs = instantiate (pc, sslName,
01034                 amEAX(eax, x, result, pc, delta, 32), DIS_DN(32));
01035         }
01036 
01037 
01038     | _shiftMR (ea)   => {
01039         // ASL, ASR, LSL, LSR, ROL, ROR, ROXL, ROXR
01040             int bump = 0, bumpr;
01041             chopDotex(name);           // Fix the name
01042             int lst = strlen(sslName) - 1;
01043             int siz = 32;
01044             if (sslName[lst] == 'b') siz = 8;
01045             if (sslName[lst] == 'w') siz = 16;
01046             RTs = instantiate (pc, sslName, maEA(ea, pc, bump, bumpr, siz));
01047             ADDBUMP;
01048         }
01049 
01050     | _shiftMR^".ex" (eax, x) [name]  => {
01051             chopDotex(name);           // Fix the name
01052             RTs = instantiate (pc, sslName, maEAX(eax, x, result, pc, 16));
01053         }
01054 
01055     | _shiftML (ea)             => {
01056             int bump = 0, bumpr;
01057             chopDotex(name);           // Fix the name
01058             int lst = strlen(sslName) - 1;
01059             int siz = 32;
01060             if (sslName[lst] == 'b') siz = 8;
01061             if (sslName[lst] == 'w') siz = 16;
01062             RTs = instantiate (pc, sslName, maEA(ea, pc, bump, bumpr, siz));
01063             ADDBUMP;
01064         }
01065 
01066     | _shiftML^".ex" (eax, x) [name]  => {
01067             chopDotex(name);           // Fix the name
01068             RTs = instantiate (pc, sslName, maEAX(eax, x, result, pc, 16));
01069         }
01070 
01071     
01072     | _shiftIRB (i8, n)    => {
01073         // _shiftIRB    is  asrib | lsrib | rorib | roxrib
01074             chop2ndLast(name);
01075             RTs = instantiate (pc, sslName, DIS_I8, DIS_DN(8));
01076         }
01077     
01078     | _shiftILB (i8, n)    => {
01079             chop2ndLast(name);
01080             RTs = instantiate (pc, sslName, DIS_I8, DIS_DN(8));
01081         }
01082     
01083     | _shiftIRW (i8, n)    => {
01084             chop2ndLast(name);
01085             RTs = instantiate (pc, sslName, DIS_I8, DIS_DN(16));
01086         }
01087     
01088     | _shiftILW (i8, n)    => {
01089             chop2ndLast(name);
01090             RTs = instantiate (pc, sslName, DIS_I8, DIS_DN(16));
01091         }
01092     
01093     | _shiftIRL (i8, n)    => {
01094             chop2ndLast(name);
01095             RTs = instantiate (pc, sslName, DIS_I8, DIS_DN(32));
01096         }
01097     
01098     | _shiftILL (i8, n)    => {
01099             chop2ndLast(name);
01100             RTs = instantiate (pc, sslName, DIS_I8, DIS_DN(32));
01101         }
01102     
01103     
01104     | _shiftRRB (n, n2)    => {
01105         // _shiftRRB    is  asrrb | lsrrb | rorrb | roxrrb
01106             chop2ndLast(name);
01107             RTs = instantiate (pc, sslName, DIS_DN(8), DIS_DN2(8));
01108         }
01109 
01110     | _shiftRLB (n, n2)    => {
01111             chop2ndLast(name);
01112             RTs = instantiate (pc, sslName, DIS_DN(8), DIS_DN2(8));
01113         }
01114     
01115     | _shiftRRW (n, n2)    => {
01116             chop2ndLast(name);
01117             RTs = instantiate (pc, sslName, DIS_DN(16), DIS_DN2(16));
01118         }
01119     
01120     | _shiftRLW (n, n2)    => {
01121             chop2ndLast(name);
01122             RTs = instantiate (pc, sslName, DIS_DN(16), DIS_DN2(16));
01123         }
01124     
01125     | _shiftRRL (n, n2)    => {
01126             chop2ndLast(name);
01127             RTs = instantiate (pc, sslName, DIS_DN(32), DIS_DN2(32));
01128         }
01129     
01130     | _shiftRLL (n, n2)    => {
01131             chop2ndLast(name);
01132             RTs = instantiate (pc, sslName, DIS_DN(32), DIS_DN2(32));
01133         }
01134 
01135     else    {   // the toolkit reserves "else" as a keyword, hence this code
01136                 if (!prevIsTrap) {
01137                     ostrstream ost;
01138                     ost << "Undecoded instruction " << hex << getWord(pc+delta);
01139                     ost << " at " << pc;
01140                     warning(str(ost));
01141                     RTs = NULL;
01142                 }
01143                 if (prevIsTrap) 
01144                     decodeTrapName (pc);
01145     }  
01146   endmatch
01147 
01148     result.numBytes += 2;           // Count the main opcode
01149     return RTs;
01150 }
01151 
01152 

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