mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-28 18:33:14 +00:00
Merge branch 'master' into jit_exit_addresses
This commit is contained in:
commit
ea9ac07ec9
@ -524,11 +524,16 @@ else()
|
|||||||
set(LZO lzo2)
|
set(LZO lzo2)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(ANDROID)
|
if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT ANDROID)
|
||||||
|
check_lib(PNG png png.h QUIET)
|
||||||
|
endif()
|
||||||
|
if (PNG_FOUND)
|
||||||
|
message("Using shared libpng")
|
||||||
|
else()
|
||||||
message("Using static libpng from Externals")
|
message("Using static libpng from Externals")
|
||||||
add_subdirectory(Externals/libpng)
|
add_subdirectory(Externals/libpng)
|
||||||
include_directories(Externals/libpng)
|
include_directories(Externals/libpng)
|
||||||
set(PNG libpng)
|
set(PNG png)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(OPENAL_FOUND)
|
if(OPENAL_FOUND)
|
||||||
|
2
Externals/wxWidgets3/CMakeLists.txt
vendored
2
Externals/wxWidgets3/CMakeLists.txt
vendored
@ -868,8 +868,6 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
|||||||
${SRCS_GENERICOSX}
|
${SRCS_GENERICOSX}
|
||||||
${SRCS_OSX}
|
${SRCS_OSX}
|
||||||
${SRCS_UNIX})
|
${SRCS_UNIX})
|
||||||
include_directories(../libpng)
|
|
||||||
add_subdirectory(../libpng ../libpng)
|
|
||||||
set(LIBS
|
set(LIBS
|
||||||
png
|
png
|
||||||
iconv
|
iconv
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<item
|
<item
|
||||||
android:id="@+id/saveStateRoot"
|
android:id="@+id/takeScreenshot"
|
||||||
android:showAsAction="ifRoom"
|
android:showAsAction="ifRoom"
|
||||||
|
android:title="@string/overlay_screenshot"/>
|
||||||
|
<item
|
||||||
|
android:id="@+id/saveStateRoot"
|
||||||
|
android:showAsAction="never"
|
||||||
android:title="@string/overlay_savestate">
|
android:title="@string/overlay_savestate">
|
||||||
<menu>
|
<menu>
|
||||||
<item android:id="@+id/saveSlot1"
|
<item android:id="@+id/saveSlot1"
|
||||||
@ -23,7 +27,7 @@
|
|||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/loadStateRoot"
|
android:id="@+id/loadStateRoot"
|
||||||
android:showAsAction="ifRoom"
|
android:showAsAction="never"
|
||||||
android:title="@string/overlay_loadstate">
|
android:title="@string/overlay_loadstate">
|
||||||
<menu>
|
<menu>
|
||||||
<item android:id="@+id/loadSlot1"
|
<item android:id="@+id/loadSlot1"
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
<!-- About Fragment -->
|
<!-- About Fragment -->
|
||||||
<string name="build_revision">ビルドのバージョン</string>
|
<string name="build_revision">ビルドのバージョン</string>
|
||||||
<string name="supports_gles3">サポートのOpenGL ES 3</string>
|
<string name="supports_gles3">サポートのOpenGL ES 3</string>
|
||||||
|
<string name="supports_neon">サポートのNEON</string>
|
||||||
|
|
||||||
<!-- Folder Browser -->
|
<!-- Folder Browser -->
|
||||||
<string name="current_dir">現在のディレクトリ: %1$s</string>
|
<string name="current_dir">現在のディレクトリ: %1$s</string>
|
||||||
@ -25,10 +26,15 @@
|
|||||||
<string name="settings">設定</string>
|
<string name="settings">設定</string>
|
||||||
<string name="about">について</string>
|
<string name="about">について</string>
|
||||||
|
|
||||||
|
<!-- Game List Activity - Device Compatibility AlertDialog -->
|
||||||
|
<string name="device_compat_warning">デバイスの互換性の警告</string>
|
||||||
|
<string name="device_compat_warning_msg">この電話は、NEON拡張をサポートしていません。 おそらくDolphinを実行することはできません。\nあなたはとにかくそれを実行してみますか?</string>
|
||||||
|
|
||||||
<!-- Game List Fragment -->
|
<!-- Game List Fragment -->
|
||||||
<string name="file_clicked">クリックされたファイル: %1$s</string>
|
<string name="file_clicked">クリックされたファイル: %1$s</string>
|
||||||
|
|
||||||
<!-- Emulation Window Overlay -->
|
<!-- Emulation Window Overlay -->
|
||||||
|
<string name="overlay_screenshot">スクリーンショットを撮る</string>
|
||||||
<string name="overlay_savestate">ステートセーブ</string>
|
<string name="overlay_savestate">ステートセーブ</string>
|
||||||
<string name="overlay_loadstate">ステートロード</string>
|
<string name="overlay_loadstate">ステートロード</string>
|
||||||
<string name="overlay_exit_emulation">終了</string>
|
<string name="overlay_exit_emulation">終了</string>
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
<!-- About Fragment -->
|
<!-- About Fragment -->
|
||||||
<string name="build_revision">Build Revision</string>
|
<string name="build_revision">Build Revision</string>
|
||||||
<string name="supports_gles3">Supports OpenGL ES 3</string>
|
<string name="supports_gles3">Supports OpenGL ES 3</string>
|
||||||
|
<string name="supports_neon">Supports NEON</string>
|
||||||
|
|
||||||
<!-- Folder Browser -->
|
<!-- Folder Browser -->
|
||||||
<string name="current_dir">Current Dir: %1$s</string>
|
<string name="current_dir">Current Dir: %1$s</string>
|
||||||
@ -25,10 +26,15 @@
|
|||||||
<string name="settings">Settings</string>
|
<string name="settings">Settings</string>
|
||||||
<string name="about">About</string>
|
<string name="about">About</string>
|
||||||
|
|
||||||
|
<!-- Game List Activity - Device Compatibility AlertDialog -->
|
||||||
|
<string name="device_compat_warning">Device Compatibility Warning</string>
|
||||||
|
<string name="device_compat_warning_msg">Your phone doesn\'t support NEON which makes it incapable of running Dolphin Mobile?\nDo you want to try anyway?</string>
|
||||||
|
|
||||||
<!-- Game List Fragment -->
|
<!-- Game List Fragment -->
|
||||||
<string name="file_clicked">File clicked: %1$s</string>
|
<string name="file_clicked">File clicked: %1$s</string>
|
||||||
|
|
||||||
<!-- Emulation Overlay -->
|
<!-- Emulation Overlay -->
|
||||||
|
<string name="overlay_screenshot">Take Screenshot</string>
|
||||||
<string name="overlay_savestate">Save State</string>
|
<string name="overlay_savestate">Save State</string>
|
||||||
<string name="overlay_loadstate">Load State</string>
|
<string name="overlay_loadstate">Load State</string>
|
||||||
<string name="overlay_exit_emulation">Exit</string>
|
<string name="overlay_exit_emulation">Exit</string>
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
package org.dolphinemu.dolphinemu;
|
package org.dolphinemu.dolphinemu;
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.ListFragment;
|
import android.app.ListFragment;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@ -27,35 +26,24 @@ import org.dolphinemu.dolphinemu.settings.VideoSettingsFragment;
|
|||||||
*/
|
*/
|
||||||
public final class AboutFragment extends ListFragment
|
public final class AboutFragment extends ListFragment
|
||||||
{
|
{
|
||||||
private static Activity m_activity;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
|
||||||
{
|
{
|
||||||
View rootView = inflater.inflate(R.layout.gamelist_listview, container, false);
|
ListView rootView = (ListView) inflater.inflate(R.layout.gamelist_listview, container, false);
|
||||||
ListView mMainList = (ListView) rootView.findViewById(R.id.gamelist);
|
|
||||||
|
|
||||||
String yes = getString(R.string.yes);
|
final String yes = getString(R.string.yes);
|
||||||
String no = getString(R.string.no);
|
final String no = getString(R.string.no);
|
||||||
|
|
||||||
List<AboutFragmentItem> Input = new ArrayList<AboutFragmentItem>();
|
List<AboutFragmentItem> Input = new ArrayList<AboutFragmentItem>();
|
||||||
Input.add(new AboutFragmentItem(getString(R.string.build_revision), NativeLibrary.GetVersionString()));
|
Input.add(new AboutFragmentItem(getString(R.string.build_revision), NativeLibrary.GetVersionString()));
|
||||||
Input.add(new AboutFragmentItem(getString(R.string.supports_gles3), VideoSettingsFragment.SupportsGLES3() ? yes : no));
|
Input.add(new AboutFragmentItem(getString(R.string.supports_gles3), VideoSettingsFragment.SupportsGLES3() ? yes : no));
|
||||||
|
Input.add(new AboutFragmentItem(getString(R.string.supports_neon), NativeLibrary.SupportsNEON() ? yes : no));
|
||||||
|
|
||||||
AboutFragmentAdapter adapter = new AboutFragmentAdapter(m_activity, R.layout.about_layout, Input);
|
AboutFragmentAdapter adapter = new AboutFragmentAdapter(getActivity(), R.layout.about_layout, Input);
|
||||||
mMainList.setAdapter(adapter);
|
rootView.setAdapter(adapter);
|
||||||
mMainList.setEnabled(false); // Makes the list view non-clickable.
|
rootView.setEnabled(false); // Makes the list view non-clickable.
|
||||||
|
|
||||||
return mMainList;
|
return rootView;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAttach(Activity activity)
|
|
||||||
{
|
|
||||||
super.onAttach(activity);
|
|
||||||
|
|
||||||
// Cache the activity instance.
|
|
||||||
m_activity = activity;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Represents an item in the AboutFragment.
|
// Represents an item in the AboutFragment.
|
||||||
@ -106,18 +94,17 @@ public final class AboutFragment extends ListFragment
|
|||||||
@Override
|
@Override
|
||||||
public View getView(int position, View convertView, ViewGroup parent)
|
public View getView(int position, View convertView, ViewGroup parent)
|
||||||
{
|
{
|
||||||
View v = convertView;
|
if (convertView == null)
|
||||||
if (v == null)
|
|
||||||
{
|
{
|
||||||
LayoutInflater vi = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
LayoutInflater vi = LayoutInflater.from(ctx);
|
||||||
v = vi.inflate(id, parent, false);
|
convertView = vi.inflate(id, parent, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
final AboutFragmentItem item = items.get(position);
|
final AboutFragmentItem item = items.get(position);
|
||||||
if (item != null)
|
if (item != null)
|
||||||
{
|
{
|
||||||
TextView title = (TextView) v.findViewById(R.id.AboutItemTitle);
|
TextView title = (TextView) convertView.findViewById(R.id.AboutItemTitle);
|
||||||
TextView subtitle = (TextView) v.findViewById(R.id.AboutItemSubTitle);
|
TextView subtitle = (TextView) convertView.findViewById(R.id.AboutItemSubTitle);
|
||||||
|
|
||||||
if (title != null)
|
if (title != null)
|
||||||
title.setText(item.getTitle());
|
title.setText(item.getTitle());
|
||||||
@ -126,7 +113,7 @@ public final class AboutFragment extends ListFragment
|
|||||||
subtitle.setText(item.getSubTitle());
|
subtitle.setText(item.getSubTitle());
|
||||||
}
|
}
|
||||||
|
|
||||||
return v;
|
return convertView;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,4 +86,9 @@ public final class DolphinEmulator extends Activity
|
|||||||
UserPreferences.LoadIniToPrefs(this);
|
UserPreferences.LoadIniToPrefs(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
protected void onRestart()
|
||||||
|
{
|
||||||
|
super.onRestart();
|
||||||
|
finish(); // If we are ever returning to this activity then we are exiting.
|
||||||
|
}
|
||||||
}
|
}
|
@ -104,6 +104,19 @@ public final class NativeLibrary
|
|||||||
*/
|
*/
|
||||||
public static native String GetVersionString();
|
public static native String GetVersionString();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns if the phone supports NEON or not
|
||||||
|
*
|
||||||
|
* @return true if it supports NEON, false otherwise.
|
||||||
|
*/
|
||||||
|
public static native boolean SupportsNEON();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves a screen capture of the game
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static native void SaveScreenShot();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves a game state to the slot number.
|
* Saves a game state to the slot number.
|
||||||
*
|
*
|
||||||
|
@ -68,12 +68,14 @@ public final class EmulationActivity extends Activity
|
|||||||
|
|
||||||
// Due to a bug in Adreno, it renders the screen rotated 90 degrees when using OpenGL
|
// Due to a bug in Adreno, it renders the screen rotated 90 degrees when using OpenGL
|
||||||
// Flip the width and height when on Adreno to work around this.
|
// Flip the width and height when on Adreno to work around this.
|
||||||
|
// This bug is fixed in Qualcomm driver v53
|
||||||
// Mali isn't affected by this bug.
|
// Mali isn't affected by this bug.
|
||||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
if (prefs.getString("gpuPref", "Software Rendering").equals("OGL")
|
if (prefs.getString("gpuPref", "Software Rendering").equals("OGL")
|
||||||
&& VideoSettingsFragment.SupportsGLES3()
|
&& VideoSettingsFragment.SupportsGLES3()
|
||||||
&& VideoSettingsFragment.m_GLVendor != null
|
&& VideoSettingsFragment.m_GLVendor != null
|
||||||
&& VideoSettingsFragment.m_GLVendor.equals("Qualcomm"))
|
&& VideoSettingsFragment.m_GLVendor.equals("Qualcomm")
|
||||||
|
&& VideoSettingsFragment.m_QualcommVersion < 53.0f)
|
||||||
NativeLibrary.SetDimensions((int)screenHeight, (int)screenWidth);
|
NativeLibrary.SetDimensions((int)screenHeight, (int)screenWidth);
|
||||||
else
|
else
|
||||||
NativeLibrary.SetDimensions((int)screenWidth, (int)screenHeight);
|
NativeLibrary.SetDimensions((int)screenWidth, (int)screenHeight);
|
||||||
@ -173,6 +175,11 @@ public final class EmulationActivity extends Activity
|
|||||||
{
|
{
|
||||||
switch(item.getItemId())
|
switch(item.getItemId())
|
||||||
{
|
{
|
||||||
|
// Screenshot capturing
|
||||||
|
case R.id.takeScreenshot:
|
||||||
|
NativeLibrary.SaveScreenShot();
|
||||||
|
return true;
|
||||||
|
|
||||||
// Save state slots
|
// Save state slots
|
||||||
case R.id.saveSlot1:
|
case R.id.saveSlot1:
|
||||||
NativeLibrary.SaveState(0);
|
NativeLibrary.SaveState(0);
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
package org.dolphinemu.dolphinemu.folderbrowser;
|
package org.dolphinemu.dolphinemu.folderbrowser;
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.ListFragment;
|
import android.app.ListFragment;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
@ -37,16 +36,18 @@ import org.dolphinemu.dolphinemu.gamelist.GameListActivity;
|
|||||||
*/
|
*/
|
||||||
public final class FolderBrowser extends ListFragment
|
public final class FolderBrowser extends ListFragment
|
||||||
{
|
{
|
||||||
private Activity m_activity;
|
|
||||||
private FolderBrowserAdapter adapter;
|
private FolderBrowserAdapter adapter;
|
||||||
private ListView mFolderBrowserList;
|
|
||||||
private ListView rootView;
|
|
||||||
private static File currentDir = null;
|
private static File currentDir = null;
|
||||||
|
|
||||||
// Populates the FolderView with the given currDir's contents.
|
// Populates the FolderView with the given currDir's contents.
|
||||||
private void Fill(File currDir)
|
private void Fill(File currDir)
|
||||||
{
|
{
|
||||||
m_activity.setTitle(String.format(getString(R.string.current_dir), currDir.getName()));
|
// Clear the adapter of previous items.
|
||||||
|
adapter.clear();
|
||||||
|
|
||||||
|
// Set the activity title to the current directory the FolderBrowser is in.
|
||||||
|
getActivity().setTitle(String.format(getString(R.string.current_dir), currDir.getName()));
|
||||||
|
|
||||||
File[] dirs = currDir.listFiles();
|
File[] dirs = currDir.listFiles();
|
||||||
List<FolderBrowserItem> dir = new ArrayList<FolderBrowserItem>();
|
List<FolderBrowserItem> dir = new ArrayList<FolderBrowserItem>();
|
||||||
List<FolderBrowserItem> fls = new ArrayList<FolderBrowserItem>();
|
List<FolderBrowserItem> fls = new ArrayList<FolderBrowserItem>();
|
||||||
@ -96,9 +97,9 @@ public final class FolderBrowser extends ListFragment
|
|||||||
if (!currDir.getPath().equalsIgnoreCase("/"))
|
if (!currDir.getPath().equalsIgnoreCase("/"))
|
||||||
dir.add(0, new FolderBrowserItem("..", getString(R.string.parent_directory), currDir.getParent()));
|
dir.add(0, new FolderBrowserItem("..", getString(R.string.parent_directory), currDir.getParent()));
|
||||||
|
|
||||||
adapter = new FolderBrowserAdapter(m_activity, R.layout.gamelist_folderbrowser_list, dir);
|
// Add the items to the adapter and notify the adapter users of its new contents.
|
||||||
mFolderBrowserList = (ListView) rootView.findViewById(R.id.gamelist);
|
adapter.addAll(dir);
|
||||||
mFolderBrowserList.setAdapter(adapter);
|
adapter.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -122,22 +123,14 @@ public final class FolderBrowser extends ListFragment
|
|||||||
if(currentDir == null)
|
if(currentDir == null)
|
||||||
currentDir = new File(Environment.getExternalStorageDirectory().getPath());
|
currentDir = new File(Environment.getExternalStorageDirectory().getPath());
|
||||||
|
|
||||||
rootView = (ListView) inflater.inflate(R.layout.gamelist_listview, container, false);
|
ListView rootView = (ListView) inflater.inflate(R.layout.gamelist_listview, container, false);
|
||||||
|
adapter = new FolderBrowserAdapter(getActivity(), R.layout.gamelist_folderbrowser_list_item);
|
||||||
|
rootView.setAdapter(adapter);
|
||||||
|
|
||||||
Fill(currentDir);
|
Fill(currentDir);
|
||||||
return mFolderBrowserList;
|
return rootView;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAttach(Activity activity)
|
|
||||||
{
|
|
||||||
super.onAttach(activity);
|
|
||||||
|
|
||||||
// Cache the activity instance.
|
|
||||||
m_activity = activity;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void FolderSelected()
|
private void FolderSelected()
|
||||||
{
|
{
|
||||||
String Directories = NativeLibrary.GetConfig("Dolphin.ini", "General", "GCMPathes", "0");
|
String Directories = NativeLibrary.GetConfig("Dolphin.ini", "General", "GCMPathes", "0");
|
||||||
@ -168,6 +161,6 @@ public final class FolderBrowser extends ListFragment
|
|||||||
NativeLibrary.SetConfig("Dolphin.ini", "General", "GCMPath" + Integer.toString(intDirectories), currentDir.getPath());
|
NativeLibrary.SetConfig("Dolphin.ini", "General", "GCMPath" + Integer.toString(intDirectories), currentDir.getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
((GameListActivity)m_activity).SwitchPage(0);
|
((GameListActivity)getActivity()).SwitchPage(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,15 +6,12 @@
|
|||||||
|
|
||||||
package org.dolphinemu.dolphinemu.folderbrowser;
|
package org.dolphinemu.dolphinemu.folderbrowser;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.dolphinemu.dolphinemu.R;
|
import org.dolphinemu.dolphinemu.R;
|
||||||
@ -27,79 +24,89 @@ import org.dolphinemu.dolphinemu.R;
|
|||||||
*/
|
*/
|
||||||
public final class FolderBrowserAdapter extends ArrayAdapter<FolderBrowserItem>
|
public final class FolderBrowserAdapter extends ArrayAdapter<FolderBrowserItem>
|
||||||
{
|
{
|
||||||
|
// ViewHolder which is used to hold onto
|
||||||
|
// items within a listview. This is done
|
||||||
|
// so that findViewById is not needed to
|
||||||
|
// be excessively called over and over.
|
||||||
|
private static final class ViewHolder
|
||||||
|
{
|
||||||
|
TextView title;
|
||||||
|
TextView subtitle;
|
||||||
|
ImageView icon;
|
||||||
|
}
|
||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private final int id;
|
private final int id;
|
||||||
private final List<FolderBrowserItem> items;
|
private ViewHolder viewHolder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param context The current {@link Context}.
|
* @param context The current {@link Context}.
|
||||||
* @param resourceId The resource ID for a layout file containing a layout to use when instantiating views.
|
* @param resourceId The resource ID for a layout file containing a layout to use when instantiating views.
|
||||||
* @param objects The objects to represent in the {@link ListView}.
|
|
||||||
*/
|
*/
|
||||||
public FolderBrowserAdapter(Context context, int resourceId, List<FolderBrowserItem> objects)
|
public FolderBrowserAdapter(Context context, int resourceId)
|
||||||
{
|
{
|
||||||
super(context, resourceId, objects);
|
super(context, resourceId);
|
||||||
|
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.id = resourceId;
|
this.id = resourceId;
|
||||||
this.items = objects;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FolderBrowserItem getItem(int i)
|
|
||||||
{
|
|
||||||
return items.get(i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View getView(int position, View convertView, ViewGroup parent)
|
public View getView(int position, View convertView, ViewGroup parent)
|
||||||
{
|
{
|
||||||
View v = convertView;
|
if (convertView == null)
|
||||||
if (v == null)
|
|
||||||
{
|
{
|
||||||
LayoutInflater vi = LayoutInflater.from(context);
|
LayoutInflater vi = LayoutInflater.from(context);
|
||||||
v = vi.inflate(id, parent, false);
|
convertView = vi.inflate(id, parent, false);
|
||||||
|
|
||||||
|
// Initialize the ViewHolder and store it.
|
||||||
|
viewHolder = new ViewHolder();
|
||||||
|
viewHolder.title = (TextView) convertView.findViewById(R.id.ListItemTitle);
|
||||||
|
viewHolder.subtitle = (TextView) convertView.findViewById(R.id.ListItemSubTitle);
|
||||||
|
viewHolder.icon = (ImageView) convertView.findViewById(R.id.ListItemIcon);
|
||||||
|
convertView.setTag(viewHolder);
|
||||||
|
}
|
||||||
|
else // Can recover the holder.
|
||||||
|
{
|
||||||
|
viewHolder = (ViewHolder) convertView.getTag();
|
||||||
}
|
}
|
||||||
|
|
||||||
final FolderBrowserItem item = items.get(position);
|
final FolderBrowserItem item = getItem(position);
|
||||||
if (item != null)
|
if (item != null)
|
||||||
{
|
{
|
||||||
ImageView icon = (ImageView) v.findViewById(R.id.ListItemIcon);
|
if (viewHolder.title != null)
|
||||||
TextView title = (TextView) v.findViewById(R.id.ListItemTitle);
|
|
||||||
TextView subtitle = (TextView) v.findViewById(R.id.ListItemSubTitle);
|
|
||||||
|
|
||||||
if(title != null)
|
|
||||||
{
|
{
|
||||||
title.setText(item.getName());
|
viewHolder.title.setText(item.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(subtitle != null)
|
if (viewHolder.subtitle != null)
|
||||||
{
|
{
|
||||||
// Remove the subtitle for all folders, except for the parent directory folder.
|
// Remove the subtitle for all folders, except for the parent directory folder.
|
||||||
if (item.isDirectory() && !item.getSubtitle().equals(context.getString(R.string.parent_directory)))
|
if (item.isDirectory() && !item.getSubtitle().equals(context.getString(R.string.parent_directory)))
|
||||||
{
|
{
|
||||||
subtitle.setVisibility(View.GONE);
|
viewHolder.subtitle.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
subtitle.setText(item.getSubtitle());
|
viewHolder.subtitle.setVisibility(View.VISIBLE);
|
||||||
|
viewHolder.subtitle.setText(item.getSubtitle());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (icon != null)
|
if (viewHolder.icon != null)
|
||||||
{
|
{
|
||||||
if (item.isDirectory())
|
if (item.isDirectory())
|
||||||
{
|
{
|
||||||
icon.setImageResource(R.drawable.ic_menu_folder);
|
viewHolder.icon.setImageResource(R.drawable.ic_menu_folder);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
icon.setImageResource(R.drawable.ic_menu_file);
|
viewHolder.icon.setImageResource(R.drawable.ic_menu_file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return v;
|
return convertView;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,20 +9,21 @@ package org.dolphinemu.dolphinemu.gamelist;
|
|||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.Fragment;
|
import android.app.Fragment;
|
||||||
import android.app.FragmentManager;
|
import android.app.FragmentTransaction;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.ActionBarDrawerToggle;
|
import android.support.v4.app.ActionBarDrawerToggle;
|
||||||
import android.support.v4.widget.DrawerLayout;
|
import android.support.v4.widget.DrawerLayout;
|
||||||
import android.view.*;
|
import android.view.Menu;
|
||||||
|
import android.view.MenuInflater;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.dolphinemu.dolphinemu.AboutFragment;
|
import org.dolphinemu.dolphinemu.AboutFragment;
|
||||||
import org.dolphinemu.dolphinemu.NativeLibrary;
|
import org.dolphinemu.dolphinemu.NativeLibrary;
|
||||||
import org.dolphinemu.dolphinemu.R;
|
import org.dolphinemu.dolphinemu.R;
|
||||||
@ -31,6 +32,9 @@ import org.dolphinemu.dolphinemu.settings.PrefsActivity;
|
|||||||
import org.dolphinemu.dolphinemu.sidemenu.SideMenuAdapter;
|
import org.dolphinemu.dolphinemu.sidemenu.SideMenuAdapter;
|
||||||
import org.dolphinemu.dolphinemu.sidemenu.SideMenuItem;
|
import org.dolphinemu.dolphinemu.sidemenu.SideMenuItem;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The activity that implements all of the functions
|
* The activity that implements all of the functions
|
||||||
* for the game list.
|
* for the game list.
|
||||||
@ -39,7 +43,6 @@ public final class GameListActivity extends Activity
|
|||||||
implements GameListFragment.OnGameListZeroListener
|
implements GameListFragment.OnGameListZeroListener
|
||||||
{
|
{
|
||||||
private int mCurFragmentNum = 0;
|
private int mCurFragmentNum = 0;
|
||||||
private Fragment mCurFragment;
|
|
||||||
|
|
||||||
private ActionBarDrawerToggle mDrawerToggle;
|
private ActionBarDrawerToggle mDrawerToggle;
|
||||||
private DrawerLayout mDrawerLayout;
|
private DrawerLayout mDrawerLayout;
|
||||||
@ -100,10 +103,36 @@ public final class GameListActivity extends Activity
|
|||||||
};
|
};
|
||||||
mDrawerLayout.setDrawerListener(mDrawerToggle);
|
mDrawerLayout.setDrawerListener(mDrawerToggle);
|
||||||
|
|
||||||
// Display the game list fragment.
|
// Display the game list fragment on activity creation,
|
||||||
mCurFragment = new GameListFragment();
|
// but only if no previous states have been saved.
|
||||||
FragmentManager fragmentManager = getFragmentManager();
|
if (savedInstanceState == null)
|
||||||
fragmentManager.beginTransaction().replace(R.id.content_frame, mCurFragment).commit();
|
{
|
||||||
|
final GameListFragment gameList = new GameListFragment();
|
||||||
|
FragmentTransaction ft = getFragmentManager().beginTransaction();
|
||||||
|
ft.replace(R.id.content_frame, gameList);
|
||||||
|
ft.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Create an alert telling them that their phone sucks
|
||||||
|
if (Build.CPU_ABI.contains("arm") && !NativeLibrary.SupportsNEON())
|
||||||
|
{
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
|
builder.setTitle(R.string.device_compat_warning);
|
||||||
|
builder.setMessage(R.string.device_compat_warning_msg);
|
||||||
|
builder.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
// Do Nothing. Just create the Yes button
|
||||||
|
}
|
||||||
|
});
|
||||||
|
builder.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int which)
|
||||||
|
{
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
builder.show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -127,9 +156,10 @@ public final class GameListActivity extends Activity
|
|||||||
setTitle(R.string.app_name);
|
setTitle(R.string.app_name);
|
||||||
|
|
||||||
mCurFragmentNum = 0;
|
mCurFragmentNum = 0;
|
||||||
mCurFragment = new GameListFragment();
|
final GameListFragment gameList = new GameListFragment();
|
||||||
FragmentManager fragmentManager = getFragmentManager();
|
FragmentTransaction ft = getFragmentManager().beginTransaction();
|
||||||
fragmentManager.beginTransaction().replace(R.id.content_frame, mCurFragment).commit();
|
ft.replace(R.id.content_frame, gameList);
|
||||||
|
ft.commit();
|
||||||
invalidateOptionsMenu();
|
invalidateOptionsMenu();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -137,9 +167,11 @@ public final class GameListActivity extends Activity
|
|||||||
case 1: // Folder Browser
|
case 1: // Folder Browser
|
||||||
{
|
{
|
||||||
mCurFragmentNum = 1;
|
mCurFragmentNum = 1;
|
||||||
mCurFragment = new FolderBrowser();
|
final FolderBrowser folderBrowser = new FolderBrowser();
|
||||||
FragmentManager fragmentManager = getFragmentManager();
|
FragmentTransaction ft = getFragmentManager().beginTransaction();
|
||||||
fragmentManager.beginTransaction().replace(R.id.content_frame, mCurFragment).commit();
|
ft.replace(R.id.content_frame, folderBrowser);
|
||||||
|
ft.addToBackStack(null);
|
||||||
|
ft.commit();
|
||||||
invalidateOptionsMenu();
|
invalidateOptionsMenu();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -154,9 +186,11 @@ public final class GameListActivity extends Activity
|
|||||||
case 3: // About
|
case 3: // About
|
||||||
{
|
{
|
||||||
mCurFragmentNum = 3;
|
mCurFragmentNum = 3;
|
||||||
mCurFragment = new AboutFragment();
|
final AboutFragment aboutFragment = new AboutFragment();
|
||||||
FragmentManager fragmentManager = getFragmentManager();
|
FragmentTransaction ft = getFragmentManager().beginTransaction();
|
||||||
fragmentManager.beginTransaction().replace(R.id.content_frame, mCurFragment).commit();
|
ft.replace(R.id.content_frame, aboutFragment);
|
||||||
|
ft.addToBackStack(null);
|
||||||
|
ft.commit();
|
||||||
invalidateOptionsMenu();
|
invalidateOptionsMenu();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -243,7 +277,7 @@ public final class GameListActivity extends Activity
|
|||||||
NativeLibrary.SetConfig("Dolphin.ini", "General", "GCMPathes", "0");
|
NativeLibrary.SetConfig("Dolphin.ini", "General", "GCMPathes", "0");
|
||||||
|
|
||||||
// Now finally, clear the game list.
|
// Now finally, clear the game list.
|
||||||
((GameListFragment) mCurFragment).clearGameList();
|
((GameListFragment) getFragmentManager().findFragmentById(R.id.content_frame)).clearGameList();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
builder.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
|
builder.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
|
||||||
@ -259,6 +293,22 @@ public final class GameListActivity extends Activity
|
|||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSaveInstanceState(Bundle outState)
|
||||||
|
{
|
||||||
|
super.onSaveInstanceState(outState);
|
||||||
|
|
||||||
|
outState.putInt("currentFragmentNum", mCurFragmentNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRestoreInstanceState(Bundle savedInstanceState)
|
||||||
|
{
|
||||||
|
super.onRestoreInstanceState(savedInstanceState);
|
||||||
|
|
||||||
|
mCurFragmentNum = savedInstanceState.getInt("currentFragmentNum");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBackPressed()
|
public void onBackPressed()
|
||||||
{
|
{
|
||||||
|
@ -12,11 +12,8 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.dolphinemu.dolphinemu.R;
|
import org.dolphinemu.dolphinemu.R;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -28,46 +25,36 @@ public final class GameListAdapter extends ArrayAdapter<GameListItem>
|
|||||||
{
|
{
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private final int id;
|
private final int id;
|
||||||
private final List<GameListItem>items;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param context The current {@link Context}.
|
* @param context The current {@link Context}.
|
||||||
* @param resourceId The resource ID for a layout file containing a layout to use when instantiating views.
|
* @param resourceId The resource ID for a layout file containing a layout to use when instantiating views.
|
||||||
* @param objects The objects to represent in the {@link ListView}.
|
|
||||||
*/
|
*/
|
||||||
public GameListAdapter(Context context, int resourceId, List<GameListItem> objects)
|
public GameListAdapter(Context context, int resourceId)
|
||||||
{
|
{
|
||||||
super(context, resourceId, objects);
|
super(context, resourceId);
|
||||||
|
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.id = resourceId;
|
this.id = resourceId;
|
||||||
this.items = objects;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public GameListItem getItem(int i)
|
|
||||||
{
|
|
||||||
return items.get(i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View getView(int position, View convertView, ViewGroup parent)
|
public View getView(int position, View convertView, ViewGroup parent)
|
||||||
{
|
{
|
||||||
View v = convertView;
|
if (convertView == null)
|
||||||
if (v == null)
|
|
||||||
{
|
{
|
||||||
LayoutInflater vi = LayoutInflater.from(context);
|
LayoutInflater vi = LayoutInflater.from(context);
|
||||||
v = vi.inflate(id, parent, false);
|
convertView = vi.inflate(id, parent, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
final GameListItem item = items.get(position);
|
final GameListItem item = getItem(position);
|
||||||
if (item != null)
|
if (item != null)
|
||||||
{
|
{
|
||||||
TextView title = (TextView) v.findViewById(R.id.ListItemTitle);
|
TextView title = (TextView) convertView.findViewById(R.id.ListItemTitle);
|
||||||
TextView subtitle = (TextView) v.findViewById(R.id.ListItemSubTitle);
|
TextView subtitle = (TextView) convertView.findViewById(R.id.ListItemSubTitle);
|
||||||
ImageView icon = (ImageView) v.findViewById(R.id.ListItemIcon);
|
ImageView icon = (ImageView) convertView.findViewById(R.id.ListItemIcon);
|
||||||
|
|
||||||
if (title != null)
|
if (title != null)
|
||||||
title.setText(item.getName());
|
title.setText(item.getName());
|
||||||
@ -83,7 +70,7 @@ public final class GameListAdapter extends ArrayAdapter<GameListItem>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return v;
|
return convertView;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,6 @@ import org.dolphinemu.dolphinemu.emulation.EmulationActivity;
|
|||||||
public final class GameListFragment extends ListFragment
|
public final class GameListFragment extends ListFragment
|
||||||
{
|
{
|
||||||
private GameListAdapter mGameAdapter;
|
private GameListAdapter mGameAdapter;
|
||||||
private static GameListActivity mMe;
|
|
||||||
private OnGameListZeroListener mCallback;
|
private OnGameListZeroListener mCallback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -84,7 +83,7 @@ public final class GameListFragment extends ListFragment
|
|||||||
if (!entry.isHidden() && !entry.isDirectory())
|
if (!entry.isHidden() && !entry.isDirectory())
|
||||||
{
|
{
|
||||||
if (exts.contains(entryName.toLowerCase().substring(entryName.lastIndexOf('.'))))
|
if (exts.contains(entryName.toLowerCase().substring(entryName.lastIndexOf('.'))))
|
||||||
fls.add(new GameListItem(mMe, entryName, String.format(getString(R.string.file_size), entry.length()), entry.getAbsolutePath()));
|
fls.add(new GameListItem(getActivity(), entryName, String.format(getString(R.string.file_size), entry.length()), entry.getAbsolutePath()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,8 +93,9 @@ public final class GameListFragment extends ListFragment
|
|||||||
}
|
}
|
||||||
Collections.sort(fls);
|
Collections.sort(fls);
|
||||||
|
|
||||||
mGameAdapter = new GameListAdapter(mMe, R.layout.gamelist_folderbrowser_list, fls);
|
// Add all the items to the adapter
|
||||||
setListAdapter(mGameAdapter);
|
mGameAdapter.addAll(fls);
|
||||||
|
mGameAdapter.notifyDataSetChanged();
|
||||||
|
|
||||||
if (fls.isEmpty())
|
if (fls.isEmpty())
|
||||||
{
|
{
|
||||||
@ -106,12 +106,13 @@ public final class GameListFragment extends ListFragment
|
|||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
|
||||||
{
|
{
|
||||||
View rootView = inflater.inflate(R.layout.gamelist_listview, container, false);
|
ListView rootView = (ListView) inflater.inflate(R.layout.gamelist_listview, container, false);
|
||||||
ListView mMainList = (ListView) rootView.findViewById(R.id.gamelist);
|
mGameAdapter = new GameListAdapter(getActivity(), R.layout.gamelist_folderbrowser_list_item);
|
||||||
|
rootView.setAdapter(mGameAdapter);
|
||||||
|
|
||||||
Fill();
|
Fill();
|
||||||
|
|
||||||
return mMainList;
|
return rootView;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -120,12 +121,12 @@ public final class GameListFragment extends ListFragment
|
|||||||
GameListItem item = mGameAdapter.getItem(position);
|
GameListItem item = mGameAdapter.getItem(position);
|
||||||
|
|
||||||
// Show a toast indicating which game was clicked.
|
// Show a toast indicating which game was clicked.
|
||||||
Toast.makeText(mMe, String.format(getString(R.string.file_clicked), item.getPath()), Toast.LENGTH_SHORT).show();
|
Toast.makeText(getActivity(), String.format(getString(R.string.file_clicked), item.getPath()), Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
// Start the emulation activity and send the path of the clicked ROM to it.
|
// Start the emulation activity and send the path of the clicked ROM to it.
|
||||||
Intent intent = new Intent(mMe, EmulationActivity.class);
|
Intent intent = new Intent(getActivity(), EmulationActivity.class);
|
||||||
intent.putExtra("SelectedGame", item.getPath());
|
intent.putExtra("SelectedGame", item.getPath());
|
||||||
mMe.startActivity(intent);
|
startActivity(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -138,7 +139,6 @@ public final class GameListFragment extends ListFragment
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
mCallback = (OnGameListZeroListener) activity;
|
mCallback = (OnGameListZeroListener) activity;
|
||||||
mMe = (GameListActivity) activity;
|
|
||||||
}
|
}
|
||||||
catch (ClassCastException e)
|
catch (ClassCastException e)
|
||||||
{
|
{
|
||||||
|
@ -28,6 +28,7 @@ public final class VideoSettingsFragment extends PreferenceFragment
|
|||||||
public static String m_GLVendor;
|
public static String m_GLVendor;
|
||||||
public static String m_GLRenderer;
|
public static String m_GLRenderer;
|
||||||
public static String m_GLExtensions;
|
public static String m_GLExtensions;
|
||||||
|
public static float m_QualcommVersion;
|
||||||
private Activity m_activity;
|
private Activity m_activity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -165,7 +166,6 @@ public final class VideoSettingsFragment extends PreferenceFragment
|
|||||||
{
|
{
|
||||||
int mVStart = m_GLVersion.indexOf("V@") + 2;
|
int mVStart = m_GLVersion.indexOf("V@") + 2;
|
||||||
int mVEnd = 0;
|
int mVEnd = 0;
|
||||||
float mVersion;
|
|
||||||
|
|
||||||
for (int a = mVStart; a < m_GLVersion.length(); ++a)
|
for (int a = mVStart; a < m_GLVersion.length(); ++a)
|
||||||
{
|
{
|
||||||
@ -176,9 +176,9 @@ public final class VideoSettingsFragment extends PreferenceFragment
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mVersion = Float.parseFloat(m_GLVersion.substring(mVStart, mVEnd));
|
m_QualcommVersion = Float.parseFloat(m_GLVersion.substring(mVStart, mVEnd));
|
||||||
|
|
||||||
if (mVersion >= 14.0f)
|
if (m_QualcommVersion >= 14.0f)
|
||||||
mSupportsGLES3 = true;
|
mSupportsGLES3 = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,23 +54,22 @@ public final class SideMenuAdapter extends ArrayAdapter<SideMenuItem>
|
|||||||
@Override
|
@Override
|
||||||
public View getView(int position, View convertView, ViewGroup parent)
|
public View getView(int position, View convertView, ViewGroup parent)
|
||||||
{
|
{
|
||||||
View v = convertView;
|
if (convertView == null)
|
||||||
if (v == null)
|
|
||||||
{
|
{
|
||||||
LayoutInflater vi = LayoutInflater.from(context);
|
LayoutInflater vi = LayoutInflater.from(context);
|
||||||
v = vi.inflate(id, null);
|
convertView = vi.inflate(id, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
final SideMenuItem item = items.get(position);
|
final SideMenuItem item = items.get(position);
|
||||||
if (item != null)
|
if (item != null)
|
||||||
{
|
{
|
||||||
TextView title = (TextView) v.findViewById(R.id.SideMenuTitle);
|
TextView title = (TextView) convertView.findViewById(R.id.SideMenuTitle);
|
||||||
|
|
||||||
if (title != null)
|
if (title != null)
|
||||||
title.setText(item.getName());
|
title.setText(item.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
return v;
|
return convertView;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ SoundStream *soundStream = nullptr;
|
|||||||
|
|
||||||
namespace AudioCommon
|
namespace AudioCommon
|
||||||
{
|
{
|
||||||
SoundStream *InitSoundStream(CMixer *mixer)
|
SoundStream *InitSoundStream(CMixer *mixer, void *hWnd)
|
||||||
{
|
{
|
||||||
// TODO: possible memleak with mixer
|
// TODO: possible memleak with mixer
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ namespace AudioCommon
|
|||||||
else if (backend == BACKEND_NULLSOUND && NullSound::isValid())
|
else if (backend == BACKEND_NULLSOUND && NullSound::isValid())
|
||||||
soundStream = new NullSound(mixer);
|
soundStream = new NullSound(mixer);
|
||||||
else if (backend == BACKEND_DIRECTSOUND && DSound::isValid())
|
else if (backend == BACKEND_DIRECTSOUND && DSound::isValid())
|
||||||
soundStream = new DSound(mixer);
|
soundStream = new DSound(mixer, hWnd);
|
||||||
else if (backend == BACKEND_XAUDIO2)
|
else if (backend == BACKEND_XAUDIO2)
|
||||||
{
|
{
|
||||||
if (XAudio2::isValid())
|
if (XAudio2::isValid())
|
||||||
|
@ -40,7 +40,7 @@ union UDSPControl
|
|||||||
|
|
||||||
namespace AudioCommon
|
namespace AudioCommon
|
||||||
{
|
{
|
||||||
SoundStream *InitSoundStream(CMixer *mixer);
|
SoundStream *InitSoundStream(CMixer *mixer, void *hWnd);
|
||||||
void ShutdownSoundStream();
|
void ShutdownSoundStream();
|
||||||
std::vector<std::string> GetSoundBackends();
|
std::vector<std::string> GetSoundBackends();
|
||||||
bool UseJIT();
|
bool UseJIT();
|
||||||
|
@ -48,7 +48,7 @@ class DSound : public SoundStream
|
|||||||
bool WriteDataToBuffer(DWORD dwOffset, char* soundData, DWORD dwSoundBytes);
|
bool WriteDataToBuffer(DWORD dwOffset, char* soundData, DWORD dwSoundBytes);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DSound(CMixer *mixer, void *_hWnd = NULL)
|
DSound(CMixer *mixer, void *_hWnd)
|
||||||
: SoundStream(mixer)
|
: SoundStream(mixer)
|
||||||
, bufferSize(0)
|
, bufferSize(0)
|
||||||
, currentPos(0)
|
, currentPos(0)
|
||||||
@ -71,7 +71,7 @@ public:
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
public:
|
public:
|
||||||
DSound(CMixer *mixer)
|
DSound(CMixer *mixer, void *_hWnd)
|
||||||
: SoundStream(mixer)
|
: SoundStream(mixer)
|
||||||
{}
|
{}
|
||||||
#endif
|
#endif
|
||||||
|
@ -938,13 +938,13 @@ u32 EncodeVm(ARMReg Vm)
|
|||||||
|
|
||||||
// Double/single, Neon
|
// Double/single, Neon
|
||||||
extern const VFPEnc VFPOps[16][2] = {
|
extern const VFPEnc VFPOps[16][2] = {
|
||||||
{{0xE0, 0xA0}, {0x20, 0xD1}}, // 0: VMLA
|
{{0xE0, 0xA0}, { -1, -1}}, // 0: VMLA
|
||||||
{{0xE1, 0xA4}, { -1, -1}}, // 1: VNMLA
|
{{0xE1, 0xA4}, { -1, -1}}, // 1: VNMLA
|
||||||
{{0xE0, 0xA4}, {0x22, 0xD1}}, // 2: VMLS
|
{{0xE0, 0xA4}, { -1, -1}}, // 2: VMLS
|
||||||
{{0xE1, 0xA0}, { -1, -1}}, // 3: VNMLS
|
{{0xE1, 0xA0}, { -1, -1}}, // 3: VNMLS
|
||||||
{{0xE3, 0xA0}, {0x20, 0xD0}}, // 4: VADD
|
{{0xE3, 0xA0}, { -1, -1}}, // 4: VADD
|
||||||
{{0xE3, 0xA4}, {0x22, 0xD0}}, // 5: VSUB
|
{{0xE3, 0xA4}, { -1, -1}}, // 5: VSUB
|
||||||
{{0xE2, 0xA0}, {0x30, 0xD1}}, // 6: VMUL
|
{{0xE2, 0xA0}, { -1, -1}}, // 6: VMUL
|
||||||
{{0xE2, 0xA4}, { -1, -1}}, // 7: VNMUL
|
{{0xE2, 0xA4}, { -1, -1}}, // 7: VNMUL
|
||||||
{{0xEB, 0xAC}, { -1 /* 0x3B */, -1 /* 0x70 */}}, // 8: VABS(Vn(0x0) used for encoding)
|
{{0xEB, 0xAC}, { -1 /* 0x3B */, -1 /* 0x70 */}}, // 8: VABS(Vn(0x0) used for encoding)
|
||||||
{{0xE8, 0xA0}, { -1, -1}}, // 9: VDIV
|
{{0xE8, 0xA0}, { -1, -1}}, // 9: VDIV
|
||||||
@ -1237,7 +1237,7 @@ void ARMXEmitter::VCVT(ARMReg Dest, ARMReg Source, int flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NEONXEmitter::VABA(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
void NEONXEmitter::VABA(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
@ -1248,7 +1248,7 @@ void NEONXEmitter::VABA(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
|||||||
| (encodedSize(Size) << 20) | EncodeVd(Vd) | (0x71 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
| (encodedSize(Size) << 20) | EncodeVd(Vd) | (0x71 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
}
|
}
|
||||||
|
|
||||||
void NEONXEmitter::VABAL(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
void NEONXEmitter::VABAL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(DYNA_REC, Vd >= Q0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vd >= Q0, "Pass invalid register to " __FUNCTION__);
|
||||||
_dbg_assert_msg_(DYNA_REC, Vn >= D0 && Vn < Q0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vn >= D0 && Vn < Q0, "Pass invalid register to " __FUNCTION__);
|
||||||
@ -1260,7 +1260,7 @@ void NEONXEmitter::VABAL(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
|||||||
| (encodedSize(Size) << 20) | EncodeVd(Vd) | (0x50 << 4) | EncodeVm(Vm));
|
| (encodedSize(Size) << 20) | EncodeVd(Vd) | (0x50 << 4) | EncodeVm(Vm));
|
||||||
}
|
}
|
||||||
|
|
||||||
void NEONXEmitter::VABD(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
void NEONXEmitter::VABD(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
@ -1273,7 +1273,7 @@ void NEONXEmitter::VABD(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
|||||||
| (encodedSize(Size) << 20) | EncodeVd(Vd) | (0x70 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
| (encodedSize(Size) << 20) | EncodeVd(Vd) | (0x70 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
}
|
}
|
||||||
|
|
||||||
void NEONXEmitter::VABDL(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
void NEONXEmitter::VABDL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(DYNA_REC, Vd >= Q0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vd >= Q0, "Pass invalid register to " __FUNCTION__);
|
||||||
_dbg_assert_msg_(DYNA_REC, Vn >= D0 && Vn < Q0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vn >= D0 && Vn < Q0, "Pass invalid register to " __FUNCTION__);
|
||||||
@ -1285,7 +1285,7 @@ void NEONXEmitter::VABDL(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
|||||||
| (encodedSize(Size) << 20) | EncodeVd(Vd) | (0x70 << 4) | EncodeVm(Vm));
|
| (encodedSize(Size) << 20) | EncodeVd(Vd) | (0x70 << 4) | EncodeVm(Vm));
|
||||||
}
|
}
|
||||||
|
|
||||||
void NEONXEmitter::VABS(NEONElementType Size, ARMReg Vd, ARMReg Vm)
|
void NEONXEmitter::VABS(u32 Size, ARMReg Vd, ARMReg Vm)
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
@ -1327,7 +1327,7 @@ void NEONXEmitter::VACLT(ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
|||||||
VACGT(Vd, Vn, Vm);
|
VACGT(Vd, Vn, Vm);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NEONXEmitter::VADD(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
void NEONXEmitter::VADD(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
@ -1341,7 +1341,7 @@ void NEONXEmitter::VADD(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
|||||||
| (0x8 << 8) | (register_quad << 6) | EncodeVm(Vm));
|
| (0x8 << 8) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
}
|
}
|
||||||
|
|
||||||
void NEONXEmitter::VADDHN(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
void NEONXEmitter::VADDHN(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(DYNA_REC, Vd < Q0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vd < Q0, "Pass invalid register to " __FUNCTION__);
|
||||||
_dbg_assert_msg_(DYNA_REC, Vn >= Q0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vn >= Q0, "Pass invalid register to " __FUNCTION__);
|
||||||
@ -1353,7 +1353,7 @@ void NEONXEmitter::VADDHN(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
|||||||
| EncodeVd(Vd) | (0x80 << 4) | EncodeVm(Vm));
|
| EncodeVd(Vd) | (0x80 << 4) | EncodeVm(Vm));
|
||||||
}
|
}
|
||||||
|
|
||||||
void NEONXEmitter::VADDL(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
void NEONXEmitter::VADDL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(DYNA_REC, Vd >= Q0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vd >= Q0, "Pass invalid register to " __FUNCTION__);
|
||||||
_dbg_assert_msg_(DYNA_REC, Vn >= D0 && Vn < Q0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vn >= D0 && Vn < Q0, "Pass invalid register to " __FUNCTION__);
|
||||||
@ -1364,7 +1364,7 @@ void NEONXEmitter::VADDL(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
|||||||
Write32((0xF2 << 24) | ((Size & I_UNSIGNED ? 1 : 0) << 24) | (1 << 23) | (encodedSize(Size) << 20) | EncodeVn(Vn) \
|
Write32((0xF2 << 24) | ((Size & I_UNSIGNED ? 1 : 0) << 24) | (1 << 23) | (encodedSize(Size) << 20) | EncodeVn(Vn) \
|
||||||
| EncodeVd(Vd) | EncodeVm(Vm));
|
| EncodeVd(Vd) | EncodeVm(Vm));
|
||||||
}
|
}
|
||||||
void NEONXEmitter::VADDW(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
void NEONXEmitter::VADDW(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(DYNA_REC, Vd >= Q0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vd >= Q0, "Pass invalid register to " __FUNCTION__);
|
||||||
_dbg_assert_msg_(DYNA_REC, Vn >= Q0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vn >= Q0, "Pass invalid register to " __FUNCTION__);
|
||||||
@ -1420,7 +1420,7 @@ void NEONXEmitter::VBSL(ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
|||||||
|
|
||||||
Write32((0xF3 << 24) | (1 << 20) | EncodeVn(Vn) | EncodeVd(Vd) | (0x11 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
Write32((0xF3 << 24) | (1 << 20) | EncodeVn(Vn) | EncodeVd(Vd) | (0x11 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
}
|
}
|
||||||
void NEONXEmitter::VCEQ(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
void NEONXEmitter::VCEQ(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
@ -1433,7 +1433,7 @@ void NEONXEmitter::VCEQ(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
|||||||
| (0x81 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
| (0x81 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
|
|
||||||
}
|
}
|
||||||
void NEONXEmitter::VCEQ(NEONElementType Size, ARMReg Vd, ARMReg Vm)
|
void NEONXEmitter::VCEQ(u32 Size, ARMReg Vd, ARMReg Vm)
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
@ -1443,7 +1443,7 @@ void NEONXEmitter::VCEQ(NEONElementType Size, ARMReg Vd, ARMReg Vm)
|
|||||||
Write32((0xF2 << 24) | (0xB << 20) | (encodedSize(Size) << 18) | (1 << 16) \
|
Write32((0xF2 << 24) | (0xB << 20) | (encodedSize(Size) << 18) | (1 << 16) \
|
||||||
| EncodeVd(Vd) | ((Size & F_32 ? 1 : 0) << 10) | (0x10 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
| EncodeVd(Vd) | ((Size & F_32 ? 1 : 0) << 10) | (0x10 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
}
|
}
|
||||||
void NEONXEmitter::VCGE(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
void NEONXEmitter::VCGE(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
@ -1455,7 +1455,7 @@ void NEONXEmitter::VCGE(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
|||||||
Write32((0xF2 << 24) | ((Size & I_UNSIGNED ? 1 : 0) << 24) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) \
|
Write32((0xF2 << 24) | ((Size & I_UNSIGNED ? 1 : 0) << 24) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) \
|
||||||
| (0x31 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
| (0x31 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
}
|
}
|
||||||
void NEONXEmitter::VCGE(NEONElementType Size, ARMReg Vd, ARMReg Vm)
|
void NEONXEmitter::VCGE(u32 Size, ARMReg Vd, ARMReg Vm)
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
@ -1464,7 +1464,7 @@ void NEONXEmitter::VCGE(NEONElementType Size, ARMReg Vd, ARMReg Vm)
|
|||||||
Write32((0xF3 << 24) | (0xB << 20) | (encodedSize(Size) << 18) | (1 << 16) \
|
Write32((0xF3 << 24) | (0xB << 20) | (encodedSize(Size) << 18) | (1 << 16) \
|
||||||
| EncodeVd(Vd) | ((Size & F_32 ? 1 : 0) << 10) | (0x8 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
| EncodeVd(Vd) | ((Size & F_32 ? 1 : 0) << 10) | (0x8 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
}
|
}
|
||||||
void NEONXEmitter::VCGT(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
void NEONXEmitter::VCGT(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
@ -1476,7 +1476,7 @@ void NEONXEmitter::VCGT(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
|||||||
Write32((0xF2 << 24) | ((Size & I_UNSIGNED ? 1 : 0) << 24) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) \
|
Write32((0xF2 << 24) | ((Size & I_UNSIGNED ? 1 : 0) << 24) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) \
|
||||||
| (0x30 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
| (0x30 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
}
|
}
|
||||||
void NEONXEmitter::VCGT(NEONElementType Size, ARMReg Vd, ARMReg Vm)
|
void NEONXEmitter::VCGT(u32 Size, ARMReg Vd, ARMReg Vm)
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
@ -1485,11 +1485,11 @@ void NEONXEmitter::VCGT(NEONElementType Size, ARMReg Vd, ARMReg Vm)
|
|||||||
Write32((0xF3 << 24) | (0xD << 20) | (encodedSize(Size) << 18) | (1 << 16) \
|
Write32((0xF3 << 24) | (0xD << 20) | (encodedSize(Size) << 18) | (1 << 16) \
|
||||||
| EncodeVd(Vd) | ((Size & F_32 ? 1 : 0) << 10) | (register_quad << 6) | EncodeVm(Vm));
|
| EncodeVd(Vd) | ((Size & F_32 ? 1 : 0) << 10) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
}
|
}
|
||||||
void NEONXEmitter::VCLE(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
void NEONXEmitter::VCLE(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
{
|
{
|
||||||
VCGE(Size, Vd, Vm, Vn);
|
VCGE(Size, Vd, Vm, Vn);
|
||||||
}
|
}
|
||||||
void NEONXEmitter::VCLE(NEONElementType Size, ARMReg Vd, ARMReg Vm)
|
void NEONXEmitter::VCLE(u32 Size, ARMReg Vd, ARMReg Vm)
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
@ -1498,7 +1498,7 @@ void NEONXEmitter::VCLE(NEONElementType Size, ARMReg Vd, ARMReg Vm)
|
|||||||
Write32((0xF3 << 24) | (0xD << 20) | (encodedSize(Size) << 18) | (1 << 16) \
|
Write32((0xF3 << 24) | (0xD << 20) | (encodedSize(Size) << 18) | (1 << 16) \
|
||||||
| EncodeVd(Vd) | ((Size & F_32 ? 1 : 0) << 10) | (3 << 7) | (register_quad << 6) | EncodeVm(Vm));
|
| EncodeVd(Vd) | ((Size & F_32 ? 1 : 0) << 10) | (3 << 7) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
}
|
}
|
||||||
void NEONXEmitter::VCLS(NEONElementType Size, ARMReg Vd, ARMReg Vm)
|
void NEONXEmitter::VCLS(u32 Size, ARMReg Vd, ARMReg Vm)
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
@ -1508,11 +1508,11 @@ void NEONXEmitter::VCLS(NEONElementType Size, ARMReg Vd, ARMReg Vm)
|
|||||||
Write32((0xF3 << 24) | (0xD << 20) | (encodedSize(Size) << 18) \
|
Write32((0xF3 << 24) | (0xD << 20) | (encodedSize(Size) << 18) \
|
||||||
| EncodeVd(Vd) | (1 << 10) | (register_quad << 6) | EncodeVm(Vm));
|
| EncodeVd(Vd) | (1 << 10) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
}
|
}
|
||||||
void NEONXEmitter::VCLT(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
void NEONXEmitter::VCLT(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
{
|
{
|
||||||
VCGT(Size, Vd, Vm, Vn);
|
VCGT(Size, Vd, Vm, Vn);
|
||||||
}
|
}
|
||||||
void NEONXEmitter::VCLT(NEONElementType Size, ARMReg Vd, ARMReg Vm)
|
void NEONXEmitter::VCLT(u32 Size, ARMReg Vd, ARMReg Vm)
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
@ -1521,7 +1521,7 @@ void NEONXEmitter::VCLT(NEONElementType Size, ARMReg Vd, ARMReg Vm)
|
|||||||
Write32((0xF3 << 24) | (0xD << 20) | (encodedSize(Size) << 18) | (1 << 16) \
|
Write32((0xF3 << 24) | (0xD << 20) | (encodedSize(Size) << 18) | (1 << 16) \
|
||||||
| EncodeVd(Vd) | ((Size & F_32 ? 1 : 0) << 10) | (0x20 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
| EncodeVd(Vd) | ((Size & F_32 ? 1 : 0) << 10) | (0x20 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
}
|
}
|
||||||
void NEONXEmitter::VCLZ(NEONElementType Size, ARMReg Vd, ARMReg Vm)
|
void NEONXEmitter::VCLZ(u32 Size, ARMReg Vd, ARMReg Vm)
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
@ -1530,7 +1530,7 @@ void NEONXEmitter::VCLZ(NEONElementType Size, ARMReg Vd, ARMReg Vm)
|
|||||||
Write32((0xF3 << 24) | (0xD << 20) | (encodedSize(Size) << 18) \
|
Write32((0xF3 << 24) | (0xD << 20) | (encodedSize(Size) << 18) \
|
||||||
| EncodeVd(Vd) | (0x48 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
| EncodeVd(Vd) | (0x48 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
}
|
}
|
||||||
void NEONXEmitter::VCNT(NEONElementType Size, ARMReg Vd, ARMReg Vm)
|
void NEONXEmitter::VCNT(u32 Size, ARMReg Vd, ARMReg Vm)
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
@ -1540,7 +1540,7 @@ void NEONXEmitter::VCNT(NEONElementType Size, ARMReg Vd, ARMReg Vm)
|
|||||||
Write32((0xF3 << 24) | (0xD << 20) | (encodedSize(Size) << 18) \
|
Write32((0xF3 << 24) | (0xD << 20) | (encodedSize(Size) << 18) \
|
||||||
| EncodeVd(Vd) | (0x90 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
| EncodeVd(Vd) | (0x90 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
}
|
}
|
||||||
void NEONXEmitter::VDUP(NEONElementType Size, ARMReg Vd, ARMReg Vm, u8 index)
|
void NEONXEmitter::VDUP(u32 Size, ARMReg Vd, ARMReg Vm, u8 index)
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
@ -1562,7 +1562,7 @@ void NEONXEmitter::VDUP(NEONElementType Size, ARMReg Vd, ARMReg Vm, u8 index)
|
|||||||
Write32((0xF3 << 24) | (0xD << 20) | (sizeEncoded << 16) | (indexEncoded << 16) \
|
Write32((0xF3 << 24) | (0xD << 20) | (sizeEncoded << 16) | (indexEncoded << 16) \
|
||||||
| EncodeVd(Vd) | (0xC0 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
| EncodeVd(Vd) | (0xC0 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
}
|
}
|
||||||
void NEONXEmitter::VDUP(NEONElementType Size, ARMReg Vd, ARMReg Rt)
|
void NEONXEmitter::VDUP(u32 Size, ARMReg Vd, ARMReg Rt)
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
_dbg_assert_msg_(DYNA_REC, Rt < D0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Rt < D0, "Pass invalid register to " __FUNCTION__);
|
||||||
@ -1616,7 +1616,7 @@ void NEONXEmitter::VFMS(ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
|||||||
|
|
||||||
Write32((0xF2 << 24) | (1 << 21) | EncodeVn(Vn) | EncodeVd(Vd) | (0xC1 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
Write32((0xF2 << 24) | (1 << 21) | EncodeVn(Vn) | EncodeVd(Vd) | (0xC1 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
}
|
}
|
||||||
void NEONXEmitter::VHADD(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
void NEONXEmitter::VHADD(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
@ -1627,7 +1627,7 @@ void NEONXEmitter::VHADD(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
|||||||
Write32((0xF2 << 24) | ((Size & I_UNSIGNED ? 1 : 0) << 23) | (encodedSize(Size) << 20) \
|
Write32((0xF2 << 24) | ((Size & I_UNSIGNED ? 1 : 0) << 23) | (encodedSize(Size) << 20) \
|
||||||
| EncodeVn(Vn) | EncodeVd(Vd) | (register_quad << 6) | EncodeVm(Vm));
|
| EncodeVn(Vn) | EncodeVd(Vd) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
}
|
}
|
||||||
void NEONXEmitter::VHSUB(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
void NEONXEmitter::VHSUB(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
@ -1638,7 +1638,7 @@ void NEONXEmitter::VHSUB(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
|||||||
Write32((0xF2 << 24) | ((Size & I_UNSIGNED ? 1 : 0) << 23) | (encodedSize(Size) << 20) \
|
Write32((0xF2 << 24) | ((Size & I_UNSIGNED ? 1 : 0) << 23) | (encodedSize(Size) << 20) \
|
||||||
| EncodeVn(Vn) | EncodeVd(Vd) | (1 << 9) | (register_quad << 6) | EncodeVm(Vm));
|
| EncodeVn(Vn) | EncodeVd(Vd) | (1 << 9) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
}
|
}
|
||||||
void NEONXEmitter::VMAX(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
void NEONXEmitter::VMAX(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
@ -1651,7 +1651,7 @@ void NEONXEmitter::VMAX(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
|||||||
Write32((0xF2 << 24) | ((Size & I_UNSIGNED ? 1 : 0) << 23) | (encodedSize(Size) << 20) \
|
Write32((0xF2 << 24) | ((Size & I_UNSIGNED ? 1 : 0) << 23) | (encodedSize(Size) << 20) \
|
||||||
| EncodeVn(Vn) | EncodeVd(Vd) | (0x60 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
| EncodeVn(Vn) | EncodeVd(Vd) | (0x60 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
}
|
}
|
||||||
void NEONXEmitter::VMIN(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
void NEONXEmitter::VMIN(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
@ -1664,7 +1664,7 @@ void NEONXEmitter::VMIN(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
|||||||
Write32((0xF2 << 24) | ((Size & I_UNSIGNED ? 1 : 0) << 23) | (encodedSize(Size) << 20) \
|
Write32((0xF2 << 24) | ((Size & I_UNSIGNED ? 1 : 0) << 23) | (encodedSize(Size) << 20) \
|
||||||
| EncodeVn(Vn) | EncodeVd(Vd) | (0x61 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
| EncodeVn(Vn) | EncodeVd(Vd) | (0x61 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
}
|
}
|
||||||
void NEONXEmitter::VMLA(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
void NEONXEmitter::VMLA(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
@ -1676,7 +1676,7 @@ void NEONXEmitter::VMLA(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
|||||||
else
|
else
|
||||||
Write32((0xF2 << 24) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | (0x90 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
Write32((0xF2 << 24) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | (0x90 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
}
|
}
|
||||||
void NEONXEmitter::VMLS(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
void NEONXEmitter::VMLS(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
@ -1688,7 +1688,7 @@ void NEONXEmitter::VMLS(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
|||||||
else
|
else
|
||||||
Write32((0xF2 << 24) | (1 << 24) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | (0x90 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
Write32((0xF2 << 24) | (1 << 24) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | (0x90 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
}
|
}
|
||||||
void NEONXEmitter::VMLAL(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
void NEONXEmitter::VMLAL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(DYNA_REC, Vd >= Q0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vd >= Q0, "Pass invalid register to " __FUNCTION__);
|
||||||
_dbg_assert_msg_(DYNA_REC, Vn >= Q0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vn >= Q0, "Pass invalid register to " __FUNCTION__);
|
||||||
@ -1699,7 +1699,7 @@ void NEONXEmitter::VMLAL(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
|||||||
Write32((0xF2 << 24) | ((Size & I_UNSIGNED ? 1 : 0) << 24) | (encodedSize(Size) << 20) \
|
Write32((0xF2 << 24) | ((Size & I_UNSIGNED ? 1 : 0) << 24) | (encodedSize(Size) << 20) \
|
||||||
| EncodeVn(Vn) | EncodeVd(Vd) | (0x80 << 4) | EncodeVm(Vm));
|
| EncodeVn(Vn) | EncodeVd(Vd) | (0x80 << 4) | EncodeVm(Vm));
|
||||||
}
|
}
|
||||||
void NEONXEmitter::VMLSL(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
void NEONXEmitter::VMLSL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(DYNA_REC, Vd >= Q0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vd >= Q0, "Pass invalid register to " __FUNCTION__);
|
||||||
_dbg_assert_msg_(DYNA_REC, Vn >= Q0, "Pass invalid register to " __FUNCTION__);
|
_dbg_assert_msg_(DYNA_REC, Vn >= Q0, "Pass invalid register to " __FUNCTION__);
|
||||||
@ -1710,23 +1710,404 @@ void NEONXEmitter::VMLSL(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
|||||||
Write32((0xF2 << 24) | ((Size & I_UNSIGNED ? 1 : 0) << 24) | (encodedSize(Size) << 20) \
|
Write32((0xF2 << 24) | ((Size & I_UNSIGNED ? 1 : 0) << 24) | (encodedSize(Size) << 20) \
|
||||||
| EncodeVn(Vn) | EncodeVd(Vd) | (0xA0 << 4) | EncodeVm(Vm));
|
| EncodeVn(Vn) | EncodeVd(Vd) | (0xA0 << 4) | EncodeVm(Vm));
|
||||||
}
|
}
|
||||||
|
void NEONXEmitter::VMUL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
void NEONXEmitter::VSUB(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(DYNA_REC, Vd >= Q0, "Pass invalid register to VSUB(integer)");
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use VSUB(integer) when CPU doesn't support it");
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
|
||||||
// Gets encoded as a double register
|
bool register_quad = Vd >= Q0;
|
||||||
|
|
||||||
|
if (Size & F_32)
|
||||||
|
Write32((0xF3 << 24) | EncodeVn(Vn) | EncodeVd(Vd) | (0xD1 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
|
else
|
||||||
|
Write32((0xF2 << 24) | ((Size & I_POLYNOMIAL) ? (1 << 24) : 0) | (encodedSize(Size) << 20) | \
|
||||||
|
EncodeVn(Vn) | EncodeVd(Vd) | (0x91 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VMULL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
_dbg_assert_msg_(DYNA_REC, !(Size & F_32), __FUNCTION__ " doesn't support float");
|
||||||
|
|
||||||
|
Write32((0xF2 << 24) | (1 << 23) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \
|
||||||
|
(0xC0 << 4) | ((Size & I_POLYNOMIAL) ? 1 << 9 : 0) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VNEG(u32 Size, ARMReg Vd, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
|
||||||
|
bool register_quad = Vd >= Q0;
|
||||||
|
|
||||||
|
Write32((0xF3 << 24) | (0xB << 20) | (encodedSize(Size) << 18) | (1 << 16) | \
|
||||||
|
EncodeVd(Vd) | ((Size & F_32) ? 1 << 10 : 0) | (0xE << 6) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VORN(ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
|
||||||
|
bool register_quad = Vd >= Q0;
|
||||||
|
|
||||||
|
Write32((0xF2 << 24) | (3 << 20) | EncodeVn(Vn) | EncodeVd(Vd) | (0x11 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VORR(ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
|
||||||
|
bool register_quad = Vd >= Q0;
|
||||||
|
|
||||||
|
Write32((0xF2 << 24) | (2 << 20) | EncodeVn(Vn) | EncodeVd(Vd) | (0x11 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VPADAL(u32 Size, ARMReg Vd, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
_dbg_assert_msg_(DYNA_REC, !(Size & F_32), __FUNCTION__ " doesn't support float");
|
||||||
|
|
||||||
|
bool register_quad = Vd >= Q0;
|
||||||
|
|
||||||
|
Write32((0xF3 << 24) | (0xB << 20) | (encodedSize(Size) << 18) | EncodeVd(Vd) | \
|
||||||
|
(0x60 << 4) | ((Size & I_UNSIGNED) ? 1 << 7 : 0) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VPADD(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
|
||||||
|
if (Size & F_32)
|
||||||
|
Write32((0xF3 << 24) | EncodeVn(Vn) | EncodeVd(Vd) | (0xD0 << 4) | EncodeVm(Vm));
|
||||||
|
else
|
||||||
|
Write32((0xF2 << 24) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \
|
||||||
|
(0xB1 << 4) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VPADDL(u32 Size, ARMReg Vd, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
_dbg_assert_msg_(DYNA_REC, !(Size & F_32), __FUNCTION__ " doesn't support float");
|
||||||
|
|
||||||
|
bool register_quad = Vd >= Q0;
|
||||||
|
|
||||||
|
Write32((0xF3 << 24) | (0xB << 20) | (encodedSize(Size) << 18) | EncodeVd(Vd) | \
|
||||||
|
(0x20 << 4) | (Size & I_UNSIGNED ? 1 << 7 : 0) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VPMAX(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
|
||||||
|
if (Size & F_32)
|
||||||
|
Write32((0xF3 << 24) | EncodeVn(Vn) | EncodeVd(Vd) | (0xF0 << 4) | EncodeVm(Vm));
|
||||||
|
else
|
||||||
|
Write32((0xF2 << 24) | (Size & I_UNSIGNED ? 1 << 24 : 0) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \
|
||||||
|
(0xA0 << 4) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VPMIN(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
|
||||||
|
if (Size & F_32)
|
||||||
|
Write32((0xF3 << 24) | (1 << 21) | EncodeVn(Vn) | EncodeVd(Vd) | (0xF0 << 4) | EncodeVm(Vm));
|
||||||
|
else
|
||||||
|
Write32((0xF2 << 24) | (Size & I_UNSIGNED ? 1 << 24 : 0) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \
|
||||||
|
(0xA1 << 4) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VQABS(u32 Size, ARMReg Vd, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
_dbg_assert_msg_(DYNA_REC, !(Size & F_32), __FUNCTION__ " doesn't support float");
|
||||||
|
|
||||||
|
bool register_quad = Vd >= Q0;
|
||||||
|
|
||||||
|
Write32((0xF3 << 24) | (0xB << 20) | (encodedSize(Size) << 18) | EncodeVd(Vd) | \
|
||||||
|
(0x70 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VQADD(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
_dbg_assert_msg_(DYNA_REC, !(Size & F_32), __FUNCTION__ " doesn't support float");
|
||||||
|
|
||||||
|
bool register_quad = Vd >= Q0;
|
||||||
|
|
||||||
|
Write32((0xF2 << 24) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \
|
||||||
|
(0x1 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VQDMLAL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
_dbg_assert_msg_(DYNA_REC, !(Size & F_32), __FUNCTION__ " doesn't support float");
|
||||||
|
|
||||||
|
Write32((0xF2 << 24) | (1 << 23) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \
|
||||||
|
(0x90 << 4) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VQDMLSL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
_dbg_assert_msg_(DYNA_REC, !(Size & F_32), __FUNCTION__ " doesn't support float");
|
||||||
|
|
||||||
|
Write32((0xF2 << 24) | (1 << 23) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \
|
||||||
|
(0xB0 << 4) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VQDMULH(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
_dbg_assert_msg_(DYNA_REC, !(Size & F_32), __FUNCTION__ " doesn't support float");
|
||||||
|
|
||||||
|
Write32((0xF2 << 24) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \
|
||||||
|
(0xB0 << 4) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VQDMULL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
_dbg_assert_msg_(DYNA_REC, !(Size & F_32), __FUNCTION__ " doesn't support float");
|
||||||
|
|
||||||
|
Write32((0xF2 << 24) | (1 << 23) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \
|
||||||
|
(0xD0 << 4) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VQNEG(u32 Size, ARMReg Vd, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
_dbg_assert_msg_(DYNA_REC, !(Size & F_32), __FUNCTION__ " doesn't support float");
|
||||||
|
|
||||||
|
bool register_quad = Vd >= Q0;
|
||||||
|
|
||||||
|
Write32((0xF3 << 24) | (0xB << 20) | (encodedSize(Size) << 18) | EncodeVd(Vd) | \
|
||||||
|
(0x78 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VQRDMULH(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
_dbg_assert_msg_(DYNA_REC, !(Size & F_32), __FUNCTION__ " doesn't support float");
|
||||||
|
|
||||||
|
Write32((0xF3 << 24) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \
|
||||||
|
(0xB0 << 4) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VQRSHL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
_dbg_assert_msg_(DYNA_REC, !(Size & F_32), __FUNCTION__ " doesn't support float");
|
||||||
|
|
||||||
|
bool register_quad = Vd >= Q0;
|
||||||
|
|
||||||
|
Write32((0xF2 << 24) | (Size & I_UNSIGNED ? 1 << 24 : 0) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \
|
||||||
|
(0x51 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VQSHL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
_dbg_assert_msg_(DYNA_REC, !(Size & F_32), __FUNCTION__ " doesn't support float");
|
||||||
|
|
||||||
|
bool register_quad = Vd >= Q0;
|
||||||
|
|
||||||
|
Write32((0xF2 << 24) | (Size & I_UNSIGNED ? 1 << 24 : 0) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \
|
||||||
|
(0x41 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VQSUB(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
_dbg_assert_msg_(DYNA_REC, !(Size & F_32), __FUNCTION__ " doesn't support float");
|
||||||
|
|
||||||
|
bool register_quad = Vd >= Q0;
|
||||||
|
|
||||||
|
Write32((0xF2 << 24) | (Size & I_UNSIGNED ? 1 << 24 : 0) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \
|
||||||
|
(0x21 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VRADDHN(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
_dbg_assert_msg_(DYNA_REC, !(Size & F_32), __FUNCTION__ " doesn't support float");
|
||||||
|
|
||||||
|
Write32((0xF3 << 24) | (1 << 23) | ((encodedSize(Size) - 1) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \
|
||||||
|
(0x40 << 4) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VRECPE(u32 Size, ARMReg Vd, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
|
||||||
|
bool register_quad = Vd >= Q0;
|
||||||
|
|
||||||
|
Write32((0xF3 << 24) | (0xB << 20) | (0xB << 16) | EncodeVd(Vd) | \
|
||||||
|
(0x40 << 4) | (Size & F_32 ? 1 << 8 : 0) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VRECPS(ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
|
||||||
|
bool register_quad = Vd >= Q0;
|
||||||
|
|
||||||
|
Write32((0xF2 << 24) | EncodeVn(Vn) | EncodeVd(Vd) | (0xF1 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VRHADD(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
_dbg_assert_msg_(DYNA_REC, !(Size & F_32), __FUNCTION__ " doesn't support float");
|
||||||
|
|
||||||
|
bool register_quad = Vd >= Q0;
|
||||||
|
|
||||||
|
Write32((0xF2 << 24) | (Size & I_UNSIGNED ? 1 << 24 : 0) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \
|
||||||
|
(0x10 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VRSHL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
_dbg_assert_msg_(DYNA_REC, !(Size & F_32), __FUNCTION__ " doesn't support float");
|
||||||
|
|
||||||
|
bool register_quad = Vd >= Q0;
|
||||||
|
|
||||||
|
Write32((0xF2 << 24) | (Size & I_UNSIGNED ? 1 << 24 : 0) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \
|
||||||
|
(0x50 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VRSQRTE(u32 Size, ARMReg Vd, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
|
||||||
|
bool register_quad = Vd >= Q0;
|
||||||
Vd = SubBase(Vd);
|
Vd = SubBase(Vd);
|
||||||
Vn = SubBase(Vn);
|
|
||||||
Vm = SubBase(Vm);
|
Vm = SubBase(Vm);
|
||||||
|
|
||||||
Write32((0xF3 << 24) | ((Vd & 0x10) << 18) | (encodedSize(Size) << 20) | ((Vn & 0xF) << 16) \
|
Write32((0xF3 << 24) | (0xB << 20) | ((Vd & 0x10) << 18) | (0xB << 16)
|
||||||
| ((Vd & 0xF) << 12) | (0x8 << 8) | ((Vn & 0x10) << 3) | (1 << 6) \
|
| ((Vd & 0xF) << 12) | (9 << 7) | (Size & F_32 ? (1 << 8) : 0) | (register_quad << 6)
|
||||||
| ((Vm & 0x10) << 1) | (Vm & 0xF));
|
| ((Vm & 0x10) << 1) | (Vm & 0xF));
|
||||||
}
|
}
|
||||||
|
void NEONXEmitter::VRSQRTS(ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
|
||||||
void NEONXEmitter::VLD1(NEONElementType Size, ARMReg Vd, ARMReg Rn, NEONAlignment align, ARMReg Rm)
|
bool register_quad = Vd >= Q0;
|
||||||
|
|
||||||
|
Write32((0xF2 << 24) | (1 << 21) | EncodeVn(Vn) | EncodeVd(Vd) | \
|
||||||
|
(0xF1 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VRSUBHN(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
_dbg_assert_msg_(DYNA_REC, !(Size & F_32), __FUNCTION__ " doesn't support float");
|
||||||
|
|
||||||
|
Write32((0xF3 << 24) | (1 << 23) | ((encodedSize(Size) - 1) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \
|
||||||
|
(0x60 << 4) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VSHL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
_dbg_assert_msg_(DYNA_REC, !(Size & F_32), __FUNCTION__ " doesn't support float");
|
||||||
|
|
||||||
|
bool register_quad = Vd >= Q0;
|
||||||
|
|
||||||
|
Write32((0xF2 << 24) | (Size & I_UNSIGNED ? 1 << 24 : 0) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \
|
||||||
|
(0x40 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VSUB(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= Q0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
|
||||||
|
bool register_quad = Vd >= Q0;
|
||||||
|
|
||||||
|
if (Size & F_32)
|
||||||
|
Write32((0xF2 << 24) | (1 << 21) | EncodeVn(Vn) | EncodeVd(Vd) | \
|
||||||
|
(0xD0 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
|
else
|
||||||
|
Write32((0xF3 << 24) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \
|
||||||
|
(0x80 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VSUBHN(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= Q0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
|
||||||
|
Write32((0xF2 << 24) | (1 << 23) | ((encodedSize(Size) - 1) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \
|
||||||
|
(0x60 << 4) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VSUBL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= Q0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
|
||||||
|
Write32((0xF2 << 24) | (Size & I_UNSIGNED ? 1 << 24 : 0) | (1 << 23) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \
|
||||||
|
(0x20 << 4) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VSUBW(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= Q0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
|
||||||
|
Write32((0xF2 << 24) | (Size & I_UNSIGNED ? 1 << 24 : 0) | (1 << 23) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \
|
||||||
|
(0x30 << 4) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VSWP(ARMReg Vd, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= Q0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
|
||||||
|
bool register_quad = Vd >= Q0;
|
||||||
|
|
||||||
|
Write32((0xF3 << 24) | (0xB << 20) | (1 << 17) | EncodeVd(Vd) | \
|
||||||
|
(register_quad << 6) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VTRN(u32 Size, ARMReg Vd, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= Q0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
|
||||||
|
bool register_quad = Vd >= Q0;
|
||||||
|
|
||||||
|
Write32((0xF3 << 24) | (0xB << 20) | (encodedSize(Size) << 18) | (1 << 17) | EncodeVd(Vd) | \
|
||||||
|
(1 << 7) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VTST(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= Q0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
|
||||||
|
bool register_quad = Vd >= Q0;
|
||||||
|
|
||||||
|
Write32((0xF2 << 24) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \
|
||||||
|
(0x81 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VUZP(u32 Size, ARMReg Vd, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= Q0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
|
||||||
|
bool register_quad = Vd >= Q0;
|
||||||
|
|
||||||
|
Write32((0xF3 << 24) | (0xB << 20) | (encodedSize(Size) << 18) | (1 << 17) | EncodeVd(Vd) | \
|
||||||
|
(0x10 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VZIP(u32 Size, ARMReg Vd, ARMReg Vm)
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(DYNA_REC, Vd >= Q0, "Pass invalid register to " __FUNCTION__);
|
||||||
|
_dbg_assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use " __FUNCTION__ " when CPU doesn't support it");
|
||||||
|
|
||||||
|
bool register_quad = Vd >= Q0;
|
||||||
|
|
||||||
|
Write32((0xF3 << 24) | (0xB << 20) | (encodedSize(Size) << 18) | (1 << 17) | EncodeVd(Vd) | \
|
||||||
|
(0x18 << 4) | (register_quad << 6) | EncodeVm(Vm));
|
||||||
|
}
|
||||||
|
void NEONXEmitter::VLD1(u32 Size, ARMReg Vd, ARMReg Rn, NEONAlignment align, ARMReg Rm)
|
||||||
{
|
{
|
||||||
u32 spacing = 0x7; // Only support loading to 1 reg
|
u32 spacing = 0x7; // Only support loading to 1 reg
|
||||||
// Gets encoded as a double register
|
// Gets encoded as a double register
|
||||||
@ -1736,8 +2117,7 @@ void NEONXEmitter::VLD1(NEONElementType Size, ARMReg Vd, ARMReg Rn, NEONAlignmen
|
|||||||
| ((Vd & 0xF) << 12) | (spacing << 8) | (encodedSize(Size) << 6)
|
| ((Vd & 0xF) << 12) | (spacing << 8) | (encodedSize(Size) << 6)
|
||||||
| (align << 4) | Rm);
|
| (align << 4) | Rm);
|
||||||
}
|
}
|
||||||
|
void NEONXEmitter::VLD2(u32 Size, ARMReg Vd, ARMReg Rn, NEONAlignment align, ARMReg Rm)
|
||||||
void NEONXEmitter::VLD2(NEONElementType Size, ARMReg Vd, ARMReg Rn, NEONAlignment align, ARMReg Rm)
|
|
||||||
{
|
{
|
||||||
u32 spacing = 0x8; // Single spaced registers
|
u32 spacing = 0x8; // Single spaced registers
|
||||||
// Gets encoded as a double register
|
// Gets encoded as a double register
|
||||||
@ -1747,8 +2127,7 @@ void NEONXEmitter::VLD2(NEONElementType Size, ARMReg Vd, ARMReg Rn, NEONAlignmen
|
|||||||
| ((Vd & 0xF) << 12) | (spacing << 8) | (encodedSize(Size) << 6)
|
| ((Vd & 0xF) << 12) | (spacing << 8) | (encodedSize(Size) << 6)
|
||||||
| (align << 4) | Rm);
|
| (align << 4) | Rm);
|
||||||
}
|
}
|
||||||
|
void NEONXEmitter::VST1(u32 Size, ARMReg Vd, ARMReg Rn, NEONAlignment align, ARMReg Rm)
|
||||||
void NEONXEmitter::VST1(NEONElementType Size, ARMReg Vd, ARMReg Rn, NEONAlignment align, ARMReg Rm)
|
|
||||||
{
|
{
|
||||||
u32 spacing = 0x7; // Single spaced registers
|
u32 spacing = 0x7; // Single spaced registers
|
||||||
// Gets encoded as a double register
|
// Gets encoded as a double register
|
||||||
@ -1759,8 +2138,7 @@ void NEONXEmitter::VST1(NEONElementType Size, ARMReg Vd, ARMReg Rn, NEONAlignmen
|
|||||||
| (align << 4) | Rm);
|
| (align << 4) | Rm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NEONXEmitter::VREVX(u32 size, u32 Size, ARMReg Vd, ARMReg Vm)
|
||||||
void NEONXEmitter::VREVX(u32 size, NEONElementType Size, ARMReg Vd, ARMReg Vm)
|
|
||||||
{
|
{
|
||||||
bool register_quad = Vd >= Q0;
|
bool register_quad = Vd >= Q0;
|
||||||
Vd = SubBase(Vd);
|
Vd = SubBase(Vd);
|
||||||
@ -1771,44 +2149,19 @@ void NEONXEmitter::VREVX(u32 size, NEONElementType Size, ARMReg Vd, ARMReg Vm)
|
|||||||
| (register_quad << 6) | ((Vm & 0x10) << 1) | (Vm & 0xF));
|
| (register_quad << 6) | ((Vm & 0x10) << 1) | (Vm & 0xF));
|
||||||
}
|
}
|
||||||
|
|
||||||
void NEONXEmitter::VREV64(NEONElementType Size, ARMReg Vd, ARMReg Vm)
|
void NEONXEmitter::VREV64(u32 Size, ARMReg Vd, ARMReg Vm)
|
||||||
{
|
{
|
||||||
VREVX(0, Size, Vd, Vm);
|
VREVX(0, Size, Vd, Vm);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NEONXEmitter::VREV32(NEONElementType Size, ARMReg Vd, ARMReg Vm)
|
void NEONXEmitter::VREV32(u32 Size, ARMReg Vd, ARMReg Vm)
|
||||||
{
|
{
|
||||||
VREVX(1, Size, Vd, Vm);
|
VREVX(1, Size, Vd, Vm);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NEONXEmitter::VREV16(NEONElementType Size, ARMReg Vd, ARMReg Vm)
|
void NEONXEmitter::VREV16(u32 Size, ARMReg Vd, ARMReg Vm)
|
||||||
{
|
{
|
||||||
VREVX(2, Size, Vd, Vm);
|
VREVX(2, Size, Vd, Vm);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NEONXEmitter::VRSQRTE(NEONElementType Size, ARMReg Vd, ARMReg Vm)
|
|
||||||
{
|
|
||||||
bool register_quad = Vd >= Q0;
|
|
||||||
Vd = SubBase(Vd);
|
|
||||||
Vm = SubBase(Vm);
|
|
||||||
|
|
||||||
Write32((0xF3 << 24) | (0xB << 20) | ((Vd & 0x10) << 18) | (0xB << 16)
|
|
||||||
| ((Vd & 0xF) << 12) | (9 << 7) | (Size & F_32 ? (1 << 8) : 0) | (register_quad << 6)
|
|
||||||
| ((Vm & 0x10) << 1) | (Vm & 0xF));
|
|
||||||
}
|
|
||||||
|
|
||||||
void NEONXEmitter::VORR(ARMReg Vd, ARMReg Vn, ARMReg Vm)
|
|
||||||
{
|
|
||||||
bool register_quad = Vd >= Q0;
|
|
||||||
Vd = SubBase(Vd);
|
|
||||||
Vn = SubBase(Vn);
|
|
||||||
Vm = SubBase(Vm);
|
|
||||||
|
|
||||||
Write32((0xF2 << 24) | (0x1 << 21) | ((Vd & 0x10) << 18) | ((Vn & 0xF) << 16)
|
|
||||||
| ((Vd & 0xF) << 12) | (1 << 8) | ((Vn & 0x10) << 3)
|
|
||||||
| (register_quad << 6) | ((Vm & 0x10) << 1) | (1 << 4) | (Vm & 0xF));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,6 +338,15 @@ struct LiteralPool
|
|||||||
};
|
};
|
||||||
|
|
||||||
typedef const u8* JumpTarget;
|
typedef const u8* JumpTarget;
|
||||||
|
// XXX: Stop polluting the global namespace
|
||||||
|
const u32 I_8 = (1 << 0);
|
||||||
|
const u32 I_16 = (1 << 1);
|
||||||
|
const u32 I_32 = (1 << 2);
|
||||||
|
const u32 I_64 = (1 << 3);
|
||||||
|
const u32 I_SIGNED = (1 << 4);
|
||||||
|
const u32 I_UNSIGNED = (1 << 5);
|
||||||
|
const u32 F_32 = (1 << 6);
|
||||||
|
const u32 I_POLYNOMIAL = (1 << 7); // Only used in VMUL/VMULL
|
||||||
|
|
||||||
u32 EncodeVd(ARMReg Vd);
|
u32 EncodeVd(ARMReg Vd);
|
||||||
u32 EncodeVn(ARMReg Vn);
|
u32 EncodeVn(ARMReg Vn);
|
||||||
@ -572,17 +581,6 @@ public:
|
|||||||
|
|
||||||
}; // class ARMXEmitter
|
}; // class ARMXEmitter
|
||||||
|
|
||||||
enum NEONElementType
|
|
||||||
{
|
|
||||||
I_8 = (1 << 0),
|
|
||||||
I_16 = (1 << 1),
|
|
||||||
I_32 = (1 << 2),
|
|
||||||
I_64 = (1 << 3),
|
|
||||||
I_SIGNED = (1 << 4),
|
|
||||||
I_UNSIGNED = (1 << 5),
|
|
||||||
F_32 = (1 << 6)
|
|
||||||
};
|
|
||||||
|
|
||||||
enum NEONAlignment
|
enum NEONAlignment
|
||||||
{
|
{
|
||||||
ALIGN_NONE = 0,
|
ALIGN_NONE = 0,
|
||||||
@ -613,71 +611,105 @@ private:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VREVX(u32 size, NEONElementType Size, ARMReg Vd, ARMReg Vm);
|
void VREVX(u32 size, u32 Size, ARMReg Vd, ARMReg Vm);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NEONXEmitter(ARMXEmitter *emit)
|
NEONXEmitter(ARMXEmitter *emit)
|
||||||
: _emit(emit)
|
: _emit(emit)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void VABA(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VABA(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VABAL(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VABAL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VABD(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VABD(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VABDL(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VABDL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VABS(NEONElementType Size, ARMReg Vd, ARMReg Vm);
|
void VABS(u32 Size, ARMReg Vd, ARMReg Vm);
|
||||||
void VACGE(ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VACGE(ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VACGT(ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VACGT(ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VACLE(ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VACLE(ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VACLT(ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VACLT(ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VADD(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VADD(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VADDHN(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VADDHN(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VADDL(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VADDL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VADDW(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VADDW(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VAND(ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VAND(ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VBIC(ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VBIC(ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VBIF(ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VBIF(ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VBIT(ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VBIT(ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VBSL(ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VBSL(ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VCEQ(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VCEQ(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VCEQ(NEONElementType Size, ARMReg Vd, ARMReg Vm);
|
void VCEQ(u32 Size, ARMReg Vd, ARMReg Vm);
|
||||||
void VCGE(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VCGE(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VCGE(NEONElementType Size, ARMReg Vd, ARMReg Vm);
|
void VCGE(u32 Size, ARMReg Vd, ARMReg Vm);
|
||||||
void VCGT(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VCGT(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VCGT(NEONElementType Size, ARMReg Vd, ARMReg Vm);
|
void VCGT(u32 Size, ARMReg Vd, ARMReg Vm);
|
||||||
void VCLE(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VCLE(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VCLE(NEONElementType Size, ARMReg Vd, ARMReg Vm);
|
void VCLE(u32 Size, ARMReg Vd, ARMReg Vm);
|
||||||
void VCLS(NEONElementType Size, ARMReg Vd, ARMReg Vm);
|
void VCLS(u32 Size, ARMReg Vd, ARMReg Vm);
|
||||||
void VCLT(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VCLT(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VCLT(NEONElementType Size, ARMReg Vd, ARMReg Vm);
|
void VCLT(u32 Size, ARMReg Vd, ARMReg Vm);
|
||||||
void VCLZ(NEONElementType Size, ARMReg Vd, ARMReg Vm);
|
void VCLZ(u32 Size, ARMReg Vd, ARMReg Vm);
|
||||||
void VCNT(NEONElementType Size, ARMReg Vd, ARMReg Vm);
|
void VCNT(u32 Size, ARMReg Vd, ARMReg Vm);
|
||||||
void VDUP(NEONElementType Size, ARMReg Vd, ARMReg Vm, u8 index);
|
void VDUP(u32 Size, ARMReg Vd, ARMReg Vm, u8 index);
|
||||||
void VDUP(NEONElementType Size, ARMReg Vd, ARMReg Rt);
|
void VDUP(u32 Size, ARMReg Vd, ARMReg Rt);
|
||||||
void VEOR(ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VEOR(ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VEXT(ARMReg Vd, ARMReg Vn, ARMReg Vm, u8 index);
|
void VEXT(ARMReg Vd, ARMReg Vn, ARMReg Vm, u8 index);
|
||||||
void VFMA(ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VFMA(ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VFMS(ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VFMS(ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VHADD(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VHADD(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VHSUB(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VHSUB(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VMAX(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VMAX(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VMIN(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VMIN(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VMLA(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VMLA(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VMLS(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VMLS(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VMLAL(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VMLAL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VMLSL(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VMLSL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VSUB(NEONElementType Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VMUL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VREV64(NEONElementType Size, ARMReg Vd, ARMReg Vm);
|
void VMULL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
void VREV32(NEONElementType Size, ARMReg Vd, ARMReg Vm);
|
void VNEG(u32 Size, ARMReg Vd, ARMReg Vm);
|
||||||
void VREV16(NEONElementType Size, ARMReg Vd, ARMReg Vm);
|
void VORN(ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
|
|
||||||
void VRSQRTE(NEONElementType Size, ARMReg Vd, ARMReg Vm);
|
|
||||||
|
|
||||||
void VORR(ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
void VORR(ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
|
void VPADAL(u32 Size, ARMReg Vd, ARMReg Vm);
|
||||||
|
void VPADD(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
|
void VPADDL(u32 Size, ARMReg Vd, ARMReg Vm);
|
||||||
|
void VPMAX(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
|
void VPMIN(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
|
void VQABS(u32 Size, ARMReg Vd, ARMReg Vm);
|
||||||
|
void VQADD(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
|
void VQDMLAL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
|
void VQDMLSL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
|
void VQDMULH(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
|
void VQDMULL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
|
void VQNEG(u32 Size, ARMReg Vd, ARMReg Vm);
|
||||||
|
void VQRDMULH(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
|
void VQRSHL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
|
void VQSHL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
|
void VQSUB(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
|
void VRADDHN(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
|
void VRECPE(u32 Size, ARMReg Vd, ARMReg Vm);
|
||||||
|
void VRECPS(ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
|
void VRHADD(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
|
void VRSHL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
|
void VRSQRTE(u32 Size, ARMReg Vd, ARMReg Vm);
|
||||||
|
void VRSQRTS(ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
|
void VRSUBHN(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
|
void VSHL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
|
void VSUB(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
|
void VSUBHN(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
|
void VSUBL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
|
void VSUBW(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
|
void VSWP(ARMReg Vd, ARMReg Vm);
|
||||||
|
void VTRN(u32 Size, ARMReg Vd, ARMReg Vm);
|
||||||
|
void VTST(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm);
|
||||||
|
void VUZP(u32 Size, ARMReg Vd, ARMReg Vm);
|
||||||
|
void VZIP(u32 Size, ARMReg Vd, ARMReg Vm);
|
||||||
|
void VREV64(u32 Size, ARMReg Vd, ARMReg Vm);
|
||||||
|
void VREV32(u32 Size, ARMReg Vd, ARMReg Vm);
|
||||||
|
void VREV16(u32 Size, ARMReg Vd, ARMReg Vm);
|
||||||
|
|
||||||
void VLD1(NEONElementType Size, ARMReg Vd, ARMReg Rn, NEONAlignment align = ALIGN_NONE, ARMReg Rm = _PC);
|
void VLD1(u32 Size, ARMReg Vd, ARMReg Rn, NEONAlignment align = ALIGN_NONE, ARMReg Rm = _PC);
|
||||||
void VLD2(NEONElementType Size, ARMReg Vd, ARMReg Rn, NEONAlignment align = ALIGN_NONE, ARMReg Rm = _PC);
|
void VLD2(u32 Size, ARMReg Vd, ARMReg Rn, NEONAlignment align = ALIGN_NONE, ARMReg Rm = _PC);
|
||||||
|
|
||||||
void VST1(NEONElementType Size, ARMReg Vd, ARMReg Rn, NEONAlignment align = ALIGN_NONE, ARMReg Rm = _PC);
|
void VST1(u32 Size, ARMReg Vd, ARMReg Rn, NEONAlignment align = ALIGN_NONE, ARMReg Rm = _PC);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Everything that needs to generate X86 code should inherit from this.
|
// Everything that needs to generate X86 code should inherit from this.
|
||||||
|
@ -41,7 +41,14 @@ struct CPUInfo
|
|||||||
bool bLZCNT;
|
bool bLZCNT;
|
||||||
bool bSSE4A;
|
bool bSSE4A;
|
||||||
bool bAVX;
|
bool bAVX;
|
||||||
|
bool bFMA;
|
||||||
bool bAES;
|
bool bAES;
|
||||||
|
// FXSAVE/FXRSTOR
|
||||||
|
bool bFXSR;
|
||||||
|
// This flag indicates that the hardware supports some mode
|
||||||
|
// in which denormal inputs _and_ outputs are automatically set to (signed) zero.
|
||||||
|
// TODO: ARM
|
||||||
|
bool bFlushToZero;
|
||||||
bool bLAHFSAHF64;
|
bool bLAHFSAHF64;
|
||||||
bool bLongMode;
|
bool bLongMode;
|
||||||
|
|
||||||
|
@ -193,11 +193,13 @@ public:
|
|||||||
void DoPointer(T*& x, T* const base)
|
void DoPointer(T*& x, T* const base)
|
||||||
{
|
{
|
||||||
// pointers can be more than 2^31 apart, but you're using this function wrong if you need that much range
|
// pointers can be more than 2^31 apart, but you're using this function wrong if you need that much range
|
||||||
s32 offset = x - base;
|
ptrdiff_t offset = x - base;
|
||||||
Do(offset);
|
Do(offset);
|
||||||
if (mode == MODE_READ)
|
if (mode == MODE_READ)
|
||||||
|
{
|
||||||
x = base + offset;
|
x = base + offset;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Let's pretend std::list doesn't exist!
|
// Let's pretend std::list doesn't exist!
|
||||||
template <class T, LinkedListItem<T>* (*TNew)(), void (*TFree)(LinkedListItem<T>*), void (*TDo)(PointerWrap&, T*)>
|
template <class T, LinkedListItem<T>* (*TNew)(), void (*TFree)(LinkedListItem<T>*), void (*TDo)(PointerWrap&, T*)>
|
||||||
|
@ -31,7 +31,12 @@ struct ArraySizeImpl : public std::extent<T>
|
|||||||
#define b32(x) (b16(x) | (b16(x) >>16) )
|
#define b32(x) (b16(x) | (b16(x) >>16) )
|
||||||
#define ROUND_UP_POW2(x) (b32(x - 1) + 1)
|
#define ROUND_UP_POW2(x) (b32(x - 1) + 1)
|
||||||
|
|
||||||
#if defined __GNUC__ && !defined __SSSE3__ && !defined _M_GENERIC
|
#ifndef __GNUC_PREREQ
|
||||||
|
#define __GNUC_PREREQ(a, b) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined __GNUC__ && !__GNUC_PREREQ(4,9)) \
|
||||||
|
&& !defined __SSSE3__ && !defined _M_GENERIC
|
||||||
#include <emmintrin.h>
|
#include <emmintrin.h>
|
||||||
static __inline __m128i __attribute__((__always_inline__))
|
static __inline __m128i __attribute__((__always_inline__))
|
||||||
_mm_shuffle_epi8(__m128i a, __m128i mask)
|
_mm_shuffle_epi8(__m128i a, __m128i mask)
|
||||||
|
@ -36,7 +36,7 @@ namespace FPURoundMode
|
|||||||
|
|
||||||
void SetPrecisionMode(u32 mode);
|
void SetPrecisionMode(u32 mode);
|
||||||
|
|
||||||
void SetSIMDMode(u32 mode);
|
void SetSIMDMode(u32 roundingMode, u32 nonIEEEMode);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There are two different flavors of float to int conversion:
|
* There are two different flavors of float to int conversion:
|
||||||
|
@ -26,7 +26,7 @@ namespace FPURoundMode
|
|||||||
void SetPrecisionMode(u32 mode)
|
void SetPrecisionMode(u32 mode)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
void SetSIMDMode(u32 mode)
|
void SetSIMDMode(u32 mode, u32 nonIEEEMode)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
void SaveSIMDState()
|
void SaveSIMDState()
|
||||||
|
@ -64,10 +64,10 @@ inline float FlushToZero(float f)
|
|||||||
return x.f;
|
return x.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline double FlushToZeroAsFloat(double d)
|
inline double FlushToZero(double d)
|
||||||
{
|
{
|
||||||
IntDouble x; x.d = d;
|
IntDouble x; x.d = d;
|
||||||
if ((x.i & DOUBLE_EXP) < 0x3800000000000000ULL)
|
if ((x.i & DOUBLE_EXP) == 0)
|
||||||
x.i &= DOUBLE_SIGN; // turn into signed zero
|
x.i &= DOUBLE_SIGN; // turn into signed zero
|
||||||
return x.d;
|
return x.d;
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <cinttypes>
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <unistd.h> // for unlink()
|
#include <unistd.h> // for unlink()
|
||||||
@ -196,7 +197,7 @@ bool SDCardCreate(u64 disk_size /*in MB*/, const char* filename)
|
|||||||
disk_size *= 1024 * 1024;
|
disk_size *= 1024 * 1024;
|
||||||
|
|
||||||
if (disk_size < 0x800000 || disk_size > 0x800000000ULL) {
|
if (disk_size < 0x800000 || disk_size > 0x800000000ULL) {
|
||||||
ERROR_LOG(COMMON, "Trying to create SD Card image of size %lliMB is out of range (8MB-32GB)", disk_size/(1024*1024));
|
ERROR_LOG(COMMON, "Trying to create SD Card image of size %" PRIu64 "MB is out of range (8MB-32GB)", disk_size/(1024*1024));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -404,26 +404,30 @@ std::string UriEncode(const std::string & sSrc)
|
|||||||
|
|
||||||
std::string UTF16ToUTF8(const std::wstring& input)
|
std::string UTF16ToUTF8(const std::wstring& input)
|
||||||
{
|
{
|
||||||
auto const size = WideCharToMultiByte(CP_UTF8, 0, input.data(), input.size(), nullptr, 0, nullptr, nullptr);
|
auto const size = WideCharToMultiByte(CP_UTF8, 0, input.data(), (int)input.size(), nullptr, 0, nullptr, nullptr);
|
||||||
|
|
||||||
std::string output;
|
std::string output;
|
||||||
output.resize(size);
|
output.resize(size);
|
||||||
|
|
||||||
if (size == 0 || size != WideCharToMultiByte(CP_UTF8, 0, input.data(), input.size(), &output[0], output.size(), nullptr, nullptr))
|
if (size == 0 || size != WideCharToMultiByte(CP_UTF8, 0, input.data(), (int)input.size(), &output[0], (int)output.size(), nullptr, nullptr))
|
||||||
|
{
|
||||||
output.clear();
|
output.clear();
|
||||||
|
}
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::wstring CPToUTF16(u32 code_page, const std::string& input)
|
std::wstring CPToUTF16(u32 code_page, const std::string& input)
|
||||||
{
|
{
|
||||||
auto const size = MultiByteToWideChar(code_page, 0, input.data(), input.size(), nullptr, 0);
|
auto const size = MultiByteToWideChar(code_page, 0, input.data(), (int)input.size(), nullptr, 0);
|
||||||
|
|
||||||
std::wstring output;
|
std::wstring output;
|
||||||
output.resize(size);
|
output.resize(size);
|
||||||
|
|
||||||
if (size == 0 || size != MultiByteToWideChar(code_page, 0, input.data(), input.size(), &output[0], output.size()))
|
if (size == 0 || size != MultiByteToWideChar(code_page, 0, input.data(), (int)input.size(), &output[0], (int)output.size()))
|
||||||
|
{
|
||||||
output.clear();
|
output.clear();
|
||||||
|
}
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
#include "FileUtil.h"
|
#include "FileUtil.h"
|
||||||
#include "SysConf.h"
|
#include "SysConf.h"
|
||||||
|
|
||||||
|
#include <cinttypes>
|
||||||
|
|
||||||
SysConf::SysConf()
|
SysConf::SysConf()
|
||||||
: m_IsValid(false)
|
: m_IsValid(false)
|
||||||
{
|
{
|
||||||
@ -42,7 +44,7 @@ bool SysConf::LoadFromFile(const char *filename)
|
|||||||
u64 size = File::GetSize(filename);
|
u64 size = File::GetSize(filename);
|
||||||
if (size != SYSCONF_SIZE)
|
if (size != SYSCONF_SIZE)
|
||||||
{
|
{
|
||||||
if (AskYesNoT("Your SYSCONF file is the wrong size.\nIt should be 0x%04x (but is 0x%04llx)\nDo you want to generate a new one?",
|
if (AskYesNoT("Your SYSCONF file is the wrong size.\nIt should be 0x%04x (but is 0x%04" PRIx64 ")\nDo you want to generate a new one?",
|
||||||
SYSCONF_SIZE, size))
|
SYSCONF_SIZE, size))
|
||||||
{
|
{
|
||||||
GenerateSysConf();
|
GenerateSysConf();
|
||||||
@ -151,7 +153,7 @@ unsigned int create_item(SSysConfEntry &item, SysconfType type, const std::strin
|
|||||||
{
|
{
|
||||||
item.offset = offset;
|
item.offset = offset;
|
||||||
item.type = type;
|
item.type = type;
|
||||||
item.nameLength = name.length();
|
item.nameLength = (u8)(name.length());
|
||||||
strncpy(item.name, name.c_str(), 32);
|
strncpy(item.name, name.c_str(), 32);
|
||||||
item.dataLength = data_length;
|
item.dataLength = data_length;
|
||||||
item.data = new u8[data_length];
|
item.data = new u8[data_length];
|
||||||
|
@ -38,7 +38,7 @@ class Event
|
|||||||
public:
|
public:
|
||||||
Event()
|
Event()
|
||||||
: is_set(false)
|
: is_set(false)
|
||||||
{};
|
{}
|
||||||
|
|
||||||
void Set()
|
void Set()
|
||||||
{
|
{
|
||||||
@ -53,34 +53,20 @@ public:
|
|||||||
void Wait()
|
void Wait()
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lk(m_mutex);
|
std::unique_lock<std::mutex> lk(m_mutex);
|
||||||
m_condvar.wait(lk, IsSet(this));
|
m_condvar.wait(lk, [&]{ return is_set; });
|
||||||
is_set = false;
|
is_set = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reset()
|
void Reset()
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lk(m_mutex);
|
std::unique_lock<std::mutex> lk(m_mutex);
|
||||||
// no other action required, since wait loops on the predicate and any lingering signal will get cleared on the first iteration
|
// no other action required, since wait loops on
|
||||||
|
// the predicate and any lingering signal will get
|
||||||
|
// cleared on the first iteration
|
||||||
is_set = false;
|
is_set = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class IsSet
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
IsSet(const Event* ev)
|
|
||||||
: m_event(ev)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool operator()()
|
|
||||||
{
|
|
||||||
return m_event->is_set;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const Event* const m_event;
|
|
||||||
};
|
|
||||||
|
|
||||||
volatile bool is_set;
|
volatile bool is_set;
|
||||||
std::condition_variable m_condvar;
|
std::condition_variable m_condvar;
|
||||||
std::mutex m_mutex;
|
std::mutex m_mutex;
|
||||||
@ -110,28 +96,12 @@ public:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_condvar.wait(lk, IsDoneWating(this));
|
m_condvar.wait(lk, [&]{ return (0 == m_waiting); });
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class IsDoneWating
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
IsDoneWating(const Barrier* bar)
|
|
||||||
: m_bar(bar)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool operator()()
|
|
||||||
{
|
|
||||||
return (0 == m_bar->m_waiting);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const Barrier* const m_bar;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::condition_variable m_condvar;
|
std::condition_variable m_condvar;
|
||||||
std::mutex m_mutex;
|
std::mutex m_mutex;
|
||||||
const size_t m_count;
|
const size_t m_count;
|
||||||
|
@ -162,6 +162,34 @@ void CPUInfo::Detect()
|
|||||||
if ((cpu_id[2] >> 20) & 1) bSSE4_2 = true;
|
if ((cpu_id[2] >> 20) & 1) bSSE4_2 = true;
|
||||||
if ((cpu_id[2] >> 25) & 1) bAES = true;
|
if ((cpu_id[2] >> 25) & 1) bAES = true;
|
||||||
|
|
||||||
|
// To check DAZ support, we first need to check FXSAVE support.
|
||||||
|
if ((cpu_id[3] >> 24) & 1)
|
||||||
|
{
|
||||||
|
// We can use FXSAVE.
|
||||||
|
bFXSR = true;
|
||||||
|
|
||||||
|
GC_ALIGNED16(u8 fx_state[512]);
|
||||||
|
memset(fx_state, 0, sizeof(fx_state));
|
||||||
|
#ifdef _WIN32
|
||||||
|
#ifdef _M_IX86
|
||||||
|
_fxsave(fx_state);
|
||||||
|
#elif defined (_M_X64)
|
||||||
|
_fxsave64(fx_state);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
__asm__("fxsave %0" : "=m" (fx_state));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// lowest byte of MXCSR_MASK
|
||||||
|
if ((fx_state[0x1C] >> 6) & 1)
|
||||||
|
{
|
||||||
|
// On x86, the FTZ field (supported since SSE1) only flushes denormal _outputs_ to zero,
|
||||||
|
// now that we checked DAZ support (flushing denormal _inputs_ to zero),
|
||||||
|
// we can set our generic flag.
|
||||||
|
bFlushToZero = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// AVX support requires 3 separate checks:
|
// AVX support requires 3 separate checks:
|
||||||
// - Is the AVX bit set in CPUID?
|
// - Is the AVX bit set in CPUID?
|
||||||
// - Is the XSAVE bit set in CPUID?
|
// - Is the XSAVE bit set in CPUID?
|
||||||
@ -169,7 +197,11 @@ void CPUInfo::Detect()
|
|||||||
if (((cpu_id[2] >> 28) & 1) && ((cpu_id[2] >> 27) & 1))
|
if (((cpu_id[2] >> 28) & 1) && ((cpu_id[2] >> 27) & 1))
|
||||||
{
|
{
|
||||||
if ((_xgetbv(_XCR_XFEATURE_ENABLED_MASK) & 0x6) == 0x6)
|
if ((_xgetbv(_XCR_XFEATURE_ENABLED_MASK) & 0x6) == 0x6)
|
||||||
|
{
|
||||||
bAVX = true;
|
bAVX = true;
|
||||||
|
if ((cpu_id[2] >> 12) & 1)
|
||||||
|
bFMA = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (max_ex_fn >= 0x80000004) {
|
if (max_ex_fn >= 0x80000004) {
|
||||||
@ -218,13 +250,19 @@ std::string CPUInfo::Summarize()
|
|||||||
{
|
{
|
||||||
std::string sum(cpu_string);
|
std::string sum(cpu_string);
|
||||||
if (bSSE) sum += ", SSE";
|
if (bSSE) sum += ", SSE";
|
||||||
if (bSSE2) sum += ", SSE2";
|
if (bSSE2)
|
||||||
|
{
|
||||||
|
sum += ", SSE2";
|
||||||
|
if (!bFlushToZero)
|
||||||
|
sum += " (but not DAZ!)";
|
||||||
|
}
|
||||||
if (bSSE3) sum += ", SSE3";
|
if (bSSE3) sum += ", SSE3";
|
||||||
if (bSSSE3) sum += ", SSSE3";
|
if (bSSSE3) sum += ", SSSE3";
|
||||||
if (bSSE4_1) sum += ", SSE4.1";
|
if (bSSE4_1) sum += ", SSE4.1";
|
||||||
if (bSSE4_2) sum += ", SSE4.2";
|
if (bSSE4_2) sum += ", SSE4.2";
|
||||||
if (HTT) sum += ", HTT";
|
if (HTT) sum += ", HTT";
|
||||||
if (bAVX) sum += ", AVX";
|
if (bAVX) sum += ", AVX";
|
||||||
|
if (bFMA) sum += ", FMA";
|
||||||
if (bAES) sum += ", AES";
|
if (bAES) sum += ", AES";
|
||||||
if (bLongMode) sum += ", 64-bit support";
|
if (bLongMode) sum += ", 64-bit support";
|
||||||
return sum;
|
return sum;
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#include "x64ABI.h"
|
#include "x64ABI.h"
|
||||||
#include "CPUDetect.h"
|
#include "CPUDetect.h"
|
||||||
|
|
||||||
|
#include <cinttypes>
|
||||||
|
|
||||||
namespace Gen
|
namespace Gen
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -154,6 +156,40 @@ void OpArg::WriteRex(XEmitter *emit, int opBits, int bits, int customOp) const
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpArg::WriteVex(XEmitter* emit, int size, int packed, Gen::X64Reg regOp1, Gen::X64Reg regOp2) const
|
||||||
|
{
|
||||||
|
int R = !(regOp1 & 8);
|
||||||
|
int X = !(indexReg & 8);
|
||||||
|
int B = !(offsetOrBaseReg & 8);
|
||||||
|
|
||||||
|
// not so sure about this one...
|
||||||
|
int W = 0;
|
||||||
|
|
||||||
|
// aka map_select in AMD manuals
|
||||||
|
// only support VEX opcode map 1 for now (analog to secondary opcode map)
|
||||||
|
int mmmmm = 1;
|
||||||
|
|
||||||
|
int vvvv = (regOp2 == X64Reg::INVALID_REG) ? 0xf : (regOp2 ^ 0xf);
|
||||||
|
int L = size == 256;
|
||||||
|
int pp = (packed << 1) | (size == 64);
|
||||||
|
|
||||||
|
// do we need any VEX fields that only appear in the three-byte form?
|
||||||
|
if (X == 1 && B == 1 && W == 0 && mmmmm == 1)
|
||||||
|
{
|
||||||
|
u8 RvvvvLpp = (R << 7) | (vvvv << 3) | (L << 1) | pp;
|
||||||
|
emit->Write8(0xC5);
|
||||||
|
emit->Write8(RvvvvLpp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
u8 RXBmmmmm = (R << 7) | (X << 6) | (B << 5) | mmmmm;
|
||||||
|
u8 WvvvvLpp = (W << 7) | (vvvv << 3) | (L << 1) | pp;
|
||||||
|
emit->Write8(0xC4);
|
||||||
|
emit->Write8(RXBmmmmm);
|
||||||
|
emit->Write8(WvvvvLpp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OpArg::WriteRest(XEmitter *emit, int extraBytes, X64Reg _operandReg,
|
void OpArg::WriteRest(XEmitter *emit, int extraBytes, X64Reg _operandReg,
|
||||||
bool warn_64bit_offset) const
|
bool warn_64bit_offset) const
|
||||||
{
|
{
|
||||||
@ -176,7 +212,7 @@ void OpArg::WriteRest(XEmitter *emit, int extraBytes, X64Reg _operandReg,
|
|||||||
_assert_msg_(DYNA_REC, (distance < 0x80000000LL
|
_assert_msg_(DYNA_REC, (distance < 0x80000000LL
|
||||||
&& distance >= -0x80000000LL) ||
|
&& distance >= -0x80000000LL) ||
|
||||||
!warn_64bit_offset,
|
!warn_64bit_offset,
|
||||||
"WriteRest: op out of range (0x%llx uses 0x%llx)",
|
"WriteRest: op out of range (0x%" PRIx64 " uses 0x%" PRIx64 ")",
|
||||||
ripAddr, offset);
|
ripAddr, offset);
|
||||||
s32 offs = (s32)distance;
|
s32 offs = (s32)distance;
|
||||||
emit->Write32((u32)offs);
|
emit->Write32((u32)offs);
|
||||||
@ -1141,6 +1177,18 @@ void XEmitter::WriteSSEOp(int size, u8 sseOp, bool packed, X64Reg regOp, OpArg a
|
|||||||
arg.WriteRest(this, extrabytes);
|
arg.WriteRest(this, extrabytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void XEmitter::WriteAVXOp(int size, u8 sseOp, bool packed, X64Reg regOp, OpArg arg, int extrabytes)
|
||||||
|
{
|
||||||
|
WriteAVXOp(size, sseOp, packed, regOp, X64Reg::INVALID_REG, arg, extrabytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void XEmitter::WriteAVXOp(int size, u8 sseOp, bool packed, X64Reg regOp1, X64Reg regOp2, OpArg arg, int extrabytes)
|
||||||
|
{
|
||||||
|
arg.WriteVex(this, size, packed, regOp1, regOp2);
|
||||||
|
Write8(sseOp);
|
||||||
|
arg.WriteRest(this, extrabytes, regOp1);
|
||||||
|
}
|
||||||
|
|
||||||
void XEmitter::MOVD_xmm(X64Reg dest, const OpArg &arg) {WriteSSEOp(64, 0x6E, true, dest, arg, 0);}
|
void XEmitter::MOVD_xmm(X64Reg dest, const OpArg &arg) {WriteSSEOp(64, 0x6E, true, dest, arg, 0);}
|
||||||
void XEmitter::MOVD_xmm(const OpArg &arg, X64Reg src) {WriteSSEOp(64, 0x7E, true, src, arg, 0);}
|
void XEmitter::MOVD_xmm(const OpArg &arg, X64Reg src) {WriteSSEOp(64, 0x7E, true, src, arg, 0);}
|
||||||
|
|
||||||
@ -1444,6 +1492,13 @@ void XEmitter::PMOVMSKB(X64Reg dest, OpArg arg) {WriteSSEOp(64, 0xD7, true, d
|
|||||||
|
|
||||||
void XEmitter::PSHUFLW(X64Reg regOp, OpArg arg, u8 shuffle) {WriteSSEOp(64, 0x70, false, regOp, arg, 1); Write8(shuffle);}
|
void XEmitter::PSHUFLW(X64Reg regOp, OpArg arg, u8 shuffle) {WriteSSEOp(64, 0x70, false, regOp, arg, 1); Write8(shuffle);}
|
||||||
|
|
||||||
|
// VEX
|
||||||
|
void XEmitter::VADDSD(X64Reg regOp1, X64Reg regOp2, OpArg arg) {WriteAVXOp(64, sseADD, false, regOp1, regOp2, arg);}
|
||||||
|
void XEmitter::VSUBSD(X64Reg regOp1, X64Reg regOp2, OpArg arg) {WriteAVXOp(64, sseSUB, false, regOp1, regOp2, arg);}
|
||||||
|
void XEmitter::VMULSD(X64Reg regOp1, X64Reg regOp2, OpArg arg) {WriteAVXOp(64, sseMUL, false, regOp1, regOp2, arg);}
|
||||||
|
void XEmitter::VDIVSD(X64Reg regOp1, X64Reg regOp2, OpArg arg) {WriteAVXOp(64, sseDIV, false, regOp1, regOp2, arg);}
|
||||||
|
void XEmitter::VSQRTSD(X64Reg regOp1, X64Reg regOp2, OpArg arg) {WriteAVXOp(64, sseSQRT, false, regOp1, regOp2, arg);}
|
||||||
|
|
||||||
// Prefixes
|
// Prefixes
|
||||||
|
|
||||||
void XEmitter::LOCK() { Write8(0xF0); }
|
void XEmitter::LOCK() { Write8(0xF0); }
|
||||||
|
@ -33,6 +33,9 @@ enum X64Reg
|
|||||||
XMM0=0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
|
XMM0=0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
|
||||||
XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15,
|
XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15,
|
||||||
|
|
||||||
|
YMM0=0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7,
|
||||||
|
YMM8, YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15,
|
||||||
|
|
||||||
INVALID_REG = 0xFFFFFFFF
|
INVALID_REG = 0xFFFFFFFF
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -111,6 +114,7 @@ struct OpArg
|
|||||||
offset = _offset;
|
offset = _offset;
|
||||||
}
|
}
|
||||||
void WriteRex(XEmitter *emit, int opBits, int bits, int customOp = -1) const;
|
void WriteRex(XEmitter *emit, int opBits, int bits, int customOp = -1) const;
|
||||||
|
void WriteVex(XEmitter* emit, int size, int packed, Gen::X64Reg regOp1, X64Reg regOp2) const;
|
||||||
void WriteRest(XEmitter *emit, int extraBytes=0, X64Reg operandReg=(X64Reg)0xFF, bool warn_64bit_offset = true) const;
|
void WriteRest(XEmitter *emit, int extraBytes=0, X64Reg operandReg=(X64Reg)0xFF, bool warn_64bit_offset = true) const;
|
||||||
void WriteSingleByteOp(XEmitter *emit, u8 op, X64Reg operandReg, int bits);
|
void WriteSingleByteOp(XEmitter *emit, u8 op, X64Reg operandReg, int bits);
|
||||||
// This one is public - must be written to
|
// This one is public - must be written to
|
||||||
@ -239,6 +243,8 @@ private:
|
|||||||
void WriteBitTest(int bits, OpArg &dest, OpArg &index, int ext);
|
void WriteBitTest(int bits, OpArg &dest, OpArg &index, int ext);
|
||||||
void WriteMXCSR(OpArg arg, int ext);
|
void WriteMXCSR(OpArg arg, int ext);
|
||||||
void WriteSSEOp(int size, u8 sseOp, bool packed, X64Reg regOp, OpArg arg, int extrabytes = 0);
|
void WriteSSEOp(int size, u8 sseOp, bool packed, X64Reg regOp, OpArg arg, int extrabytes = 0);
|
||||||
|
void WriteAVXOp(int size, u8 sseOp, bool packed, X64Reg regOp, OpArg arg, int extrabytes = 0);
|
||||||
|
void WriteAVXOp(int size, u8 sseOp, bool packed, X64Reg regOp1, X64Reg regOp2, OpArg arg, int extrabytes = 0);
|
||||||
void WriteNormalOp(XEmitter *emit, int bits, NormalOp op, const OpArg &a1, const OpArg &a2);
|
void WriteNormalOp(XEmitter *emit, int bits, NormalOp op, const OpArg &a1, const OpArg &a2);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -616,6 +622,13 @@ public:
|
|||||||
void PSRAW(X64Reg reg, int shift);
|
void PSRAW(X64Reg reg, int shift);
|
||||||
void PSRAD(X64Reg reg, int shift);
|
void PSRAD(X64Reg reg, int shift);
|
||||||
|
|
||||||
|
// AVX
|
||||||
|
void VADDSD(X64Reg regOp1, X64Reg regOp2, OpArg arg);
|
||||||
|
void VSUBSD(X64Reg regOp1, X64Reg regOp2, OpArg arg);
|
||||||
|
void VMULSD(X64Reg regOp1, X64Reg regOp2, OpArg arg);
|
||||||
|
void VDIVSD(X64Reg regOp1, X64Reg regOp2, OpArg arg);
|
||||||
|
void VSQRTSD(X64Reg regOp1, X64Reg regOp2, OpArg arg);
|
||||||
|
|
||||||
void RTDSC();
|
void RTDSC();
|
||||||
|
|
||||||
// Utility functions
|
// Utility functions
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "FPURoundMode.h"
|
#include "FPURoundMode.h"
|
||||||
|
#include "CPUDetect.h"
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
static const unsigned short FPU_ROUND_NEAR = 0 << 10;
|
static const unsigned short FPU_ROUND_NEAR = 0 << 10;
|
||||||
@ -14,8 +15,11 @@ static const unsigned short FPU_ROUND_MASK = 3 << 10;
|
|||||||
#include <xmmintrin.h>
|
#include <xmmintrin.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const u32 MASKS = 0x1F80; // mask away the interrupts.
|
// OR-mask for disabling FPU exceptions (bits 7-12 in the MXCSR register)
|
||||||
|
const u32 EXCEPTION_MASK = 0x1F80;
|
||||||
|
// Denormals-Are-Zero (non-IEEE mode: denormal inputs are set to +/- 0)
|
||||||
const u32 DAZ = 0x40;
|
const u32 DAZ = 0x40;
|
||||||
|
// Flush-To-Zero (non-IEEE mode: denormal outputs are set to +/- 0)
|
||||||
const u32 FTZ = 0x8000;
|
const u32 FTZ = 0x8000;
|
||||||
|
|
||||||
namespace FPURoundMode
|
namespace FPURoundMode
|
||||||
@ -79,16 +83,28 @@ namespace FPURoundMode
|
|||||||
//but still - set any useful sse options here
|
//but still - set any useful sse options here
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
void SetSIMDMode(u32 mode)
|
|
||||||
|
void SetSIMDMode(u32 roundingMode, u32 nonIEEEMode)
|
||||||
{
|
{
|
||||||
static const u32 ssetable[4] =
|
// lookup table for FPSCR.RN-to-MXCSR.RC translation
|
||||||
|
static const u32 roundingModeLUT[4] =
|
||||||
{
|
{
|
||||||
(0 << 13) | MASKS,
|
(0 << 13) | EXCEPTION_MASK, // nearest
|
||||||
(3 << 13) | MASKS,
|
(3 << 13) | EXCEPTION_MASK, // -inf
|
||||||
(2 << 13) | MASKS,
|
(2 << 13) | EXCEPTION_MASK, // +inf
|
||||||
(1 << 13) | MASKS,
|
(1 << 13) | EXCEPTION_MASK, // zero
|
||||||
};
|
};
|
||||||
u32 csr = ssetable[mode];
|
u32 csr = roundingModeLUT[roundingMode];
|
||||||
|
|
||||||
|
static const u32 denormalLUT[2] =
|
||||||
|
{
|
||||||
|
FTZ, // flush-to-zero only
|
||||||
|
FTZ | DAZ, // flush-to-zero and denormals-are-zero (may not be supported)
|
||||||
|
};
|
||||||
|
if (nonIEEEMode)
|
||||||
|
{
|
||||||
|
csr |= denormalLUT[cpu_info.bFlushToZero];
|
||||||
|
}
|
||||||
_mm_setcsr(csr);
|
_mm_setcsr(csr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,6 +133,9 @@
|
|||||||
<Filter Include="IPC HLE %28IOS/Starlet%29\USB/BT/Wiimote">
|
<Filter Include="IPC HLE %28IOS/Starlet%29\USB/BT/Wiimote">
|
||||||
<UniqueIdentifier>{8352be4d-d37d-4f55-adec-b940a9712802}</UniqueIdentifier>
|
<UniqueIdentifier>{8352be4d-d37d-4f55-adec-b940a9712802}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="PowerPC\JitILCommon">
|
||||||
|
<UniqueIdentifier>{827afa93-1a80-4835-93ae-b5516d95867f}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Src\BootManager.cpp" />
|
<ClCompile Include="Src\BootManager.cpp" />
|
||||||
@ -636,39 +639,12 @@
|
|||||||
<ClCompile Include="Src\PowerPC\JitCommon\JitCache.cpp">
|
<ClCompile Include="Src\PowerPC\JitCommon\JitCache.cpp">
|
||||||
<Filter>PowerPC\JitCommon</Filter>
|
<Filter>PowerPC\JitCommon</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Src\PowerPC\Jit64IL\IR.cpp">
|
|
||||||
<Filter>PowerPC\JitIL</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Src\PowerPC\Jit64IL\IR_X86.cpp">
|
<ClCompile Include="Src\PowerPC\Jit64IL\IR_X86.cpp">
|
||||||
<Filter>PowerPC\JitIL</Filter>
|
<Filter>PowerPC\JitIL</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Src\PowerPC\Jit64IL\JitIL.cpp">
|
<ClCompile Include="Src\PowerPC\Jit64IL\JitIL.cpp">
|
||||||
<Filter>PowerPC\JitIL</Filter>
|
<Filter>PowerPC\JitIL</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Src\PowerPC\Jit64IL\JitIL_Branch.cpp">
|
|
||||||
<Filter>PowerPC\JitIL</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Src\PowerPC\Jit64IL\JitIL_FloatingPoint.cpp">
|
|
||||||
<Filter>PowerPC\JitIL</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Src\PowerPC\Jit64IL\JitIL_Integer.cpp">
|
|
||||||
<Filter>PowerPC\JitIL</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Src\PowerPC\Jit64IL\JitIL_LoadStore.cpp">
|
|
||||||
<Filter>PowerPC\JitIL</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Src\PowerPC\Jit64IL\JitIL_LoadStoreFloating.cpp">
|
|
||||||
<Filter>PowerPC\JitIL</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Src\PowerPC\Jit64IL\JitIL_LoadStorePaired.cpp">
|
|
||||||
<Filter>PowerPC\JitIL</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Src\PowerPC\Jit64IL\JitIL_Paired.cpp">
|
|
||||||
<Filter>PowerPC\JitIL</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Src\PowerPC\Jit64IL\JitIL_SystemRegisters.cpp">
|
|
||||||
<Filter>PowerPC\JitIL</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Src\PowerPC\Jit64IL\JitIL_Tables.cpp">
|
<ClCompile Include="Src\PowerPC\Jit64IL\JitIL_Tables.cpp">
|
||||||
<Filter>PowerPC\JitIL</Filter>
|
<Filter>PowerPC\JitIL</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -706,6 +682,33 @@
|
|||||||
<Filter>PowerPC\Jit64</Filter>
|
<Filter>PowerPC\Jit64</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Src\stdafx.cpp" />
|
<ClCompile Include="Src\stdafx.cpp" />
|
||||||
|
<ClCompile Include="Src\PowerPC\JitILCommon\JitILBase_Branch.cpp">
|
||||||
|
<Filter>PowerPC\JitILCommon</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Src\PowerPC\JitILCommon\JitILBase_FloatingPoint.cpp">
|
||||||
|
<Filter>PowerPC\JitILCommon</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Src\PowerPC\JitILCommon\JitILBase_Integer.cpp">
|
||||||
|
<Filter>PowerPC\JitILCommon</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Src\PowerPC\JitILCommon\JitILBase_LoadStore.cpp">
|
||||||
|
<Filter>PowerPC\JitILCommon</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Src\PowerPC\JitILCommon\JitILBase_LoadStoreFloating.cpp">
|
||||||
|
<Filter>PowerPC\JitILCommon</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Src\PowerPC\JitILCommon\JitILBase_LoadStorePaired.cpp">
|
||||||
|
<Filter>PowerPC\JitILCommon</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Src\PowerPC\JitILCommon\JitILBase_Paired.cpp">
|
||||||
|
<Filter>PowerPC\JitILCommon</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Src\PowerPC\JitILCommon\JitILBase_SystemRegisters.cpp">
|
||||||
|
<Filter>PowerPC\JitILCommon</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Src\PowerPC\JitILCommon\IR.cpp">
|
||||||
|
<Filter>PowerPC\JitILCommon</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Src\BootManager.h" />
|
<ClInclude Include="Src\BootManager.h" />
|
||||||
@ -1190,9 +1193,6 @@
|
|||||||
<ClInclude Include="Src\PowerPC\JitCommon\JitCache.h">
|
<ClInclude Include="Src\PowerPC\JitCommon\JitCache.h">
|
||||||
<Filter>PowerPC\JitCommon</Filter>
|
<Filter>PowerPC\JitCommon</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Src\PowerPC\Jit64IL\IR.h">
|
|
||||||
<Filter>PowerPC\JitIL</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Src\PowerPC\Jit64IL\JitIL.h">
|
<ClInclude Include="Src\PowerPC\Jit64IL\JitIL.h">
|
||||||
<Filter>PowerPC\JitIL</Filter>
|
<Filter>PowerPC\JitIL</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@ -1209,6 +1209,12 @@
|
|||||||
<Filter>PowerPC\Jit64</Filter>
|
<Filter>PowerPC\Jit64</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Src\stdafx.h" />
|
<ClInclude Include="Src\stdafx.h" />
|
||||||
|
<ClInclude Include="Src\PowerPC\JitILCommon\JitILBase.h">
|
||||||
|
<Filter>PowerPC\JitILCommon</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Src\PowerPC\JitILCommon\IR.h">
|
||||||
|
<Filter>PowerPC\JitILCommon</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Text Include="CMakeLists.txt" />
|
<Text Include="CMakeLists.txt" />
|
||||||
|
@ -17,8 +17,8 @@
|
|||||||
#include "PowerPCDisasm.h"
|
#include "PowerPCDisasm.h"
|
||||||
#include "Console.h"
|
#include "Console.h"
|
||||||
|
|
||||||
#define CASE1(x) if (memcmp(cmd, x, 2*sizeof(TCHAR))==0)
|
#define CASE1(x) if (!strcmp(cmd, (x)))
|
||||||
#define CASE(x) else if (memcmp(cmd, x, 4*sizeof(TCHAR))==0)
|
#define CASE(x) else if (!strcmp(cmd, (x)))
|
||||||
|
|
||||||
void Console_Submit(const char *cmd)
|
void Console_Submit(const char *cmd)
|
||||||
{
|
{
|
||||||
@ -27,7 +27,7 @@ void Console_Submit(const char *cmd)
|
|||||||
Core::StartTrace(false);
|
Core::StartTrace(false);
|
||||||
INFO_LOG(CONSOLE, "Read tracing started.");
|
INFO_LOG(CONSOLE, "Read tracing started.");
|
||||||
}
|
}
|
||||||
CASE1("w")
|
CASE("w")
|
||||||
{
|
{
|
||||||
Core::StartTrace(true);
|
Core::StartTrace(true);
|
||||||
INFO_LOG(CONSOLE, "Write tracing started.");
|
INFO_LOG(CONSOLE, "Write tracing started.");
|
||||||
@ -141,3 +141,6 @@ void Console_Submit(const char *cmd)
|
|||||||
ERROR_LOG(CONSOLE, "Invalid command");
|
ERROR_LOG(CONSOLE, "Invalid command");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef CASE1
|
||||||
|
#undef CASE
|
||||||
|
@ -388,8 +388,8 @@ void EmuThread()
|
|||||||
|
|
||||||
OSD::AddMessage("Dolphin " + g_video_backend->GetName() + " Video Backend.", 5000);
|
OSD::AddMessage("Dolphin " + g_video_backend->GetName() + " Video Backend.", 5000);
|
||||||
|
|
||||||
if (!DSP::GetDSPEmulator()->Initialize(_CoreParameter.bWii,
|
if (!DSP::GetDSPEmulator()->Initialize(g_pWindowHandle,
|
||||||
_CoreParameter.bDSPThread))
|
_CoreParameter.bWii, _CoreParameter.bDSPThread))
|
||||||
{
|
{
|
||||||
HW::Shutdown();
|
HW::Shutdown();
|
||||||
g_video_backend->Shutdown();
|
g_video_backend->Shutdown();
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
#include "Core.h" // for bWii
|
#include "Core.h" // for bWii
|
||||||
#include "FifoPlayer/FifoDataFile.h"
|
#include "FifoPlayer/FifoDataFile.h"
|
||||||
|
|
||||||
|
#include <cinttypes>
|
||||||
|
|
||||||
SCoreStartupParameter::SCoreStartupParameter()
|
SCoreStartupParameter::SCoreStartupParameter()
|
||||||
: hInstance(0),
|
: hInstance(0),
|
||||||
bEnableDebugging(false), bAutomaticStart(false), bBootToPause(false),
|
bEnableDebugging(false), bAutomaticStart(false), bBootToPause(false),
|
||||||
@ -278,7 +280,7 @@ bool SCoreStartupParameter::AutoSetup(EBootBS2 _BootBS2)
|
|||||||
// Use the TitleIDhex for name and/or unique ID if launching from nand folder
|
// Use the TitleIDhex for name and/or unique ID if launching from nand folder
|
||||||
// or if it is not ascii characters (specifically sysmenu could potentially apply to other things)
|
// or if it is not ascii characters (specifically sysmenu could potentially apply to other things)
|
||||||
char titleidstr[17];
|
char titleidstr[17];
|
||||||
snprintf(titleidstr, 17, "%016llx", ContentLoader.GetTitleID());
|
snprintf(titleidstr, 17, "%016" PRIx64, ContentLoader.GetTitleID());
|
||||||
|
|
||||||
if (!m_strName.length())
|
if (!m_strName.length())
|
||||||
{
|
{
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <cinttypes>
|
||||||
|
|
||||||
#include "Thread.h"
|
#include "Thread.h"
|
||||||
#include "PowerPC/PowerPC.h"
|
#include "PowerPC/PowerPC.h"
|
||||||
@ -429,7 +430,7 @@ void LogPendingEvents()
|
|||||||
Event *ptr = first;
|
Event *ptr = first;
|
||||||
while (ptr)
|
while (ptr)
|
||||||
{
|
{
|
||||||
INFO_LOG(POWERPC, "PENDING: Now: %lld Pending: %lld Type: %d", globalTimer, ptr->time, ptr->type);
|
INFO_LOG(POWERPC, "PENDING: Now: %" PRId64 " Pending: %" PRId64 " Type: %d", globalTimer, ptr->time, ptr->type);
|
||||||
ptr = ptr->next;
|
ptr = ptr->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ public:
|
|||||||
|
|
||||||
virtual bool IsLLE() = 0;
|
virtual bool IsLLE() = 0;
|
||||||
|
|
||||||
virtual bool Initialize(bool bWii, bool bDSPThread) = 0;
|
virtual bool Initialize(void *hWnd, bool bWii, bool bDSPThread) = 0;
|
||||||
virtual void Shutdown() = 0;
|
virtual void Shutdown() = 0;
|
||||||
|
|
||||||
virtual void DoState(PointerWrap &p) = 0;
|
virtual void DoState(PointerWrap &p) = 0;
|
||||||
@ -35,6 +35,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
SoundStream *soundStream;
|
SoundStream *soundStream;
|
||||||
|
void *m_hWnd;
|
||||||
};
|
};
|
||||||
|
|
||||||
DSPEmulator *CreateDSPEmulator(bool HLE);
|
DSPEmulator *CreateDSPEmulator(bool HLE);
|
||||||
|
@ -86,7 +86,7 @@ bool FifoDataFile::Save(const char *filename)
|
|||||||
header.xfRegsSize = XF_REGS_SIZE;
|
header.xfRegsSize = XF_REGS_SIZE;
|
||||||
|
|
||||||
header.frameListOffset = frameListOffset;
|
header.frameListOffset = frameListOffset;
|
||||||
header.frameCount = m_Frames.size();
|
header.frameCount = (u32)m_Frames.size();
|
||||||
|
|
||||||
header.flags = m_Flags;
|
header.flags = m_Flags;
|
||||||
|
|
||||||
@ -111,7 +111,7 @@ bool FifoDataFile::Save(const char *filename)
|
|||||||
dstFrame.fifoStart = srcFrame.fifoStart;
|
dstFrame.fifoStart = srcFrame.fifoStart;
|
||||||
dstFrame.fifoEnd = srcFrame.fifoEnd;
|
dstFrame.fifoEnd = srcFrame.fifoEnd;
|
||||||
dstFrame.memoryUpdatesOffset = memoryUpdatesOffset;
|
dstFrame.memoryUpdatesOffset = memoryUpdatesOffset;
|
||||||
dstFrame.numMemoryUpdates = srcFrame.memoryUpdates.size();
|
dstFrame.numMemoryUpdates = (u32)srcFrame.memoryUpdates.size();
|
||||||
|
|
||||||
// Write frame info
|
// Write frame info
|
||||||
u64 frameOffset = frameListOffset + (i * sizeof(FileFrameInfo));
|
u64 frameOffset = frameListOffset + (i * sizeof(FileFrameInfo));
|
||||||
|
@ -234,7 +234,7 @@ u32 FifoPlaybackAnalyzer::DecodeCommand(u8 *data)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return data - dataStart;
|
return (u32)(data - dataStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FifoPlaybackAnalyzer::StoreEfbCopyRegion()
|
void FifoPlaybackAnalyzer::StoreEfbCopyRegion()
|
||||||
|
@ -105,7 +105,9 @@ bool FifoPlayer::Play()
|
|||||||
u32 FifoPlayer::GetFrameObjectCount()
|
u32 FifoPlayer::GetFrameObjectCount()
|
||||||
{
|
{
|
||||||
if (m_CurrentFrame < m_FrameInfo.size())
|
if (m_CurrentFrame < m_FrameInfo.size())
|
||||||
return m_FrameInfo[m_CurrentFrame].objectStarts.size();
|
{
|
||||||
|
return (u32)(m_FrameInfo[m_CurrentFrame].objectStarts.size());
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -172,7 +174,7 @@ void FifoPlayer::WriteFrame(const FifoFrameInfo &frame, const AnalyzedFrameInfo
|
|||||||
m_FrameFifoSize = frame.fifoDataSize;
|
m_FrameFifoSize = frame.fifoDataSize;
|
||||||
|
|
||||||
// Determine start and end objects
|
// Determine start and end objects
|
||||||
u32 numObjects = info.objectStarts.size();
|
u32 numObjects = (u32)(info.objectStarts.size());
|
||||||
u32 drawStart = std::min(numObjects, m_ObjectRangeStart);
|
u32 drawStart = std::min(numObjects, m_ObjectRangeStart);
|
||||||
u32 drawEnd = std::min(numObjects - 1, m_ObjectRangeEnd);
|
u32 drawEnd = std::min(numObjects - 1, m_ObjectRangeEnd);
|
||||||
|
|
||||||
@ -181,7 +183,9 @@ void FifoPlayer::WriteFrame(const FifoFrameInfo &frame, const AnalyzedFrameInfo
|
|||||||
|
|
||||||
// Skip memory updates during frame if true
|
// Skip memory updates during frame if true
|
||||||
if (m_EarlyMemoryUpdates)
|
if (m_EarlyMemoryUpdates)
|
||||||
memoryUpdate = frame.memoryUpdates.size();
|
{
|
||||||
|
memoryUpdate = (u32)(frame.memoryUpdates.size());
|
||||||
|
}
|
||||||
|
|
||||||
if (numObjects > 0)
|
if (numObjects > 0)
|
||||||
{
|
{
|
||||||
|
@ -83,9 +83,9 @@ void FifoRecorder::WriteGPCommand(u8 *data, u32 size)
|
|||||||
if (m_FrameEnded && m_FifoData.size() > 0)
|
if (m_FrameEnded && m_FifoData.size() > 0)
|
||||||
{
|
{
|
||||||
size_t dataSize = m_FifoData.size();
|
size_t dataSize = m_FifoData.size();
|
||||||
m_CurrentFrame.fifoDataSize = dataSize;
|
m_CurrentFrame.fifoDataSize = (u32)dataSize;
|
||||||
m_CurrentFrame.fifoData = new u8[dataSize];
|
m_CurrentFrame.fifoData = new u8[dataSize];
|
||||||
memcpy(m_CurrentFrame.fifoData, &m_FifoData[0], dataSize);
|
memcpy(m_CurrentFrame.fifoData, m_FifoData.data(), dataSize);
|
||||||
|
|
||||||
sMutex.lock();
|
sMutex.lock();
|
||||||
|
|
||||||
@ -129,7 +129,7 @@ void FifoRecorder::WriteMemory(u32 address, u32 size, MemoryUpdate::Type type)
|
|||||||
// Record memory update
|
// Record memory update
|
||||||
MemoryUpdate memUpdate;
|
MemoryUpdate memUpdate;
|
||||||
memUpdate.address = address;
|
memUpdate.address = address;
|
||||||
memUpdate.fifoPosition = m_FifoData.size();
|
memUpdate.fifoPosition = (u32)(m_FifoData.size());
|
||||||
memUpdate.size = size;
|
memUpdate.size = size;
|
||||||
memUpdate.type = type;
|
memUpdate.type = type;
|
||||||
memUpdate.data = new u8[size];
|
memUpdate.data = new u8[size];
|
||||||
|
@ -42,8 +42,9 @@ struct DSPState
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool DSPHLE::Initialize(bool bWii, bool bDSPThread)
|
bool DSPHLE::Initialize(void *hWnd, bool bWii, bool bDSPThread)
|
||||||
{
|
{
|
||||||
|
m_hWnd = hWnd;
|
||||||
m_bWii = bWii;
|
m_bWii = bWii;
|
||||||
m_pUCode = NULL;
|
m_pUCode = NULL;
|
||||||
m_lastUCode = NULL;
|
m_lastUCode = NULL;
|
||||||
@ -265,7 +266,7 @@ void DSPHLE::InitMixer()
|
|||||||
unsigned int AISampleRate, DACSampleRate;
|
unsigned int AISampleRate, DACSampleRate;
|
||||||
AudioInterface::Callback_GetSampleRate(AISampleRate, DACSampleRate);
|
AudioInterface::Callback_GetSampleRate(AISampleRate, DACSampleRate);
|
||||||
delete soundStream;
|
delete soundStream;
|
||||||
soundStream = AudioCommon::InitSoundStream(new HLEMixer(this, AISampleRate, DACSampleRate, 48000));
|
soundStream = AudioCommon::InitSoundStream(new HLEMixer(this, AISampleRate, DACSampleRate, 48000), m_hWnd);
|
||||||
if(!soundStream) PanicAlert("Error starting up sound stream");
|
if(!soundStream) PanicAlert("Error starting up sound stream");
|
||||||
// Mixer is initialized
|
// Mixer is initialized
|
||||||
m_InitMixer = true;
|
m_InitMixer = true;
|
||||||
|
@ -16,7 +16,7 @@ class DSPHLE : public DSPEmulator {
|
|||||||
public:
|
public:
|
||||||
DSPHLE();
|
DSPHLE();
|
||||||
|
|
||||||
virtual bool Initialize(bool bWii, bool bDSPThread) override;
|
virtual bool Initialize(void *hWnd, bool bWii, bool bDSPThread) override;
|
||||||
virtual void Shutdown() override;
|
virtual void Shutdown() override;
|
||||||
virtual bool IsLLE() override { return false ; }
|
virtual bool IsLLE() override { return false ; }
|
||||||
|
|
||||||
|
@ -469,36 +469,42 @@ void ProcessVoice(PB_TYPE& pb, const AXBuffers& buffers, u16 count, AXMixControl
|
|||||||
// Mix LRS, AUXA and AUXB depending on mixer_control
|
// Mix LRS, AUXA and AUXB depending on mixer_control
|
||||||
// TODO: Handle DPL2 on AUXB.
|
// TODO: Handle DPL2 on AUXB.
|
||||||
|
|
||||||
if (mctrl & MIX_L)
|
#define MIX_ON(C) (0 != (mctrl & MIX_##C))
|
||||||
MixAdd(buffers.left, samples, count, &pb.mixer.left, &pb.dpop.left, mctrl & MIX_L_RAMP);
|
#define RAMP_ON(C) (0 != (mctrl & MIX_##C##_RAMP))
|
||||||
if (mctrl & MIX_R)
|
|
||||||
MixAdd(buffers.right, samples, count, &pb.mixer.right, &pb.dpop.right, mctrl & MIX_R_RAMP);
|
|
||||||
if (mctrl & MIX_S)
|
|
||||||
MixAdd(buffers.surround, samples, count, &pb.mixer.surround, &pb.dpop.surround, mctrl & MIX_S_RAMP);
|
|
||||||
|
|
||||||
if (mctrl & MIX_AUXA_L)
|
if (MIX_ON(L))
|
||||||
MixAdd(buffers.auxA_left, samples, count, &pb.mixer.auxA_left, &pb.dpop.auxA_left, mctrl & MIX_AUXA_L_RAMP);
|
MixAdd(buffers.left, samples, count, &pb.mixer.left, &pb.dpop.left, RAMP_ON(L));
|
||||||
if (mctrl & MIX_AUXA_R)
|
if (MIX_ON(R))
|
||||||
MixAdd(buffers.auxA_right, samples, count, &pb.mixer.auxA_right, &pb.dpop.auxA_right, mctrl & MIX_AUXA_R_RAMP);
|
MixAdd(buffers.right, samples, count, &pb.mixer.right, &pb.dpop.right, RAMP_ON(R));
|
||||||
if (mctrl & MIX_AUXA_S)
|
if (MIX_ON(S))
|
||||||
MixAdd(buffers.auxA_surround, samples, count, &pb.mixer.auxA_surround, &pb.dpop.auxA_surround, mctrl & MIX_AUXA_S_RAMP);
|
MixAdd(buffers.surround, samples, count, &pb.mixer.surround, &pb.dpop.surround, RAMP_ON(S));
|
||||||
|
|
||||||
if (mctrl & MIX_AUXB_L)
|
if (MIX_ON(AUXA_L))
|
||||||
MixAdd(buffers.auxB_left, samples, count, &pb.mixer.auxB_left, &pb.dpop.auxB_left, mctrl & MIX_AUXB_L_RAMP);
|
MixAdd(buffers.auxA_left, samples, count, &pb.mixer.auxA_left, &pb.dpop.auxA_left, RAMP_ON(AUXA_L));
|
||||||
if (mctrl & MIX_AUXB_R)
|
if (MIX_ON(AUXA_R))
|
||||||
MixAdd(buffers.auxB_right, samples, count, &pb.mixer.auxB_right, &pb.dpop.auxB_right, mctrl & MIX_AUXB_R_RAMP);
|
MixAdd(buffers.auxA_right, samples, count, &pb.mixer.auxA_right, &pb.dpop.auxA_right, RAMP_ON(AUXA_R));
|
||||||
if (mctrl & MIX_AUXB_S)
|
if (MIX_ON(AUXA_S))
|
||||||
MixAdd(buffers.auxB_surround, samples, count, &pb.mixer.auxB_surround, &pb.dpop.auxB_surround, mctrl & MIX_AUXB_S_RAMP);
|
MixAdd(buffers.auxA_surround, samples, count, &pb.mixer.auxA_surround, &pb.dpop.auxA_surround, RAMP_ON(AUXA_S));
|
||||||
|
|
||||||
|
if (MIX_ON(AUXB_L))
|
||||||
|
MixAdd(buffers.auxB_left, samples, count, &pb.mixer.auxB_left, &pb.dpop.auxB_left, RAMP_ON(AUXB_L));
|
||||||
|
if (MIX_ON(AUXB_R))
|
||||||
|
MixAdd(buffers.auxB_right, samples, count, &pb.mixer.auxB_right, &pb.dpop.auxB_right, RAMP_ON(AUXB_R));
|
||||||
|
if (MIX_ON(AUXB_S))
|
||||||
|
MixAdd(buffers.auxB_surround, samples, count, &pb.mixer.auxB_surround, &pb.dpop.auxB_surround, RAMP_ON(AUXB_S));
|
||||||
|
|
||||||
#ifdef AX_WII
|
#ifdef AX_WII
|
||||||
if (mctrl & MIX_AUXC_L)
|
if (MIX_ON(AUXC_L))
|
||||||
MixAdd(buffers.auxC_left, samples, count, &pb.mixer.auxC_left, &pb.dpop.auxC_left, mctrl & MIX_AUXC_L_RAMP);
|
MixAdd(buffers.auxC_left, samples, count, &pb.mixer.auxC_left, &pb.dpop.auxC_left, RAMP_ON(AUXC_L));
|
||||||
if (mctrl & MIX_AUXC_R)
|
if (MIX_ON(AUXC_R))
|
||||||
MixAdd(buffers.auxC_right, samples, count, &pb.mixer.auxC_right, &pb.dpop.auxC_right, mctrl & MIX_AUXC_R_RAMP);
|
MixAdd(buffers.auxC_right, samples, count, &pb.mixer.auxC_right, &pb.dpop.auxC_right, RAMP_ON(AUXC_R));
|
||||||
if (mctrl & MIX_AUXC_S)
|
if (MIX_ON(AUXC_S))
|
||||||
MixAdd(buffers.auxC_surround, samples, count, &pb.mixer.auxC_surround, &pb.dpop.auxC_surround, mctrl & MIX_AUXC_S_RAMP);
|
MixAdd(buffers.auxC_surround, samples, count, &pb.mixer.auxC_surround, &pb.dpop.auxC_surround, RAMP_ON(AUXC_S));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#undef MIX_ON
|
||||||
|
#undef RAMP_ON
|
||||||
|
|
||||||
// Optionally, phase shift left or right channel to simulate 3D sound.
|
// Optionally, phase shift left or right channel to simulate 3D sound.
|
||||||
if (pb.initial_time_delay.on)
|
if (pb.initial_time_delay.on)
|
||||||
{
|
{
|
||||||
@ -524,8 +530,8 @@ void ProcessVoice(PB_TYPE& pb, const AXBuffers& buffers, u16 count, AXMixControl
|
|||||||
pb.remote_src.cur_addr_frac = curr_pos & 0xFFFF;
|
pb.remote_src.cur_addr_frac = curr_pos & 0xFFFF;
|
||||||
|
|
||||||
// Mix to main[0-3] and aux[0-3]
|
// Mix to main[0-3] and aux[0-3]
|
||||||
#define WMCHAN_MIX_ON(n) ((pb.remote_mixer_control >> (2 * n)) & 3)
|
#define WMCHAN_MIX_ON(n) (0 != ((pb.remote_mixer_control >> (2 * n)) & 3))
|
||||||
#define WMCHAN_MIX_RAMP(n) ((pb.remote_mixer_control >> (2 * n)) & 2)
|
#define WMCHAN_MIX_RAMP(n) (0 != ((pb.remote_mixer_control >> (2 * n)) & 2))
|
||||||
|
|
||||||
if (WMCHAN_MIX_ON(0))
|
if (WMCHAN_MIX_ON(0))
|
||||||
MixAdd(buffers.wm_main0, wm_samples, wm_count, &pb.remote_mixer.main0, &pb.remote_dpop.main0, WMCHAN_MIX_RAMP(0));
|
MixAdd(buffers.wm_main0, wm_samples, wm_count, &pb.remote_mixer.main0, &pb.remote_dpop.main0, WMCHAN_MIX_RAMP(0));
|
||||||
@ -544,6 +550,8 @@ void ProcessVoice(PB_TYPE& pb, const AXBuffers& buffers, u16 count, AXMixControl
|
|||||||
if (WMCHAN_MIX_ON(7))
|
if (WMCHAN_MIX_ON(7))
|
||||||
MixAdd(buffers.wm_aux3, wm_samples, wm_count, &pb.remote_mixer.aux3, &pb.remote_dpop.aux3, WMCHAN_MIX_RAMP(7));
|
MixAdd(buffers.wm_aux3, wm_samples, wm_count, &pb.remote_mixer.aux3, &pb.remote_dpop.aux3, WMCHAN_MIX_RAMP(7));
|
||||||
}
|
}
|
||||||
|
#undef WMCHAN_MIX_RAMP
|
||||||
|
#undef WMCHAN_MIX_ON
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,8 +130,9 @@ void DSPLLE::dsp_thread(DSPLLE *dsp_lle)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DSPLLE::Initialize(bool bWii, bool bDSPThread)
|
bool DSPLLE::Initialize(void *hWnd, bool bWii, bool bDSPThread)
|
||||||
{
|
{
|
||||||
|
m_hWnd = hWnd;
|
||||||
m_bWii = bWii;
|
m_bWii = bWii;
|
||||||
m_bDSPThread = bDSPThread;
|
m_bDSPThread = bDSPThread;
|
||||||
m_InitMixer = false;
|
m_InitMixer = false;
|
||||||
@ -184,7 +185,7 @@ void DSPLLE::InitMixer()
|
|||||||
unsigned int AISampleRate, DACSampleRate;
|
unsigned int AISampleRate, DACSampleRate;
|
||||||
AudioInterface::Callback_GetSampleRate(AISampleRate, DACSampleRate);
|
AudioInterface::Callback_GetSampleRate(AISampleRate, DACSampleRate);
|
||||||
delete soundStream;
|
delete soundStream;
|
||||||
soundStream = AudioCommon::InitSoundStream(new CMixer(AISampleRate, DACSampleRate, 48000));
|
soundStream = AudioCommon::InitSoundStream(new CMixer(AISampleRate, DACSampleRate, 48000), m_hWnd);
|
||||||
if(!soundStream) PanicAlert("Error starting up sound stream");
|
if(!soundStream) PanicAlert("Error starting up sound stream");
|
||||||
// Mixer is initialized
|
// Mixer is initialized
|
||||||
m_InitMixer = true;
|
m_InitMixer = true;
|
||||||
|
@ -14,7 +14,7 @@ class DSPLLE : public DSPEmulator {
|
|||||||
public:
|
public:
|
||||||
DSPLLE();
|
DSPLLE();
|
||||||
|
|
||||||
virtual bool Initialize(bool bWii, bool bDSPThread);
|
virtual bool Initialize(void *hWnd, bool bWii, bool bDSPThread);
|
||||||
virtual void Shutdown();
|
virtual void Shutdown();
|
||||||
virtual bool IsLLE() { return true; }
|
virtual bool IsLLE() { return true; }
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "FileUtil.h"
|
#include "FileUtil.h"
|
||||||
#include "DSP/DSPCore.h"
|
#include "DSP/DSPCore.h"
|
||||||
#include "DSPLLEGlobals.h"
|
#include "DSPLLEGlobals.h"
|
||||||
|
#include <cinttypes>
|
||||||
|
|
||||||
#if PROFILE
|
#if PROFILE
|
||||||
|
|
||||||
@ -37,12 +38,12 @@ void ProfilerDump(u64 count)
|
|||||||
File::IOFile pFile("DSP_Prof.txt", "wt");
|
File::IOFile pFile("DSP_Prof.txt", "wt");
|
||||||
if (pFile)
|
if (pFile)
|
||||||
{
|
{
|
||||||
fprintf(pFile.GetHandle(), "Number of DSP steps: %llu\n\n", count);
|
fprintf(pFile.GetHandle(), "Number of DSP steps: %" PRIu64 "\n\n", count);
|
||||||
for (int i=0; i<PROFILE_MAP_SIZE;i++)
|
for (int i=0; i<PROFILE_MAP_SIZE;i++)
|
||||||
{
|
{
|
||||||
if (g_profileMap[i] > 0)
|
if (g_profileMap[i] > 0)
|
||||||
{
|
{
|
||||||
fprintf(pFile.GetHandle(), "0x%04X: %llu\n", i, g_profileMap[i]);
|
fprintf(pFile.GetHandle(), "0x%04X: %" PRIu64 "\n", i, g_profileMap[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -325,7 +325,7 @@ void ChangeDisc(const char* _newFileName)
|
|||||||
{
|
{
|
||||||
Movie::g_bDiscChange = true;
|
Movie::g_bDiscChange = true;
|
||||||
std::string fileName = _newFileName;
|
std::string fileName = _newFileName;
|
||||||
int sizeofpath = fileName.find_last_of("/\\") + 1;
|
auto sizeofpath = fileName.find_last_of("/\\") + 1;
|
||||||
if (fileName.substr(sizeofpath).length() > 40)
|
if (fileName.substr(sizeofpath).length() > 40)
|
||||||
{
|
{
|
||||||
PanicAlert("Saving iso filename to .dtm failed; max file name length is 40 characters.");
|
PanicAlert("Saving iso filename to .dtm failed; max file name length is 40 characters.");
|
||||||
|
@ -191,7 +191,7 @@ void CEXIMemoryCard::CmdDone()
|
|||||||
void CEXIMemoryCard::CmdDoneLater(u64 cycles)
|
void CEXIMemoryCard::CmdDoneLater(u64 cycles)
|
||||||
{
|
{
|
||||||
CoreTiming::RemoveEvent(et_cmd_done);
|
CoreTiming::RemoveEvent(et_cmd_done);
|
||||||
CoreTiming::ScheduleEvent(cycles, et_cmd_done, (u64)card_index);
|
CoreTiming::ScheduleEvent((int)cycles, et_cmd_done, (u64)card_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CEXIMemoryCard::SetCS(int cs)
|
void CEXIMemoryCard::SetCS(int cs)
|
||||||
|
@ -4,6 +4,9 @@
|
|||||||
|
|
||||||
#include "GCMemcard.h"
|
#include "GCMemcard.h"
|
||||||
#include "ColorUtil.h"
|
#include "ColorUtil.h"
|
||||||
|
|
||||||
|
#include <cinttypes>
|
||||||
|
|
||||||
static void ByteSwap(u8 *valueA, u8 *valueB)
|
static void ByteSwap(u8 *valueA, u8 *valueB)
|
||||||
{
|
{
|
||||||
u8 tmp = *valueA;
|
u8 tmp = *valueA;
|
||||||
@ -37,19 +40,19 @@ GCMemcard::GCMemcard(const char *filename, bool forceCreation, bool sjis)
|
|||||||
PanicAlertT("File has the extension \"%s\"\nvalid extensions are (.raw/.gcp)", fileType.c_str());
|
PanicAlertT("File has the extension \"%s\"\nvalid extensions are (.raw/.gcp)", fileType.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
u32 size = mcdFile.GetSize();
|
auto size = mcdFile.GetSize();
|
||||||
if (size < MC_FST_BLOCKS*BLOCK_SIZE)
|
if (size < MC_FST_BLOCKS*BLOCK_SIZE)
|
||||||
{
|
{
|
||||||
PanicAlertT("%s failed to load as a memorycard \nfile is not large enough to be a valid memory card file (0x%x bytes)", filename, size);
|
PanicAlertT("%s failed to load as a memorycard \nfile is not large enough to be a valid memory card file (0x%x bytes)", filename, (unsigned) size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (size % BLOCK_SIZE)
|
if (size % BLOCK_SIZE)
|
||||||
{
|
{
|
||||||
PanicAlertT("%s failed to load as a memorycard \n Card file size is invalid (0x%x bytes)", filename, size);
|
PanicAlertT("%s failed to load as a memorycard \n Card file size is invalid (0x%x bytes)", filename, (unsigned) size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_sizeMb = (size/BLOCK_SIZE) / MBIT_TO_BLOCKS;
|
m_sizeMb = (u16)((size/BLOCK_SIZE) / MBIT_TO_BLOCKS);
|
||||||
switch (m_sizeMb)
|
switch (m_sizeMb)
|
||||||
{
|
{
|
||||||
case MemCard59Mb:
|
case MemCard59Mb:
|
||||||
@ -60,7 +63,7 @@ GCMemcard::GCMemcard(const char *filename, bool forceCreation, bool sjis)
|
|||||||
case MemCard2043Mb:
|
case MemCard2043Mb:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
PanicAlertT("%s failed to load as a memorycard \n Card size is invalid (0x%x bytes)", filename, size);
|
PanicAlertT("%s failed to load as a memorycard \n Card size is invalid (0x%x bytes)", filename, (unsigned) size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -173,7 +176,7 @@ GCMemcard::GCMemcard(const char *filename, bool forceCreation, bool sjis)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PanicAlertT("Failed to read block %d of the save data\nMemcard may be truncated\nFilePosition:%llx", i, mcdFile.Tell());
|
PanicAlertT("Failed to read block %d of the save data\nMemcard may be truncated\nFilePosition:%" PRIx64, i, mcdFile.Tell());
|
||||||
m_valid = false;
|
m_valid = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -209,5 +209,5 @@ void GCPad::LoadDefaults(const ControllerInterface& ciface)
|
|||||||
|
|
||||||
bool GCPad::GetMicButton() const
|
bool GCPad::GetMicButton() const
|
||||||
{
|
{
|
||||||
return m_buttons->controls.back()->control_ref->State();
|
return (0.0f != m_buttons->controls.back()->control_ref->State());
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
namespace WiimoteEmu
|
namespace WiimoteEmu
|
||||||
{
|
{
|
||||||
|
|
||||||
void Spy(Wiimote* wm_, const void* data_, int size_)
|
void Spy(Wiimote* wm_, const void* data_, size_t size_)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
// enable log
|
// enable log
|
||||||
@ -1275,7 +1275,7 @@ void Wiimote::DoState(PointerWrap& p)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::queue<ReadRequest> tmp_queue(m_read_requests);
|
std::queue<ReadRequest> tmp_queue(m_read_requests);
|
||||||
size = m_read_requests.size();
|
size = (u32)(m_read_requests.size());
|
||||||
p.Do(size);
|
p.Do(size);
|
||||||
while (!tmp_queue.empty())
|
while (!tmp_queue.empty())
|
||||||
{
|
{
|
||||||
|
@ -765,7 +765,7 @@ void Wiimote::Update()
|
|||||||
if (-1 == rptf_size)
|
if (-1 == rptf_size)
|
||||||
{
|
{
|
||||||
std::copy(rpt.begin(), rpt.end(), data);
|
std::copy(rpt.begin(), rpt.end(), data);
|
||||||
rptf_size = rpt.size();
|
rptf_size = (s8)(rpt.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ inline double trim(double a)
|
|||||||
class Wiimote : public ControllerEmu
|
class Wiimote : public ControllerEmu
|
||||||
{
|
{
|
||||||
friend class WiimoteReal::Wiimote;
|
friend class WiimoteReal::Wiimote;
|
||||||
friend void Spy(Wiimote* wm_, const void* data_, int size_);
|
friend void Spy(Wiimote* wm_, const void* data_, size_t size_);
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum
|
enum
|
||||||
@ -245,7 +245,7 @@ private:
|
|||||||
} m_reg_speaker;
|
} m_reg_speaker;
|
||||||
};
|
};
|
||||||
|
|
||||||
void Spy(Wiimote* wm_, const void* data_, int size_);
|
void Spy(Wiimote* wm_, const void* data_, size_t size_);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ int Wiimote::IORead(u8* buf)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Wiimote::IOWrite(const u8* buf, int len)
|
int Wiimote::IOWrite(const u8* buf, size_t len)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -263,9 +263,9 @@ int Wiimote::IORead(u8* buf)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Wiimote::IOWrite(u8 const* buf, int len)
|
int Wiimote::IOWrite(u8 const* buf, size_t len)
|
||||||
{
|
{
|
||||||
return write(int_sock, buf, len);
|
return write(int_sock, buf, (int)len);
|
||||||
}
|
}
|
||||||
|
|
||||||
}; // WiimoteReal
|
}; // WiimoteReal
|
||||||
|
@ -140,7 +140,7 @@ namespace WiimoteReal
|
|||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stack_t &stack, const u8* buf, int len);
|
int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stack_t &stack, const u8* buf, size_t len);
|
||||||
int _IORead(HANDLE &dev_handle, OVERLAPPED &hid_overlap_read, u8* buf, int index);
|
int _IORead(HANDLE &dev_handle, OVERLAPPED &hid_overlap_read, u8* buf, int index);
|
||||||
void _IOWakeup(HANDLE &dev_handle, OVERLAPPED &hid_overlap_read);
|
void _IOWakeup(HANDLE &dev_handle, OVERLAPPED &hid_overlap_read);
|
||||||
|
|
||||||
@ -247,7 +247,7 @@ void WiimoteScanner::FindWiimotes(std::vector<Wiimote*> & found_wiimotes, Wiimot
|
|||||||
// SLEEP(2000);
|
// SLEEP(2000);
|
||||||
|
|
||||||
}
|
}
|
||||||
int CheckDeviceType_Write(HANDLE &dev_handle, const u8* buf, int size, int attempts)
|
int CheckDeviceType_Write(HANDLE &dev_handle, const u8* buf, size_t size, int attempts)
|
||||||
{
|
{
|
||||||
OVERLAPPED hid_overlap_write = OVERLAPPED();
|
OVERLAPPED hid_overlap_write = OVERLAPPED();
|
||||||
hid_overlap_write.hEvent = CreateEvent(NULL, true, false, NULL);
|
hid_overlap_write.hEvent = CreateEvent(NULL, true, false, NULL);
|
||||||
@ -641,7 +641,7 @@ int Wiimote::IORead(u8* buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stack_t &stack, const u8* buf, int len)
|
int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stack_t &stack, const u8* buf, size_t len)
|
||||||
{
|
{
|
||||||
WiimoteEmu::Spy(NULL, buf, len);
|
WiimoteEmu::Spy(NULL, buf, len);
|
||||||
|
|
||||||
@ -663,7 +663,7 @@ int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stac
|
|||||||
}
|
}
|
||||||
case MSBT_STACK_MS:
|
case MSBT_STACK_MS:
|
||||||
{
|
{
|
||||||
auto result = HidD_SetOutputReport(dev_handle, const_cast<u8*>(buf) + 1, len - 1);
|
auto result = HidD_SetOutputReport(dev_handle, const_cast<u8*>(buf) + 1, (ULONG)(len - 1));
|
||||||
//FlushFileBuffers(dev_handle);
|
//FlushFileBuffers(dev_handle);
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
@ -715,7 +715,7 @@ int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stac
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Wiimote::IOWrite(const u8* buf, int len)
|
int Wiimote::IOWrite(const u8* buf, size_t len)
|
||||||
{
|
{
|
||||||
return _IOWrite(dev_handle, hid_overlap_write, stack, buf, len);
|
return _IOWrite(dev_handle, hid_overlap_write, stack, buf, len);
|
||||||
}
|
}
|
||||||
|
@ -310,14 +310,14 @@ int Wiimote::IORead(unsigned char *buf)
|
|||||||
return inputlen;
|
return inputlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Wiimote::IOWrite(const unsigned char *buf, int len)
|
int Wiimote::IOWrite(const unsigned char *buf, size_t len)
|
||||||
{
|
{
|
||||||
IOReturn ret;
|
IOReturn ret;
|
||||||
|
|
||||||
if (!IsConnected())
|
if (!IsConnected())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ret = [ichan writeAsync: const_cast<void*>((void *)buf) length: len refcon: nil];
|
ret = [ichan writeAsync: const_cast<void*>((void *)buf) length: (int)len refcon: nil];
|
||||||
|
|
||||||
if (ret == kIOReturnSuccess)
|
if (ret == kIOReturnSuccess)
|
||||||
return len;
|
return len;
|
||||||
|
@ -239,7 +239,9 @@ bool Wiimote::Write()
|
|||||||
IOWrite(rpt.data(), rpt.size());
|
IOWrite(rpt.data(), rpt.size());
|
||||||
|
|
||||||
if (is_speaker_data)
|
if (is_speaker_data)
|
||||||
|
{
|
||||||
m_last_audio_report.Update();
|
m_last_audio_report.Update();
|
||||||
|
}
|
||||||
|
|
||||||
m_write_reports.Pop();
|
m_write_reports.Pop();
|
||||||
return true;
|
return true;
|
||||||
@ -293,8 +295,10 @@ void Wiimote::Update()
|
|||||||
|
|
||||||
// Send the report
|
// Send the report
|
||||||
if (!rpt.empty() && m_channel > 0)
|
if (!rpt.empty() && m_channel > 0)
|
||||||
|
{
|
||||||
Core::Callback_WiimoteInterruptChannel(index, m_channel,
|
Core::Callback_WiimoteInterruptChannel(index, m_channel,
|
||||||
rpt.data(), rpt.size());
|
rpt.data(), (u32)rpt.size());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Wiimote::Prepare(int _index)
|
void Wiimote::Prepare(int _index)
|
||||||
|
@ -106,7 +106,7 @@ private:
|
|||||||
void WriteReport(Report rpt);
|
void WriteReport(Report rpt);
|
||||||
|
|
||||||
int IORead(u8* buf);
|
int IORead(u8* buf);
|
||||||
int IOWrite(u8 const* buf, int len);
|
int IOWrite(u8 const* buf, size_t len);
|
||||||
void IOWakeup();
|
void IOWakeup();
|
||||||
|
|
||||||
void ThreadFunc();
|
void ThreadFunc();
|
||||||
|
@ -83,7 +83,7 @@ static u64 last_reply_time;
|
|||||||
void EnqueReplyCallback(u64 userdata, int)
|
void EnqueReplyCallback(u64 userdata, int)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lk(s_reply_queue);
|
std::lock_guard<std::mutex> lk(s_reply_queue);
|
||||||
reply_queue.push_back(userdata);
|
reply_queue.push_back((u32)userdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Init()
|
void Init()
|
||||||
@ -546,7 +546,9 @@ void ExecuteCommand(u32 _Address)
|
|||||||
const s64 ticks_til_last_reply = last_reply_time - CoreTiming::GetTicks();
|
const s64 ticks_til_last_reply = last_reply_time - CoreTiming::GetTicks();
|
||||||
|
|
||||||
if (ticks_til_last_reply > 0)
|
if (ticks_til_last_reply > 0)
|
||||||
reply_delay = ticks_til_last_reply;
|
{
|
||||||
|
reply_delay = (int)ticks_til_last_reply;
|
||||||
|
}
|
||||||
|
|
||||||
last_reply_time = CoreTiming::GetTicks() + reply_delay;
|
last_reply_time = CoreTiming::GetTicks() + reply_delay;
|
||||||
|
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
#include "../../DiscIO/Src/FileMonitor.h"
|
#include "../../DiscIO/Src/FileMonitor.h"
|
||||||
|
|
||||||
|
#include <cinttypes>
|
||||||
|
|
||||||
using namespace DVDInterface;
|
using namespace DVDInterface;
|
||||||
|
|
||||||
|
|
||||||
@ -108,7 +110,7 @@ bool CWII_IPC_HLE_Device_di::IOCtlV(u32 _CommandAddress)
|
|||||||
// Get TMD offset for requested partition...
|
// Get TMD offset for requested partition...
|
||||||
u64 const TMDOffset = ((u64)Memory::Read_U32(CommandBuffer.InBuffer[0].m_Address + 4) << 2 ) + 0x2c0;
|
u64 const TMDOffset = ((u64)Memory::Read_U32(CommandBuffer.InBuffer[0].m_Address + 4) << 2 ) + 0x2c0;
|
||||||
|
|
||||||
INFO_LOG(WII_IPC_DVD, "DVDLowOpenPartition: TMDOffset 0x%016llx", TMDOffset);
|
INFO_LOG(WII_IPC_DVD, "DVDLowOpenPartition: TMDOffset 0x%016" PRIx64, TMDOffset);
|
||||||
|
|
||||||
static u32 const TMDsz = 0x208; //CommandBuffer.PayloadBuffer[0].m_Size;
|
static u32 const TMDsz = 0x208; //CommandBuffer.PayloadBuffer[0].m_Size;
|
||||||
u8 pTMD[TMDsz];
|
u8 pTMD[TMDsz];
|
||||||
@ -204,13 +206,13 @@ u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32
|
|||||||
pFilename = m_pFileSystem->GetFileName(DVDAddress);
|
pFilename = m_pFileSystem->GetFileName(DVDAddress);
|
||||||
if (pFilename != NULL)
|
if (pFilename != NULL)
|
||||||
{
|
{
|
||||||
INFO_LOG(WII_IPC_DVD, "DVDLowRead: %s (0x%llx) - (DVDAddr: 0x%llx, Size: 0x%x)",
|
INFO_LOG(WII_IPC_DVD, "DVDLowRead: %s (0x%" PRIx64 ") - (DVDAddr: 0x%" PRIx64 ", Size: 0x%x)",
|
||||||
pFilename, m_pFileSystem->GetFileSize(pFilename), DVDAddress, Size);
|
pFilename, m_pFileSystem->GetFileSize(pFilename), DVDAddress, Size);
|
||||||
FileMon::CheckFile(std::string(pFilename), (int)m_pFileSystem->GetFileSize(pFilename));
|
FileMon::CheckFile(std::string(pFilename), (int)m_pFileSystem->GetFileSize(pFilename));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
INFO_LOG(WII_IPC_DVD, "DVDLowRead: file unknown - (DVDAddr: 0x%llx, Size: 0x%x)",
|
INFO_LOG(WII_IPC_DVD, "DVDLowRead: file unknown - (DVDAddr: 0x%" PRIx64 ", Size: 0x%x)",
|
||||||
DVDAddress, Size);
|
DVDAddress, Size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -308,7 +310,7 @@ u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32
|
|||||||
|
|
||||||
u64 DVDAddress = (u64)DVDAddress32 << 2;
|
u64 DVDAddress = (u64)DVDAddress32 << 2;
|
||||||
|
|
||||||
INFO_LOG(WII_IPC_DVD, "DVDLowUnencryptedRead: DVDAddr: 0x%08llx, Size: 0x%x", DVDAddress, Size);
|
INFO_LOG(WII_IPC_DVD, "DVDLowUnencryptedRead: DVDAddr: 0x%08" PRIx64 ", Size: 0x%x", DVDAddress, Size);
|
||||||
|
|
||||||
if (Size > _BufferOutSize)
|
if (Size > _BufferOutSize)
|
||||||
{
|
{
|
||||||
@ -342,12 +344,12 @@ u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32
|
|||||||
pFilename = m_pFileSystem->GetFileName(DVDAddress);
|
pFilename = m_pFileSystem->GetFileName(DVDAddress);
|
||||||
if (pFilename != NULL)
|
if (pFilename != NULL)
|
||||||
{
|
{
|
||||||
INFO_LOG(WII_IPC_DVD, "DVDLowSeek: %s (0x%llx) - (DVDAddr: 0x%llx)",
|
INFO_LOG(WII_IPC_DVD, "DVDLowSeek: %s (0x%" PRIx64 ") - (DVDAddr: 0x%" PRIx64 ")",
|
||||||
pFilename, m_pFileSystem->GetFileSize(pFilename), DVDAddress);
|
pFilename, m_pFileSystem->GetFileSize(pFilename), DVDAddress);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
INFO_LOG(WII_IPC_DVD, "DVDLowSeek: file unknown - (DVDAddr: 0x%llx)",
|
INFO_LOG(WII_IPC_DVD, "DVDLowSeek: file unknown - (DVDAddr: 0x%" PRIx64 ")",
|
||||||
DVDAddress);
|
DVDAddress);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,10 @@
|
|||||||
|
|
||||||
#include "WII_IPC_HLE_Device_es.h"
|
#include "WII_IPC_HLE_Device_es.h"
|
||||||
|
|
||||||
|
// need to include this before polarssl/aes.h,
|
||||||
|
// otherwise we may not get __STDC_FORMAT_MACROS
|
||||||
|
#include <cinttypes>
|
||||||
|
|
||||||
#include "../PowerPC/PowerPC.h"
|
#include "../PowerPC/PowerPC.h"
|
||||||
#include "../VolumeHandler.h"
|
#include "../VolumeHandler.h"
|
||||||
#include "FileUtil.h"
|
#include "FileUtil.h"
|
||||||
@ -129,7 +133,7 @@ void CWII_IPC_HLE_Device_es::DoState(PointerWrap& p)
|
|||||||
p.Do(m_AccessIdentID);
|
p.Do(m_AccessIdentID);
|
||||||
p.Do(m_TitleIDs);
|
p.Do(m_TitleIDs);
|
||||||
|
|
||||||
u32 Count = m_ContentAccessMap.size();
|
u32 Count = (u32)(m_ContentAccessMap.size());
|
||||||
p.Do(Count);
|
p.Do(Count);
|
||||||
|
|
||||||
u32 CFD, Position;
|
u32 CFD, Position;
|
||||||
@ -205,7 +209,7 @@ u32 CWII_IPC_HLE_Device_es::OpenTitleContent(u32 CFD, u64 TitleID, u16 Index)
|
|||||||
|
|
||||||
if (!Loader.IsValid())
|
if (!Loader.IsValid())
|
||||||
{
|
{
|
||||||
WARN_LOG(WII_IPC_ES, "ES: loader not valid for %llx", TitleID);
|
WARN_LOG(WII_IPC_ES, "ES: loader not valid for %" PRIx64, TitleID);
|
||||||
return 0xffffffff;
|
return 0xffffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -940,7 +944,7 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
|
|||||||
if (!bSuccess)
|
if (!bSuccess)
|
||||||
{
|
{
|
||||||
PanicAlertT("IOCTL_ES_LAUNCH: Game tried to reload a title that is not available in your NAND dump\n"
|
PanicAlertT("IOCTL_ES_LAUNCH: Game tried to reload a title that is not available in your NAND dump\n"
|
||||||
"TitleID %016llx.\n Dolphin will likely hang now.", TitleID);
|
"TitleID %016" PRIx64".\n Dolphin will likely hang now.", TitleID);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -983,7 +987,7 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
|
|||||||
//TODO: provide correct return code when bSuccess= false
|
//TODO: provide correct return code when bSuccess= false
|
||||||
Memory::Write_U32(0, _CommandAddress + 0x4);
|
Memory::Write_U32(0, _CommandAddress + 0x4);
|
||||||
|
|
||||||
ERROR_LOG(WII_IPC_ES, "IOCTL_ES_LAUNCH %016llx %08x %016llx %08x %016llx %04x", TitleID,view,ticketid,devicetype,titleid,access);
|
ERROR_LOG(WII_IPC_ES, "IOCTL_ES_LAUNCH %016" PRIx64 " %08x %016" PRIx64 " %08x %016" PRIx64 " %04x", TitleID,view,ticketid,devicetype,titleid,access);
|
||||||
// IOCTL_ES_LAUNCH 0001000248414341 00000001 0001c0fef3df2cfa 00000000 0001000248414341 ffff
|
// IOCTL_ES_LAUNCH 0001000248414341 00000001 0001c0fef3df2cfa 00000000 0001000248414341 ffff
|
||||||
|
|
||||||
// This is necessary because Reset(true) above deleted this object. Ew.
|
// This is necessary because Reset(true) above deleted this object. Ew.
|
||||||
|
@ -571,7 +571,7 @@ void CWII_IPC_HLE_Device_fs::DoState(PointerWrap& p)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
u32 size = entry.size;
|
u32 size = (u32)entry.size;
|
||||||
p.Do(size);
|
p.Do(size);
|
||||||
|
|
||||||
File::IOFile handle(entry.physicalName, "rb");
|
File::IOFile handle(entry.physicalName, "rb");
|
||||||
|
@ -385,12 +385,12 @@ void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize)
|
|||||||
Memory::WriteBigEData((const u8*)&wii_device, OffsetBuffer, Align(wii_device.bLength, 4));
|
Memory::WriteBigEData((const u8*)&wii_device, OffsetBuffer, Align(wii_device.bLength, 4));
|
||||||
OffsetBuffer += Align(wii_device.bLength, 4);
|
OffsetBuffer += Align(wii_device.bLength, 4);
|
||||||
bool deviceValid = true;
|
bool deviceValid = true;
|
||||||
|
bool isHID = false;
|
||||||
|
|
||||||
for (c = 0; deviceValid && c < desc.bNumConfigurations; c++)
|
for (c = 0; deviceValid && c < desc.bNumConfigurations; c++)
|
||||||
{
|
{
|
||||||
struct libusb_config_descriptor *config = NULL;
|
struct libusb_config_descriptor *config = NULL;
|
||||||
int cRet = libusb_get_config_descriptor(device, c, &config);
|
int cRet = libusb_get_config_descriptor(device, c, &config);
|
||||||
|
|
||||||
// do not try to use usb devices with more than one interface, games can crash
|
// do not try to use usb devices with more than one interface, games can crash
|
||||||
if(cRet == 0 && config->bNumInterfaces <= MAX_HID_INTERFACES)
|
if(cRet == 0 && config->bNumInterfaces <= MAX_HID_INTERFACES)
|
||||||
{
|
{
|
||||||
@ -402,10 +402,14 @@ void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize)
|
|||||||
for (ic = 0; ic < config->bNumInterfaces; ic++)
|
for (ic = 0; ic < config->bNumInterfaces; ic++)
|
||||||
{
|
{
|
||||||
const struct libusb_interface *interfaceContainer = &config->interface[ic];
|
const struct libusb_interface *interfaceContainer = &config->interface[ic];
|
||||||
|
|
||||||
for (i = 0; i < interfaceContainer->num_altsetting; i++)
|
for (i = 0; i < interfaceContainer->num_altsetting; i++)
|
||||||
{
|
{
|
||||||
const struct libusb_interface_descriptor *interface = &interfaceContainer->altsetting[i];
|
const struct libusb_interface_descriptor *interface = &interfaceContainer->altsetting[i];
|
||||||
|
|
||||||
|
if (interface->bInterfaceClass == LIBUSB_CLASS_HID)
|
||||||
|
isHID = true;
|
||||||
|
|
||||||
WiiHIDInterfaceDescriptor wii_interface;
|
WiiHIDInterfaceDescriptor wii_interface;
|
||||||
ConvertInterfaceToWii(&wii_interface, interface);
|
ConvertInterfaceToWii(&wii_interface, interface);
|
||||||
Memory::WriteBigEData((const u8*)&wii_interface, OffsetBuffer, Align(wii_interface.bLength, 4));
|
Memory::WriteBigEData((const u8*)&wii_interface, OffsetBuffer, Align(wii_interface.bLength, 4));
|
||||||
@ -435,6 +439,12 @@ void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize)
|
|||||||
}
|
}
|
||||||
} // configs
|
} // configs
|
||||||
|
|
||||||
|
if (!isHID)
|
||||||
|
{
|
||||||
|
deviceValid = false;
|
||||||
|
OffsetBuffer = OffsetStart;
|
||||||
|
}
|
||||||
|
|
||||||
if (deviceValid)
|
if (deviceValid)
|
||||||
{
|
{
|
||||||
Memory::Write_U32(OffsetBuffer-OffsetStart, OffsetStart); // fill in length
|
Memory::Write_U32(OffsetBuffer-OffsetStart, OffsetStart); // fill in length
|
||||||
|
@ -866,7 +866,7 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventRoleChange(bdaddr_t _bd, bool
|
|||||||
|
|
||||||
bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventNumberOfCompletedPackets()
|
bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventNumberOfCompletedPackets()
|
||||||
{
|
{
|
||||||
SQueuedEvent Event(sizeof(hci_event_hdr_t) + sizeof(hci_num_compl_pkts_ep) + sizeof(hci_num_compl_pkts_info) * m_WiiMotes.size(), 0);
|
SQueuedEvent Event((u32)(sizeof(hci_event_hdr_t) + sizeof(hci_num_compl_pkts_ep) + (sizeof(hci_num_compl_pkts_info) * m_WiiMotes.size())), 0);
|
||||||
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, "Event: SendEventNumberOfCompletedPackets");
|
INFO_LOG(WII_IPC_WIIMOTE, "Event: SendEventNumberOfCompletedPackets");
|
||||||
|
|
||||||
|
@ -84,14 +84,6 @@
|
|||||||
// All structs in this file are packed
|
// All structs in this file are packed
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
|
|
||||||
/*
|
|
||||||
* Bluetooth Address Family Protocol Numbers
|
|
||||||
*/
|
|
||||||
#define BTPROTO_HCI 1
|
|
||||||
#define BTPROTO_L2CAP 2
|
|
||||||
#define BTPROTO_RFCOMM 3
|
|
||||||
#define BTPROTO_SCO 4
|
|
||||||
|
|
||||||
/* All sizes are in bytes */
|
/* All sizes are in bytes */
|
||||||
#define BLUETOOTH_BDADDR_SIZE 6
|
#define BLUETOOTH_BDADDR_SIZE 6
|
||||||
|
|
||||||
@ -102,9 +94,8 @@
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t b[BLUETOOTH_BDADDR_SIZE];
|
uint8_t b[BLUETOOTH_BDADDR_SIZE];
|
||||||
} bdaddr_t;
|
} bdaddr_t;
|
||||||
#endif
|
|
||||||
|
|
||||||
#define BDADDR_ANY { { 0, 0, 0, 0, 0, 0 } }
|
#define BDADDR_ANY { { 0, 0, 0, 0, 0, 0 } }
|
||||||
|
#endif
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
|
@ -445,10 +445,11 @@ void NetPlayClient::SendWiimoteState(const PadMapping in_game_pad, const NetWiim
|
|||||||
sf::Packet spac;
|
sf::Packet spac;
|
||||||
spac << (MessageId)NP_MSG_WIIMOTE_DATA;
|
spac << (MessageId)NP_MSG_WIIMOTE_DATA;
|
||||||
spac << in_game_pad;
|
spac << in_game_pad;
|
||||||
u8 size = nw.size();
|
spac << (u8)nw.size();
|
||||||
spac << size;
|
for (auto it : nw)
|
||||||
for (unsigned int i = 0; i < size; ++i)
|
{
|
||||||
spac << nw.data()[i];
|
spac << it;
|
||||||
|
}
|
||||||
|
|
||||||
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
|
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
|
||||||
m_socket.Send(spac);
|
m_socket.Send(spac);
|
||||||
|
@ -153,7 +153,7 @@ unsigned int NetPlayServer::OnConnect(sf::SocketTCP& socket)
|
|||||||
rpac >> player.name;
|
rpac >> player.name;
|
||||||
|
|
||||||
// give new client first available id
|
// give new client first available id
|
||||||
player.pid = m_players.size() + 1;
|
player.pid = (PlayerId)(m_players.size() + 1);
|
||||||
|
|
||||||
// try to automatically assign new user a pad
|
// try to automatically assign new user a pad
|
||||||
for (unsigned int m = 0; m < 4; ++m)
|
for (unsigned int m = 0; m < 4; ++m)
|
||||||
@ -435,12 +435,14 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, sf::SocketTCP& socket)
|
|||||||
|
|
||||||
case NP_MSG_PONG :
|
case NP_MSG_PONG :
|
||||||
{
|
{
|
||||||
const u32 ping = m_ping_timer.GetTimeElapsed();
|
const u32 ping = (u32)m_ping_timer.GetTimeElapsed();
|
||||||
u32 ping_key = 0;
|
u32 ping_key = 0;
|
||||||
packet >> ping_key;
|
packet >> ping_key;
|
||||||
|
|
||||||
if (m_ping_key == ping_key)
|
if (m_ping_key == ping_key)
|
||||||
|
{
|
||||||
player.ping = ping;
|
player.ping = ping;
|
||||||
|
}
|
||||||
|
|
||||||
sf::Packet spac;
|
sf::Packet spac;
|
||||||
spac << (MessageId)NP_MSG_PLAYER_PING_DATA;
|
spac << (MessageId)NP_MSG_PLAYER_PING_DATA;
|
||||||
|
@ -10,11 +10,11 @@
|
|||||||
#include "../../Host.h"
|
#include "../../Host.h"
|
||||||
#include "../../IPC_HLE/WII_IPC_HLE.h"
|
#include "../../IPC_HLE/WII_IPC_HLE.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_GDBSTUB
|
#ifdef USE_GDBSTUB
|
||||||
#include "../GDBStub.h"
|
#include "../GDBStub.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <cinttypes>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
u32 last_pc;
|
u32 last_pc;
|
||||||
@ -79,7 +79,7 @@ void Trace( UGeckoInstruction &instCode )
|
|||||||
std::string fregs = "";
|
std::string fregs = "";
|
||||||
for (int i=0; i<32; i++)
|
for (int i=0; i<32; i++)
|
||||||
{
|
{
|
||||||
sprintf(freg, "f%02d: %08llx %08llx ", i, PowerPC::ppcState.ps[i][0], PowerPC::ppcState.ps[i][1]);
|
sprintf(freg, "f%02d: %08" PRIx64 " %08" PRIx64 " ", i, PowerPC::ppcState.ps[i][0], PowerPC::ppcState.ps[i][1]);
|
||||||
fregs.append(freg);
|
fregs.append(freg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#ifndef _INTERPRETER_FPUTILS_H
|
#ifndef _INTERPRETER_FPUTILS_H
|
||||||
#define _INTERPRETER_FPUTILS_H
|
#define _INTERPRETER_FPUTILS_H
|
||||||
|
|
||||||
|
#include "CPUDetect.h"
|
||||||
#include "Interpreter.h"
|
#include "Interpreter.h"
|
||||||
#include "MathUtil.h"
|
#include "MathUtil.h"
|
||||||
|
|
||||||
@ -69,28 +70,22 @@ inline void UpdateFPSCR()
|
|||||||
|
|
||||||
inline double ForceSingle(double _x)
|
inline double ForceSingle(double _x)
|
||||||
{
|
{
|
||||||
//if (FPSCR.RN != 0)
|
// convert to float...
|
||||||
// PanicAlert("RN = %d at %x", (int)FPSCR.RN, PC);
|
float x = _x;
|
||||||
if (FPSCR.NI)
|
if (!cpu_info.bFlushToZero && FPSCR.NI)
|
||||||
_x = FlushToZeroAsFloat(_x);
|
{
|
||||||
|
x = FlushToZero(x);
|
||||||
double x = static_cast<float>(_x);
|
}
|
||||||
|
// ...and back to double:
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline double ForceDouble(double d)
|
inline double ForceDouble(double d)
|
||||||
{
|
{
|
||||||
//if (FPSCR.RN != 0)
|
if (!cpu_info.bFlushToZero && FPSCR.NI)
|
||||||
// PanicAlert("RN = %d at %x", (int)FPSCR.RN, PC);
|
{
|
||||||
|
d = FlushToZero(d);
|
||||||
//if (FPSCR.NI)
|
}
|
||||||
//{
|
|
||||||
// IntDouble x; x.d = d;
|
|
||||||
//if ((x.i & DOUBLE_EXP) == 0)
|
|
||||||
// x.i &= DOUBLE_SIGN; // turn into signed zero
|
|
||||||
// return x.d;
|
|
||||||
//}
|
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,15 +48,8 @@ static void FPSCRtoFPUSettings(UReg_FPSCR fp)
|
|||||||
// Pokemon Colosseum does this. Gah.
|
// Pokemon Colosseum does this. Gah.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also corresponding SSE rounding mode setting
|
// Set SSE rounding mode and denormal handling
|
||||||
if (FPSCR.NI)
|
FPURoundMode::SetSIMDMode(FPSCR.RN, FPSCR.NI);
|
||||||
{
|
|
||||||
// Either one of these two breaks Beyond Good & Evil.
|
|
||||||
// if (cpu_info.bSSSE3)
|
|
||||||
// csr |= DAZ;
|
|
||||||
// csr |= FTZ;
|
|
||||||
}
|
|
||||||
FPURoundMode::SetSIMDMode(FPSCR.RN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::mtfsb0x(UGeckoInstruction _inst)
|
void Interpreter::mtfsb0x(UGeckoInstruction _inst)
|
||||||
|
@ -119,7 +119,7 @@ public:
|
|||||||
void tri_op(int d, int a, int b, bool reversible, void (XEmitter::*op)(Gen::X64Reg, Gen::OpArg));
|
void tri_op(int d, int a, int b, bool reversible, void (XEmitter::*op)(Gen::X64Reg, Gen::OpArg));
|
||||||
typedef u32 (*Operation)(u32 a, u32 b);
|
typedef u32 (*Operation)(u32 a, u32 b);
|
||||||
void regimmop(int d, int a, bool binary, u32 value, Operation doop, void (XEmitter::*op)(int, const Gen::OpArg&, const Gen::OpArg&), bool Rc = false, bool carry = false);
|
void regimmop(int d, int a, bool binary, u32 value, Operation doop, void (XEmitter::*op)(int, const Gen::OpArg&, const Gen::OpArg&), bool Rc = false, bool carry = false);
|
||||||
void fp_tri_op(int d, int a, int b, bool reversible, bool dupe, void (XEmitter::*op)(Gen::X64Reg, Gen::OpArg));
|
void fp_tri_op(int d, int a, int b, bool reversible, bool dupe, void (XEmitter::*op_2)(Gen::X64Reg, Gen::OpArg), void (XEmitter::*op_3)(Gen::X64Reg, Gen::X64Reg, Gen::OpArg));
|
||||||
|
|
||||||
// OPCODES
|
// OPCODES
|
||||||
void unknown_instruction(UGeckoInstruction _inst);
|
void unknown_instruction(UGeckoInstruction _inst);
|
||||||
@ -182,7 +182,7 @@ public:
|
|||||||
void ps_sum(UGeckoInstruction inst);
|
void ps_sum(UGeckoInstruction inst);
|
||||||
void ps_muls(UGeckoInstruction inst);
|
void ps_muls(UGeckoInstruction inst);
|
||||||
|
|
||||||
void fp_arith_s(UGeckoInstruction inst);
|
void fp_arith(UGeckoInstruction inst);
|
||||||
void frsqrtex(UGeckoInstruction inst);
|
void frsqrtex(UGeckoInstruction inst);
|
||||||
|
|
||||||
void fcmpx(UGeckoInstruction inst);
|
void fcmpx(UGeckoInstruction inst);
|
||||||
|
@ -320,12 +320,12 @@ static GekkoOPTemplate table31_2[] =
|
|||||||
|
|
||||||
static GekkoOPTemplate table59[] =
|
static GekkoOPTemplate table59[] =
|
||||||
{
|
{
|
||||||
{18, &Jit64::Default}, //{"fdivsx", OPTYPE_FPU, FL_RC_BIT_F, 16}},
|
{18, &Jit64::fp_arith}, //{"fdivsx", OPTYPE_FPU, FL_RC_BIT_F, 16}},
|
||||||
{20, &Jit64::fp_arith_s}, //"fsubsx", OPTYPE_FPU, FL_RC_BIT_F}},
|
{20, &Jit64::fp_arith}, //"fsubsx", OPTYPE_FPU, FL_RC_BIT_F}},
|
||||||
{21, &Jit64::fp_arith_s}, //"faddsx", OPTYPE_FPU, FL_RC_BIT_F}},
|
{21, &Jit64::fp_arith}, //"faddsx", OPTYPE_FPU, FL_RC_BIT_F}},
|
||||||
// {22, &Jit64::Default}, //"fsqrtsx", OPTYPE_FPU, FL_RC_BIT_F}}, // Not implemented on gekko
|
// {22, &Jit64::Default}, //"fsqrtsx", OPTYPE_FPU, FL_RC_BIT_F}}, // Not implemented on gekko
|
||||||
{24, &Jit64::Default}, //"fresx", OPTYPE_FPU, FL_RC_BIT_F}},
|
{24, &Jit64::Default}, //"fresx", OPTYPE_FPU, FL_RC_BIT_F}},
|
||||||
{25, &Jit64::fp_arith_s}, //"fmulsx", OPTYPE_FPU, FL_RC_BIT_F}},
|
{25, &Jit64::fp_arith}, //"fmulsx", OPTYPE_FPU, FL_RC_BIT_F}},
|
||||||
{28, &Jit64::fmaddXX}, //"fmsubsx", OPTYPE_FPU, FL_RC_BIT_F}},
|
{28, &Jit64::fmaddXX}, //"fmsubsx", OPTYPE_FPU, FL_RC_BIT_F}},
|
||||||
{29, &Jit64::fmaddXX}, //"fmaddsx", OPTYPE_FPU, FL_RC_BIT_F}},
|
{29, &Jit64::fmaddXX}, //"fmaddsx", OPTYPE_FPU, FL_RC_BIT_F}},
|
||||||
{30, &Jit64::fmaddXX}, //"fnmsubsx", OPTYPE_FPU, FL_RC_BIT_F}},
|
{30, &Jit64::fmaddXX}, //"fnmsubsx", OPTYPE_FPU, FL_RC_BIT_F}},
|
||||||
@ -354,12 +354,12 @@ static GekkoOPTemplate table63[] =
|
|||||||
|
|
||||||
static GekkoOPTemplate table63_2[] =
|
static GekkoOPTemplate table63_2[] =
|
||||||
{
|
{
|
||||||
{18, &Jit64::Default}, //"fdivx", OPTYPE_FPU, FL_RC_BIT_F, 30}},
|
{18, &Jit64::fp_arith}, //"fdivx", OPTYPE_FPU, FL_RC_BIT_F, 30}},
|
||||||
{20, &Jit64::Default}, //"fsubx", OPTYPE_FPU, FL_RC_BIT_F}},
|
{20, &Jit64::fp_arith}, //"fsubx", OPTYPE_FPU, FL_RC_BIT_F}},
|
||||||
{21, &Jit64::Default}, //"faddx", OPTYPE_FPU, FL_RC_BIT_F}},
|
{21, &Jit64::fp_arith}, //"faddx", OPTYPE_FPU, FL_RC_BIT_F}},
|
||||||
{22, &Jit64::Default}, //"fsqrtx", OPTYPE_FPU, FL_RC_BIT_F}},
|
{22, &Jit64::Default}, //"fsqrtx", OPTYPE_FPU, FL_RC_BIT_F}},
|
||||||
{23, &Jit64::Default}, //"fselx", OPTYPE_FPU, FL_RC_BIT_F}},
|
{23, &Jit64::Default}, //"fselx", OPTYPE_FPU, FL_RC_BIT_F}},
|
||||||
{25, &Jit64::fp_arith_s}, //"fmulx", OPTYPE_FPU, FL_RC_BIT_F}},
|
{25, &Jit64::fp_arith}, //"fmulx", OPTYPE_FPU, FL_RC_BIT_F}},
|
||||||
{26, &Jit64::frsqrtex}, //"frsqrtex", OPTYPE_FPU, FL_RC_BIT_F}},
|
{26, &Jit64::frsqrtex}, //"frsqrtex", OPTYPE_FPU, FL_RC_BIT_F}},
|
||||||
{28, &Jit64::fmaddXX}, //"fmsubx", OPTYPE_FPU, FL_RC_BIT_F}},
|
{28, &Jit64::fmaddXX}, //"fmsubx", OPTYPE_FPU, FL_RC_BIT_F}},
|
||||||
{29, &Jit64::fmaddXX}, //"fmaddx", OPTYPE_FPU, FL_RC_BIT_F}},
|
{29, &Jit64::fmaddXX}, //"fmaddx", OPTYPE_FPU, FL_RC_BIT_F}},
|
||||||
|
@ -166,7 +166,7 @@ int RegCache::SanityCheck() const
|
|||||||
|
|
||||||
void RegCache::DiscardRegContentsIfCached(int preg)
|
void RegCache::DiscardRegContentsIfCached(int preg)
|
||||||
{
|
{
|
||||||
if (regs[preg].away && regs[preg].location.IsSimpleReg())
|
if (IsBound(preg))
|
||||||
{
|
{
|
||||||
X64Reg xr = regs[preg].location.GetSimpleReg();
|
X64Reg xr = regs[preg].location.GetSimpleReg();
|
||||||
xregs[xr].free = true;
|
xregs[xr].free = true;
|
||||||
@ -351,11 +351,12 @@ void FPURegCache::StoreFromRegister(int i)
|
|||||||
{
|
{
|
||||||
X64Reg xr = regs[i].location.GetSimpleReg();
|
X64Reg xr = regs[i].location.GetSimpleReg();
|
||||||
_assert_msg_(DYNA_REC, xr < NUMXREGS, "WTF - store - invalid reg");
|
_assert_msg_(DYNA_REC, xr < NUMXREGS, "WTF - store - invalid reg");
|
||||||
|
OpArg newLoc = GetDefaultLocation(i);
|
||||||
|
if (xregs[xr].dirty)
|
||||||
|
emit->MOVAPD(newLoc, xr);
|
||||||
xregs[xr].free = true;
|
xregs[xr].free = true;
|
||||||
xregs[xr].dirty = false;
|
xregs[xr].dirty = false;
|
||||||
xregs[xr].ppcReg = -1;
|
xregs[xr].ppcReg = -1;
|
||||||
OpArg newLoc = GetDefaultLocation(i);
|
|
||||||
emit->MOVAPD(newLoc, xr);
|
|
||||||
regs[i].location = newLoc;
|
regs[i].location = newLoc;
|
||||||
regs[i].away = false;
|
regs[i].away = false;
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ public:
|
|||||||
const OpArg &R(int preg) const {return regs[preg].location;}
|
const OpArg &R(int preg) const {return regs[preg].location;}
|
||||||
X64Reg RX(int preg) const
|
X64Reg RX(int preg) const
|
||||||
{
|
{
|
||||||
if (regs[preg].away && regs[preg].location.IsSimpleReg())
|
if (IsBound(preg))
|
||||||
return regs[preg].location.GetSimpleReg();
|
return regs[preg].location.GetSimpleReg();
|
||||||
PanicAlert("Not so simple - %i", preg);
|
PanicAlert("Not so simple - %i", preg);
|
||||||
return (X64Reg)-1;
|
return (X64Reg)-1;
|
||||||
@ -111,6 +111,11 @@ public:
|
|||||||
return xregs[xreg].free && !xlocks[xreg];
|
return xregs[xreg].free && !xlocks[xreg];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsBound(int preg) const
|
||||||
|
{
|
||||||
|
return regs[preg].away && regs[preg].location.IsSimpleReg();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
X64Reg GetFreeXReg();
|
X64Reg GetFreeXReg();
|
||||||
|
|
||||||
|
@ -13,37 +13,62 @@ static const u64 GC_ALIGNED16(psAbsMask2[2]) = {0x7FFFFFFFFFFFFFFFULL, 0x7FFFFF
|
|||||||
static const double GC_ALIGNED16(psOneOne2[2]) = {1.0, 1.0};
|
static const double GC_ALIGNED16(psOneOne2[2]) = {1.0, 1.0};
|
||||||
static const double one_const = 1.0f;
|
static const double one_const = 1.0f;
|
||||||
|
|
||||||
void Jit64::fp_tri_op(int d, int a, int b, bool reversible, bool dupe, void (XEmitter::*op)(Gen::X64Reg, Gen::OpArg))
|
void Jit64::fp_tri_op(int d, int a, int b, bool reversible, bool single,
|
||||||
|
void (XEmitter::*op_2)(Gen::X64Reg, Gen::OpArg),
|
||||||
|
void (XEmitter::*op_3)(Gen::X64Reg, Gen::X64Reg, Gen::OpArg))
|
||||||
{
|
{
|
||||||
|
if (!cpu_info.bAVX)
|
||||||
|
{
|
||||||
|
op_3 = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
fpr.Lock(d, a, b);
|
fpr.Lock(d, a, b);
|
||||||
if (d == a)
|
if (d == a)
|
||||||
{
|
{
|
||||||
fpr.BindToRegister(d, true);
|
fpr.BindToRegister(d);
|
||||||
(this->*op)(fpr.RX(d), fpr.R(b));
|
(this->*op_2)(fpr.RX(d), fpr.R(b));
|
||||||
}
|
}
|
||||||
else if (d == b)
|
else if (d == b)
|
||||||
{
|
{
|
||||||
if (reversible)
|
if (reversible)
|
||||||
{
|
{
|
||||||
fpr.BindToRegister(d, true);
|
fpr.BindToRegister(d);
|
||||||
(this->*op)(fpr.RX(d), fpr.R(a));
|
(this->*op_2)(fpr.RX(d), fpr.R(a));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (op_3)
|
||||||
|
{
|
||||||
|
fpr.BindToRegister(d);
|
||||||
|
fpr.BindToRegister(a, true, false);
|
||||||
|
(this->*op_3)(fpr.RX(d), fpr.RX(a), fpr.R(b));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MOVSD(XMM0, fpr.R(b));
|
MOVSD(XMM0, fpr.R(b));
|
||||||
fpr.BindToRegister(d, !dupe);
|
fpr.BindToRegister(d, false);
|
||||||
MOVSD(fpr.RX(d), fpr.R(a));
|
MOVSD(fpr.RX(d), fpr.R(a));
|
||||||
(this->*op)(fpr.RX(d), Gen::R(XMM0));
|
(this->*op_2)(fpr.RX(d), Gen::R(XMM0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Sources different from d, can use rather quick solution
|
if (op_3)
|
||||||
fpr.BindToRegister(d, !dupe);
|
{
|
||||||
MOVSD(fpr.RX(d), fpr.R(a));
|
fpr.BindToRegister(d, false);
|
||||||
(this->*op)(fpr.RX(d), fpr.R(b));
|
fpr.BindToRegister(a);
|
||||||
|
(this->*op_3)(fpr.RX(d), fpr.RX(a), fpr.R(b));
|
||||||
}
|
}
|
||||||
if (dupe)
|
else
|
||||||
|
{
|
||||||
|
fpr.BindToRegister(d, false);
|
||||||
|
MOVSD(fpr.RX(d), fpr.R(a));
|
||||||
|
(this->*op_2)(fpr.RX(d), fpr.R(b));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (single)
|
||||||
{
|
{
|
||||||
ForceSinglePrecisionS(fpr.RX(d));
|
ForceSinglePrecisionS(fpr.RX(d));
|
||||||
if (cpu_info.bSSE3)
|
if (cpu_info.bSSE3)
|
||||||
@ -60,7 +85,7 @@ void Jit64::fp_tri_op(int d, int a, int b, bool reversible, bool dupe, void (XEm
|
|||||||
fpr.UnlockAll();
|
fpr.UnlockAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Jit64::fp_arith_s(UGeckoInstruction inst)
|
void Jit64::fp_arith(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
INSTRUCTION_START
|
INSTRUCTION_START
|
||||||
JITDISABLE(bJITFloatingPointOff)
|
JITDISABLE(bJITFloatingPointOff)
|
||||||
@ -73,15 +98,15 @@ void Jit64::fp_arith_s(UGeckoInstruction inst)
|
|||||||
Default(inst); return;
|
Default(inst); return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dupe = inst.OPCD == 59;
|
bool single = inst.OPCD == 59;
|
||||||
switch (inst.SUBOP5)
|
switch (inst.SUBOP5)
|
||||||
{
|
{
|
||||||
case 18: fp_tri_op(inst.FD, inst.FA, inst.FB, false, dupe, &XEmitter::DIVSD); break; //div
|
case 18: fp_tri_op(inst.FD, inst.FA, inst.FB, false, single, &XEmitter::DIVSD, &XEmitter::VDIVSD); break; //div
|
||||||
case 20: fp_tri_op(inst.FD, inst.FA, inst.FB, false, dupe, &XEmitter::SUBSD); break; //sub
|
case 20: fp_tri_op(inst.FD, inst.FA, inst.FB, false, single, &XEmitter::SUBSD, &XEmitter::VSUBSD); break; //sub
|
||||||
case 21: fp_tri_op(inst.FD, inst.FA, inst.FB, true, dupe, &XEmitter::ADDSD); break; //add
|
case 21: fp_tri_op(inst.FD, inst.FA, inst.FB, true, single, &XEmitter::ADDSD, &XEmitter::VADDSD); break; //add
|
||||||
case 25: fp_tri_op(inst.FD, inst.FA, inst.FC, true, dupe, &XEmitter::MULSD); break; //mul
|
case 25: fp_tri_op(inst.FD, inst.FA, inst.FC, true, single, &XEmitter::MULSD, &XEmitter::VMULSD); break; //mul
|
||||||
default:
|
default:
|
||||||
_assert_msg_(DYNA_REC, 0, "fp_arith_s WTF!!!");
|
_assert_msg_(DYNA_REC, 0, "fp_arith WTF!!!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,11 +117,18 @@ void Jit64::frsqrtex(UGeckoInstruction inst)
|
|||||||
int d = inst.FD;
|
int d = inst.FD;
|
||||||
int b = inst.FB;
|
int b = inst.FB;
|
||||||
fpr.Lock(b, d);
|
fpr.Lock(b, d);
|
||||||
fpr.BindToRegister(d, true, true);
|
fpr.BindToRegister(d, d == b, true);
|
||||||
MOVSD(XMM0, M((void *)&one_const));
|
MOVSD(XMM0, M((void *)&one_const));
|
||||||
SQRTSD(XMM1, fpr.R(b));
|
SQRTSD(XMM1, fpr.R(b));
|
||||||
|
if (cpu_info.bAVX)
|
||||||
|
{
|
||||||
|
VDIVSD(fpr.RX(d), XMM0, R(XMM1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
DIVSD(XMM0, R(XMM1));
|
DIVSD(XMM0, R(XMM1));
|
||||||
MOVSD(fpr.R(d), XMM0);
|
MOVSD(fpr.R(d), XMM0);
|
||||||
|
}
|
||||||
fpr.UnlockAll();
|
fpr.UnlockAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,16 +224,28 @@ void Jit64::fmrx(UGeckoInstruction inst)
|
|||||||
{
|
{
|
||||||
INSTRUCTION_START
|
INSTRUCTION_START
|
||||||
JITDISABLE(bJITFloatingPointOff)
|
JITDISABLE(bJITFloatingPointOff)
|
||||||
if (inst.Rc) {
|
if (inst.Rc)
|
||||||
|
{
|
||||||
Default(inst); return;
|
Default(inst); return;
|
||||||
}
|
}
|
||||||
int d = inst.FD;
|
int d = inst.FD;
|
||||||
int b = inst.FB;
|
int b = inst.FB;
|
||||||
|
if (d != b)
|
||||||
|
{
|
||||||
fpr.Lock(b, d);
|
fpr.Lock(b, d);
|
||||||
fpr.BindToRegister(d, true, true);
|
|
||||||
MOVSD(XMM0, fpr.R(b));
|
// we don't need to load d, but if it already is, it must be marked as dirty
|
||||||
MOVSD(fpr.R(d), XMM0);
|
if (fpr.IsBound(d))
|
||||||
|
{
|
||||||
|
fpr.BindToRegister(d);
|
||||||
|
}
|
||||||
|
fpr.BindToRegister(b, true, false);
|
||||||
|
|
||||||
|
// caveat: the order of ModRM:r/m, ModRM:reg is deliberate!
|
||||||
|
// "MOVSD reg, mem" zeros out the upper half of the destination register
|
||||||
|
MOVSD(fpr.R(d), fpr.RX(b));
|
||||||
fpr.UnlockAll();
|
fpr.UnlockAll();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Jit64::fcmpx(UGeckoInstruction inst)
|
void Jit64::fcmpx(UGeckoInstruction inst)
|
||||||
|
@ -122,12 +122,6 @@ void Jit64::psq_l(UGeckoInstruction inst)
|
|||||||
|
|
||||||
const UGQR gqr(rSPR(SPR_GQR0 + inst.I));
|
const UGQR gqr(rSPR(SPR_GQR0 + inst.I));
|
||||||
|
|
||||||
if (inst.W) {
|
|
||||||
// PanicAlert("Single ps load: %i %i", gqr.ST_TYPE, gqr.ST_SCALE);
|
|
||||||
Default(inst);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool update = inst.OPCD == 57;
|
bool update = inst.OPCD == 57;
|
||||||
int offset = inst.SIMM_12;
|
int offset = inst.SIMM_12;
|
||||||
|
|
||||||
@ -143,6 +137,8 @@ void Jit64::psq_l(UGeckoInstruction inst)
|
|||||||
MOV(32, gpr.R(inst.RA), R(ECX));
|
MOV(32, gpr.R(inst.RA), R(ECX));
|
||||||
MOVZX(32, 16, EAX, M(((char *)&GQR(inst.I)) + 2));
|
MOVZX(32, 16, EAX, M(((char *)&GQR(inst.I)) + 2));
|
||||||
MOVZX(32, 8, EDX, R(AL));
|
MOVZX(32, 8, EDX, R(AL));
|
||||||
|
if (inst.W)
|
||||||
|
OR(32, R(EDX), Imm8(8));
|
||||||
#ifdef _M_IX86
|
#ifdef _M_IX86
|
||||||
int addr_scale = SCALE_4;
|
int addr_scale = SCALE_4;
|
||||||
#else
|
#else
|
||||||
|
@ -14,10 +14,9 @@
|
|||||||
// cmppd, andpd, andnpd, or
|
// cmppd, andpd, andnpd, or
|
||||||
// lfsx, ps_merge01 etc
|
// lfsx, ps_merge01 etc
|
||||||
|
|
||||||
const u64 GC_ALIGNED16(psSignBits[2]) = {0x8000000000000000ULL, 0x8000000000000000ULL};
|
static const u64 GC_ALIGNED16(psSignBits[2]) = {0x8000000000000000ULL, 0x8000000000000000ULL};
|
||||||
const u64 GC_ALIGNED16(psAbsMask[2]) = {0x7FFFFFFFFFFFFFFFULL, 0x7FFFFFFFFFFFFFFFULL};
|
static const u64 GC_ALIGNED16(psAbsMask[2]) = {0x7FFFFFFFFFFFFFFFULL, 0x7FFFFFFFFFFFFFFFULL};
|
||||||
const double GC_ALIGNED16(psOneOne[2]) = {1.0, 1.0};
|
static const double GC_ALIGNED16(psOneOne[2]) = {1.0, 1.0};
|
||||||
const double GC_ALIGNED16(psZeroZero[2]) = {0.0, 0.0};
|
|
||||||
|
|
||||||
void Jit64::ps_mr(UGeckoInstruction inst)
|
void Jit64::ps_mr(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
@ -52,14 +51,15 @@ void Jit64::ps_sel(UGeckoInstruction inst)
|
|||||||
|
|
||||||
fpr.Lock(a, b, c, d);
|
fpr.Lock(a, b, c, d);
|
||||||
MOVAPD(XMM0, fpr.R(a));
|
MOVAPD(XMM0, fpr.R(a));
|
||||||
|
XORPD(XMM1, R(XMM1));
|
||||||
// XMM0 = XMM0 < 0 ? all 1s : all 0s
|
// XMM0 = XMM0 < 0 ? all 1s : all 0s
|
||||||
CMPPD(XMM0, M((void*)psZeroZero), LT);
|
CMPPD(XMM0, R(XMM1), LT);
|
||||||
MOVAPD(XMM1, R(XMM0));
|
MOVAPD(XMM1, R(XMM0));
|
||||||
ANDPD(XMM0, fpr.R(b));
|
ANDPD(XMM0, fpr.R(b));
|
||||||
ANDNPD(XMM1, fpr.R(c));
|
ANDNPD(XMM1, fpr.R(c));
|
||||||
|
ORPD(XMM0, R(XMM1));
|
||||||
fpr.BindToRegister(d, false);
|
fpr.BindToRegister(d, false);
|
||||||
MOVAPD(fpr.RX(d), R(XMM0));
|
MOVAPD(fpr.RX(d), R(XMM0));
|
||||||
ORPD(fpr.RX(d), R(XMM1));
|
|
||||||
fpr.UnlockAll();
|
fpr.UnlockAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -470,7 +470,7 @@ static void regEmitMemLoad(RegInfo& RI, InstLoc I, unsigned Size) {
|
|||||||
X64Reg reg;
|
X64Reg reg;
|
||||||
auto info = regBuildMemAddress(RI, I, getOp1(I), 1, Size, ®);
|
auto info = regBuildMemAddress(RI, I, getOp1(I), 1, Size, ®);
|
||||||
|
|
||||||
RI.Jit->SafeLoadToReg(reg, info.first, Size, info.second, regsInUse(RI), false);
|
RI.Jit->SafeLoadToReg(reg, info.first, Size, info.second, regsInUse(RI), false, EmuCodeBlock::SAFE_LOADSTORE_NO_FASTMEM);
|
||||||
if (regReadUse(RI, I))
|
if (regReadUse(RI, I))
|
||||||
RI.regs[reg] = I;
|
RI.regs[reg] = I;
|
||||||
}
|
}
|
||||||
@ -498,7 +498,7 @@ static void regEmitMemStore(RegInfo& RI, InstLoc I, unsigned Size) {
|
|||||||
} else {
|
} else {
|
||||||
RI.Jit->MOV(32, R(EAX), regLocForInst(RI, getOp1(I)));
|
RI.Jit->MOV(32, R(EAX), regLocForInst(RI, getOp1(I)));
|
||||||
}
|
}
|
||||||
RI.Jit->SafeWriteRegToReg(EAX, ECX, Size, 0, regsInUse(RI));
|
RI.Jit->SafeWriteRegToReg(EAX, ECX, Size, 0, regsInUse(RI), EmuCodeBlock::SAFE_LOADSTORE_NO_FASTMEM);
|
||||||
if (RI.IInfo[I - RI.FirstI] & 4)
|
if (RI.IInfo[I - RI.FirstI] & 4)
|
||||||
regClearInst(RI, getOp1(I));
|
regClearInst(RI, getOp1(I));
|
||||||
}
|
}
|
||||||
@ -1188,7 +1188,7 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress) {
|
|||||||
Jit->MOV(32, R(EAX), loc1);
|
Jit->MOV(32, R(EAX), loc1);
|
||||||
}
|
}
|
||||||
Jit->MOV(32, R(ECX), regLocForInst(RI, getOp2(I)));
|
Jit->MOV(32, R(ECX), regLocForInst(RI, getOp2(I)));
|
||||||
RI.Jit->SafeWriteRegToReg(EAX, ECX, 32, 0, regsInUse(RI));
|
RI.Jit->SafeWriteRegToReg(EAX, ECX, 32, 0, regsInUse(RI), EmuCodeBlock::SAFE_LOADSTORE_NO_FASTMEM);
|
||||||
if (RI.IInfo[I - RI.FirstI] & 4)
|
if (RI.IInfo[I - RI.FirstI] & 4)
|
||||||
fregClearInst(RI, getOp1(I));
|
fregClearInst(RI, getOp1(I));
|
||||||
if (RI.IInfo[I - RI.FirstI] & 8)
|
if (RI.IInfo[I - RI.FirstI] & 8)
|
||||||
@ -1251,12 +1251,12 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress) {
|
|||||||
Jit->PSRLQ(XMM0, 32);
|
Jit->PSRLQ(XMM0, 32);
|
||||||
Jit->MOVD_xmm(R(EAX), XMM0);
|
Jit->MOVD_xmm(R(EAX), XMM0);
|
||||||
Jit->MOV(32, R(ECX), address);
|
Jit->MOV(32, R(ECX), address);
|
||||||
RI.Jit->SafeWriteRegToReg(EAX, ECX, 32, 0, regsInUse(RI));
|
RI.Jit->SafeWriteRegToReg(EAX, ECX, 32, 0, regsInUse(RI), EmuCodeBlock::SAFE_LOADSTORE_NO_FASTMEM);
|
||||||
|
|
||||||
Jit->MOVAPD(XMM0, value);
|
Jit->MOVAPD(XMM0, value);
|
||||||
Jit->MOVD_xmm(R(EAX), XMM0);
|
Jit->MOVD_xmm(R(EAX), XMM0);
|
||||||
Jit->MOV(32, R(ECX), address);
|
Jit->MOV(32, R(ECX), address);
|
||||||
RI.Jit->SafeWriteRegToReg(EAX, ECX, 32, 4, regsInUse(RI));
|
RI.Jit->SafeWriteRegToReg(EAX, ECX, 32, 4, regsInUse(RI), EmuCodeBlock::SAFE_LOADSTORE_NO_FASTMEM);
|
||||||
Jit->SetJumpTarget(exit);
|
Jit->SetJumpTarget(exit);
|
||||||
|
|
||||||
if (RI.IInfo[I - RI.FirstI] & 4)
|
if (RI.IInfo[I - RI.FirstI] & 4)
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <cinttypes>
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "../../HLE/HLE.h"
|
#include "../../HLE/HLE.h"
|
||||||
@ -217,14 +219,14 @@ namespace JitILProfiler
|
|||||||
const u64 totalElapsed = block.totalElapsed;
|
const u64 totalElapsed = block.totalElapsed;
|
||||||
const u64 numberOfCalls = block.numberOfCalls;
|
const u64 numberOfCalls = block.numberOfCalls;
|
||||||
const double elapsedPerCall = totalElapsed / (double)numberOfCalls;
|
const double elapsedPerCall = totalElapsed / (double)numberOfCalls;
|
||||||
fprintf(file.GetHandle(), "%016llx,%lld,%lld,%f\n", codeHash, totalElapsed, numberOfCalls, elapsedPerCall);
|
fprintf(file.GetHandle(), "%016" PRIx64 ",%" PRId64 ",%" PRId64 ",%f\n", codeHash, totalElapsed, numberOfCalls, elapsedPerCall);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
std::auto_ptr<JitILProfilerFinalizer> finalizer;
|
std::unique_ptr<JitILProfilerFinalizer> finalizer;
|
||||||
static void Init()
|
static void Init()
|
||||||
{
|
{
|
||||||
finalizer = std::auto_ptr<JitILProfilerFinalizer>(new JitILProfilerFinalizer);
|
finalizer = std::unique_ptr<JitILProfilerFinalizer>(new JitILProfilerFinalizer);
|
||||||
}
|
}
|
||||||
static void Shutdown()
|
static void Shutdown()
|
||||||
{
|
{
|
||||||
|
@ -58,14 +58,10 @@ private:
|
|||||||
JitBlockCache blocks;
|
JitBlockCache blocks;
|
||||||
TrampolineCache trampolines;
|
TrampolineCache trampolines;
|
||||||
|
|
||||||
// The default code buffer. We keep it around to not have to alloc/dealloc a
|
|
||||||
// large chunk of memory for each recompiled block.
|
|
||||||
PPCAnalyst::CodeBuffer code_buffer;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
JitILAsmRoutineManager asm_routines;
|
JitILAsmRoutineManager asm_routines;
|
||||||
|
|
||||||
JitIL() : code_buffer(32000) {}
|
JitIL() {}
|
||||||
~JitIL() {}
|
~JitIL() {}
|
||||||
|
|
||||||
// Initialization, etc
|
// Initialization, etc
|
||||||
@ -140,6 +136,4 @@ public:
|
|||||||
void DynaRunTable63(UGeckoInstruction _inst) override;
|
void DynaRunTable63(UGeckoInstruction _inst) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
void Jit(u32 em_address);
|
|
||||||
|
|
||||||
#endif // _JITIL_H
|
#endif // _JITIL_H
|
||||||
|
@ -196,7 +196,7 @@ void CommonAsmRoutines::GenQuantizedStores()
|
|||||||
PACKSSDW(XMM0, R(XMM0));
|
PACKSSDW(XMM0, R(XMM0));
|
||||||
PACKUSWB(XMM0, R(XMM0));
|
PACKUSWB(XMM0, R(XMM0));
|
||||||
MOVD_xmm(R(EAX), XMM0);
|
MOVD_xmm(R(EAX), XMM0);
|
||||||
SafeWriteRegToReg(AX, ECX, 16, 0, QUANTIZED_REGS_TO_SAVE, SAFE_WRITE_NO_SWAP | SAFE_WRITE_NO_PROLOG | SAFE_WRITE_NO_FASTMEM);
|
SafeWriteRegToReg(AX, ECX, 16, 0, QUANTIZED_REGS_TO_SAVE, SAFE_LOADSTORE_NO_SWAP | SAFE_LOADSTORE_NO_PROLOG | SAFE_LOADSTORE_NO_FASTMEM);
|
||||||
|
|
||||||
RET();
|
RET();
|
||||||
|
|
||||||
@ -215,7 +215,7 @@ void CommonAsmRoutines::GenQuantizedStores()
|
|||||||
PACKSSWB(XMM0, R(XMM0));
|
PACKSSWB(XMM0, R(XMM0));
|
||||||
MOVD_xmm(R(EAX), XMM0);
|
MOVD_xmm(R(EAX), XMM0);
|
||||||
|
|
||||||
SafeWriteRegToReg(AX, ECX, 16, 0, QUANTIZED_REGS_TO_SAVE, SAFE_WRITE_NO_SWAP | SAFE_WRITE_NO_PROLOG | SAFE_WRITE_NO_FASTMEM);
|
SafeWriteRegToReg(AX, ECX, 16, 0, QUANTIZED_REGS_TO_SAVE, SAFE_LOADSTORE_NO_SWAP | SAFE_LOADSTORE_NO_PROLOG | SAFE_LOADSTORE_NO_FASTMEM);
|
||||||
|
|
||||||
RET();
|
RET();
|
||||||
|
|
||||||
@ -241,7 +241,7 @@ void CommonAsmRoutines::GenQuantizedStores()
|
|||||||
MOV(16, R(AX), M((char*)psTemp + 4));
|
MOV(16, R(AX), M((char*)psTemp + 4));
|
||||||
|
|
||||||
BSWAP(32, EAX);
|
BSWAP(32, EAX);
|
||||||
SafeWriteRegToReg(EAX, ECX, 32, 0, QUANTIZED_REGS_TO_SAVE, SAFE_WRITE_NO_SWAP | SAFE_WRITE_NO_PROLOG | SAFE_WRITE_NO_FASTMEM);
|
SafeWriteRegToReg(EAX, ECX, 32, 0, QUANTIZED_REGS_TO_SAVE, SAFE_LOADSTORE_NO_SWAP | SAFE_LOADSTORE_NO_PROLOG | SAFE_LOADSTORE_NO_FASTMEM);
|
||||||
|
|
||||||
RET();
|
RET();
|
||||||
|
|
||||||
@ -261,7 +261,7 @@ void CommonAsmRoutines::GenQuantizedStores()
|
|||||||
MOVD_xmm(R(EAX), XMM0);
|
MOVD_xmm(R(EAX), XMM0);
|
||||||
BSWAP(32, EAX);
|
BSWAP(32, EAX);
|
||||||
ROL(32, R(EAX), Imm8(16));
|
ROL(32, R(EAX), Imm8(16));
|
||||||
SafeWriteRegToReg(EAX, ECX, 32, 0, QUANTIZED_REGS_TO_SAVE, SAFE_WRITE_NO_SWAP | SAFE_WRITE_NO_PROLOG | SAFE_WRITE_NO_FASTMEM);
|
SafeWriteRegToReg(EAX, ECX, 32, 0, QUANTIZED_REGS_TO_SAVE, SAFE_LOADSTORE_NO_SWAP | SAFE_LOADSTORE_NO_PROLOG | SAFE_LOADSTORE_NO_FASTMEM);
|
||||||
|
|
||||||
RET();
|
RET();
|
||||||
|
|
||||||
@ -286,7 +286,7 @@ void CommonAsmRoutines::GenQuantizedSingleStores()
|
|||||||
|
|
||||||
// Easy!
|
// Easy!
|
||||||
const u8* storeSingleFloat = AlignCode4();
|
const u8* storeSingleFloat = AlignCode4();
|
||||||
SafeWriteFloatToReg(XMM0, ECX, QUANTIZED_REGS_TO_SAVE, SAFE_WRITE_NO_PROLOG | SAFE_WRITE_NO_FASTMEM);
|
SafeWriteFloatToReg(XMM0, ECX, QUANTIZED_REGS_TO_SAVE, SAFE_LOADSTORE_NO_PROLOG | SAFE_LOADSTORE_NO_FASTMEM);
|
||||||
RET();
|
RET();
|
||||||
/*
|
/*
|
||||||
if (cpu_info.bSSSE3) {
|
if (cpu_info.bSSSE3) {
|
||||||
@ -294,11 +294,11 @@ void CommonAsmRoutines::GenQuantizedSingleStores()
|
|||||||
// TODO: SafeWriteFloat
|
// TODO: SafeWriteFloat
|
||||||
MOVSS(M(&psTemp[0]), XMM0);
|
MOVSS(M(&psTemp[0]), XMM0);
|
||||||
MOV(32, R(EAX), M(&psTemp[0]));
|
MOV(32, R(EAX), M(&psTemp[0]));
|
||||||
SafeWriteRegToReg(EAX, ECX, 32, 0, SAFE_WRITE_NO_SWAP | SAFE_WRITE_NO_PROLOG | SAFE_WRITE_NO_FASTMEM);
|
SafeWriteRegToReg(EAX, ECX, 32, 0, SAFE_LOADSTORE_NO_SWAP | SAFE_LOADSTORE_NO_PROLOG | SAFE_LOADSTORE_NO_FASTMEM);
|
||||||
} else {
|
} else {
|
||||||
MOVSS(M(&psTemp[0]), XMM0);
|
MOVSS(M(&psTemp[0]), XMM0);
|
||||||
MOV(32, R(EAX), M(&psTemp[0]));
|
MOV(32, R(EAX), M(&psTemp[0]));
|
||||||
SafeWriteRegToReg(EAX, ECX, 32, 0, SAFE_WRITE_NO_PROLOG | SAFE_WRITE_NO_FASTMEM);
|
SafeWriteRegToReg(EAX, ECX, 32, 0, SAFE_LOADSTORE_NO_PROLOG | SAFE_LOADSTORE_NO_FASTMEM);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
const u8* storeSingleU8 = AlignCode4(); // Used by MKWii
|
const u8* storeSingleU8 = AlignCode4(); // Used by MKWii
|
||||||
@ -309,7 +309,7 @@ void CommonAsmRoutines::GenQuantizedSingleStores()
|
|||||||
MAXSS(XMM0, R(XMM1));
|
MAXSS(XMM0, R(XMM1));
|
||||||
MINSS(XMM0, M((void *)&m_255));
|
MINSS(XMM0, M((void *)&m_255));
|
||||||
CVTTSS2SI(EAX, R(XMM0));
|
CVTTSS2SI(EAX, R(XMM0));
|
||||||
SafeWriteRegToReg(AL, ECX, 8, 0, QUANTIZED_REGS_TO_SAVE, SAFE_WRITE_NO_PROLOG | SAFE_WRITE_NO_FASTMEM);
|
SafeWriteRegToReg(AL, ECX, 8, 0, QUANTIZED_REGS_TO_SAVE, SAFE_LOADSTORE_NO_PROLOG | SAFE_LOADSTORE_NO_FASTMEM);
|
||||||
RET();
|
RET();
|
||||||
|
|
||||||
const u8* storeSingleS8 = AlignCode4();
|
const u8* storeSingleS8 = AlignCode4();
|
||||||
@ -319,7 +319,7 @@ void CommonAsmRoutines::GenQuantizedSingleStores()
|
|||||||
MAXSS(XMM0, M((void *)&m_m128));
|
MAXSS(XMM0, M((void *)&m_m128));
|
||||||
MINSS(XMM0, M((void *)&m_127));
|
MINSS(XMM0, M((void *)&m_127));
|
||||||
CVTTSS2SI(EAX, R(XMM0));
|
CVTTSS2SI(EAX, R(XMM0));
|
||||||
SafeWriteRegToReg(AL, ECX, 8, 0, QUANTIZED_REGS_TO_SAVE, SAFE_WRITE_NO_PROLOG | SAFE_WRITE_NO_FASTMEM);
|
SafeWriteRegToReg(AL, ECX, 8, 0, QUANTIZED_REGS_TO_SAVE, SAFE_LOADSTORE_NO_PROLOG | SAFE_LOADSTORE_NO_FASTMEM);
|
||||||
RET();
|
RET();
|
||||||
|
|
||||||
const u8* storeSingleU16 = AlignCode4(); // Used by MKWii
|
const u8* storeSingleU16 = AlignCode4(); // Used by MKWii
|
||||||
@ -330,7 +330,7 @@ void CommonAsmRoutines::GenQuantizedSingleStores()
|
|||||||
MAXSS(XMM0, R(XMM1));
|
MAXSS(XMM0, R(XMM1));
|
||||||
MINSS(XMM0, M((void *)&m_65535));
|
MINSS(XMM0, M((void *)&m_65535));
|
||||||
CVTTSS2SI(EAX, R(XMM0));
|
CVTTSS2SI(EAX, R(XMM0));
|
||||||
SafeWriteRegToReg(EAX, ECX, 16, 0, QUANTIZED_REGS_TO_SAVE, SAFE_WRITE_NO_PROLOG | SAFE_WRITE_NO_FASTMEM);
|
SafeWriteRegToReg(EAX, ECX, 16, 0, QUANTIZED_REGS_TO_SAVE, SAFE_LOADSTORE_NO_PROLOG | SAFE_LOADSTORE_NO_FASTMEM);
|
||||||
RET();
|
RET();
|
||||||
|
|
||||||
const u8* storeSingleS16 = AlignCode4();
|
const u8* storeSingleS16 = AlignCode4();
|
||||||
@ -340,7 +340,7 @@ void CommonAsmRoutines::GenQuantizedSingleStores()
|
|||||||
MAXSS(XMM0, M((void *)&m_m32768));
|
MAXSS(XMM0, M((void *)&m_m32768));
|
||||||
MINSS(XMM0, M((void *)&m_32767));
|
MINSS(XMM0, M((void *)&m_32767));
|
||||||
CVTTSS2SI(EAX, R(XMM0));
|
CVTTSS2SI(EAX, R(XMM0));
|
||||||
SafeWriteRegToReg(EAX, ECX, 16, 0, QUANTIZED_REGS_TO_SAVE, SAFE_WRITE_NO_PROLOG | SAFE_WRITE_NO_FASTMEM);
|
SafeWriteRegToReg(EAX, ECX, 16, 0, QUANTIZED_REGS_TO_SAVE, SAFE_LOADSTORE_NO_PROLOG | SAFE_LOADSTORE_NO_FASTMEM);
|
||||||
RET();
|
RET();
|
||||||
|
|
||||||
singleStoreQuantized = reinterpret_cast<const u8**>(const_cast<u8*>(AlignCode16()));
|
singleStoreQuantized = reinterpret_cast<const u8**>(const_cast<u8*>(AlignCode16()));
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <cinttypes>
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "disasm.h"
|
#include "disasm.h"
|
||||||
@ -32,7 +33,7 @@ static void BackPatchError(const std::string &text, u8 *codePtr, u32 emAddress)
|
|||||||
#endif
|
#endif
|
||||||
PanicAlert("%s\n\n"
|
PanicAlert("%s\n\n"
|
||||||
"Error encountered accessing emulated address %08x.\n"
|
"Error encountered accessing emulated address %08x.\n"
|
||||||
"Culprit instruction: \n%s\nat %#llx",
|
"Culprit instruction: \n%s\nat %#" PRIx64,
|
||||||
text.c_str(), emAddress, disbuf, code_addr);
|
text.c_str(), emAddress, disbuf, code_addr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -233,7 +234,7 @@ const u8 *Jitx86Base::BackPatch(u8 *codePtr, u32 emAddress, void *ctx_void)
|
|||||||
XEmitter emitter(start);
|
XEmitter emitter(start);
|
||||||
const u8 *trampoline = trampolines.GetWriteTrampoline(info, registersInUse);
|
const u8 *trampoline = trampolines.GetWriteTrampoline(info, registersInUse);
|
||||||
emitter.CALL((void *)trampoline);
|
emitter.CALL((void *)trampoline);
|
||||||
emitter.NOP(codePtr + info.instructionSize - emitter.GetCodePtr());
|
emitter.NOP((int)(codePtr + info.instructionSize - emitter.GetCodePtr()));
|
||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -117,18 +117,20 @@ u8 *EmuCodeBlock::UnsafeLoadToReg(X64Reg reg_value, Gen::OpArg opAddress, int ac
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuCodeBlock::SafeLoadToReg(X64Reg reg_value, const Gen::OpArg & opAddress, int accessSize, s32 offset, u32 registersInUse, bool signExtend)
|
void EmuCodeBlock::SafeLoadToReg(X64Reg reg_value, const Gen::OpArg & opAddress, int accessSize, s32 offset, u32 registersInUse, bool signExtend, int flags)
|
||||||
{
|
{
|
||||||
if (!jit->js.memcheck)
|
if (!jit->js.memcheck)
|
||||||
{
|
{
|
||||||
registersInUse &= ~(1 << RAX | 1 << reg_value);
|
registersInUse &= ~(1 << RAX | 1 << reg_value);
|
||||||
}
|
}
|
||||||
#if defined(_M_X64)
|
#if defined(_M_X64)
|
||||||
|
if (!Core::g_CoreStartupParameter.bMMU &&
|
||||||
|
Core::g_CoreStartupParameter.bFastmem &&
|
||||||
|
!(flags & (SAFE_LOADSTORE_NO_SWAP | SAFE_LOADSTORE_NO_FASTMEM))
|
||||||
#ifdef ENABLE_MEM_CHECK
|
#ifdef ENABLE_MEM_CHECK
|
||||||
if (!Core::g_CoreStartupParameter.bMMU && !Core::g_CoreStartupParameter.bEnableDebugging && Core::g_CoreStartupParameter.bFastmem)
|
&& !Core::g_CoreStartupParameter.bEnableDebugging
|
||||||
#else
|
|
||||||
if (!Core::g_CoreStartupParameter.bMMU && Core::g_CoreStartupParameter.bFastmem)
|
|
||||||
#endif
|
#endif
|
||||||
|
)
|
||||||
{
|
{
|
||||||
u8 *mov = UnsafeLoadToReg(reg_value, opAddress, accessSize, offset, signExtend);
|
u8 *mov = UnsafeLoadToReg(reg_value, opAddress, accessSize, offset, signExtend);
|
||||||
|
|
||||||
@ -282,14 +284,14 @@ void EmuCodeBlock::SafeWriteRegToReg(X64Reg reg_value, X64Reg reg_addr, int acce
|
|||||||
#if defined(_M_X64)
|
#if defined(_M_X64)
|
||||||
if (!Core::g_CoreStartupParameter.bMMU &&
|
if (!Core::g_CoreStartupParameter.bMMU &&
|
||||||
Core::g_CoreStartupParameter.bFastmem &&
|
Core::g_CoreStartupParameter.bFastmem &&
|
||||||
!(flags & (SAFE_WRITE_NO_SWAP | SAFE_WRITE_NO_FASTMEM))
|
!(flags & (SAFE_LOADSTORE_NO_SWAP | SAFE_LOADSTORE_NO_FASTMEM))
|
||||||
#ifdef ENABLE_MEM_CHECK
|
#ifdef ENABLE_MEM_CHECK
|
||||||
&& !Core::g_CoreStartupParameter.bEnableDebugging
|
&& !Core::g_CoreStartupParameter.bEnableDebugging
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
MOV(32, M(&PC), Imm32(jit->js.compilerPC)); // Helps external systems know which instruction triggered the write
|
MOV(32, M(&PC), Imm32(jit->js.compilerPC)); // Helps external systems know which instruction triggered the write
|
||||||
u8 *mov = UnsafeWriteRegToReg(reg_value, reg_addr, accessSize, offset, !(flags & SAFE_WRITE_NO_SWAP));
|
u8 *mov = UnsafeWriteRegToReg(reg_value, reg_addr, accessSize, offset, !(flags & SAFE_LOADSTORE_NO_SWAP));
|
||||||
if (accessSize == 8)
|
if (accessSize == 8)
|
||||||
{
|
{
|
||||||
NOP(1);
|
NOP(1);
|
||||||
@ -321,8 +323,8 @@ void EmuCodeBlock::SafeWriteRegToReg(X64Reg reg_value, X64Reg reg_addr, int acce
|
|||||||
MOV(32, M(&PC), Imm32(jit->js.compilerPC)); // Helps external systems know which instruction triggered the write
|
MOV(32, M(&PC), Imm32(jit->js.compilerPC)); // Helps external systems know which instruction triggered the write
|
||||||
TEST(32, R(reg_addr), Imm32(mem_mask));
|
TEST(32, R(reg_addr), Imm32(mem_mask));
|
||||||
FixupBranch fast = J_CC(CC_Z, true);
|
FixupBranch fast = J_CC(CC_Z, true);
|
||||||
bool noProlog = flags & SAFE_WRITE_NO_PROLOG;
|
bool noProlog = (0 != (flags & SAFE_LOADSTORE_NO_PROLOG));
|
||||||
bool swap = !(flags & SAFE_WRITE_NO_SWAP);
|
bool swap = !(flags & SAFE_LOADSTORE_NO_SWAP);
|
||||||
ABI_PushRegistersAndAdjustStack(registersInUse, noProlog);
|
ABI_PushRegistersAndAdjustStack(registersInUse, noProlog);
|
||||||
switch (accessSize)
|
switch (accessSize)
|
||||||
{
|
{
|
||||||
|
@ -28,13 +28,13 @@ public:
|
|||||||
// these return the address of the MOV, for backpatching
|
// these return the address of the MOV, for backpatching
|
||||||
u8 *UnsafeWriteRegToReg(Gen::X64Reg reg_value, Gen::X64Reg reg_addr, int accessSize, s32 offset = 0, bool swap = true);
|
u8 *UnsafeWriteRegToReg(Gen::X64Reg reg_value, Gen::X64Reg reg_addr, int accessSize, s32 offset = 0, bool swap = true);
|
||||||
u8 *UnsafeLoadToReg(Gen::X64Reg reg_value, Gen::OpArg opAddress, int accessSize, s32 offset, bool signExtend);
|
u8 *UnsafeLoadToReg(Gen::X64Reg reg_value, Gen::OpArg opAddress, int accessSize, s32 offset, bool signExtend);
|
||||||
void SafeLoadToReg(Gen::X64Reg reg_value, const Gen::OpArg & opAddress, int accessSize, s32 offset, u32 registersInUse, bool signExtend);
|
enum SafeLoadStoreFlags
|
||||||
enum SafeWriteFlags
|
|
||||||
{
|
{
|
||||||
SAFE_WRITE_NO_SWAP = 1,
|
SAFE_LOADSTORE_NO_SWAP = 1,
|
||||||
SAFE_WRITE_NO_PROLOG = 2,
|
SAFE_LOADSTORE_NO_PROLOG = 2,
|
||||||
SAFE_WRITE_NO_FASTMEM = 4
|
SAFE_LOADSTORE_NO_FASTMEM = 4
|
||||||
};
|
};
|
||||||
|
void SafeLoadToReg(Gen::X64Reg reg_value, const Gen::OpArg & opAddress, int accessSize, s32 offset, u32 registersInUse, bool signExtend, int flags = 0);
|
||||||
void SafeWriteRegToReg(Gen::X64Reg reg_value, Gen::X64Reg reg_addr, int accessSize, s32 offset, u32 registersInUse, int flags = 0);
|
void SafeWriteRegToReg(Gen::X64Reg reg_value, Gen::X64Reg reg_addr, int accessSize, s32 offset, u32 registersInUse, int flags = 0);
|
||||||
|
|
||||||
// Trashes both inputs and EAX.
|
// Trashes both inputs and EAX.
|
||||||
|
@ -118,6 +118,7 @@ Fix profiled loads/stores to work safely. On 32-bit, one solution is to
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <cinttypes>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include "IR.h"
|
#include "IR.h"
|
||||||
@ -1223,7 +1224,7 @@ struct Writer
|
|||||||
virtual ~Writer() {}
|
virtual ~Writer() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::auto_ptr<Writer> writer;
|
static std::unique_ptr<Writer> writer;
|
||||||
|
|
||||||
static const std::string opcodeNames[] = {
|
static const std::string opcodeNames[] = {
|
||||||
"Nop", "LoadGReg", "LoadLink", "LoadCR", "LoadCarry", "LoadCTR",
|
"Nop", "LoadGReg", "LoadLink", "LoadCR", "LoadCarry", "LoadCTR",
|
||||||
@ -1275,11 +1276,11 @@ void IRBuilder::WriteToFile(u64 codeHash) {
|
|||||||
_assert_(sizeof(opcodeNames) / sizeof(opcodeNames[0]) == Int3 + 1);
|
_assert_(sizeof(opcodeNames) / sizeof(opcodeNames[0]) == Int3 + 1);
|
||||||
|
|
||||||
if (!writer.get()) {
|
if (!writer.get()) {
|
||||||
writer = std::auto_ptr<Writer>(new Writer);
|
writer = std::unique_ptr<Writer>(new Writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE* const file = writer->file.GetHandle();
|
FILE* const file = writer->file.GetHandle();
|
||||||
fprintf(file, "\ncode hash:%016llx\n", codeHash);
|
fprintf(file, "\ncode hash:%016" PRIx64 "\n", codeHash);
|
||||||
|
|
||||||
const InstLoc lastCurReadPtr = curReadPtr;
|
const InstLoc lastCurReadPtr = curReadPtr;
|
||||||
StartForwardPass();
|
StartForwardPass();
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cinttypes>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
@ -171,12 +172,12 @@ namespace JitInterface
|
|||||||
double percent = 100.0 * (double)stat.cost / (double)cost_sum;
|
double percent = 100.0 * (double)stat.cost / (double)cost_sum;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
double timePercent = 100.0 * (double)block->ticCounter / (double)timecost_sum;
|
double timePercent = 100.0 * (double)block->ticCounter / (double)timecost_sum;
|
||||||
fprintf(f.GetHandle(), "%08x\t%s\t%llu\t%llu\t%.2lf\t%llf\t%lf\t%i\n",
|
fprintf(f.GetHandle(), "%08x\t%s\t%" PRIu64 "\t%" PRIu64 "\t%.2lf\t%llf\t%lf\t%i\n",
|
||||||
block->originalAddress, name.c_str(), stat.cost,
|
block->originalAddress, name.c_str(), stat.cost,
|
||||||
block->ticCounter, percent, timePercent,
|
block->ticCounter, percent, timePercent,
|
||||||
(double)block->ticCounter*1000.0/(double)countsPerSec, block->codeSize);
|
(double)block->ticCounter*1000.0/(double)countsPerSec, block->codeSize);
|
||||||
#else
|
#else
|
||||||
fprintf(f.GetHandle(), "%08x\t%s\t%llu\t???\t%.2lf\t???\t???\t%i\n",
|
fprintf(f.GetHandle(), "%08x\t%s\t%" PRIu64 "\t???\t%.2lf\t???\t???\t%i\n",
|
||||||
block->originalAddress, name.c_str(), stat.cost, percent, block->codeSize);
|
block->originalAddress, name.c_str(), stat.cost, percent, block->codeSize);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <cinttypes>
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "PPCTables.h"
|
#include "PPCTables.h"
|
||||||
@ -13,24 +14,15 @@
|
|||||||
#include "Interpreter/Interpreter_Tables.h"
|
#include "Interpreter/Interpreter_Tables.h"
|
||||||
#include "JitInterface.h"
|
#include "JitInterface.h"
|
||||||
|
|
||||||
struct op_inf
|
GekkoOPInfo *m_infoTable[64];
|
||||||
{
|
GekkoOPInfo *m_infoTable4[1024];
|
||||||
const char *name;
|
GekkoOPInfo *m_infoTable19[1024];
|
||||||
int count;
|
GekkoOPInfo *m_infoTable31[1024];
|
||||||
bool operator < (const op_inf &o) const
|
GekkoOPInfo *m_infoTable59[32];
|
||||||
{
|
GekkoOPInfo *m_infoTable63[1024];
|
||||||
return count > o.count;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
GekkoOPInfo *m_infoTable[64];
|
|
||||||
GekkoOPInfo *m_infoTable4[1024];
|
|
||||||
GekkoOPInfo *m_infoTable19[1024];
|
|
||||||
GekkoOPInfo *m_infoTable31[1024];
|
|
||||||
GekkoOPInfo *m_infoTable59[32];
|
|
||||||
GekkoOPInfo *m_infoTable63[1024];
|
|
||||||
|
|
||||||
GekkoOPInfo *m_allInstructions[512];
|
GekkoOPInfo *m_allInstructions[512];
|
||||||
int m_numInstructions;
|
int m_numInstructions;
|
||||||
|
|
||||||
GekkoOPInfo *GetOpInfo(UGeckoInstruction _inst)
|
GekkoOPInfo *GetOpInfo(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
@ -181,26 +173,34 @@ void CountInstruction(UGeckoInstruction _inst)
|
|||||||
{
|
{
|
||||||
GekkoOPInfo *info = GetOpInfo(_inst);
|
GekkoOPInfo *info = GetOpInfo(_inst);
|
||||||
if (info)
|
if (info)
|
||||||
|
{
|
||||||
info->runCount++;
|
info->runCount++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintInstructionRunCounts()
|
void PrintInstructionRunCounts()
|
||||||
{
|
{
|
||||||
std::vector<op_inf> temp;
|
typedef std::pair<const char*, u64> OpInfo;
|
||||||
for (int i = 0; i < m_numInstructions; i++)
|
std::vector<OpInfo> temp;
|
||||||
|
temp.reserve(m_numInstructions);
|
||||||
|
for (int i = 0; i < m_numInstructions; ++i)
|
||||||
{
|
{
|
||||||
op_inf x;
|
GekkoOPInfo *pInst = m_allInstructions[i];
|
||||||
x.name = m_allInstructions[i]->opname;
|
temp.emplace_back(pInst->opname, pInst->runCount);
|
||||||
x.count = m_allInstructions[i]->runCount;
|
|
||||||
temp.push_back(x);
|
|
||||||
}
|
}
|
||||||
std::sort(temp.begin(), temp.end());
|
std::sort(temp.begin(), temp.end(),
|
||||||
for (int i = 0; i < m_numInstructions; i++)
|
[](const OpInfo &a, const OpInfo &b)
|
||||||
{
|
{
|
||||||
if (temp[i].count == 0)
|
return a.second > b.second;
|
||||||
|
});
|
||||||
|
|
||||||
|
for (auto &inst : temp)
|
||||||
|
{
|
||||||
|
if (inst.second == 0)
|
||||||
break;
|
break;
|
||||||
DEBUG_LOG(POWERPC, "%s : %i", temp[i].name,temp[i].count);
|
|
||||||
//PanicAlert("%s : %i", temp[i].name,temp[i].count);
|
DEBUG_LOG(POWERPC, "%s : %llu", inst.first, inst.second);
|
||||||
|
//PanicAlert("%s : %llu", inst.first, inst.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,20 +211,22 @@ void LogCompiledInstructions()
|
|||||||
File::IOFile f(StringFromFormat("%sinst_log%i.txt", File::GetUserPath(D_LOGS_IDX).c_str(), time), "w");
|
File::IOFile f(StringFromFormat("%sinst_log%i.txt", File::GetUserPath(D_LOGS_IDX).c_str(), time), "w");
|
||||||
for (int i = 0; i < m_numInstructions; i++)
|
for (int i = 0; i < m_numInstructions; i++)
|
||||||
{
|
{
|
||||||
if (m_allInstructions[i]->compileCount > 0)
|
GekkoOPInfo *pInst = m_allInstructions[i];
|
||||||
|
if (pInst->compileCount > 0)
|
||||||
{
|
{
|
||||||
fprintf(f.GetHandle(), "%s\t%i\t%lld\t%08x\n", m_allInstructions[i]->opname,
|
fprintf(f.GetHandle(), "%s\t%i\t%" PRId64 "\t%08x\n", pInst->opname,
|
||||||
m_allInstructions[i]->compileCount, m_allInstructions[i]->runCount, m_allInstructions[i]->lastUse);
|
pInst->compileCount, pInst->runCount, pInst->lastUse);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
f.Open(StringFromFormat("%sinst_not%i.txt", File::GetUserPath(D_LOGS_IDX).c_str(), time), "w");
|
f.Open(StringFromFormat("%sinst_not%i.txt", File::GetUserPath(D_LOGS_IDX).c_str(), time), "w");
|
||||||
for (int i = 0; i < m_numInstructions; i++)
|
for (int i = 0; i < m_numInstructions; i++)
|
||||||
{
|
{
|
||||||
if (m_allInstructions[i]->compileCount == 0)
|
GekkoOPInfo *pInst = m_allInstructions[i];
|
||||||
|
if (pInst->compileCount == 0)
|
||||||
{
|
{
|
||||||
fprintf(f.GetHandle(), "%s\t%i\t%lld\n", m_allInstructions[i]->opname,
|
fprintf(f.GetHandle(), "%s\t%i\t%" PRId64 "\n", pInst->opname,
|
||||||
m_allInstructions[i]->compileCount, m_allInstructions[i]->runCount);
|
pInst->compileCount, pInst->runCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,7 +247,7 @@ void CompressAndDumpState(CompressAndDumpState_args save_args)
|
|||||||
// Setting up the header
|
// Setting up the header
|
||||||
StateHeader header;
|
StateHeader header;
|
||||||
memcpy(header.gameID, SConfig::GetInstance().m_LocalCoreStartupParameter.GetUniqueID().c_str(), 6);
|
memcpy(header.gameID, SConfig::GetInstance().m_LocalCoreStartupParameter.GetUniqueID().c_str(), 6);
|
||||||
header.size = g_use_compression ? buffer_size : 0;
|
header.size = g_use_compression ? (u32)buffer_size : 0;
|
||||||
header.time = Common::Timer::GetDoubleTime();
|
header.time = Common::Timer::GetDoubleTime();
|
||||||
|
|
||||||
f.WriteArray(&header, 1);
|
f.WriteArray(&header, 1);
|
||||||
@ -261,9 +261,13 @@ void CompressAndDumpState(CompressAndDumpState_args save_args)
|
|||||||
lzo_uint out_len = 0;
|
lzo_uint out_len = 0;
|
||||||
|
|
||||||
if ((i + IN_LEN) >= buffer_size)
|
if ((i + IN_LEN) >= buffer_size)
|
||||||
cur_len = buffer_size - i;
|
{
|
||||||
|
cur_len = (lzo_uint32)(buffer_size - i);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
cur_len = IN_LEN;
|
cur_len = IN_LEN;
|
||||||
|
}
|
||||||
|
|
||||||
if (lzo1x_1_compress(buffer_data + i, cur_len, out, &out_len, wrkmem) != LZO_E_OK)
|
if (lzo1x_1_compress(buffer_data + i, cur_len, out, &out_len, wrkmem) != LZO_E_OK)
|
||||||
PanicAlertT("Internal LZO Error - compression failed");
|
PanicAlertT("Internal LZO Error - compression failed");
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <cinttypes>
|
||||||
|
|
||||||
#include "CompressedBlob.h"
|
#include "CompressedBlob.h"
|
||||||
#include "DiscScrubber.h"
|
#include "DiscScrubber.h"
|
||||||
#include "FileUtil.h"
|
#include "FileUtil.h"
|
||||||
@ -99,7 +101,7 @@ void CompressedBlobReader::GetBlock(u64 block_num, u8 *out_ptr)
|
|||||||
// First, check hash.
|
// First, check hash.
|
||||||
u32 block_hash = HashAdler32(source, comp_block_size);
|
u32 block_hash = HashAdler32(source, comp_block_size);
|
||||||
if (block_hash != hashes[block_num])
|
if (block_hash != hashes[block_num])
|
||||||
PanicAlert("Hash of block %lli is %08x instead of %08x.\n"
|
PanicAlert("Hash of block %" PRIu64 " is %08x instead of %08x.\n"
|
||||||
"Your ISO, %s, is corrupt.",
|
"Your ISO, %s, is corrupt.",
|
||||||
block_num, block_hash, hashes[block_num],
|
block_num, block_hash, hashes[block_num],
|
||||||
file_name.c_str());
|
file_name.c_str());
|
||||||
@ -127,7 +129,7 @@ void CompressedBlobReader::GetBlock(u64 block_num, u8 *out_ptr)
|
|||||||
{
|
{
|
||||||
// this seem to fire wrongly from time to time
|
// this seem to fire wrongly from time to time
|
||||||
// to be sure, don't use compressed isos :P
|
// to be sure, don't use compressed isos :P
|
||||||
PanicAlert("Failure reading block %lli - out of data and not at end.", block_num);
|
PanicAlert("Failure reading block %" PRIu64 " - out of data and not at end.", block_num);
|
||||||
}
|
}
|
||||||
inflateEnd(&z);
|
inflateEnd(&z);
|
||||||
if (uncomp_size != header.block_size)
|
if (uncomp_size != header.block_size)
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#include "FileUtil.h"
|
#include "FileUtil.h"
|
||||||
#include "DiscScrubber.h"
|
#include "DiscScrubber.h"
|
||||||
|
|
||||||
|
#include <cinttypes>
|
||||||
|
|
||||||
namespace DiscIO
|
namespace DiscIO
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -121,13 +123,13 @@ void GetNextBlock(File::IOFile& in, u8* buffer)
|
|||||||
|
|
||||||
if (m_isScrubbing && m_FreeTable[i])
|
if (m_isScrubbing && m_FreeTable[i])
|
||||||
{
|
{
|
||||||
DEBUG_LOG(DISCIO, "Freeing 0x%016llx", CurrentOffset);
|
DEBUG_LOG(DISCIO, "Freeing 0x%016" PRIx64, CurrentOffset);
|
||||||
std::fill(buffer, buffer + m_BlockSize, 0xFF);
|
std::fill(buffer, buffer + m_BlockSize, 0xFF);
|
||||||
in.Seek(m_BlockSize, SEEK_CUR);
|
in.Seek(m_BlockSize, SEEK_CUR);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DEBUG_LOG(DISCIO, "Used 0x%016llx", CurrentOffset);
|
DEBUG_LOG(DISCIO, "Used 0x%016" PRIx64, CurrentOffset);
|
||||||
in.ReadBytes(buffer, m_BlockSize);
|
in.ReadBytes(buffer, m_BlockSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +152,7 @@ void MarkAsUsed(u64 _Offset, u64 _Size)
|
|||||||
u64 CurrentOffset = _Offset;
|
u64 CurrentOffset = _Offset;
|
||||||
u64 EndOffset = CurrentOffset + _Size;
|
u64 EndOffset = CurrentOffset + _Size;
|
||||||
|
|
||||||
DEBUG_LOG(DISCIO, "Marking 0x%016llx - 0x%016llx as used", _Offset, EndOffset);
|
DEBUG_LOG(DISCIO, "Marking 0x%016" PRIx64 " - 0x%016" PRIx64 " as used", _Offset, EndOffset);
|
||||||
|
|
||||||
while ((CurrentOffset < EndOffset) && (CurrentOffset < m_FileSize))
|
while ((CurrentOffset < EndOffset) && (CurrentOffset < m_FileSize))
|
||||||
{
|
{
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cinttypes>
|
||||||
|
|
||||||
#include "FileSystemGCWii.h"
|
#include "FileSystemGCWii.h"
|
||||||
#include "StringUtil.h"
|
#include "StringUtil.h"
|
||||||
@ -70,7 +71,7 @@ u64 CFileSystemGCWii::ReadFile(const char* _rFullPath, u8* _pBuffer, size_t _Max
|
|||||||
if (pFileInfo->m_FileSize > _MaxBufferSize)
|
if (pFileInfo->m_FileSize > _MaxBufferSize)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
DEBUG_LOG(DISCIO, "Filename: %s. Offset: %llx. Size: %llx",_rFullPath,
|
DEBUG_LOG(DISCIO, "Filename: %s. Offset: %" PRIx64 ". Size: %" PRIx64, _rFullPath,
|
||||||
pFileInfo->m_Offset, pFileInfo->m_FileSize);
|
pFileInfo->m_Offset, pFileInfo->m_FileSize);
|
||||||
|
|
||||||
m_rVolume->Read(pFileInfo->m_Offset, pFileInfo->m_FileSize, _pBuffer);
|
m_rVolume->Read(pFileInfo->m_Offset, pFileInfo->m_FileSize, _pBuffer);
|
||||||
|
@ -183,8 +183,18 @@ static IVolume* CreateVolumeFromCryptedWiiImage(IBlobReader& _rReader, u32 _Part
|
|||||||
memset(IV, 0, 16);
|
memset(IV, 0, 16);
|
||||||
_rReader.Read(rPartition.Offset + 0x44c, 8, IV);
|
_rReader.Read(rPartition.Offset + 0x44c, 8, IV);
|
||||||
|
|
||||||
|
bool usingKoreanKey = false;
|
||||||
|
// Issue: 6813
|
||||||
|
// Magic value is at 0x501f1 (1byte)
|
||||||
|
// If encrypted with the Korean key, the magic value would be 1
|
||||||
|
// Otherwise it is zero
|
||||||
|
if (Korean && Reader.Read32(0x501ee) != 0)
|
||||||
|
{
|
||||||
|
usingKoreanKey = true;
|
||||||
|
}
|
||||||
|
|
||||||
aes_context AES_ctx;
|
aes_context AES_ctx;
|
||||||
aes_setkey_dec(&AES_ctx, (Korean ? g_MasterKeyK : g_MasterKey), 128);
|
aes_setkey_dec(&AES_ctx, (usingKoreanKey ? g_MasterKeyK : g_MasterKey), 128);
|
||||||
|
|
||||||
u8 VolumeKey[16];
|
u8 VolumeKey[16];
|
||||||
aes_crypt_cbc(&AES_ctx, AES_DECRYPT, 16, IV, SubKey, VolumeKey);
|
aes_crypt_cbc(&AES_ctx, AES_DECRYPT, 16, IV, SubKey, VolumeKey);
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <wx/filename.h>
|
#include <wx/filename.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cinttypes>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "FileSearch.h"
|
#include "FileSearch.h"
|
||||||
@ -383,7 +384,7 @@ wxString NiceSizeFormat(u64 _size)
|
|||||||
auto const value = (_size + unit_size / 2) / unit_size;
|
auto const value = (_size + unit_size / 2) / unit_size;
|
||||||
auto const frac = (_size % unit_size * 10 + unit_size / 2) / unit_size % 10;
|
auto const frac = (_size % unit_size * 10 + unit_size / 2) / unit_size % 10;
|
||||||
|
|
||||||
return StrToWxStr(StringFromFormat("%llu.%llu %s", value, frac, unit_symbols[unit]));
|
return StrToWxStr(StringFromFormat("%" PRIu64 ".%" PRIu64 " %s", value, frac, unit_symbols[unit]));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameListCtrl::InsertItemInReportView(long _Index)
|
void CGameListCtrl::InsertItemInReportView(long _Index)
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user