void wxSheetValueProviderSparseString::SetValue( const wxSheetCoords& coords_, const wxString& value ) { wxCHECK_RET(ContainsCell(coords_), wxT("Invalid coords")); wxSheetCoords coords(HasOption(wxSHEET_ValueProviderColPref) ? coords_ : coords_.GetSwapped()); const int rowPos = m_data.Index(coords.m_row); if (!HasOption(wxSHEET_ValueProviderAllowEmpty) && value.IsEmpty()) { // remove the value if empty if (rowPos != wxNOT_FOUND) { m_data.ItemValue(rowPos).Remove(coords.m_col); // remove this row if empty if (m_data.ItemValue(rowPos).GetCount() == 0) m_data.RemoveAt(rowPos); } } else { if (rowPos == wxNOT_FOUND) m_data.GetOrCreateValue(coords.m_row).Add(coords.m_col, value); else m_data.ItemValue(rowPos).Add(coords.m_col, value); } }
wxSheetValueProviderSparseStringTest::wxSheetValueProviderSparseStringTest(size_t numRows, size_t numCols, int options) :wxSheetValueProviderBase(0, 0, options) { m_numRows += numRows; m_numCols += numCols; DoUpdateRows(0, HasOption(wxSHEET_ValueProviderColPref) ? numRows : numCols); DoUpdateCols(0, HasOption(wxSHEET_ValueProviderColPref) ? numCols : numRows); }
void PPCAnalyzer::ReorderInstructions(u32 instructions, CodeOp *code) { // Reorder cror instructions upwards (e.g. towards an fcmp). Technically we should be more // picky about this, but cror seems to almost solely be used for this purpose in real code. // Additionally, the other boolean ops seem to almost never be used. ReorderInstructionsCore(instructions, code, true, REORDER_CROR); // For carry, bubble instructions *towards* each other; one direction often isn't enough // to get pairs like addc/adde next to each other. if (HasOption(OPTION_CARRY_MERGE)) { ReorderInstructionsCore(instructions, code, false, REORDER_CARRY); ReorderInstructionsCore(instructions, code, true, REORDER_CARRY); } if (HasOption(OPTION_BRANCH_MERGE)) ReorderInstructionsCore(instructions, code, false, REORDER_CMP); }
ApiErrorCode JSONConfiguration::InitFromFile(IN const string &filename) { ifstream is(filename.c_str()); if (read(is, _rootValue) == false) { cerr << "Error reading json configuration file '" << filename << "'. Check that file exists, accessible and JSON valid." << endl; return API_FAILURE; } is.close(); if (HasOption("dump_configuration") && GetBool("dump_configuration") == TRUE) { cout << "Dumping Configuration...\n"; ifstream is1(filename.c_str()); if (is1.is_open()) { string line; while ( is1.good() ) { getline (is1,line); cout << line << endl; } is1.close(); } else { cerr << "Error dumping '" << filename << "'. Check that file exists and accessible." << endl; return API_FAILURE; } } return API_SUCCESS; }
void wxSheetValueProviderSparseStringTest::SetValue( const wxSheetCoords& coords_, const wxString& value ) { wxCHECK_RET(ContainsCell(coords_), wxT("Invalid coords")); wxSheetCoords coords(HasOption(wxSHEET_ValueProviderColPref) ? coords_ : coords_.GetSwapped()); m_intArrayIntString.m_key = coords.m_row; const int rowPos = m_data.Index(&m_intArrayIntString); //const int rowPos = m_data.Index(wxSheetIntArrayIntString(coords.m_row)); if (value.IsEmpty()) { // remove the value if empty if (rowPos != wxNOT_FOUND) { m_data[rowPos].m_value->Remove(wxSheetIntString(coords.m_col)); // remove this row if empty if (m_data[rowPos].m_value->GetCount() == 0) m_data.RemoveAt(rowPos); } } else { if (rowPos == wxNOT_FOUND) { //m_intArrayIntString.m_key = coords.m_row; //m_intArrayIntString.m_value = wxSheetIntStringSortedObjArray(wxSheetIntString(coords.m_col, value)); //m_intArrayIntString.m_value.Add(new wxSheetIntString(coords.m_col, value)); //m_data.Add(m_intArrayIntString); m_data.Add(new wxSheetIntArrayIntString(coords.m_row, new wxSheetIntStringSortedObjArray(new wxSheetIntString(coords.m_col, value)))); } else m_data[rowPos].m_value->Add(new wxSheetIntString(coords.m_col, value)); } }
bool wxSheetValueProviderString::UpdateRows( size_t row, int numRows ) { wxSHEET_CHECKUPDATE_MSG(row, numRows, m_numRows, false); m_numRows += numRows; return HasOption(wxSHEET_ValueProviderColPref) ? DoUpdateRows(row, numRows) : DoUpdateCols(row, numRows); }
bool wxSheetValueProviderSparseStringTest::UpdateCols( size_t col, int numCols ) { wxSHEET_CHECKUPDATE_MSG(col, numCols, m_numRows, false) m_numCols += numCols; return HasOption(wxSHEET_ValueProviderColPref) ? DoUpdateCols(col, numCols) : DoUpdateRows(col, numCols); }
status_t ServerIconExportUpdateProcess::RunInternal() { status_t result = B_OK; if (NULL == fLocalIconStore || fLocalIconStoragePath.Path() == NULL) result = B_ERROR; if (IsSuccess(result) && HasOption(SERVER_PROCESS_DROP_CACHE)) { result = StorageUtils::RemoveDirectoryContents(fLocalIconStoragePath); } if (result == B_OK) { bool hasData; result = HasLocalData(&hasData); if (result == B_OK && ShouldAttemptNetworkDownload(hasData)) result = _DownloadAndUnpack(); if (IsSuccess(result)) { status_t hasDataResult = HasLocalData(&hasData); if (hasDataResult == B_OK && !hasData) result = HD_ERR_NO_DATA; } } if (IsSuccess(result) && !WasStopped()) result = Populate(); return result; }
bool wxSheetValueProviderSparseStringTest::HasValue( const wxSheetCoords& coords_ ) const { wxCHECK_MSG(ContainsCell(coords_), false, wxT("Invalid coords")); wxSheetCoords coords(HasOption(wxSHEET_ValueProviderColPref) ? coords_ : coords_.GetSwapped()); const int rowPos = m_data.Index(wxSheetIntArrayIntString(coords.m_row)); if (rowPos == wxNOT_FOUND) return false; return m_data[rowPos].m_value->Index(wxSheetIntString(coords.m_col)) != wxNOT_FOUND; }
wxString wxSheetValueProviderSparseString::GetValue( const wxSheetCoords& coords_ ) const { wxCHECK_MSG(ContainsCell(coords_), wxEmptyString, wxT("Invalid coords")); wxSheetCoords coords(HasOption(wxSHEET_ValueProviderColPref) ? coords_ : coords_.GetSwapped()); const int rowPos = m_data.Index(coords.m_row); if (rowPos != wxNOT_FOUND) return m_data.ItemValue(rowPos).GetValue(coords.m_col); return wxEmptyString; }
int wxSheetValueProviderString::GetFirstNonEmptyColToLeft( const wxSheetCoords& coords ) const { wxCHECK_MSG(ContainsCell(coords), coords.m_col - 1, wxT("Invalid coords")); if (HasOption(wxSHEET_ValueProviderColPref)) { if (int(m_data.GetCount()) <= coords.m_row) return -1; if (int(m_data[coords.m_row].GetCount()) < coords.m_col) return m_data[coords.m_row].GetCount() - 1; } // the else case cannot be optimized - just use default return coords.m_col - 1; }
wxString wxSheetValueProviderString::GetValue( const wxSheetCoords& coords_ ) const { wxCHECK_MSG(ContainsCell(coords_), wxEmptyString, wxT("Invalid coords")); wxSheetCoords coords(HasOption(wxSHEET_ValueProviderColPref) ? coords_ : coords_.GetSwapped()); //wxPrintf(wxT("RC %d %d - NumRC %d %d DataRC %d %d '%s'\n"), coords_.m_row, coords_.m_col, m_numRows, m_numCols, // m_data.GetCount(), int(m_data.GetCount()) > coords.m_col ? m_data[coords.m_col].GetCount() : 0, // wxDateTime::Now().FormatISOTime().c_str()); if ((int(m_data.GetCount()) > coords.m_row) && (int(m_data[coords.m_row].GetCount()) > coords.m_col)) return m_data[coords.m_row][coords.m_col]; return wxEmptyString; }
int wxSheetValueProviderSparseStringTest::GetFirstNonEmptyColToLeft( const wxSheetCoords& coords ) const { wxCHECK_MSG(ContainsCell(coords), coords.m_col - 1, wxT("Invalid coords")); if (HasOption(wxSHEET_ValueProviderColPref)) { const int rowPos = m_data.Index(wxSheetIntArrayIntString(coords.m_row)); if (rowPos != wxNOT_FOUND) { // pos == 0 meaning nothing to left, == count for col > last filled const int colPos = m_data[rowPos].m_value->IndexForInsert(wxSheetIntString(coords.m_col)); if (colPos > 0) return m_data[rowPos].m_value->Item(colPos-1).m_key; } return -1; } return coords.m_col - 1; }
wxString wxSheetValueProviderSparseStringTest::GetValue( const wxSheetCoords& coords_ ) const { wxCHECK_MSG(ContainsCell(coords_), wxEmptyString, wxT("Invalid coords")); wxSheetCoords coords(HasOption(wxSHEET_ValueProviderColPref) ? coords_ : coords_.GetSwapped()); ((wxSheetValueProviderSparseStringTest*)this)->m_intArrayIntString.m_key = coords.m_row; const int rowPos = m_data.Index((wxSheetIntArrayIntString*)&m_intArrayIntString); // const int rowPos = m_data.Index(wxSheetIntArrayIntString(coords.m_row)); if (rowPos != wxNOT_FOUND) { ((wxSheetValueProviderSparseStringTest*)this)->m_intString.m_key = coords.m_col; const int colPos = m_data[rowPos].m_value->Index((wxSheetIntString*)&m_intString); //const int colPos = m_data[rowPos].m_value.Index(wxSheetIntString(coords.m_col)); if (colPos != wxNOT_FOUND) return m_data[rowPos].m_value->Item(colPos).m_value; } return wxEmptyString; }
void wxSheetValueProviderBase::Copy(const wxSheetValueProviderBase& other) { Clear(); const int numRows = other.GetNumberRows(); const int numCols = other.GetNumberCols(); SetOptions(other.GetOptions()); UpdateRows(0, numRows); UpdateCols(0, numCols); wxSheetCoords c; bool allow_empty = HasOption(wxSHEET_ValueProviderAllowEmpty); for (c.m_row = 0; c.m_row < numRows; c.m_row++) { for (c.m_col = 0; c.m_col < numCols; c.m_col++) { wxString val(other.GetValue(c)); if (allow_empty || !val.IsEmpty()) SetValue(c, val); } } }
void wxSheetValueProviderString::SetValue( const wxSheetCoords& coords_, const wxString& value ) { wxCHECK_RET(ContainsCell(coords_), wxT("Invalid coords")); wxSheetCoords coords(HasOption(wxSHEET_ValueProviderColPref) ? coords_ : coords_.GetSwapped()); // add "rows" as necessary to store value int count = m_data.GetCount(); if (count <= coords.m_row) { wxArrayString sa; sa.Add( wxEmptyString, 1+coords.m_col ); m_data.Insert( sa, count, 1+coords.m_row-count ); } else // believe it or not - NOT having this else statement is 10% faster in gcc { // add "cols" as necessary to store value count = m_data[coords.m_row].GetCount(); if (count <= coords.m_col) { m_data.Item(coords.m_row).Insert( wxEmptyString, count, 1+coords.m_col-count ); } } m_data[coords.m_row][coords.m_col] = value; }
wxSheetValueProviderString::wxSheetValueProviderString(size_t numRows, size_t numCols, int options) :wxSheetValueProviderBase(numRows, numCols, options) { DoUpdateRows(0, HasOption(wxSHEET_ValueProviderColPref) ? numRows : numCols); DoUpdateCols(0, HasOption(wxSHEET_ValueProviderColPref) ? numCols : numRows); }
void ProjectOptionsManipulator::ProcessLinkerLibs(cbProject* prj, const wxString& lib, const wxString& lib_new, wxArrayString& result) { ProjectOptionsManipulatorDlg::EProjectScanOption scan_opt = m_Dlg->GetScanOption(); switch (scan_opt) { case ProjectOptionsManipulatorDlg::eSearch: case ProjectOptionsManipulatorDlg::eSearchNot: { if ( m_Dlg->GetOptionActive(ProjectOptionsManipulatorDlg::eProject) ) { bool has_opt = HasOption(prj->GetLinkLibs(), lib); if (has_opt && scan_opt==ProjectOptionsManipulatorDlg::eSearch) { result.Add(wxString::Format(_("Project '%s': Contains linker lib '%s'."), prj->GetTitle().wx_str(), lib.wx_str())); } else if (!has_opt && scan_opt==ProjectOptionsManipulatorDlg::eSearchNot) { result.Add(wxString::Format(_("Project '%s': Does not contain linker lib '%s'."), prj->GetTitle().wx_str(), lib.wx_str())); } } if ( m_Dlg->GetOptionActive(ProjectOptionsManipulatorDlg::eTarget) ) { for (int i=0; i<prj->GetBuildTargetsCount(); ++i) { ProjectBuildTarget* tgt = prj->GetBuildTarget(i); if (tgt) { bool has_opt = HasOption(tgt->GetLinkLibs(), lib); if (has_opt && scan_opt==ProjectOptionsManipulatorDlg::eSearch) { result.Add(wxString::Format(_("Project '%s', target '%s': Contains linker lib '%s'."), prj->GetTitle().wx_str(), tgt->GetTitle().wx_str(), lib.wx_str())); } else if (!has_opt && scan_opt==ProjectOptionsManipulatorDlg::eSearchNot) { result.Add(wxString::Format(_("Project '%s', target '%s': Does not contain linker lib '%s'."), prj->GetTitle().wx_str(), tgt->GetTitle().wx_str(), lib.wx_str())); } } } } } break; case ProjectOptionsManipulatorDlg::eRemove: { wxString full_lib; if ( m_Dlg->GetOptionActive(ProjectOptionsManipulatorDlg::eProject) ) { if ( HasOption(prj->GetLinkLibs(), lib, full_lib) ) prj->RemoveLinkLib(full_lib); } if ( m_Dlg->GetOptionActive(ProjectOptionsManipulatorDlg::eTarget) ) { for (int i=0; i<prj->GetBuildTargetsCount(); ++i) { ProjectBuildTarget* tgt = prj->GetBuildTarget(i); if (tgt && HasOption(tgt->GetLinkLibs(), lib, full_lib)) tgt->RemoveLinkLib(lib); } } } break; case ProjectOptionsManipulatorDlg::eAdd: { if ( m_Dlg->GetOptionActive(ProjectOptionsManipulatorDlg::eProject) ) { if ( !HasOption(prj->GetLinkLibs(), lib) ) prj->AddLinkLib(lib); } if ( m_Dlg->GetOptionActive(ProjectOptionsManipulatorDlg::eTarget) ) { for (int i=0; i<prj->GetBuildTargetsCount(); ++i) { ProjectBuildTarget* tgt = prj->GetBuildTarget(i); if (tgt && !HasOption(tgt->GetLinkLibs(), lib)) tgt->AddLinkLib(lib); } } } break; case ProjectOptionsManipulatorDlg::eReplace: { wxString full_lib; if ( m_Dlg->GetOptionActive(ProjectOptionsManipulatorDlg::eProject) ) { if ( HasOption(prj->GetLinkLibs(), lib, full_lib) ) prj->ReplaceLinkLib(full_lib, ManipulateOption(full_lib, lib, lib_new)); } if ( m_Dlg->GetOptionActive(ProjectOptionsManipulatorDlg::eTarget) ) { for (int i=0; i<prj->GetBuildTargetsCount(); ++i) { ProjectBuildTarget* tgt = prj->GetBuildTarget(i); if (tgt && HasOption(tgt->GetLinkLibs(), lib, full_lib)) tgt->ReplaceLinkLib(full_lib, ManipulateOption(full_lib, lib, lib_new)); } } } break; case ProjectOptionsManipulatorDlg::eFiles: // fall-through default: break; } }
void ProjectOptionsManipulator::ProcessResCompPaths(cbProject* prj, const wxString& path, const wxString& path_new, wxArrayString& result) { ProjectOptionsManipulatorDlg::EProjectScanOption scan_opt = m_Dlg->GetScanOption(); switch (scan_opt) { case ProjectOptionsManipulatorDlg::eSearch: case ProjectOptionsManipulatorDlg::eSearchNot: { if ( m_Dlg->GetOptionActive(ProjectOptionsManipulatorDlg::eProject) ) { bool has_opt = HasOption(prj->GetResourceIncludeDirs(), path); if (has_opt && scan_opt==ProjectOptionsManipulatorDlg::eSearch) { result.Add(wxString::Format(_("Project '%s': Contains resource compiler path '%s'."), prj->GetTitle().wx_str(), path.wx_str())); } else if (!has_opt && scan_opt==ProjectOptionsManipulatorDlg::eSearchNot) { result.Add(wxString::Format(_("Project '%s': Does not contain resource compiler path '%s'."), prj->GetTitle().wx_str(), path.wx_str())); } } if ( m_Dlg->GetOptionActive(ProjectOptionsManipulatorDlg::eTarget) ) { for (int i=0; i<prj->GetBuildTargetsCount(); ++i) { ProjectBuildTarget* tgt = prj->GetBuildTarget(i); if (tgt) { bool has_opt = HasOption(tgt->GetResourceIncludeDirs(), path); if (has_opt && scan_opt==ProjectOptionsManipulatorDlg::eSearch) { result.Add(wxString::Format(_("Project '%s', target '%s': Contains resource compiler path '%s'."), prj->GetTitle().wx_str(), tgt->GetTitle().wx_str(), path.wx_str())); } else if (!has_opt && scan_opt==ProjectOptionsManipulatorDlg::eSearchNot) { result.Add(wxString::Format(_("Project '%s', target '%s': Does not contain resource compiler path '%s'."), prj->GetTitle().wx_str(), tgt->GetTitle().wx_str(), path.wx_str())); } } } } } break; case ProjectOptionsManipulatorDlg::eRemove: { wxString full_path; if ( m_Dlg->GetOptionActive(ProjectOptionsManipulatorDlg::eProject) ) { if ( HasOption(prj->GetResourceIncludeDirs(), path, full_path) ) prj->RemoveResourceIncludeDir(full_path); } if ( m_Dlg->GetOptionActive(ProjectOptionsManipulatorDlg::eTarget) ) { for (int i=0; i<prj->GetBuildTargetsCount(); ++i) { ProjectBuildTarget* tgt = prj->GetBuildTarget(i); if (tgt && HasOption(tgt->GetResourceIncludeDirs(), path, full_path)) tgt->RemoveResourceIncludeDir(path); } } } break; case ProjectOptionsManipulatorDlg::eAdd: { if ( m_Dlg->GetOptionActive(ProjectOptionsManipulatorDlg::eProject) ) { if ( !HasOption(prj->GetResourceIncludeDirs(), path) ) prj->AddResourceIncludeDir(path); } if ( m_Dlg->GetOptionActive(ProjectOptionsManipulatorDlg::eTarget) ) { for (int i=0; i<prj->GetBuildTargetsCount(); ++i) { ProjectBuildTarget* tgt = prj->GetBuildTarget(i); if (tgt && !HasOption(tgt->GetResourceIncludeDirs(), path)) tgt->AddResourceIncludeDir(path); } } } break; case ProjectOptionsManipulatorDlg::eReplace: { wxString full_path; if ( m_Dlg->GetOptionActive(ProjectOptionsManipulatorDlg::eProject) ) { if ( HasOption(prj->GetResourceIncludeDirs(), path, full_path) ) prj->ReplaceResourceIncludeDir(full_path, ManipulateOption(full_path, path, path_new)); } if ( m_Dlg->GetOptionActive(ProjectOptionsManipulatorDlg::eTarget) ) { for (int i=0; i<prj->GetBuildTargetsCount(); ++i) { ProjectBuildTarget* tgt = prj->GetBuildTarget(i); if (tgt && HasOption(tgt->GetResourceIncludeDirs(), path, full_path)) tgt->ReplaceResourceIncludeDir(full_path, ManipulateOption(full_path, path, path_new)); } } } break; case ProjectOptionsManipulatorDlg::eFiles: // fall-through default: break; } }
bool ProjectOptionsManipulator::HasOption(const wxArrayString& opt_array, const wxString& opt) { wxString dummy; return HasOption(opt_array, opt, dummy); }
u32 PPCAnalyzer::Analyze(u32 address, CodeBlock *block, CodeBuffer *buffer, u32 blockSize) { // Clear block stats memset(block->m_stats, 0, sizeof(BlockStats)); // Clear register stats block->m_gpa->any = true; block->m_fpa->any = false; block->m_gpa->Clear(); block->m_fpa->Clear(); // Set the blocks start address block->m_address = address; // Reset our block state block->m_broken = false; block->m_memory_exception = false; block->m_num_instructions = 0; if (address == 0) { // Memory exception occurred during instruction fetch block->m_memory_exception = true; return address; } if (SConfig::GetInstance().m_LocalCoreStartupParameter.bMMU && (address & JIT_ICACHE_VMEM_BIT)) { if (!Memory::TranslateAddress(address, Memory::FLAG_NO_EXCEPTION)) { // Memory exception occurred during instruction fetch block->m_memory_exception = true; return address; } } CodeOp *code = buffer->codebuffer; bool found_exit = false; u32 return_address = 0; u32 numFollows = 0; u32 num_inst = 0; for (u32 i = 0; i < blockSize; ++i) { UGeckoInstruction inst = JitInterface::ReadOpcodeJIT(address); if (inst.hex != 0) { num_inst++; memset(&code[i], 0, sizeof(CodeOp)); GekkoOPInfo *opinfo = GetOpInfo(inst); code[i].opinfo = opinfo; code[i].address = address; code[i].inst = inst; code[i].branchTo = -1; code[i].branchToIndex = -1; code[i].skip = false; block->m_stats->numCycles += opinfo->numCycles; SetInstructionStats(block, &code[i], opinfo, i); bool follow = false; u32 destination = 0; bool conditional_continue = false; // Do we inline leaf functions? if (HasOption(OPTION_LEAF_INLINE)) { if (inst.OPCD == 18 && blockSize > 1) { //Is bx - should we inline? yes! if (inst.AA) destination = SignExt26(inst.LI << 2); else destination = address + SignExt26(inst.LI << 2); if (destination != block->m_address) follow = true; } else if (inst.OPCD == 19 && inst.SUBOP10 == 16 && (inst.BO & (1 << 4)) && (inst.BO & (1 << 2)) && return_address != 0) { // bclrx with unconditional branch = return follow = true; destination = return_address; return_address = 0; if (inst.LK) return_address = address + 4; } else if (inst.OPCD == 31 && inst.SUBOP10 == 467) { // mtspr const u32 index = (inst.SPRU << 5) | (inst.SPRL & 0x1F); if (index == SPR_LR) { // We give up to follow the return address // because we have to check the register usage. return_address = 0; } } // TODO: Find the optimal value for FUNCTION_FOLLOWING_THRESHOLD. // If it is small, the performance will be down. // If it is big, the size of generated code will be big and // cache clearning will happen many times. // TODO: Investivate the reason why // "0" is fastest in some games, MP2 for example. if (numFollows > FUNCTION_FOLLOWING_THRESHOLD) follow = false; } if (HasOption(OPTION_CONDITIONAL_CONTINUE)) { if (inst.OPCD == 16 && ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0 || (inst.BO & BO_DONT_CHECK_CONDITION) == 0)) { // bcx with conditional branch conditional_continue = true; } else if (inst.OPCD == 19 && inst.SUBOP10 == 16 && ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0 || (inst.BO & BO_DONT_CHECK_CONDITION) == 0)) { // bclrx with conditional branch conditional_continue = true; } else if (inst.OPCD == 3 || (inst.OPCD == 31 && inst.SUBOP10 == 4)) { // tw/twi tests and raises an exception conditional_continue = true; } else if (inst.OPCD == 19 && inst.SUBOP10 == 528 && (inst.BO_2 & BO_DONT_CHECK_CONDITION) == 0) { // Rare bcctrx with conditional branch // Seen in NES games conditional_continue = true; } } if (!follow) { address += 4; if (!conditional_continue && opinfo->flags & FL_ENDBLOCK) //right now we stop early { found_exit = true; break; } } // XXX: We don't support inlining yet. #if 0 else { numFollows++; // We don't "code[i].skip = true" here // because bx may store a certain value to the link register. // Instead, we skip a part of bx in Jit**::bx(). address = destination; merged_addresses[size_of_merged_addresses++] = address; } #endif } else { // ISI exception or other critical memory exception occured (game over) ERROR_LOG(DYNA_REC, "Instruction hex was 0!"); break; } } block->m_num_instructions = num_inst; if (block->m_num_instructions > 1) ReorderInstructions(block->m_num_instructions, code); if ((!found_exit && num_inst > 0) || blockSize == 1) { // We couldn't find an exit block->m_broken = true; } // Scan for flag dependencies; assume the next block (or any branch that can leave the block) // wants flags, to be safe. bool wantsCR0 = true, wantsCR1 = true, wantsFPRF = true, wantsCA = true; BitSet32 fprInUse, gprInUse, gprInReg, fprInXmm; for (int i = block->m_num_instructions - 1; i >= 0; i--) { bool opWantsCR0 = code[i].wantsCR0; bool opWantsCR1 = code[i].wantsCR1; bool opWantsFPRF = code[i].wantsFPRF; bool opWantsCA = code[i].wantsCA; code[i].wantsCR0 = wantsCR0 || code[i].canEndBlock; code[i].wantsCR1 = wantsCR1 || code[i].canEndBlock; code[i].wantsFPRF = wantsFPRF || code[i].canEndBlock; code[i].wantsCA = wantsCA || code[i].canEndBlock; wantsCR0 |= opWantsCR0 || code[i].canEndBlock; wantsCR1 |= opWantsCR1 || code[i].canEndBlock; wantsFPRF |= opWantsFPRF || code[i].canEndBlock; wantsCA |= opWantsCA || code[i].canEndBlock; wantsCR0 &= !code[i].outputCR0 || opWantsCR0; wantsCR1 &= !code[i].outputCR1 || opWantsCR1; wantsFPRF &= !code[i].outputFPRF || opWantsFPRF; wantsCA &= !code[i].outputCA || opWantsCA; code[i].gprInUse = gprInUse; code[i].fprInUse = fprInUse; code[i].gprInReg = gprInReg; code[i].fprInXmm = fprInXmm; // TODO: if there's no possible endblocks or exceptions in between, tell the regcache // we can throw away a register if it's going to be overwritten later. gprInUse |= code[i].regsIn; gprInReg |= code[i].regsIn; fprInUse |= code[i].fregsIn; if (strncmp(code[i].opinfo->opname, "stfd", 4)) fprInXmm |= code[i].fregsIn; // For now, we need to count output registers as "used" though; otherwise the flush // will result in a redundant store (e.g. store to regcache, then store again to // the same location later). gprInUse |= code[i].regsOut; if (code[i].fregOut >= 0) fprInUse[code[i].fregOut] = true; } // Forward scan, for flags that need the other direction for calculation. BitSet32 fprIsSingle, fprIsDuplicated, fprIsStoreSafe; for (u32 i = 0; i < block->m_num_instructions; i++) { code[i].fprIsSingle = fprIsSingle; code[i].fprIsDuplicated = fprIsDuplicated; code[i].fprIsStoreSafe = fprIsStoreSafe; if (code[i].fregOut >= 0) { fprIsSingle[code[i].fregOut] = false; fprIsDuplicated[code[i].fregOut] = false; fprIsStoreSafe[code[i].fregOut] = false; // Single, duplicated, and doesn't need PPC_FP. if (code[i].opinfo->type == OPTYPE_SINGLEFP) { fprIsSingle[code[i].fregOut] = true; fprIsDuplicated[code[i].fregOut] = true; fprIsStoreSafe[code[i].fregOut] = true; } // Single and duplicated, but might be a denormal (not safe to skip PPC_FP). // TODO: if we go directly from a load to store, skip conversion entirely? // TODO: if we go directly from a load to a float instruction, and the value isn't used // for anything else, we can skip PPC_FP on a load too. if (!strncmp(code[i].opinfo->opname, "lfs", 3)) { fprIsSingle[code[i].fregOut] = true; fprIsDuplicated[code[i].fregOut] = true; } // Paired are still floats, but the top/bottom halves may differ. if (code[i].opinfo->type == OPTYPE_PS || code[i].opinfo->type == OPTYPE_LOADPS) { fprIsSingle[code[i].fregOut] = true; fprIsStoreSafe[code[i].fregOut] = true; } // Careful: changing the float mode in a block breaks this optimization, since // a previous float op might have had had FTZ off while the later store has FTZ // on. So, discard all information we have. if (!strncmp(code[i].opinfo->opname, "mtfs", 4)) fprIsStoreSafe = BitSet32(0); } } return address; }
void PPCAnalyzer::SetInstructionStats(CodeBlock *block, CodeOp *code, GekkoOPInfo *opinfo, u32 index) { code->wantsCR0 = false; code->wantsCR1 = false; if (opinfo->flags & FL_USE_FPU) block->m_fpa->any = true; if (opinfo->flags & FL_TIMER) block->m_gpa->anyTimer = true; // Does the instruction output CR0? if (opinfo->flags & FL_RC_BIT) code->outputCR0 = code->inst.hex & 1; //todo fix else if ((opinfo->flags & FL_SET_CRn) && code->inst.CRFD == 0) code->outputCR0 = true; else code->outputCR0 = (opinfo->flags & FL_SET_CR0) ? true : false; // Does the instruction output CR1? if (opinfo->flags & FL_RC_BIT_F) code->outputCR1 = code->inst.hex & 1; //todo fix else if ((opinfo->flags & FL_SET_CRn) && code->inst.CRFD == 1) code->outputCR1 = true; else code->outputCR1 = (opinfo->flags & FL_SET_CR1) ? true : false; code->wantsFPRF = (opinfo->flags & FL_READ_FPRF) ? true : false; code->outputFPRF = (opinfo->flags & FL_SET_FPRF) ? true : false; code->canEndBlock = (opinfo->flags & FL_ENDBLOCK) ? true : false; code->wantsCA = (opinfo->flags & FL_READ_CA) ? true : false; code->outputCA = (opinfo->flags & FL_SET_CA) ? true : false; // We're going to try to avoid storing carry in XER if we can avoid it -- keep it in the x86 carry flag! // If the instruction reads CA but doesn't write it, we still need to store CA in XER; we can't // leave it in flags. if (HasOption(OPTION_CARRY_MERGE)) code->wantsCAInFlags = code->wantsCA && code->outputCA && opinfo->type == OPTYPE_INTEGER; else code->wantsCAInFlags = false; // mfspr/mtspr can affect/use XER, so be super careful here // we need to note specifically that mfspr needs CA in XER, not in the x86 carry flag if (code->inst.OPCD == 31 && code->inst.SUBOP10 == 339) // mfspr code->wantsCA = ((code->inst.SPRU << 5) | (code->inst.SPRL & 0x1F)) == SPR_XER; if (code->inst.OPCD == 31 && code->inst.SUBOP10 == 467) // mtspr code->outputCA = ((code->inst.SPRU << 5) | (code->inst.SPRL & 0x1F)) == SPR_XER; code->regsIn = BitSet32(0); code->regsOut = BitSet32(0); if (opinfo->flags & FL_OUT_A) { code->regsOut[code->inst.RA] = true; block->m_gpa->SetOutputRegister(code->inst.RA, index); } if (opinfo->flags & FL_OUT_D) { code->regsOut[code->inst.RD] = true; block->m_gpa->SetOutputRegister(code->inst.RD, index); } if (opinfo->flags & FL_OUT_S) { code->regsOut[code->inst.RS] = true; block->m_gpa->SetOutputRegister(code->inst.RS, index); } if ((opinfo->flags & FL_IN_A) || ((opinfo->flags & FL_IN_A0) && code->inst.RA != 0)) { code->regsIn[code->inst.RA] = true; block->m_gpa->SetInputRegister(code->inst.RA, index); } if (opinfo->flags & FL_IN_B) { code->regsIn[code->inst.RB] = true; block->m_gpa->SetInputRegister(code->inst.RB, index); } if (opinfo->flags & FL_IN_C) { code->regsIn[code->inst.RC] = true; block->m_gpa->SetInputRegister(code->inst.RC, index); } if (opinfo->flags & FL_IN_S) { code->regsIn[code->inst.RS] = true; block->m_gpa->SetInputRegister(code->inst.RS, index); } if (code->inst.OPCD == 46) // lmw { for (int iReg = code->inst.RD; iReg < 32; ++iReg) { code->regsOut[iReg] = true; block->m_gpa->SetOutputRegister(iReg, index); } } else if (code->inst.OPCD == 47) //stmw { for (int iReg = code->inst.RS; iReg < 32; ++iReg) { code->regsIn[iReg] = true; block->m_gpa->SetInputRegister(iReg, index); } } code->fregOut = -1; if (opinfo->flags & FL_OUT_FLOAT_D) code->fregOut = code->inst.FD; else if (opinfo->flags & FL_OUT_FLOAT_S) code->fregOut = code->inst.FS; code->fregsIn = BitSet32(0); if (opinfo->flags & FL_IN_FLOAT_A) code->fregsIn[code->inst.FA] = true; if (opinfo->flags & FL_IN_FLOAT_B) code->fregsIn[code->inst.FB] = true; if (opinfo->flags & FL_IN_FLOAT_C) code->fregsIn[code->inst.FC] = true; if (opinfo->flags & FL_IN_FLOAT_D) code->fregsIn[code->inst.FD] = true; if (opinfo->flags & FL_IN_FLOAT_S) code->fregsIn[code->inst.FS] = true; switch (opinfo->type) { case OPTYPE_INTEGER: case OPTYPE_LOAD: case OPTYPE_STORE: case OPTYPE_LOADFP: case OPTYPE_STOREFP: break; case OPTYPE_SINGLEFP: case OPTYPE_DOUBLEFP: break; case OPTYPE_BRANCH: if (code->inst.hex == 0x4e800020) { // For analysis purposes, we can assume that blr eats opinfo->flags. code->outputCR0 = true; code->outputCR1 = true; } break; case OPTYPE_SYSTEM: case OPTYPE_SYSTEMFP: break; } }
status_t AbstractSingleFileServerProcess::RunInternal() { if (Logger::IsInfoEnabled()) printf("[%s] will fetch data\n", Name()); BPath localPath; status_t result = GetLocalPath(localPath); if (result != B_OK) return result; BString urlPathComponent = UrlPathComponent(); if (IsSuccess(result) && HasOption(SERVER_PROCESS_DROP_CACHE)) result = DeleteLocalFile(localPath); bool hasData = false; off_t size; if (IsSuccess(result)) result = StorageUtils::ExistsObject(localPath, &hasData, NULL, &size); hasData = hasData && size > 0; if (IsSuccess(result) && ShouldAttemptNetworkDownload(hasData)) { result = DownloadToLocalFileAtomically( localPath, ServerSettings::CreateFullUrl(urlPathComponent)); if (!IsSuccess(result)) { if (hasData) { printf("[%s] failed to update data, but have old data " "anyway so carry on with that\n", Name()); result = B_OK; } else { printf("[%s] failed to obtain data\n", Name()); } } else { if (Logger::IsInfoEnabled()) printf("[%s] did fetch data\n", Name()); } } if (IsSuccess(result)) { status_t hasDataResult = StorageUtils::ExistsObject( localPath, &hasData, NULL, &size); hasData = hasData && size > 0; if (hasDataResult == B_OK && !hasData) result = HD_ERR_NO_DATA; } if (IsSuccess(result)) { printf("[%s] will process data\n", Name()); result = ProcessLocalData(); switch (result) { case B_OK: printf("[%s] did process data\n", Name()); break; default: MoveDamagedFileAside(localPath); break; } } return result; }
bool OptionDict::HasMultiOption(const wxString& key) const { MultiDict::const_iterator valP = m_multiDict.find(key); return (valP != m_multiDict.end() || HasOption(key)); }
void DwUseOptions::ThrowIfHasValue(string name) { if( HasOption(name) && GetOption(name) != "" ) throw DwUseException( "Invalid value for '"+name+"': " + GetOption(name) ); }