Beispiel #1
0
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);
    }
}
Beispiel #2
0
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);
}
Beispiel #3
0
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);
}
Beispiel #4
0
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;
}
Beispiel #5
0
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));
    }
}
Beispiel #6
0
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);
}
Beispiel #7
0
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;
}
Beispiel #9
0
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;
}
Beispiel #10
0
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;
}
Beispiel #11
0
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;
}
Beispiel #12
0
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;
}
Beispiel #13
0
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;
}
Beispiel #14
0
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;
}
Beispiel #15
0
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);
        }
    }
}
Beispiel #16
0
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;
}
Beispiel #17
0
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);
}
Beispiel #21
0
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;
}
Beispiel #22
0
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;
}
Beispiel #24
0
bool OptionDict::HasMultiOption(const wxString& key) const {
	MultiDict::const_iterator valP = m_multiDict.find(key);
	
	return (valP != m_multiDict.end() || HasOption(key));
}
Beispiel #25
0
void DwUseOptions::ThrowIfHasValue(string name) {
	if( HasOption(name) && GetOption(name) != "" )
		throw DwUseException( "Invalid value for '"+name+"': " + GetOption(name) ); 
}