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 }