st20decoder.cpp

Go to the documentation of this file.
00001 #define sign_extend(N,SIZE) (((int)((N) << (sizeof(unsigned)*8-(SIZE)))) >> (sizeof(unsigned)*8-(SIZE)))
00002 #include <assert.h>
00003 
00004 #line 1 "frontend/machine/st20/decoder.m"
00005 /*
00006  * Copyright (C) 2005 Mike Van Emmerik
00007  *
00008  * See the file "LICENSE.TERMS" for information on usage and
00009  * redistribution of this file, and for a DISCLAIMER OF ALL
00010  * WARRANTIES.
00011  *
00012  */
00013 
00014 /*==============================================================================
00015  * FILE:       decoder.m
00016  * OVERVIEW:   This file contains the high level decoding functionality, for matching ST-20 instructions.
00017  *============================================================================*/ 
00018 /*
00019  * $Revision: 1.3 $ // 1.2.2.2
00020  *
00021  * 10 Mar 05 - Mike: Created.
00022 */
00023 
00024 #include <assert.h>
00025 
00026 #include "rtl.h"
00027 #include "decoder.h"
00028 #include "st20decoder.h"
00029 #include "exp.h"
00030 #include "proc.h"
00031 #include "boomerang.h"
00032 #include "statement.h"
00033 
00034 /**********************************
00035  * ST20Decoder methods.
00036  **********************************/   
00037 
00038 /*==============================================================================
00039  * FUNCTION:       unused
00040  * OVERVIEW:       A dummy function to suppress "unused local variable" messages
00041  * PARAMETERS:     x: integer variable to be "used"
00042  * RETURNS:        Nothing
00043  *============================================================================*/
00044 void ST20Decoder::unused(int x)
00045 {}
00046 
00047 /*==============================================================================
00048  * FUNCTION:       ST20Decoder::decodeInstruction
00049  * OVERVIEW:       Decodes a machine instruction and returns an RTL instance. In all cases a single instruction is decoded.
00050  * PARAMETERS:     pc - the native address of the pc
00051  *                 delta - the difference between the above address and the host address of the pc (i.e. the address that
00052                     the pc is at in the loaded object file)
00053  *                 RTLDict - the dictionary of RTL templates used to instantiate the RTL for the instruction being decoded
00054  *                 proc - the enclosing procedure
00055  * RETURNS:        a DecodeResult structure containing all the information gathered during decoding
00056  *============================================================================*/
00057 static  DecodeResult result;
00058 DecodeResult& ST20Decoder::decodeInstruction (ADDRESS pc, int delta) {
00059     result.reset();                         // Clear the result structure (numBytes = 0 etc)
00060     ADDRESS hostPC = pc + delta;
00061     std::list<Statement*>* stmts = NULL;    // The actual list of instantiated Statements
00062     unsigned total = 0;                     // Total value from all prefixes
00063 
00064     while (1) {
00065 
00066 
00067 #line 60 "frontend/machine/st20/decoder.m"
00068 { 
00069   dword MATCH_p = 
00070     
00071 #line 60 "frontend/machine/st20/decoder.m"
00072     hostPC+result.numBytes++
00073     ;
00074   char *MATCH_name;
00075   static char *MATCH_name_fc_0[] = {
00076     (char *)0, "ldlp", (char *)0, "ldnl", "ldc", "ldnlp", (char *)0, "ldl", 
00077     "adc", (char *)0, (char *)0, "ajw", "eqc", "stl", "stnl", 
00078   };
00079   unsigned /* [0..255] */ MATCH_w_8_0;
00080   { 
00081     MATCH_w_8_0 = getByte(MATCH_p); 
00082     
00083       switch((MATCH_w_8_0 >> 4 & 0xf) /* fc at 0 */) {
00084         case 0: 
00085           { 
00086             unsigned oper = (MATCH_w_8_0 & 0xf) /* bot at 0 */;
00087             
00088 #line 74 "frontend/machine/st20/decoder.m"
00089             
00090 
00091                         unconditionalJump("j", result.numBytes, hostPC+result.numBytes+total+oper, delta, pc, stmts, result);
00092 
00093             
00094 
00095             
00096             
00097             
00098           }
00099           
00100           break;
00101         case 1: case 3: case 4: case 5: case 7: case 8: case 11: case 12: 
00102         case 13: case 14: 
00103           MATCH_name = 
00104             MATCH_name_fc_0[(MATCH_w_8_0 >> 4 & 0xf) /* fc at 0 */]; 
00105           { 
00106             char *name = MATCH_name;
00107             unsigned oper = (MATCH_w_8_0 & 0xf) /* bot at 0 */;
00108             
00109 #line 71 "frontend/machine/st20/decoder.m"
00110             
00111 
00112                         stmts = instantiate(pc, name, new Const(total+oper));
00113 
00114             
00115 
00116             
00117             
00118             
00119           }
00120           
00121           break;
00122         case 2: 
00123           { 
00124             unsigned oper = (MATCH_w_8_0 & 0xf) /* bot at 0 */;
00125             
00126 #line 63 "frontend/machine/st20/decoder.m"
00127             
00128 
00129                         total = (total + oper) << 4;
00130 
00131                         continue;
00132 
00133                                 
00134 
00135             
00136             
00137             
00138           }
00139           
00140           break;
00141         case 6: 
00142           { 
00143             unsigned oper = (MATCH_w_8_0 & 0xf) /* bot at 0 */;
00144             
00145 #line 67 "frontend/machine/st20/decoder.m"
00146             
00147 
00148                         total = (total + ~oper) << 4;
00149 
00150                         continue;
00151 
00152             
00153 
00154             
00155             
00156             
00157           }
00158           
00159           break;
00160         case 9: 
00161           { 
00162             unsigned oper = (MATCH_w_8_0 & 0xf) /* bot at 0 */;
00163             
00164 #line 77 "frontend/machine/st20/decoder.m"
00165             
00166 
00167                         total += oper;
00168 
00169                         stmts = instantiate(pc, "call" , new Const(total));
00170 
00171                         CallStatement* newCall = new CallStatement;
00172 
00173                         newCall->setIsComputed(false);
00174 
00175                         newCall->setDest(pc+result.numBytes+total);
00176 
00177                         result.rtl = new RTL(pc, stmts);
00178 
00179                         result.rtl->appendStmt(newCall);
00180 
00181             
00182 
00183             
00184             
00185             
00186           }
00187           
00188           break;
00189         case 10: 
00190           { 
00191             unsigned oper = (MATCH_w_8_0 & 0xf) /* bot at 0 */;
00192             
00193 #line 86 "frontend/machine/st20/decoder.m"
00194             
00195 
00196                         BranchStatement* br = new BranchStatement();
00197 
00198                         //br->setCondType(BRANCH_JE);
00199 
00200                         br->setDest(pc+result.numBytes+total+oper);
00201 
00202                         //br->setCondExpr(dis_Reg(0));
00203 
00204                         br->setCondExpr(new Binary(opEquals,dis_Reg(0),new Const(0)));
00205 
00206                         result.rtl = new RTL(pc, stmts);
00207 
00208                         result.rtl->appendStmt(br);
00209 
00210             
00211 
00212             
00213             
00214             
00215           }
00216           
00217           break;
00218         case 15: 
00219           { 
00220             unsigned oper = (MATCH_w_8_0 & 0xf) /* bot at 0 */;
00221             
00222 #line 95 "frontend/machine/st20/decoder.m"
00223             
00224 
00225                         total |= oper;
00226 
00227                         char* name = NULL;
00228 
00229                         bool isRet = false;
00230 
00231                         if (total >= 0) {
00232 
00233                             switch (total) {
00234 
00235                                 case 0x00:  name = "rev";   break;
00236 
00237                                 case 0x01: name = "lb";     break;
00238 
00239                                 case 0x02: name = "bsub";   break;
00240 
00241                                 case 0x03: name = "endp";   break;
00242 
00243                                 case 0x04: name = "diff";   break;
00244 
00245                                 case 0x05: name = "add";    break;
00246 
00247                                 case 0x06: name = "gcall";  break;
00248 
00249                                 case 0x07: name = "in";     break;
00250 
00251                                 case 0x08: name = "prod";   break;
00252 
00253                                 case 0x09: name = "gt";     break;
00254 
00255                                 case 0x0A: name = "wsub";   break;
00256 
00257                                 case 0x0B: name = "out";    break;
00258 
00259                                 case 0x0C: name = "sub";    break;
00260 
00261                                 case 0x0D: name = "startp"; break;
00262 
00263                                 case 0x0E: name = "outbyte";break;
00264 
00265                                 case 0x0F: name = "outword";break;
00266 
00267                                 case 0x10: name = "seterr"; break;
00268 
00269                                 case 0x12: name = "resetch";break;
00270 
00271                                 case 0x13: name = "csub0";  break;
00272 
00273                                 case 0x15: name = "stopp";  break;
00274 
00275                                 case 0x16: name = "ladd";   break;
00276 
00277                                 case 0x17: name = "stlb";   break;
00278 
00279                                 case 0x18: name = "sthf";   break;
00280 
00281                                 case 0x19: name = "norm";   break;
00282 
00283                                 case 0x1A: name = "ldiv";   break;
00284 
00285                                 case 0x1B: name = "ldpi";   break;
00286 
00287                                 case 0x1C: name = "stlf";   break;
00288 
00289                                 case 0x1D: name = "xdble";  break;
00290 
00291                                 case 0x1E: name = "ldpri";  break;
00292 
00293                                 case 0x1F: name = "rem";    break;
00294 
00295                                 case 0x20: name = "ret"; isRet = true; break;
00296 
00297                                 case 0x21: name = "lend";   break;
00298 
00299                                 case 0x22: name = "ldtimer";break;
00300 
00301                                 case 0x29: name = "testerr";break;
00302 
00303                                 case 0x2A: name = "testpranal";break;
00304 
00305                                 case 0x2B: name = "tin";    break;
00306 
00307                                 case 0x2C: name = "div";    break;
00308 
00309                                 case 0x2E: name = "dist";   break;
00310 
00311                                 case 0x2F: name = "disc";   break;
00312 
00313                                 case 0x30: name = "diss";   break;
00314 
00315                                 case 0x31: name = "lmul";   break;
00316 
00317                                 case 0x32: name = "not";    break;
00318 
00319                                 case 0x33: name = "xor";    break;
00320 
00321                                 case 0x34: name = "bcnt";   break;
00322 
00323                                 case 0x35: name = "lshr";   break;
00324 
00325                                 case 0x36: name = "lshl";   break;
00326 
00327                                 case 0x37: name = "lsum";   break;
00328 
00329                                 case 0x38: name = "lsub";   break;
00330 
00331                                 case 0x39: name = "runp";   break;
00332 
00333                                 case 0x3A: name = "xword";  break;
00334 
00335                                 case 0x3B: name = "sb";     break;
00336 
00337                                 case 0x3C: name = "gajw";   break;
00338 
00339                                 case 0x3D: name = "savel";  break;
00340 
00341                                 case 0x3E: name = "saveh";  break;
00342 
00343                                 case 0x3F: name = "wcnt";   break;
00344 
00345                                 case 0x40: name = "shr";    break;
00346 
00347                                 case 0x41: name = "shl";    break;
00348 
00349                                 case 0x42: name = "mint";   break;
00350 
00351                                 case 0x43: name = "alt";    break;
00352 
00353                                 case 0x44: name = "altwt";  break;
00354 
00355                                 case 0x45: name = "altend"; break;
00356 
00357                                 case 0x46: name = "and";    break;
00358 
00359                                 case 0x47: name = "enbt";   break;
00360 
00361                                 case 0x48: name = "enbc";   break;
00362 
00363                                 case 0x49: name = "enbs";   break;
00364 
00365                                 case 0x4A: name = "move";   break;
00366 
00367                                 case 0x4B: name = "or";     break;
00368 
00369                                 case 0x4C: name = "csngl";  break;
00370 
00371                                 case 0x4D: name = "ccnt1";  break;
00372 
00373                                 case 0x4E: name = "talt";   break;
00374 
00375                                 case 0x4F: name = "ldiff";  break;
00376 
00377                                 case 0x50: name = "sthb";   break;
00378 
00379                                 case 0x51: name = "taltwt"; break;
00380 
00381                                 case 0x52: name = "sum";    break;
00382 
00383                                 case 0x53: name = "mul";    break;
00384 
00385                                 case 0x54: name = "sttimer";break;
00386 
00387                                 case 0x55: name = "stoperr";break;
00388 
00389                                 case 0x56: name = "cword";  break;
00390 
00391                                 case 0x57: name = "clrhalterr"; break;
00392 
00393                                 case 0x58: name = "sethalterr"; break;
00394 
00395                                 case 0x59: name = "testhalterr";break;
00396 
00397                                 case 0x5A: name = "dup";        break;
00398 
00399                                 case 0x5B: name = "move2dinit"; break;
00400 
00401                                 case 0x5C: name = "move2dall";  break;
00402 
00403                                 case 0x5D: name = "move2dnonzero";break;
00404 
00405                                 case 0x5E: name = "move2dzero"; break;
00406 
00407                                 case 0x5F: name = "gtu";        break;
00408 
00409                                 case 0x63: name = "unpacksn";   break;
00410 
00411                                 case 0x64: name = "slmul";      break;
00412 
00413                                 case 0x65: name = "sulmul";     break;
00414 
00415                                 case 0x68: name = "satadd";     break;
00416 
00417                                 case 0x69: name = "satsub";     break;
00418 
00419                                 case 0x6A: name = "satmul";     break;
00420 
00421                                 case 0x6C: name = "postnormsn"; break;
00422 
00423                                 case 0x6D: name = "roundsn";    break;
00424 
00425                                 case 0x6E: name = "ldtraph";    break;
00426 
00427                                 case 0x6F: name = "sttraph";    break;
00428 
00429                                 case 0x71: name = "ldinf";      break;
00430 
00431                                 case 0x72: name = "fmul";       break;
00432 
00433                                 case 0x73: name = "cflerr";     break;
00434 
00435                                 case 0x74: name = "crcword";    break;
00436 
00437                                 case 0x75: name = "crcbyte";    break;
00438 
00439                                 case 0x76: name = "bitcnt";     break;
00440 
00441                                 case 0x77: name = "bitrevword"; break;
00442 
00443                                 case 0x78: name = "bitrevnbits";break;
00444 
00445                                 case 0x79: name = "pop";        break;
00446 
00447                                 case 0x7E: name = "ldmemstartval";break;
00448 
00449                                 case 0x81: name = "wsubdb";     break;
00450 
00451                                 case 0x9C: name = "fptesterr";  break;
00452 
00453                                 case 0xB0: name = "settimeslice";break;
00454 
00455                                 case 0xB8: name = "xbword";     break;
00456 
00457                                 case 0xB9: name = "lbx";        break;
00458 
00459                                 case 0xBA: name = "cb";         break;
00460 
00461                                 case 0xBB: name = "cbu";        break;
00462 
00463                                 case 0xC1: name = "ssub";       break;
00464 
00465                                 case 0xC4: name = "intdis";     break;
00466 
00467                                 case 0xC5: name = "intenb";     break;
00468 
00469                                 case 0xC6: name = "ldtrapped";  break;
00470 
00471                                 case 0xC7: name = "cir";        break;
00472 
00473                                 case 0xC8: name = "ss";         break;
00474 
00475                                 case 0xCA: name = "ls";         break;
00476 
00477                                 case 0xCB: name = "sttrapped";  break;
00478 
00479                                 case 0xCC: name = "ciru";       break;
00480 
00481                                 case 0xCD: name = "gintdis";    break;
00482 
00483                                 case 0xCE: name = "gintenb";    break;
00484 
00485                                 case 0xF0: name = "devlb";      break;
00486 
00487                                 case 0xF1: name = "devsb";      break;
00488 
00489                                 case 0xF2: name = "devls";      break;
00490 
00491                                 case 0xF3: name = "devss";      break;
00492 
00493                                 case 0xF4: name = "devlw";      break;
00494 
00495                                 case 0xF5: name = "devsw";      break;
00496 
00497                                 case 0xF6: name = "null";       break;
00498 
00499                                 case 0xF7: name = "null";       break;
00500 
00501                                 case 0xF8: name = "xsword";     break;
00502 
00503                                 case 0xF9: name = "lsx";        break;
00504 
00505                                 case 0xFA: name = "cs";         break;
00506 
00507                                 case 0xFB: name = "csu";        break;
00508 
00509                                 case 0x17C:name = "lddevid";    break;
00510 
00511                             }
00512 
00513                         } else {
00514 
00515                             // Total is negative, as a result of nfixes
00516 
00517                             total = (~total & ~0xF) | (total & 0xF);        // 1's complement the upper nibbles
00518 
00519                             switch (total) {
00520 
00521                                 case 0x00: name = "swapqueue";  break;
00522 
00523                                 case 0x01: name = "swaptimer";  break;
00524 
00525                                 case 0x02: name = "insertqueue";break;
00526 
00527                                 case 0x03: name = "timeslice";  break;
00528 
00529                                 case 0x04: name = "signal";     break;
00530 
00531                                 case 0x05: name = "wait";       break;
00532 
00533                                 case 0x06: name = "trapdis";    break;
00534 
00535                                 case 0x07: name = "trapenb";    break;
00536 
00537                                 case 0x0B: name = "tret"; isRet = true; break;
00538 
00539                                 case 0x0C: name = "ldshadow";   break;
00540 
00541                                 case 0x0D: name = "stshadow";   break;
00542 
00543                                 case 0x1F: name = "iret"; isRet = true; break;
00544 
00545                                 case 0x24: name = "devmove";    break;
00546 
00547                                 case 0x2E: name = "restart";    break;
00548 
00549                                 case 0x2F: name = "causeerror"; break;
00550 
00551                                 case 0x30: name = "nop";        break;
00552 
00553                                 case 0x4C: name = "stclock";    break;
00554 
00555                                 case 0x4D: name = "ldclock";    break;
00556 
00557                                 case 0x4E: name = "clockdis";   break;
00558 
00559                                 case 0x4F: name = "clockenb";   break;
00560 
00561                                 case 0x8C: name = "ldprodid";   break;
00562 
00563                                 case 0x8D: name = "reboot";     break;
00564 
00565                             }
00566 
00567                         }
00568 
00569                         if (name) {
00570 
00571                             stmts = instantiate(pc, name);
00572 
00573                             if (isRet) {
00574 
00575                                 result.rtl = new RTL(pc, stmts);
00576 
00577                                 result.rtl->appendStmt(new ReturnStatement);
00578 
00579                             }
00580 
00581                         } else {
00582 
00583                             result.valid = false;       // Invalid instruction
00584 
00585                             result.rtl = NULL;
00586 
00587                             result.numBytes = 0;
00588 
00589                             return result;
00590 
00591                         }
00592 
00593             
00594 
00595             
00596 
00597             
00598             
00599             
00600           }
00601           
00602           break;
00603         default: assert(0);
00604       } /* (MATCH_w_8_0 >> 4 & 0xf) -- fc at 0 --*/ 
00605     
00606   }goto MATCH_finished_a; 
00607   
00608   MATCH_finished_a: (void)0; /*placeholder for label*/
00609   
00610 }
00611 
00612 #line 283 "frontend/machine/st20/decoder.m"
00613         break;
00614     }
00615 
00616     if (result.rtl == 0)
00617         result.rtl = new RTL(pc, stmts);
00618     return result;
00619 }
00620 
00621 /*==============================================================================
00622  * These are machine specific functions used to decode instruction operands into Exp*s.
00623  *============================================================================*/
00624 
00625 /**********************************
00626  * These are the fetch routines.
00627  **********************************/   
00628 
00629 /*==============================================================================
00630  * FUNCTION:        getWord
00631  * OVERVIEW:        Returns the word starting at the given address.
00632  * PARAMETERS:      lc - address at which to decode the double
00633  * RETURNS:         the decoded double
00634  *============================================================================*/
00635 Byte ST20Decoder::getByte (unsigned lc)
00636 /* getByte - returns next byte from image pointed to by lc.  */
00637 {
00638     return *(Byte *)lc;
00639 }
00640 
00641 /*==============================================================================
00642  * FUNCTION:        getWord
00643  * OVERVIEW:        Returns the word starting at the given address.
00644  * PARAMETERS:      lc - address at which to decode the double
00645  * RETURNS:         the decoded double
00646  *============================================================================*/
00647 SWord ST20Decoder::getWord (unsigned lc)
00648 /* get2Bytes - returns next 2-Byte from image pointed to by lc.  */
00649 {
00650     return (SWord)(*(Byte *)lc + (*(Byte *)(lc+1) << 8));
00651 }
00652 
00653 /*==============================================================================
00654  * FUNCTION:        getDword
00655  * OVERVIEW:        Returns the double starting at the given address.
00656  * PARAMETERS:      lc - address at which to decode the double
00657  * RETURNS:         the decoded double
00658  *============================================================================*/
00659 DWord ST20Decoder::getDword (unsigned lc)
00660 /* get4Bytes - returns the next 4-Byte word from image pointed to by lc. */
00661 {
00662     return (DWord)(*(Byte *)lc + (*(Byte *)(lc+1) << 8) +
00663         (*(Byte *)(lc+2) << 16) + (*(Byte *)(lc+3) << 24));
00664 }
00665 
00666 
00667 /*==============================================================================
00668  * FUNCTION:       ST20Decoder::ST20Decoder
00669  * OVERVIEW:       Constructor. The code won't work without this (not sure why the default constructor won't do...)
00670  * PARAMETERS:     None
00671  * RETURNS:        N/A
00672  *============================================================================*/
00673 ST20Decoder::ST20Decoder() : NJMCDecoder(prog)
00674 {
00675     std::string file = Boomerang::get()->getProgPath() + "frontend/machine/st20/st20.ssl";
00676     RTLDict.readSSLFile(file.c_str());
00677 }
00678 
00679 // For now...
00680 int ST20Decoder::decodeAssemblyInstruction(unsigned, int)
00681 { return 0; }
00682 
00683 
00684 

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