| 79 | // |
| 80 | |
| 81 | CTraceRecorder::EUpdateTraceStatus CTraceRecorder::UpdateTrace( u32 address, |
| 82 | bool branch_delay_slot, |
| 83 | bool branch_taken, |
| 84 | OpCode op_code, |
| 85 | CFragment * p_fragment ) |
| 86 | { |
| 87 | #ifdef DAEDALUS_ENABLE_ASSERTS |
| 88 | DAEDALUS_ASSERT( mTracing, "We're not tracing" ); |
| 89 | #endif |
| 90 | bool want_to_stop( p_fragment != nullptr ); |
| 91 | |
| 92 | if( mTraceBuffer.size() > MAX_TRACE_LENGTH ) |
| 93 | { |
| 94 | #ifdef DAEDALUS_DEBUG_CONSOLE |
| 95 | DBGConsole_Msg(0, "Hit max trace size!"); |
| 96 | #endif |
| 97 | want_to_stop = true; |
| 98 | } |
| 99 | |
| 100 | // Terminate if the current instruction is in the fragment cache or the trace reaches a specified size |
| 101 | if( want_to_stop && (mActiveBranchIdx == INVALID_IDX) ) |
| 102 | { |
| 103 | #ifdef DAEDALUS_ENABLE_ASSERTS |
| 104 | DAEDALUS_ASSERT( mActiveBranchIdx == INVALID_IDX, "Exiting trace while in the middle of handling branch!" ); |
| 105 | #endif |
| 106 | // Stop immediately so we can be sure of linking up with fragment |
| 107 | mTracing = false; |
| 108 | mExpectedExitTraceAddress = address; |
| 109 | return UTS_CREATE_FRAGMENT; |
| 110 | } |
| 111 | |
| 112 | // |
| 113 | // Figure out whether to terminate this trace after adding this instruction |
| 114 | // |
| 115 | bool stop_trace_on_exit( false ); |
| 116 | |
| 117 | // |
| 118 | // We want to record the delay slot op for the active branch |
| 119 | // |
| 120 | if( mActiveBranchIdx != INVALID_IDX ) |
| 121 | { |
| 122 | #ifdef DAEDALUS_ENABLE_ASSERTS |
| 123 | DAEDALUS_ASSERT( mActiveBranchIdx < mBranchDetails.size(), "Branch index is out of bounds" ); |
| 124 | #endif |
| 125 | mBranchDetails[ mActiveBranchIdx ].DelaySlotTraceIndex = mTraceBuffer.size(); |
| 126 | |
| 127 | if (mBranchDetails[ mActiveBranchIdx ].SpeedHack == SHACK_POSSIBLE) |
| 128 | { |
| 129 | if (op_code._u32 == 0) |
| 130 | { |
| 131 | mBranchDetails[ mActiveBranchIdx ].SpeedHack = SHACK_SKIPTOEVENT; |
| 132 | |
| 133 | } |
| 134 | #ifndef DAEDALUS_SILENT |
| 135 | else if (op_code.op == OP_ADDIU || op_code.op == OP_DADDI || op_code.op == OP_ADDI || op_code.op == OP_DADDIU) |
| 136 | { // We don't handle COPYREG SPEEDHACKS |
| 137 | mBranchDetails[ mActiveBranchIdx ].SpeedHack = SHACK_COPYREG; |
| 138 | } |
no test coverage detected