mirror of
https://github.com/kanjitalk755/macemu.git
synced 2025-02-08 10:30:45 +00:00
Merge pull request #37 from rakslice/sheepshaver_mingw32_jit
SS mingw32 JIT & GTK prefs GUI fixes
This commit is contained in:
commit
573adb507f
@ -118,7 +118,7 @@ $(APP): $(XPLATSRCS) $(OBJ_DIR) $(OBJS)
|
||||
$(CXX) -o $@ $(LDFLAGS) $(OBJS) $(LIBS) $(SDL_LIBS)
|
||||
|
||||
$(UI_APP): $(XPLATSRCS) $(OBJ_DIR) $(UI_OBJS)
|
||||
$(CXX) -o $@ $(LDFLAGS) $(UI_OBJS) $(LIBS) $(GTK_LIBS) -mwindows -mno-cygwin
|
||||
$(CXX) -o $@ $(LDFLAGS) $(UI_OBJS) $(LIBS) -Wl,-Bdynamic $(GTK_LIBS) -Wl,-Bstatic -mwindows -static-libgcc
|
||||
|
||||
mostlyclean:
|
||||
rm -f $(APP) $(UI_APP) $(OBJ_DIR)/* core* *.core *~ *.bak
|
||||
@ -149,7 +149,7 @@ $(OBJ_DIR)/%.o : %.cpp
|
||||
$(OBJ_DIR)/%.o : %.s
|
||||
$(CC) $(CPPFLAGS) $(DEFS) $(CFLAGS) -c $< -o $@
|
||||
$(OBJ_DIR)/prefs_editor_gtk.o: prefs_editor_gtk.cpp
|
||||
$(CXX) -O2 -mno-cygwin -mms-bitfields $(CPPFLAGS) $(DEFS) $(GTK_CFLAGS) -c $< -o $@
|
||||
$(CXX) -O2 -mms-bitfields $(CPPFLAGS) $(DEFS) $(GTK_CFLAGS) -c $< -o $@
|
||||
|
||||
# Windows resources
|
||||
$(OBJ_DIR)/%.o: %.rc
|
||||
|
@ -79,24 +79,33 @@ extern int my_errno;
|
||||
|
||||
// must hook all other functions that manipulate file names
|
||||
#ifndef NO_POSIX_API_HOOK
|
||||
#define stat my_stat
|
||||
#define fstat my_fstat
|
||||
#define open my_open
|
||||
#define rename my_rename
|
||||
#define access my_access
|
||||
#define mkdir my_mkdir
|
||||
#define remove my_remove
|
||||
#define creat my_creat
|
||||
#define close my_close
|
||||
#define lseek my_lseek
|
||||
#define read my_read
|
||||
#define write my_write
|
||||
#define ftruncate my_chsize
|
||||
#define locking my_locking
|
||||
#define utime my_utime
|
||||
# ifdef stat
|
||||
# undef stat
|
||||
# endif
|
||||
# define stat my_stat
|
||||
# ifdef fstat
|
||||
# undef fstat
|
||||
# endif
|
||||
# define fstat my_fstat
|
||||
# define open my_open
|
||||
# define rename my_rename
|
||||
# define access my_access
|
||||
# define mkdir my_mkdir
|
||||
# define remove my_remove
|
||||
# define creat my_creat
|
||||
# define close my_close
|
||||
# ifdef lseek
|
||||
# undef lseek
|
||||
# endif
|
||||
# define lseek my_lseek
|
||||
# define read my_read
|
||||
# define write my_write
|
||||
# define ftruncate my_chsize
|
||||
# define locking my_locking
|
||||
# define utime my_utime
|
||||
|
||||
#undef errno
|
||||
#define errno my_errno
|
||||
# undef errno
|
||||
# define errno my_errno
|
||||
#endif //!NO_POSIX_API_HOOK
|
||||
|
||||
#ifndef S_ISDIR
|
||||
@ -125,6 +134,6 @@ struct my_utimbuf
|
||||
};
|
||||
|
||||
// Your compiler may have different "struct stat" -> edit "struct my_stat"
|
||||
#define validate_stat_struct ( sizeof(struct my_stat) == sizeof(struct stat) )
|
||||
#define validate_stat_struct ( sizeof(struct my_stat) == sizeof(struct _stat) )
|
||||
|
||||
#define st_crtime st_ctime
|
||||
|
@ -26,6 +26,8 @@
|
||||
#include <sys/stat.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <shellapi.h>
|
||||
|
||||
#include "user_strings.h"
|
||||
#include "version.h"
|
||||
#include "cdrom.h"
|
||||
@ -76,6 +78,27 @@ enum {
|
||||
* Utility functions
|
||||
*/
|
||||
|
||||
gchar * tchar_to_g_utf8(const TCHAR * str) {
|
||||
gchar * out;
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
int len = _tcslen(str) + 1;
|
||||
#ifdef _UNICODE
|
||||
/* First call just to find what the output size will be */
|
||||
int size = WideCharToMultiByte(CP_UTF8, 0, str, len, NULL, 0, NULL, NULL);
|
||||
if (size == 0)
|
||||
return NULL;
|
||||
out = (gchar *) g_malloc(size);
|
||||
if (out == NULL)
|
||||
return NULL;
|
||||
WideCharToMultiByte(CP_UTF8, 0, str, len, out, size, NULL, NULL);
|
||||
#else /* _UNICODE */
|
||||
out = g_locale_to_utf8(str, -1, NULL, NULL, NULL);
|
||||
#endif /* _UNICODE */
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
struct opt_desc {
|
||||
int label_id;
|
||||
GtkSignalFunc func;
|
||||
@ -672,11 +695,11 @@ static GList *add_cdrom_names(void)
|
||||
{
|
||||
GList *glist = NULL;
|
||||
|
||||
char rootdir[4] = "X:\\";
|
||||
for (char letter = 'C'; letter <= 'Z'; letter++) {
|
||||
TCHAR rootdir[4] = TEXT("X:\\");
|
||||
for (TCHAR letter = TEXT('C'); letter <= TEXT('Z'); letter++) {
|
||||
rootdir[0] = letter;
|
||||
if (GetDriveType(rootdir) == DRIVE_CDROM)
|
||||
glist = g_list_append(glist, strdup(rootdir));
|
||||
glist = g_list_append(glist, _tcsdup(rootdir));
|
||||
}
|
||||
|
||||
return glist;
|
||||
@ -887,11 +910,12 @@ static void create_jit_pane(GtkWidget *top)
|
||||
#endif
|
||||
|
||||
set_jit_sensitive();
|
||||
#endif
|
||||
|
||||
#ifdef SHEEPSHAVER
|
||||
make_checkbox(box, STR_JIT_68K_CTRL, "jit68k", GTK_SIGNAL_FUNC(tb_jit_68k));
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1466,24 +1490,25 @@ static int create_ether_menu(GtkWidget *menu)
|
||||
n_items++;
|
||||
|
||||
// Basilisk II Ethernet Adapter
|
||||
PacketOpenAdapter("", 0);
|
||||
PacketOpenAdapter(TEXT(""), 0);
|
||||
{
|
||||
ULONG sz;
|
||||
char names[1024];
|
||||
TCHAR names[1024];
|
||||
sz = sizeof(names);
|
||||
if (PacketGetAdapterNames(NULL, names, &sz) == ERROR_SUCCESS) {
|
||||
char *p = names;
|
||||
TCHAR *p = names;
|
||||
while (*p) {
|
||||
const char DEVICE_HEADER[] = "\\Device\\B2ether_";
|
||||
if (strnicmp(p, DEVICE_HEADER, sizeof(DEVICE_HEADER) - 1) == 0) {
|
||||
const TCHAR DEVICE_HEADER[] = TEXT("\\Device\\B2ether_");
|
||||
if (_tcsnicmp(p, DEVICE_HEADER, sizeof(DEVICE_HEADER) - 1) == 0) {
|
||||
LPADAPTER fd = PacketOpenAdapter(p + sizeof(DEVICE_HEADER) - 1, 0);
|
||||
if (fd) {
|
||||
char guid[256];
|
||||
sprintf(guid, "%s", p + sizeof(DEVICE_HEADER) - 1);
|
||||
const char *name = ether_guid_to_name(guid);
|
||||
if (name && (name = g_locale_to_utf8(name, -1, NULL, NULL, NULL))) {
|
||||
add_menu_item(menu, name, (GtkSignalFunc)mn_ether_b2ether, strdup(guid));
|
||||
if (etherguid && strcmp(guid, etherguid) == 0 &&
|
||||
TCHAR guid[256];
|
||||
_stprintf(guid, TEXT("%s"), p + sizeof(DEVICE_HEADER) - 1);
|
||||
const gchar *name = tchar_to_g_utf8(ether_guid_to_name(guid));
|
||||
if (name) {
|
||||
std::string str_guid = to_string(guid);
|
||||
add_menu_item(menu, name, (GtkSignalFunc)mn_ether_b2ether, strdup(str_guid.c_str()));
|
||||
if (etherguid && to_tstring(guid).compare(to_tstring(etherguid)) == 0 &&
|
||||
ether && strcmp(ether, "b2ether") == 0)
|
||||
active = n_items;
|
||||
n_items++;
|
||||
@ -1491,26 +1516,27 @@ static int create_ether_menu(GtkWidget *menu)
|
||||
PacketCloseAdapter(fd);
|
||||
}
|
||||
}
|
||||
p += strlen(p) + 1;
|
||||
p += _tcslen(p) + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
PacketCloseAdapter(NULL);
|
||||
|
||||
// TAP-Win32
|
||||
const char *tap_devices;
|
||||
const TCHAR *tap_devices;
|
||||
if ((tap_devices = ether_tap_devices()) != NULL) {
|
||||
const char *guid = tap_devices;
|
||||
const TCHAR *guid = tap_devices;
|
||||
while (*guid) {
|
||||
const char *name = ether_guid_to_name(guid);
|
||||
if (name && (name = g_locale_to_utf8(name, -1, NULL, NULL, NULL))) {
|
||||
add_menu_item(menu, name, (GtkSignalFunc)mn_ether_tap, strdup(guid));
|
||||
if (etherguid && strcmp(guid, etherguid) == 0 &&
|
||||
const gchar *name = tchar_to_g_utf8(ether_guid_to_name(guid));
|
||||
if (name) {
|
||||
std::string str_guid = to_string(guid);
|
||||
add_menu_item(menu, name, (GtkSignalFunc)mn_ether_tap, strdup(str_guid.c_str()));
|
||||
if (etherguid && to_tstring(guid).compare(to_tstring(etherguid)) == 0 &&
|
||||
ether && strcmp(ether, "tap") == 0)
|
||||
active = n_items;
|
||||
n_items++;
|
||||
}
|
||||
guid += strlen(guid) + 1;
|
||||
guid += _tcslen(guid) + 1;
|
||||
}
|
||||
free((char *)tap_devices);
|
||||
}
|
||||
@ -1734,21 +1760,66 @@ void SysAddSerialPrefs(void)
|
||||
* Display alerts
|
||||
*/
|
||||
|
||||
static HWND GetMainWindowHandle() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void display_alert(int title_id, const char *text, int flags)
|
||||
{
|
||||
MessageBox(NULL, text, GetString(title_id), MB_OK | flags);
|
||||
HWND hMainWnd = GetMainWindowHandle();
|
||||
MessageBoxA(hMainWnd, text, GetString(title_id), MB_OK | flags);
|
||||
}
|
||||
#ifdef _UNICODE
|
||||
static void display_alert(int title_id, const wchar_t *text, int flags)
|
||||
{
|
||||
HWND hMainWnd = GetMainWindowHandle();
|
||||
MessageBoxW(hMainWnd, text, GetStringW(title_id).get(), MB_OK | flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Display error alert
|
||||
*/
|
||||
|
||||
void ErrorAlert(const char *text)
|
||||
{
|
||||
if (PrefsFindBool("nogui"))
|
||||
return;
|
||||
|
||||
display_alert(STR_ERROR_ALERT_TITLE, text, MB_ICONSTOP);
|
||||
}
|
||||
#ifdef _UNICODE
|
||||
void ErrorAlert(const wchar_t *text)
|
||||
{
|
||||
if (PrefsFindBool("nogui"))
|
||||
return;
|
||||
|
||||
display_alert(STR_ERROR_ALERT_TITLE, text, MB_ICONSTOP);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Display warning alert
|
||||
*/
|
||||
|
||||
void WarningAlert(const char *text)
|
||||
{
|
||||
if (PrefsFindBool("nogui"))
|
||||
return;
|
||||
|
||||
display_alert(STR_WARNING_ALERT_TITLE, text, MB_ICONSTOP);
|
||||
}
|
||||
#ifdef _UNICODE
|
||||
void WarningAlert(const wchar_t *text)
|
||||
{
|
||||
if (PrefsFindBool("nogui"))
|
||||
return;
|
||||
|
||||
display_alert(STR_WARNING_ALERT_TITLE, text, MB_ICONSTOP);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Start standalone GUI
|
||||
@ -1774,23 +1845,23 @@ int main(int argc, char *argv[])
|
||||
|
||||
// Transfer control to the executable
|
||||
if (start) {
|
||||
char path[_MAX_PATH];
|
||||
TCHAR path[_MAX_PATH];
|
||||
bool ok = GetModuleFileName(NULL, path, sizeof(path)) != 0;
|
||||
if (ok) {
|
||||
char b2_path[_MAX_PATH];
|
||||
char *p = strrchr(path, '\\');
|
||||
*++p = '\0';
|
||||
TCHAR b2_path[_MAX_PATH];
|
||||
TCHAR *p = _tcsrchr(path, TEXT('\\'));
|
||||
*++p = TEXT('\0');
|
||||
SetCurrentDirectory(path);
|
||||
strcpy(b2_path, path);
|
||||
strcat(b2_path, PROGRAM_NAME);
|
||||
strcat(b2_path, ".exe");
|
||||
HINSTANCE h = ShellExecute(GetDesktopWindow(), "open",
|
||||
b2_path, "", path, SW_SHOWNORMAL);
|
||||
_tcscpy(b2_path, path);
|
||||
_tcscat(b2_path, TEXT(PROGRAM_NAME));
|
||||
_tcscat(b2_path, TEXT(".exe"));
|
||||
HINSTANCE h = ShellExecute(GetDesktopWindow(), TEXT("open"),
|
||||
b2_path, TEXT(""), path, SW_SHOWNORMAL);
|
||||
if ((int)h <= 32)
|
||||
ok = false;
|
||||
}
|
||||
if (!ok) {
|
||||
ErrorAlert("Coult not start " PROGRAM_NAME " executable");
|
||||
ErrorAlert(TEXT("Could not start ") TEXT(PROGRAM_NAME) TEXT(" executable"));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#define _UNICODE
|
||||
#define UNICODE
|
||||
#endif
|
||||
|
||||
#if !defined _MSC_VER && !defined __STDC__
|
||||
|
@ -427,7 +427,7 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds)
|
||||
/* Connected */
|
||||
so->so_state &= ~SS_ISFCONNECTING;
|
||||
|
||||
ret = send(so->s, &ret, 0, 0);
|
||||
ret = send(so->s, NULL, 0, 0);
|
||||
if (ret < 0) {
|
||||
/* XXXXX Must fix, zero bytes is a NOP */
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK ||
|
||||
|
@ -32,21 +32,6 @@ typedef unsigned long ioctlsockopt_t;
|
||||
# include <winsock2.h>
|
||||
# include <WS2tcpip.h>
|
||||
|
||||
#ifdef __MINGW32__
|
||||
char * WSAAPI inet_ntop(
|
||||
INT Family,
|
||||
PVOID pAddr,
|
||||
PTSTR pStringBuf,
|
||||
size_t StringBufSize
|
||||
);
|
||||
|
||||
INT WSAAPI inet_pton(
|
||||
INT Family,
|
||||
const char * pszAddrString,
|
||||
PVOID pAddrBuf
|
||||
);
|
||||
#endif
|
||||
|
||||
# include <sys/timeb.h>
|
||||
# include <iphlpapi.h>
|
||||
|
||||
|
@ -99,7 +99,7 @@ links:
|
||||
case $$i in *codegen_x86.h) o=kpx_cpu/src/cpu/jit/x86/codegen_x86.h;; esac; \
|
||||
SUB=`echo $$o | sed 's;[^/]*/;../;g' | sed 's;[^/]*$$;;'` ;\
|
||||
cur_link=src/$$o ;\
|
||||
if [ -d "$$cur_link" ]; then rm -rf "$$cur_link"; fi ;\
|
||||
if [ -e "$$cur_link" ]; then rm -rf "$$cur_link"; fi ;\
|
||||
ln -sf "$$PREFIX$$SUB$(B2_TOPDIR)/src/$$i" $$cur_link; \
|
||||
fi; \
|
||||
done;
|
||||
|
@ -35,7 +35,7 @@ CC = @CC@
|
||||
CXX = @CXX@
|
||||
CFLAGS = @CFLAGS@ $(SDL_CFLAGS)
|
||||
CXXFLAGS = @CXXFLAGS@ $(SDL_CFLAGS)
|
||||
CPPFLAGS = @CPPFLAGS@ -I../include -I. -I../slirp -I../Unix/dyngen_precompiled
|
||||
CPPFLAGS = @CPPFLAGS@ -I../include -I. -I../slirp
|
||||
DEFS = @DEFS@
|
||||
LDFLAGS = @LDFLAGS@ -Wl,-Bstatic
|
||||
#TODO remove pthread part of that if irrelevant
|
||||
@ -44,6 +44,7 @@ CPUSRCS = @CPUSRCS@
|
||||
PERL = @PERL@
|
||||
|
||||
USE_DYNGEN = @USE_DYNGEN@
|
||||
USE_PREGENERATED_DYNGEN = @USE_PREGENERATED_DYNGEN@
|
||||
DYNGENSRCS = @DYNGENSRCS@
|
||||
DYNGEN_CC = $(CXX)
|
||||
DYNGEN_OP_FLAGS = @DYNGEN_OP_FLAGS@
|
||||
@ -76,6 +77,7 @@ SRCS = ../main.cpp main_windows.cpp ../prefs.cpp ../prefs_items.cpp prefs_window
|
||||
|
||||
UI_SRCS = ../prefs.cpp prefs_windows.cpp prefs_editor_gtk.cpp xpram_windows.cpp \
|
||||
../prefs_items.cpp ../user_strings.cpp user_strings_windows.cpp util_windows.cpp \
|
||||
../dummy/prefs_dummy.cpp \
|
||||
b2ether/packet32.cpp SheepShaverGUI.rc
|
||||
|
||||
UI_APP = SheepShaverGUI.exe
|
||||
@ -128,14 +130,15 @@ $(APP): $(XPLATSRCS) $(OBJ_DIR) $(OBJS)
|
||||
$(CXX) -o $(APP) $(LDFLAGS) $(OBJS) $(LIBS) $(SDL_LIBS)
|
||||
|
||||
$(UI_APP): $(XPLATSRCS) $(OBJ_DIR) $(UI_OBJS)
|
||||
$(CXX) -o $@ $(LDFLAGS) $(UI_OBJS) $(LIBS) $(GTK_LIBS) -mwindows -mno-cygwin
|
||||
$(CXX) -o $@ $(LDFLAGS) $(UI_OBJS) $(LIBS) -Wl,-Bdynamic $(GTK_LIBS) -Wl,-Bstatic -mwindows -static-libgcc
|
||||
|
||||
mostlyclean:
|
||||
rm -f $(APP) $(UI_APP) $(OBJ_DIR)/* core* *.core *~ *.bak
|
||||
|
||||
clean: mostlyclean
|
||||
clean: mostlyclean dyngenclean
|
||||
rm -f $(XPLATSRCS)
|
||||
rm -f dyngen basic-dyngen-ops.hpp ppc-dyngen-ops.hpp ppc-execute-impl.cpp
|
||||
dyngenclean:
|
||||
rm -f $(DYNGEN) basic-dyngen-ops.hpp ppc-dyngen-ops.hpp ppc-execute-impl.cpp
|
||||
|
||||
distclean: clean
|
||||
rm -rf $(OBJ_DIR)
|
||||
@ -163,7 +166,7 @@ $(OBJ_DIR)/%.o : %.S
|
||||
$(AS) $(ASFLAGS) -o $@ $*.out.s
|
||||
rm $*.out.s
|
||||
$(OBJ_DIR)/prefs_editor_gtk.o: prefs_editor_gtk.cpp
|
||||
$(CXX) -O2 -mno-cygwin -mms-bitfields $(CPPFLAGS) $(DEFS) $(GTK_CFLAGS) -c $< -o $@
|
||||
$(CXX) -O2 -mms-bitfields $(CPPFLAGS) $(DEFS) $(GTK_CFLAGS) -c $< -o $@
|
||||
|
||||
# Windows resources
|
||||
$(OBJ_DIR)/%.o: %.rc
|
||||
@ -176,36 +179,35 @@ DYNGEN = dyngen.exe
|
||||
|
||||
ifeq ($(USE_DYNGEN),yes)
|
||||
DYNGENDEPS = basic-dyngen-ops.hpp ppc-dyngen-ops.hpp
|
||||
dyngendeps: $(DYNGENDEPS)
|
||||
|
||||
###
|
||||
|
||||
basic-dyngen-ops.hpp: ../Unix/dyngen_precompiled/basic-dyngen-ops.hpp basic-dyngen-ops-x86_32.hpp basic-dyngen-ops-x86_64.hpp
|
||||
$(OBJ_DIR)/basic-dyngen.o: basic-dyngen-ops.hpp
|
||||
$(OBJ_DIR)/ppc-dyngen.o: ppc-dyngen-ops.hpp
|
||||
|
||||
ifeq ($(USE_PREGENERATED_DYNGEN),yes)
|
||||
|
||||
basic-dyngen-ops.hpp: cygwin_precompiled_dyngen/basic-dyngen-ops.hpp
|
||||
cp -f $< $@
|
||||
basic-dyngen-ops-x86_32.hpp: ../Unix/dyngen_precompiled/basic-dyngen-ops-x86_32.hpp
|
||||
cp -f $< $@
|
||||
basic-dyngen-ops-x86_64.hpp: ../Unix/dyngen_precompiled/basic-dyngen-ops-x86_64.hpp
|
||||
cp -f $< $@
|
||||
ppc-dyngen-ops.hpp: ../Unix/dyngen_precompiled/ppc-dyngen-ops.hpp ppc-dyngen-ops-x86_32.hpp ppc-dyngen-ops-x86_64.hpp
|
||||
cp -f $< $@
|
||||
ppc-dyngen-ops-x86_32.hpp: ../Unix/dyngen_precompiled/ppc-dyngen-ops-x86_32.hpp
|
||||
cp -f $< $@
|
||||
ppc-dyngen-ops-x86_64.hpp: ../Unix/dyngen_precompiled/ppc-dyngen-ops-x86_64.hpp
|
||||
ppc-dyngen-ops.hpp: cygwin_precompiled_dyngen/ppc-dyngen-ops.hpp
|
||||
cp -f $< $@
|
||||
|
||||
else
|
||||
# Only GCC is supported for generating synthetic opcodes
|
||||
#$(DYNGEN): $(DYNGENOBJS)
|
||||
# $(HOST_CXX) -o $@ $(LDFLAGS) $(DYNGENOBJS)
|
||||
$(DYNGEN): $(DYNGENOBJS)
|
||||
$(HOST_CXX) -o $@ $(LDFLAGS) $(DYNGENOBJS)
|
||||
|
||||
#$(OBJ_DIR)/basic-dyngen.o: basic-dyngen-ops.hpp
|
||||
#$(OBJ_DIR)/basic-dyngen-ops.o: $(kpxsrcdir)/cpu/jit/basic-dyngen-ops.cpp
|
||||
# $(DYNGEN_CC) $(CPPFLAGS) $(DEFS) $(CXXFLAGS) $(DYNGEN_OP_FLAGS) -c $< -o $@
|
||||
#basic-dyngen-ops.hpp: $(OBJ_DIR)/basic-dyngen-ops.o $(DYNGEN)
|
||||
# ./$(DYNGEN) -o $@ $<
|
||||
$(OBJ_DIR)/basic-dyngen-ops.o: $(kpxsrcdir)/cpu/jit/basic-dyngen-ops.cpp
|
||||
$(DYNGEN_CC) $(CPPFLAGS) $(DEFS) $(CXXFLAGS) $(DYNGEN_OP_FLAGS) -c $< -o $@
|
||||
basic-dyngen-ops.hpp: $(OBJ_DIR)/basic-dyngen-ops.o $(DYNGEN)
|
||||
./$(DYNGEN) -o $@ $<
|
||||
|
||||
#$(OBJ_DIR)/ppc-dyngen.o: ppc-dyngen-ops.hpp
|
||||
#$(OBJ_DIR)/ppc-dyngen-ops.o: $(kpxsrcdir)/cpu/ppc/ppc-dyngen-ops.cpp basic-dyngen-ops.hpp
|
||||
# $(DYNGEN_CC) $(CPPFLAGS) $(DEFS) $(CXXFLAGS) $(DYNGEN_OP_FLAGS) -c $< -o $@
|
||||
#ppc-dyngen-ops.hpp: $(OBJ_DIR)/ppc-dyngen-ops.o $(DYNGEN)
|
||||
# ./$(DYNGEN) -o $@ $<
|
||||
$(OBJ_DIR)/ppc-dyngen-ops.o: $(kpxsrcdir)/cpu/ppc/ppc-dyngen-ops.cpp basic-dyngen-ops.hpp
|
||||
$(DYNGEN_CC) $(CPPFLAGS) $(DEFS) $(CXXFLAGS) $(DYNGEN_OP_FLAGS) -c $< -o $@
|
||||
ppc-dyngen-ops.hpp: $(OBJ_DIR)/ppc-dyngen-ops.o $(DYNGEN)
|
||||
./$(DYNGEN) -o $@ $<
|
||||
endif
|
||||
|
||||
$(OBJ_DIR)/sheepshaver_glue.o $(OBJ_DIR)/ppc-cpu.o $(OBJ_DIR)/ppc-decode.o $(OBJ_DIR)/ppc-translate.o $(OBJ_DIR)/ppc-jit.o: basic-dyngen-ops.hpp ppc-dyngen-ops.hpp
|
||||
endif
|
||||
|
@ -192,6 +192,13 @@ if [[ "x$HAVE_GCC30" = "xyes" ]]; then
|
||||
CFLAGS="$SAVED_CFLAGS"
|
||||
fi
|
||||
|
||||
case $host_os in
|
||||
cygwin)
|
||||
CFLAGS="$CFLAGS -mwin32"
|
||||
CXXFLAGS="$CXXFLAGS -mwin32"
|
||||
;;
|
||||
esac
|
||||
|
||||
dnl CPU emulator sources
|
||||
CPUSRCS="\
|
||||
../kpx_cpu/src/mathlib/ieeefp.cpp \
|
||||
@ -205,6 +212,7 @@ CPPFLAGS="$CPPFLAGS -I../kpx_cpu/include -I../kpx_cpu/src"
|
||||
|
||||
dnl Enable JIT compiler, if possible
|
||||
USE_DYNGEN="no"
|
||||
USE_PREGENERATED_DYNGEN="no"
|
||||
if [[ "x$WANT_JIT" = "xyes" ]]; then
|
||||
case $host_cpu in
|
||||
i?86)
|
||||
@ -216,6 +224,16 @@ if [[ "x$WANT_JIT" = "xyes" ]]; then
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
case $host_os in
|
||||
cygwin)
|
||||
USE_PREGENERATED_DYNGEN="no"
|
||||
;;
|
||||
*)
|
||||
USE_PREGENERATED_DYNGEN="yes"
|
||||
;;
|
||||
esac
|
||||
|
||||
USE_DYNGEN="yes"
|
||||
DYNGEN_OP_FLAGS="$DYNGEN_OP_FLAGS -finline-limit=10000 -g0"
|
||||
if [[ "x$HAVE_GCC30" = "xyes" ]]; then
|
||||
@ -256,6 +274,7 @@ fi
|
||||
dnl Generate Makefile.
|
||||
AC_SUBST(PERL)
|
||||
AC_SUBST(USE_DYNGEN)
|
||||
AC_SUBST(USE_PREGENERATED_DYNGEN)
|
||||
AC_SUBST(DYNGENSRCS)
|
||||
AC_SUBST(DYNGEN_OP_FLAGS)
|
||||
AC_SUBST(CPUSRCS)
|
||||
|
File diff suppressed because it is too large
Load Diff
11173
SheepShaver/src/Windows/cygwin_precompiled_dyngen/ppc-dyngen-ops.hpp
Normal file
11173
SheepShaver/src/Windows/cygwin_precompiled_dyngen/ppc-dyngen-ops.hpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -41,7 +41,9 @@
|
||||
#undef _TEXT
|
||||
#include <time.h>
|
||||
#ifdef __WIN32__
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <WinSock2.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
|
||||
@ -147,6 +149,19 @@ static inline uint32 do_opt_bswap_32(uint32 x)
|
||||
__asm__ __volatile__ ("bswap %0" : "=r" (v) : "0" (x));
|
||||
return v;
|
||||
}
|
||||
|
||||
#if defined(__CYGWIN__) || defined(__MINGW32__)
|
||||
|
||||
#define opt_bswap_16 do_opt_bswap_16
|
||||
static inline uint16 do_opt_bswap_16(uint16 x)
|
||||
{
|
||||
uint16 v;
|
||||
__asm__ __volatile__ ("rolw $8, %0" : "=r" (v) : "0" (x));
|
||||
return v;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -525,7 +525,7 @@ union DL_primitives {
|
||||
struct EnetPacketHeader {
|
||||
uint8 fDestAddr[6];
|
||||
uint8 fSourceAddr[6];
|
||||
nw_uint16 fProto;
|
||||
uint16 fProto;
|
||||
} PACKED__;
|
||||
|
||||
struct T8022Header {
|
||||
@ -548,7 +548,7 @@ struct T8022FullPacketHeader {
|
||||
|
||||
struct T8022AddressStruct {
|
||||
uint8 fHWAddr[6];
|
||||
nw_uint16 fSAP;
|
||||
uint16 fSAP;
|
||||
uint8 fSNAP[k8022SNAPLength];
|
||||
} PACKED__;
|
||||
|
||||
|
@ -23,6 +23,10 @@
|
||||
|
||||
#include <functional>
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#include "vm_alloc.h"
|
||||
#endif
|
||||
|
||||
#if defined __GNUC__
|
||||
#define HAVE_FAST_NV_MEM_FUN 1
|
||||
#define MEM_FUN_WORDS 2
|
||||
@ -91,11 +95,123 @@ template< class R, class T, class A >
|
||||
class nv_mem_fun1_t : public std::binary_function<T, A, R> {
|
||||
typedef R (T::*pmf_t)(A);
|
||||
typedef R (* PF_CONVENTION pf_t)(T *, A x);
|
||||
#ifdef __MINGW32__
|
||||
typedef R (* default_call_conv_pf_t)(T *, A x);
|
||||
#endif
|
||||
pf_t pf;
|
||||
public:
|
||||
nv_mem_fun1_t(pmf_t pmf) : pf(nv_mem_fun_of<pmf_t, pf_t>(pmf)) {}
|
||||
nv_mem_fun1_t(pmf_t pmf) : pf(nv_mem_fun_of<pmf_t, pf_t>(pmf)) {
|
||||
#ifdef __MINGW32__
|
||||
init_func();
|
||||
#endif
|
||||
}
|
||||
R operator()(T *p, A x) const { return (*pf)(p, x); }
|
||||
|
||||
#ifdef __MINGW32__
|
||||
|
||||
#define NVMEMFUN_THUNK_DEBUG 0
|
||||
|
||||
private:
|
||||
#define DO_CONVENTION_CALL_PF_PLACEHOLDER 0x12345678
|
||||
|
||||
#define DO_CONVENTION_CALL_STATICS
|
||||
static bool do_convention_call_init_done;
|
||||
static int do_convention_call_code_len;
|
||||
static int do_convention_call_pf_offset;
|
||||
unsigned char * do_convention_call_instance_copy;
|
||||
|
||||
static void init_do_convention_call() {
|
||||
if (do_convention_call_init_done) return;
|
||||
|
||||
const int max_code_bytes = 100;
|
||||
const unsigned char last_code_byte_value = 0xc3;
|
||||
|
||||
// figure out the size of the function
|
||||
unsigned char * func_pos = (unsigned char *) &do_convention_call;
|
||||
int i;
|
||||
for (i = 0; i < max_code_bytes; i++) {
|
||||
if (func_pos[i] == last_code_byte_value) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
do_convention_call_code_len = i + 1;
|
||||
|
||||
#if NVMEMFUN_THUNK_DEBUG
|
||||
printf("do_convention_call func size %d ", do_convention_call_code_len);
|
||||
#endif
|
||||
|
||||
// find the position of the pf placeholder in the function
|
||||
int placeholder_matches = 0;
|
||||
for (i = 0; i < do_convention_call_code_len - 3; i++) {
|
||||
pf_t * cur_ptr = (pf_t*)(func_pos + i);
|
||||
if (*cur_ptr == (pf_t) DO_CONVENTION_CALL_PF_PLACEHOLDER) {
|
||||
do_convention_call_pf_offset = i;
|
||||
#if NVMEMFUN_THUNK_DEBUG
|
||||
printf("ptr pos offset %x", (uint32)cur_ptr - (uint32)func_pos);
|
||||
#endif
|
||||
++placeholder_matches;
|
||||
}
|
||||
}
|
||||
|
||||
#if NVMEMFUN_THUNK_DEBUG
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
assert(placeholder_matches == 1);
|
||||
|
||||
do_convention_call_init_done = true;
|
||||
}
|
||||
|
||||
void init_func() {
|
||||
if (!do_convention_call_init_done) {
|
||||
init_do_convention_call();
|
||||
}
|
||||
|
||||
// copy do_convention_call and patch in the address of pf
|
||||
|
||||
do_convention_call_instance_copy = (unsigned char *) vm_acquire(do_convention_call_code_len);
|
||||
// Thunk buffer needs to be around while default_call_conv_ptr() is still in use,
|
||||
// longer than nv_mem_fun1_t lifetime
|
||||
//FIXME track the lifetime of this
|
||||
if (do_convention_call_instance_copy == NULL) return;
|
||||
unsigned char * func_pos = (unsigned char *) &do_convention_call;
|
||||
memcpy((void *)do_convention_call_instance_copy, func_pos, do_convention_call_code_len);
|
||||
|
||||
// replace byte sequence in buf copy
|
||||
*(pf_t*)(do_convention_call_instance_copy + do_convention_call_pf_offset) = pf;
|
||||
|
||||
#if NVMEMFUN_THUNK_DEBUG
|
||||
printf("patching do_convention_call to %x; func size %d ", do_convention_call_instance_copy, do_convention_call_code_len);
|
||||
for (int i = 0 ; i < do_convention_call_code_len; i ++) {
|
||||
printf("%02x ", do_convention_call_instance_copy[i]);
|
||||
}
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
vm_protect(do_convention_call_instance_copy, do_convention_call_code_len, VM_PAGE_READ | VM_PAGE_EXECUTE);
|
||||
}
|
||||
|
||||
// Cheesy thunk solution to adapt the calling convention:
|
||||
// do_convention_call accepts the default calling convention and calls pf with PF_CONVENTION
|
||||
// Each instance makes its own copy of do_convention_call in a buffer and patches the address of pf into it
|
||||
static R do_convention_call(T * obj, A x) {
|
||||
pf_t fn = (pf_t) DO_CONVENTION_CALL_PF_PLACEHOLDER;
|
||||
return (*fn)(obj, x);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
default_call_conv_pf_t default_call_conv_ptr() const { return (default_call_conv_pf_t) do_convention_call_instance_copy; }
|
||||
|
||||
#else
|
||||
|
||||
pf_t ptr() const { return pf; }
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
};
|
||||
|
||||
template< class R, class T, class A >
|
||||
|
@ -151,9 +151,11 @@ public:
|
||||
|
||||
// Execute NATIVE_OP routine
|
||||
void execute_native_op(uint32 native_op);
|
||||
static void call_execute_native_op(powerpc_cpu * cpu, uint32 native_op);
|
||||
|
||||
// Execute EMUL_OP routine
|
||||
void execute_emul_op(uint32 emul_op);
|
||||
static void call_execute_emul_op(powerpc_cpu * cpu, uint32 emul_op);
|
||||
|
||||
// Execute 68k routine
|
||||
void execute_68k(uint32 entry, M68kRegisters *r);
|
||||
@ -170,6 +172,7 @@ public:
|
||||
#endif
|
||||
// Resource manager thunk
|
||||
void get_resource(uint32 old_get_resource);
|
||||
static void call_get_resource(powerpc_cpu * cpu, uint32 old_get_resource);
|
||||
|
||||
// Handle MacOS interrupt
|
||||
void interrupt(uint32 entry);
|
||||
@ -218,6 +221,10 @@ typedef bit_field< 19, 19 > FN_field;
|
||||
typedef bit_field< 20, 25 > NATIVE_OP_field;
|
||||
typedef bit_field< 26, 31 > EMUL_OP_field;
|
||||
|
||||
void sheepshaver_cpu::call_execute_emul_op(powerpc_cpu * cpu, uint32 emul_op) {
|
||||
static_cast<sheepshaver_cpu *>(cpu)->execute_emul_op(emul_op);
|
||||
}
|
||||
|
||||
// Execute EMUL_OP routine
|
||||
void sheepshaver_cpu::execute_emul_op(uint32 emul_op)
|
||||
{
|
||||
@ -332,7 +339,7 @@ int sheepshaver_cpu::compile1(codegen_context_t & cg_context)
|
||||
};
|
||||
uint32 old_get_resource = ReadMacInt32(get_resource_ptr[selector - NATIVE_GET_RESOURCE]);
|
||||
typedef void (*func_t)(dyngen_cpu_base, uint32);
|
||||
func_t func = (func_t)nv_mem_fun(&sheepshaver_cpu::get_resource).ptr();
|
||||
func_t func = &sheepshaver_cpu::call_get_resource;
|
||||
dg.gen_invoke_CPU_im(func, old_get_resource);
|
||||
status = COMPILE_CODE_OK;
|
||||
break;
|
||||
@ -421,7 +428,7 @@ int sheepshaver_cpu::compile1(codegen_context_t & cg_context)
|
||||
// Invoke NativeOp handler
|
||||
if (!FN_field::test(opcode)) {
|
||||
typedef void (*func_t)(dyngen_cpu_base, uint32);
|
||||
func_t func = (func_t)nv_mem_fun(&sheepshaver_cpu::execute_native_op).ptr();
|
||||
func_t func = &sheepshaver_cpu::call_execute_native_op;
|
||||
dg.gen_invoke_CPU_im(func, selector);
|
||||
cg_context.done_compile = false;
|
||||
status = COMPILE_CODE_OK;
|
||||
@ -445,7 +452,7 @@ int sheepshaver_cpu::compile1(codegen_context_t & cg_context)
|
||||
#else
|
||||
// Invoke EmulOp handler
|
||||
typedef void (*func_t)(dyngen_cpu_base, uint32);
|
||||
func_t func = (func_t)nv_mem_fun(&sheepshaver_cpu::execute_emul_op).ptr();
|
||||
func_t func = &sheepshaver_cpu::call_execute_emul_op;
|
||||
dg.gen_invoke_CPU_im(func, emul_op);
|
||||
cg_context.done_compile = false;
|
||||
status = COMPILE_CODE_OK;
|
||||
@ -685,6 +692,10 @@ inline void sheepshaver_cpu::execute_ppc(uint32 entry)
|
||||
lr() = saved_lr;
|
||||
}
|
||||
|
||||
void sheepshaver_cpu::call_get_resource(powerpc_cpu * cpu, uint32 old_get_resource) {
|
||||
static_cast<sheepshaver_cpu *>(cpu)->get_resource(old_get_resource);
|
||||
}
|
||||
|
||||
// Resource Manager thunk
|
||||
inline void sheepshaver_cpu::get_resource(uint32 old_get_resource)
|
||||
{
|
||||
@ -897,14 +908,14 @@ void init_emul_op_trampolines(basic_dyngen & dg)
|
||||
|
||||
// EmulOp
|
||||
emul_op_trampoline = dg.gen_start();
|
||||
func = (func_t)nv_mem_fun(&sheepshaver_cpu::execute_emul_op).ptr();
|
||||
func = &sheepshaver_cpu::call_execute_emul_op;
|
||||
dg.gen_invoke_CPU_T0(func);
|
||||
dg.gen_exec_return();
|
||||
dg.gen_end();
|
||||
|
||||
// NativeOp
|
||||
native_op_trampoline = dg.gen_start();
|
||||
func = (func_t)nv_mem_fun(&sheepshaver_cpu::execute_native_op).ptr();
|
||||
func = &sheepshaver_cpu::call_execute_native_op;
|
||||
dg.gen_invoke_CPU_T0(func);
|
||||
dg.gen_exec_return();
|
||||
dg.gen_end();
|
||||
@ -1030,6 +1041,10 @@ void HandleInterrupt(powerpc_registers *r)
|
||||
}
|
||||
}
|
||||
|
||||
void sheepshaver_cpu::call_execute_native_op(powerpc_cpu * cpu, uint32 selector) {
|
||||
static_cast<sheepshaver_cpu *>(cpu)->execute_native_op(selector);
|
||||
}
|
||||
|
||||
// Execute NATIVE_OP routine
|
||||
void sheepshaver_cpu::execute_native_op(uint32 selector)
|
||||
{
|
||||
|
@ -64,6 +64,12 @@ int register_info_compare(const void *e1, const void *e2)
|
||||
|
||||
static int ppc_refcount = 0;
|
||||
|
||||
#ifdef DO_CONVENTION_CALL_STATICS
|
||||
template<> bool nv_mem_fun1_t<void, powerpc_cpu, uint32>::do_convention_call_init_done = false;
|
||||
template<> int nv_mem_fun1_t<void, powerpc_cpu, uint32>::do_convention_call_code_len = 0;
|
||||
template<> int nv_mem_fun1_t<void, powerpc_cpu, uint32>::do_convention_call_pf_offset = 0;
|
||||
#endif
|
||||
|
||||
void powerpc_cpu::set_register(int id, any_register const & value)
|
||||
{
|
||||
if (id >= powerpc_registers::GPR(0) && id <= powerpc_registers::GPR(31)) {
|
||||
@ -542,7 +548,12 @@ bool powerpc_cpu::check_spcflags()
|
||||
}
|
||||
|
||||
#if DYNGEN_DIRECT_BLOCK_CHAINING
|
||||
void *powerpc_cpu::compile_chain_block(block_info *sbi)
|
||||
void * powerpc_cpu::call_compile_chain_block(powerpc_cpu * the_cpu, block_info *sbi)
|
||||
{
|
||||
return the_cpu->compile_chain_block(sbi);
|
||||
}
|
||||
|
||||
void * PF_CONVENTION powerpc_cpu::compile_chain_block(block_info *sbi)
|
||||
{
|
||||
// Block index is stuffed into the source basic block pointer,
|
||||
// which is aligned at least on 4-byte boundaries
|
||||
@ -719,7 +730,11 @@ void powerpc_cpu::execute(uint32 entry)
|
||||
if (is_logging())
|
||||
record_step(opcode);
|
||||
#endif
|
||||
#ifdef __MINGW32__
|
||||
assert(ii->execute.default_call_conv_ptr() != 0);
|
||||
#else
|
||||
assert(ii->execute.ptr() != 0);
|
||||
#endif
|
||||
ii->execute(this, opcode);
|
||||
#if PPC_EXECUTE_DUMP_STATE
|
||||
if (dump_state)
|
||||
|
@ -371,8 +371,10 @@ private:
|
||||
friend class powerpc_jit;
|
||||
powerpc_jit codegen;
|
||||
block_info *compile_block(uint32 entry);
|
||||
static void call_do_record_step(powerpc_cpu * cpu, uint32 pc, uint32 opcode);
|
||||
#if DYNGEN_DIRECT_BLOCK_CHAINING
|
||||
void *compile_chain_block(block_info *sbi);
|
||||
static void * call_compile_chain_block(powerpc_cpu * the_cpu, block_info *sbi);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -389,6 +391,7 @@ private:
|
||||
// Instruction handlers
|
||||
void execute_nop(uint32 opcode);
|
||||
void execute_illegal(uint32 opcode);
|
||||
static void call_execute_illegal(powerpc_cpu * cpu, uint32 opcode);
|
||||
template< class RA, class RB, class RC, class CA, class OE, class Rc >
|
||||
void execute_addition(uint32 opcode);
|
||||
template< class OP, class RD, class RA, class RB, class RC, class OE, class Rc >
|
||||
@ -453,6 +456,7 @@ private:
|
||||
void execute_icbi(uint32 opcode);
|
||||
void execute_isync(uint32 opcode);
|
||||
void execute_invalidate_cache_range();
|
||||
static void call_execute_invalidate_cache_range(powerpc_cpu * cpu);
|
||||
template< class RA, class RB >
|
||||
void execute_dcbz(uint32 opcode);
|
||||
template< bool SL >
|
||||
|
@ -481,7 +481,6 @@ DEFINE_OP(fmov_FD_F2, FD_dw = F2_dw);
|
||||
DEFINE_OP(fabs_FD_F0, FD = do_fabs(F0));
|
||||
DEFINE_OP(fneg_FD_F0, FD = do_fneg(F0));
|
||||
DEFINE_OP(fnabs_FD_F0, FD = do_fnabs(F0));
|
||||
DEFINE_OP(frsqrte_FD_F0, FD = do_frsqrte(F0));
|
||||
|
||||
DEFINE_OP(fadd_FD_F0_F1, FD = do_fadd(F0, F1));
|
||||
DEFINE_OP(fsub_FD_F0_F1, FD = do_fsub(F0, F1));
|
||||
|
@ -90,6 +90,7 @@ static inline int ppc_to_native_rounding_mode(int round)
|
||||
case 2: return FE_UPWARD;
|
||||
case 3: return FE_DOWNWARD;
|
||||
}
|
||||
return FE_TONEAREST;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -36,6 +36,11 @@ powerpc_jit::powerpc_jit(dyngen_cpu_base cpu)
|
||||
{
|
||||
}
|
||||
|
||||
// An operand that refers to an address relative to the emulated machine
|
||||
static x86_memory_operand vm_memory_operand(int32 d, int b, int i = X86_NOREG, int s = 1) {
|
||||
return x86_memory_operand(d + VMBaseDiff, b, i, s);
|
||||
}
|
||||
|
||||
bool powerpc_jit::initialize(void)
|
||||
{
|
||||
if (!powerpc_dyngen::initialize())
|
||||
@ -239,21 +244,25 @@ bool powerpc_jit::initialize(void)
|
||||
// Dispatch mid-level code generators
|
||||
bool powerpc_jit::gen_vector_1(int mnemo, int vD)
|
||||
{
|
||||
if (jit_info[mnemo]->handler == (gen_handler_t)&powerpc_jit::gen_not_available) return false;
|
||||
return (this->*((bool (powerpc_jit::*)(int, int))jit_info[mnemo]->handler))(mnemo, vD);
|
||||
}
|
||||
|
||||
bool powerpc_jit::gen_vector_2(int mnemo, int vD, int vA, int vB)
|
||||
{
|
||||
if (jit_info[mnemo]->handler == (gen_handler_t)&powerpc_jit::gen_not_available) return false;
|
||||
return (this->*((bool (powerpc_jit::*)(int, int, int, int))jit_info[mnemo]->handler))(mnemo, vD, vA, vB);
|
||||
}
|
||||
|
||||
bool powerpc_jit::gen_vector_3(int mnemo, int vD, int vA, int vB, int vC)
|
||||
{
|
||||
if (jit_info[mnemo]->handler == (gen_handler_t)&powerpc_jit::gen_not_available) return false;
|
||||
return (this->*((bool (powerpc_jit::*)(int, int, int, int, int))jit_info[mnemo]->handler))(mnemo, vD, vA, vB, vC);
|
||||
}
|
||||
|
||||
bool powerpc_jit::gen_vector_compare(int mnemo, int vD, int vA, int vB, bool Rc)
|
||||
{
|
||||
if (jit_info[mnemo]->handler == (gen_handler_t)&powerpc_jit::gen_not_available) return false;
|
||||
return (this->*((bool (powerpc_jit::*)(int, int, int, int, bool))jit_info[mnemo]->handler))(mnemo, vD, vA, vB, Rc);
|
||||
}
|
||||
|
||||
@ -395,8 +404,8 @@ bool powerpc_jit::gen_x86_lvx(int mnemo, int vD, int rA, int rB)
|
||||
gen_add_32(x86_memory_operand(xPPC_GPR(rA), REG_CPU_ID), REG_T0_ID);
|
||||
gen_and_32(x86_immediate_operand(-16), REG_T0_ID);
|
||||
#if SIZEOF_VOID_P == 8
|
||||
gen_mov_64(x86_memory_operand(0, REG_T0_ID), REG_T1_ID);
|
||||
gen_mov_64(x86_memory_operand(8, REG_T0_ID), REG_T2_ID);
|
||||
gen_mov_64(vm_memory_operand(0, REG_T0_ID), REG_T1_ID);
|
||||
gen_mov_64(vm_memory_operand(8, REG_T0_ID), REG_T2_ID);
|
||||
gen_bswap_64(REG_T1_ID);
|
||||
gen_bswap_64(REG_T2_ID);
|
||||
gen_rol_64(x86_immediate_operand(32), REG_T1_ID);
|
||||
@ -404,14 +413,14 @@ bool powerpc_jit::gen_x86_lvx(int mnemo, int vD, int rA, int rB)
|
||||
gen_mov_64(REG_T1_ID, x86_memory_operand(xPPC_VR(vD) + 0, REG_CPU_ID));
|
||||
gen_mov_64(REG_T2_ID, x86_memory_operand(xPPC_VR(vD) + 8, REG_CPU_ID));
|
||||
#else
|
||||
gen_mov_32(x86_memory_operand(0*4, REG_T0_ID), REG_T1_ID);
|
||||
gen_mov_32(x86_memory_operand(1*4, REG_T0_ID), REG_T2_ID);
|
||||
gen_mov_32(vm_memory_operand(0*4, REG_T0_ID), REG_T1_ID);
|
||||
gen_mov_32(vm_memory_operand(1*4, REG_T0_ID), REG_T2_ID);
|
||||
gen_bswap_32(REG_T1_ID);
|
||||
gen_bswap_32(REG_T2_ID);
|
||||
gen_mov_32(REG_T1_ID, x86_memory_operand(xPPC_VR(vD) + 0*4, REG_CPU_ID));
|
||||
gen_mov_32(REG_T2_ID, x86_memory_operand(xPPC_VR(vD) + 1*4, REG_CPU_ID));
|
||||
gen_mov_32(x86_memory_operand(2*4, REG_T0_ID), REG_T1_ID);
|
||||
gen_mov_32(x86_memory_operand(3*4, REG_T0_ID), REG_T2_ID);
|
||||
gen_mov_32(vm_memory_operand(2*4, REG_T0_ID), REG_T1_ID);
|
||||
gen_mov_32(vm_memory_operand(3*4, REG_T0_ID), REG_T2_ID);
|
||||
gen_bswap_32(REG_T1_ID);
|
||||
gen_bswap_32(REG_T2_ID);
|
||||
gen_mov_32(REG_T1_ID, x86_memory_operand(xPPC_VR(vD) + 2*4, REG_CPU_ID));
|
||||
@ -435,8 +444,8 @@ bool powerpc_jit::gen_x86_stvx(int mnemo, int vS, int rA, int rB)
|
||||
gen_and_32(x86_immediate_operand(-16), REG_T0_ID);
|
||||
gen_rol_64(x86_immediate_operand(32), REG_T1_ID);
|
||||
gen_rol_64(x86_immediate_operand(32), REG_T2_ID);
|
||||
gen_mov_64(REG_T1_ID, x86_memory_operand(0, REG_T0_ID));
|
||||
gen_mov_64(REG_T2_ID, x86_memory_operand(8, REG_T0_ID));
|
||||
gen_mov_64(REG_T1_ID, vm_memory_operand(0, REG_T0_ID));
|
||||
gen_mov_64(REG_T2_ID, vm_memory_operand(8, REG_T0_ID));
|
||||
#else
|
||||
gen_mov_32(x86_memory_operand(xPPC_VR(vS) + 0*4, REG_CPU_ID), REG_T1_ID);
|
||||
gen_mov_32(x86_memory_operand(xPPC_VR(vS) + 1*4, REG_CPU_ID), REG_T2_ID);
|
||||
@ -445,14 +454,14 @@ bool powerpc_jit::gen_x86_stvx(int mnemo, int vS, int rA, int rB)
|
||||
gen_bswap_32(REG_T1_ID);
|
||||
gen_bswap_32(REG_T2_ID);
|
||||
gen_and_32(x86_immediate_operand(-16), REG_T0_ID);
|
||||
gen_mov_32(REG_T1_ID, x86_memory_operand(0*4, REG_T0_ID));
|
||||
gen_mov_32(REG_T2_ID, x86_memory_operand(1*4, REG_T0_ID));
|
||||
gen_mov_32(REG_T1_ID, vm_memory_operand(0*4, REG_T0_ID));
|
||||
gen_mov_32(REG_T2_ID, vm_memory_operand(1*4, REG_T0_ID));
|
||||
gen_mov_32(x86_memory_operand(xPPC_VR(vS) + 2*4, REG_CPU_ID), REG_T1_ID);
|
||||
gen_mov_32(x86_memory_operand(xPPC_VR(vS) + 3*4, REG_CPU_ID), REG_T2_ID);
|
||||
gen_bswap_32(REG_T1_ID);
|
||||
gen_bswap_32(REG_T2_ID);
|
||||
gen_mov_32(REG_T1_ID, x86_memory_operand(2*4, REG_T0_ID));
|
||||
gen_mov_32(REG_T2_ID, x86_memory_operand(3*4, REG_T0_ID));
|
||||
gen_mov_32(REG_T1_ID, vm_memory_operand(2*4, REG_T0_ID));
|
||||
gen_mov_32(REG_T2_ID, vm_memory_operand(3*4, REG_T0_ID));
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
@ -667,7 +676,7 @@ void powerpc_jit::gen_sse2_vsplat(int vD, int rValue)
|
||||
}
|
||||
|
||||
// vspltisb
|
||||
bool powerpc_jit::gen_sse2_vspltisb(int mnemo, int vD, int SIMM)
|
||||
bool powerpc_jit::gen_sse2_vspltisb(int mnemo, int vD, int SIMM, int unused)
|
||||
{
|
||||
switch (SIMM) {
|
||||
case 0:
|
||||
@ -718,7 +727,7 @@ bool powerpc_jit::gen_sse2_vspltisb(int mnemo, int vD, int SIMM)
|
||||
}
|
||||
|
||||
// vspltish
|
||||
bool powerpc_jit::gen_sse2_vspltish(int mnemo, int vD, int SIMM)
|
||||
bool powerpc_jit::gen_sse2_vspltish(int mnemo, int vD, int SIMM, int unused)
|
||||
{
|
||||
switch (SIMM) {
|
||||
case 0:
|
||||
@ -764,7 +773,7 @@ bool powerpc_jit::gen_sse2_vspltish(int mnemo, int vD, int SIMM)
|
||||
}
|
||||
|
||||
// vspltisw
|
||||
bool powerpc_jit::gen_sse2_vspltisw(int mnemo, int vD, int SIMM)
|
||||
bool powerpc_jit::gen_sse2_vspltisw(int mnemo, int vD, int SIMM, int unused)
|
||||
{
|
||||
switch (SIMM) {
|
||||
case 0:
|
||||
@ -866,7 +875,7 @@ bool powerpc_jit::gen_ssse3_lvx(int mnemo, int vD, int rA, int rB)
|
||||
gen_and_32(x86_immediate_operand(-16), REG_T0_ID);
|
||||
|
||||
x86_memory_operand vswapmask(gen_ssse3_vswap_mask(), X86_NOREG);
|
||||
gen_movdqa(x86_memory_operand(0, REG_T0_ID), REG_V0_ID);
|
||||
gen_movdqa(vm_memory_operand(0, REG_T0_ID), REG_V0_ID);
|
||||
gen_insn(X86_INSN_SSE_3P, X86_SSSE3_PSHUFB, vswapmask, REG_V0_ID);
|
||||
gen_movdqa(REG_V0_ID, x86_memory_operand(xPPC_VR(vD), REG_CPU_ID));
|
||||
return true;
|
||||
@ -883,7 +892,7 @@ bool powerpc_jit::gen_ssse3_stvx(int mnemo, int vS, int rA, int rB)
|
||||
x86_memory_operand vswapmask(gen_ssse3_vswap_mask(), X86_NOREG);
|
||||
gen_movdqa(x86_memory_operand(xPPC_VR(vS), REG_CPU_ID), REG_V0_ID);
|
||||
gen_insn(X86_INSN_SSE_3P, X86_SSSE3_PSHUFB, vswapmask, REG_V0_ID);
|
||||
gen_movdqa(REG_V0_ID, x86_memory_operand(0, REG_T0_ID));
|
||||
gen_movdqa(REG_V0_ID, vm_memory_operand(0, REG_T0_ID));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -90,9 +90,9 @@ private:
|
||||
bool gen_sse2_vsel(int mnemo, int vD, int vA, int vB, int vC);
|
||||
bool gen_sse2_vsldoi(int mnemo, int vD, int vA, int vB, int SH);
|
||||
void gen_sse2_vsplat(int vD, int rValue);
|
||||
bool gen_sse2_vspltisb(int mnemo, int vD, int SIMM);
|
||||
bool gen_sse2_vspltish(int mnemo, int vD, int SIMM);
|
||||
bool gen_sse2_vspltisw(int mnemo, int vD, int SIMM);
|
||||
bool gen_sse2_vspltisb(int mnemo, int vD, int SIMM, int unused);
|
||||
bool gen_sse2_vspltish(int mnemo, int vD, int SIMM, int unused);
|
||||
bool gen_sse2_vspltisw(int mnemo, int vD, int SIMM, int unused);
|
||||
bool gen_sse2_vspltb(int mnemo, int vD, int UIMM, int vB);
|
||||
bool gen_sse2_vsplth(int mnemo, int vD, int UIMM, int vB);
|
||||
bool gen_sse2_vspltw(int mnemo, int vD, int UIMM, int vB);
|
||||
|
@ -125,6 +125,22 @@ static void disasm_translation(uint32 src_addr, uint32 src_len,
|
||||
**/
|
||||
|
||||
#if PPC_ENABLE_JIT
|
||||
|
||||
void
|
||||
powerpc_cpu::call_do_record_step(powerpc_cpu * cpu, uint32 param1, uint32 param2) {
|
||||
cpu->do_record_step(param1, param2);
|
||||
}
|
||||
|
||||
void
|
||||
powerpc_cpu::call_execute_invalidate_cache_range(powerpc_cpu * cpu) {
|
||||
cpu->execute_invalidate_cache_range();
|
||||
}
|
||||
|
||||
void
|
||||
powerpc_cpu::call_execute_illegal(powerpc_cpu * cpu, uint32 param1) {
|
||||
cpu->execute_illegal(param1);
|
||||
}
|
||||
|
||||
powerpc_cpu::block_info *
|
||||
powerpc_cpu::compile_block(uint32 entry_point)
|
||||
{
|
||||
@ -169,7 +185,7 @@ powerpc_cpu::compile_block(uint32 entry_point)
|
||||
#if PPC_FLIGHT_RECORDER
|
||||
if (is_logging()) {
|
||||
typedef void (*func_t)(dyngen_cpu_base, uint32, uint32);
|
||||
func_t func = (func_t)nv_mem_fun((execute_pmf)&powerpc_cpu::do_record_step).ptr();
|
||||
func_t func = &powerpc_cpu::call_do_record_step;
|
||||
dg.gen_invoke_CPU_im_im(func, dpc, opcode);
|
||||
}
|
||||
#endif
|
||||
@ -1120,7 +1136,7 @@ powerpc_cpu::compile_block(uint32 entry_point)
|
||||
case PPC_I(ISYNC): // Instruction synchronize
|
||||
{
|
||||
typedef void (*func_t)(dyngen_cpu_base);
|
||||
func_t func = (func_t)nv_mem_fun(&powerpc_cpu::execute_invalidate_cache_range).ptr();
|
||||
func_t func = &powerpc_cpu::call_execute_invalidate_cache_range;
|
||||
dg.gen_invoke_CPU(func);
|
||||
break;
|
||||
}
|
||||
@ -1377,10 +1393,17 @@ powerpc_cpu::compile_block(uint32 entry_point)
|
||||
case PPC_I(STVEWX):
|
||||
case PPC_I(STVX):
|
||||
case PPC_I(STVXL):
|
||||
{
|
||||
assert(vD_field::mask() == vS_field::mask());
|
||||
assert(vA_field::mask() == rA_field::mask());
|
||||
assert(vB_field::mask() == rB_field::mask());
|
||||
// fall-through
|
||||
const int vD = vD_field::extract(opcode);
|
||||
const int vA = vA_field::extract(opcode);
|
||||
const int vB = vB_field::extract(opcode);
|
||||
if (!dg.gen_vector_2(ii->mnemo, vD, vA, vB))
|
||||
goto do_generic;
|
||||
break;
|
||||
}
|
||||
case PPC_I(VCMPEQFP):
|
||||
case PPC_I(VCMPEQUB):
|
||||
case PPC_I(VCMPEQUH):
|
||||
@ -1488,10 +1511,14 @@ powerpc_cpu::compile_block(uint32 entry_point)
|
||||
typedef void (*func_t)(dyngen_cpu_base, uint32);
|
||||
func_t func;
|
||||
do_generic:
|
||||
#ifdef __MINGW32__
|
||||
func = (func_t)ii->execute.default_call_conv_ptr();
|
||||
#else
|
||||
func = (func_t)ii->execute.ptr();
|
||||
#endif
|
||||
goto do_invoke;
|
||||
do_illegal:
|
||||
func = (func_t)nv_mem_fun(&powerpc_cpu::execute_illegal).ptr();
|
||||
func = &powerpc_cpu::call_execute_illegal;
|
||||
goto do_invoke;
|
||||
do_invoke:
|
||||
#if PPC_PROFILE_GENERIC_CALLS
|
||||
@ -1554,7 +1581,7 @@ powerpc_cpu::compile_block(uint32 entry_point)
|
||||
// Generate backpatch trampolines
|
||||
if (use_direct_block_chaining) {
|
||||
typedef void *(*func_t)(dyngen_cpu_base);
|
||||
func_t func = (func_t)nv_mem_fun(&powerpc_cpu::compile_chain_block).ptr();
|
||||
func_t func = (func_t)&powerpc_cpu::call_compile_chain_block;
|
||||
for (int i = 0; i < block_info::MAX_TARGETS; i++) {
|
||||
if (bi->li[i].jmp_pc != block_info::INVALID_PC) {
|
||||
uint8 *p = dg.gen_align(16);
|
||||
|
@ -88,6 +88,7 @@ int mathlib_fpclassify (double x)
|
||||
int mathlib_fpclassifyl(long double x)
|
||||
{
|
||||
unimplemented("fpclassifyl");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@ -114,6 +115,7 @@ int mathlib_signbit (double x)
|
||||
int mathlib_signbitl(long double x)
|
||||
{
|
||||
unimplemented("signbitl");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user