fronthppa.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2001, The University of Queensland
00003  * Copyright (C) 2001, Sun Microsystems, Inc
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:       fronthppa.cc
00013  * OVERVIEW:   This file contains routines to manage the decoding of HP pc-risc
00014  *             instructions and the instantiation to RTLs. These functions
00015  *             replace Frontend.cc for decoding hppa instructions.
00016  *============================================================================*/
00017 
00018 /*
00019  * $Revision: 1.4 $
00020  *
00021  * 14 May 01 - Mike: Created from frontsparc.cc
00022  * 17 May 01 - Mike: Modified SCD logic to take account of register interference
00023  * 24 Jul 01 - Mike: Added helperFunc a la Sparc
00024  * 24 Jul 01 - Mike: Millicode return value register is %r29
00025  * 25 Jul 01 - Mike: helperFunc copes with no symbols
00026  * 27 Jul 01 - Mike: Added $$dyncall helper func
00027  * 31 Jul 01 - Brian: New class HRTL replaces RTlist. Renamed LRTL to HRTLList.
00028  * 07 Aug 01 - Mike: Implement DU (Dynamic, not anulled) instruction type
00029  * 20 Aug 01 - Mike: Handle SU as call/return (if applicable)
00030  */
00031 
00032 /*==============================================================================
00033  * Dependencies.
00034  *============================================================================*/
00035 
00036 #include "global.h"
00037 #include "ss.h"
00038 #include "rtl.h"
00039 #include "cfg.h"
00040 #include "proc.h"
00041 #include "prog.h"
00042 #include "options.h"
00043 #include "csr.h"
00044 #include "frontend.h"
00045 #include "decoder.h"
00046 #include "BinaryFile.h"
00047 
00048 /*==============================================================================
00049  * Globals and enumerated types used for decoding.
00050  *============================================================================*/
00051 
00052 // These are indexes to the most common control/status registers.
00053 int idNPC = -1;
00054 int idCWP = -1;
00055 int idTmp = -1;
00056 
00057 // This struct represents a single nop instruction. Used as a substitute
00058 // delay slot instruction
00059 static DecodeResult nop_inst;
00060 
00061 
00062 /*==============================================================================
00063  * Forward declarations.
00064  *============================================================================*/
00065 void emitNop(HRTLList* pRtls, ADDRESS uAddr);
00066 void emitCopyPC(HRTLList* pRtls, ADDRESS uAddr);
00067 void initCti();             // Imp in ctisparc.cc
00068 void setReturnLocations(CalleeEpilogue* epilogue, int iReg);
00069 bool helperFunc(ADDRESS dest, ADDRESS addr, HRTLList* lrtl);
00070 
00071 /*==============================================================================
00072  * FUNCTION:        initFront
00073  * OVERVIEW:        Initialise any globals used by the front end.
00074  * PARAMETERS:      <none>
00075  * RETURNS:         <nothing>
00076  *============================================================================*/
00077 // Initialise the front end
00078 void initFront()
00079 {
00080     // We need the 2nd parameter to findItem because we may or may not have
00081     // parsed any instructions that involve %npc etc (depending on whether
00082     // we want the low level RTLs or not). This prevents needless error messages
00083     idNPC = theSemTable.findItem("%npc", false);
00084     idTmp = theSemTable.findItem("tmp", false);
00085 
00086     // This struct represents a single nop instruction. Used as a substitute
00087     // delay slot instruction
00088     nop_inst.numBytes = 0;          // So won't disturb coverage
00089     nop_inst.type = NOP;
00090     nop_inst.valid = true;
00091     nop_inst.rtl = new RTL();
00092 }
00093 
00094 /*==============================================================================
00095  * FUNCTION:         warnDCTcouple
00096  * OVERVIEW:         Emit a warning when encountering a DCTI couple.
00097  * PARAMETERS:       uAt - the address of the couple
00098  *                   uDest - the address of the first DCTI in the couple
00099  * RETURNS:          <nothing>
00100  *============================================================================*/
00101 void warnDCTcouple(ADDRESS uAt, ADDRESS uDest)
00102 {
00103     ostrstream ost;
00104     ost << "DCTI couple at " << hex;
00105     ost << uAt << " points to delayed branch at " << uDest << "...\n";
00106     ost << "Translation will likely be incorrect";
00107     error(str(ost));
00108 }
00109 
00110 /*==============================================================================
00111  * FUNCTION:         interferes
00112  * OVERVIEW:         Return true if the delay slot instruction interferes with
00113  *                      a register used by the main instruction
00114  * PARAMETERS:       delayRtl: pointer to the HRTL for the delay slot instr
00115  *                   mainRtl: pointer to the HRTL for the main instruction
00116  * RETURNS:          true if interference detected
00117  *============================================================================*/
00118 bool interferes(HRTL* delayRtl, HRTL* mainRtl)
00119 {
00120     if (delayRtl == NULL) return false;
00121     int n = delayRtl->getNumRT();
00122     int m = mainRtl->getNumRT();
00123     for (int i=0; i < n; i++) {
00124         RTAssgn* rta = (RTAssgn*)delayRtl->elementAt(i);
00125         if (rta->getKind() != RTASSGN) continue;
00126         SemStr* lhs = rta->getLHS();
00127         // Assume that only registers will interfere
00128         if (lhs->getFirstIdx() != idRegOf) continue;
00129         if (lhs->getSecondIdx() != idIntConst) continue;
00130         for (int j=0; j < m; j++) {
00131             rta = (RTAssgn*)delayRtl->elementAt(j);
00132             if (rta->getKind() != RTASSGN) continue;
00133             SemStr* rhs = rta->getRHS();
00134             SemStr result;
00135             if (rhs->search(*lhs, result))
00136                 return true;
00137         }
00138     }
00139     return false;
00140 }
00141 
00142 /*==============================================================================
00143  * FUNCTION:        optimise_DelayCopy
00144  * OVERVIEW:        Determines if a delay instruction is exactly the same as the
00145  *                  instruction immediately preceding the destination of a CTI;
00146  *                  i.e. has been copied from the real destination to the delay
00147  *                  slot as an optimisation
00148  * PARAMETERS:      src - the logical source address of a CTI
00149  *                  dest - the logical destination address of the CTI
00150  *                  delta - used to convert logical to real addresses
00151  *                  uUpper - first address past the end of the main text
00152  *                    section
00153  * SIDE EFFECT:     Optionally displays an error message if the target of the
00154  *                    branch is the delay slot of another delayed CTI
00155  * RETURNS:         can optimise away the delay instruction
00156  *============================================================================*/
00157 bool optimise_DelayCopy(ADDRESS src, ADDRESS dest, int delta, ADDRESS uUpper)
00158 {
00159     // Check that the destination is within the main test section; may not be
00160     // when we speculatively decode junk
00161     if ((dest - 4) > uUpper)
00162         return false;
00163     unsigned delay_inst = *((unsigned*)(src+4+delta));
00164     unsigned inst_before_dest = *((unsigned*)(dest-4+delta));
00165     return (delay_inst == inst_before_dest);
00166 }
00167 
00168 /*==============================================================================
00169  * FUNCTION:        handleBranch
00170  * OVERVIEW:        Adds the destination of a branch to the queue of address
00171  *                  that must be decoded (if this destination has not already
00172  *                  been visited). 
00173  * PARAMETERS:      newBB - the new basic block delimited by the branch
00174  *                    instruction. May be NULL if this block has been built
00175  *                    before.
00176  *                  dest - the destination being branched to
00177  *                  hiAddress - the last address in the current procedure
00178  *                  cfg - the CFG of the current procedure
00179  *                  targets: queue of targets still to be processed
00180  * RETURNS:         <nothing>, but newBB may be changed if the destination of
00181  *                  the branch is in the middle of an existing BB. It will then
00182  *                  be changed to point to a new BB beginning with the dest
00183  *============================================================================*/
00184 void handleBranch(ADDRESS dest, ADDRESS hiAddress, BasicBlock*& newBB, Cfg* cfg,
00185     TARGETS& targets)
00186 {
00187     if (newBB == NULL)
00188         return;
00189 
00190     if (dest < hiAddress) {
00191         visit(cfg, dest, targets, newBB);
00192         cfg->addOutEdge(newBB, dest, true);
00193     }
00194     else {
00195         ostrstream ost;
00196         ost << "branch to " << hex << dest << " goes beyond section.";
00197         error(str(ost));
00198     }   
00199 }
00200 
00201 /*==============================================================================
00202  * FUNCTION:          handleCall
00203  * OVERVIEW:          Records the fact that there is a procedure at a given
00204  *                    address. Also adds the out edge to the
00205  *                    lexical successor of the call site (taking into
00206  *                    consideration the delay slot and possible UNIMP
00207  *                    instruction).
00208  * PARAMETERS:        dest - the address of the callee
00209  *                    callBB - the basic block delimited by the call
00210  *                    cfg - CFG of the enclosing procedure
00211  *                    address - the address of the call instruction
00212  *                    offset - the offset from the call instruction to which an
00213  *                      outedge must be added. A value of 0 means no edge is to
00214  *                      be added.
00215  * RETURNS:           <nothing>
00216  *============================================================================*/
00217 void handleCall(ADDRESS dest, BasicBlock* callBB, Cfg* cfg, ADDRESS address,
00218     int offset = 0)
00219 {
00220     if (callBB == NULL)
00221         return;
00222 
00223     // If the destination address is the same as this very instruction,
00224     // we have a call with offset == 0. Don't treat this as the start
00225     // of a real procedure.
00226     if ((dest != address) && prog.findProc(dest) == 0)
00227     {
00228         // We don't want to call prog.visitProc just yet, in case this is
00229         // a speculative decode that failed. Instead, we use the set of
00230         // HLCalls (not in this procedure) that is needed by CSR
00231         if (progOptions.trace)
00232             cout << "p" << hex << dest << "\t";
00233     }
00234 
00235     // Add the out edge if required
00236     if (offset != 0)
00237         cfg->addOutEdge(callBB, address+offset);
00238 
00239 }
00240 
00241 /*==============================================================================
00242  * FUNCTION:         case_unhandled_stub
00243  * OVERVIEW:         This is the stub for cases of DCTI couples that we haven't
00244  *                   written analysis code for yet. It simply displays an
00245  *                   informative warning and returns.
00246  * PARAMETERS:       addr - the address of the first CTI in the couple
00247  * RETURNS:          <nothing>
00248  *============================================================================*/
00249 void case_unhandled_stub(ADDRESS addr)
00250 {
00251     ostrstream ost;
00252     ost << "DCTI couple at " << hex << addr << endl;
00253     error(str(ost));
00254 }
00255 
00256 /*==============================================================================
00257  * FUNCTION:         case_CALL_NCT
00258  * OVERVIEW:         Handles a call instruction followed by an NCT or NOP
00259  *                   instruction.
00260  * PARAMETERS:       address - the native address of the call instruction
00261  *                   inst - the info summaries when decoding the call
00262  *                     instruction
00263  *                   delay_inst - the info summaries when decoding the delay
00264  *                     instruction
00265  *                   BB_rtls - the list of RTLs currently built for the BB under
00266  *                     construction
00267  *                   proc - the enclosing procedure
00268  *                   callSet - a set of pointers to HLCalls for procs yet to
00269  *                     be processed
00270  *                   isPattern - true if the call is an idiomatic pattern (e.g.
00271  *                      a move_call_move pattern)
00272  *                   os - output stream for rtls
00273  * SIDE EFFECTS:     address may change; BB_rtls may be appended to or set NULL
00274  * RETURNS:          true if next instruction is to be fetched sequentially from
00275  *                      this one
00276  *============================================================================*/
00277 bool case_CALL_NCT(ADDRESS& address, DecodeResult& inst,
00278     DecodeResult& delay_inst, list<HRTL*>*& BB_rtls, 
00279     UserProc* proc, std::list<CallStatement*>& callList, ofstream &os, bool isPattern = false )
00280 {
00281     // Aliases for the call and delay RTLs
00282     HLCall* call_rtl = static_cast<HLCall*>(inst.rtl);
00283     HRTL* delay_rtl = delay_inst.rtl;
00284 
00285     Cfg* cfg = proc->getCFG();
00286 
00287     // Assume that if we find a call in the delay slot, it's actually a pattern
00288     // such as move/call/move
00289     bool delayPattern = delay_rtl->getKind() == CALL_HRTL;
00290 
00291     // Emit the delay instruction, unless a the delay instruction is a nop,
00292     // or we have a pattern, or are followed by a restore
00293     if ((delay_inst.type != NOP) && !delayPattern &&
00294       !call_rtl->isReturnAfterCall()) {
00295         delay_rtl->updateAddress(address);
00296         BB_rtls->push_back(delay_rtl);
00297         if (progOptions.rtl)
00298             delay_rtl->print(os);
00299     }
00300 
00301     {
00302 
00303 
00304         ADDRESS dest = call_rtl->getFixedDest();
00305         // First check for helper functions
00306         if (helperFunc(dest, address, BB_rtls)) {
00307             address += 8;           // Skip call, delay slot
00308             return true;
00309         }
00310 
00311         // Emit the call
00312         BB_rtls->push_back(call_rtl);
00313 
00314         // End the current basic block
00315         BasicBlock* callBB = cfg->newBB(BB_rtls, CALL, 1);
00316         if (callBB == NULL)
00317             return false;
00318 
00319         // Add this call site to the set of call sites which
00320         // need to be analysed later.
00321         // This set will be used later to call prog.visitProc (so the proc
00322         // will get decoded)
00323         callList.push_back((HLCall*)inst.rtl);
00324 
00325         if (call_rtl->isReturnAfterCall()) {
00326             // Handle the call but don't add any outedges from it just yet.
00327             handleCall(call_rtl->getFixedDest(), callBB, cfg, address);
00328 
00329             // Constuct the RTLs for the new basic block
00330             list<HRTL*>* rtls = new list<HRTL*>();
00331 
00332             // The only RTL in the basic block is a high level return that
00333             // doesn't have any RTs.
00334             rtls->push_back(new HLReturn(0, NULL));
00335             BasicBlock* returnBB = cfg->newBB(rtls, RET, 0);
00336 
00337             // Now add the out edge
00338             cfg->addOutEdge(callBB, returnBB);
00339             // Put a label on the return BB; indicate that a jump is reqd
00340             cfg->setLabel(returnBB);
00341             callBB->setJumpReqd();
00342 
00343             // Note that we get here for certain types of patterns as well as
00344             // for call/return pairs. This could all go away if we could
00345             // specify that some sparc Logues are caller-prologue and also
00346             // callee-epilogues!
00347             // This is a hack until we figure out how to match these
00348             // patterns using a .pat file. We have to set the epilogue
00349             // for the enclosing procedure (all proc's must have an
00350             // epilogue).
00351             proc->setEpilogue(new CalleeEpilogue("__dummy",list<string>()));
00352             // Set the return location; this is now always %r28
00353             setReturnLocations(proc->getEpilogue(), 28);
00354 
00355             address += inst.numBytes;       // For coverage
00356             // This is a CTI block that doesn't fall through and so must
00357             // stop sequentially decoding
00358             return false;
00359         }
00360         else
00361         {
00362             // Else no restore after this call.
00363             // An outedge may be added to the lexical
00364             // successor of the call which will be 8 bytes
00365             // ahead or in the case where the callee returns
00366             // a struct, 12 bytes head
00367             // If forceOutEdge is set, set offset to 0 and no out-edge will be
00368             // added yet
00369             int offset = inst.forceOutEdge ? 0 : 8;
00370 
00371             bool ret = true;
00372             // Check for _exit; probably should check for other "never return"
00373             // functions
00374             const char* name = prog.pBF->SymbolByAddress(dest);
00375             if (name && strcmp(name, "_exit") == 0) {
00376                 // Don't keep decoding after this call
00377                 ret = false;
00378                 // Also don't add an out-edge; setting offset to 0 will do this
00379                 offset = 0;
00380                 // But we have already set the number of out-edges to 1
00381                 callBB->updateType(CALL, 0);
00382             }
00383 
00384             // Handle the call (register the destination as a proc)
00385             // and possibly set the outedge.
00386             handleCall(dest, callBB, cfg, address, offset);
00387 
00388             if (inst.forceOutEdge) {
00389                 // There is no need to force a goto to the new out-edge, since
00390                 // we will continue decoding from there. If other edges exist
00391                 // to the outedge, they will generate the required label
00392                 cfg->addOutEdge(callBB, inst.forceOutEdge);
00393                 address = inst.forceOutEdge;
00394             }
00395             else {
00396                 // Continue decoding from the lexical successor
00397                 address += offset;
00398             }
00399             BB_rtls = NULL;
00400 
00401             return ret;
00402         }
00403     }
00404 }
00405 
00406 /*==============================================================================
00407  * FUNCTION:         case_SD_NCT
00408  * OVERVIEW:         Handles a non-call, static delayed (SD) instruction
00409  *                   followed by an NCT or NOP instruction.
00410  * PARAMETERS:       address - the native address of the SD
00411  *                   delta - the offset of the above address from the logical
00412  *                     address at which the procedure starts (i.e. the one
00413  *                     given by dis)
00414  *                   inst - the info summaries when decoding the SD
00415  *                     instruction
00416  *                   delay_inst - the info summaries when decoding the delay
00417  *                     instruction
00418  *                   BB_rtls - the list of RTLs currently built for the BB under
00419  *                     construction
00420  *                   cfg - the CFG of the enclosing procedure
00421  *                   targets: queue of targets still to be processed
00422  *                   os - output stream for rtls
00423  * SIDE EFFECTS:     address may change; BB_rtls may be appended to or set NULL
00424  * RETURNS:          <nothing>
00425  *============================================================================*/
00426 void case_SD_NCT(ADDRESS& address, int delta, ADDRESS hiAddress,
00427     DecodeResult& inst, DecodeResult& delay_inst, list<HRTL*>*& BB_rtls,
00428     Cfg* cfg, TARGETS& targets, ofstream &os)
00429 {
00430 
00431     // Aliases for the SD and delay RTLs
00432     HLJump* SD_rtl = static_cast<HLJump*>(inst.rtl);
00433     HRTL* delay_rtl = delay_inst.rtl;
00434 
00435     // Try the "delay instruction has been copied" optimisation, emitting the
00436     // delay instruction now if the optimisation won't apply
00437     if (delay_inst.type != NOP) {
00438         if (optimise_DelayCopy(address, SD_rtl->getFixedDest(), delta,
00439           hiAddress))
00440             SD_rtl->adjustFixedDest(-4);
00441         else {
00442             // Move the delay instruction before the SD. Must update the address
00443             // in case there is a branch to the SD
00444             delay_rtl->updateAddress(address);
00445             BB_rtls->push_back(delay_rtl);
00446             // Display RTL representation if asked
00447             if (progOptions.rtl)
00448                 delay_rtl->print(os);
00449         }
00450     }
00451 
00452     // Update the address (for coverage)
00453     address += 8;
00454 
00455     // Add the SD
00456     BB_rtls->push_back(SD_rtl);
00457 
00458     // Add the one-way branch BB
00459     PBB pBB = cfg->newBB(BB_rtls, ONEWAY, 1);
00460     if (pBB == 0) { BB_rtls = NULL; return; }
00461 
00462     // Visit the destination, and add the out-edge
00463     ADDRESS uDest = SD_rtl->getFixedDest();
00464     handleBranch(uDest, hiAddress, pBB, cfg, targets);
00465     BB_rtls = NULL;
00466 }
00467 
00468 
00469 /*==============================================================================
00470  * FUNCTION:         case_DD_NCT
00471  * OVERVIEW:         Handles all dynamic delayed jumps (jmpl, also dynamic
00472  *                    calls) followed by an NCT or NOP instruction.
00473  * NOTE:             Also handles DU, if delay_inst is assigned nop_inst
00474  * PARAMETERS:       address - the native address of the DD
00475  *                   delta - the offset of the above address from the logical
00476  *                     address at which the procedure starts (i.e. the one
00477  *                     given by dis)
00478  *                   inst - the info summaries when decoding the SD
00479  *                     instruction
00480  *                   delay_inst - the info summaries when decoding the delay
00481  *                     instruction
00482  *                   BB_rtls - the list of RTLs currently built for the BB under
00483  *                     construction
00484  *                   cfg - the CFG of the enclosing procedure
00485  *                   targets: queue of targets still to be processed
00486  *                   proc: pointer to the current Proc object
00487  *                   callSet - a set of pointers to HLCalls for procs yet to
00488  *                     be processed
00489  *                   size: size of this instruction (8 if delay slot)
00490  * SIDE EFFECTS:     address may change; BB_rtls may be appended to or set NULL
00491  * RETURNS:          true if next instruction is to be fetched sequentially from
00492  *                      this one
00493  *============================================================================*/
00494 bool case_DD_NCT(ADDRESS& address, int delta, DecodeResult& inst,
00495     DecodeResult& delay_inst, list<HRTL*>*& BB_rtls, Cfg* cfg,
00496     TARGETS& targets, UserProc* proc, std::list<CallStatement*>& callList, int size)
00497 {
00498     // Assume that if we find a call in the delay slot, it's actually a pattern
00499     // such as move/call/move
00500     bool delayPattern = delay_inst.rtl->getKind() == CALL_HRTL;
00501 
00502     if ((delay_inst.type != NOP) && !delayPattern) {
00503         // Emit the delayed instruction, unless a pattern
00504         delay_inst.rtl->updateAddress(address);
00505         BB_rtls->push_back(delay_inst.rtl);
00506     }
00507 
00508     // Set address past this instruction and delay slot (if any).
00509     // This is so that we cover the jmp/call and delay slot instruction, in
00510     // case we return false
00511     address += size;
00512 
00513     // Emit the DD and end the current BB
00514     BB_rtls->push_back(inst.rtl);
00515     BasicBlock* newBB;
00516     bool bRet = true;
00517     switch (inst.rtl->getKind()) {
00518         case CALL_HRTL:
00519             // Will be a computed call
00520             newBB = cfg->newBB(BB_rtls, COMPCALL, 1);
00521             break;
00522         case RET_HRTL:
00523             newBB = cfg->newBB(BB_rtls, RET, 0);
00524             bRet = false;
00525             break;
00526         case NWAYJUMP_HRTL:
00527             newBB = cfg->newBB(BB_rtls, COMPJUMP, 0);
00528             bRet = false;
00529             break;
00530         default:
00531             break;
00532     }
00533     if (newBB == NULL) return false;
00534 
00535     // Do extra processing for for special types of DD
00536     if (inst.rtl->getKind() == CALL_HRTL) {
00537 
00538         // Attempt to add a return BB if the delay
00539         // instruction is a RESTORE
00540         HLCall*   rtl_call   = static_cast<HLCall*>(inst.rtl);
00541 #if 0           // Sparc specific code, but we may need something similar
00542         BasicBlock* returnBB = optimise_CallReturn(rtl_call,
00543             delay_inst.rtl, cfg);
00544         if (returnBB != NULL) {
00545             cfg->addOutEdge(newBB,returnBB);
00546 
00547             // We have to set the epilogue
00548             // for the enclosing procedure (all proc's must have an
00549             // epilogue) and remove the RESTORE in the delay slot that
00550             // has just been pushed to the list of RTLs
00551             proc->setEpilogue(new CalleeEpilogue("__dummy",list<string>()));
00552             // Set the return location; this is now always %r28
00553             setReturnLocations(proc->getEpilogue(), 28);
00554             newBB->getHRTLs()->remove(delay_inst.rtl);
00555 
00556             // Put a label on the return BB; indicate that a jump is reqd
00557             cfg->setLabel(returnBB);
00558             newBB->setJumpReqd();
00559 
00560             // Add this call to the list of calls to analyse. We won't be able
00561             // to analyse it's callee(s), of course.
00562             callList.push_back(rtl_call);
00563 
00564             return false;
00565         }
00566         else {
00567 #else
00568         {
00569 #endif
00570             // Instead, add the standard out edge to original address+8 (now
00571             // just address)
00572             cfg->addOutEdge(newBB, address);
00573         }
00574         // Add this call to the list of calls to analyse. We won't be able
00575         // to analyse its callee(s), of course.
00576         callList.push_back(rtl_call);
00577     }
00578     else if(inst.rtl->getKind() == NWAYJUMP_HRTL) {
00579 
00580         // Attempt to process this jmpl as a switch statement.
00581         // NOTE: the isSwitch and processSwitch methods should
00582         // really be merged into one
00583         HLNwayJump*   rtl_jump   = static_cast<HLNwayJump*>(inst.rtl);
00584         if (isSwitch(newBB, rtl_jump->getDest(), proc, pBF))
00585             processSwitch(newBB, delta, cfg, targets, pBF);
00586         else {
00587             ostrstream os;
00588             os << "COMPUTED JUMP at " << hex << address-8;
00589             warning(str(os));
00590         }
00591     }
00592 
00593     // Set the address of the lexical successor of the call
00594     // that is to be decoded next and create a new list of
00595     // RTLs for the next basic block.
00596     // Except if we had a pattern in the delay slot; then don't skip
00597     // Remember that we have already bumped address by 8
00598     if (delayPattern) address -= 4;
00599     BB_rtls = NULL;
00600     return bRet;
00601 }
00602 
00603 /*==============================================================================
00604  * FUNCTION:         case_SCD_NCT
00605  * OVERVIEW:         Handles all static conditional delayed non-anulled branches
00606  *                     followed by an NCT or NOP instruction.
00607  * PARAMETERS:       address - the native address of the DD
00608  *                   delta - the offset of the above address from the logical
00609  *                     address at which the procedure starts (i.e. the one
00610  *                     given by dis)
00611                      hiAddress - first address outside this code section
00612  *                   inst - the info summaries when decoding the SD
00613  *                     instruction
00614  *                   delay_inst - the info summaries when decoding the delay
00615  *                     instruction
00616  *                   BB_rtls - the list of RTLs currently built for the BB under
00617  *                     construction
00618  *                   cfg - the CFG of the enclosing procedure
00619  *                   targets: queue of targets still to be processed
00620  * SIDE EFFECTS:     address may change; BB_rtls may be appended to or set NULL
00621  * RETURNS:          true if next instruction is to be fetched sequentially from
00622  *                      this one
00623  *============================================================================*/
00624 bool case_SCD_NCT(ADDRESS& address, int delta, ADDRESS hiAddress,
00625     DecodeResult& inst, DecodeResult& delay_inst, list<HRTL*>*& BB_rtls,
00626     Cfg* cfg, TARGETS& targets)
00627 {
00628     HLJump*   rtl_jump   = static_cast<HLJump*>(inst.rtl);
00629     ADDRESS uDest = rtl_jump->getFixedDest();
00630     
00631 #if 0
00632     // Assume that if we find a call in the delay slot, it's actually a pattern
00633     // such as move/call/move
00634     bool delayPattern = delay_inst.rtl->getKind() == CALL_HRTL;
00635 
00636     if (delayPattern) {
00637         // Just emit the branch, and decode the instruction immediately
00638         // following next. Assumes the first instruction of the pattern is
00639         // not used in the true leg
00640         BB_rtls->push_back(inst.rtl);
00641         PBB pBB = cfg->newBB(BB_rtls, TWOWAY, 2);
00642         if (pBB == 0)  return false;
00643         handleBranch(uDest, hiAddress, pBB, cfg, targets);
00644         // Add the "false" leg
00645         cfg->addOutEdge(pBB, address+4);
00646         address += 4;           // Skip the SCD only
00647         // Start a new list of RTLs for the next BB
00648         BB_rtls = NULL;
00649         ostrstream ost;
00650         ost << "instruction at " << hex << address;
00651         ost << " not copied to true leg of preceeding branch";
00652         warning(str(ost));
00653         return true;
00654     }
00655 #endif
00656 
00657     if (!interferes(delay_inst.rtl, inst.rtl)) {
00658         // SCD; no interference. Put delay inst first
00659         if (delay_inst.type != NOP) {
00660             // Emit delay instr
00661             BB_rtls->push_back(delay_inst.rtl);
00662             // This is in case we have an in-edge to the branch. If the BB
00663             // is split, we want the split to happen here, so this delay
00664             // instruction is active on this path
00665             delay_inst.rtl->updateAddress(address);
00666         }
00667         // Now emit the branch
00668         BB_rtls->push_back(inst.rtl);
00669         PBB pBB = cfg->newBB(BB_rtls, TWOWAY, 2);
00670         if (pBB == 0)  return false;
00671         handleBranch(uDest, hiAddress, pBB, cfg, targets);
00672         // Add the "false" leg; skips the NCT
00673         cfg->addOutEdge(pBB, address+8);
00674         // Skip the NCT/NOP instruction
00675         address += 8;
00676     }
00677     else if (optimise_DelayCopy(address, uDest, delta, hiAddress)) {
00678         // We can just branch to the instr before uDest.
00679         // Adjust the destination of the branch
00680         rtl_jump->adjustFixedDest(-4);
00681         // Now emit the branch
00682         BB_rtls->push_back(inst.rtl);
00683         PBB pBB = cfg->newBB(BB_rtls, TWOWAY, 2);
00684         if (pBB == 0) return false;
00685         handleBranch(uDest-4, hiAddress, pBB, cfg, targets);
00686         // Add the "false" leg: point to the delay inst
00687         cfg->addOutEdge(pBB, address+4);
00688         address += 4;           // Skip branch but not delay
00689     }
00690     else // There is interference, and we can't use the copy delay slot trick
00691     {
00692         // SCD, must copy delay instr to orphan
00693         // Copy the delay instruction to the dest of the branch, as an orphan
00694         // First add the branch.
00695         BB_rtls->push_back(inst.rtl);
00696         // Make a BB for the current list of RTLs
00697         // We want to do this first, else ordering can go silly
00698         PBB pBB = cfg->newBB(BB_rtls, TWOWAY, 2);
00699         if (pBB == 0) return false;
00700         // Visit the target of the branch
00701         visit(cfg, uDest, targets, pBB);
00702         HRTLList* pOrphan = new HRTLList;
00703         pOrphan->push_back(delay_inst.rtl);
00704         // Change the address to 0, since this code has no source address
00705         // (else we may branch to here when we want to branch to the real
00706         // BB with this instruction).
00707         // Note that you can't use an address that is a fixed function of the
00708         // destination addr, because there can be several jumps to the same
00709         // destination that all require an orphan. The instruction in the
00710         // orphan will often but not necessarily be the same, so we can't use
00711         // the same orphan BB. newBB knows to consider BBs with address 0 as
00712         // being in the map, so several BBs can exist with address 0
00713         delay_inst.rtl->updateAddress(0);
00714         // Add a branch from the orphan instruction to the dest of the branch
00715         // Again, we can't even give the jumps a special address like 1, since
00716         // then the BB would have this getLowAddr.
00717         pOrphan->push_back(new HLJump(0, uDest));
00718         PBB pOrBB = cfg->newBB(pOrphan, ONEWAY, 1);
00719         // Add an out edge from the orphan as well
00720         cfg->addOutEdge(pOrBB, uDest, true);
00721         // Add an out edge from the current RTL to
00722         // the orphan. Put a label at the orphan
00723         cfg->addOutEdge(pBB, pOrBB, true);
00724         // Add the "false" leg to the NCT
00725         cfg->addOutEdge(pBB, address+4);
00726         // Don't skip the delay instruction, so it will
00727         // be decoded next.
00728         address += 4;
00729     }
00730 
00731     // Start a new list of RTLs for the next BB
00732     BB_rtls = NULL;
00733     return true;
00734 }
00735 
00736 /*==============================================================================
00737  * FUNCTION:         case_SCDAN_NCT
00738  * OVERVIEW:         Handles all static conditional delayed anulled branches
00739  *                     followed by an NCT (but not NOP) instruction.
00740  * PARAMETERS:       address - the native address of the DD
00741  *                   delta - the offset of the above address from the logical
00742  *                     address at which the procedure starts (i.e. the one
00743  *                     given by dis)
00744                      hiAddress - first address outside this code section
00745  *                   inst - the info summaries when decoding the SD
00746  *                     instruction
00747  *                   delay_inst - the info summaries when decoding the delay
00748  *                     instruction
00749  *                   BB_rtls - the list of RTLs currently built for the BB under
00750  *                     construction
00751  *                   cfg - the CFG of the enclosing procedure
00752  *                   targets: queue of targets still to be processed
00753  * SIDE EFFECTS:     address may change; BB_rtls may be appended to or set NULL
00754  * RETURNS:          true if next instruction is to be fetched sequentially from
00755  *                      this one
00756  *============================================================================*/
00757 bool case_SCDAN_NCT(ADDRESS& address, int delta, ADDRESS hiAddress,
00758     DecodeResult& inst, DecodeResult& delay_inst, list<HRTL*>*& BB_rtls,
00759     Cfg* cfg, TARGETS& targets)
00760 {
00761     // We may have to move the delay instruction to an orphan
00762     // BB, which then branches to the target of the jump.
00763     // Instead of moving the delay instruction to an orphan BB,
00764     // we may have a duplicate of the delay instruction just
00765     // before the target; if so, we can branch to that and not
00766     // need the orphan. We do just a binary comparison; that
00767     // may fail to make this optimisation if the instr has
00768     // relative fields.
00769     HLJump*   rtl_jump   = static_cast<HLJump*>(inst.rtl);
00770     ADDRESS uDest = rtl_jump->getFixedDest();
00771     PBB pBB;
00772     if (optimise_DelayCopy(address, uDest, delta, hiAddress)) {
00773         // Adjust the destination of the branch
00774         rtl_jump->adjustFixedDest(-4);
00775         // Now emit the branch
00776         BB_rtls->push_back(inst.rtl);
00777         pBB = cfg->newBB(BB_rtls, TWOWAY, 2);
00778         if (pBB == 0) return false;
00779         handleBranch(uDest-4, hiAddress, pBB, cfg, targets);
00780     }
00781     else    // SCDAN; must move delay instr to orphan. Assume it's not a NOP
00782             // (though if it is, no harm done)
00783     {
00784         // Move the delay instruction to the dest of the branch, as an orphan
00785         // First add the branch.
00786         BB_rtls->push_back(inst.rtl);
00787         // Make a BB for the current list of RTLs
00788         // We want to do this first, else ordering can go silly
00789         pBB = cfg->newBB(BB_rtls, TWOWAY, 2);
00790         if (pBB == 0) return false;
00791         // Visit the target of the branch
00792         visit(cfg, uDest, targets, pBB);
00793         HRTLList* pOrphan = new HRTLList;
00794         pOrphan->push_back(delay_inst.rtl);
00795         // Change the address to 0, since this code has no source address
00796         // (else we may branch to here when we want to branch to the real
00797         // BB with this instruction).
00798         delay_inst.rtl->updateAddress(0);
00799         // Add a branch from the orphan instruction to the dest of the branch
00800         pOrphan->push_back(new HLJump(0, uDest));
00801         PBB pOrBB = cfg->newBB(pOrphan, ONEWAY, 1);
00802         // Add an out edge from the orphan as well. Set a label there.
00803         cfg->addOutEdge(pOrBB, uDest, true);
00804         // Add an out edge from the current RTL to
00805         // the orphan. Set a label there.
00806         cfg->addOutEdge(pBB, pOrBB, true);
00807     }
00808     // Both cases (orphan or not)
00809     // Add the "false" leg: point past delay inst. Set a label there (see below)
00810     cfg->addOutEdge(pBB, address+8, true);
00811     // Could need a jump to the following BB, e.g. if uDest is the delay slot
00812     // instruction itself! e.g. beq,a $+8
00813     pBB->setJumpReqd();
00814     address += 8;           // Skip branch and delay
00815     BB_rtls = NULL;         // Start new BB return true;
00816     return true;
00817 }
00818 
00819 
00820 /*==============================================================================
00821  * FUNCTION:         FrontEndSrc::processProc
00822  * OVERVIEW:         Builds the CFG for a procedure out of the RTLs constructed
00823  *                   during decoding. The semantics of delayed CTIs are
00824  *                   transformed into CTIs that aren't delayed.
00825  * NOTE:             This function overrides (and replaces) the function with
00826  *                     the same name in class FrontEnd. The required actions
00827  *                     are so different that the base class implementation
00828  *                     can't be re-used
00829  * PARAMETERS:       address - the address at which the procedure starts
00830  *                   proc - the procedure object
00831  *                   spec - if true, this is a speculative decode
00832  *                   os - output stream for rtl output
00833  * RETURNS:          True if a good decode
00834  *============================================================================*/
00835 bool FrontEndSrc::processProc(ADDRESS address, UserProc* proc, ofstream &os,
00836     bool spec /* = false */)
00837 {
00838     // Declare a queue of targets not yet processed yet. This has to be
00839     // individual to the procedure! (so not a global)
00840     TARGETS targets;
00841 
00842     // Similarly, we have a set of HLCall pointers. These may be disregarded
00843     // if this is a speculative decode that fails (i.e. an illegal instruction
00844     // is found). If not, this set will be used to add to the set of calls to
00845     // be analysed in the cfg, and also to call prog.visitProc()
00846     std::list<CallStatement*> callList;
00847 
00848     // Indicates whether or not the next instruction to be decoded is the
00849     // lexical successor of the current one. Will be true for all NCTs and for
00850     // CTIs with a fall through branch.
00851     bool sequentialDecode = true;
00852 
00853     // The control flow graph of the current procedure
00854     Cfg* cfg = proc->getCFG();
00855 
00856     // If this is a speculative decode, the second time we decode the same
00857     // address, we get no cfg. Else an error.
00858     if (spec && (cfg == 0))
00859         return false;
00860     assert(cfg);
00861 
00862     // Initialise the queue of control flow targets that have yet to be decoded.
00863     targets.push(address);
00864 
00865     // Get the next address from which to continue decoding and go from
00866     // there. Exit the loop if there are no more addresses or they all
00867     // correspond to locations that have been decoded.
00868     while ((address = nextAddress(targets, cfg)) != NO_ADDRESS) {
00869 
00870         // The list of RTLs for the current basic block
00871         list<HRTL*>* BB_rtls = new list<HRTL*>();
00872 
00873         // Keep decoding sequentially until a CTI without a fall through branch
00874         // is decoded
00875         ADDRESS start = address;
00876         DecodeResult inst;
00877         while (sequentialDecode) {
00878 
00879             if (progOptions.trace)
00880                 cout << "*" << hex << address << "\t" << flush;
00881 
00882             inst = decoder.decodeInstruction(address, delta, proc);
00883 
00884             // If invalid and we are speculating, just exit
00885             if (spec && !inst.valid)
00886                 return false;
00887 
00888             // If it's a cancelled instruction (e.g. call to __main), just
00889             // ignore it
00890             if (inst.rtl == 0) {
00891                 address += 4;           // Advance to next instr
00892                 continue;
00893             }
00894             // Don't display the RTL here; do it after the switch statement
00895             // in case the delay slot instruction is moved before this one
00896 
00897             // Need to construct a new list of RTLs if a basic block has just
00898             // been finished but decoding is continuing from its lexical
00899             // successor
00900             if (BB_rtls == NULL)
00901                 BB_rtls = new list<HRTL*>();
00902 
00903             // Define aliases to the RTLs so that they can be treated as a high
00904             // level types where appropriate.
00905             HRTL*   rtl        = inst.rtl;
00906             HLJump*   rtl_jump   = static_cast<HLJump*>(rtl);
00907 
00908             // Update the number of bytes (for coverage)
00909             rtl->updateNumBytes(inst.numBytes);
00910 
00911 #define BRANCH_DS_ERROR 0   // If set, a branch to the delay slot of a delayed
00912                             // CTI instruction is flagged as an error
00913 #if BRANCH_DS_ERROR
00914             if ((rtl->getKind() == JUMP_HRTL) ||
00915                 (rtl->getKind() == CALL_HRTL) ||
00916                 (rtl->getKind() == JCOND_HRTL) ||
00917                 (rtl->getKind() == RET_HRTL)) {
00918                 ADDRESS dest = rtl_jump->getFixedDest();
00919                 if ((dest != NO_ADDRESS) && (dest < hiAddress)){
00920                     unsigned inst_before_dest = *((unsigned*)(dest-4+delta));
00921 
00922                     // FIXME! This is sarc specific
00923                     unsigned bits31_30 = inst_before_dest >> 30;
00924                     unsigned bits23_22 = (inst_before_dest >> 22) & 3;
00925                     unsigned bits24_19 = (inst_before_dest >> 19) & 0x3f;
00926                     unsigned bits29_25 = (inst_before_dest >> 25) & 0x1f;
00927                     if ((bits31_30 == 0x01) ||      // Call
00928                         ((bits31_30 == 0x02) && (bits24_19 == 0x38)) || // Jmpl
00929                         ((bits31_30 == 0x00) && (bits23_22 == 0x02) &&
00930                          (bits29_25 != 0x18))) {// Branch, but not (f)ba,a
00931                             // The above test includes floating point branches
00932                             ostrstream ost;
00933                             ost << "Target of branch at " << hex <<
00934                                 rtl->getAddress() <<
00935                                 " is delay slot of CTI at " << dest-4;
00936                             error(str(ost));
00937                     }
00938                 }
00939             }
00940 #endif
00941 
00942             switch (inst.type) {
00943             case NOP:
00944                 // Always put the NOP into the BB. It may be needed if it is the
00945                 // the destinsation of a branch. Even if not the start of a BB,
00946                 // some other branch may be discovered to it later.
00947                 BB_rtls->push_back(rtl);
00948 
00949                 // Then increment the native address pointer
00950                 address = address + 4;
00951                 break;
00952 
00953             case NCT:
00954                 // Ordinary instruction. Add it to the list of RTLs this BB
00955                 BB_rtls->push_back(rtl);
00956                 address += inst.numBytes;
00957                 // Ret/restore epilogues are handled as ordinary RTLs now
00958                 if (rtl->getKind() == RET_HRTL)
00959                     sequentialDecode = false;
00960                 break;
00961 
00962             case SKIP:
00963             {
00964                 // We can't simply ignore the skipped delay instruction as there
00965                 // will most likely be a branch to it so we simply set the jump
00966                 // to go to one past the skipped instruction.
00967                 rtl_jump->setDest(address+8);
00968                 BB_rtls->push_back(rtl_jump);
00969 
00970                 // Construct the new basic block and save its destination
00971                 // address if it hasn't been visited already
00972                 PBB pBB = cfg->newBB(BB_rtls, ONEWAY, 1);
00973                 handleBranch(address+8, uUpper, pBB, cfg, targets);
00974 
00975                 // There is no fall through branch.
00976                 sequentialDecode = false;
00977                 address += 8;       // Update address for coverage
00978                 break;
00979             }
00980 
00981             case SU:
00982             {   
00983                 // Ordinary, non-delay branch or call/return
00984                 if (rtl->getKind() == CALL_HRTL) {
00985                     // This is a call followed by a return, e.g. a BL to printf
00986                     case_CALL_NCT(address, inst, nop_inst, BB_rtls, proc,
00987                       callList, os);
00988                 } else {
00989                     BB_rtls->push_back(rtl_jump);
00990                     PBB pBB = cfg->newBB(BB_rtls, ONEWAY, 1);
00991                     handleBranch(rtl_jump->getFixedDest(), uUpper, pBB, cfg,
00992                       targets);
00993                     address += inst.numBytes;    // Update address for coverage
00994                 }
00995 
00996                 // There is no fall through branch, either way
00997                 sequentialDecode = false;
00998                 break;
00999             }
01000 
01001             case SD:    // This includes cases where the link register is 2
01002                         // (i.e. a call)
01003             {
01004                 DecodeResult delay_inst = 
01005                     decoder.decodeInstruction(address+4, delta, proc);
01006                 HRTL* delay_rtl = delay_inst.rtl;
01007                 delay_rtl->updateNumBytes(delay_inst.numBytes);
01008 
01009                 switch(delay_inst.type) {
01010                 case NOP:
01011                 case NCT:
01012                 {
01013                     // Ordinary delayed instruction. Since NCT's can't
01014                     // affect unconditional jumps, we put the delay
01015                     // instruction before the jump or call
01016                     if (rtl->getKind() == CALL_HRTL) {
01017 
01018                         // This is a call followed by an NCT/NOP
01019                         sequentialDecode = case_CALL_NCT(address, inst,
01020                             delay_inst, BB_rtls, proc, callList, os);
01021                     }
01022                     else {
01023                         // This is a non-call followed by an NCT/NOP
01024                         case_SD_NCT(address, delta, uUpper, inst, delay_inst,
01025                             BB_rtls, cfg, targets, os);
01026 
01027                         // There is no fall through branch.
01028                         sequentialDecode = false;
01029                     }
01030                     break;
01031                 }
01032 
01033                 case SKIP:
01034                     case_unhandled_stub(address);
01035                     address += 8;
01036                     break;
01037 
01038                 case SU:
01039                 {
01040                     // SD/SU.
01041                     // This will be B.l (call or branch) followed by B.l.n. Our
01042                     // interpretation is that it is as if the SD (i.e. the
01043                     // B.l) now takes the destination of the SU
01044                     // (i.e. the B.l.n). For example:
01045                     //     B.l 1000,2 ;  B.l.n 2000
01046                     // is really like:
01047                     //     call 2000.
01048 
01049                     // Just so that we can check that our interpretation is
01050                     // correct the first time we hit this case...
01051                 case_unhandled_stub(address);
01052 
01053                     // Adjust the destination of the SD and emit it.
01054                     HLJump* delay_jump = static_cast<HLJump*>(delay_rtl);
01055                     int dest = delay_jump->getFixedDest();
01056                     rtl_jump->setDest(dest);
01057                     BB_rtls->push_back(rtl_jump);
01058 
01059                     // Create the appropriate BB
01060                     if (rtl->getKind() == CALL_HRTL) {
01061                         handleCall(dest, cfg->newBB(BB_rtls,CALL, 1), cfg,
01062                             address, 8);
01063                         
01064                         // Set the address of the lexical successor of the
01065                         // call that is to be decoded next. Set RTLs to
01066                         // NULL so that a new list of RTLs will be created
01067                         // for the next BB.
01068                         BB_rtls = NULL;
01069                         address = address + 8;
01070 
01071                         // Add this call site to the set of call sites which
01072                         // need to be analysed later.
01073                         callList.push_back((HLCall*)inst.rtl);
01074                     }
01075                     else {
01076                         PBB pBB = cfg->newBB(BB_rtls,ONEWAY, 1);
01077                         handleBranch(dest, uUpper, pBB, cfg, targets);
01078 
01079                         // There is no fall through branch.
01080                         sequentialDecode = false;
01081                     }
01082                     break;
01083                 }
01084                 default:
01085                     case_unhandled_stub(address);
01086                     address += 8;       // Skip the pair
01087                     break;
01088                 }
01089                 break;
01090             }
01091 
01092             case DD:
01093             {
01094                 DecodeResult delay_inst; 
01095                 if (inst.numBytes == 4) {
01096                     // Ordinary instruction. Look at the delay slot
01097                     delay_inst = decoder.decodeInstruction(address+4,
01098                         delta, proc);
01099                     delay_inst.rtl->updateNumBytes(delay_inst.numBytes);
01100                 }
01101                 else {
01102                     // Must be a prologue or epilogue or something.
01103                     delay_inst = nop_inst;
01104                     // Should be no need to adjust the coverage; the number of
01105                     // bytes should take care of it
01106                 }
01107                     
01108                 HRTL* delay_rtl = delay_inst.rtl;
01109 
01110                 // Display RTL representation if asked
01111                 if (progOptions.rtl && delay_rtl != NULL)
01112                     delay_rtl->print(os);
01113 
01114                 switch(delay_inst.type) {
01115                 case NOP:
01116                 case NCT:
01117                 {
01118                     sequentialDecode = case_DD_NCT(address, delta, inst,
01119                         delay_inst, BB_rtls, cfg, targets, proc, callList, 8);
01120                     break;
01121                 }
01122                 default:
01123                     case_unhandled_stub(address);
01124                     break;
01125                 }
01126                 break;
01127             }
01128 
01129             case DU: {
01130                 // Same as DD case, but no delay slot to worry about
01131                 DecodeResult delay_inst = nop_inst;
01132                     
01133                 sequentialDecode = case_DD_NCT(address, delta, inst,
01134                   delay_inst, BB_rtls, cfg, targets, proc, callList, 4);
01135                 break;
01136             }
01137 
01138             case SCD:
01139             {
01140                 // Always execute the delay instr, and branch if
01141                 // condition is met.
01142                 // Normally, the delayed instruction moves in front
01143                 // of the branch. But if it affects a register being
01144                 // used in the SCD, we may have to duplicate it as an orphan
01145                 // in the true leg of the branch, and fall through to the
01146                 // delay instruction in the "false" leg.
01147                 // Instead of moving the delay instruction to an orphan BB, we
01148                 // may have a duplicate of the delay instruction just before the
01149                 // target; if so, we can branch to that and not need the orphan
01150                 // We do just a binary comparison; that may fail to make this
01151                 // optimisation if the instr has relative fields.
01152 
01153                 DecodeResult delay_inst = 
01154                     decoder.decodeInstruction(address+4,delta, proc);
01155                 HRTL* delay_rtl = delay_inst.rtl;
01156                 delay_rtl->updateNumBytes(delay_inst.numBytes);
01157 
01158                 // Display low level RTL representation if asked
01159                 if (progOptions.rtl && delay_rtl != NULL)
01160                     delay_rtl->print(os);
01161 
01162                 switch(delay_inst.type) {
01163                 case NOP:
01164                 case NCT:
01165                 {
01166                     sequentialDecode = case_SCD_NCT(address, delta, uUpper,
01167                         inst, delay_inst, BB_rtls, cfg, targets);
01168                     break;
01169                 }
01170                 default:
01171                     case_unhandled_stub(address);
01172                     break;
01173                 }
01174                 break;
01175             }
01176 
01177             case SCDAN:
01178             {
01179                 // Execute the delay instruction if the branch is taken;
01180                 // skip (anull) the delay instruction if branch not taken.
01181                 DecodeResult delay_inst = 
01182                     decoder.decodeInstruction(address+4,delta, proc);
01183                 HRTL* delay_rtl = delay_inst.rtl;
01184                 delay_rtl->updateNumBytes(delay_inst.numBytes);
01185 
01186                 // Display RTL representation if asked
01187                 if (progOptions.rtl && delay_rtl != NULL)
01188                     delay_rtl->print(os);
01189 
01190                 switch(delay_inst.type) {
01191                 case NOP:
01192                 {
01193                     // This is an ordinary two-way branch.
01194                     // Add the branch to the list of RTLs for this BB
01195                     BB_rtls->push_back(rtl);
01196                     // Create the BB and add it to the CFG
01197                     PBB pBB = cfg->newBB(BB_rtls, TWOWAY, 2);
01198                     if (pBB == 0) {
01199                         sequentialDecode = false; break;
01200                     }
01201                     // Visit the destination of the branch; add "true" leg
01202                     ADDRESS uDest = rtl_jump->getFixedDest();
01203                     handleBranch(uDest, uUpper, pBB, cfg, targets);
01204                     // Add the "false" leg: point past the delay inst
01205                     cfg->addOutEdge(pBB, address+8);
01206                     address += 8;           // Skip branch and delay
01207                     BB_rtls = NULL;         // Start new BB
01208                     break;
01209                 }
01210 
01211                 case NCT:
01212                 {
01213                     sequentialDecode = case_SCDAN_NCT(address, delta, uUpper,
01214                         inst, delay_inst, BB_rtls, cfg, targets);
01215                     break;
01216                 }
01217 
01218                 default:
01219                     case_unhandled_stub(address);
01220                     address = address + 8;
01221                     break;
01222                 }
01223                 break;
01224             }
01225 
01226             case SCDAT: {
01227                 // Static Conditional Delayed, Anulled if Taken
01228                 // Basically, like an ordinary undelayed jump, but has two
01229                 // out-edges
01230                 BB_rtls->push_back(rtl);        // Add the jump
01231                 ADDRESS uDest = ((HLJump*)rtl)->getFixedDest();
01232                 PBB pBB = cfg->newBB(BB_rtls, TWOWAY, 2);
01233                 if (pBB == 0) { BB_rtls = NULL; continue;}
01234                 handleBranch(uDest, uUpper, pBB, cfg, targets);
01235                 address += 4;           // "Delay slot" instruction is next
01236                 cfg->addOutEdge(pBB, address);  // False leg
01237                 BB_rtls = NULL;         // Start new list of RTLs for next BB
01238                 break;
01239             }
01240 
01241             case NCTA: {
01242                 // These instructions have been identified as anulling the
01243                 // following instuction. First we decode the following instr
01244                 BB_rtls->push_back(rtl);        // Add the jump
01245                 DecodeResult follow_inst = 
01246                     decoder.decodeInstruction(address+4,delta, proc);
01247                 HRTL* follow_rtl = follow_inst.rtl;
01248                 follow_rtl->updateNumBytes(follow_inst.numBytes);
01249 
01250                 int n = follow_rtl->getNumRT();
01251                 for (int i=0; i < n; i++) {
01252                     RTAssgn* rt = (RTAssgn*)follow_rtl->elementAt(i);
01253                     if (rt->getKind() == RTASSGN) {
01254                         SemStr* notNull = new SemStr;
01255                         // We want L! r[ tpmNul ]
01256                         *notNull << idLNot << idRegOf << idTemp << idTmpNul;
01257                         rt->addGuard(notNull);
01258                         delete notNull;
01259                     }
01260                 }
01261 
01262                 BB_rtls->push_back(follow_rtl);         // Add the follow instr
01263                 // Display low level RTL representation if asked
01264                 if (progOptions.rtl && follow_rtl != NULL)
01265                     follow_rtl->print(os);
01266 
01267                 address += 8;           // Skip NCTA and following instr
01268             }
01269 
01270             }   // switch inst.type
01271 
01272             // Display RTL representation if asked
01273             if (progOptions.rtl && (inst.rtl != NULL))
01274                 inst.rtl->print(os);
01275 
01276             // If sequentially decoding, check if the next address happens to
01277             // be the start of an existing BB. If so, finish off the current BB
01278             // (if any RTLs) as a fallthrough, and  no need to decode again
01279             // (unless it's an incomplete BB, then we do decode it).
01280             // In fact, mustn't decode twice, because it will muck up the
01281             // coverage, but also will cause subtle problems like add a call
01282             // to the list of calls to be processed, then delete the call RTL
01283             // (e.g. Pentium 134.perl benchmark)
01284             if (sequentialDecode && cfg->existsBB(address)) {
01285                 // Create the fallthrough BB, if there are any RTLs at all
01286                 if (BB_rtls) {
01287                     PBB pBB = cfg->newBB(BB_rtls, FALL, 1);
01288                     // Add an out edge to this address
01289                     if (pBB) {
01290                         cfg->addOutEdge(pBB, address);
01291                         BB_rtls = NULL;         // Need new list of RTLs
01292                     }
01293                 }
01294                 // Pick a new address to decode from, if the BB is complete
01295                 if (!cfg->isIncomplete(address))
01296                     sequentialDecode = false;
01297             }
01298 
01299         }       // while (sequentialDecode)
01300 
01301         // Add this range to the coverage
01302         proc->addRange(start, address);
01303 
01304         // Must set sequentialDecode back to true
01305         sequentialDecode = true;
01306     }
01307 
01308     // This pass is to remove single nops between ranges.
01309     // These will be assumed to be padding for alignments of BBs
01310     // Possibly removes a lot of ranges that could otherwise be combined
01311     ADDRESS a1, a2;
01312     COV_CIT ii;
01313     Coverage temp;
01314     if (proc->getFirstGap(a1, a2, ii)) {
01315         do {
01316             int gap = a2 - a1;
01317             if (gap < 8) {
01318                 bool allNops = true;
01319                 for (int i=0; i < gap; i+= 4) {
01320                     // Beware endianness! getDword will work properly
01321                     if (getDword(a1+i+delta) != 0x08000240) {
01322                         allNops = false;
01323                         break;
01324                     }
01325                 }
01326                 if (allNops)
01327                     // Remove this gap, by adding a range equal to the gap
01328                     // Note: it's not safe to add the range now, so we put
01329                     // the range into a temp Coverage object to be added later
01330                     temp.addRange(a1, a2);
01331             }
01332         } while (proc->getNextGap(a1, a2, ii));
01333     }
01334     // Now add the ranges in temp
01335     proc->addRanges(temp);
01336 
01337     // Add the resultant coverage to the program's coverage
01338     proc->addProcCoverage();
01339 
01340     // Add the callees to the set of HLCalls to proces for CSR, and also
01341     // to the Prog object
01342     for (std::list<CallStatement*>::iterator it = callList.begin(); it != callList.end(); it++) {
01343         ADDRESS dest = (*it)->getFixedDest();
01344         // Don't speculatively decode procs that are outside of the main text
01345         // section, apart from dynamically linked ones (in the .plt)
01346         if (prog.pBF->IsDynamicLinkedProc(dest) || !spec || (dest < uUpper)) {
01347             cfg->addCall(*it);
01348             // Don't visit the destination of a register call
01349             if (dest != NO_ADDRESS) prog.visitProc(dest);
01350         }
01351     }
01352     return true;
01353 }
01354 
01355 /*==============================================================================
01356  * FUNCTION:      emitNop
01357  * OVERVIEW:      Emit a null RTL with the given address.
01358  * PARAMETERS:    pRtls - List of RTLs to append this instruction to
01359  *                uAddr - Native address of this instruction
01360  * RETURNS:       <nothing>
01361  *============================================================================*/
01362 void emitNop(HRTLList* pRtls, ADDRESS uAddr)
01363 {
01364     // Emit a null RTL with the given address. Required to cope with
01365     // SKIP instructions. Yes, they really happen, e.g. /usr/bin/vi 2.5
01366     HRTL* pRtl = new RTL;
01367     pRtl->updateAddress(uAddr);
01368     pRtls->push_back(pRtl);
01369 }
01370 
01371 /*==============================================================================
01372  * FUNCTION:      emitCopyPC
01373  * OVERVIEW:      Emit the RTL for a call $+8 instruction, which is merely
01374  *                  %o7 = %pc
01375  * NOTE:          Assumes that the delay slot RTL has already been pushed; we
01376  *                  must push the semantics BEFORE that RTL, since the delay
01377  *                  slot instruction may use %o7. Example:
01378  *                  CALL $+8            ! This code is common in startup code
01379  *                  ADD  %o7, 20, %o0
01380  * PARAMETERS:    pRtls - list of RTLs to append to
01381  *                uAddr - native address for the RTL
01382  * RETURNS:       <nothing>
01383  *============================================================================*/
01384 void emitCopyPC(HRTLList* pRtls, ADDRESS uAddr)
01385 {
01386     // Emit %o7 = %pc
01387     SemStr* pssSrc = new SemStr;
01388     pssSrc->push(idPC);
01389     SemStr* pssDest = new SemStr;
01390     pssDest->push(idRegOf);
01391     pssDest->push(idIntConst);
01392     pssDest->push(15);      // %o7
01393     // Make an assignment RT
01394     RTAssgn* pRt = new RTAssgn(pssDest, pssSrc, 32);
01395     // Add the RT to an RTL
01396     HRTL* pRtl = new RTL(uAddr);
01397     pRtl->appendRT(pRt);
01398     // Add the RTL to the list of RTLs, but to the second last position
01399     pRtls->insert(--pRtls->end(), pRtl);
01400 }
01401 
01402 /*==============================================================================
01403  * FUNCTION:        helperFunc
01404  * OVERVIEW:        Checks for sparc specific helper functions like .urem,
01405  *                      which have specific sematics.
01406  * NOTE:            This needs to be handled in a resourcable way.
01407  * PARAMETERS:      dest: destination of the call (native address)
01408  *                  addr: address of current instruction (native addr)
01409  *                  lrtl: list of RTL* for current BB
01410  * RETURNS:         True if a helper function was found and handled; false
01411  *                      otherwise
01412  *============================================================================*/
01413 // Append one assignment to a list of RTLs
01414 void appendAssignment(SemStr* lhs, SemStr* rhs, int size, ADDRESS addr, HRTLList*
01415     lrtl)
01416 {
01417     RTAssgn* rta = new RTAssgn(lhs, rhs, size);
01418     // Create an RTL with this one RT
01419     list<RT*>* lrt = new list<RT*>;
01420     lrt->push_back(rta);
01421     HRTL* rtl = new RTL(addr, lrt);
01422     // Append this RTL to the list of RTLs for this BB
01423     lrtl->push_back(rtl);
01424 }
01425 
01426 
01427 // Determine if this is a helper function, e.g. .mul. If so, append the
01428 // appropriate RTLs to lrtl, and return true
01429 bool helperFunc(ADDRESS dest, ADDRESS addr, HRTLList* lrtl)
01430 {
01431     // Helper functions are millicode, and don't seem to appear in the imports
01432     // section. So they don't appear to be dynamically linked
01433 //  if (!prog.pBF->IsDynamicLinkedProc(dest)) return false;
01434     const char* pName =  prog.pBF->SymbolByAddress(dest);
01435     if (pName == 0) return false;
01436     string name(pName);
01437 //    if (progOptions.fastInstr == false)
01438 //        return helperFuncLong(dest, addr, lrtl, name);
01439     SemStr* rhs = new SemStr;
01440     if (name == "$$remU") {
01441         // %r26 % %r25
01442         *rhs << idMod << idRegOf << idIntConst << 26 <<
01443                          idRegOf << idIntConst << 25;
01444     } else if (name == "$$remI") {
01445         // %r26 %! %r25
01446         *rhs << idMods << idRegOf << idIntConst << 26 <<
01447                           idRegOf << idIntConst << 25;
01448     } else if (name == "$$divU") {
01449         // %r26 / %r25
01450         *rhs << idDiv << idRegOf << idIntConst << 26 <<
01451                          idRegOf << idIntConst << 25;
01452     } else if (name == "$$divI") {
01453         // %r26 /! %r25
01454         *rhs << idDivs << idRegOf << idIntConst << 26 <<
01455                           idRegOf << idIntConst << 25;
01456     } else if (name == "$$dyncall") {
01457         // *(r22)()
01458         list<RT*> ll;
01459         HLCall* call = new HLCall(addr);
01460         SemStr* dest = new SemStr;
01461         *dest << idMemOf << idRegOf << idIntConst << 22;
01462         call->setDest(dest);
01463         // Append this RTL to the list of RTLs for this BB
01464         lrtl->push_back(call);
01465         return true;
01466     } else {
01467         // Not a (known) helper function
01468         delete rhs;
01469         return false;
01470     }
01471     // Need to make an RTAssgn with %r29 = rhs
01472     // Note: r29 is the millicode return value register. This code assumes that
01473     // all helper functions are millicode functions!
01474     SemStr* lhs = new SemStr;
01475     *lhs << idRegOf << idIntConst << 29;
01476     RTAssgn* rta = new RTAssgn(lhs, rhs, 32);
01477     // Create an RTL with this one RT
01478     list<RT*>* lrt = new list<RT*>;
01479     lrt->push_back(rta);
01480     HRTL* rtl = new RTL(addr, lrt);
01481     // Append this RTL to the list of RTLs for this BB
01482     lrtl->push_back(rtl);
01483     return true;
01484 }
01485 
01486 #if 0
01487 /* Small "local" function to build an expression with
01488  * *128* m[m[r[14]+64]] = m[r[8]] OP m[r[9]] */
01489 void quadOperation(ADDRESS addr, HRTLList* lrtl, int op)
01490 {
01491     SemStr* lhs = new SemStr(Type(FLOATP, 128, true));
01492     SemStr* rhs = new SemStr(Type(FLOATP, 128, true));
01493     lhs->push(idMemOf); lhs->push(idMemOf); lhs->push(idPlus);
01494     lhs->push(idRegOf); lhs->push(idIntConst); lhs->push(14);
01495     lhs->push(idIntConst); lhs->push(64);
01496     rhs->push(op);
01497     rhs->push(idMemOf);
01498     rhs->push(idRegOf); rhs->push(idIntConst); rhs->push(8);
01499     rhs->push(idMemOf);
01500     rhs->push(idRegOf); rhs->push(idIntConst); rhs->push(9);
01501     appendAssignment(lhs, rhs, 128, addr, lrtl);
01502 }
01503 // This is the long version of helperFunc (i.e. -f not used). This does the
01504 // complete 64 bit semantics
01505 bool helperFuncLong(ADDRESS dest, ADDRESS addr, HRTLList* lrtl, string& name)
01506 {
01507     SemStr* rhs = new SemStr;
01508     SemStr* lhs = new SemStr;
01509     list<RT*>* lrt = new list<RT*>;
01510     int tmpl = theSemTable.findItem("tmpl");
01511     if (name == ".umul") {
01512         // r[tmpl] = sgnex(32, 64, r8) * sgnex(32, 64, r9)
01513         *lhs << idRegOf << idTemp << tmpl;
01514         *rhs << idMult <<
01515           idSgnEx << 32 << 64 << idRegOf << idIntConst << 8 <<
01516           idSgnEx << 32 << 64 << idRegOf << idIntConst << 9;
01517         lrt->push_back(new RTAssgn(lhs, rhs, 64));
01518         // r8 = truncs(64, 32, r[tmpl]);
01519         lhs = new SemStr; rhs = new SemStr;
01520         *lhs << idRegOf << idIntConst << 8;
01521         *rhs << idTruncs << 64 << 32 << idRegOf << idTemp << tmpl;
01522         lrt->push_back(new RTAssgn(lhs, rhs, 32));
01523         // r9 = r[tmpl]@32:63;
01524         lhs = new SemStr; rhs = new SemStr;
01525         *lhs << idRegOf << idIntConst << 9;
01526         *rhs << idAt << idRegOf << idTemp << tmpl << idIntConst << 32 <<
01527           idIntConst << 63;
01528         lrt->push_back(new RTAssgn(lhs, rhs, 32));
01529         HRTL* rtl = new RTL(addr, lrt);
01530         lrtl->push_back(rtl);
01531         return true;
01532     } else if (name == ".mul") {
01533         // r[tmpl] = sgnex(32, 64, r8) *! sgnex(32, 64, r9)
01534         *lhs << idRegOf << idTemp << tmpl;
01535         *rhs << idMults <<
01536           idSgnEx << 32 << 64 << idRegOf << idIntConst << 8 <<
01537           idSgnEx << 32 << 64 << idRegOf << idIntConst << 9;
01538         lrt->push_back(new RTAssgn(lhs, rhs, 64));
01539         // r8 = truncs(64, 32, r[tmpl]);
01540         lhs = new SemStr; rhs = new SemStr;
01541         *lhs << idRegOf << idIntConst << 8;
01542         *rhs << idTruncs << 64 << 32 << idRegOf << idTemp << tmpl;
01543         lrt->push_back(new RTAssgn(lhs, rhs, 32));
01544         // r9 = r[tmpl]@32:63;
01545         lhs = new SemStr; rhs = new SemStr;
01546         *lhs << idRegOf << idIntConst << 9;
01547         *rhs << idAt << idRegOf << idTemp << tmpl << idIntConst << 32 <<
01548           idIntConst << 63;
01549         lrt->push_back(new RTAssgn(lhs, rhs, 32));
01550         HRTL* rtl = new RTL(addr, lrt);
01551         lrtl->push_back(rtl);
01552         return true;
01553     } else if (name == ".udiv") {
01554         // %o0 / %o1
01555         *rhs << idDiv <<
01556           idRegOf << idIntConst << 8 << 
01557           idRegOf << idIntConst << 9;
01558     } else if (name == ".div") {
01559         // %o0 /! %o1
01560         *rhs << idDivs <<
01561           idRegOf << idIntConst << 8 << 
01562           idRegOf << idIntConst << 9;
01563     } else if (name == ".urem") {
01564         // %o0 % %o1
01565         *rhs << idMod <<
01566           idRegOf << idIntConst << 8 << 
01567           idRegOf << idIntConst << 9;
01568     } else if (name == ".rem") {
01569         // %o0 %! %o1
01570         *rhs << idMods <<
01571           idRegOf << idIntConst << 8 << 
01572           idRegOf << idIntConst << 9;
01573 //  } else if (name.substr(0, 6) == ".stret") {
01574 //      // No operation. Just use %o0
01575 //      rhs->push(idRegOf); rhs->push(idIntConst); rhs->push(8);
01576     } else if (name == "_Q_mul") {
01577         // Pointers to args are in %o0 and %o1; ptr to result at [%sp+64]
01578         // So semantics is m[m[r[14]] = m[r[8]] *f m[r[9]]
01579         quadOperation(addr, lrtl, idFMult);
01580         return true;
01581     } else if (name == "_Q_div") {
01582         quadOperation(addr, lrtl, idFDiv);
01583         return true;
01584     } else if (name == "_Q_add") {
01585         quadOperation(addr, lrtl, idFPlus);
01586         return true;
01587     } else if (name == "_Q_sub") {
01588         quadOperation(addr, lrtl, idFMinus);
01589         return true;
01590     } else {
01591         // Not a (known) helper function
01592         delete lhs; delete rhs; delete lrt;
01593         return false;
01594     }
01595     // Need to make an RTAssgn with %o0 = rhs
01596     *lhs << idRegOf << idIntConst << 8;
01597     appendAssignment(lhs, rhs, 32, addr, lrtl);
01598     return true;
01599 }
01600 #endif
01601 
01602 /*==============================================================================
01603  * FUNCTION:        setReturnLocations
01604  * OVERVIEW:        Set the return location for the given callee epilogue
01605  *                      to be the standard set of Hppa locations, using iReg
01606  *                      (always 28) to return integers
01607  * NOTE:            This is part of a hack that would go away if we could have
01608  *                  Logues that were both caller-prologues and callee-epilogues
01609  * PARAMETERS:      epilogue: pointer to a CalleeEpilogue object that is to
01610  *                      have it's return spec set
01611  *                  iReg: The register that integers are returned in
01612  * RETURNS:         nothing
01613  *============================================================================*/
01614 void setReturnLocations(CalleeEpilogue* epilogue, int iReg)
01615 {
01616     // This function is somewhat similar to CSRParser::setReturnLocations() in
01617     // CSR/csrparser.y
01618     // First need to set up spec, which is a ReturnLocation object with the
01619     // four Sparc return locations
01620     typeToSemStrMap retMap;
01621     SemStr ss;
01622     ss.push(idRegOf); ss.push(idIntConst); ss.push(iReg);
01623     retMap.insert(pair<Type, SemStr>(Type(::INTEGER), ss));
01624     retMap.insert(pair<Type, SemStr>(Type(::DATA_ADDRESS), ss));
01625     // FIXME! This is sparc specific, but we haven't considered floating point
01626     // as yet
01627     // Now we want ss to be %f0, i.e. r[32]
01628     ss.substIndex(2, 32);
01629     retMap.insert(pair<Type, SemStr>(Type(::FLOATP, 32), ss));
01630     // Now we want ss to be %f0to1, i.e. r[64]
01631     ss.substIndex(2, 64);
01632     retMap.insert(pair<Type, SemStr>(Type(::FLOATP, 64), ss));
01633     ReturnLocations spec(retMap);
01634     epilogue->setRetSpec(spec);
01635 }

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