From ad054f1b96234ae9750b6543aea27ee0ffbf1929 Mon Sep 17 00:00:00 2001 From: Stefanos Kornilios Mitsis Poiitidis Date: Tue, 25 Mar 2014 00:12:30 +0200 Subject: [PATCH 01/20] Working on linux x86 dyna --- core/build.h | 5 +++++ core/core.mk | 6 +++++- core/emitter/types.h | 6 +++++- core/emitter/x86_emitter.h | 20 ++++++++++---------- core/hw/arm7/arm7.cpp | 10 +++++----- core/hw/arm7/virt_arm.cpp | 4 ++-- core/hw/sh4/dyna/blockmanager.cpp | 8 ++++---- core/linux/common.cpp | 2 +- core/types.h | 2 +- shell/lin86/Makefile | 29 ++++++++++++++++------------- 10 files changed, 54 insertions(+), 38 deletions(-) diff --git a/core/build.h b/core/build.h index bfff0af60..94e8f5d2d 100755 --- a/core/build.h +++ b/core/build.h @@ -85,3 +85,8 @@ #error Invalid Target: TARGET_* not defined #endif +#ifdef HOST_NO_REC + #ifndef HOST_NO_AREC + #define HOST_NO_AREC 1 + #endif +#endif diff --git a/core/core.mk b/core/core.mk index 886b2cd16..4b4e3880f 100755 --- a/core/core.mk +++ b/core/core.mk @@ -19,6 +19,10 @@ ifndef NOT_ARM RZDCY_MODULES += rec-ARM/ endif +ifdef X86_REC + RZDCY_MODULES += rec-x86/ +endif + ifndef NO_REND RZDCY_MODULES += rend/gles/ else @@ -69,4 +73,4 @@ endif ifdef NO_REC RZDCY_CXXFLAGS += -DHOST_NO_REC -endif \ No newline at end of file +endif diff --git a/core/emitter/types.h b/core/emitter/types.h index 4b23850ee..691254d22 100644 --- a/core/emitter/types.h +++ b/core/emitter/types.h @@ -1,5 +1,8 @@ #pragma once +#if 1 +#include "types.h" +#else //basic types typedef signed __int8 s8; typedef signed __int16 s16; @@ -49,4 +52,5 @@ using namespace std; #ifndef die #define die(reason) { printf("Fatal error : %s\n in %s -> %s : %d \n",reason,__FUNCTION__,__FILE__,__LINE__); dbgbreak;} -#endif \ No newline at end of file +#endif +#endif diff --git a/core/emitter/x86_emitter.h b/core/emitter/x86_emitter.h index 6e4d9b3f3..ae709ab72 100644 --- a/core/emitter/x86_emitter.h +++ b/core/emitter/x86_emitter.h @@ -193,7 +193,7 @@ typedef void* dyna_finalizeFP(void* ptr,u32 oldsize,u32 newsize); //define it here cus we use it on label type ;) class x86_block; // a label -struct __declspec(dllexport) x86_Label +struct /*__declspec(dllexport)*/ x86_Label { u32 target_opcode; u8 patch_sz; @@ -202,7 +202,7 @@ struct __declspec(dllexport) x86_Label void* GetPtr(); }; //An empty type that we will use as ptr type.This is ptr-reference -struct __declspec(dllexport) x86_ptr +struct /*__declspec(dllexport)*/ x86_ptr { union { @@ -216,7 +216,7 @@ struct __declspec(dllexport) x86_ptr } }; //This is ptr/imm (for call/jmp) -struct __declspec(dllexport) x86_ptr_imm +struct /*__declspec(dllexport)*/ x86_ptr_imm { union { @@ -255,11 +255,11 @@ struct x86_mrm_t u32 disp; }; -__declspec(dllexport) x86_mrm_t x86_mrm(x86_reg base); -__declspec(dllexport) x86_mrm_t x86_mrm(x86_reg base,x86_ptr disp); -__declspec(dllexport) x86_mrm_t x86_mrm(x86_reg base,x86_reg index); -__declspec(dllexport) x86_mrm_t x86_mrm(x86_reg index,x86_sib_scale scale,x86_ptr disp); -__declspec(dllexport) x86_mrm_t x86_mrm(x86_reg base,x86_reg index,x86_sib_scale scale,x86_ptr disp); +/*__declspec(dllexport)*/ x86_mrm_t x86_mrm(x86_reg base); +/*__declspec(dllexport)*/ x86_mrm_t x86_mrm(x86_reg base,x86_ptr disp); +/*__declspec(dllexport)*/ x86_mrm_t x86_mrm(x86_reg base,x86_reg index); +/*__declspec(dllexport)*/ x86_mrm_t x86_mrm(x86_reg index,x86_sib_scale scale,x86_ptr disp); +/*__declspec(dllexport)*/ x86_mrm_t x86_mrm(x86_reg base,x86_reg index,x86_sib_scale scale,x86_ptr disp); struct code_patch @@ -273,7 +273,7 @@ struct code_patch u32 offset; //offset in opcode stream :) }; -struct __declspec(dllexport) x86_block_externs +struct /*__declspec(dllexport)*/ x86_block_externs { void Apply(void* code_base); bool Modify(u32 offs,u8* dst); @@ -282,7 +282,7 @@ struct __declspec(dllexport) x86_block_externs }; //A block of x86 code :p -class __declspec(dllexport) x86_block +class /*__declspec(dllexport)*/ x86_block { private: void* _labels; diff --git a/core/hw/arm7/arm7.cpp b/core/hw/arm7/arm7.cpp index 2ddb37c1d..3d8dcc84a 100644 --- a/core/hw/arm7/arm7.cpp +++ b/core/hw/arm7/arm7.cpp @@ -188,7 +188,7 @@ void armt_init(); //void CreateTables(); void arm_Init() { -#if !defined(HOST_NO_REC) +#if !defined(HOST_NO_AREC) armt_init(); #endif //CreateTables(); @@ -398,7 +398,7 @@ void FlushCache(); void arm_Reset() { -#if !defined(HOST_NO_REC) +#if !defined(HOST_NO_AREC) FlushCache(); #endif Arm7Enabled = false; @@ -512,7 +512,7 @@ void update_armintc() reg[INTR_PEND].I=e68k_out && armFiqEnable; } -#ifdef HOST_NO_REC +#ifdef HOST_NO_AREC void arm_Run(u32 CycleCount) { arm_Run_(CycleCount); } #else extern "C" void CompileCode(); @@ -789,7 +789,7 @@ u32 DYNACALL DoMemOp(u32 addr,u32 data) { u32 rv=0; -#if HOST_CPU==CPU_X86 && !defined(HOST_NO_REC) +#if HOST_CPU==CPU_X86 && !defined(HOST_NO_AREC) addr=virt_arm_reg(0); data=virt_arm_reg(1); #endif @@ -809,7 +809,7 @@ u32 DYNACALL DoMemOp(u32 addr,u32 data) arm_WriteMem32(addr,data); } - #if HOST_CPU==CPU_X86 && !defined(HOST_NO_REC) + #if HOST_CPU==CPU_X86 && !defined(HOST_NO_AREC) virt_arm_reg(0)=rv; #endif diff --git a/core/hw/arm7/virt_arm.cpp b/core/hw/arm7/virt_arm.cpp index 857082603..d55c4dda1 100644 --- a/core/hw/arm7/virt_arm.cpp +++ b/core/hw/arm7/virt_arm.cpp @@ -1,6 +1,6 @@ #include "virt_arm.h" -#if HOST_CPU==CPU_X86 && !defined(HOST_NO_REC) +#if HOST_CPU==CPU_X86 && !defined(HOST_NO_AREC) #define C_CORE @@ -321,4 +321,4 @@ u32& virt_arm_reg(u32 id) return VARM::arm_Reg[id].I; } -#endif \ No newline at end of file +#endif diff --git a/core/hw/sh4/dyna/blockmanager.cpp b/core/hw/sh4/dyna/blockmanager.cpp index 2ed79ea73..eec9cdd4b 100644 --- a/core/hw/sh4/dyna/blockmanager.cpp +++ b/core/hw/sh4/dyna/blockmanager.cpp @@ -92,14 +92,14 @@ u32 bm_gc_luc,bm_gcf_luc; DynarecCodeEntry* DYNACALL bm_GetCode(u32 addr) { //rdv_FailedToFindBlock_pc=addr; - DynarecCodeEntry* rv=FPCA(addr); + DynarecCodeEntry* rv=(DynarecCodeEntry*)FPCA(addr); - return rv; + return (DynarecCodeEntry*)rv; } DynarecCodeEntry* DYNACALL bm_GetCode2(u32 addr) { - return bm_GetCode(addr); + return (DynarecCodeEntry*)bm_GetCode(addr); } RuntimeBlockInfo* DYNACALL bm_GetBlock(u32 addr) @@ -155,7 +155,7 @@ void bm_AddBlock(RuntimeBlockInfo* blk) blkmap.insert(blk); - verify(bm_GetCode(blk->addr)==ngen_FailedToFindBlock); + verify((void*)bm_GetCode(blk->addr)==(void*)ngen_FailedToFindBlock); FPCA(blk->addr)=blk->code; #ifdef DYNA_OPROF diff --git a/core/linux/common.cpp b/core/linux/common.cpp index f05ead9bd..4809553a7 100644 --- a/core/linux/common.cpp +++ b/core/linux/common.cpp @@ -66,7 +66,7 @@ void fault_handler (int sn, siginfo_t * si, void *ctxr) if (VramLockedWrite((u8*)si->si_addr) || BM_LockedWrite((u8*)si->si_addr)) return; -#ifndef HOST_NO_REC +#if !defined( HOST_NO_REC) && HOST_CPU==CPU_ARM else if (dyna_cde) { GET_PC_FROM_CONTEXT(ctxr)=(u32)ngen_readm_fail_v2((u32*)GET_PC_FROM_CONTEXT(ctxr),(u32*)&(ctx->uc_mcontext.arm_r0),(unat)si->si_addr); diff --git a/core/types.h b/core/types.h index a9bce6c23..2fe4c8172 100644 --- a/core/types.h +++ b/core/types.h @@ -14,7 +14,7 @@ #if BUILD_COMPILER==COMPILER_VC #define DYNACALL __fastcall #else -#define DYNACALL +#define DYNACALL __attribute__((fastcall)) #endif #if BUILD_COMPILER==COMPILER_VC diff --git a/shell/lin86/Makefile b/shell/lin86/Makefile index d7503dfc1..8e3bb792a 100644 --- a/shell/lin86/Makefile +++ b/shell/lin86/Makefile @@ -2,7 +2,8 @@ LOCAL_PATH := $(call my-dir) FOR_LINUX :=1 NOT_ARM := 1 -NO_REC := 1 +X86_REC := 1 +#NO_REC := 1 #NO_REND := 1 RZDCY_SRC_DIR = ../../core @@ -26,33 +27,35 @@ LDFLAGS := -m32 -g -Wl,-Map,$(notdir $@).map,--gc-sections -Wl,-O3 -Wl,--sort-co SOURCES := cfg/ hw/arm7/ hw/aica/ hw/asic/ hw/ hw/gdrom/ hw/maple/ \ hw/mem/ hw/pvr/ hw/sh4/ hw/sh4/rec_v2/ plugins/ profiler/ serial_ipc/ \ - hw/extdev/ hw/arm/ imgread/ linux/ linux-dist/ ./ rec-ARM/ deps/zlib/ deps/chdr/ deps/crypto/ arm_emitter/ + hw/extdev/ hw/arm/ imgread/ linux/ linux-dist/ ./ rec-x86/ deps/zlib/ deps/chdr/ deps/crypto/ arm_emitter/ + + +CFLAGS := -m32 -g -O3 -D RELEASE -c -D TARGET_LINUX_x86 -D USES_HOMEDIR -D HOST_NO_AREC #-D NO_REND +CFLAGS += -D SUPPORT_X11 +CFLAGS += -frename-registers -fno-strict-aliasing -fsingle-precision-constant +CFLAGS += -ffast-math -ftree-vectorize -CXXFLAGS := -m32 -g -O3 -D RELEASE -c -D TARGET_LINUX_x86 -D USES_HOMEDIR -D HOST_NO_REC #-D NO_REND -CXXFLAGS += -frename-registers -fno-strict-aliasing -fsingle-precision-constant -CXXFLAGS += -ffast-math -ftree-vectorize #-fprefetch-loop-arrays #-std=c++0x -CXXFLAGS += $(CFLAGS) $(MFLAGS) -fno-exceptions -fno-rtti -CXXFLAGS += -D SUPPORT_X11 +CXXFLAGS = $(MFLAGS) -fno-exceptions -fno-rtti -fpermissive ifdef PGO_MAKE - CXXFLAGS += -fprofile-generate -pg + CFLAGS += -fprofile-generate -pg LDFLAGS += -fprofile-generate else - CXXFLAGS += -fomit-frame-pointer + CFLAGS += -fomit-frame-pointer endif ifdef PGO_USE - CXXFLAGS += -fprofile-use + CFLAGS += -fprofile-use endif ifdef LTO_TEST - CXXFLAGS += -flto -fwhole-program + CFLAGS += -flto -fwhole-program LDFLAGS +=-flto -fwhole-program endif @@ -86,11 +89,11 @@ $(EXECUTABLE_STRIPPED): $(EXECUTABLE) obj/%.build_obj : $(RZDCY_SRC_DIR)/%.cpp mkdir -p $(dir $@) - $(CXX) $(EXTRAFLAGS) $(INCS) $(CXXFLAGS) $< -o $@ + $(CXX) $(EXTRAFLAGS) $(INCS) $(CFLAGS) $(CXXFLAGS) $< -o $@ obj/%.build_obj : $(RZDCY_SRC_DIR)/%.c mkdir -p $(dir $@) - $(CC) $(EXTRAFLAGS) $(INCS) $(CXXFLAGS) $< -o $@ + $(CC) $(EXTRAFLAGS) $(INCS) $(CFLAGS) $< -o $@ obj/%.build_obj : $(RZDCY_SRC_DIR)/%.S mkdir -p $(dir $@) From 3eb27fc1099e5046ecea25754905d265b984873d Mon Sep 17 00:00:00 2001 From: Stefanos Kornilios Mitsis Poiitidis Date: Fri, 25 Apr 2014 12:52:08 +0300 Subject: [PATCH 02/20] Compiles and links for linux x86. No worky yet. Woohoo, a new gcc bug! The x86 linux dynarec just got a couple of months further away thanks to gcc being totally retarded as some things (namely, fastcalls). And yes, reicast depends on fastcalls for a lot of things, and no, i don't care if you don't like fastcalls. --- core/core.mk | 2 +- core/emitter/x86_emitter.cpp | 18 +- core/emitter/x86_emitter.h | 42 +- core/emitter/x86_op_encoder.h | 5 + core/rec-x86/lin86_asm.S | 148 ++++ core/rec-x86/win86_driver.cpp | 781 +++++++++++++++++ core/rec-x86/win86_il.cpp | 1529 +++++++++++++++++++++++++++++++++ core/rec-x86/win86_ngen.cpp | 128 +++ core/rec-x86/win86_ngen.h | 59 ++ core/types.h | 4 +- shell/lin86/Makefile | 3 +- 11 files changed, 2689 insertions(+), 30 deletions(-) create mode 100644 core/rec-x86/lin86_asm.S create mode 100644 core/rec-x86/win86_driver.cpp create mode 100644 core/rec-x86/win86_il.cpp create mode 100644 core/rec-x86/win86_ngen.cpp create mode 100644 core/rec-x86/win86_ngen.h diff --git a/core/core.mk b/core/core.mk index 4b4e3880f..89a2a0f02 100755 --- a/core/core.mk +++ b/core/core.mk @@ -20,7 +20,7 @@ ifndef NOT_ARM endif ifdef X86_REC - RZDCY_MODULES += rec-x86/ + RZDCY_MODULES += rec-x86/ emitter/ endif ifndef NO_REND diff --git a/core/emitter/x86_emitter.cpp b/core/emitter/x86_emitter.cpp index 66eb9aaf6..5ef9d4650 100644 --- a/core/emitter/x86_emitter.cpp +++ b/core/emitter/x86_emitter.cpp @@ -3,6 +3,7 @@ #pragma warning(disable:4244) #pragma warning(disable:4245) +#include "../types.h" #include "x86_emitter.h" bool IsS8(u32 value) { @@ -183,6 +184,8 @@ x86_block_externs* x86_block::GetExterns() return rv; } + +#if 0 #include "windows.h" /*void x86_block::CopyTo(void* to) { @@ -194,6 +197,8 @@ x86_block_externs* x86_block::GetExterns() } */ +#endif + //wut ? void x86_block::ApplyPatches(u8* base) { @@ -409,7 +414,10 @@ void x86_block::Emit(x86_opcode_class op,x86_reg reg1,x86_reg reg2,u32 imm) //reg,mrm,imm, reg1 is written void x86_block::Emit(x86_opcode_class op,x86_reg reg,x86_ptr mem,u32 imm) { - ME_op_3_imm(op,reg,c_mrm(mem),imm); + //GCC bitches about using this directly. It doesn't complain for the other uses though + //go figure .... + x86_mrm_t mrm = c_mrm(mem); + ME_op_3_imm(op,reg,mrm,imm); } //reg,mrm,imm, reg1 is written @@ -449,19 +457,19 @@ u8 EncodeDisp(u32 disp,x86_mrm_t* to,u8 flags) verify(false); return 0; } -__declspec(dllexport) x86_mrm_t x86_mrm(x86_reg base) +/*__declspec(dllexport) */x86_mrm_t x86_mrm(x86_reg base) { return x86_mrm(base,NO_REG,sib_scale_1,0); } -__declspec(dllexport) x86_mrm_t x86_mrm(x86_reg base,x86_ptr disp) +/*__declspec(dllexport) */x86_mrm_t x86_mrm(x86_reg base,x86_ptr disp) { return x86_mrm(base,NO_REG,sib_scale_1,disp); } -__declspec(dllexport) x86_mrm_t x86_mrm(x86_reg index,x86_sib_scale scale,x86_ptr disp) +/*__declspec(dllexport) */x86_mrm_t x86_mrm(x86_reg index,x86_sib_scale scale,x86_ptr disp) { return x86_mrm(NO_REG,index,scale,disp); } -__declspec(dllexport) x86_mrm_t x86_mrm(x86_reg base,x86_reg index) +/*__declspec(dllexport) */x86_mrm_t x86_mrm(x86_reg base,x86_reg index) { return x86_mrm(base,index,sib_scale_1,0); } diff --git a/core/emitter/x86_emitter.h b/core/emitter/x86_emitter.h index ae709ab72..ecffcd327 100644 --- a/core/emitter/x86_emitter.h +++ b/core/emitter/x86_emitter.h @@ -303,9 +303,9 @@ public: ~x86_block(); void x86_buffer_ensure(u32 size); - void x86_block::write8(u32 value); - void x86_block::write16(u32 value); - void x86_block::write32(u32 value); + void write8(u32 value); + void write16(u32 value); + void write32(u32 value); //init things void Init(dyna_reallocFP* ral,dyna_finalizeFP* alf); @@ -332,45 +332,45 @@ public: //opcode Emitters //no param - void x86_block::Emit(x86_opcode_class op); + void Emit(x86_opcode_class op); //1 param //reg - void x86_block::Emit(x86_opcode_class op,x86_reg reg); + void Emit(x86_opcode_class op,x86_reg reg); //smrm - void x86_block::Emit(x86_opcode_class op,x86_ptr mem); + void Emit(x86_opcode_class op,x86_ptr mem); //mrm - void x86_block::Emit(x86_opcode_class op,x86_mrm_t mrm); + void Emit(x86_opcode_class op,x86_mrm_t mrm); //imm - void x86_block::Emit(x86_opcode_class op,u32 imm); + void Emit(x86_opcode_class op,u32 imm); //ptr_imm - void x86_block::Emit(x86_opcode_class op,x86_ptr_imm disp); + void Emit(x86_opcode_class op,x86_ptr_imm disp); //lbl - void x86_block::Emit(x86_opcode_class op,x86_Label* lbl); + void Emit(x86_opcode_class op,x86_Label* lbl); //2 param //reg,reg, reg1 is written - void x86_block::Emit(x86_opcode_class op,x86_reg reg1,x86_reg reg2); + void Emit(x86_opcode_class op,x86_reg reg1,x86_reg reg2); //reg,smrm, reg is written - void x86_block::Emit(x86_opcode_class op,x86_reg reg,x86_ptr mem); + void Emit(x86_opcode_class op,x86_reg reg,x86_ptr mem); //reg,mrm, reg is written - void x86_block::Emit(x86_opcode_class op,x86_reg reg1,x86_mrm_t mrm); + void Emit(x86_opcode_class op,x86_reg reg1,x86_mrm_t mrm); //reg,imm, reg is written - void x86_block::Emit(x86_opcode_class op,x86_reg reg,u32 imm); + void Emit(x86_opcode_class op,x86_reg reg,u32 imm); //smrm,reg, mem is written - void x86_block::Emit(x86_opcode_class op,x86_ptr mem,x86_reg reg); + void Emit(x86_opcode_class op,x86_ptr mem,x86_reg reg); //smrm,imm, mem is written - void x86_block::Emit(x86_opcode_class op,x86_ptr mem,u32 imm); + void Emit(x86_opcode_class op,x86_ptr mem,u32 imm); //mrm,reg, mrm is written - void x86_block::Emit(x86_opcode_class op,x86_mrm_t mrm,x86_reg reg); + void Emit(x86_opcode_class op,x86_mrm_t mrm,x86_reg reg); //mrm,imm, mrm is written - void x86_block::Emit(x86_opcode_class op,x86_mrm_t mrm,u32 imm); + void Emit(x86_opcode_class op,x86_mrm_t mrm,u32 imm); //3 param //reg,reg,imm, reg1 is written - void x86_block::Emit(x86_opcode_class op,x86_reg reg1,x86_reg reg2,u32 imm); + void Emit(x86_opcode_class op,x86_reg reg1,x86_reg reg2,u32 imm); //reg,mrm,imm, reg1 is written - void x86_block::Emit(x86_opcode_class op,x86_reg reg,x86_ptr mem,u32 imm); + void Emit(x86_opcode_class op,x86_reg reg,x86_ptr mem,u32 imm); //reg,mrm,imm, reg1 is written - void x86_block::Emit(x86_opcode_class op,x86_reg reg,x86_mrm_t mrm,u32 imm); + void Emit(x86_opcode_class op,x86_reg reg,x86_mrm_t mrm,u32 imm); }; diff --git a/core/emitter/x86_op_encoder.h b/core/emitter/x86_op_encoder.h index c77a1596b..fd6c03244 100644 --- a/core/emitter/x86_op_encoder.h +++ b/core/emitter/x86_op_encoder.h @@ -58,6 +58,11 @@ } */ +#include "build.h" + +#if BUILD_COMPILER == COMPILER_GCC + #define __fastcall +#endif enum enc_param diff --git a/core/rec-x86/lin86_asm.S b/core/rec-x86/lin86_asm.S new file mode 100644 index 000000000..4918f4313 --- /dev/null +++ b/core/rec-x86/lin86_asm.S @@ -0,0 +1,148 @@ +.section .text +.intel_syntax noprefix + + +.extern rdv_LinkBlock +.globl p_sh4rcb +.globl gas_offs +.globl rdv_FailedToFindBlock +.globl cycle_counter +.globl loop_no_update +.globl intc_sched +.globl bm_GetCode +.globl cycle_counter +.globl UpdateSystem +.globl rdv_DoInterrupts +.globl rdv_BlockCheckFail + +########################################### + +.globl ngen_LinkBlock_Shared_stub +.type ngen_LinkBlock_Shared_stub, @function + +ngen_LinkBlock_Shared_stub: + pop ecx + sub ecx,5 + call rdv_LinkBlock + jmp eax + + + +########################################### + +.globl ngen_LinkBlock_cond_Next_stub +.type ngen_LinkBlock_cond_Next_stub, @function + +ngen_LinkBlock_cond_Next_stub: + mov edx,0 + jmp ngen_LinkBlock_Shared_stub + + + +########################################### + +.globl ngen_LinkBlock_cond_Branch_stub +.type ngen_LinkBlock_cond_Branch_stub, @function + +ngen_LinkBlock_cond_Branch_stub: + mov edx,1 + jmp ngen_LinkBlock_Shared_stub + + +########################################### + +.globl ngen_LinkBlock_Generic_stub +.type ngen_LinkBlock_Generic_stub, @function + +# u32 gas_offs=offsetof(Sh4RCB,cntx.jdyn); +ngen_LinkBlock_Generic_stub: + mov edx,p_sh4rcb + add edx,gas_offs + mov edx,[edx] + jmp ngen_LinkBlock_Shared_stub + + + + +########################################### + +.globl ngen_FailedToFindBlock_ +.type ngen_FailedToFindBlock_, @function + +ngen_FailedToFindBlock_: + mov ecx,esi + call rdv_FailedToFindBlock + jmp eax + + + +########################################### +#define SH4_TIMESLICE 448 + +.globl ngen_mainloop +.type ngen_mainloop, @function + +ngen_mainloop: + push esi + push edi + push ebp + push ebx + + mov ecx,0xA0000000 + mov dword ptr cycle_counter, 448 #SH4_TIMESLICE + + mov dword ptr loop_no_update,offset no_update + mov dword ptr intc_sched,offset intc_sched_offs + + mov eax,0 + +# next_pc _MUST_ be on ecx +no_update: + mov esi,ecx + call _Z10bm_GetCodej #bm_GetCode + jmp eax + +intc_sched_offs: + add dword ptr cycle_counter, 448 #SH4_TIMESLICE + call UpdateSystem + cmp eax,0 + jnz do_iter + ret + +do_iter: + pop ecx + call rdv_DoInterrupts + mov ecx,eax +# cmp byte ptr [sh4_int_bCpuRun],0 +# jz cleanup + jmp no_update + +cleanup: + pop ebx + pop ebp + pop edi + pop esi + + ret + + + +########################################### + +.globl ngen_blockcheckfail +.type ngen_blockcheckfail, @function + +ngen_blockcheckfail: + call rdv_BlockCheckFail + jmp eax + + +########################################### + +.globl ngen_blockcheckfail2 +.type ngen_blockcheckfail2, @function + +ngen_blockcheckfail2: + int 3 + call rdv_BlockCheckFail + jmp eax diff --git a/core/rec-x86/win86_driver.cpp b/core/rec-x86/win86_driver.cpp new file mode 100644 index 000000000..4c85b6b24 --- /dev/null +++ b/core/rec-x86/win86_driver.cpp @@ -0,0 +1,781 @@ +#include "types.h" + +#ifndef HOST_NO_REC +#include "win86_ngen.h" + + + +struct DynaRBI: RuntimeBlockInfo +{ + x86_block_externs* reloc_info; + + virtual ~DynaRBI() { if (reloc_info) reloc_info->Free(); } + + virtual u32 Relink(); + virtual void Relocate(void* dst) + { + reloc_info->Apply(dst); + } +}; + +x86_block* x86e; + +u32 cycle_counter; + +void* loop_no_update; +void* intc_sched; + +bool sse_1=true; +bool sse_2=true; +bool sse_3=true; +bool ssse_3=true; +bool mmx=true; + +void DetectCpuFeatures() +{ + static bool detected=false; + if (detected) return; + detected=true; + +#if HOST_OS==OS_WINDOWS + __try + { + __asm addps xmm0,xmm0 + } + __except(1) + { + sse_1=false; + } + + __try + { + __asm addpd xmm0,xmm0 + } + __except(1) + { + sse_2=false; + } + + __try + { + __asm addsubpd xmm0,xmm0 + } + __except(1) + { + sse_3=false; + } + + __try + { + __asm phaddw xmm0,xmm0 + } + __except(1) + { + ssse_3=false; + } + + + __try + { + __asm paddd mm0,mm1 + __asm emms; + } + __except(1) + { + mmx=false; + } + #endif +} + + +#define CSC_SIZE 64 +struct csc_et +{ + u32 pc; + void* code; +}; +csc_et csc[CSC_SIZE<32?32:CSC_SIZE]; + + +#define CSC_SHIFT 1 +u32 csc_hash(u32 addr) +{ + return (addr>>CSC_SHIFT)&(CSC_SIZE-1); +} + +u32 csc_mode=0; + +u32 csc_sidx=1; + +x86_reg alloc_regs[]={EBX,EBP,ESI,EDI,NO_REG}; +x86_reg xmm_alloc_regs[]={XMM7,XMM6,XMM5,XMM4,NO_REG}; +f32 ALIGN(16) thaw_regs[4]; + + +void x86_reg_alloc::Preload(u32 reg,x86_reg nreg) +{ + x86e->Emit(op_mov32,nreg,GetRegPtr(reg)); +} +void x86_reg_alloc::Writeback(u32 reg,x86_reg nreg) +{ + x86e->Emit(op_mov32,GetRegPtr(reg),nreg); +} + +void x86_reg_alloc::Preload_FPU(u32 reg,x86_reg nreg) +{ + x86e->Emit(op_movss,nreg,GetRegPtr(reg)); +} +void x86_reg_alloc::Writeback_FPU(u32 reg,x86_reg nreg) +{ + x86e->Emit(op_movss,GetRegPtr(reg),nreg); +} +#ifdef PROF2 +extern u32 flsh; +#endif + +void x86_reg_alloc::FreezeXMM() +{ + x86_reg* fpreg=xmm_alloc_regs; + f32* slpc=thaw_regs; + while(*fpreg!=-1) + { + if (SpanNRegfIntr(current_opid,*fpreg)) + x86e->Emit(op_movss,slpc++,*fpreg); + fpreg++; + } +#ifdef PROF2 + x86e->Emit(op_add32,&flsh,1); +#endif +} + +void x86_reg_alloc::ThawXMM() +{ + x86_reg* fpreg=xmm_alloc_regs; + f32* slpc=thaw_regs; + while(*fpreg!=-1) + { + if (SpanNRegfIntr(current_opid,*fpreg)) + x86e->Emit(op_movss,*fpreg,slpc++); + fpreg++; + } +} + + +x86_reg_alloc reg; + +u32 ret_hit,ret_all,ret_stc; + +void csc_push(RuntimeBlockInfo* block) +{ + if (csc_mode==0) + { + x86e->Emit(op_mov32,&csc[csc_hash(block->NextBlock)].pc,block->NextBlock); + } + else if (csc_mode==1) + { + //x86e->Emit(op_int3); + x86e->Emit(op_ror32,&csc_sidx,1); + x86e->Emit(op_bsr32,EAX,&csc_sidx); + x86e->Emit(op_mov32,x86_mrm(EAX,sib_scale_8,x86_ptr(csc)),block->NextBlock); + } +} + +void DYNACALL csc_fail(u32 addr,u32 addy) +{ + if (csc_mode==0) + { + //too bad ? + } + else if (csc_mode==1) + { + u32 fail_idx=(csc_sidx>>1)|(csc_sidx<<31); + + printf("Ret Mismatch: %08X instead of %08X!\n",addr,addy); + } +} +void csc_pop(RuntimeBlockInfo* block) +{ + x86_Label* end=x86e->CreateLabel(false,8); + x86_Label* try_dyn=x86e->CreateLabel(false,8); + + //static guess + x86_Label* stc_hit=x86e->CreateLabel(false,8); + x86e->Emit(op_cmp32,ECX,&block->csc_RetCache); + x86e->Emit(op_je,stc_hit); + //if !eq + { + //if (cached) goto dyn + x86e->Emit(op_cmp32,&block->csc_RetCache,-1); + x86e->Emit(op_jne,try_dyn); + //else, do cache + x86e->Emit(op_mov32,&block->csc_RetCache,ECX); + } + + x86e->MarkLabel(stc_hit); + x86e->Emit(op_add32,&ret_stc,1); + if (csc_mode==1) + x86e->Emit(op_rol32,&csc_sidx,1); + x86e->Emit(op_jmp,end); + + x86e->MarkLabel(try_dyn); + + if (csc_mode==0) + { + //csc ! + //x86e->Emit(op_int3); + x86e->Emit(op_mov32,ECX,GetRegPtr(reg_pc_dyn)); + x86e->Emit(op_mov32,EAX,ECX); + x86e->Emit(op_shr32,EAX,CSC_SHIFT); + x86e->Emit(op_and32,EAX,CSC_SIZE-1); + x86e->Emit(op_cmp32,x86_mrm(EAX,sib_scale_8,x86_ptr(csc)),ECX); + } + else if (csc_mode==1) + { + //x86e->Emit(op_int3); + x86e->Emit(op_mov32,ECX,GetRegPtr(reg_pc_dyn)); + x86e->Emit(op_bsr32,EAX,&csc_sidx); + x86e->Emit(op_rol32,&csc_sidx,1); + x86e->Emit(op_mov32,EDX,x86_mrm(EAX,sib_scale_8,x86_ptr(csc))); + x86e->Emit(op_cmp32,EDX,ECX); + } + + + x86e->Emit(op_jne,end); + x86e->Emit(op_add32,&ret_hit,1); + //x86e->Emit(op_jmp,end); + + x86e->MarkLabel(end); + x86e->Emit(op_add32,&ret_all,1); + +} + +void DYNACALL PrintBlock(u32 pc) +{ + printf("block: 0x%08X\n",pc); + for (int i=0;i<16;i++) + printf("%08X ",r[i]); + printf("\n"); +} + +u32* GetRegPtr(u32 reg) +{ + return Sh4_int_GetRegisterPtr((Sh4RegType)reg); +} + +u32 cvld; +u32 rdmt[6]; +extern u32 memops_t,memops_l; + +void CheckBlock(RuntimeBlockInfo* block,x86_ptr_imm place) +{ + s32 sz=block->sh4_code_size; + u32 sa=block->addr; + while(sz>0) + { + void* ptr=(void*)GetMemPtr(sa,4); + if (ptr) + { + if (sz==2) + x86e->Emit(op_cmp16,ptr,*(u16*)ptr); + else + x86e->Emit(op_cmp32,ptr,*(u32*)ptr); + x86e->Emit(op_jne,place); + } + sz-=4; + sa+=4; + } + +} +void ngen_Compile(RuntimeBlockInfo* block,bool force_checks, bool reset, bool staging,bool optimise) +{ + //initialise stuff + DetectCpuFeatures(); + + ((DynaRBI*)block)->reloc_info=0; + + + //Setup emitter + x86e = new x86_block(); + x86e->Init(0,0); + x86e->x86_buff=(u8*)emit_GetCCPtr(); + x86e->x86_size=emit_FreeSpace(); + x86e->do_realloc=false; + + block->code=(DynarecCodeEntry*)emit_GetCCPtr(); + + x86e->Emit(op_add32,&memops_t,block->memops); + x86e->Emit(op_add32,&memops_l,block->linkedmemops); + + //run register allocator + reg.DoAlloc(block,alloc_regs,xmm_alloc_regs); + + //block header// + + //block invl. checks + x86e->Emit(op_mov32,ECX,block->addr); + + CheckBlock(block,force_checks?x86_ptr_imm(ngen_blockcheckfail):x86_ptr_imm(ngen_blockcheckfail2)); + + //Scheduler + x86_Label* no_up=x86e->CreateLabel(false,8); + + x86e->Emit(op_sub32,&cycle_counter,block->guest_cycles); + + x86e->Emit(op_jns,no_up); + { + x86e->Emit(op_call,x86_ptr_imm(intc_sched)); + } + + x86e->MarkLabel(no_up); + + //stating counter + if (staging) x86e->Emit(op_sub32,&block->staging_runs,1); + + //profiler + if (prof.enable || 1) + x86e->Emit(op_add32,&block->runs,1); + + if (prof.enable) + { + if (force_checks) + x86e->Emit(op_add32,&prof.counters.blkrun.force_check,1); + + x86e->Emit(op_add32,&prof.counters.blkrun.cycles[block->guest_cycles],1); + } + + for (size_t i=0;ioplist.size();i++) + { + shil_opcode* op=&block->oplist[i]; + + u32 opcd_start=x86e->opcode_count; + if (prof.enable) + { + x86e->Emit(op_add32,&prof.counters.shil.executed[op->op],1); + } + + op->host_offs=x86e->x86_indx; + + if (prof.enable) + { + set reg_wt; + set reg_rd; + + for (int z=0;op->rd.is_reg() && zrd.count();z++) + reg_wt.insert(op->rd._reg+z); + + for (int z=0;op->rd2.is_reg() && zrd2.count();z++) + reg_wt.insert(op->rd2._reg+z); + + for (int z=0;op->rs1.is_reg() && zrs1.count();z++) + reg_rd.insert(op->rs1._reg+z); + + for (int z=0;op->rs2.is_reg() && zrs2.count();z++) + reg_rd.insert(op->rs2._reg+z); + + for (int z=0;op->rs3.is_reg() && zrs3.count();z++) + reg_rd.insert(op->rs3._reg+z); + + set::iterator iter=reg_wt.begin(); + while( iter != reg_wt.end() ) + { + if (reg_rd.count(*iter)) + { + reg_rd.erase(*iter); + x86e->Emit(op_add32, &prof.counters.ralloc.reg_rw[*iter], 1); + } + else + { + x86e->Emit(op_add32, &prof.counters.ralloc.reg_w[*iter], 1); + } + + ++iter; + } + + iter=reg_rd.begin(); + while( iter != reg_rd.end() ) + { + x86e->Emit(op_add32,&prof.counters.ralloc.reg_r[*iter],1); + ++iter; + } + } + + reg.OpBegin(op,i); + + ngen_opcode(block,op,x86e,staging,optimise); + + if (prof.enable) x86e->Emit(op_add32,&prof.counters.shil.host_ops[op->op],x86e->opcode_count-opcd_start); + + reg.OpEnd(op); + } + + block->relink_offset=x86e->x86_indx; + block->relink_data=0; + + x86e->x86_indx+=block->Relink(); + + x86e->Generate(); + block->host_code_size=x86e->x86_indx; + block->host_opcodes=x86e->opcode_count; + + emit_Skip(block->host_code_size); + + delete x86e; + x86e=0; +} + +u32 DynaRBI::Relink() +{ + x86_block* x86e=new x86_block(); + x86e->Init(0,0); + x86e->x86_buff=(u8*)code + relink_offset; + x86e->x86_size=512; + x86e->do_realloc=false; + + if (BlockType==BET_StaticCall || BlockType==BET_DynamicCall) + { + //csc_push(this); + } + + switch(BlockType) + { + case BET_Cond_0: + case BET_Cond_1: + { + x86e->Emit(op_cmp32,GetRegPtr(has_jcond?reg_pc_dyn:reg_sr_T),BlockType&1); + + x86_Label* noBranch=x86e->CreateLabel(0,8); + + x86e->Emit(op_jne,noBranch); + { + //branch block + if (pBranchBlock) + x86e->Emit(op_jmp,x86_ptr_imm(pBranchBlock->code)); + else + x86e->Emit(op_call,x86_ptr_imm(ngen_LinkBlock_cond_Branch_stub)); + } + x86e->MarkLabel(noBranch); + { + //no branch block + if (pNextBlock) + x86e->Emit(op_jmp,x86_ptr_imm(pNextBlock->code)); + else + x86e->Emit(op_call,x86_ptr_imm(ngen_LinkBlock_cond_Next_stub)); + } + } + break; + + + case BET_DynamicRet: + { + //csc_pop(this); + } + case BET_DynamicCall: + case BET_DynamicJump: + { + if (relink_data==0) + { + if (pBranchBlock) + { + x86e->Emit(op_cmp32,GetRegPtr(reg_pc_dyn),pBranchBlock->addr); + x86e->Emit(op_je,x86_ptr_imm(pBranchBlock->code)); + x86e->Emit(op_call,x86_ptr_imm(ngen_LinkBlock_Generic_stub)); + } + else + { + x86e->Emit(op_cmp32,GetRegPtr(reg_pc_dyn),0xFABCDECF); + x86e->Emit(op_call,x86_ptr_imm(ngen_LinkBlock_Generic_stub)); + x86e->Emit(op_je,x86_ptr_imm(ngen_LinkBlock_Generic_stub)); + } + } + else + { + verify(pBranchBlock==0); + x86e->Emit(op_mov32,ECX,GetRegPtr(reg_pc_dyn)); + x86e->Emit(op_jmp,x86_ptr_imm(loop_no_update)); + } + } + break; + + case BET_StaticCall: + case BET_StaticJump: + { + if (pBranchBlock) + x86e->Emit(op_jmp,x86_ptr_imm(pBranchBlock->code)); + else + x86e->Emit(op_call,x86_ptr_imm(ngen_LinkBlock_Generic_stub)); + break; + } + + case BET_StaticIntr: + case BET_DynamicIntr: + if (BlockType==BET_StaticIntr) + { + x86e->Emit(op_mov32,&next_pc,NextBlock); + } + else + { + x86e->Emit(op_mov32,EAX,GetRegPtr(reg_pc_dyn)); + x86e->Emit(op_mov32,&next_pc,EAX); + } + x86e->Emit(op_call,x86_ptr_imm(UpdateINTC)); + + x86e->Emit(op_mov32,ECX,&next_pc); + + x86e->Emit(op_jmp,x86_ptr_imm(loop_no_update)); + + break; + } + + + + x86e->Generate(); + return x86e->x86_indx; +} + + +/* + //10 + R S8 B,M + R S16 B,M + R I32 B,M + R F32 B,M + R F32v2 B{,M} + + //13 + W I8 B,M + W I16 B,M + W I32 B,S,M + W F32 B,S,M + W F32v2 B,S{,M} +*/ + +extern u8* virt_ram_base; +#include "hw/sh4/sh4_mmr.h" + +enum mem_op_type +{ + SZ_8, + SZ_16, + SZ_32I, + SZ_32F, + SZ_64F, +}; + +void gen_hande(u32 w, u32 sz, u32 mode) +{ + static const x86_ptr_imm rwm[2][5]= + { + {x86_ptr_imm(&_vmem_ReadMem8SX32),x86_ptr_imm(&_vmem_ReadMem16SX32),x86_ptr_imm(&ReadMem32),x86_ptr_imm(&ReadMem32),x86_ptr_imm(&ReadMem64),}, + {x86_ptr_imm(&WriteMem8),x86_ptr_imm(&WriteMem16),x86_ptr_imm(&WriteMem32),x86_ptr_imm(&WriteMem32),x86_ptr_imm(&WriteMem64),} + }; + + static const x86_opcode_class opcl_i[2][3]= + { + {op_movsx8to32,op_movsx16to32,op_mov32}, + {op_mov8,op_mov16,op_mov32} + }; + + u32 si=x86e->x86_indx; + + if (mode==0) + { + //Buffer + x86e->Emit(op_mov32,EAX,ECX); + x86e->Emit(op_and32,ECX,0x1FFFFFFF); + + x86_mrm_t buff=x86_mrm(ECX,virt_ram_base); + x86_mrm_t buff4=x86_mrm(ECX,virt_ram_base+4); + + if (sz==SZ_8 || sz==SZ_16 || sz==SZ_32I) + { + if (w==0) + x86e->Emit(opcl_i[w][sz],sz==SZ_8?AL:sz==SZ_16?AX:EAX,buff); + else + x86e->Emit(opcl_i[w][sz],buff,sz==SZ_8?DL:sz==SZ_16?DX:EDX); + } + else + { + if (w==0) + { + x86e->Emit(op_movss,XMM0,buff); + if (sz==SZ_64F) + x86e->Emit(op_movss,XMM1,buff4); + } + else + { + x86e->Emit(op_movss,buff,XMM0); + if (sz==SZ_64F) + x86e->Emit(op_movss,buff4,XMM1); + } + } + } + else if (mode==1) + { + //SQ + verify(w==1); + x86e->Emit(op_mov32,EAX,ECX); + x86e->Emit(op_and32,ECX,0x3f); + + x86e->Emit(op_shr32,EAX,26); + x86e->Emit(op_cmp32,EAX,0x38); + x86_Label* l=x86e->CreateLabel(false,8); + x86e->Emit(op_je,l); + x86e->Emit(op_int3); + x86e->MarkLabel(l); + + if (sz==SZ_32I) + x86e->Emit(op_mov32,x86_mrm(ECX,sq_both),EDX); + else if (sz==SZ_32F || sz==SZ_64F) + { + x86e->Emit(op_movss,x86_mrm(ECX,sq_both),XMM0); + if (sz==SZ_64F) + x86e->Emit(op_movss,x86_mrm(ECX,sq_both+4),XMM1); + } + else + { + die("Can't happen\n"); + } + } + else + { + //General + + if ((sz==SZ_32F || sz==SZ_64F) && w==1) + { + if (sz==SZ_32F) + { + x86e->Emit(op_movd_xmm_to_r32,EDX,XMM0); + } + else + { + x86e->Emit(op_sub32,ESP,8); + x86e->Emit(op_movss,x86_mrm(ESP,x86_ptr::create(+4)),XMM1); + x86e->Emit(op_movss,x86_mrm(ESP,x86_ptr::create(-0)),XMM0); + } + } + + x86e->Emit(op_call,rwm[w][sz]); + + if ((sz==SZ_32F || sz==SZ_64F) && w==0) + { + x86e->Emit(op_movd_xmm_from_r32,XMM0,EAX); + if (sz==SZ_64F) + { + x86e->Emit(op_movd_xmm_from_r32,XMM1,EDX); + } + } + } + + x86e->Emit(op_ret); + + emit_Skip(x86e->x86_indx-si); +} + +unat mem_code_base=0; +unat mem_code_end=0; +void* mem_code[3][2][5]; + +void ngen_init() +{ + //Setup emitter + x86e = new x86_block(); + x86e->Init(0,0); + x86e->x86_buff=(u8*)emit_GetCCPtr(); + x86e->x86_size=emit_FreeSpace(); + x86e->do_realloc=false; + + + mem_code_base=(unat)emit_GetCCPtr(); + + for (int sz=0;sz<5;sz++) + { + for (int w=0;w<2;w++) + { + for (int m=0;m<3;m++) + { + if (m==1 && (sz<=SZ_16 || w==0)) + continue; + + mem_code[m][w][sz]=emit_GetCCPtr(); + gen_hande(w,sz,m); + } + } + } + + mem_code_end=(unat)emit_GetCCPtr(); + + x86e->Generate(); + + delete x86e; + + emit_SetBaseAddr(); +} + +void ngen_ResetBlocks() +{ +} + +void ngen_GetFeatures(ngen_features* dst) +{ + dst->InterpreterFallback=false; + dst->OnlyDynamicEnds=false; +} + + +RuntimeBlockInfo* ngen_AllocateBlock() +{ + return new DynaRBI(); +} + + +bool ngen_Rewrite(unat& addr,unat retadr,unat acc) +{ + if (addr>=mem_code_base && addrInit(0,0); + x86e->x86_buff=(u8*)retadr-5; + x86e->x86_size=emit_FreeSpace(); + x86e->do_realloc=false; + + for (int i=0;i<5;i++) + { + for (int w=0;w<2;w++) + { + if ((u32)mem_code[0][w][i]==ca) + { + //found ! + + if ((acc >> 26) == 0x38) //sq ? + { + verify(w == 1); + x86e->Emit(op_call, x86_ptr_imm(mem_code[1][w][i])); + } + else + { + x86e->Emit(op_call, x86_ptr_imm(mem_code[2][w][i])); + } + + x86e->Generate(); + delete x86e; + + addr=retadr-5; + + //printf("Patched: %08X for access @ %08X\n",addr,acc); + return true; + } + } + } + + die("Failed to match the code :(\n"); + + return false; + } + else + { + return false; + } +} +#endif diff --git a/core/rec-x86/win86_il.cpp b/core/rec-x86/win86_il.cpp new file mode 100644 index 000000000..ec6322d48 --- /dev/null +++ b/core/rec-x86/win86_il.cpp @@ -0,0 +1,1529 @@ +#include "win86_ngen.h" +#include "hw/sh4/sh4_mmr.h" +#include "hw/sh4/sh4_rom.h" + +void ngen_Bin(shil_opcode* op,x86_opcode_class natop,bool has_imm=true,bool has_wb=true) +{ + //x86e->Emit(op_mov32,EAX,op->rs1.reg_ptr()); + + verify(reg.IsAllocg(op->rs1._reg)); + verify(reg.IsAllocg(op->rd._reg)); + + if (has_wb && reg.mapg(op->rs1)!=reg.mapg(op->rd)) + { + x86e->Emit(op_mov32,reg.mapg(op->rd),reg.mapg(op->rs1)); + } + + if (has_imm && op->rs2.is_imm()) + { + x86e->Emit(natop,has_wb?reg.mapg(op->rd):reg.mapg(op->rs1),op->rs2._imm); + } + else if (op->rs2.is_r32i()) + { + verify(reg.IsAllocg(op->rs2._reg)); + + x86e->Emit(natop,has_wb?reg.mapg(op->rd):reg.mapg(op->rs1),reg.mapg(op->rs2)); + } + else + { + printf("%d \n",op->rs1.type); + verify(false); + } +} + +void ngen_fp_bin(shil_opcode* op,x86_opcode_class natop) +{ + verify(reg.IsAllocf(op->rs1)); + verify(reg.IsAllocf(op->rs2)); + verify(reg.IsAllocf(op->rd)); + + if (op->rd._reg!=op->rs1._reg) + x86e->Emit(op_movss,reg.mapf(op->rd),reg.mapf(op->rs1)); + + if (op->rs2.is_r32f()) + { + x86e->Emit(natop,reg.mapf(op->rd),reg.mapf(op->rs2)); + } + else + { + printf("%d \n",op->rs2.type); + verify(false); + } +// verify(has_wb); + //x86e->Emit(op_movss,op->rd.reg_ptr(),XMM0); +} +void ngen_Unary(shil_opcode* op,x86_opcode_class natop) +{ + verify(reg.IsAllocg(op->rs1)); + verify(reg.IsAllocg(op->rd)); + + if (reg.mapg(op->rs1)!=reg.mapg(op->rd)) + x86e->Emit(op_mov32,reg.mapg(op->rd),reg.mapg(op->rs1)); + + x86e->Emit(natop,reg.mapg(op->rd)); +} + +void* _vmem_read_const(u32 addr,bool& ismem,u32 sz); + +u32 ngen_CC_BytesPushed; +void ngen_CC_Start(shil_opcode* op) +{ + ngen_CC_BytesPushed=0; +} +void ngen_CC_Param(shil_opcode* op,shil_param* par,CanonicalParamType tp) +{ + switch(tp) + { + //push the contents + case CPT_u32: + case CPT_f32: + if (par->is_reg()) + { + if (reg.IsAllocg(*par)) + x86e->Emit(op_push32,reg.mapg(*par)); + else if (reg.IsAllocf(*par)) + { + x86e->Emit(op_sub32,ESP,4); + x86e->Emit(op_movss,x86_mrm(ESP), reg.mapf(*par)); + } + else + { + die("Must not happen !\n"); + x86e->Emit(op_push32,x86_ptr(par->reg_ptr())); + } + } + else if (par->is_imm()) + x86e->Emit(op_push,par->_imm); + else + die("invalid combination"); + ngen_CC_BytesPushed+=4; + break; + //push the ptr itself + case CPT_ptr: + verify(par->is_reg()); + + die("FAIL"); + x86e->Emit(op_push,(unat)par->reg_ptr()); + + for (u32 ri=0; ri<(*par).count(); ri++) + { + if (reg.IsAllocf(*par,ri)) + { + x86e->Emit(op_sub32,ESP,4); + x86e->Emit(op_movss,x86_mrm(ESP),reg.mapfv(*par,ri)); + } + else + { + verify(!reg.IsAllocAny((Sh4RegType)(par->_reg+ri))); + } + } + + + ngen_CC_BytesPushed+=4; + break; + + //store from EAX + case CPT_u64rvL: + case CPT_u32rv: + if (reg.IsAllocg(*par)) + x86e->Emit(op_mov32,reg.mapg(*par),EAX); + /*else if (reg.IsAllocf(*par)) + x86e->Emit(op_movd_xmm_from_r32,reg.mapf(*par),EAX);*/ + else + die("Must not happen!\n"); + break; + + case CPT_u64rvH: + if (reg.IsAllocg(*par)) + x86e->Emit(op_mov32,reg.mapg(*par),EDX); + else + die("Must not happen!\n"); + break; + + //Store from ST(0) + case CPT_f32rv: + verify(reg.IsAllocf(*par)); + x86e->Emit(op_fstp32f,x86_ptr(par->reg_ptr())); + x86e->Emit(op_movss,reg.mapf(*par),x86_ptr(par->reg_ptr())); + break; + + } +} + +void ngen_CC_Call(shil_opcode*op,void* function) +{ + reg.FreezeXMM(); + x86e->Emit(op_call,x86_ptr_imm(function)); + reg.ThawXMM(); +} +void ngen_CC_Finish(shil_opcode* op) +{ + x86e->Emit(op_add32,ESP,ngen_CC_BytesPushed); +} + +extern u32 vrml_431; +#ifdef PROF2 + +extern u32 srmls,srmlu,srmlc; +extern u32 rmls,rmlu; +extern u32 wmls,wmlu; +extern u32 vrd; +#endif + + +void DYNACALL VERIFYME(u32 addr) +{ + verify((addr>>26)==0x38); +} + +extern u8* virt_ram_base; + +/* + + ReadM + I8 GAI1 [m] + I16 GAI2 [m] + I32 GAI4 [m] + F32 GA4 [m] + F32v2 RA4 [m,m] + F32v4 RA4 [m,m,m,m] + F32v4r3i1 RA4 [m,m,m,1.0] + F32v4r3i0 RA4 [m,m,m,0.0] + + WriteM + I8 GA1 + I16 GA2 + I32 GA4 + F32 GA4 + F32v2 SA + F32v4 + F32v4s3 + F32v4s4 + + + //10 + R S8 B,M + R S16 B,M + R I32 B,M + R F32 B,M + R F32v2 B{,M} + + //13 + W I8 B,M + W I16 B,M + W I32 B,S,M + W F32 B,S,M + W F32v2 B,S{,M} +*/ + +extern void* mem_code[3][2][5]; + +void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool staging, bool optimise) +{ + switch(op->op) + { + case shop_readm: + { + void* fuct=0; + bool isram=false; + verify(op->rs1.is_imm() || op->rs1.is_r32i()); + + verify(op->rs1.is_imm() || reg.IsAllocg(op->rs1)); + verify(op->rs3.is_null() || op->rs3.is_imm() || reg.IsAllocg(op->rs3)); + + for (u32 i=0;ird.count();i++) + { + verify(reg.IsAllocAny((Sh4RegType)(op->rd._reg+i))); + } + + u32 size=op->flags&0x7f; + + if (op->rs1.is_imm()) + { + if (prof.enable) x86e->Emit(op_add32,&prof.counters.shil.readm_const,1); + void* ptr=_vmem_read_const(op->rs1._imm,isram,size); + if (isram) + { +#ifdef PROF2 + x86e->Emit(op_add32,&srmlu,1); +#endif + if (size==1) + x86e->Emit(op_movsx8to32,EAX,ptr); + else if (size==2) + x86e->Emit(op_movsx16to32,EAX,ptr); + else if (size==4) + { + x86e->Emit(op_mov32,EAX,ptr); + //this is a pretty good sieve, but its not perfect. + //whitelisting is much better, but requires side channel data + //Page locking w/ invalidation is another strategy we can try (leads to 'excessive' + //compiling. Maybe a mix of both ?), its what the mainline nulldc uses + if (optimise) + { + if (staging && !is_s8(*(u32*)ptr) && abs((int)op->rs1._imm-(int)block->addr)<=1024) + { + x86_Label* _same=x86e->CreateLabel(false,8); + x86e->Emit(op_cmp32,EAX,*(u32*)ptr); + x86e->Emit(op_je,_same); + x86e->Emit(op_and32,&op->flags,~0x40000000); + x86e->MarkLabel(_same); + + op->flags|=0x40000000; + } + else if (!staging && op->flags & 0x40000000) + { + x86_Label* _same=x86e->CreateLabel(false,8); + x86e->Emit(op_cmp32,EAX,*(u32*)ptr); + x86e->Emit(op_je,_same); + x86e->Emit(op_int3); + x86e->MarkLabel(_same); +#ifdef PROF2 + x86e->Emit(op_add32,&srmlc,1); +#endif + } + } + } + else if (size==8) + { + x86e->Emit(op_mov32,EAX,ptr); + x86e->Emit(op_mov32,EDX,(u8*)ptr+4); + } + else + { + die("Invalid mem read size"); + } + } + else + { +#ifdef PROF2 + x86e->Emit(op_add32,&srmls,1); +#endif + x86e->Emit(op_mov32,ECX,op->rs1._imm); + fuct=ptr; + } + } + else + { + x86e->Emit(op_mov32,ECX,reg.mapg(op->rs1)); + if (op->rs3.is_imm()) + { + x86e->Emit(op_add32,ECX,op->rs3._imm); + if (prof.enable) x86e->Emit(op_add32,&prof.counters.shil.readm_reg_imm,1); + } + else if (op->rs3.is_r32i()) + { + x86e->Emit(op_add32,ECX,reg.mapg(op->rs3)); + if (prof.enable) x86e->Emit(op_add32,&prof.counters.shil.readm_reg_reg,1); + } + else if (!op->rs3.is_null()) + { + die("invalid rs3"); + } + else + if (prof.enable) x86e->Emit(op_add32,&prof.counters.shil.readm_reg,1); +#if 0 + if (op->flags==0x431 || op->flags==0x440) + { + verify(!reg.IsAllocAny(op->rd)); + verify(!reg.IsAllocAny((Sh4RegType)(op->rd._reg+1))); + verify(!reg.IsAllocAny((Sh4RegType)(op->rd._reg+2))); + verify(!reg.IsAllocAny((Sh4RegType)(op->rd._reg+3))); + + x86e->Emit(op_add32,&vrml_431,1); + x86e->Emit(op_mov32,EDX,ECX); + x86e->Emit(op_and32,EDX,0x1FFFFFFF); + x86e->Emit(op_movups,XMM0,x86_mrm(EDX,x86_ptr(virt_ram_base))); + x86e->Emit(op_movaps,op->rd.reg_ptr(),XMM0); + + if (op->flags==0x431) + x86e->Emit(op_mov32,op->rd.reg_ptr()+3,0x3f800000); + else if (op->flags==0x430) + x86e->Emit(op_mov32,op->rd.reg_ptr()+3,0); + + break; + } + + bool vect=op->flags&0x80; + + if (vect) + { + u32 sz=size; + //x86e->Emit(op_add32,&cvld,sz/(op->flags&0x100?8:4)); + x86e->Emit(op_add32,&vrml_431,sz/(op->flags&0x100?8:4)*2); + verify(sz==8 || sz==12 || sz==16 || sz==32 || sz==64); + + void** vmap,** funct; + _vmem_get_ptrs(4,false,&vmap,&funct); + x86e->Emit(op_mov32,EAX,ECX); + x86e->Emit(op_shr32,EAX,24); + x86e->Emit(op_mov32,EAX,x86_mrm(EAX,sib_scale_4,vmap)); + + x86e->Emit(op_test32,EAX,~0x7F); + x86e->Emit(op_jz,x86_ptr_imm::create(op->flags)); + x86e->Emit(op_xchg32,ECX,EAX); + x86e->Emit(op_shl32,EAX,ECX); + x86e->Emit(op_shr32,EAX,ECX); + x86e->Emit(op_and32,ECX,~0x7F); + + int i=0; + for (i=0;(i+16)<=sz;i+=16) + { + x86e->Emit(op_movups,XMM0,x86_mrm(EAX,ECX,sib_scale_1,x86_ptr::create(i))); + if (op->rd._reg&3) + x86e->Emit(op_movups,op->rd.reg_ptr()+i/4,XMM0); + else + x86e->Emit(op_movaps,op->rd.reg_ptr()+i/4,XMM0); + } + for (;(i+8)<=sz;i+=8) + { + x86e->Emit(op_movlps,XMM0,x86_mrm(EAX,ECX,sib_scale_1,x86_ptr::create(i))); + x86e->Emit(op_movlps,op->rd.reg_ptr()+i/4,XMM0); + } + for (;(i+4)<=sz;i+=4) + { + x86e->Emit(op_movss,XMM0,x86_mrm(EAX,ECX,sib_scale_1,x86_ptr::create(i))); + x86e->Emit(op_movss,op->rd.reg_ptr()+i/4,XMM0); + } + + verify(i==sz); + + break; + + } + + if (optimise) + { + if (staging || op->flags&0x80000000) + { + + //opt disabled for now + op->flags|=0x80000000; + + x86_Label* _ram=x86e->CreateLabel(false,8); + void** vmap,** funct; + _vmem_get_ptrs(4,false,&vmap,&funct); + x86e->Emit(op_mov32,EAX,ECX); + x86e->Emit(op_shr32,EAX,24); + x86e->Emit(op_mov32,EAX,x86_mrm(EAX,sib_scale_4,vmap)); + + x86e->Emit(op_test32,EAX,~0x7F); + x86e->Emit(op_jnz,_ram); + + if (staging) + { + x86e->Emit(op_and32,&op->flags,~0x80000000); + } + else + { + //x86e->Emit(op_int3); + } + + x86e->MarkLabel(_ram); + } + + if ( !staging) + { + if (op->flags & 0x80000000) + { +#ifdef PROF2 + x86e->Emit(op_add32,&rmlu,1); +#endif + if (true) + { + u32 sz=op->flags&0x7f; + if (sz!=8) + { + x86e->Emit(op_mov32,EDX,ECX); + x86e->Emit(op_and32,EDX,0x1FFFFFFF); + if (sz==1) + { + x86e->Emit(op_movsx8to32,EAX,x86_mrm(EDX,x86_ptr(virt_ram_base))); + } + else if (sz==2) + { + x86e->Emit(op_movsx16to32,EAX,x86_mrm(EDX,x86_ptr(virt_ram_base))); + } + else if (sz==4) + { + x86e->Emit(op_mov32,EAX,x86_mrm(EDX,x86_ptr(virt_ram_base))); + } + isram=true; + } + } + + } +#ifdef PROF2 + else + { + x86e->Emit(op_add32,&rmls,1); + } +#endif + } + } +#endif +#if 1 + //new code ... + //yay ... + + int Lsz=0; + int sz=size; + if (sz==2) Lsz=1; + if (sz==4 && op->rd.is_r32i()) Lsz=2; + if (sz==4 && op->rd.is_r32f()) Lsz=3; + if (sz==8) Lsz=4; + + //x86e->Emit(op_int3); + + reg.FreezeXMM(); + x86e->Emit(op_call,x86_ptr_imm(mem_code[0][0][Lsz])); + reg.ThawXMM(); + + if (Lsz <= 2) + { + x86e->Emit(op_mov32, reg.mapg(op->rd), EAX); + } + else + { + x86e->Emit(op_movss, reg.mapfv(op->rd, 0), XMM0); + if (Lsz == 4) + x86e->Emit(op_movss, reg.mapfv(op->rd, 1), XMM1); + } + break; +#endif + } + + if (size<=8) + { + + if (size==8 && optimise) + { + verify(op->rd.count()==2 && reg.IsAllocf(op->rd,0) && reg.IsAllocf(op->rd,1)); + + x86e->Emit(op_mov32,EDX,ECX); + x86e->Emit(op_and32,EDX,0x1FFFFFFF); + x86e->Emit(op_movss,reg.mapfv(op->rd,0),x86_mrm(EDX,x86_ptr(virt_ram_base))); + x86e->Emit(op_movss,reg.mapfv(op->rd,1),x86_mrm(EDX,x86_ptr(4+virt_ram_base))); + break; + } + if (!isram) + { + reg.FreezeXMM(); + switch(size) + { + case 1: + if (!fuct) fuct=ReadMem8; + x86e->Emit(op_call,x86_ptr_imm(fuct)); + x86e->Emit(op_movsx8to32,EAX,EAX); + break; + case 2: + if (!fuct) fuct=ReadMem16; + x86e->Emit(op_call,x86_ptr_imm(fuct)); + x86e->Emit(op_movsx16to32,EAX,EAX); + break; + case 4: + if (!fuct) fuct=ReadMem32; + x86e->Emit(op_call,x86_ptr_imm(fuct)); + break; + case 8: + if (!fuct) fuct=ReadMem64; + x86e->Emit(op_call,x86_ptr_imm(fuct)); + break; + default: + verify(false); + } + reg.ThawXMM(); + } + + if (size!=8) + { + if (reg.IsAllocg(op->rd)) + x86e->Emit(op_mov32,reg.mapg(op->rd),EAX); + else if (reg.IsAllocf(op->rd)) + x86e->Emit(op_movd_xmm_from_r32,reg.mapf(op->rd),EAX); + else + x86e->Emit(op_mov32,op->rd.reg_ptr(),EAX); + } + else + { + verify(op->rd.count()==2 && reg.IsAllocf(op->rd,0) && reg.IsAllocf(op->rd,1)); + + x86e->Emit(op_movd_xmm_from_r32,reg.mapfv(op->rd,0),EAX); + x86e->Emit(op_movd_xmm_from_r32,reg.mapfv(op->rd,1),EDX); + } + + } + } + break; + + case shop_writem: + { + u32 size=op->flags&0x7f; + verify(reg.IsAllocg(op->rs1) || op->rs1.is_imm()); + + verify(op->rs2.is_r32() || (op->rs2.count()==2 && reg.IsAllocf(op->rs2,0) && reg.IsAllocf(op->rs2,1))); + + if (op->rs1.is_imm() && size<=4) + { + if (prof.enable) x86e->Emit(op_add32,&prof.counters.shil.readm_const,1); + bool isram; + void* ptr=_vmem_read_const(op->rs1._imm,isram,size); + if (isram) + { + if (size<=2) + x86e->Emit(op_mov32,EAX,reg.mapg(op->rs2)); + if (size==1) + x86e->Emit(op_mov8,ptr,EAX); + else if (size==2) + x86e->Emit(op_mov16,ptr,EAX); + else if (size==4) + { + if (op->rs2.is_r32i()) + x86e->Emit(op_mov32,ptr,reg.mapg(op->rs2)); + else + x86e->Emit(op_movss,ptr,reg.mapf(op->rs2)); + } + + else if (size==8) + { + die("A"); + } + else + die("Invalid mem read size"); + + goto done_writem; + } + else + x86e->Emit(op_mov32,ECX,op->rs1._imm); + } + else + { + x86e->Emit(op_mov32,ECX,reg.mapg(op->rs1)); + } + + if (op->rs3.is_imm()) + { + x86e->Emit(op_add32,ECX,op->rs3._imm); + } + else if (op->rs3.is_r32i()) + { + verify(reg.IsAllocg(op->rs3)); + x86e->Emit(op_add32,ECX,reg.mapg(op->rs3)); + } + else if (!op->rs3.is_null()) + { + printf("rs3: %08X\n",op->rs3.type); + die("invalid rs3"); + } + +#if 1 + //new code ... + //yay ... + + int Lsz=0; + int sz=size; + if (sz==2) Lsz=1; + if (sz==4 && op->rs2.is_r32i()) Lsz=2; + if (sz==4 && op->rs2.is_r32f()) Lsz=3; + if (sz==8) Lsz=4; + + //x86e->Emit(op_int3); + //if (Lsz==0) + { + + if (Lsz<=2) + x86e->Emit(op_mov32,EDX,reg.mapg(op->rs2)); + else + { + x86e->Emit(op_movss,XMM0,reg.mapfv(op->rs2,0)); + if (Lsz==4) + x86e->Emit(op_movss,XMM1,reg.mapfv(op->rs2,1)); + } + + reg.FreezeXMM(); + x86e->Emit(op_call,x86_ptr_imm(mem_code[2][1][Lsz])); + reg.ThawXMM(); + + break; + } +#endif + + die("woohoo"); + /* + if (size==8 && optimise) + { + verify(!reg.IsAllocAny(op->rd)); + verify(!reg.IsAllocAny((Sh4RegType)(op->rd._reg+1))); + + x86e->Emit(op_mov32,EDX,ECX); + x86e->Emit(op_and32,EDX,0x1FFFFFFF); + x86e->Emit(op_movlps,XMM0,op->rs2.reg_ptr()); + x86e->Emit(op_movlps,x86_mrm(EDX,x86_ptr(virt_ram_base)),XMM0); + break; + }*/ + + bool vect=op->flags&0x80; + + if (!vect && size<=8) + { + if (size!=8) + { + if (reg.IsAllocg(op->rs2)) + { + x86e->Emit(op_mov32,EDX,reg.mapg(op->rs2)); + } + else if (reg.IsAllocf(op->rs2)) + { + x86e->Emit(op_movd_xmm_to_r32,EDX,reg.mapf(op->rs2)); + } + else + { + die("Must not happen\n"); + } + } + else + { + verify(op->rs2.count()==2 && reg.IsAllocf(op->rs2,0) && reg.IsAllocf(op->rs2,1)); + + x86e->Emit(op_sub32,ESP,8); + //[ESP+4]=rs2[1]//-4 +8= +4 + //[ESP+0]=rs2[0]//-8 +8 = 0 + x86e->Emit(op_movss,x86_mrm(ESP,x86_ptr::create(+4)),reg.mapfv(op->rs2,1)); + x86e->Emit(op_movss,x86_mrm(ESP,x86_ptr::create(-0)),reg.mapfv(op->rs2,0)); + } + + + + if (optimise) + { + if (staging || op->flags&0x80000000) + { + + //opt disabled for now + op->flags|=0x80000000; + x86_Label* _ram=x86e->CreateLabel(false,8); + void** vmap,** funct; + _vmem_get_ptrs(4,false,&vmap,&funct); + x86e->Emit(op_mov32,EAX,ECX); + x86e->Emit(op_shr32,EAX,24); + x86e->Emit(op_mov32,EAX,x86_mrm(EAX,sib_scale_4,vmap)); + + x86e->Emit(op_test32,EAX,~0x7F); + x86e->Emit(op_jnz,_ram); + + if (staging) + { + x86e->Emit(op_and32,&op->flags,~0x80000000); + } + else + { + //x86e->Emit(op_int3); + } + + x86e->MarkLabel(_ram); + } + + + if (!staging) + { + if (op->flags & 0x80000000) + { +#ifdef PROF2 + x86e->Emit(op_add32,&wmlu,1); +#endif + if (false && size<4) + { + x86e->Emit(op_mov32,EAX,ECX); + x86e->Emit(op_and32,EAX,0x1FFFFFFF); + + if (size==1) + { + x86e->Emit(op_mov8,x86_mrm(EAX,x86_ptr(virt_ram_base)),EDX); + } + else if (size==2) + { + x86e->Emit(op_mov16,x86_mrm(EAX,x86_ptr(virt_ram_base)),EDX); + } + else if (size==4) + { + x86e->Emit(op_mov32,x86_mrm(EAX,x86_ptr(virt_ram_base)),EAX); + } + break; + } + + } +#ifdef PROF2 + else + x86e->Emit(op_add32,&wmls,1); +#endif + } + } + } + + if (vect) + { + u32 sz=op->flags&0x7f; + x86e->Emit(op_add32,&vrml_431,sz/(op->flags&0x100?8:4)*5); + verify(sz==8 || sz==12 || sz==16 || sz==32 || sz==64); + + void** vmap,** funct; + _vmem_get_ptrs(4,false,&vmap,&funct); + x86e->Emit(op_mov32,EAX,ECX); + x86e->Emit(op_shr32,EAX,24); + x86e->Emit(op_mov32,EAX,x86_mrm(EAX,sib_scale_4,vmap)); + + x86e->Emit(op_test32,EAX,~0x7F); + x86e->Emit(op_jz,x86_ptr_imm::create(op->flags)); + x86e->Emit(op_xchg32,ECX,EAX); + x86e->Emit(op_shl32,EAX,ECX); + x86e->Emit(op_shr32,EAX,ECX); + x86e->Emit(op_and32,ECX,~0x7F); + + u32 i=0; + for (; (i+16)<=sz; i+=16) + { + if (op->rs2._reg&3) + x86e->Emit(op_movups,XMM0,op->rs2.reg_ptr()+i/4); + else + x86e->Emit(op_movaps,XMM0,op->rs2.reg_ptr()+i/4); + + x86e->Emit(op_movups,x86_mrm(EAX,ECX,sib_scale_1,x86_ptr::create(i)),XMM0); + } + for (; (i+8)<=sz; i+=8) + { + x86e->Emit(op_movlps,XMM0,op->rs2.reg_ptr()+i/4); + x86e->Emit(op_movlps,x86_mrm(EAX,ECX,sib_scale_1,x86_ptr::create(i)),XMM0); + } + for (; (i+4)<=sz; i+=4) + { + x86e->Emit(op_movss,XMM0,op->rs2.reg_ptr()+i/4); + x86e->Emit(op_movss,x86_mrm(EAX,ECX,sib_scale_1,x86_ptr::create(i)),XMM0); + } + + verify(i==sz); + } + else + { + + reg.FreezeXMM(); + switch(size) + { + case 1: + x86e->Emit(op_call,x86_ptr_imm(&WriteMem8)); + break; + case 2: + x86e->Emit(op_call,x86_ptr_imm(&WriteMem16)); + break; + case 4: + x86e->Emit(op_call,x86_ptr_imm(&WriteMem32)); + break; + case 8: + x86e->Emit(op_call,x86_ptr_imm(&WriteMem64)); + break; + default: + verify(false); + } + reg.ThawXMM(); + } + } + done_writem: + break; + + case shop_ifb: + { + /* + //reg alloc should be flushed here. Add Check + for (int i=0;irs1._imm) + { + x86e->Emit(op_mov32,&next_pc,op->rs2._imm); + } + x86e->Emit(op_mov32,ECX,op->rs3._imm); +#ifdef PROF2 + x86e->Emit(op_add32,&OpDesc[op->rs3._imm]->fallbacks,1); + x86e->Emit(op_adc32,((u8*)&OpDesc[op->rs3._imm]->fallbacks)+4,0); +#endif + x86e->Emit(op_call,x86_ptr_imm(OpDesc[op->rs3._imm]->oph)); + } + break; + + case shop_jdyn: + { + + verify(reg.IsAllocg(op->rs1)); + verify(reg.IsAllocg(op->rd)); + + x86e->Emit(op_mov32,reg.mapg(op->rd),reg.mapg(op->rs1)); + if (op->rs2.is_imm()) + { + x86e->Emit(op_add32,reg.mapg(op->rd),op->rs2._imm); + } + //x86e->Emit(op_mov32,op->rd.reg_ptr(),EAX); + } + break; + + case shop_jcond: + { + verify(block->has_jcond); + verify(reg.IsAllocg(op->rs1)); + verify(reg.IsAllocg(op->rd)); + + x86e->Emit(op_mov32,reg.mapg(op->rd),reg.mapg(op->rs1)); + //x86e->Emit(op_mov32,op->rd.reg_ptr(),EAX); + } + break; + + case shop_mov64: + { + verify(op->rd.is_r64()); + verify(op->rs1.is_r64()); + + verify(reg.IsAllocf(op->rs1,0) && reg.IsAllocf(op->rs1,1)); + verify(reg.IsAllocf(op->rd,0) && reg.IsAllocf(op->rd,1)); + + + x86e->Emit(op_movaps,reg.mapfv(op->rd,0),reg.mapfv(op->rs1,0)); + x86e->Emit(op_movaps,reg.mapfv(op->rd,1),reg.mapfv(op->rs1,1)); + } + break; + + case shop_mov32: + { + verify(op->rd.is_r32()); + + if (op->rs1.is_imm()) + { + if (op->rd.is_r32i()) + { + x86e->Emit(op_mov32,reg.mapg(op->rd),op->rs1._imm); + // x86e->Emit(op_add32,&rdmt[4],1); + } + else + { + //verify(!reg.IsAllocAny(op->rd)); + x86e->Emit(op_mov32,EAX,op->rs1._imm); + x86e->Emit(op_movd_xmm_from_r32,reg.mapf(op->rd),EAX); + // x86e->Emit(op_add32,&rdmt[5],1); + } + } + else if (op->rs1.is_r32()) + { + u32 type=0; + + if (reg.IsAllocf(op->rd)) + type|=1; + + if (reg.IsAllocf(op->rs1)) + type|=2; + // x86e->Emit(op_add32,&rdmt[type],1); + switch(type) + { + case 0: //reg=reg + if (reg.mapg(op->rd) != reg.mapg(op->rs1)) + x86e->Emit(op_mov32,reg.mapg(op->rd),reg.mapg(op->rs1)); + + break; + + case 1: //xmm=reg + x86e->Emit(op_movd_xmm_from_r32,reg.mapf(op->rd),reg.mapg(op->rs1)); + break; + + case 2: //reg=xmm + x86e->Emit(op_movd_xmm_to_r32,reg.mapg(op->rd),reg.mapf(op->rs1)); + break; + + case 3: //xmm=xmm + if (reg.mapf(op->rd) != reg.mapf(op->rs1)) + x86e->Emit(op_movss,reg.mapf(op->rd),reg.mapf(op->rs1)); + else + printf("Renamed fmov !\n"); + break; + + } + } + else + { + die("Invalid mov32 size"); + } + + } + break; + +//if CANONICAL_TEST is defined all opcodes use the C-based canonical implementation ! +//#define CANONICAL_TEST 1 +#ifndef CANONICAL_TEST + case shop_and: ngen_Bin(op,op_and32); break; + case shop_or: ngen_Bin(op,op_or32); break; + case shop_xor: ngen_Bin(op,op_xor32); break; + case shop_add: ngen_Bin(op,op_add32); break; + case shop_sub: ngen_Bin(op,op_sub32); break; + case shop_ror: ngen_Bin(op,op_ror32); break; + + case shop_shl: + case shop_shr: + case shop_sar: + { + x86_opcode_class opcd[]={op_shl32,op_shr32,op_sar32}; + ngen_Bin(op,opcd[op->op-shop_shl]); + } + break; + + case shop_rocr: + case shop_rocl: + { + x86e->Emit(op_sar32,reg.mapg(op->rs2),1); + x86e->Emit(op->op==shop_rocr?op_rcr32:op_rcl32,reg.mapg(op->rd),1); + x86e->Emit(op_rcl32,reg.mapg(op->rd2),1); + } + break; + + case shop_test: + case shop_seteq: + case shop_setge: + case shop_setgt: + case shop_setae: + case shop_setab: + { + x86_opcode_class opcls1=op->op==shop_test?op_test32:op_cmp32; + x86_opcode_class opcls2[]={op_setz,op_sete,op_setge,op_setg,op_setae,op_seta }; + ngen_Bin(op,opcls1,true,false); + x86e->Emit(opcls2[op->op-shop_test],AL); + x86e->Emit(op_movzx8to32,reg.mapg(op->rd),AL); + } + break; + + case shop_adc: + { + x86e->Emit(op_sar32,reg.mapg(op->rs3),1); + if (reg.mapg(op->rd)!=reg.mapg(op->rs1)) + x86e->Emit(op_mov32,reg.mapg(op->rd),reg.mapg(op->rs1)); + x86e->Emit(op_adc32,reg.mapg(op->rd),reg.mapg(op->rs2)); + x86e->Emit(op_rcl32,reg.mapg(op->rd2),1); + } + break; + + //rd=rs1<rs1)); + verify(op->rs2.is_imm() || reg.IsAllocg(op->rs2)); + verify(reg.IsAllocg(op->rd)); + + x86_opcode_class sl32=op->op==shop_shad?op_sal32:op_shl32; + x86_opcode_class sr32=op->op==shop_shad?op_sar32:op_shr32; + + if (reg.mapg(op->rd)!=reg.mapg(op->rs1)) + x86e->Emit(op_mov32,reg.mapg(op->rd),reg.mapg(op->rs1)); + + if (op->rs2.is_imm()) + { + die("sh*d: no imms please\n"); + } + else + { + x86e->Emit(op_mov32,ECX,reg.mapg(op->rs2)); + + x86_Label* _exit=x86e->CreateLabel(false,8); + x86_Label* _neg=x86e->CreateLabel(false,8); + x86_Label* _nz=x86e->CreateLabel(false,8); + + x86e->Emit(op_cmp32,reg.mapg(op->rs2),0); + x86e->Emit(op_js,_neg); + { + //>=0 + //r[n]<<=sf; + x86e->Emit(sl32,reg.mapg(op->rd),ECX); + x86e->Emit(op_jmp,_exit); + } + x86e->MarkLabel(_neg); + x86e->Emit(op_test32,reg.mapg(op->rs2),0x1f); + x86e->Emit(op_jnz,_nz); + { + //1fh==0 + if (op->op!=shop_shad) + { + //r[n]=0; + x86e->Emit(op_mov32,reg.mapg(op->rd),0); + } + else + { + //r[n]>>=31; + x86e->Emit(op_sar32,reg.mapg(op->rd),31); + } + x86e->Emit(op_jmp,_exit); + } + x86e->MarkLabel(_nz); + { + //<0 + //r[n]>>=(-sf); + x86e->Emit(op_neg32,ECX); + x86e->Emit(sr32,reg.mapg(op->rd),ECX); + } + x86e->MarkLabel(_exit); + } + } + break; + + case shop_swaplb: + { + if (reg.mapg(op->rd)!=reg.mapg(op->rs1)) + x86e->Emit(op_mov32,reg.mapg(op->rd),reg.mapg(op->rs1)); + x86e->Emit(op_ror16,reg.mapg(op->rd),8); + } + break; + + + case shop_neg: ngen_Unary(op,op_neg32); break; + case shop_not: ngen_Unary(op,op_not32); break; + + + case shop_sync_sr: + { + //reg alloc should be flushed here. Add Check + for (int i=0;i<8;i++) + { + verify(!reg.IsAllocAny((Sh4RegType)(reg_r0+i))); + verify(!reg.IsAllocAny((Sh4RegType)(reg_r0_Bank+i))); + } + + verify(!reg.IsAllocAny(reg_old_sr_status)); + verify(!reg.IsAllocAny(reg_sr_status)); + + //reg alloc should be flushed here, add checks + x86e->Emit(op_call,x86_ptr_imm(UpdateSR)); + } + break; + + case shop_sync_fpscr: + { + //reg alloc should be flushed here. Add Check + for (int i=0;i<16;i++) + { + verify(!reg.IsAllocAny((Sh4RegType)(reg_fr_0+i))); + verify(!reg.IsAllocAny((Sh4RegType)(reg_xf_0+i))); + } + + verify(!reg.IsAllocAny(reg_old_fpscr)); + verify(!reg.IsAllocAny(reg_fpscr)); + + + //reg alloc should be flushed here, add checks + x86e->Emit(op_call,x86_ptr_imm(UpdateFPSCR)); + } + break; + + + case shop_mul_u16: + case shop_mul_s16: + case shop_mul_i32: + case shop_mul_u64: + case shop_mul_s64: + { + verify(reg.IsAllocg(op->rs1)); + verify(reg.IsAllocg(op->rs2)); + verify(reg.IsAllocg(op->rd)); + + x86_opcode_class opdt[]={op_movzx16to32,op_movsx16to32,op_mov32,op_mov32,op_mov32}; + x86_opcode_class opmt[]={op_mul32,op_mul32,op_mul32,op_mul32,op_imul32}; + //only the top 32 bits are different on signed vs unsigned + + u32 opofs=op->op-shop_mul_u16; + + x86e->Emit(opdt[opofs],EAX,reg.mapg(op->rs1)); + x86e->Emit(opdt[opofs],EDX,reg.mapg(op->rs2)); + + x86e->Emit(opmt[opofs],EDX); + x86e->Emit(op_mov32,reg.mapg(op->rd),EAX); + + if (op->op>=shop_mul_u64) + x86e->Emit(op_mov32,reg.mapg(op->rd2),EDX); + } + break; + + + //fpu + case shop_fadd: + case shop_fsub: + case shop_fmul: + case shop_fdiv: + { + verify(reg.IsAllocf(op->rs1)); + verify(reg.IsAllocf(op->rs2)); + verify(reg.IsAllocf(op->rd)); + + const x86_opcode_class opcds[]= { op_addss, op_subss, op_mulss, op_divss }; + ngen_fp_bin(op,opcds[op->op-shop_fadd]); + } + break; + + case shop_fabs: + { + verify(reg.IsAllocf(op->rs1)); + verify(reg.IsAllocf(op->rd)); + + static ALIGN(16) u32 AND_ABS_MASK[4]={0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF}; + + verify(op->rd._reg==op->rs1._reg); + x86e->Emit(op_pand,reg.mapf(op->rd),AND_ABS_MASK); + } + break; + + case shop_fneg: + { + verify(reg.IsAllocf(op->rs1)); + verify(reg.IsAllocf(op->rd)); + + static ALIGN(16) u32 XOR_NEG_MASK[4]={0x80000000,0x80000000,0x80000000,0x80000000}; + + verify(op->rd._reg==op->rs1._reg); + x86e->Emit(op_pxor,reg.mapf(op->rd),XOR_NEG_MASK); + } + break; + + case shop_fsca: + { + verify(op->rs1.is_r32i()); + + //verify(op->rd.is_vector); //double ? vector(2) ? + + verify(reg.IsAllocg(op->rs1)); + verify(reg.IsAllocf(op->rd,0) && reg.IsAllocf(op->rd,1)); + + //sin/cos + x86e->Emit(op_movzx16to32,EAX,reg.mapg(op->rs1)); + x86e->Emit(op_movss,reg.mapfv(op->rd,0),x86_mrm(EAX,sib_scale_8,x86_ptr(&sin_table->u[0]))); + x86e->Emit(op_movss,reg.mapfv(op->rd,1),x86_mrm(EAX,sib_scale_8,x86_ptr(&sin_table->u[1]))); + } + break; + + case shop_fipr: + { + //rd=rs1*rs2 (vectors) +// verify(!reg.IsAllocAny(op->rs1)); +// verify(!reg.IsAllocAny(op->rs2)); + verify(reg.IsAllocf(op->rd)); + + verify(op->rs1.is_r32fv()==4); + verify(op->rs2.is_r32fv()==4); + verify(op->rd.is_r32()); + + if (sse_3) + { + x86_reg xmm=reg.mapf(op->rd); + + x86e->Emit(op_movaps ,xmm,op->rs1.reg_ptr()); + x86e->Emit(op_mulps ,xmm,op->rs2.reg_ptr()); + //xmm0={a0 ,a1 ,a2 ,a3} + x86e->Emit(op_haddps,xmm,xmm); //xmm0={a0+a1 ,a2+a3 ,a0+a1 ,a2+a3} + x86e->Emit(op_haddps,xmm,xmm); //xmm0={(a0+a1)+(a2+a3) ,(a0+a1)+(a2+a3),(a0+a1)+(a2+a3),(a0+a1)+(a2+a3)} + } + else + { + x86_reg xmm=reg.mapf(op->rd); + + x86e->Emit(op_movaps ,xmm,op->rs1.reg_ptr()); + x86e->Emit(op_mulps ,xmm,op->rs2.reg_ptr()); + x86e->Emit(op_movhlps ,XMM1,xmm); + x86e->Emit(op_addps ,xmm,XMM1); + x86e->Emit(op_movaps ,XMM1,xmm); + x86e->Emit(op_shufps ,XMM1,XMM1,1); + x86e->Emit(op_addss ,xmm,XMM1); + } + } + break; + + case shop_fsqrt: + { + verify(reg.IsAllocf(op->rs1)); + verify(reg.IsAllocf(op->rd)); + + //rd=sqrt(rs1) + x86e->Emit(op_sqrtss ,reg.mapf(op->rd),reg.mapf(op->rs1)); + //x86e->Emit(op_movss ,op->rd.reg_ptr(),XMM0); + } + break; + + case shop_ftrv: + { +#ifdef PROF2 + x86e->Emit(op_add32,&vrd,16); +#endif + verify(!reg.IsAllocAny(op->rs1)); + verify(!reg.IsAllocAny(op->rs2)); + verify(!reg.IsAllocAny(op->rd)); + + //rd(vector)=rs1(vector)*rs2(matrix) + verify(op->rd.is_r32fv()==4); + verify(op->rs1.is_r32fv()==4); + verify(op->rs2.is_r32fv()==16); + +#if 1 + //load the vector .. + if (sse_2) + { + x86e->Emit(op_movaps ,XMM3,op->rs1.reg_ptr()); //xmm0=vector + x86e->Emit(op_pshufd ,XMM0,XMM3,0); //xmm0={v0} + x86e->Emit(op_pshufd ,XMM1,XMM3,0x55); //xmm1={v1} + x86e->Emit(op_pshufd ,XMM2,XMM3,0xaa); //xmm2={v2} + x86e->Emit(op_pshufd ,XMM3,XMM3,0xff); //xmm3={v3} + } + else + { + x86e->Emit(op_movaps ,XMM0,op->rs1.reg_ptr()); //xmm0=vector + + x86e->Emit(op_movaps ,XMM3,XMM0); //xmm3=vector + x86e->Emit(op_shufps ,XMM0,XMM0,0); //xmm0={v0} + x86e->Emit(op_movaps ,XMM1,XMM3); //xmm1=vector + x86e->Emit(op_movaps ,XMM2,XMM3); //xmm2=vector + x86e->Emit(op_shufps ,XMM3,XMM3,0xff); //xmm3={v3} + x86e->Emit(op_shufps ,XMM1,XMM1,0x55); //xmm1={v1} + x86e->Emit(op_shufps ,XMM2,XMM2,0xaa); //xmm2={v2} + } + + //do the matrix mult ! + x86e->Emit(op_mulps ,XMM0,op->rs2.reg_ptr() + 0); //v0*=vm0 + x86e->Emit(op_mulps ,XMM1,op->rs2.reg_ptr() + 4); //v1*=vm1 + x86e->Emit(op_mulps ,XMM2,op->rs2.reg_ptr() + 8); //v2*=vm2 + x86e->Emit(op_mulps ,XMM3,op->rs2.reg_ptr() + 12); //v3*=vm3 + + x86e->Emit(op_addps ,XMM0,XMM1); //sum it all up + x86e->Emit(op_addps ,XMM2,XMM3); + x86e->Emit(op_addps ,XMM0,XMM2); + + x86e->Emit(op_movaps ,op->rd.reg_ptr(),XMM0); +#else + /* + AABB CCDD + + ABCD * 0 1 2 3 0 1 4 5 + 4 5 6 7 2 3 6 7 + 8 9 a b 8 9 c d + c d e f a b e f + */ + + x86e->Emit(op_movaps ,XMM1,op->rs1.reg_ptr()); //xmm1=vector + + x86e->Emit(op_pshufd ,XMM0,XMM1,0x05); //xmm0={v0,v0,v1,v1} + x86e->Emit(op_pshufd ,XMM1,XMM1,0xaf); //xmm1={v2,v2,v3,v3} + + x86e->Emit(op_movaps,XMM2,XMM0); //xmm2={v0,v0,v1,v1} + x86e->Emit(op_movaps,XMM3,XMM1); //xmm3={v2,v2,v3,v3} + + x86e->Emit(op_mulps ,XMM0,op->rs2.reg_ptr() + 0); //aabb * 0145 + x86e->Emit(op_mulps ,XMM2,op->rs2.reg_ptr() + 4); //aabb * 2367 + x86e->Emit(op_mulps ,XMM1,op->rs2.reg_ptr() + 8); //ccdd * 89cd + x86e->Emit(op_mulps ,XMM3,op->rs2.reg_ptr() + 12); //ccdd * abef + + + x86e->Emit(op_addps ,XMM0,XMM1); //sum it all up + x86e->Emit(op_addps ,XMM2,XMM3); + + //XMM0 -> A0C8 | A1C9 | B4DC | B5DD + verify(sse_3); + + x86e->Emit(op_shufps,XMM0,XMM0,0x27); //A0C8 B4DC A1C9 B5DC + x86e->Emit(op_shufps,XMM2,XMM2,0x27); + + x86e->Emit(op_haddps,XMM0,XMM2); //haddps ={a0+a1 ,a2+a3 ,b0+b1 ,b2+b3} + + + x86e->Emit(op_movaps ,op->rd.reg_ptr(),XMM0); +#endif + } + break; + + case shop_fmac: + { + verify(reg.IsAllocf(op->rs1)); + verify(reg.IsAllocf(op->rs2)); + verify(reg.IsAllocf(op->rs3)); + verify(reg.IsAllocf(op->rd)); + + //rd=rs1+rs2*rs3 + //rd might be rs1,rs2 or rs3, so can't prestore here (iirc, rd==rs1==fr0) + x86e->Emit(op_movss ,XMM0,reg.mapf(op->rs2)); + x86e->Emit(op_mulss ,XMM0,reg.mapf(op->rs3)); + x86e->Emit(op_addss ,XMM0,reg.mapf(op->rs1)); + x86e->Emit(op_movss ,reg.mapf(op->rd),XMM0); + } + break; + + case shop_fsrra: + { + verify(reg.IsAllocf(op->rs1)); + verify(reg.IsAllocf(op->rd)); + + //rd=1/sqrt(rs1) + static float one=1.0f; + x86e->Emit(op_sqrtss ,XMM0,reg.mapf(op->rs1)); + x86e->Emit(op_movss ,reg.mapf(op->rd),&one); + x86e->Emit(op_divss ,reg.mapf(op->rd),XMM0); + } + break; + + case shop_fseteq: + case shop_fsetgt: + { + verify(reg.IsAllocf(op->rs1)); + verify(reg.IsAllocf(op->rs2)); + verify(reg.IsAllocg(op->rd)); + + //x86e->Emit(op_movss,XMM0,op->rs1.reg_ptr()); + x86e->Emit(op_ucomiss,reg.mapf(op->rs1),reg.mapf(op->rs2)); + + if (op->op==shop_fseteq) + { + //special case + //We want to take in account the 'unordered' case on the fpu + x86e->Emit(op_lahf); + x86e->Emit(op_test8,AH,0x44); + x86e->Emit(op_setnp,AL); + } + else + { + x86e->Emit(op_seta,AL); + } + + x86e->Emit(op_movzx8to32,reg.mapg(op->rd),AL); + } + break; + + case shop_pref: + { + verify(op->rs1.is_r32i()); + verify(reg.IsAllocg(op->rs1)); + + if (op->flags==0x1337) + { + // + x86e->Emit(op_mov32 ,ECX,reg.mapg(op->rs1)); + x86e->Emit(op_call,x86_ptr_imm(&VERIFYME)); //call do_sqw_mmu + } + + x86e->Emit(op_mov32 ,EDX,reg.mapg(op->rs1)); + x86e->Emit(op_mov32 ,ECX,reg.mapg(op->rs1)); + x86e->Emit(op_shr32 ,EDX,26); + + x86_Label* nosq=x86e->CreateLabel(false,8); + + x86e->Emit(op_cmp32,EDX,0x38); + x86e->Emit(op_jne,nosq); + { + if (CCN_MMUCR.AT) + x86e->Emit(op_call,x86_ptr_imm(&do_sqw_mmu)); //call do_sqw_mmu + else + { + x86e->Emit(op_mov32 ,EDX,(u32)sq_both); + x86e->Emit(op_call32,x86_ptr(&do_sqw_nommu)); //call [do_sqw_nommu] + } + } + x86e->MarkLabel(nosq); + } + break; + + case shop_ext_s8: + case shop_ext_s16: + { + verify(op->rd.is_r32i()); + verify(op->rs1.is_r32i()); + + verify(reg.IsAllocg(op->rd)); + verify(reg.IsAllocg(op->rs1)); + + x86e->Emit(op_mov32,EAX,reg.mapg(op->rs1)); + + if (op->op==shop_ext_s8) + x86e->Emit(op_movsx8to32,reg.mapg(op->rd),EAX); + else + x86e->Emit(op_movsx16to32,reg.mapg(op->rd),EAX); + } + break; + + case shop_cvt_f2i_t: + verify(op->rd.is_r32i()); + verify(op->rs1.is_r32f()); + verify(reg.IsAllocg(op->rd)); + verify(reg.IsAllocf(op->rs1)); + + x86e->Emit(op_cvttss2si,reg.mapg(op->rd),reg.mapf(op->rs1)); + break; + + //i hope that the round mode bit is set properly here :p + case shop_cvt_i2f_n: + case shop_cvt_i2f_z: + verify(op->rd.is_r32f()); + verify(op->rs1.is_r32i()); + verify(reg.IsAllocf(op->rd)); + verify(reg.IsAllocg(op->rs1)); + + x86e->Emit(op_cvtsi2ss,reg.mapf(op->rd),reg.mapg(op->rs1)); + //x86e->Emit(op_movss,op->rd.reg_ptr(),XMM0); + break; + + case shop_frswap: + { + verify(op->rd._reg==op->rs2._reg); + verify(op->rd2._reg==op->rs1._reg); + + verify(op->rs1.count()==16 && op->rs2.count()==16); + verify(op->rd2.count()==16 && op->rd.count()==16); +#ifdef PROF2 + x86e->Emit(op_add32,&vrd,32); +#endif + for (int i=0;i<4;i++) + { + x86e->Emit(op_movaps,XMM0,op->rs1.reg_ptr()+i*4); + x86e->Emit(op_movaps,XMM1,op->rs2.reg_ptr()+i*4); + x86e->Emit(op_movaps,op->rd.reg_ptr()+i*4,XMM0); + x86e->Emit(op_movaps,op->rd2.reg_ptr()+i*4,XMM1); + } + } + break; + + case shop_div32s: + case shop_div32u: + { + x86e->Emit(op_mov32,EAX,reg.mapg(op->rs1)); + if (op->op==shop_div32s) + x86e->Emit(op_cdq); + else + x86e->Emit(op_xor32,EDX,EDX); + + x86e->Emit(op->op==shop_div32s?op_idiv32:op_div32,reg.mapg(op->rs2)); + + x86e->Emit(op_mov32,reg.mapg(op->rd),EAX); + x86e->Emit(op_mov32,reg.mapg(op->rd2),EDX); + } + break; + + case shop_div32p2: + { + x86e->Emit(op_xor32,EAX,EAX); + x86e->Emit(op_cmp32,reg.mapg(op->rs3),0); + x86e->Emit(op_cmove32,EAX,reg.mapg(op->rs2)); + if (reg.mapg(op->rd)!=reg.mapg(op->rs1)) + x86e->Emit(op_mov32,reg.mapg(op->rd),reg.mapg(op->rs1)); + + x86e->Emit(op_sub32,reg.mapg(op->rd),EAX); + } + break; + + +#endif + + default: +#if 1 || CANONICAL_TEST + shil_chf[op->op](op); + break; +#endif + + +defaulty: + printf("OH CRAP %d\n",op->op); + verify(false); + } +} \ No newline at end of file diff --git a/core/rec-x86/win86_ngen.cpp b/core/rec-x86/win86_ngen.cpp new file mode 100644 index 000000000..64986ec51 --- /dev/null +++ b/core/rec-x86/win86_ngen.cpp @@ -0,0 +1,128 @@ +#include "win86_ngen.h" + +#if HOST_OS == OS_WINDOWS + +naked void ngen_LinkBlock_Shared_stub() +{ + __asm + { + pop ecx; + sub ecx,5; + call rdv_LinkBlock; + jmp eax; + } +} + +naked void ngen_LinkBlock_cond_Next_stub() +{ + __asm + { + mov edx,0 + jmp ngen_LinkBlock_Shared_stub; + } +} +naked void ngen_LinkBlock_cond_Branch_stub() +{ + __asm + { + mov edx,1 + jmp ngen_LinkBlock_Shared_stub; + } +} + +const u32 offs=offsetof(Sh4RCB,cntx.jdyn); +naked void ngen_LinkBlock_Generic_stub() +{ + __asm + { + mov edx,[p_sh4rcb]; + add edx,[offs]; + mov edx,[edx]; + jmp ngen_LinkBlock_Shared_stub; + } +} + + + + +naked void ngen_FailedToFindBlock_() +{ + __asm + { + mov ecx,esi; + call rdv_FailedToFindBlock; + jmp eax; + } +} + +void (*ngen_FailedToFindBlock)()=&ngen_FailedToFindBlock_; +naked void ngen_mainloop(void* cntx) +{ + __asm + { + push esi; + push edi; + push ebp; + push ebx; + + mov ecx,0xA0000000; + mov [cycle_counter],SH4_TIMESLICE; + + mov [loop_no_update],offset no_update; + mov [intc_sched],offset intc_sched_offs; + + mov eax,0; + //next_pc _MUST_ be on ecx +no_update: + mov esi,ecx; + call bm_GetCode + jmp eax; + +intc_sched_offs: + add [cycle_counter],SH4_TIMESLICE; + call UpdateSystem; + cmp eax,0; + jnz do_iter; + ret; + +do_iter: + pop ecx; + call rdv_DoInterrupts; + mov ecx,eax; +// cmp byte ptr [sh4_int_bCpuRun],0; + // jz cleanup; + jmp no_update; + +cleanup: + pop ebx; + pop ebp; + pop edi; + pop esi; + + ret; + } +} + + +naked void DYNACALL ngen_blockcheckfail(u32 addr) +{ + __asm + { + call rdv_BlockCheckFail; + jmp eax; + } +} + +naked void DYNACALL ngen_blockcheckfail2(u32 addr) +{ + __asm + { + int 3; + call rdv_BlockCheckFail; + jmp eax; + } +} +#else + u32 gas_offs=offsetof(Sh4RCB,cntx.jdyn); + void (*ngen_FailedToFindBlock)()=&ngen_FailedToFindBlock_; +#endif \ No newline at end of file diff --git a/core/rec-x86/win86_ngen.h b/core/rec-x86/win86_ngen.h new file mode 100644 index 000000000..680e9cc5c --- /dev/null +++ b/core/rec-x86/win86_ngen.h @@ -0,0 +1,59 @@ +#include "types.h" + +#include "hw/sh4/sh4_opcode_list.h" +#include "hw/sh4/modules/ccn.h" +#include "hw/sh4/sh4_interrupts.h" + +#include "hw/sh4/sh4_core.h" +#include "hw/sh4/dyna/ngen.h" +#include "hw/sh4/sh4_mem.h" +#include "hw/sh4/dyna/regalloc.h" +#include "emitter/x86_emitter.h" +#include "profiler/profiler.h" +#include "oslib/oslib.h" + +void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool staging, bool optimise); + +#if BUILD_COMPILER == COMPILER_GCC +extern "C" +{ +#endif + +void ngen_LinkBlock_Generic_stub(); +void ngen_LinkBlock_cond_Next_stub(); +void ngen_LinkBlock_cond_Branch_stub(); +void ngen_FailedToFindBlock_(); +void ngen_mainloop(void* p); + + +void DYNACALL ngen_blockcheckfail(u32 addr); +void DYNACALL ngen_blockcheckfail2(u32 addr); + +#if BUILD_COMPILER == COMPILER_GCC +} +#endif + +extern x86_block* x86e; + +extern u32 cycle_counter; + +extern void* loop_no_update; +extern void* intc_sched; + +extern bool sse_1; +extern bool sse_2; +extern bool sse_3; +extern bool ssse_3; +extern bool mmx; + +struct x86_reg_alloc: RegAlloc +{ + virtual void Preload(u32 reg,x86_reg nreg); + virtual void Writeback(u32 reg,x86_reg nreg); + virtual void Preload_FPU(u32 reg,x86_reg nreg); + virtual void Writeback_FPU(u32 reg,x86_reg nreg); + void FreezeXMM(); + void ThawXMM(); +}; + +extern x86_reg_alloc reg; diff --git a/core/types.h b/core/types.h index 2fe4c8172..2d4c54e0f 100644 --- a/core/types.h +++ b/core/types.h @@ -13,8 +13,10 @@ #if BUILD_COMPILER==COMPILER_VC #define DYNACALL __fastcall +#define DYNACALL_T #else -#define DYNACALL __attribute__((fastcall)) +#define DYNACALL +#define DYNACALL_T __attribute__((fastcall)) #endif #if BUILD_COMPILER==COMPILER_VC diff --git a/shell/lin86/Makefile b/shell/lin86/Makefile index 8e3bb792a..873a2cda8 100644 --- a/shell/lin86/Makefile +++ b/shell/lin86/Makefile @@ -20,7 +20,7 @@ LD=${CC} MFLAGS := -m32 #-marm -march=armv7-a -mtune=cortex-a9 -mfpu=neon -mfloat-abi=softfp -funroll-loops -ASFLAGS := -m32 +ASFLAGS := -32 #-march=armv7-a -mfpu=neon -mfloat-abi=softfp LDFLAGS := -m32 -g -Wl,-Map,$(notdir $@).map,--gc-sections -Wl,-O3 -Wl,--sort-common @@ -81,7 +81,6 @@ PACKAGE_FILES=$(EXECUTABLE_STRIPPED) default.gcw0.desktop icon-32.png all: $(CPPFILES) $(EXECUTABLE) $(EXECUTABLE_STRIPPED) $(EXECUTABLE): $(OBJECTS) - echo $(RZDCY_FILES) $(CXX) $(MFLAGS) $(EXTRAFLAGS) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $@ $(EXECUTABLE_STRIPPED): $(EXECUTABLE) From f14932c362b91ceb75e3d6c0b052e97d3e073a3f Mon Sep 17 00:00:00 2001 From: Stefanos Kornilios Mitsis Poiitids Date: Tue, 30 Sep 2014 12:00:46 +0300 Subject: [PATCH 03/20] Building on osx w/o rec or rend --- core/deps/coreio/coreio.cpp | 4 +- core/hw/mem/_vmem.cpp | 16 ++++-- core/hw/pvr/Renderer_if.cpp | 2 +- core/hw/pvr/Renderer_if.h | 8 ++- core/hw/pvr/ta_vtx.cpp | 2 +- core/linux-dist/main.cpp | 22 +++++--- core/linux/common.cpp | 16 ++++-- core/linux/nixprof.cpp | 2 +- core/nullDC.cpp | 2 +- core/rend/norend/norend.cpp | 10 +++- core/rend/rend.h | 10 +++- core/stdclass.h | 3 +- shell/mac86/Makefile | 102 ++++++++++++++++++++++++++++++++++++ 13 files changed, 174 insertions(+), 25 deletions(-) create mode 100644 shell/mac86/Makefile diff --git a/core/deps/coreio/coreio.cpp b/core/deps/coreio/coreio.cpp index afc54e905..f726bb17c 100644 --- a/core/deps/coreio/coreio.cpp +++ b/core/deps/coreio/coreio.cpp @@ -17,7 +17,7 @@ #include #include #include - #include + #include #include #include #endif @@ -262,4 +262,4 @@ size_t core_fsize(core_file* fc) else { return HTTP_GET(f->host, f->port, f->path, 0, 0,0); } -} \ No newline at end of file +} diff --git a/core/hw/mem/_vmem.cpp b/core/hw/mem/_vmem.cpp index e54f6a78a..2e0239856 100644 --- a/core/hw/mem/_vmem.cpp +++ b/core/hw/mem/_vmem.cpp @@ -570,7 +570,9 @@ error: u32 sz= 512*1024*1024 + sizeof(Sh4RCB) + ARAM_SIZE + 0x10000; void* rv=mmap(0, sz, PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0); + verify(rv != NULL); munmap(rv,sz); + printf("%X\n",rv); return (u8*)rv + 0x10000 - unat(rv)%0x10000;//align to 64 KB (Needed for linaro mmap not to extend to next region) } #endif @@ -590,8 +592,13 @@ void _vmem_bm_reset() #else mprotect(p_sh4rcb, sizeof(p_sh4rcb->fpcb), PROT_NONE); madvise(p_sh4rcb,sizeof(p_sh4rcb->fpcb),MADV_DONTNEED); + #ifdef MADV_REMOVE + //Linux, Android madvise(p_sh4rcb,sizeof(p_sh4rcb->fpcb),MADV_REMOVE); - //madvise(p_sh4rcb,sizeof(p_sh4rcb->fpcb),MADV_FREE); + #else + //OSX, ? + madvise(p_sh4rcb,sizeof(p_sh4rcb->fpcb),MADV_FREE); + #endif #endif printf("Freeing fpcb\n"); @@ -631,6 +638,10 @@ bool _vmem_reserve() verify((sizeof(Sh4RCB)%PAGE_SIZE)==0); virt_ram_base=(u8*)_nvmem_alloc_mem(); + + if (virt_ram_base==0) + return false; + p_sh4rcb=(Sh4RCB*)virt_ram_base; #if HOST_OS==OS_WINDOWS @@ -644,9 +655,6 @@ bool _vmem_reserve() #endif virt_ram_base+=sizeof(Sh4RCB); - if (virt_ram_base==0) - return false; - //Area 0 //[0x00000000 ,0x00800000) -> unused unused_buffer(0x00000000,0x00800000); diff --git a/core/hw/pvr/Renderer_if.cpp b/core/hw/pvr/Renderer_if.cpp index 348c7a030..d4b6e83aa 100644 --- a/core/hw/pvr/Renderer_if.cpp +++ b/core/hw/pvr/Renderer_if.cpp @@ -219,7 +219,7 @@ void rend_end_wait() bool rend_init() { -#if NO_REND +#ifdef NO_REND rend = rend_norend(); #else diff --git a/core/hw/pvr/Renderer_if.h b/core/hw/pvr/Renderer_if.h index d95fcecb3..0d181a86a 100644 --- a/core/hw/pvr/Renderer_if.h +++ b/core/hw/pvr/Renderer_if.h @@ -17,6 +17,12 @@ void rend_set_fb_scale(float x,float y); void rend_text_invl(vram_block* bl); +#ifdef GLuint +GLuint +#else +u32 +#endif +GetTexture(TSP tsp,TCW tcw); /////// @@ -43,4 +49,4 @@ struct Renderer Renderer* rend_D3D11(); Renderer* rend_GLES2(); -Renderer* rend_norend(); \ No newline at end of file +Renderer* rend_norend(); diff --git a/core/hw/pvr/ta_vtx.cpp b/core/hw/pvr/ta_vtx.cpp index 7a813b7aa..5f03bfe7a 100644 --- a/core/hw/pvr/ta_vtx.cpp +++ b/core/hw/pvr/ta_vtx.cpp @@ -8,7 +8,7 @@ #include "ta.h" #include "ta_ctx.h" #include "pvr_mem.h" -#include "rend/gles/gles.h" +//#include "rend/gles/gles.h" #include "Renderer_if.h" u32 ta_type_lut[256]; diff --git a/core/linux-dist/main.cpp b/core/linux-dist/main.cpp index 44d20c2f7..c53c05e74 100755 --- a/core/linux-dist/main.cpp +++ b/core/linux-dist/main.cpp @@ -24,7 +24,7 @@ #include #endif -#if !defined(ANDROID) +#if !defined(ANDROID) && 0 #include #include #include @@ -134,6 +134,7 @@ void SetupInput() lt[port]=0; } +#if 0 if (true) { #ifdef TARGET_PANDORA const char* device = "/dev/input/event4"; @@ -154,10 +155,10 @@ void SetupInput() else perror("evdev open"); } - +#endif // Open joystick device JoyFD = open("/dev/input/js0",O_RDONLY); - +#if 0 if(JoyFD>=0) { int AxisCount,ButtonCount; @@ -181,10 +182,12 @@ void SetupInput() printf("Using Xbox 360 map\n"); } } +#endif } bool HandleKb(u32 port) { - struct input_event ie; +#if 0 + //struct input_event ie; if (kbfd < 0) return false; @@ -278,17 +281,19 @@ bool HandleKb(u32 port) { printf("type %i key %i state %i\n", ie.type, ie.code, ie.value); } #endif - +#endif +return true; } bool HandleJoystick(u32 port) { - struct js_event JE; + //struct js_event JE; // Joystick must be connected if(JoyFD<0) return false; +#if 0 while(read(JoyFD,&JE,sizeof(JE))==sizeof(JE)) if (JE.number #include #include //#include @@ -32,6 +35,7 @@ struct sigcontext uc_mcontext; } ucontext_t; #endif + #if HOST_CPU == CPU_ARM #define GET_PC_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.arm_pc) #elif HOST_CPU == CPU_MIPS @@ -44,7 +48,7 @@ struct sigcontext uc_mcontext; #ifdef _ANDROID #define GET_PC_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.eip) #else -#define GET_PC_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.gregs[REG_EIP]) +#define GET_PC_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext->__ss.__eip) #endif #else #error fix ->pc support @@ -116,8 +120,10 @@ cResetEvent::cResetEvent(bool State,bool Auto) { //sem_init((sem_t*)hEvent, 0, State?1:0); verify(State==false&&Auto==true); - mutx = PTHREAD_MUTEX_INITIALIZER; - cond = PTHREAD_COND_INITIALIZER; + //mutx = PTHREAD_MUTEX_INITIALIZER; + pthread_mutex_init(&mutx, NULL); + //cond = PTHREAD_COND_INITIALIZER; + pthread_cond_init(&cond, NULL); } cResetEvent::~cResetEvent() { @@ -216,6 +222,10 @@ double os_GetSeconds() return a.tv_sec-tvs_base+a.tv_usec/1000000.0; } +void os_DebugBreak() +{ + __builtin_trap(); +} void enable_runfast() { diff --git a/core/linux/nixprof.cpp b/core/linux/nixprof.cpp index 7dd97db8d..0b8bb25eb 100644 --- a/core/linux/nixprof.cpp +++ b/core/linux/nixprof.cpp @@ -68,7 +68,7 @@ typedef struct ucontext_t #ifdef _ANDROID #define GET_PC_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.eip) #else -#define GET_PC_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.gregs[REG_EIP]) +#define GET_PC_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext->__ss.__eip) #endif #else #error fix ->pc support diff --git a/core/nullDC.cpp b/core/nullDC.cpp index 7d84454c0..0c537a67e 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -131,7 +131,7 @@ void plugins_Reset(bool Manual) void* webui_th(void* p) { - #if HOST_OS == OS_WINDOWS || HOST_OS == OS_LINUX + #if (HOST_OS == OS_WINDOWS || HOST_OS == OS_LINUX) && defined(WEBUI) webui_start(); #endif diff --git a/core/rend/norend/norend.cpp b/core/rend/norend/norend.cpp index 499227938..03ec7564a 100644 --- a/core/rend/norend/norend.cpp +++ b/core/rend/norend/norend.cpp @@ -7,6 +7,7 @@ void rend_text_invl(vram_block* bl) { } struct norend : Renderer { + bool Init() { return true; @@ -15,9 +16,14 @@ struct norend : Renderer void Resize(int w, int h) { } void Term() { } + + bool Process(TA_context* ctx) { return true; } + + void DrawOSD() { } + bool Render() { - return !pvrrc.isRTT; + return true;//!pvrrc.isRTT; } void Present() { } @@ -25,3 +31,5 @@ struct norend : Renderer Renderer* rend_norend() { return new norend(); } + +u32 GetTexture(TSP tsp,TCW tcw) { return 0; } diff --git a/core/rend/rend.h b/core/rend/rend.h index 25c7b56fc..3386fbdf8 100644 --- a/core/rend/rend.h +++ b/core/rend/rend.h @@ -1,3 +1,11 @@ #pragma once #include "hw/pvr/ta_ctx.h" -#include "hw/pvr/Renderer_if.h" \ No newline at end of file +#include "hw/pvr/Renderer_if.h" + + +#ifdef GLuint +GLuint +#else +u32 +#endif +GetTexture(TSP tsp,TCW tcw); diff --git a/core/stdclass.h b/core/stdclass.h index f7f351bbc..762bcaa54 100644 --- a/core/stdclass.h +++ b/core/stdclass.h @@ -220,7 +220,8 @@ public : #if HOST_OS==OS_WINDOWS InitializeCriticalSection(&cs); #else - mutx=PTHREAD_MUTEX_INITIALIZER; + //mutx=PTHREAD_MUTEX_INITIALIZER; + pthread_mutex_init ( &mutx, NULL); #endif } ~cMutex() diff --git a/shell/mac86/Makefile b/shell/mac86/Makefile new file mode 100644 index 000000000..aab1ebf97 --- /dev/null +++ b/shell/mac86/Makefile @@ -0,0 +1,102 @@ + +LOCAL_PATH := $(call my-dir) +FOR_LINUX :=1 +NOT_ARM := 1 +NO_REC := 1 +NO_REND := 1 +#WEBUI :=1 + +RZDCY_SRC_DIR = ../../core + +include $(RZDCY_SRC_DIR)/core.mk + + +CXX=${CC_PREFIX}g++ +CC=${CC_PREFIX}gcc +AS=${CC_PREFIX}as +STRIP=${CC_PREFIX}strip + +LD=${CC} + +MFLAGS := -m32 +#-marm -march=armv7-a -mtune=cortex-a9 -mfpu=neon -mfloat-abi=softfp -funroll-loops +ASFLAGS := -m32 +#-march=armv7-a -mfpu=neon -mfloat-abi=softfp + +LDFLAGS := -m32 -g + +SOURCES := cfg/ hw/arm7/ hw/aica/ hw/asic/ hw/ hw/gdrom/ hw/maple/ \ + hw/mem/ hw/pvr/ hw/sh4/ hw/sh4/rec_v2/ plugins/ profiler/ serial_ipc/ \ + hw/extdev/ hw/arm/ imgread/ linux/ linux-dist/ ./ rec-ARM/ deps/zlib/ deps/chdr/ deps/crypto/ arm_emitter/ + + +CXXFLAGS := -m32 -g -O3 -D RELEASE -c -D TARGET_LINUX_x86 -D HOST_NO_REC -D NO_REND +CXXFLAGS += -fno-strict-aliasing +CXXFLAGS += -ffast-math -ftree-vectorize +#-fprefetch-loop-arrays +#-std=c++0x + +CXXFLAGS += $(CFLAGS) $(MFLAGS) -fno-exceptions -fno-rtti +# CXXFLAGS += -D SUPPORT_X11 + + +ifdef PGO_MAKE + CXXFLAGS += -fprofile-generate -pg + LDFLAGS += -fprofile-generate +else + CXXFLAGS += -fomit-frame-pointer +endif + +ifdef PGO_USE + CXXFLAGS += -fprofile-use +endif + + +ifdef LTO_TEST + CXXFLAGS += -flto -fwhole-program + LDFLAGS +=-flto -fwhole-program +endif + +INCS := -I$(RZDCY_SRC_DIR) -I$(RZDCY_SRC_DIR)/deps -I$(RZDCY_SRC_DIR)/khronos -I../linux-deps/include + +LIBS := -L../linux-deps/lib/x86 -L./enta_viv +#LIBS += -lglapi +LIBS += -lm # -lrt -lEGL -lGLESv2 #-lglslcompiler -lIMGegl -lpvr2d -lsrv_um +LIBS += -lpthread # -lX11 -lXdmcp -lXau + + +OBJECTS=$(RZDCY_FILES:.cpp=.build_obj) +OBJECTS:=$(OBJECTS:.c=.build_obj) +OBJECTS:=$(OBJECTS:.S=.build_obj) +OBJECTS:=$(patsubst $(RZDCY_SRC_DIR)/%,obj/%,$(OBJECTS)) + + +EXECUTABLE_STRIPPED=nosym-reicast.elf +EXECUTABLE=reicast.elf + +PACKAGE_FILES=$(EXECUTABLE_STRIPPED) default.gcw0.desktop icon-32.png + +all: $(CPPFILES) $(EXECUTABLE) $(EXECUTABLE_STRIPPED) + +$(EXECUTABLE): $(OBJECTS) + echo $(RZDCY_FILES) + $(CXX) $(MFLAGS) $(EXTRAFLAGS) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $@ + +$(EXECUTABLE_STRIPPED): $(EXECUTABLE) + cp $< $@ && $(STRIP) $@ + +obj/%.build_obj : $(RZDCY_SRC_DIR)/%.cpp + mkdir -p $(dir $@) + $(CXX) $(EXTRAFLAGS) $(INCS) $(CXXFLAGS) $< -o $@ + +obj/%.build_obj : $(RZDCY_SRC_DIR)/%.c + mkdir -p $(dir $@) + $(CC) $(EXTRAFLAGS) $(INCS) $(CXXFLAGS) $< -o $@ + +obj/%.build_obj : $(RZDCY_SRC_DIR)/%.S + mkdir -p $(dir $@) + $(AS) $(ASFLAGS) $(INCS) $< -o $@ + + +clean: + rm $(OBJECTS) $(EXECUTABLE) -f From 86e2408acec652e4f3e0af361974f69af30153b0 Mon Sep 17 00:00:00 2001 From: Stefanos Kornilios Mitsis Poiitidis Date: Wed, 17 Dec 2014 03:10:18 -0800 Subject: [PATCH 04/20] wip to get ios compiling --- core/hw/mem/_vmem.cpp | 6 ++- core/hw/sh4/dyna/regalloc.h | 3 ++ core/hw/sh4/dyna/shil.cpp | 4 +- core/rec-ARM/arm_dyna.cpp | 12 ++--- core/rend/gles/gles.cpp | 2 +- shell/ios/emulator.xcodeproj/project.pbxproj | 53 +++++++++----------- shell/ios/emulator/EmulatorViewController.m | 9 +++- shell/ios/emulator/emulator-Info.plist | 2 +- shell/ios/emulator/reicast.entitlements | 5 +- 9 files changed, 52 insertions(+), 44 deletions(-) diff --git a/core/hw/mem/_vmem.cpp b/core/hw/mem/_vmem.cpp index 32125ea42..847aadec0 100644 --- a/core/hw/mem/_vmem.cpp +++ b/core/hw/mem/_vmem.cpp @@ -590,8 +590,12 @@ void _vmem_bm_reset() #else mprotect(p_sh4rcb, sizeof(p_sh4rcb->fpcb), PROT_NONE); madvise(p_sh4rcb,sizeof(p_sh4rcb->fpcb),MADV_DONTNEED); + #ifdef MADV_REMOVE madvise(p_sh4rcb,sizeof(p_sh4rcb->fpcb),MADV_REMOVE); - //madvise(p_sh4rcb,sizeof(p_sh4rcb->fpcb),MADV_FREE); + #else + //OSX, IOS + madvise(p_sh4rcb,sizeof(p_sh4rcb->fpcb),MADV_FREE); + #endif #endif printf("Freeing fpcb\n"); diff --git a/core/hw/sh4/dyna/regalloc.h b/core/hw/sh4/dyna/regalloc.h index 7e0d32cd8..ecdb5a78e 100644 --- a/core/hw/sh4/dyna/regalloc.h +++ b/core/hw/sh4/dyna/regalloc.h @@ -411,6 +411,9 @@ struct RegAlloc return all_spans[sid]; } } + + die("Failed to find span"); + return NULL; } void flush_span(u32 sid) diff --git a/core/hw/sh4/dyna/shil.cpp b/core/hw/sh4/dyna/shil.cpp index f86ba267b..f1a7b058a 100644 --- a/core/hw/sh4/dyna/shil.cpp +++ b/core/hw/sh4/dyna/shil.cpp @@ -2,6 +2,8 @@ Some WIP optimisation stuff and maby helper functions for shil */ +#include + #include "types.h" #include "shil.h" #include "decoder.h" @@ -1020,8 +1022,6 @@ bool UpdateSR(); #include "shil_canonical.h" #endif -#include - string name_reg(u32 reg) { stringstream ss; diff --git a/core/rec-ARM/arm_dyna.cpp b/core/rec-ARM/arm_dyna.cpp index 61eb30078..a7bf2289c 100755 --- a/core/rec-ARM/arm_dyna.cpp +++ b/core/rec-ARM/arm_dyna.cpp @@ -183,10 +183,10 @@ typedef ConditionCode eCC; #define rfp_r9 r9 -typedef void FPBinOP (eFSReg Sd, eFSReg Sn, eFSReg Sm, ConditionCode CC=CC_AL); -typedef void FPUnOP (eFSReg Sd, eFSReg Sm, ConditionCode CC=CC_AL); -typedef void BinaryOP (eReg Rd, eReg Rn, eReg Rm, ConditionCode CC=AL); -typedef void BinaryOPImm (eReg Rd, eReg Rn, s32 sImm8, ConditionCode CC=AL); +typedef void FPBinOP (eFSReg Sd, eFSReg Sn, eFSReg Sm, ConditionCode CC); +typedef void FPUnOP (eFSReg Sd, eFSReg Sm, ConditionCode CC); +typedef void BinaryOP (eReg Rd, eReg Rn, eReg Rm, ConditionCode CC); +typedef void BinaryOPImm (eReg Rd, eReg Rn, s32 sImm8, ConditionCode CC); typedef void UnaryOP (eReg Rd, eReg Rs); @@ -535,14 +535,14 @@ void ngen_Binary(shil_opcode* op, BinaryOP dtop,BinaryOPImm dtopimm, bool has_im dtop(reg.mapg(op->rd),reg.mapg(op->rs1), rs2, CC_AL); } -void ngen_fp_bin(shil_opcode* op, FPBinOP fpop) +void ngen_fp_bin(shil_opcode* op, const FPBinOP fpop) { verify(op->rs1.is_r32f()); verify(op->rs2.is_r32f()); fpop(reg.mapfs(op->rd),reg.mapfs(op->rs1),reg.mapfs(op->rs2),CC_AL); } -void ngen_fp_una(shil_opcode* op, FPUnOP fpop) +void ngen_fp_una(shil_opcode* op, const FPUnOP fpop) { verify(op->rd.is_r32f()); verify(op->rs1.is_r32f()); diff --git a/core/rend/gles/gles.cpp b/core/rend/gles/gles.cpp index cf9412b34..bc62b0bd7 100755 --- a/core/rend/gles/gles.cpp +++ b/core/rend/gles/gles.cpp @@ -394,7 +394,7 @@ bool gl_init(void* wind, void* disp) return false; } - gl.setup.surface = eglCreateWindowSurface(gl.setup.display, config, wind, NULL); + gl.setup.surface = eglCreateWindowSurface(gl.setup.display, config, gl.setup.native_wind, (EGLint*)NULL); if (eglCheck()) return false; diff --git a/shell/ios/emulator.xcodeproj/project.pbxproj b/shell/ios/emulator.xcodeproj/project.pbxproj index 42bc4997a..70d2bd0b9 100644 --- a/shell/ios/emulator.xcodeproj/project.pbxproj +++ b/shell/ios/emulator.xcodeproj/project.pbxproj @@ -169,7 +169,6 @@ 9C7A3B3818C806E00070BB5F /* gdi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9C7A3A6018C806E00070BB5F /* gdi.cpp */; }; 9C7A3B3918C806E00070BB5F /* ImgReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9C7A3A6118C806E00070BB5F /* ImgReader.cpp */; }; 9C7A3B3A18C806E00070BB5F /* ioctl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9C7A3A6318C806E00070BB5F /* ioctl.cpp */; }; - 9C7A3B3E18C806E00070BB5F /* nacl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9C7A3A7B18C806E00070BB5F /* nacl.cpp */; }; 9C7A3B3F18C806E00070BB5F /* nullDC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9C7A3A7C18C806E00070BB5F /* nullDC.cpp */; }; 9C7A3B4018C806E00070BB5F /* alsa_audiostream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9C7A3A7E18C806E00070BB5F /* alsa_audiostream.cpp */; }; 9C7A3B4118C806E00070BB5F /* audiostream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9C7A3A7F18C806E00070BB5F /* audiostream.cpp */; }; @@ -184,7 +183,6 @@ 9C7A3B4A18C806E00070BB5F /* gltex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9C7A3A9118C806E00070BB5F /* gltex.cpp */; }; 9C7A3B4B18C806E00070BB5F /* norend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9C7A3A9318C806E00070BB5F /* norend.cpp */; }; 9C7A3B4C18C806E00070BB5F /* TexCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9C7A3A9518C806E00070BB5F /* TexCache.cpp */; }; - 9C7A3B4D18C806E00070BB5F /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9C7A3A9818C806E00070BB5F /* main.cpp */; }; 9C7A3B4E18C806E00070BB5F /* stdclass.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9C7A3A9918C806E00070BB5F /* stdclass.cpp */; }; 9C7A3B5918C81A4F0070BB5F /* SWRevealViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C7A3B5818C81A4F0070BB5F /* SWRevealViewController.m */; }; 9C7A3B5C18C81BC80070BB5F /* SideDrawerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C7A3B5B18C81BC80070BB5F /* SideDrawerViewController.m */; }; @@ -510,7 +508,6 @@ 9C7A3A7018C806E00070BB5F /* gl3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gl3.h; sourceTree = ""; }; 9C7A3A7118C806E00070BB5F /* gl3platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gl3platform.h; sourceTree = ""; }; 9C7A3A7318C806E00070BB5F /* khrplatform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = khrplatform.h; sourceTree = ""; }; - 9C7A3A7B18C806E00070BB5F /* nacl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = nacl.cpp; sourceTree = ""; }; 9C7A3A7C18C806E00070BB5F /* nullDC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = nullDC.cpp; sourceTree = ""; }; 9C7A3A7E18C806E00070BB5F /* alsa_audiostream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = alsa_audiostream.cpp; sourceTree = ""; }; 9C7A3A7F18C806E00070BB5F /* audiostream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = audiostream.cpp; sourceTree = ""; }; @@ -531,7 +528,6 @@ 9C7A3A9418C806E00070BB5F /* rend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rend.h; sourceTree = ""; }; 9C7A3A9518C806E00070BB5F /* TexCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TexCache.cpp; sourceTree = ""; }; 9C7A3A9618C806E00070BB5F /* TexCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TexCache.h; sourceTree = ""; }; - 9C7A3A9818C806E00070BB5F /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; 9C7A3A9918C806E00070BB5F /* stdclass.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = stdclass.cpp; sourceTree = ""; }; 9C7A3A9A18C806E00070BB5F /* stdclass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stdclass.h; sourceTree = ""; }; 9C7A3A9B18C806E00070BB5F /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = types.h; sourceTree = ""; }; @@ -726,14 +722,12 @@ 9C7A39DE18C806DF0070BB5F /* hw */, 9C7A3A5A18C806E00070BB5F /* imgread */, 9C7A3A6518C806E00070BB5F /* khronos */, - 9C7A3A7A18C806E00070BB5F /* nacl */, 9C7A3A7C18C806E00070BB5F /* nullDC.cpp */, 9C7A3A7D18C806E00070BB5F /* oslib */, 9C7A3A8318C806E00070BB5F /* profiler */, 9C7A3A8618C806E00070BB5F /* README.md */, 9C7A3A8718C806E00070BB5F /* rec-ARM */, 9C7A3A8A18C806E00070BB5F /* rend */, - 9C7A3A9718C806E00070BB5F /* sdl */, 9C7A3A9918C806E00070BB5F /* stdclass.cpp */, 9C7A3A9A18C806E00070BB5F /* stdclass.h */, 9C7A3A9B18C806E00070BB5F /* types.h */, @@ -1238,14 +1232,6 @@ path = KHR; sourceTree = ""; }; - 9C7A3A7A18C806E00070BB5F /* nacl */ = { - isa = PBXGroup; - children = ( - 9C7A3A7B18C806E00070BB5F /* nacl.cpp */, - ); - path = nacl; - sourceTree = ""; - }; 9C7A3A7D18C806E00070BB5F /* oslib */ = { isa = PBXGroup; children = ( @@ -1316,14 +1302,6 @@ path = norend; sourceTree = ""; }; - 9C7A3A9718C806E00070BB5F /* sdl */ = { - isa = PBXGroup; - children = ( - 9C7A3A9818C806E00070BB5F /* main.cpp */, - ); - path = sdl; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -1353,6 +1331,11 @@ attributes = { LastUpgradeCheck = 0500; ORGANIZATIONNAME = "Karen Tsai (angelXwind)"; + TargetAttributes = { + 87078A8218A47FE90034C7A0 = { + DevelopmentTeam = QRT73U549N; + }; + }; }; buildConfigurationList = 87078A7E18A47FE90034C7A0 /* Build configuration list for PBXProject "emulator" */; compatibilityVersion = "Xcode 3.2"; @@ -1564,7 +1547,6 @@ 9C7A3AB218C806E00070BB5F /* pngrio.c in Sources */, 9C7A3AC118C806E00070BB5F /* zip_entry_free.c in Sources */, 9C7A3B4018C806E00070BB5F /* alsa_audiostream.cpp in Sources */, - 9C7A3B3E18C806E00070BB5F /* nacl.cpp in Sources */, 9C7A3AE518C806E00070BB5F /* zip_source_filep.c in Sources */, 9C7A3B0318C806E00070BB5F /* dsp.cpp in Sources */, 9C7A3B0B18C806E00070BB5F /* holly_intc.cpp in Sources */, @@ -1583,7 +1565,6 @@ 9C7A3B1318C806E00070BB5F /* _vmem.cpp in Sources */, 9C7A3B1118C806E00070BB5F /* maple_helper.cpp in Sources */, 9C7A3AD018C806E00070BB5F /* zip_fopen.c in Sources */, - 9C7A3B4D18C806E00070BB5F /* main.cpp in Sources */, 9C7A3B1718C806E00070BB5F /* pvr_sb_regs.cpp in Sources */, 9C7A3B3918C806E00070BB5F /* ImgReader.cpp in Sources */, 9C7A3ACC18C806E00070BB5F /* zip_file_error_get.c in Sources */, @@ -1699,10 +1680,16 @@ ); ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; - CODE_SIGN_ENTITLEMENTS = emulator/reicast.entitlements; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "emulator/emulator-Prefix.pch"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "GLES=1", + "DEBUG=1", + "TARGET_IPHONE=1", + "$(inherited)", + ); HEADER_SEARCH_PATHS = ( "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, @@ -1711,8 +1698,11 @@ ../../core/khronos/, ); INFOPLIST_FILE = "emulator/emulator-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; ONLY_ACTIVE_ARCH = NO; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; + TARGETED_DEVICE_FAMILY = "1,2"; VALID_ARCHS = "armv7 armv7s"; WRAPPER_EXTENSION = app; }; @@ -1727,10 +1717,14 @@ ); ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; - CODE_SIGN_ENTITLEMENTS = emulator/reicast.entitlements; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "emulator/emulator-Prefix.pch"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "GLES=1", + "TARGET_IPHONE=1", + ); HEADER_SEARCH_PATHS = ( "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, @@ -1739,8 +1733,11 @@ ../../core/khronos/, ); INFOPLIST_FILE = "emulator/emulator-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; ONLY_ACTIVE_ARCH = NO; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; + TARGETED_DEVICE_FAMILY = "1,2"; VALID_ARCHS = "armv7 armv7s"; WRAPPER_EXTENSION = app; }; diff --git a/shell/ios/emulator/EmulatorViewController.m b/shell/ios/emulator/EmulatorViewController.m index 192096a78..6002ad3cf 100644 --- a/shell/ios/emulator/EmulatorViewController.m +++ b/shell/ios/emulator/EmulatorViewController.m @@ -7,6 +7,7 @@ // #import "EmulatorViewController.h" +#import #define BUFFER_OFFSET(i) ((char *)NULL + (i)) @@ -161,8 +162,12 @@ GLfloat gCubeVertexData[216] = [EAGLContext setCurrentContext:self.context]; glDeleteBuffers(1, &_vertexBuffer); + + + //Is this needed? xcode fails to resole it glDeleteVertexArraysOES(1, &_vertexArray); + self.effect = nil; if (_program) { @@ -207,8 +212,10 @@ GLfloat gCubeVertexData[216] = glClearColor(0.65f, 0.65f, 0.65f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glBindVertexArrayOES(_vertexArray); + //See .. + glBindVertexArrayOES(_vertexArray); + // Render the object with GLKit [self.effect prepareToDraw]; diff --git a/shell/ios/emulator/emulator-Info.plist b/shell/ios/emulator/emulator-Info.plist index a57996257..7bdce4f25 100644 --- a/shell/ios/emulator/emulator-Info.plist +++ b/shell/ios/emulator/emulator-Info.plist @@ -9,7 +9,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - com.reicast.${PRODUCT_NAME:rfc1034identifier} + com.camerize.$(PRODUCT_NAME:rfc1034identifier) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/shell/ios/emulator/reicast.entitlements b/shell/ios/emulator/reicast.entitlements index 42cfb9cdc..0c67376eb 100644 --- a/shell/ios/emulator/reicast.entitlements +++ b/shell/ios/emulator/reicast.entitlements @@ -1,8 +1,5 @@ - - get-task-allow - - + From 069e96384b36f1e4c8a23b4dc9f68805ef694249 Mon Sep 17 00:00:00 2001 From: TwistedUmbrella Date: Fri, 19 Dec 2014 14:59:38 -0500 Subject: [PATCH 05/20] update build configuration for public repository --- shell/ios/emulator.xcodeproj/project.pbxproj | 69 +++++++++++-------- shell/ios/emulator/assets/Icon-72.png | Bin 0 -> 9856 bytes shell/ios/emulator/assets/Icon-72@2x.png | Bin 0 -> 20070 bytes shell/ios/emulator/assets/Icon.png | Bin 0 -> 8068 bytes shell/ios/emulator/assets/Icon@2x.png | Bin 0 -> 15566 bytes shell/ios/emulator/emulator-Info.plist | 21 ++++-- 6 files changed, 56 insertions(+), 34 deletions(-) create mode 100644 shell/ios/emulator/assets/Icon-72.png create mode 100644 shell/ios/emulator/assets/Icon-72@2x.png create mode 100644 shell/ios/emulator/assets/Icon.png create mode 100644 shell/ios/emulator/assets/Icon@2x.png diff --git a/shell/ios/emulator.xcodeproj/project.pbxproj b/shell/ios/emulator.xcodeproj/project.pbxproj index 36cde6436..b3dd793b6 100644 --- a/shell/ios/emulator.xcodeproj/project.pbxproj +++ b/shell/ios/emulator.xcodeproj/project.pbxproj @@ -14,6 +14,10 @@ 8497BCCA1A41BFBA00EFB9ED /* audiostream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8497BCC51A41BFBA00EFB9ED /* audiostream.cpp */; }; 8497BCCB1A41BFBA00EFB9ED /* ds_audiostream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8497BCC71A41BFBA00EFB9ED /* ds_audiostream.cpp */; }; 8497BCCF1A41BFD800EFB9ED /* coreio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8497BCCD1A41BFD800EFB9ED /* coreio.cpp */; }; + 8703BC3B1A44B8DA00E7E939 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 8703BC371A44B8DA00E7E939 /* Icon-72.png */; }; + 8703BC3C1A44B8DA00E7E939 /* Icon-72@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8703BC381A44B8DA00E7E939 /* Icon-72@2x.png */; }; + 8703BC3D1A44B8DA00E7E939 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 8703BC391A44B8DA00E7E939 /* Icon.png */; }; + 8703BC3E1A44B8DA00E7E939 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8703BC3A1A44B8DA00E7E939 /* Icon@2x.png */; }; 87078A8718A47FE90034C7A0 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 87078A8618A47FE90034C7A0 /* Foundation.framework */; }; 87078A8918A47FE90034C7A0 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 87078A8818A47FE90034C7A0 /* CoreGraphics.framework */; }; 87078A8B18A47FE90034C7A0 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 87078A8A18A47FE90034C7A0 /* UIKit.framework */; }; @@ -24,7 +28,8 @@ 87078AA318A47FE90034C7A0 /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 87078AA218A47FE90034C7A0 /* Shader.fsh */; }; 87078AA518A47FE90034C7A0 /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 87078AA418A47FE90034C7A0 /* Shader.vsh */; }; 87078AA818A47FE90034C7A0 /* EmulatorViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 87078AA718A47FE90034C7A0 /* EmulatorViewController.mm */; }; - 87078AAA18A47FE90034C7A0 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 87078AA918A47FE90034C7A0 /* Images.xcassets */; }; + 87C4AA541A440BEB0048DBF4 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 87C4AA531A440BEB0048DBF4 /* libz.dylib */; }; + 87C4AA561A4414070048DBF4 /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 87C4AA551A4414070048DBF4 /* AssetsLibrary.framework */; }; 9C7A393318C804A80070BB5F /* reicast.entitlements in Resources */ = {isa = PBXBuildFile; fileRef = 9C7A393218C804A80070BB5F /* reicast.entitlements */; }; 9C7A3AA218C806E00070BB5F /* cfg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9C7A395118C806DE0070BB5F /* cfg.cpp */; }; 9C7A3AA318C806E00070BB5F /* cl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9C7A395318C806DE0070BB5F /* cl.cpp */; }; @@ -231,6 +236,10 @@ 8497BCC81A41BFBA00EFB9ED /* oslib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oslib.h; sourceTree = ""; }; 8497BCCD1A41BFD800EFB9ED /* coreio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = coreio.cpp; sourceTree = ""; }; 8497BCCE1A41BFD800EFB9ED /* coreio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = coreio.h; sourceTree = ""; }; + 8703BC371A44B8DA00E7E939 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = ""; }; + 8703BC381A44B8DA00E7E939 /* Icon-72@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72@2x.png"; sourceTree = ""; }; + 8703BC391A44B8DA00E7E939 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; + 8703BC3A1A44B8DA00E7E939 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = ""; }; 87078A8318A47FE90034C7A0 /* emulator.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = emulator.app; sourceTree = BUILT_PRODUCTS_DIR; }; 87078A8618A47FE90034C7A0 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 87078A8818A47FE90034C7A0 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; @@ -246,8 +255,9 @@ 87078AA418A47FE90034C7A0 /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; 87078AA618A47FE90034C7A0 /* EmulatorViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = EmulatorViewController.h; path = emulator/EmulatorViewController.h; sourceTree = ""; }; 87078AA718A47FE90034C7A0 /* EmulatorViewController.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = EmulatorViewController.mm; path = emulator/EmulatorViewController.mm; sourceTree = ""; }; - 87078AA918A47FE90034C7A0 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = emulator/Images.xcassets; sourceTree = ""; }; 87078AB018A47FE90034C7A0 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; + 87C4AA531A440BEB0048DBF4 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; + 87C4AA551A4414070048DBF4 /* AssetsLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AssetsLibrary.framework; path = System/Library/Frameworks/AssetsLibrary.framework; sourceTree = SDKROOT; }; 9C7A393218C804A80070BB5F /* reicast.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = reicast.entitlements; sourceTree = ""; }; 9C7A393A18C806DE0070BB5F /* arm_coding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = arm_coding.h; sourceTree = ""; }; 9C7A393B18C806DE0070BB5F /* arm_disasm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = arm_disasm.h; sourceTree = ""; }; @@ -583,6 +593,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 87C4AA561A4414070048DBF4 /* AssetsLibrary.framework in Frameworks */, + 87C4AA541A440BEB0048DBF4 /* libz.dylib in Frameworks */, 87078A8F18A47FE90034C7A0 /* OpenGLES.framework in Frameworks */, 87078A8918A47FE90034C7A0 /* CoreGraphics.framework in Frameworks */, 87078A8B18A47FE90034C7A0 /* UIKit.framework in Frameworks */, @@ -626,6 +638,17 @@ path = deps/coreio; sourceTree = ""; }; + 8703BC361A44B8DA00E7E939 /* assets */ = { + isa = PBXGroup; + children = ( + 8703BC371A44B8DA00E7E939 /* Icon-72.png */, + 8703BC381A44B8DA00E7E939 /* Icon-72@2x.png */, + 8703BC391A44B8DA00E7E939 /* Icon.png */, + 8703BC3A1A44B8DA00E7E939 /* Icon@2x.png */, + ); + path = assets; + sourceTree = ""; + }; 87078A7A18A47FE90034C7A0 = { isa = PBXGroup; children = ( @@ -646,6 +669,8 @@ 87078A8518A47FE90034C7A0 /* Frameworks */ = { isa = PBXGroup; children = ( + 87C4AA551A4414070048DBF4 /* AssetsLibrary.framework */, + 87C4AA531A440BEB0048DBF4 /* libz.dylib */, 87078A8618A47FE90034C7A0 /* Foundation.framework */, 87078A8818A47FE90034C7A0 /* CoreGraphics.framework */, 87078A8A18A47FE90034C7A0 /* UIKit.framework */, @@ -679,6 +704,7 @@ 87078A9118A47FE90034C7A0 /* Supporting Files */ = { isa = PBXGroup; children = ( + 8703BC361A44B8DA00E7E939 /* assets */, 87078A9218A47FE90034C7A0 /* emulator-Info.plist */, 87078A9618A47FE90034C7A0 /* main.m */, 87078A9818A47FE90034C7A0 /* emulator-Prefix.pch */, @@ -744,7 +770,6 @@ 9C7A3BFC18C851C50070BB5F /* RTrigger@2x.png */, 9C7A3BFD18C851C50070BB5F /* Start.png */, 9C7A3BFE18C851C50070BB5F /* Start@2x.png */, - 87078AA918A47FE90034C7A0 /* Images.xcassets */, ); name = Images; path = ..; @@ -1341,12 +1366,7 @@ isa = PBXProject; attributes = { LastUpgradeCheck = 0500; - ORGANIZATIONNAME = "Karen Tsai (angelXwind)"; - TargetAttributes = { - 87078A8218A47FE90034C7A0 = { - DevelopmentTeam = QRT73U549N; - }; - }; + ORGANIZATIONNAME = reicast; }; buildConfigurationList = 87078A7E18A47FE90034C7A0 /* Build configuration list for PBXProject "emulator" */; compatibilityVersion = "Xcode 3.2"; @@ -1373,6 +1393,7 @@ files = ( 9C7A3C1818C851C50070BB5F /* LTrigger@2x.png in Resources */, 9C7A3C1318C851C50070BB5F /* JoystickBackground.png in Resources */, + 8703BC3C1A44B8DA00E7E939 /* Icon-72@2x.png in Resources */, 9C7A393318C804A80070BB5F /* reicast.entitlements in Resources */, 9C7A3C0018C851C50070BB5F /* 210-octocat@2x.png in Resources */, 9C7A3C1718C851C50070BB5F /* LTrigger.png in Resources */, @@ -1384,11 +1405,13 @@ 9C7A3C2118C851C50070BB5F /* RTrigger.png in Resources */, 9C7A3C1C18C851C50070BB5F /* menuicon@2x.png in Resources */, 9C7A3C0118C851C50070BB5F /* 210-twitterbird.png in Resources */, + 8703BC3D1A44B8DA00E7E939 /* Icon.png in Resources */, 9C7A3C0D18C851C50070BB5F /* DPad.png in Resources */, 9C7A3C1518C851C50070BB5F /* JoystickButton.png in Resources */, + 8703BC3E1A44B8DA00E7E939 /* Icon@2x.png in Resources */, 9C7A3BFF18C851C50070BB5F /* 210-octocat.png in Resources */, + 8703BC3B1A44B8DA00E7E939 /* Icon-72.png in Resources */, 9C7A3C1618C851C50070BB5F /* JoystickButton@2x.png in Resources */, - 87078AAA18A47FE90034C7A0 /* Images.xcassets in Resources */, 9C7A3C1418C851C50070BB5F /* JoystickBackground@2x.png in Resources */, 9C7A3C1918C851C50070BB5F /* menuback.png in Resources */, 9C7A3BC418C84EA10070BB5F /* MainStoryboard.storyboard in Resources */, @@ -1687,14 +1710,9 @@ 87078AC118A47FE90034C7A0 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - armv7s, - armv7, - ); - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; - CODE_SIGN_IDENTITY = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + ARCHS = "$(ARCHS_STANDARD)"; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "emulator/emulator-Prefix.pch"; GCC_PREPROCESSOR_DEFINITIONS = ( @@ -1717,7 +1735,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; TARGETED_DEVICE_FAMILY = "1,2"; - VALID_ARCHS = armv7; + VALID_ARCHS = "armv7 armv7s"; WRAPPER_EXTENSION = app; }; name = Debug; @@ -1725,14 +1743,9 @@ 87078AC218A47FE90034C7A0 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - armv7s, - armv7, - ); - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; - CODE_SIGN_IDENTITY = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + ARCHS = "$(ARCHS_STANDARD)"; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "emulator/emulator-Prefix.pch"; GCC_PREPROCESSOR_DEFINITIONS = ( @@ -1753,7 +1766,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; TARGETED_DEVICE_FAMILY = "1,2"; - VALID_ARCHS = armv7; + VALID_ARCHS = "armv7 armv7s"; WRAPPER_EXTENSION = app; }; name = Release; diff --git a/shell/ios/emulator/assets/Icon-72.png b/shell/ios/emulator/assets/Icon-72.png new file mode 100644 index 0000000000000000000000000000000000000000..647ca0bac997c43b7115928220354ab977a3f849 GIT binary patch literal 9856 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 Rz^?cJd1)1?S_$Kz{{fB)&=CLt literal 0 HcmV?d00001 diff --git a/shell/ios/emulator/assets/Icon-72@2x.png b/shell/ios/emulator/assets/Icon-72@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..0d528bcd545f8f80449a06023916edb57dd6f96a GIT binary patch literal 20070 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�U)8O{xwn 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 + NSHighResolutionCapable + + UIFileSharingEnabled + CFBundleDevelopmentRegion en CFBundleDisplayName Reicast CFBundleExecutable ${EXECUTABLE_NAME} + CFBundleIconFiles + + emulator/assets/Icon-72.png + emulator/assets/Icon-72@2x.png + emulator/assets/Icon.png + emulator/assets/Icon@2x.png + CFBundleIdentifier com.reicast.$(PRODUCT_NAME:rfc1034identifier) CFBundleInfoDictionaryVersion @@ -24,6 +35,8 @@ 1.0 LSRequiresIPhoneOS + UILaunchStoryboardName + MainStoryboard UIMainStoryboardFile MainStoryboard UIMainStoryboardFile~ipad @@ -35,13 +48,13 @@ armv7 UIStatusBarHidden - + UISupportedInterfaceOrientations - UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationPortrait UISupportedInterfaceOrientations~ipad @@ -50,10 +63,6 @@ UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight - UIFileSharingEnabled - - NSHighResolutionCapable - UIViewControllerBasedStatusBarAppearance From f2c07917c7f1500438529d5bee95dcbff0a58e33 Mon Sep 17 00:00:00 2001 From: Stefanos Kornilios Mitsis Poiitidis Date: Sun, 18 Jan 2015 23:52:12 -0800 Subject: [PATCH 06/20] Partially working dyna for iOS. Very few games working atm. This works, but is extremelly hacky. Must be started without attached debugger, lldb doesn't want to let go of EXC_BAD_ADDRESS, but reicast really depends on it getting delivered as SIGSEGV/SIGBUS. Also xcode has a really bad day upon seeing the jit code. Oh well. There's some dynarec bug that causes color corruption on bios logo/boot triagles, TA crash on ikaruga and infinitive loop on crazy taxi. I'd guess some fp-memory-write thingy, abi, or smth. Too bad. - Force code to compile in arm mode (arm jit -> thumb mem functions is complicated) - SIGILL, SIGBUS. Works w/o Mach exceptions and EXC_BAD_ADDRESS - Code buffers move to __TEXT, munmapped && memmapped to actually work - Primitive input. Button + start, or left (works to get out of bios date screen) - Fixup emitter for thumb2/interworking (didn't work though, reverted to arm cc) - Block Manager: Disable mem saving / page fault alloc-on-demand logic - Move cycle counter to r11, r9 is not clean on iOS. Remove r11 from reg alloc list - Cache flushes for iOS - log to log.txt - load game.chd --- core/arm_emitter/E_Branches.h | 8 +-- core/arm_emitter/H_Branches.h | 18 +++++-- core/arm_emitter/arm_emitter.h | 2 +- core/hw/arm7/arm7.cpp | 24 +++++++-- core/hw/mem/_vmem.cpp | 3 +- core/hw/sh4/dyna/blockmanager.cpp | 2 +- core/hw/sh4/dyna/driver.cpp | 18 ++++--- core/linux/common.cpp | 34 +++++++++--- core/nullDC.cpp | 2 +- core/rec-ARM/arm_dyna.cpp | 56 ++++++++++++++++---- core/rec-ARM/ngen_arm.S | 8 +-- shell/ios/emulator.xcodeproj/project.pbxproj | 23 +++++--- shell/ios/emulator/EmulatorView.h | 13 +++++ shell/ios/emulator/EmulatorView.mm | 51 ++++++++++++++++++ shell/ios/emulator/MainStoryboard.storyboard | 2 +- shell/ios/emulator/emulator-Info.plist | 8 +-- shell/ios/emulator/ios_main.mm | 2 + 17 files changed, 220 insertions(+), 54 deletions(-) create mode 100644 shell/ios/emulator/EmulatorView.h create mode 100644 shell/ios/emulator/EmulatorView.mm diff --git a/core/arm_emitter/E_Branches.h b/core/arm_emitter/E_Branches.h index 626ba54ac..32c74a9da 100644 --- a/core/arm_emitter/E_Branches.h +++ b/core/arm_emitter/E_Branches.h @@ -12,7 +12,7 @@ namespace ARM EAPI B(u32 sImm24, ConditionCode CC=AL) { DECL_Id(0x0A000000); - + SET_CC; I |= ((sImm24>>2)&0xFFFFFF); EMIT_I; @@ -64,12 +64,12 @@ namespace ARM // This encoding looks correct, but segfaults, the pc val is align(pc,4) but this should be right in ARM // #if defined(_DEVEL) - EAPI BLX(u32 sImm24) // Form I * H is derived so not needed, fixup sImm24 so one can just pass a real addr + EAPI BLX(u32 sImm24, bool toThumb) // Form I * H is derived so not needed, fixup sImm24 so one can just pass a real addr { DECL_Id(0xFA000000); - //if(sImm24&1) - // I |= 1<<24; // SET_H + if(toThumb) + I |= 1<<24; // SET_H I |= ((sImm24>>2)&0xFFFFFF); EMIT_I; diff --git a/core/arm_emitter/H_Branches.h b/core/arm_emitter/H_Branches.h index c99332010..93af27abe 100644 --- a/core/arm_emitter/H_Branches.h +++ b/core/arm_emitter/H_Branches.h @@ -22,6 +22,8 @@ namespace ARM EAPI CALL(unat FnAddr, ConditionCode CC=AL) { + bool isThumb = FnAddr & 1; + FnAddr &= ~1; snat lit = Literal(FnAddr); if(0==lit) { @@ -39,15 +41,24 @@ namespace ARM return; } - BL(lit,CC); + if (isThumb) { + verify (CC==CC_EQ); + BLX(lit, isThumb); + } else { + BL(lit,CC); + } } EAPI JUMP(unat FnAddr, ConditionCode CC=AL) { + bool isThumb = FnAddr & 1; + FnAddr &= ~1; + + verify(!isThumb); snat lit = Literal(FnAddr); - + /*if(0==lit) { printf("Error, Compiler caught NULL literal, JUMP(%08X)\n", FnAddr); verify(false); @@ -62,8 +73,7 @@ namespace ARM BX(IP, CC); return; } - - B(lit,CC); // Note, wont work for THUMB*, have to use bx which is reg only ! + B(lit,CC); // Note, wont work for THUMB*, have to use bx which is reg only ! } diff --git a/core/arm_emitter/arm_emitter.h b/core/arm_emitter/arm_emitter.h index 25544261c..636cedf3d 100644 --- a/core/arm_emitter/arm_emitter.h +++ b/core/arm_emitter/arm_emitter.h @@ -34,7 +34,7 @@ namespace ARM #if defined(_DEBUG) || defined(DEBUG) - #define EAPI void + #define EAPI static void #define DECL_I \ u32 Instruction=0 diff --git a/core/hw/arm7/arm7.cpp b/core/hw/arm7/arm7.cpp index 2ddb37c1d..12a57641d 100644 --- a/core/hw/arm7/arm7.cpp +++ b/core/hw/arm7/arm7.cpp @@ -734,15 +734,17 @@ u8* icPtr; u8* ICache; const u32 ICacheSize=1024*1024; -#if HOST_OS != OS_LINUX +#if HOST_OS == OS_WINDOWS u8 ARM7_TCB[ICacheSize+4096]; -#elif HOST_OS == OS_LINUX +#elif HOST_OS == OS_LINUX || HOST_OS==OS_DARWIN u8 ARM7_TCB[ICacheSize+4096] #ifndef DYNA_OPROF -__attribute__((section(".text"))) +__attribute__((section("__TEXT, .text"))) #endif ; +#else +//dynamic mmap #endif #include "arm_emitter/arm_emitter.h" @@ -1531,9 +1533,17 @@ void *armGetEmitPtr() return NULL; } +#if HOST_OS==OS_DARWIN +#include +extern "C" void armFlushICache(void *code, void *pEnd) { + sys_dcache_flush(code, (u8*)pEnd - (u8*)code + 1); + sys_icache_invalidate(code, (u8*)pEnd - (u8*)code + 1); +} +#else extern "C" void armFlushICache(void *bgn, void *end) { __clear_cache(bgn, end); } +#endif void armv_imm_to_reg(u32 regn, u32 imm) @@ -2119,14 +2129,18 @@ void armt_init() InitHash(); //align to next page .. + ICache = (u8*)(((unat)ARM7_TCB+4095)& ~4095); + munmap(ICache, ICacheSize); + ICache = (u8*)mmap(ICache, ICacheSize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_ANON, 0, 0); + #if HOST_OS == OS_WINDOWS DWORD old; VirtualProtect(ICache,ICacheSize,PAGE_EXECUTE_READWRITE,&old); -#elif HOST_OS == OS_LINUX +#elif HOST_OS == OS_LINUX || HOST_OS == OS_DARWIN - printf("\n\t ARM7_TCB addr: %p | from: %p | addr here: %p\n", ICache, ARM7_TCB, armt_init); + printf("\n\t ARM7_TCB addr: %p | from: %p | addr here: %p\n", ICache, ICache, armt_init); if (mprotect(ICache, ICacheSize, PROT_EXEC|PROT_READ|PROT_WRITE)) { diff --git a/core/hw/mem/_vmem.cpp b/core/hw/mem/_vmem.cpp index 01838ab9b..daec16fd2 100644 --- a/core/hw/mem/_vmem.cpp +++ b/core/hw/mem/_vmem.cpp @@ -586,12 +586,13 @@ void _vmem_bm_pagefail(void** ptr,u32 PAGE_SZ); u32 pagecnt; void _vmem_bm_reset() { + mprotect(p_sh4rcb, sizeof(p_sh4rcb->fpcb), PROT_READ | PROT_WRITE); + return; pagecnt=0; #if HOST_OS==OS_WINDOWS VirtualFree(p_sh4rcb,sizeof(p_sh4rcb->fpcb),MEM_DECOMMIT); #else - mprotect(p_sh4rcb, sizeof(p_sh4rcb->fpcb), PROT_NONE); madvise(p_sh4rcb,sizeof(p_sh4rcb->fpcb),MADV_DONTNEED); #ifdef MADV_REMOVE madvise(p_sh4rcb,sizeof(p_sh4rcb->fpcb),MADV_REMOVE); diff --git a/core/hw/sh4/dyna/blockmanager.cpp b/core/hw/sh4/dyna/blockmanager.cpp index 2ed79ea73..620ea66b0 100644 --- a/core/hw/sh4/dyna/blockmanager.cpp +++ b/core/hw/sh4/dyna/blockmanager.cpp @@ -384,7 +384,7 @@ void bm_Reset() for (u32 i=0;i<(8*1024*1024);i++) { - //sh4rcb.fpcb[i]=(void*)ngen_FailedToFindBlock; + sh4rcb.fpcb[i]=(void*)ngen_FailedToFindBlock; } for (size_t i=0; i + void recSh4_Init() { printf("recSh4 Init\n"); @@ -407,14 +410,17 @@ void recSh4_Init() //align to next page .. CodeCache = (u8*)(((unat)SH4_TCB+4095)& ~4095); + munmap(CodeCache, CODE_SIZE*2); + CodeCache = (u8*)mmap(CodeCache, 2*CODE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_ANON, 0, 0); + #if HOST_OS == OS_WINDOWS DWORD old; VirtualProtect(CodeCache,CODE_SIZE*2,PAGE_EXECUTE_READWRITE,&old); -#elif HOST_OS == OS_LINUX +#elif HOST_OS == OS_LINUX || HOST_OS == OS_DARWIN - printf("\n\t CodeCache addr: %p | from: %p | addr here: %p\n", CodeCache, SH4_TCB, recSh4_Init); + printf("\n\t CodeCache addr: %p | from: %p | addr here: %p\n", CodeCache, CodeCache, recSh4_Init); - if (mprotect(CodeCache, CODE_SIZE*2, PROT_EXEC|PROT_READ|PROT_WRITE)) + if (mprotect(CodeCache, CODE_SIZE*2, PROT_READ|PROT_WRITE|PROT_EXEC)) { perror("\n\tError,Couldn’t mprotect CodeCache!"); verify(false); diff --git a/core/linux/common.cpp b/core/linux/common.cpp index 5fa3f0510..c484bafde 100644 --- a/core/linux/common.cpp +++ b/core/linux/common.cpp @@ -60,12 +60,29 @@ u32* ngen_readm_fail_v2(u32* ptr,u32* regs,u32 saddr); bool VramLockedWrite(u8* address); bool BM_LockedWrite(u8* address); +void sigill_handler(int sn, siginfo_t * si, void *ctxr) { + + ucontext_t* ctx=(ucontext_t*)ctxr; + unat pc = (unat)GET_PC_FROM_CONTEXT(ctxr); + bool dyna_cde=((u32)GET_PC_FROM_CONTEXT(ctxr)>(u32)CodeCache) && ((u32)GET_PC_FROM_CONTEXT(ctxr)<(u32)(CodeCache+CODE_SIZE)); + + printf("SIGILL @ %08X, fault_handler+0x%08X ... %08X -> was not in vram, %d\n",GET_PC_FROM_CONTEXT(ctxr), GET_PC_FROM_CONTEXT(ctxr)-(u32)sigill_handler,(unat)si->si_addr, dyna_cde); + + printf("Entering infiniloop"); + + for(;;); + + printf("PC is used here %08X\n", pc); +} + void fault_handler (int sn, siginfo_t * si, void *ctxr) { - + #ifndef HOST_NO_REC bool dyna_cde=((u32)GET_PC_FROM_CONTEXT(ctxr)>(u32)CodeCache) && ((u32)GET_PC_FROM_CONTEXT(ctxr)<(u32)(CodeCache+CODE_SIZE)); #endif + + //printf("SIGSEGV @ fault_handler+0x%08X ... %08X -> was not in vram, %d\n",GET_PC_FROM_CONTEXT(ctxr)-(u32)fault_handler,(unat)si->si_addr, dyna_cde); ucontext_t* ctx=(ucontext_t*)ctxr; //printf("mprot hit @ ptr 0x%08X @@ code: %08X, %d\n",si->si_addr,ctx->uc_mcontext.arm_pc,dyna_cde); @@ -76,8 +93,9 @@ void fault_handler (int sn, siginfo_t * si, void *ctxr) #ifndef HOST_NO_REC else if (dyna_cde) { - GET_PC_FROM_CONTEXT(ctxr)=(u32)ngen_readm_fail_v2((u32*)GET_PC_FROM_CONTEXT(ctxr),(u32*)&(ctx->uc_mcontext.arm_r0),(unat)si->si_addr); - } + GET_PC_FROM_CONTEXT(ctxr)=(u32)ngen_readm_fail_v2((u32*)GET_PC_FROM_CONTEXT(ctxr),(u32*)(ctx->uc_mcontext->__ss.__r),(unat)si->si_addr); + //printf("returning at %08X\n", (unat)GET_PC_FROM_CONTEXT(ctxr)); + } #endif else { @@ -98,6 +116,10 @@ void install_fault_handler (void) //this is broken on osx/ios/mach in general sigaction(SIGSEGV, &act, &segv_oact); + sigaction(SIGBUS, &act, &segv_oact); + + act.sa_sigaction = sigill_handler; + sigaction(SIGILL, &act, &segv_oact); } @@ -169,16 +191,14 @@ void cResetEvent::Wait()//Wait for signal , then reset void VArray2::LockRegion(u32 offset,u32 size) { -#if HOST_OS != OS_DARWIN //darwin doesn't have sane exception handling, leave this off for now. - u32 inpage=offset & PAGE_MASK; + u32 inpage=offset & PAGE_MASK; u32 rv=mprotect (data+offset-inpage, size+inpage, PROT_READ ); if (rv!=0) { printf("mprotect(%08X,%08X,R) failed: %d | %d\n",data+offset-inpage,size+inpage,rv,errno); die("mprotect failed ..\n"); } -#endif } void print_mem_addr() @@ -213,7 +233,7 @@ void print_mem_addr() void VArray2::UnLockRegion(u32 offset,u32 size) { - u32 inpage=offset & PAGE_MASK; + u32 inpage=offset & PAGE_MASK; u32 rv=mprotect (data+offset-inpage, size+inpage, PROT_READ | PROT_WRITE); if (rv!=0) { diff --git a/core/nullDC.cpp b/core/nullDC.cpp index e20dd9801..0d8899167 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -66,7 +66,7 @@ int GetFile(char *szFileName, char *szParse=0,u32 flags=0) //strcpy(szFileName,ofn.lpstrFile); } #else - strcpy(szFileName,GetPath("/discs/game.gdi").c_str()); + strcpy(szFileName,GetPath("/game.chd").c_str()); #endif #endif } diff --git a/core/rec-ARM/arm_dyna.cpp b/core/rec-ARM/arm_dyna.cpp index f78598fba..5eb9dccbd 100755 --- a/core/rec-ARM/arm_dyna.cpp +++ b/core/rec-ARM/arm_dyna.cpp @@ -56,7 +56,14 @@ struct DynaRBI: RuntimeBlockInfo #include // for cache flushing. #endif -#if !defined(ARMCC) +#if HOST_OS == OS_DARWIN +#include +void CacheFlush(void* code, void* pEnd) +{ + sys_dcache_flush(code, (u8*)pEnd - (u8*)code + 1); + sys_icache_invalidate(code, (u8*)pEnd - (u8*)code + 1); +} +#elif !defined(ARMCC) void CacheFlush(void* code, void* pEnd) { #if !defined(_ANDROID) && HOST_OS!=OS_DARWIN @@ -250,7 +257,7 @@ EmitAPI StoreSh4Reg64(eReg Rt, shil_param Sh4_Reg, eCC CC=CC_AL) #include "hw/sh4/dyna/regalloc.h" -eReg alloc_regs[]={r5,r6,r7,r10,r11,(eReg)-1}; +eReg alloc_regs[]={r5,r6,r7,r10,(eReg)-1}; eFSReg alloc_fpu[]={f16,f17,f18,f19,f20,f21,f22,f23, f24,f25,f26,f27,f28,f29,f30,f31,(eFSReg)-1}; @@ -494,8 +501,9 @@ u32 DynaRBI::Relink() } CacheFlush(code_start,emit_ptr); - - u32 sz=(u8*)emit_ptr-code_start; + + u32 sz=(u8*)emit_ptr-code_start; + unat offs = (unat)code_start & PAGE_MASK; emit_ptr=0; return sz; @@ -2027,7 +2035,7 @@ void ngen_Compile(RuntimeBlockInfo* block,bool force_checks, bool reset, bool st cyc&=~3; } - SUB(rfp_r9,rfp_r9,cyc,true,CC_AL); + SUB(r11,r11,cyc,true,CC_AL); CALL((u32)intc_sched, CC_LE); //compile the block's opcodes @@ -2115,6 +2123,28 @@ void ngen_ResetBlocks() */ void ngen_init() { + /* + { + uint32_t* p; + p = (uint32_t*)malloc(1024+4096-1); + p = (uint32_t*)(((int)p + 4096 -1) & ~(4096 - 1)); + + if (mprotect(p, 1024, PROT_READ | PROT_WRITE)) { + die("failed to mprotect"); + } + + if (mprotect(p, 1024, PROT_READ | PROT_EXEC)) { + die("failed to mprotect"); + } + + if (mprotect(p, 1024, PROT_READ | PROT_WRITE | PROT_EXEC)) { + die("failed to mprotect"); + } + p[0] = 0x323232; + + } + */ + for (int s=0;s<6;s++) { void* fn=s==0?(void*)_vmem_ReadMem8SX32: @@ -2142,7 +2172,10 @@ void ngen_init() { v=(unat)EMIT_GET_PTR(); MOV(r0,(eReg)(i)); - JUMP((u32)fn); + + JUMP((u32)fn); + //MOV32(r9, (unat)fn); + //BX(r9); } } else @@ -2153,8 +2186,11 @@ void ngen_init() { v=(unat)EMIT_GET_PTR(); MOV(r0,(eReg)(i)); - JUMP((u32)fn); - } + + JUMP((u32)fn); + //MOV32(r9, (unat)fn); + //BX(r9); + } } _mem_hndl[read][s%3][i]=v; @@ -2175,7 +2211,9 @@ void ngen_init() ADD(r3,r3,r8); CMP(r2,0x38); JUMP((unat)&WriteMem32,CC_NE); - STR(r1,r3,rcb_noffs(sq_both)); + //MOV32(r9, (unat)&WriteMem32); + //BX(r9, CC_NE); + STR(r1,r3,rcb_noffs(sq_both)); BX(LR); } diff --git a/core/rec-ARM/ngen_arm.S b/core/rec-ARM/ngen_arm.S index baa832e01..bd4fd0a08 100644 --- a/core/rec-ARM/ngen_arm.S +++ b/core/rec-ARM/ngen_arm.S @@ -120,7 +120,7 @@ CSYM(ngen_mainloop): push { r4-r12,lr } - mov r9, #SH4_TIMESLICE @ load cycle counter + mov r11, #SH4_TIMESLICE @ load cycle counter mov r8, r0 @Load context ldr r4, [r8,#-184] @load pc @@ -131,7 +131,7 @@ push { r4-r12,lr } @this code is here for fall-through behavior of do_iter .global CSYM(intc_sched) CSYM(intc_sched): @ next_pc _MUST_ be on ram - add r9,r9,#SH4_TIMESLICE + add r11,r11,#SH4_TIMESLICE mov r4,lr bl CSYM(UpdateSystem) mov lr,r4 @@ -173,7 +173,7 @@ XEntryPoints: .word CSYM(EntryPoints) .global CSYM(arm_mainloop) CSYM(arm_mainloop): @(cntx,lookup_base,cycles) -push {r4,r5,r8,r9,lr} +push {r4,r5,r8,r11,lr} #ifdef TARGET_IPHONE ldr r8,Xarm_Reg @load cntx @@ -209,7 +209,7 @@ arm_dofiq: .global CSYM(arm_exit) CSYM(arm_exit): str r5,[r8,#192] @if timeslice is over, save remaining cycles - pop {r4,r5,r8,r9,pc} + pop {r4,r5,r8,r11,pc} @@@@@@ @matrix mul diff --git a/shell/ios/emulator.xcodeproj/project.pbxproj b/shell/ios/emulator.xcodeproj/project.pbxproj index b3dd793b6..15cf5c26f 100644 --- a/shell/ios/emulator.xcodeproj/project.pbxproj +++ b/shell/ios/emulator.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 846293C61A6CE61900262464 /* EmulatorView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 846293C51A6CE61900262464 /* EmulatorView.mm */; }; 8497BCBF1A41A0E900EFB9ED /* common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8497BCBC1A41A0E900EFB9ED /* common.cpp */; }; 8497BCC01A41A0E900EFB9ED /* nixprof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8497BCBD1A41A0E900EFB9ED /* nixprof.cpp */; }; 8497BCC21A41B02000EFB9ED /* ios_main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8497BCC11A41B02000EFB9ED /* ios_main.mm */; }; @@ -225,6 +226,8 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 846293C41A6CE61900262464 /* EmulatorView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EmulatorView.h; path = emulator/EmulatorView.h; sourceTree = ""; }; + 846293C51A6CE61900262464 /* EmulatorView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = EmulatorView.mm; path = emulator/EmulatorView.mm; sourceTree = ""; }; 8497BCBC1A41A0E900EFB9ED /* common.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = common.cpp; sourceTree = ""; }; 8497BCBD1A41A0E900EFB9ED /* nixprof.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = nixprof.cpp; sourceTree = ""; }; 8497BCBE1A41A0E900EFB9ED /* typedefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = typedefs.h; sourceTree = ""; }; @@ -740,6 +743,8 @@ 9C7A3B5B18C81BC80070BB5F /* SideDrawerViewController.m */, 87078AA618A47FE90034C7A0 /* EmulatorViewController.h */, 87078AA718A47FE90034C7A0 /* EmulatorViewController.mm */, + 846293C41A6CE61900262464 /* EmulatorView.h */, + 846293C51A6CE61900262464 /* EmulatorView.mm */, ); name = "View Controller Subclasses"; path = ..; @@ -1367,6 +1372,11 @@ attributes = { LastUpgradeCheck = 0500; ORGANIZATIONNAME = reicast; + TargetAttributes = { + 87078A8218A47FE90034C7A0 = { + DevelopmentTeam = QRT73U549N; + }; + }; }; buildConfigurationList = 87078A7E18A47FE90034C7A0 /* Build configuration list for PBXProject "emulator" */; compatibilityVersion = "Xcode 3.2"; @@ -1577,6 +1587,7 @@ 9C7A3B1518C806E00070BB5F /* pvr_mem.cpp in Sources */, 9C7A3B6218C820630070BB5F /* AboutViewController.m in Sources */, 9C7A3AF718C806E00070BB5F /* inflate.c in Sources */, + 846293C61A6CE61900262464 /* EmulatorView.mm in Sources */, 9C7A3AC918C806E00070BB5F /* zip_error_to_str.c in Sources */, 9C7A3B0918C806E00070BB5F /* gdrom_response.cpp in Sources */, 9C7A3B2218C806E00070BB5F /* sh4_interpreter.cpp in Sources */, @@ -1711,8 +1722,8 @@ isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD)"; - CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "emulator/emulator-Prefix.pch"; GCC_PREPROCESSOR_DEFINITIONS = ( @@ -1720,7 +1731,6 @@ "DEBUG=1", "TARGET_IPHONE=1", "$(inherited)", - "HOST_NO_REC=1", ); HEADER_SEARCH_PATHS = ( "$(inherited)", @@ -1732,6 +1742,7 @@ INFOPLIST_FILE = "emulator/emulator-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; ONLY_ACTIVE_ARCH = NO; + OTHER_CFLAGS = "-mno-thumb"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; TARGETED_DEVICE_FAMILY = "1,2"; @@ -1744,14 +1755,13 @@ isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD)"; - CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "emulator/emulator-Prefix.pch"; GCC_PREPROCESSOR_DEFINITIONS = ( "GLES=1", "TARGET_IPHONE=1", - "HOST_NO_REC=1", ); HEADER_SEARCH_PATHS = ( "$(inherited)", @@ -1763,6 +1773,7 @@ INFOPLIST_FILE = "emulator/emulator-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; ONLY_ACTIVE_ARCH = NO; + OTHER_CFLAGS = "-mno-thumb"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; TARGETED_DEVICE_FAMILY = "1,2"; diff --git a/shell/ios/emulator/EmulatorView.h b/shell/ios/emulator/EmulatorView.h new file mode 100644 index 000000000..655a02aaf --- /dev/null +++ b/shell/ios/emulator/EmulatorView.h @@ -0,0 +1,13 @@ +// +// EmulatorView.h +// emulator +// +// Created by admin on 1/18/15. +// Copyright (c) 2015 reicast. All rights reserved. +// + +#import + +@interface EmulatorView : GLKView + +@end diff --git a/shell/ios/emulator/EmulatorView.mm b/shell/ios/emulator/EmulatorView.mm new file mode 100644 index 000000000..8909eb56c --- /dev/null +++ b/shell/ios/emulator/EmulatorView.mm @@ -0,0 +1,51 @@ +// +// EmulatorView.m +// emulator +// +// Created by admin on 1/18/15. +// Copyright (c) 2015 reicast. All rights reserved. +// + +#import "EmulatorView.h" + +#include "types.h" + +extern u16 kcode[4]; +extern u32 vks[4]; +extern s8 joyx[4],joyy[4]; +extern u8 rt[4],lt[4]; + +#define key_CONT_A (1 << 2) +#define key_CONT_START (1 << 3) +#define key_CONT_DPAD_LEFT (1 << 6) + +int dpad_or_btn = 0; + +@implementation EmulatorView + +/* +// Only override drawRect: if you perform custom drawing. +// An empty implementation adversely affects performance during animation. +- (void)drawRect:(CGRect)rect { + // Drawing code +} +*/ + +-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { + + if (dpad_or_btn &1) + kcode[0] &= ~(key_CONT_START|key_CONT_A); + else + kcode[0] &= ~(key_CONT_DPAD_LEFT); +} + +-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { + + if (dpad_or_btn &1) + kcode[0] |= (key_CONT_START|key_CONT_A); + else + kcode[0] |= (key_CONT_DPAD_LEFT); + + dpad_or_btn++; +} +@end diff --git a/shell/ios/emulator/MainStoryboard.storyboard b/shell/ios/emulator/MainStoryboard.storyboard index 8a0522c90..276a2a495 100644 --- a/shell/ios/emulator/MainStoryboard.storyboard +++ b/shell/ios/emulator/MainStoryboard.storyboard @@ -8,7 +8,7 @@ - + diff --git a/shell/ios/emulator/emulator-Info.plist b/shell/ios/emulator/emulator-Info.plist index 8c59d95a3..f0895e952 100644 --- a/shell/ios/emulator/emulator-Info.plist +++ b/shell/ios/emulator/emulator-Info.plist @@ -2,10 +2,6 @@ - NSHighResolutionCapable - - UIFileSharingEnabled - CFBundleDevelopmentRegion en CFBundleDisplayName @@ -35,6 +31,10 @@ 1.0 LSRequiresIPhoneOS + NSHighResolutionCapable + + UIFileSharingEnabled + UILaunchStoryboardName MainStoryboard UIMainStoryboardFile diff --git a/shell/ios/emulator/ios_main.mm b/shell/ios/emulator/ios_main.mm index 0bc2df4af..42c151887 100644 --- a/shell/ios/emulator/ios_main.mm +++ b/shell/ios/emulator/ios_main.mm @@ -54,6 +54,8 @@ extern "C" int reicast_main(int argc, wchar* argv[]) string homedir = [ [[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] objectAtIndex:0] path] UTF8String]; SetHomeDir(homedir); + freopen( (homedir + "/log.txt").c_str(), "wb", stdout); + printf("Home dir is: %s\n",GetPath("/").c_str()); common_linux_setup(); From d33ad6edfb42b19d6b2e85fb0854d4b6d63227f7 Mon Sep 17 00:00:00 2001 From: Stefanos Kornilios Mitsis Poiitidis Date: Fri, 8 May 2015 17:44:27 +0200 Subject: [PATCH 07/20] Updating from linux/x64 --- core/hw/arm7/arm7.cpp | 11 ++- core/hw/pvr/Renderer_if.cpp | 12 ++- core/hw/pvr/Renderer_if.h | 2 +- core/linux-dist/main.cpp | 165 ++++++++++++++++++++++++++++---- core/oslib/alsa_audiostream.cpp | 32 ++++++- core/rend/gles/gles.cpp | 39 +++++++- core/stdclass.h | 2 +- 7 files changed, 233 insertions(+), 30 deletions(-) diff --git a/core/hw/arm7/arm7.cpp b/core/hw/arm7/arm7.cpp index 3d8dcc84a..e625bf0d4 100644 --- a/core/hw/arm7/arm7.cpp +++ b/core/hw/arm7/arm7.cpp @@ -512,8 +512,16 @@ void update_armintc() reg[INTR_PEND].I=e68k_out && armFiqEnable; } +void libAICA_TimeStep(); + #ifdef HOST_NO_AREC -void arm_Run(u32 CycleCount) { arm_Run_(CycleCount); } +void arm_Run(u32 CycleCount) { + for (int i=0;i<32;i++) + { + arm_Run_(CycleCount/32); + libAICA_TimeStep(); + } +} #else extern "C" void CompileCode(); @@ -1594,7 +1602,6 @@ void armv_MOV32(eReg regn, u32 imm) #endif // HOST_CPU -void libAICA_TimeStep(); //Run a timeslice for ARMREC //CycleCount is pretty much fixed to (512*32) for now (might change to a diff constant, but will be constant) void arm_Run(u32 CycleCount) diff --git a/core/hw/pvr/Renderer_if.cpp b/core/hw/pvr/Renderer_if.cpp index f10547b81..a08d7f97d 100644 --- a/core/hw/pvr/Renderer_if.cpp +++ b/core/hw/pvr/Renderer_if.cpp @@ -244,7 +244,8 @@ void* rend_thread(void* p) if (!renderer->Init()) die("rend->init() failed\n"); - renderer->Resize(640, 480); + //we don't know if this is true, so let's not speculate here + //renderer->Resize(640, 480); for(;;) { @@ -258,6 +259,11 @@ cThread rthd(rend_thread,0); bool pend_rend = false; +void rend_resize(int width, int height) { + renderer->Resize(width, height); +} + + void rend_start_render() { pend_rend = false; @@ -311,7 +317,9 @@ void rend_end_render() { #if 1 //also disabled the printf, it takes quite some time ... #if HOST_OS!=OS_WINDOWS && !(defined(_ANDROID) || defined(TARGET_PANDORA)) - if (!re.state) printf("Render > Extended time slice ...\n"); + //too much console spam. + //TODO: how about a counter? + //if (!re.state) printf("Render > Extended time slice ...\n"); #endif #endif diff --git a/core/hw/pvr/Renderer_if.h b/core/hw/pvr/Renderer_if.h index d95fcecb3..f27f5c57a 100644 --- a/core/hw/pvr/Renderer_if.h +++ b/core/hw/pvr/Renderer_if.h @@ -14,7 +14,7 @@ void rend_end_render(); void rend_end_wait(); void rend_set_fb_scale(float x,float y); - +void rend_resize(int width, int height); void rend_text_invl(vram_block* bl); diff --git a/core/linux-dist/main.cpp b/core/linux-dist/main.cpp index 2bd594b6a..5f821ed88 100755 --- a/core/linux-dist/main.cpp +++ b/core/linux-dist/main.cpp @@ -27,7 +27,9 @@ #include #include #endif - + + #include + map x11_keymap; #endif #if !defined(ANDROID) @@ -403,11 +405,13 @@ static Cursor CreateNullCursor(Display *display, Window root) } #endif +int x11_dc_buttons = 0xFFFF; + void UpdateInputState(u32 port) { static char key = 0; - kcode[port]=0xFFFF; + kcode[port]= x11_dc_buttons; rt[port]=0; lt[port]=0; @@ -464,7 +468,39 @@ return; void os_DoEvents() { + #if defined(SUPPORT_X11) + if (x11_win) { + //Handle X11 + XEvent e; + if(XCheckWindowEvent((Display*)x11_disp, (Window)x11_win, KeyPressMask | KeyReleaseMask, &e)) + { + switch(e.type) + { + case KeyPress: + case KeyRelease: + { + int dc_key = x11_keymap[e.xkey.keycode]; + + if (e.type == KeyPress) + x11_dc_buttons &= ~dc_key; + else + x11_dc_buttons |= dc_key; + + //printf("KEY: %d -> %d: %d\n",e.xkey.keycode, dc_key, x11_dc_buttons ); + } + break; + + + { + printf("KEYRELEASE\n"); + } + break; + + } + } + } + #endif } void os_SetWindowText(const char * text) @@ -472,7 +508,7 @@ void os_SetWindowText(const char * text) if (0==x11_win || 0==x11_disp || 1) printf("%s\n",text); #if defined(SUPPORT_X11) - else { + else if (x11_win) { XChangeProperty((Display*)x11_disp, (Window)x11_win, XInternAtom((Display*)x11_disp, "WM_NAME", False), //WM_NAME, XInternAtom((Display*)x11_disp, "UTF8_STRING", False), //UTF8_STRING, @@ -490,6 +526,7 @@ void os_CreateWindow() #if defined(SUPPORT_X11) if (cfgLoadInt("pvr","nox11",0)==0) { + XInitThreads(); // X11 variables Window x11Window = 0; Display* x11Display = 0; @@ -520,15 +557,51 @@ void os_CreateWindow() int depth = CopyFromParent; #if !defined(GLES) - int attr32[] = { GLX_RGBA, GLX_DEPTH_SIZE, 32, GLX_DOUBLEBUFFER, GLX_STENCIL_SIZE, 8, None }; - int attr24[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, GLX_STENCIL_SIZE, 8, None }; + // Get a matching FB config + static int visual_attribs[] = + { + GLX_X_RENDERABLE , True, + GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT, + GLX_RENDER_TYPE , GLX_RGBA_BIT, + GLX_X_VISUAL_TYPE , GLX_TRUE_COLOR, + GLX_RED_SIZE , 8, + GLX_GREEN_SIZE , 8, + GLX_BLUE_SIZE , 8, + GLX_ALPHA_SIZE , 8, + GLX_DEPTH_SIZE , 24, + GLX_STENCIL_SIZE , 8, + GLX_DOUBLEBUFFER , True, + //GLX_SAMPLE_BUFFERS , 1, + //GLX_SAMPLES , 4, + None + }; + + int glx_major, glx_minor; + + // FBConfigs were added in GLX version 1.3. + if ( !glXQueryVersion( x11Display, &glx_major, &glx_minor ) || + ( ( glx_major == 1 ) && ( glx_minor < 3 ) ) || ( glx_major < 1 ) ) + { + printf("Invalid GLX version"); + exit(1); + } + + int fbcount; + GLXFBConfig* fbc = glXChooseFBConfig(x11Display, x11Screen, visual_attribs, &fbcount); + if (!fbc) + { + printf( "Failed to retrieve a framebuffer config\n" ); + exit(1); + } + printf( "Found %d matching FB configs.\n", fbcount ); + + GLXFBConfig bestFbc = fbc[ 0 ]; + XFree( fbc ); + + // Get a visual + XVisualInfo *vi = glXGetVisualFromFBConfig( x11Display, bestFbc ); + printf( "Chosen visual ID = 0x%x\n", vi->visualid ); - XVisualInfo* vi = glXChooseVisual(x11Display, 0, attr32); - if (!vi) - vi = glXChooseVisual(x11Display, 0, attr24); - - if (!vi) - die("Failed to glXChooseVisual"); depth = vi->depth; x11Visual = vi; @@ -580,8 +653,31 @@ void os_CreateWindow() XMapWindow(x11Display, x11Window); #if !defined(GLES) - x11_glc = glXCreateContext(x11Display, x11Visual, NULL, GL_TRUE); - //glXMakeCurrent(x11Display, x11Window, glc); + + #define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 + #define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 + typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*); + + glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0; + glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc) + glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" ); + + verify( glXCreateContextAttribsARB != 0 ); + + int context_attribs[] = { + GLX_CONTEXT_MAJOR_VERSION_ARB, 3, + GLX_CONTEXT_MINOR_VERSION_ARB, 1, + GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB, + GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, + None + }; + + x11_glc = glXCreateContextAttribsARB( x11Display, bestFbc, 0, True, context_attribs); + XSync( x11Display, False ); + + if (!x11_glc) { + die("Failed to create GL3.1 context\n"); + } #endif #endif XFlush(x11Display); @@ -681,8 +777,9 @@ void clean_exit(int sig_num) { void init_sound() { - if((audio_fd=open("/dev/dsp",O_WRONLY))<0) + if((audio_fd=open("/dev/dsp",O_WRONLY))<0) { printf("Couldn't open /dev/dsp.\n"); + } else { printf("sound enabled, dsp openned for write\n"); @@ -711,6 +808,9 @@ int main(int argc, wchar* argv[]) signal(SIGKILL, clean_exit); init_sound(); +#else + void os_InitAudio(); + os_InitAudio(); #endif #if defined(USES_HOMEDIR) @@ -727,6 +827,27 @@ int main(int argc, wchar* argv[]) SetHomeDir("."); #endif + #if defined(SUPPORT_X11) + x11_keymap[113] = DPad_Left; + x11_keymap[114] = DPad_Right; + + x11_keymap[111] = DPad_Up; + x11_keymap[116] = DPad_Down; + + x11_keymap[52] = Btn_Y; + x11_keymap[53] = Btn_X; + x11_keymap[54] = Btn_B; + x11_keymap[55] = Btn_A; + + /* + //TODO: Fix sliders + x11_keymap[38] = DPad_Down; + x11_keymap[39] = DPad_Down; + */ + + x11_keymap[36] = Btn_Start; + #endif + printf("Home dir is: %s\n",GetPath("/").c_str()); common_linux_setup(); @@ -746,12 +867,20 @@ int main(int argc, wchar* argv[]) return 0; } +u32 alsa_Push(void* frame, u32 samples, bool wait); u32 os_Push(void* frame, u32 samples, bool wait) { -#ifdef TARGET_PANDORA - write(audio_fd, frame, samples*4); -#endif -return 1; + #ifndef TARGET_PANDORA + int audio_fd = -1; + #endif + + if (audio_fd > 0) { + write(audio_fd, frame, samples*4); + } else { + return alsa_Push(frame, samples, wait); + } + + return 1; } #endif diff --git a/core/oslib/alsa_audiostream.cpp b/core/oslib/alsa_audiostream.cpp index 055fe778d..801d6bc7b 100644 --- a/core/oslib/alsa_audiostream.cpp +++ b/core/oslib/alsa_audiostream.cpp @@ -4,14 +4,37 @@ #include "cfg/cfg.h" -#if 0 && HOST_OS==OS_LINUX && !defined(TARGET_NACL32) +#if HOST_OS==OS_LINUX && !defined(TARGET_NACL32) && !defined(ANDROID) -#if !defined(ANDROID) +#if 1 #include #include snd_pcm_t *handle; +u32 alsa_Push(void* frame, u32 samples, bool wait) { + + snd_pcm_nonblock(handle, wait ? 0 : 1); + + int rc = snd_pcm_writei(handle, frame, samples); + if (rc == -EPIPE) + { + /* EPIPE means underrun */ + fprintf(stderr, "ALSA: underrun occurred\n"); + snd_pcm_prepare(handle); + alsa_Push(frame, samples * 8, wait); + } + else if (rc < 0) + { + fprintf(stderr, "ALSA: error from writei: %s\n", snd_strerror(rc)); + } + else if (rc != samples) + { + fprintf(stderr, "ALSA: short write, wrote %d frames of %d\n", rc, samples); + } + return 1; +} +#if 0 u8 Tempbuffer[8192*4]; void* AudioThread(void*) { @@ -44,6 +67,7 @@ void* AudioThread(void*) } cThread aud_thread(AudioThread,0); +#endif void os_InitAudio() { @@ -123,7 +147,7 @@ void os_InitAudio() } /* Set period size to settings.aica.BufferSize frames. */ - frames = settings.aica.BufferSize; + frames = 2 * 1024;//settings.aica.BufferSize; rc=snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir); if (rc < 0) { @@ -145,8 +169,6 @@ void os_InitAudio() fprintf(stderr, "Unable to set hw parameters: %s\n", snd_strerror(rc)); return; } - - aud_thread.Start(); } void os_TermAudio() diff --git a/core/rend/gles/gles.cpp b/core/rend/gles/gles.cpp index a0b079d68..97235ae9b 100755 --- a/core/rend/gles/gles.cpp +++ b/core/rend/gles/gles.cpp @@ -617,12 +617,39 @@ int screen_height; (GLXDrawable)libPvr_GetRenderTarget(), (GLXContext)x11_glc); + screen_width = 640; + screen_height = 480; return gl3wInit() != -1 && gl3wIsSupported(3, 1); } void gl_swap() { glXSwapBuffers((Display*)libPvr_GetRenderSurface(), (GLXDrawable)libPvr_GetRenderTarget()); + + Window win; + int temp; + unsigned int tempu, new_w, new_h; + XGetGeometry((Display*)libPvr_GetRenderSurface(), (GLXDrawable)libPvr_GetRenderTarget(), + &win, &temp, &temp, &new_w, &new_h,&tempu,&tempu); + + //if resized, clear up the draw buffers, to avoid out-of-draw-area junk data + if (new_w != screen_width || new_h != screen_height) { + screen_width = new_w; + screen_height = new_h; + } + + #if 0 + //handy to debug really stupid render-not-working issues ... + + glClearColor( 0, 0.5, 1, 1 ); + glClear( GL_COLOR_BUFFER_BIT ); + glXSwapBuffers((Display*)libPvr_GetRenderSurface(), (GLXDrawable)libPvr_GetRenderTarget()); + + + glClearColor ( 1, 0.5, 0, 1 ); + glClear ( GL_COLOR_BUFFER_BIT ); + glXSwapBuffers((Display*)libPvr_GetRenderSurface(), (GLXDrawable)libPvr_GetRenderTarget()); + #endif } #endif #endif @@ -1411,6 +1438,7 @@ bool RenderFrame() bool is_rtt=pvrrc.isRTT; + OSD_HOOK(); //if (FrameCount&7) return; @@ -1745,6 +1773,14 @@ bool RenderFrame() //not all scaling affects pixel operations, scale to adjust for that scale_x *= scissoring_scale_x; + + #if 0 + //handy to debug really stupid render-not-working issues ... + printf("SS: %dx%d\n", screen_width, screen_height); + printf("SCI: %d, %f\n", pvrrc.fb_X_CLIP.max, dc2s_scale_h); + printf("SCI: %f, %f, %f, %f\n", offs_x+pvrrc.fb_X_CLIP.min/scale_x,(pvrrc.fb_Y_CLIP.min/scale_y)*dc2s_scale_h,(pvrrc.fb_X_CLIP.max-pvrrc.fb_X_CLIP.min+1)/scale_x*dc2s_scale_h,(pvrrc.fb_Y_CLIP.max-pvrrc.fb_Y_CLIP.min+1)/scale_y*dc2s_scale_h); + #endif + glScissor(offs_x+pvrrc.fb_X_CLIP.min/scale_x,(pvrrc.fb_Y_CLIP.min/scale_y)*dc2s_scale_h,(pvrrc.fb_X_CLIP.max-pvrrc.fb_X_CLIP.min+1)/scale_x*dc2s_scale_h,(pvrrc.fb_Y_CLIP.max-pvrrc.fb_Y_CLIP.min+1)/scale_y*dc2s_scale_h); if (settings.rend.WideScreen && pvrrc.fb_X_CLIP.min==0 && ((pvrrc.fb_X_CLIP.max+1)/scale_x==640) && (pvrrc.fb_Y_CLIP.min==0) && ((pvrrc.fb_Y_CLIP.max+1)/scale_y==480 ) ) { @@ -1753,6 +1789,7 @@ bool RenderFrame() else glEnable(GL_SCISSOR_TEST); + //restore scale_x scale_x /= scissoring_scale_x; @@ -1812,7 +1849,7 @@ void rend_set_fb_scale(float x,float y) struct glesrend : Renderer { bool Init() { return gles_init(); } - void Resize(int w, int h) { } + void Resize(int w, int h) { screen_width=w; screen_height=h; } void Term() { } bool Process(TA_context* ctx) { return ProcessFrame(ctx); } diff --git a/core/stdclass.h b/core/stdclass.h index f7f351bbc..529927e33 100644 --- a/core/stdclass.h +++ b/core/stdclass.h @@ -220,7 +220,7 @@ public : #if HOST_OS==OS_WINDOWS InitializeCriticalSection(&cs); #else - mutx=PTHREAD_MUTEX_INITIALIZER; + pthread_mutex_init ( &mutx, NULL); #endif } ~cMutex() From 5b609a6be4a17b2a8835e346f3866868795d28ca Mon Sep 17 00:00:00 2001 From: Stefanos Kornilios Mitsis Poiitidis Date: Fri, 8 May 2015 18:59:20 +0200 Subject: [PATCH 08/20] linux: Sh4 dynarec works --- core/emitter/x86_matcher.h | 12 ++++++------ core/emitter/x86_op_encoder.h | 10 +++++----- core/hw/arm7/virt_arm.cpp | 2 +- core/hw/sh4/dyna/blockmanager.cpp | 14 +++++++------- core/hw/sh4/dyna/blockmanager.h | 8 ++++---- core/hw/sh4/dyna/driver.cpp | 16 ++++++++-------- core/hw/sh4/dyna/ngen.h | 10 +++++----- core/hw/sh4/sh4_mem.h | 2 -- core/hw/sh4/sh4_mmr.h | 2 +- core/linux/common.cpp | 28 ++++++++++++++++++++++------ core/rec-ARM/arm_dyna.cpp | 2 +- core/rec-x86/win86_driver.cpp | 2 +- core/types.h | 6 ++---- core/windows/win86_driver.cpp | 2 +- 14 files changed, 64 insertions(+), 52 deletions(-) diff --git a/core/emitter/x86_matcher.h b/core/emitter/x86_matcher.h index a1ec8bd41..9bcaa05fc 100644 --- a/core/emitter/x86_matcher.h +++ b/core/emitter/x86_matcher.h @@ -20,7 +20,7 @@ enum x86_op_params encoded_type pg_none = {pg_NONE}; -encoded_type __fastcall param_type(x86_Label* lbl) +encoded_type param_type(x86_Label* lbl) { encoded_type rv; //Return pg_MEM_Rel32/pg_MEM_Rel16/pg_MEM_Rel8 @@ -33,7 +33,7 @@ encoded_type __fastcall param_type(x86_Label* lbl) rv.ptr_type=1; return rv; } -encoded_type __fastcall param_type(x86_ptr_imm ptr) +encoded_type param_type(x86_ptr_imm ptr) { encoded_type rv; //Return pg_MEM_Rel32.Due to relocation we cant optimise to 16/8 in one pass ... @@ -43,7 +43,7 @@ encoded_type __fastcall param_type(x86_ptr_imm ptr) rv.ptr_type=0; return rv; } -encoded_type __fastcall param_type(x86_mrm_t& modrm) +encoded_type param_type(x86_mrm_t& modrm) { encoded_type rv; rv.modrm=modrm; @@ -51,7 +51,7 @@ encoded_type __fastcall param_type(x86_mrm_t& modrm) rv.type=pg_ModRM; return rv; } -encoded_type __fastcall param_type(x86_reg reg) +encoded_type param_type(x86_reg reg) { encoded_type rv; rv.reg=REG_ID(reg); @@ -65,7 +65,7 @@ encoded_type __fastcall param_type(x86_reg reg) return rv; } -encoded_type __fastcall param_type(u32 imm) +encoded_type param_type(u32 imm) { encoded_type rv; rv.imm=imm; @@ -82,7 +82,7 @@ encoded_type __fastcall param_type(u32 imm) return rv; } -void __fastcall Match_opcode(x86_block* block,const x86_opcode* ops,encoded_type pg1,encoded_type pg2,encoded_type pg3) +void Match_opcode(x86_block* block,const x86_opcode* ops,encoded_type pg1,encoded_type pg2,encoded_type pg3) { block->opcode_count++; const x86_opcode* match=0; diff --git a/core/emitter/x86_op_encoder.h b/core/emitter/x86_op_encoder.h index fd6c03244..0f3e9db9c 100644 --- a/core/emitter/x86_op_encoder.h +++ b/core/emitter/x86_op_encoder.h @@ -61,7 +61,7 @@ #include "build.h" #if BUILD_COMPILER == COMPILER_GCC - #define __fastcall + #define __fastcall BALLZZ!! #endif @@ -173,7 +173,7 @@ struct encoded_type struct x86_opcode; -typedef void __fastcall x86_opcode_encoderFP(x86_block* block,const x86_opcode* op,encoded_type* p1,encoded_type* p2,u32 p3); +typedef void x86_opcode_encoderFP(x86_block* block,const x86_opcode* op,encoded_type* p1,encoded_type* p2,u32 p3); //enc_param_none is alower w/ params set to implicit registers (ie , mov eax,xxxx is enc_imm , pg1:pg_EAX , pg2:pg_imm @@ -190,7 +190,7 @@ struct x86_opcode }; //mod|reg|rm -void __fastcall encode_modrm(x86_block* block,encoded_type* mrm, u32 extra) +void encode_modrm(x86_block* block,encoded_type* mrm, u32 extra) { if (mrm->type != pg_ModRM) { @@ -213,7 +213,7 @@ void __fastcall encode_modrm(x86_block* block,encoded_type* mrm, u32 extra) } #ifdef X64 //x64 stuff -void __fastcall encode_rex(x86_block* block,encoded_type* mrm,u32 mrm_reg,u32 ofe=0) +void encode_rex(x86_block* block,encoded_type* mrm,u32 mrm_reg,u32 ofe=0) { u32 flags = (ofe>>3) & 1; //opcode field extension @@ -237,7 +237,7 @@ void __fastcall encode_rex(x86_block* block,encoded_type* mrm,u32 mrm_reg,u32 of //Encoding function (partially) specialised by templates to gain speed :) template < enc_param enc_1,enc_imm enc_2,u32 sz,x86_operand_size enc_op_size> -void __fastcall x86_encode_opcode_tmpl(x86_block* block, const x86_opcode* op, encoded_type* p1,encoded_type* p2,u32 p3) +void x86_encode_opcode_tmpl(x86_block* block, const x86_opcode* op, encoded_type* p1,encoded_type* p2,u32 p3) { //printf("Encoding : "); diff --git a/core/hw/arm7/virt_arm.cpp b/core/hw/arm7/virt_arm.cpp index d55c4dda1..f9aef686b 100644 --- a/core/hw/arm7/virt_arm.cpp +++ b/core/hw/arm7/virt_arm.cpp @@ -311,7 +311,7 @@ void virt_arm_init() VARM::virt_arm_init(); } -u32 __fastcall virt_arm_op(u32 opcode) +u32 DYNACALL virt_arm_op(u32 opcode) { return VARM::virt_arm_op(opcode); } diff --git a/core/hw/sh4/dyna/blockmanager.cpp b/core/hw/sh4/dyna/blockmanager.cpp index eec9cdd4b..cb84ca4c3 100644 --- a/core/hw/sh4/dyna/blockmanager.cpp +++ b/core/hw/sh4/dyna/blockmanager.cpp @@ -87,24 +87,24 @@ blkmap_t blkmap; u32 bm_gc_luc,bm_gcf_luc; -#define FPCA(x) ((DynarecCodeEntry*&)sh4rcb.fpcb[(x>>1)&(8*1024*1024-1)]) +#define FPCA(x) ((DynarecCodeEntryPtr&)sh4rcb.fpcb[(x>>1)&(8*1024*1024-1)]) -DynarecCodeEntry* DYNACALL bm_GetCode(u32 addr) +DynarecCodeEntryPtr DYNACALL bm_GetCode(u32 addr) { //rdv_FailedToFindBlock_pc=addr; - DynarecCodeEntry* rv=(DynarecCodeEntry*)FPCA(addr); + DynarecCodeEntryPtr rv=(DynarecCodeEntryPtr)FPCA(addr); - return (DynarecCodeEntry*)rv; + return (DynarecCodeEntryPtr)rv; } -DynarecCodeEntry* DYNACALL bm_GetCode2(u32 addr) +DynarecCodeEntryPtr DYNACALL bm_GetCode2(u32 addr) { - return (DynarecCodeEntry*)bm_GetCode(addr); + return (DynarecCodeEntryPtr)bm_GetCode(addr); } RuntimeBlockInfo* DYNACALL bm_GetBlock(u32 addr) { - DynarecCodeEntry* cde=bm_GetCode(addr); + DynarecCodeEntryPtr cde=bm_GetCode(addr); if (cde==ngen_FailedToFindBlock) return 0; diff --git a/core/hw/sh4/dyna/blockmanager.h b/core/hw/sh4/dyna/blockmanager.h index c8876fc90..8f87dc03a 100644 --- a/core/hw/sh4/dyna/blockmanager.h +++ b/core/hw/sh4/dyna/blockmanager.h @@ -5,12 +5,12 @@ #include "decoder.h" #pragma once -typedef void DynarecCodeEntry(); +typedef void (*DynarecCodeEntryPtr)(); struct RuntimeBlockInfo_Core { u32 addr; - DynarecCodeEntry* code; + DynarecCodeEntryPtr code; u32 lookups; }; @@ -81,13 +81,13 @@ struct CachedBlockInfo: RuntimeBlockInfo_Core void bm_WriteBlockMap(const string& file); -DynarecCodeEntry* DYNACALL bm_GetCode(u32 addr); +DynarecCodeEntryPtr DYNACALL bm_GetCode(u32 addr); #if HOST_OS==OS_LINUX extern "C" { #endif -DynarecCodeEntry* DYNACALL bm_GetCode2(u32 addr); +DynarecCodeEntryPtr DYNACALL bm_GetCode2(u32 addr); #if HOST_OS==OS_LINUX } #endif diff --git a/core/hw/sh4/dyna/driver.cpp b/core/hw/sh4/dyna/driver.cpp index 669c39a95..2d22045b7 100644 --- a/core/hw/sh4/dyna/driver.cpp +++ b/core/hw/sh4/dyna/driver.cpp @@ -208,7 +208,7 @@ void RuntimeBlockInfo::Setup(u32 rpc,fpscr_t rfpu_cfg) AnalyseBlock(this); } -DynarecCodeEntry* rdv_CompilePC() +DynarecCodeEntryPtr rdv_CompilePC() { u32 pc=next_pc; @@ -240,7 +240,7 @@ DynarecCodeEntry* rdv_CompilePC() return rv->code; } -DynarecCodeEntry* DYNACALL rdv_FailedToFindBlock(u32 pc) +DynarecCodeEntryPtr DYNACALL rdv_FailedToFindBlock(u32 pc) { //printf("rdv_FailedToFindBlock ~ %08X\n",pc); next_pc=pc; @@ -269,25 +269,25 @@ u32 DYNACALL rdv_DoInterrupts(void* block_cpde) return next_pc; } -DynarecCodeEntry* DYNACALL rdv_BlockCheckFail(u32 pc) +DynarecCodeEntryPtr DYNACALL rdv_BlockCheckFail(u32 pc) { next_pc=pc; recSh4_ClearCache(); return rdv_CompilePC(); } -DynarecCodeEntry* rdv_FindCode() +DynarecCodeEntryPtr rdv_FindCode() { - DynarecCodeEntry* rv=bm_GetCode(next_pc); + DynarecCodeEntryPtr rv=bm_GetCode(next_pc); if (rv==ngen_FailedToFindBlock) return 0; return rv; } -DynarecCodeEntry* rdv_FindOrCompile() +DynarecCodeEntryPtr rdv_FindOrCompile() { - DynarecCodeEntry* rv=bm_GetCode(next_pc); + DynarecCodeEntryPtr rv=bm_GetCode(next_pc); if (rv==ngen_FailedToFindBlock) rv=rdv_CompilePC(); @@ -324,7 +324,7 @@ void* DYNACALL rdv_LinkBlock(u8* code,u32 dpc) next_pc=rbi->NextBlock; } - DynarecCodeEntry* rv=rdv_FindOrCompile(); + DynarecCodeEntryPtr rv=rdv_FindOrCompile(); bool do_link=bm_GetBlock(code)==rbi; diff --git a/core/hw/sh4/dyna/ngen.h b/core/hw/sh4/dyna/ngen.h index 1a7592fa8..d41fd60d7 100644 --- a/core/hw/sh4/dyna/ngen.h +++ b/core/hw/sh4/dyna/ngen.h @@ -63,15 +63,15 @@ void* emit_GetCCPtr(); void emit_SetBaseAddr(); //Called from ngen_FailedToFindBlock -DynarecCodeEntry* DYNACALL rdv_FailedToFindBlock(u32 pc); +DynarecCodeEntryPtr DYNACALL rdv_FailedToFindBlock(u32 pc); //Called when a block check failed, and the block needs to be invalidated -DynarecCodeEntry* DYNACALL rdv_BlockCheckFail(u32 pc); +DynarecCodeEntryPtr DYNACALL rdv_BlockCheckFail(u32 pc); //Called to compile code @pc -DynarecCodeEntry* rdv_CompilePC(); +DynarecCodeEntryPtr rdv_CompilePC(); //Returns 0 if there is no code @pc, code ptr otherwise -DynarecCodeEntry* rdv_FindCode(); +DynarecCodeEntryPtr rdv_FindCode(); //Finds or compiles code @pc -DynarecCodeEntry* rdv_FindOrCompile(); +DynarecCodeEntryPtr rdv_FindOrCompile(); //code -> pointer to code of block, dpc -> if dynamic block, pc. if cond, 0 for next, 1 for branch void* DYNACALL rdv_LinkBlock(u8* code,u32 dpc); diff --git a/core/hw/sh4/sh4_mem.h b/core/hw/sh4/sh4_mem.h index 5b3a051ca..f9f132f90 100644 --- a/core/hw/sh4/sh4_mem.h +++ b/core/hw/sh4/sh4_mem.h @@ -4,8 +4,6 @@ //main system mem extern VArray2 mem_b; -#define MEMCALL __fastcall - #include "hw/mem/_vmem.h" #include "modules/mmu.h" diff --git a/core/hw/sh4/sh4_mmr.h b/core/hw/sh4/sh4_mmr.h index 740c9969f..2bfead711 100644 --- a/core/hw/sh4/sh4_mmr.h +++ b/core/hw/sh4/sh4_mmr.h @@ -31,7 +31,7 @@ void WriteMem_P4(u32 addr,u32 data,u32 sz); //Area7 u32 ReadMem_area7(u32 addr,u32 sz); void WriteMem_area7(u32 addr,u32 data,u32 sz); -void __fastcall WriteMem_sq_32(u32 address,u32 data);*/ +void DYNACALL WriteMem_sq_32(u32 address,u32 data);*/ //Init/Res/Term void sh4_mmr_init(); diff --git a/core/linux/common.cpp b/core/linux/common.cpp index cdd536c2b..98a08b5ff 100644 --- a/core/linux/common.cpp +++ b/core/linux/common.cpp @@ -47,6 +47,9 @@ struct sigcontext uc_mcontext; #define GET_PC_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.eip) #else #define GET_PC_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.gregs[REG_EIP]) +#define GET_ESP_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.gregs[REG_ESP]) +#define GET_EAX_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.gregs[REG_EAX]) +#define GET_ECX_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.gregs[REG_ECX]) #endif #else #error fix ->pc support @@ -54,6 +57,7 @@ struct sigcontext uc_mcontext; #include "hw/sh4/dyna/ngen.h" +bool ngen_Rewrite(unat& addr,unat retadr,unat acc); u32* ngen_readm_fail_v2(u32* ptr,u32* regs,u32 saddr); bool VramLockedWrite(u8* address); bool BM_LockedWrite(u8* address); @@ -68,12 +72,24 @@ void fault_handler (int sn, siginfo_t * si, void *ctxr) if (VramLockedWrite((u8*)si->si_addr) || BM_LockedWrite((u8*)si->si_addr)) return; -#if !defined( HOST_NO_REC) && HOST_CPU==CPU_ARM - else if (dyna_cde) - { - GET_PC_FROM_CONTEXT(ctxr)=(u32)ngen_readm_fail_v2((u32*)GET_PC_FROM_CONTEXT(ctxr),(u32*)&(ctx->uc_mcontext.arm_r0),(unat)si->si_addr); - } -#endif + #if !defined(HOST_NO_REC) + #if HOST_CPU==CPU_ARM + else if (dyna_cde) + { + GET_PC_FROM_CONTEXT(ctxr)=(u32)ngen_readm_fail_v2((u32*)GET_PC_FROM_CONTEXT(ctxr),(u32*)&(ctx->uc_mcontext.arm_r0),(unat)si->si_addr); + } + #elif HOST_CPU==CPU_X86 + else if ( ngen_Rewrite((unat&)GET_PC_FROM_CONTEXT(ctxr),*(unat*)GET_ESP_FROM_CONTEXT(ctxr),GET_EAX_FROM_CONTEXT(ctxr)) ) + { + //remove the call from call stack + GET_ESP_FROM_CONTEXT(ctxr)+=4; + //restore the addr from eax to ecx so its valid again + GET_ECX_FROM_CONTEXT(ctxr)=GET_EAX_FROM_CONTEXT(ctxr); + } + #else + #error JIT: Not supported arch + #endif + #endif else { printf("SIGSEGV @ fault_handler+0x%08X ... %08X -> was not in vram\n",GET_PC_FROM_CONTEXT(ctxr)-(u32)fault_handler,si->si_addr); diff --git a/core/rec-ARM/arm_dyna.cpp b/core/rec-ARM/arm_dyna.cpp index 7cfff89cd..45325e326 100755 --- a/core/rec-ARM/arm_dyna.cpp +++ b/core/rec-ARM/arm_dyna.cpp @@ -1979,7 +1979,7 @@ __default: void ngen_Compile(RuntimeBlockInfo* block,bool force_checks, bool reset, bool staging,bool optimise) { //printf("Compile: %08X, %d, %d\n",block->addr,staging,optimise); - block->code=(DynarecCodeEntry*)EMIT_GET_PTR(); + block->code=(DynarecCodeEntryPtr)EMIT_GET_PTR(); //StoreImms(r0,r1,(u32)&last_run_block,(u32)code); //useful when code jumps to random locations ... ++blockno; diff --git a/core/rec-x86/win86_driver.cpp b/core/rec-x86/win86_driver.cpp index 4c85b6b24..a7c3d6e99 100644 --- a/core/rec-x86/win86_driver.cpp +++ b/core/rec-x86/win86_driver.cpp @@ -301,7 +301,7 @@ void ngen_Compile(RuntimeBlockInfo* block,bool force_checks, bool reset, bool st x86e->x86_size=emit_FreeSpace(); x86e->do_realloc=false; - block->code=(DynarecCodeEntry*)emit_GetCCPtr(); + block->code=(DynarecCodeEntryPtr)emit_GetCCPtr(); x86e->Emit(op_add32,&memops_t,block->memops); x86e->Emit(op_add32,&memops_l,block->linkedmemops); diff --git a/core/types.h b/core/types.h index 62d8ee578..e46a604f5 100644 --- a/core/types.h +++ b/core/types.h @@ -13,10 +13,8 @@ #if BUILD_COMPILER==COMPILER_VC #define DYNACALL __fastcall -#define DYNACALL_T #else -#define DYNACALL -#define DYNACALL_T __attribute__((fastcall)) +#define DYNACALL __attribute__((fastcall)) #endif #if BUILD_COMPILER==COMPILER_VC @@ -511,7 +509,7 @@ void os_DebugBreak(); #define stricmp strcasecmp #endif -//#define __fastcall +#define __fastcall #ifndef STRIP_TEXT #define verify(x) if((x)==false){ msgboxf("Verify Failed : " #x "\n in %s -> %s : %d \n",MBX_ICONERROR,(__FUNCTION__),(__FILE__),__LINE__); dbgbreak;} #define die(reason) { msgboxf("Fatal error : %s\n in %s -> %s : %d \n",MBX_ICONERROR,(reason),(__FUNCTION__),(__FILE__),__LINE__); dbgbreak;} diff --git a/core/windows/win86_driver.cpp b/core/windows/win86_driver.cpp index 41efb2630..384df8f51 100644 --- a/core/windows/win86_driver.cpp +++ b/core/windows/win86_driver.cpp @@ -299,7 +299,7 @@ void ngen_Compile(RuntimeBlockInfo* block,bool force_checks, bool reset, bool st x86e->x86_size=emit_FreeSpace(); x86e->do_realloc=false; - block->code=(DynarecCodeEntry*)emit_GetCCPtr(); + block->code=(DynarecCodeEntryPtr)emit_GetCCPtr(); x86e->Emit(op_add32,&memops_t,block->memops); x86e->Emit(op_add32,&memops_l,block->linkedmemops); From cf473a14a4835e74ba4b002fecb1f4e47a7a09ea Mon Sep 17 00:00:00 2001 From: Stefanos Kornilios Mitsis Poiitidis Date: Fri, 15 May 2015 23:33:47 +0200 Subject: [PATCH 09/20] x86 jit: fix android --- core/rec-x86/lin86_asm.S | 10 ++++++++++ core/rec-x86/win86_driver.cpp | 11 ++++++++++- core/types.h | 14 ++++++++++---- shell/android/jni/Android.mk | 12 +++++++++++- shell/reicast.vcxproj | 15 +++++++++++++++ shell/reicast.vcxproj.filters | 18 ++++++++++++++++++ 6 files changed, 74 insertions(+), 6 deletions(-) diff --git a/core/rec-x86/lin86_asm.S b/core/rec-x86/lin86_asm.S index 4918f4313..612cc4e89 100644 --- a/core/rec-x86/lin86_asm.S +++ b/core/rec-x86/lin86_asm.S @@ -83,6 +83,11 @@ ngen_FailedToFindBlock_: .type ngen_mainloop, @function ngen_mainloop: + # quick hack to maintain 16-byte alignment + push esi + push esi + push esi + push esi push edi push ebp @@ -122,6 +127,11 @@ cleanup: pop ebp pop edi pop esi + + # quick hack to maintain 16-byte alignment + pop esi + pop esi + pop esi ret diff --git a/core/rec-x86/win86_driver.cpp b/core/rec-x86/win86_driver.cpp index a7c3d6e99..7d7122a08 100644 --- a/core/rec-x86/win86_driver.cpp +++ b/core/rec-x86/win86_driver.cpp @@ -640,6 +640,9 @@ void gen_hande(u32 w, u32 sz, u32 mode) { //General + //maintain 16 byte alignment + x86e->Emit(op_sub32, ESP, 12); + if ((sz==SZ_32F || sz==SZ_64F) && w==1) { if (sz==SZ_32F) @@ -648,7 +651,6 @@ void gen_hande(u32 w, u32 sz, u32 mode) } else { - x86e->Emit(op_sub32,ESP,8); x86e->Emit(op_movss,x86_mrm(ESP,x86_ptr::create(+4)),XMM1); x86e->Emit(op_movss,x86_mrm(ESP,x86_ptr::create(-0)),XMM0); } @@ -664,6 +666,13 @@ void gen_hande(u32 w, u32 sz, u32 mode) x86e->Emit(op_movd_xmm_from_r32,XMM1,EDX); } } + + if ((sz == SZ_64F) && w == 1) { + x86e->Emit(op_add32, ESP, 4); + } + else { + x86e->Emit(op_add32, ESP, 12); + } } x86e->Emit(op_ret); diff --git a/core/types.h b/core/types.h index e46a604f5..09e125217 100644 --- a/core/types.h +++ b/core/types.h @@ -11,10 +11,17 @@ #endif -#if BUILD_COMPILER==COMPILER_VC -#define DYNACALL __fastcall +#if HOST_CPU == CPU_X86 + + #if BUILD_COMPILER==COMPILER_VC + #define DYNACALL __fastcall + #else + //android defines fastcall as regparm(3), it doesn't work for us + #undef fastcall + #define DYNACALL __attribute__((fastcall)) + #endif #else -#define DYNACALL __attribute__((fastcall)) + #define DYNACALL #endif #if BUILD_COMPILER==COMPILER_VC @@ -509,7 +516,6 @@ void os_DebugBreak(); #define stricmp strcasecmp #endif -#define __fastcall #ifndef STRIP_TEXT #define verify(x) if((x)==false){ msgboxf("Verify Failed : " #x "\n in %s -> %s : %d \n",MBX_ICONERROR,(__FUNCTION__),(__FILE__),__LINE__); dbgbreak;} #define die(reason) { msgboxf("Fatal error : %s\n in %s -> %s : %d \n",MBX_ICONERROR,(reason),(__FUNCTION__),(__FILE__),__LINE__); dbgbreak;} diff --git a/shell/android/jni/Android.mk b/shell/android/jni/Android.mk index ec4ce06f3..d63f41327 100644 --- a/shell/android/jni/Android.mk +++ b/shell/android/jni/Android.mk @@ -24,7 +24,11 @@ WEBUI := 1 ifneq ($(TARGET_ARCH_ABI),armeabi-v7a) NOT_ARM := 1 - NO_REC := 1 + ifneq ($(TARGET_ARCH_ABI),x86) + NO_REC := 1 + else + X86_REC := 1 + endif endif ifeq ($(TARGET_ARCH_ABI),mips) @@ -40,6 +44,12 @@ LOCAL_CFLAGS := $(RZDCY_CFLAGS) -fvisibility=hidden -fvisibility-inlines-hidden LOCAL_CXXFLAGS := $(RZDCY_CXXFLAGS) -fvisibility=hidden -fvisibility-inlines-hidden -ffunction-sections -fdata-sections LOCAL_CPPFLAGS := $(RZDCY_CXXFLAGS) -fvisibility=hidden -fvisibility-inlines-hidden -ffunction-sections -fdata-sections +ifeq ($(TARGET_ARCH_ABI),x86) + LOCAL_CFLAGS+= -DHOST_NO_AREC + LOCAL_CXXFLAGS+= -DHOST_NO_AREC -fpermissive + LOCAL_CPPFLAGS+= -DHOST_NO_AREC +endif + LOCAL_CPP_FEATURES := LOCAL_SHARED_LIBRARIES:= libcutils libutils LOCAL_PRELINK_MODULE := false diff --git a/shell/reicast.vcxproj b/shell/reicast.vcxproj index 6315fa26a..cbde1546b 100644 --- a/shell/reicast.vcxproj +++ b/shell/reicast.vcxproj @@ -157,6 +157,15 @@ true true + + true + + + true + + + true + @@ -290,6 +299,9 @@ + + true + @@ -310,6 +322,9 @@ true true + + true + {58B14048-EACB-4780-8B1E-9C84C2C30A8E} diff --git a/shell/reicast.vcxproj.filters b/shell/reicast.vcxproj.filters index 83249949a..ba43d8d0f 100644 --- a/shell/reicast.vcxproj.filters +++ b/shell/reicast.vcxproj.filters @@ -411,6 +411,15 @@ reios + + rec-x86 + + + rec-x86 + + + rec-x86 + @@ -533,6 +542,9 @@ {f614dd66-5d30-4548-a209-f857f95fb505} + + {df854851-d3b5-4549-8248-acdfa954be44} + @@ -895,6 +907,9 @@ reios + + rec-x86 + @@ -903,5 +918,8 @@ rec-ARM + + rec-x86 + \ No newline at end of file From 30709c948ef27f4e4f0fc8d6b1a01133505522d9 Mon Sep 17 00:00:00 2001 From: Stefanos Kornilios Mitsis Poiitidis Date: Fri, 15 May 2015 23:35:25 +0200 Subject: [PATCH 10/20] Android makefile: C doesn't support -fvisibility-inlines-hidden --- shell/android/jni/Android.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/android/jni/Android.mk b/shell/android/jni/Android.mk index d63f41327..4d4b27d1f 100644 --- a/shell/android/jni/Android.mk +++ b/shell/android/jni/Android.mk @@ -40,7 +40,7 @@ include $(LOCAL_PATH)/../../core/core.mk LOCAL_SRC_FILES := $(RZDCY_FILES) LOCAL_SRC_FILES += $(wildcard $(LOCAL_PATH)/jni/src/Android.cpp) LOCAL_SRC_FILES += $(wildcard $(LOCAL_PATH)/jni/src/utils.cpp) -LOCAL_CFLAGS := $(RZDCY_CFLAGS) -fvisibility=hidden -fvisibility-inlines-hidden -ffunction-sections -fdata-sections +LOCAL_CFLAGS := $(RZDCY_CFLAGS) -fvisibility=hidden -ffunction-sections -fdata-sections LOCAL_CXXFLAGS := $(RZDCY_CXXFLAGS) -fvisibility=hidden -fvisibility-inlines-hidden -ffunction-sections -fdata-sections LOCAL_CPPFLAGS := $(RZDCY_CXXFLAGS) -fvisibility=hidden -fvisibility-inlines-hidden -ffunction-sections -fdata-sections From a2ac4015d1194454973581e8142054a387737126 Mon Sep 17 00:00:00 2001 From: Stefanos Kornilios Mitsis Poiitidis Date: Sat, 16 May 2015 00:31:25 +0200 Subject: [PATCH 11/20] Android/Makefile: Fix build by avoiding var-leakage Apparently include $(CLEAR_VARS) doesn't quite do what one expects --- shell/android/jni/Android.mk | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/shell/android/jni/Android.mk b/shell/android/jni/Android.mk index 4d4b27d1f..80b9fbac9 100644 --- a/shell/android/jni/Android.mk +++ b/shell/android/jni/Android.mk @@ -24,17 +24,26 @@ WEBUI := 1 ifneq ($(TARGET_ARCH_ABI),armeabi-v7a) NOT_ARM := 1 - ifneq ($(TARGET_ARCH_ABI),x86) - NO_REC := 1 - else - X86_REC := 1 - endif +else + NOT_ARM := +endif + +ifeq ($(TARGET_ARCH_ABI),x86) + X86_REC := 1 +else + X86_REC := endif ifeq ($(TARGET_ARCH_ABI),mips) ISMIPS := 1 + NO_REC := 1 +else + ISMIPS := + NO_REC := endif +$(info $$TARGET_ARCH_ABI is [${TARGET_ARCH_ABI}]) + include $(LOCAL_PATH)/../../core/core.mk LOCAL_SRC_FILES := $(RZDCY_FILES) From bdece20e3a7350c89731eaee246ae3689e12b466 Mon Sep 17 00:00:00 2001 From: Stefanos Kornilios Mitsis Poiitidis Date: Sat, 16 May 2015 00:37:02 +0200 Subject: [PATCH 12/20] VS project: Exclude rec-86 from all build configs --- shell/reicast.vcxproj | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/shell/reicast.vcxproj b/shell/reicast.vcxproj index cbde1546b..698f2db9d 100644 --- a/shell/reicast.vcxproj +++ b/shell/reicast.vcxproj @@ -159,12 +159,21 @@ true + true + true + true true + true + true + true true + true + true + true @@ -301,6 +310,9 @@ true + true + true + true @@ -324,6 +336,9 @@ true + true + true + true From 341c421dd7068171f1e14fa293ad8105bcafec05 Mon Sep 17 00:00:00 2001 From: Stefanos Kornilios Mitsis Poiitidis Date: Sat, 16 May 2015 00:52:42 +0200 Subject: [PATCH 13/20] travis: Add sudo: false to use docker stack Hopefully fixes ndk extraction issues, docker containers have more resources --- .travis.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index ed10b01f8..c7255d86f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,14 +7,10 @@ android: - tools - build-tools-22.0.0 - android-21 +sudo: false before_install: - openssl aes-256-cbc -K $encrypted_c726d225a9d9_key -iv $encrypted_c726d225a9d9_iv -in debug.keystore.enc -out debug.keystore -d -- sudo apt-get install aria2 -qq -- download_extract() { aria2c -x 16 $1 -o $2 && tar -xf $2; } -- download_extract_zip() { aria2c -x 16 $1 -o $2 && unzip -qq $2; } -- sudo apt-get -qq update -- sudo apt-get -qq -y install openjdk-7-jdk ant lib32z1-dev lib32stdc++6 - GIT_HASH=`git log --pretty=format:'%h' -n 1` - GIT_BUILD=`git describe --all`-$GIT_HASH install: From 8c469e4b5c36f06e5795a1e45cd21202a4dfd08c Mon Sep 17 00:00:00 2001 From: Stefanos Kornilios Mitsis Poiitidis Date: Sat, 16 May 2015 03:05:11 +0200 Subject: [PATCH 14/20] *nix: move context massaging to linux/context.cpp, ALIGN -> DECL_ALIGN Yay some warnings gone from not conflicting with ALIGN anymore --- core/hw/aica/dsp.cpp | 2 +- core/hw/aica/dsp.h | 2 +- core/hw/arm7/arm7.cpp | 2 +- core/hw/pvr/ta_vtx.cpp | 8 ++-- core/hw/sh4/sh4_interrupts.cpp | 6 +-- core/linux/common.cpp | 69 ++++++++++------------------------ core/linux/nixprof.cpp | 47 +++-------------------- core/rec-x86/win86_driver.cpp | 2 +- core/rec-x86/win86_il.cpp | 4 +- core/types.h | 4 +- core/windows/win86_driver.cpp | 2 +- core/windows/win86_il.cpp | 4 +- shell/reicast.vcxproj | 12 ++++++ shell/reicast.vcxproj.filters | 6 +++ 14 files changed, 60 insertions(+), 110 deletions(-) diff --git a/core/hw/aica/dsp.cpp b/core/hw/aica/dsp.cpp index 9d712876e..8d8be3814 100644 --- a/core/hw/aica/dsp.cpp +++ b/core/hw/aica/dsp.cpp @@ -20,7 +20,7 @@ See LICENSE & COPYRIGHT files further details */ -ALIGN(4096) dsp_t dsp; +DECL_ALIGN(4096) dsp_t dsp; #if HOST_OS==OS_WINDOWS && !defined(HOST_NO_REC) #include "emitter/x86_emitter.h" diff --git a/core/hw/aica/dsp.h b/core/hw/aica/dsp.h index ae007bfc5..e9e790d74 100644 --- a/core/hw/aica/dsp.h +++ b/core/hw/aica/dsp.h @@ -86,7 +86,7 @@ struct dsp_t bool dyndirty; }; -ALIGN(4096) +DECL_ALIGN(4096) extern dsp_t dsp; void dsp_init(); diff --git a/core/hw/arm7/arm7.cpp b/core/hw/arm7/arm7.cpp index e625bf0d4..7be68e06f 100644 --- a/core/hw/arm7/arm7.cpp +++ b/core/hw/arm7/arm7.cpp @@ -121,7 +121,7 @@ typedef union //bool arm_FiqPending; -- not used , i use the input directly :) //bool arm_IrqPending; -ALIGN(8) reg_pair arm_Reg[RN_ARM_REG_COUNT]; +DECL_ALIGN(8) reg_pair arm_Reg[RN_ARM_REG_COUNT]; void CPUSwap(u32 *a, u32 *b) { diff --git a/core/hw/pvr/ta_vtx.cpp b/core/hw/pvr/ta_vtx.cpp index 591b3b24e..bc564e59e 100644 --- a/core/hw/pvr/ta_vtx.cpp +++ b/core/hw/pvr/ta_vtx.cpp @@ -84,10 +84,10 @@ PolyParam* CurrentPP=&nullPP; List* CurrentPPlist; //TA state vars -ALIGN(4) static u8 FaceBaseColor[4]; -ALIGN(4) static u8 FaceOffsColor[4]; -ALIGN(4) static u32 SFaceBaseColor; -ALIGN(4) static u32 SFaceOffsColor; +DECL_ALIGN(4) static u8 FaceBaseColor[4]; +DECL_ALIGN(4) static u8 FaceOffsColor[4]; +DECL_ALIGN(4) static u32 SFaceBaseColor; +DECL_ALIGN(4) static u32 SFaceOffsColor; diff --git a/core/hw/sh4/sh4_interrupts.cpp b/core/hw/sh4/sh4_interrupts.cpp index d8fe1584c..43b9cc9b1 100644 --- a/core/hw/sh4/sh4_interrupts.cpp +++ b/core/hw/sh4/sh4_interrupts.cpp @@ -42,11 +42,11 @@ struct InterptSourceList_Entry InterptSourceList_Entry InterruptSourceList[28]; //Maps siid -> EventID -ALIGN(64) u16 InterruptEnvId[32]= { 0 }; +DECL_ALIGN(64) u16 InterruptEnvId[32] = { 0 }; //Maps piid -> 1< #include "hw/sh4/dyna/blockmanager.h" -#if defined(_ANDROID) -#include -#if 0 -typedef struct ucontext_t { -unsigned long uc_flags; -struct ucontext_t *uc_link; -struct { -void *p; -int flags; -size_t size; -} sstack_data; -struct sigcontext uc_mcontext; -/* some 2.6.x kernel has fp data here after a few other fields -* we don't use them for now... -*/ -} ucontext_t; -#endif -#endif - -#if HOST_CPU == CPU_ARM -#define GET_PC_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.arm_pc) -#elif HOST_CPU == CPU_MIPS -#if 0 && _ANDROID -#define GET_PC_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.sc_pc) -#else -#define GET_PC_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.pc) -#endif -#elif HOST_CPU == CPU_X86 -#if 0 && _ANDROID -#define GET_PC_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.eip) -#else -#define GET_PC_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.gregs[REG_EIP]) -#define GET_ESP_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.gregs[REG_ESP]) -#define GET_EAX_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.gregs[REG_EAX]) -#define GET_ECX_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.gregs[REG_ECX]) -#endif -#else -#error fix ->pc support -#endif +#include "linux/context.h" #include "hw/sh4/dyna/ngen.h" @@ -62,11 +24,15 @@ u32* ngen_readm_fail_v2(u32* ptr,u32* regs,u32 saddr); bool VramLockedWrite(u8* address); bool BM_LockedWrite(u8* address); -void fault_handler (int sn, siginfo_t * si, void *ctxr) +void fault_handler (int sn, siginfo_t * si, void *segfault_ctx) { - bool dyna_cde=((u32)GET_PC_FROM_CONTEXT(ctxr)>(u32)CodeCache) && ((u32)GET_PC_FROM_CONTEXT(ctxr)<(u32)(CodeCache+CODE_SIZE)); + rei_host_context_t ctx; - ucontext_t* ctx=(ucontext_t*)ctxr; + context_from_segfault(&ctx, segfault_ctx); + + bool dyna_cde = ((unat)ctx.pc>(unat)CodeCache) && ((unat)ctx.pc<(unat)(CodeCache + CODE_SIZE)); + + //ucontext_t* ctx=(ucontext_t*)ctxr; //printf("mprot hit @ ptr 0x%08X @@ code: %08X, %d\n",si->si_addr,ctx->uc_mcontext.arm_pc,dyna_cde); @@ -76,15 +42,19 @@ void fault_handler (int sn, siginfo_t * si, void *ctxr) #if HOST_CPU==CPU_ARM else if (dyna_cde) { - GET_PC_FROM_CONTEXT(ctxr)=(u32)ngen_readm_fail_v2((u32*)GET_PC_FROM_CONTEXT(ctxr),(u32*)&(ctx->uc_mcontext.arm_r0),(unat)si->si_addr); + ctx.pc = (u32)ngen_readm_fail_v2((u32*)ctx.pc, (u32*)&(ctx.r0), (unat)si->si_addr); + + context_to_segfault(&ctx, segfault_ctx); } #elif HOST_CPU==CPU_X86 - else if ( ngen_Rewrite((unat&)GET_PC_FROM_CONTEXT(ctxr),*(unat*)GET_ESP_FROM_CONTEXT(ctxr),GET_EAX_FROM_CONTEXT(ctxr)) ) + else if (ngen_Rewrite((unat&)ctx.pc, *(unat*)ctx.esp, ctx.eax)) { //remove the call from call stack - GET_ESP_FROM_CONTEXT(ctxr)+=4; - //restore the addr from eax to ecx so its valid again - GET_ECX_FROM_CONTEXT(ctxr)=GET_EAX_FROM_CONTEXT(ctxr); + ctx.esp += 4; + //restore the addr from eax to ecx so it's valid again + ctx.ecx = ctx.eax; + + context_to_segfault(&ctx, segfault_ctx); } #else #error JIT: Not supported arch @@ -92,9 +62,8 @@ void fault_handler (int sn, siginfo_t * si, void *ctxr) #endif else { - printf("SIGSEGV @ fault_handler+0x%08X ... %08X -> was not in vram\n",GET_PC_FROM_CONTEXT(ctxr)-(u32)fault_handler,si->si_addr); + printf("SIGSEGV @ %08X (fault_handler+0x%08X) ... %08X -> was not in vram\n", ctx.pc, ctx.pc - (unat)fault_handler, si->si_addr); die("segfault"); -// asm volatile("bkpt 0x0001\n\t"); signal(SIGSEGV, SIG_DFL); } } @@ -188,7 +157,7 @@ void VArray2::LockRegion(u32 offset,u32 size) void print_mem_addr() { FILE *ifp, *ofp; - char *mode = "r"; + const char *mode = "r"; char outputFilename[] = "/data/data/com.reicast.emulator/files/mem_alloc.txt"; ifp = fopen("/proc/self/maps", mode); diff --git a/core/linux/nixprof.cpp b/core/linux/nixprof.cpp index 0ccc57b5c..b6086c7b2 100644 --- a/core/linux/nixprof.cpp +++ b/core/linux/nixprof.cpp @@ -33,46 +33,7 @@ #include #include "deps/libelf/elf.h" -#if defined(_ANDROID) -#include -#if 0 -typedef struct ucontext_t -{ - unsigned long uc_flags; - struct ucontext_t *uc_link; - struct - { - void *p; - int flags; - size_t size; - } sstack_data; - - struct sigcontext uc_mcontext; - /* some 2.6.x kernel has fp data here after a few other fields - * we don't use them for now... - */ -} ucontext_t; -#endif -#include -#endif - -#if HOST_CPU == CPU_ARM -#define GET_PC_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.arm_pc) -#elif HOST_CPU == CPU_MIPS -#if 0 && _ANDROID -#define GET_PC_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.sc_pc) -#else -#define GET_PC_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.pc) -#endif -#elif HOST_CPU == CPU_X86 -#if 0 && _ANDROID -#define GET_PC_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.eip) -#else -#define GET_PC_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.gregs[REG_EIP]) -#endif -#else -#error fix ->pc support -#endif +#include "context.h" /** @file CallStack_Android.h @@ -100,13 +61,15 @@ void sample_Syms(u8* data,u32 len) void prof_handler (int sn, siginfo_t * si, void *ctxr) { - ucontext_t* ctx=(ucontext_t*)ctxr; + rei_host_context_t ctx; + context_from_segfault(&ctx, ctxr); + int thd=-1; if (pthread_self()==thread[0]) thd=0; else if (pthread_self()==thread[1]) thd=1; else return; - prof_address[thd]=(void*)GET_PC_FROM_CONTEXT(ctx); + prof_address[thd] = (void*)ctx.pc; } diff --git a/core/rec-x86/win86_driver.cpp b/core/rec-x86/win86_driver.cpp index 7d7122a08..0e419aba9 100644 --- a/core/rec-x86/win86_driver.cpp +++ b/core/rec-x86/win86_driver.cpp @@ -109,7 +109,7 @@ u32 csc_sidx=1; x86_reg alloc_regs[]={EBX,EBP,ESI,EDI,NO_REG}; x86_reg xmm_alloc_regs[]={XMM7,XMM6,XMM5,XMM4,NO_REG}; -f32 ALIGN(16) thaw_regs[4]; +f32 DECL_ALIGN(16) thaw_regs[4]; void x86_reg_alloc::Preload(u32 reg,x86_reg nreg) diff --git a/core/rec-x86/win86_il.cpp b/core/rec-x86/win86_il.cpp index ec6322d48..99fe9f912 100644 --- a/core/rec-x86/win86_il.cpp +++ b/core/rec-x86/win86_il.cpp @@ -1165,7 +1165,7 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool verify(reg.IsAllocf(op->rs1)); verify(reg.IsAllocf(op->rd)); - static ALIGN(16) u32 AND_ABS_MASK[4]={0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF}; + static DECL_ALIGN(16) u32 AND_ABS_MASK[4] = { 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF }; verify(op->rd._reg==op->rs1._reg); x86e->Emit(op_pand,reg.mapf(op->rd),AND_ABS_MASK); @@ -1177,7 +1177,7 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool verify(reg.IsAllocf(op->rs1)); verify(reg.IsAllocf(op->rd)); - static ALIGN(16) u32 XOR_NEG_MASK[4]={0x80000000,0x80000000,0x80000000,0x80000000}; + static DECL_ALIGN(16) u32 XOR_NEG_MASK[4] = { 0x80000000, 0x80000000, 0x80000000, 0x80000000 }; verify(op->rd._reg==op->rs1._reg); x86e->Emit(op_pxor,reg.mapf(op->rd),XOR_NEG_MASK); diff --git a/core/types.h b/core/types.h index 09e125217..e90e5c3c4 100644 --- a/core/types.h +++ b/core/types.h @@ -3,10 +3,10 @@ #include "build.h" #if BUILD_COMPILER==COMPILER_VC -#define ALIGN(x) __declspec(align(x)) +#define DECL_ALIGN(x) __declspec(align(x)) #else #define __forceinline inline -#define ALIGN(x) __attribute__((aligned(x))) +#define DECL_ALIGN(x) __attribute__((aligned(x))) #define __debugbreak #endif diff --git a/core/windows/win86_driver.cpp b/core/windows/win86_driver.cpp index 384df8f51..b59db8961 100644 --- a/core/windows/win86_driver.cpp +++ b/core/windows/win86_driver.cpp @@ -107,7 +107,7 @@ u32 csc_sidx=1; x86_reg alloc_regs[]={EBX,EBP,ESI,EDI,NO_REG}; x86_reg xmm_alloc_regs[]={XMM7,XMM6,XMM5,XMM4,NO_REG}; -f32 ALIGN(16) thaw_regs[4]; +f32 DECL_ALIGN(16) thaw_regs[4]; void x86_reg_alloc::Preload(u32 reg,x86_reg nreg) diff --git a/core/windows/win86_il.cpp b/core/windows/win86_il.cpp index b75b98330..13917124b 100644 --- a/core/windows/win86_il.cpp +++ b/core/windows/win86_il.cpp @@ -1168,7 +1168,7 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool verify(reg.IsAllocf(op->rs1)); verify(reg.IsAllocf(op->rd)); - static ALIGN(16) u32 AND_ABS_MASK[4]={0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF}; + static DECL_ALIGN(16) u32 AND_ABS_MASK[4] = { 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF }; verify(op->rd._reg==op->rs1._reg); x86e->Emit(op_pand,reg.mapf(op->rd),AND_ABS_MASK); @@ -1180,7 +1180,7 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool verify(reg.IsAllocf(op->rs1)); verify(reg.IsAllocf(op->rd)); - static ALIGN(16) u32 XOR_NEG_MASK[4]={0x80000000,0x80000000,0x80000000,0x80000000}; + static DECL_ALIGN(16) u32 XOR_NEG_MASK[4] = { 0x80000000, 0x80000000, 0x80000000, 0x80000000 }; verify(op->rd._reg==op->rs1._reg); x86e->Emit(op_pxor,reg.mapf(op->rd),XOR_NEG_MASK); diff --git a/shell/reicast.vcxproj b/shell/reicast.vcxproj index 698f2db9d..d3f104ad5 100644 --- a/shell/reicast.vcxproj +++ b/shell/reicast.vcxproj @@ -140,6 +140,12 @@ true true + + true + true + true + true + true true @@ -299,6 +305,12 @@ + + true + true + true + true + true true diff --git a/shell/reicast.vcxproj.filters b/shell/reicast.vcxproj.filters index ba43d8d0f..b47ab6dcb 100644 --- a/shell/reicast.vcxproj.filters +++ b/shell/reicast.vcxproj.filters @@ -420,6 +420,9 @@ rec-x86 + + linux + @@ -910,6 +913,9 @@ rec-x86 + + linux + From 902c5e294962b808862ac22312e0f224c42cb5c6 Mon Sep 17 00:00:00 2001 From: Stefanos Kornilios Mitsis Poiitidis Date: Sat, 16 May 2015 03:10:39 +0200 Subject: [PATCH 15/20] linux/context.*: Add missing files --- core/linux/context.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++ core/linux/context.h | 17 ++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 core/linux/context.cpp create mode 100644 core/linux/context.h diff --git a/core/linux/context.cpp b/core/linux/context.cpp new file mode 100644 index 000000000..d51de1a3c --- /dev/null +++ b/core/linux/context.cpp @@ -0,0 +1,46 @@ +#include "context.h" + +#if defined(_ANDROID) +#include +#else +#include +#endif + + +////// + +#define MCTX(p) (((ucontext_t *)(segfault_ctx))->uc_mcontext.p) +template +void swap(Ta& a, Tb& b, bool reverse) { + if (reverse) { + b = a; + } + else { + a = b; + } +} + +void context_segfault(rei_host_context_t* reictx, void* segfault_ctx, bool to_segfault) { + +#if HOST_CPU == CPU_ARM + swap(reictx->pc, MCTX(arm_pc), to_segfault); +#elif HOST_CPU == CPU_X86 + swap(reictx->pc, MCTX(gregs[REG_EIP]), to_segfault); + swap(reictx->esp, MCTX(gregs[REG_ESP]), to_segfault); + swap(reictx->eax, MCTX(gregs[REG_EAX]), to_segfault); + swap(reictx->ecx, MCTX(gregs[REG_ECX]), to_segfault); +#elif HOST_CPU == CPU_MIPS + swap(reictx->pc, MCTX(pc), to_segfault); +#else +#error Unsupported HOST_CPU +#endif + +} + +void context_from_segfault(rei_host_context_t* reictx, void* segfault_ctx) { + context_segfault(reictx, segfault_ctx, false); +} + +void context_to_segfault(rei_host_context_t* reictx, void* segfault_ctx) { + context_segfault(reictx, segfault_ctx, true); +} \ No newline at end of file diff --git a/core/linux/context.h b/core/linux/context.h new file mode 100644 index 000000000..d7cc103b6 --- /dev/null +++ b/core/linux/context.h @@ -0,0 +1,17 @@ +#include "types.h" + + +struct rei_host_context_t { + unat pc; + +#if HOST_CPU == CPU_X86 + u32 eax; + u32 ecx; + u32 esp; +#elif HOST_CPU == CPU_ARM + u32 r0; +#endif +}; + +void context_from_segfault(rei_host_context_t* reictx, void* segfault_ctx); +void context_to_segfault(rei_host_context_t* reictx, void* segfault_ctx); \ No newline at end of file From 03914309e359d2db8bca3bd977560fc1a3c416c6 Mon Sep 17 00:00:00 2001 From: Stefanos Kornilios Mitsis Poiitidis Date: Sat, 16 May 2015 07:16:46 +0200 Subject: [PATCH 16/20] linux/context: Add updated context files --- core/linux/context.cpp | 48 +++++++++++++++++++++++++++++++++--------- core/linux/context.h | 2 +- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/core/linux/context.cpp b/core/linux/context.cpp index d51de1a3c..693633ca9 100644 --- a/core/linux/context.cpp +++ b/core/linux/context.cpp @@ -1,15 +1,20 @@ #include "context.h" #if defined(_ANDROID) -#include + #include #else -#include + #if HOST_OS == OS_DARWIN + #define _XOPEN_SOURCE 1 + #define __USE_GNU 1 + #endif + + #include #endif ////// -#define MCTX(p) (((ucontext_t *)(segfault_ctx))->uc_mcontext.p) +#define MCTX(p) (((ucontext_t *)(segfault_ctx))->uc_mcontext p) template void swap(Ta& a, Tb& b, bool reverse) { if (reverse) { @@ -23,16 +28,39 @@ void swap(Ta& a, Tb& b, bool reverse) { void context_segfault(rei_host_context_t* reictx, void* segfault_ctx, bool to_segfault) { #if HOST_CPU == CPU_ARM - swap(reictx->pc, MCTX(arm_pc), to_segfault); + #if HOST_OS == OS_LINUX + swap(reictx->pc, MCTX(.arm_pc), to_segfault); + u32* r =(u32*) &MCTX(.arm_r0); + + for (int i = 0; i < 15; i++) + swap(reictx->r[i], r[i], to_segfault); + + #elif HOST_OS == OS_DARWIN + swap(reictx->pc, MCTX(->__ss.__pc), to_segfault); + + for (int i = 0; i < 15; i++) + swap(reictx->r[i], MCTX(->__ss.__r[i]), to_segfault); + #else + #error HOST_OS + #endif #elif HOST_CPU == CPU_X86 - swap(reictx->pc, MCTX(gregs[REG_EIP]), to_segfault); - swap(reictx->esp, MCTX(gregs[REG_ESP]), to_segfault); - swap(reictx->eax, MCTX(gregs[REG_EAX]), to_segfault); - swap(reictx->ecx, MCTX(gregs[REG_ECX]), to_segfault); + #if HOST_OS == OS_LINUX + swap(reictx->pc, MCTX(.gregs[REG_EIP]), to_segfault); + swap(reictx->esp, MCTX(.gregs[REG_ESP]), to_segfault); + swap(reictx->eax, MCTX(.gregs[REG_EAX]), to_segfault); + swap(reictx->ecx, MCTX(.gregs[REG_ECX]), to_segfault); + #elif HOST_OS == OS_DARWIN + swap(reictx->pc, MCTX(->__ss.__eip), to_segfault); + swap(reictx->esp, MCTX(->__ss.__esp), to_segfault); + swap(reictx->eax, MCTX(->__ss.__eax), to_segfault); + swap(reictx->ecx, MCTX(->__ss.__ecx), to_segfault); + #else + #error HOST_OS + #endif #elif HOST_CPU == CPU_MIPS - swap(reictx->pc, MCTX(pc), to_segfault); + swap(reictx->pc, MCTX(.pc), to_segfault); #else -#error Unsupported HOST_CPU + #error Unsupported HOST_CPU #endif } diff --git a/core/linux/context.h b/core/linux/context.h index d7cc103b6..7c53a4a86 100644 --- a/core/linux/context.h +++ b/core/linux/context.h @@ -9,7 +9,7 @@ struct rei_host_context_t { u32 ecx; u32 esp; #elif HOST_CPU == CPU_ARM - u32 r0; + u32 r[15]; #endif }; From 6547d800950df47e39e90c76e1ceb3c2386a702b Mon Sep 17 00:00:00 2001 From: Stefanos Kornilios Mitsis Poiitidis Date: Sat, 16 May 2015 08:18:46 +0200 Subject: [PATCH 17/20] Fixes for android, cleanup context.cpp --- core/hw/mem/_vmem.cpp | 1 + core/linux/context.cpp | 34 +++++++++++++++++----------------- core/nullDC.cpp | 4 ++-- 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/core/hw/mem/_vmem.cpp b/core/hw/mem/_vmem.cpp index 80fd0539b..61cfdb79a 100644 --- a/core/hw/mem/_vmem.cpp +++ b/core/hw/mem/_vmem.cpp @@ -600,6 +600,7 @@ void _vmem_bm_reset() #if HOST_OS==OS_WINDOWS VirtualFree(p_sh4rcb,sizeof(p_sh4rcb->fpcb),MEM_DECOMMIT); #else + mprotect(p_sh4rcb, sizeof(p_sh4rcb->fpcb), PROT_NONE); madvise(p_sh4rcb,sizeof(p_sh4rcb->fpcb),MADV_DONTNEED); #ifdef MADV_REMOVE madvise(p_sh4rcb,sizeof(p_sh4rcb->fpcb),MADV_REMOVE); diff --git a/core/linux/context.cpp b/core/linux/context.cpp index 693633ca9..ae7939911 100644 --- a/core/linux/context.cpp +++ b/core/linux/context.cpp @@ -16,12 +16,12 @@ #define MCTX(p) (((ucontext_t *)(segfault_ctx))->uc_mcontext p) template -void swap(Ta& a, Tb& b, bool reverse) { - if (reverse) { - b = a; +void bicopy(Ta& rei, Tb& seg, bool to_segfault) { + if (to_segfault) { + seg = rei; } else { - a = b; + rei = seg; } } @@ -29,36 +29,36 @@ void context_segfault(rei_host_context_t* reictx, void* segfault_ctx, bool to_se #if HOST_CPU == CPU_ARM #if HOST_OS == OS_LINUX - swap(reictx->pc, MCTX(.arm_pc), to_segfault); + bicopy(reictx->pc, MCTX(.arm_pc), to_segfault); u32* r =(u32*) &MCTX(.arm_r0); for (int i = 0; i < 15; i++) - swap(reictx->r[i], r[i], to_segfault); + bicopy(reictx->r[i], r[i], to_segfault); #elif HOST_OS == OS_DARWIN - swap(reictx->pc, MCTX(->__ss.__pc), to_segfault); + bicopy(reictx->pc, MCTX(->__ss.__pc), to_segfault); for (int i = 0; i < 15; i++) - swap(reictx->r[i], MCTX(->__ss.__r[i]), to_segfault); + bicopy(reictx->r[i], MCTX(->__ss.__r[i]), to_segfault); #else #error HOST_OS #endif #elif HOST_CPU == CPU_X86 #if HOST_OS == OS_LINUX - swap(reictx->pc, MCTX(.gregs[REG_EIP]), to_segfault); - swap(reictx->esp, MCTX(.gregs[REG_ESP]), to_segfault); - swap(reictx->eax, MCTX(.gregs[REG_EAX]), to_segfault); - swap(reictx->ecx, MCTX(.gregs[REG_ECX]), to_segfault); + bicopy(reictx->pc, MCTX(.gregs[REG_EIP]), to_segfault); + bicopy(reictx->esp, MCTX(.gregs[REG_ESP]), to_segfault); + bicopy(reictx->eax, MCTX(.gregs[REG_EAX]), to_segfault); + bicopy(reictx->ecx, MCTX(.gregs[REG_ECX]), to_segfault); #elif HOST_OS == OS_DARWIN - swap(reictx->pc, MCTX(->__ss.__eip), to_segfault); - swap(reictx->esp, MCTX(->__ss.__esp), to_segfault); - swap(reictx->eax, MCTX(->__ss.__eax), to_segfault); - swap(reictx->ecx, MCTX(->__ss.__ecx), to_segfault); + bicopy(reictx->pc, MCTX(->__ss.__eip), to_segfault); + bicopy(reictx->esp, MCTX(->__ss.__esp), to_segfault); + bicopy(reictx->eax, MCTX(->__ss.__eax), to_segfault); + bicopy(reictx->ecx, MCTX(->__ss.__ecx), to_segfault); #else #error HOST_OS #endif #elif HOST_CPU == CPU_MIPS - swap(reictx->pc, MCTX(.pc), to_segfault); + bicopy(reictx->pc, MCTX(.pc), to_segfault); #else #error Unsupported HOST_CPU #endif diff --git a/core/nullDC.cpp b/core/nullDC.cpp index a3d69bc59..d522d59ff 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -170,9 +170,9 @@ int dc_init(int argc,wchar* argv[]) int rv= 0; - if (settings.bios.UseReios || !LoadRomFiles(GetPath("/data/")) && !LoadRomFiles(GetPath("/"))) + if (settings.bios.UseReios || !LoadRomFiles(GetPath("/data/"))) { - if (!LoadHle(GetPath("/data/")) || !LoadHle(GetPath("/"))) + if (!LoadHle(GetPath("/data/"))) return -3; else printf("Did not load bios, using reios\n"); From 9c2a4dc5a4db2d97d3d9d3c00d74a761d5cf8061 Mon Sep 17 00:00:00 2001 From: Stefanos Kornilios Mitsis Poiitidis Date: Sat, 16 May 2015 01:04:30 -0700 Subject: [PATCH 18/20] iOS fixes --- core/hw/pvr/Renderer_if.cpp | 2 ++ core/hw/sh4/sh4_core.h | 8 ++--- core/linux/common.cpp | 15 ++++---- core/linux/nixprof.cpp | 2 ++ core/nullDC.cpp | 11 ++++-- core/oslib/oslib.h | 2 +- core/rec-ARM/ngen_arm.S | 36 ++++++++++--------- shell/ios/emulator.xcodeproj/project.pbxproj | 38 ++++++++++++++++++++ 8 files changed, 83 insertions(+), 31 deletions(-) diff --git a/core/hw/pvr/Renderer_if.cpp b/core/hw/pvr/Renderer_if.cpp index 528c006a2..f310e9598 100644 --- a/core/hw/pvr/Renderer_if.cpp +++ b/core/hw/pvr/Renderer_if.cpp @@ -178,6 +178,8 @@ TA_context* read_frame(const char* file, u8* vram_ref) { ctx->tad.thd_data += t; fclose(fw); + + return ctx; } bool rend_frame(TA_context* ctx, bool draw_osd) { diff --git a/core/hw/sh4/sh4_core.h b/core/hw/sh4/sh4_core.h index 0ca976877..1adfaeb9d 100644 --- a/core/hw/sh4/sh4_core.h +++ b/core/hw/sh4/sh4_core.h @@ -39,7 +39,7 @@ union DoubleReg f32 sgl[2]; }; -INLINE f64 GetDR(u32 n) +static INLINE f64 GetDR(u32 n) { #ifdef TRACE if (n>7) @@ -53,7 +53,7 @@ INLINE f64 GetDR(u32 n) return t.dbl; } -INLINE f64 GetXD(u32 n) +static INLINE f64 GetXD(u32 n) { #ifdef TRACE if (n>7) @@ -67,7 +67,7 @@ INLINE f64 GetXD(u32 n) return t.dbl; } -INLINE void SetDR(u32 n,f64 val) +static INLINE void SetDR(u32 n,f64 val) { #ifdef TRACE if (n>7) @@ -81,7 +81,7 @@ INLINE void SetDR(u32 n,f64 val) fr[(n<<1) | 0]=t.sgl[1]; } -INLINE void SetXD(u32 n,f64 val) +static INLINE void SetXD(u32 n,f64 val) { #ifdef TRACE if (n>7) diff --git a/core/linux/common.cpp b/core/linux/common.cpp index 831e873da..d28c1ed88 100644 --- a/core/linux/common.cpp +++ b/core/linux/common.cpp @@ -1,4 +1,4 @@ -#include "types.h" + #include "types.h" #include "cfg/cfg.h" #if HOST_OS==OS_LINUX || HOST_OS == OS_DARWIN @@ -29,13 +29,16 @@ bool VramLockedWrite(u8* address); bool BM_LockedWrite(u8* address); #if HOST_OS == OS_DARWIN -+void sigill_handler(int sn, siginfo_t * si, void *ctxr) { +void sigill_handler(int sn, siginfo_t * si, void *segfault_ctx) { - ucontext_t* ctx = (ucontext_t*)ctxr; - unat pc = (unat)GET_PC_FROM_CONTEXT(ctxr); - bool dyna_cde = ((u32)GET_PC_FROM_CONTEXT(ctxr)>(u32)CodeCache) && ((u32)GET_PC_FROM_CONTEXT(ctxr)<(u32)(CodeCache + CODE_SIZE)); + rei_host_context_t ctx; + + context_from_segfault(&ctx, segfault_ctx); + + unat pc = (unat)ctx.pc; + bool dyna_cde = (pc>(unat)CodeCache) && (pc<(unat)(CodeCache + CODE_SIZE)); - printf("SIGILL @ %08X, fault_handler+0x%08X ... %08X -> was not in vram, %d\n", GET_PC_FROM_CONTEXT(ctxr), GET_PC_FROM_CONTEXT(ctxr) - (u32)sigill_handler, (unat)si->si_addr, dyna_cde); + printf("SIGILL @ %08X, fault_handler+0x%08X ... %08X -> was not in vram, %d\n", pc, pc - (u32)sigill_handler, (unat)si->si_addr, dyna_cde); printf("Entering infiniloop"); diff --git a/core/linux/nixprof.cpp b/core/linux/nixprof.cpp index b6086c7b2..7e5f90547 100644 --- a/core/linux/nixprof.cpp +++ b/core/linux/nixprof.cpp @@ -277,6 +277,8 @@ void* prof(void *ptr) fclose(maps); fclose(prof_out); + + return 0; } void sample_Start(int freq) diff --git a/core/nullDC.cpp b/core/nullDC.cpp index d522d59ff..953d1b6fd 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -169,10 +169,15 @@ int dc_init(int argc,wchar* argv[]) int rv= 0; - - if (settings.bios.UseReios || !LoadRomFiles(GetPath("/data/"))) +#if HOST_OS != OS_DARWIN + #define DATA_PATH "/data/" +#else + #define DATA_PATH "/" +#endif + + if (settings.bios.UseReios || !LoadRomFiles(GetPath(DATA_PATH))) { - if (!LoadHle(GetPath("/data/"))) + if (!LoadHle(GetPath(DATA_PATH))) return -3; else printf("Did not load bios, using reios\n"); diff --git a/core/oslib/oslib.h b/core/oslib/oslib.h index 8d9df70ff..08ca94a23 100644 --- a/core/oslib/oslib.h +++ b/core/oslib/oslib.h @@ -16,7 +16,7 @@ void WriteSample(s16 right, s16 left); #include #endif -u32 INLINE bitscanrev(u32 v) +u32 static INLINE bitscanrev(u32 v) { #if (BUILD_COMPILER==COMPILER_GCC) return 31-__builtin_clz(v); diff --git a/core/rec-ARM/ngen_arm.S b/core/rec-ARM/ngen_arm.S index 6157259df..2d10c0d64 100644 --- a/core/rec-ARM/ngen_arm.S +++ b/core/rec-ARM/ngen_arm.S @@ -11,14 +11,16 @@ #if HOST_OS == OS_DARWIN #define CSYM(n) _##n +#define HIDDEN(n) #else #define CSYM(n) n +#define HIDDEN(n) .hidden CSYM(n) #endif @@@@@@@@@@ some helpers @@@@@@@@@@ .global CSYM(do_sqw_nommu_area_3) -.hidden CSYM(do_sqw_nommu_area_3) +HIDDEN(do_sqw_nommu_area_3) @r0: addr @r1: sq_both CSYM(do_sqw_nommu_area_3): @@ -33,7 +35,7 @@ vstm r3,{d0-d3} bx lr .global CSYM(TAWriteSQ) -.hidden TAWriteSQ +HIDDEN(TAWriteSQ) @r0: addr @r1: sq_both CSYM(TAWriteSQ): @@ -69,7 +71,7 @@ bx lr @@@@@@@@@@ ngen_LinkBlock_*****_stub @@@@@@@@@@ .global CSYM(ngen_LinkBlock_Generic_stub) -.hidden CSYM(ngen_LinkBlock_Generic_stub) +HIDDEN(ngen_LinkBlock_Generic_stub) CSYM(ngen_LinkBlock_Generic_stub): mov r1,r4 @ djump/pc -> in case we need it .. @@ -77,14 +79,14 @@ CSYM(ngen_LinkBlock_Generic_stub): .global CSYM(ngen_LinkBlock_cond_Branch_stub) -.hidden CSYM(ngen_LinkBlock_cond_Branch_stub) +HIDDEN(ngen_LinkBlock_cond_Branch_stub) CSYM(ngen_LinkBlock_cond_Branch_stub): mov r1,#1 b CSYM(ngen_LinkBlock_Shared_stub) .global CSYM(ngen_LinkBlock_cond_Next_stub) -.hidden CSYM(ngen_LinkBlock_cond_Next_stub) +HIDDEN(ngen_LinkBlock_cond_Next_stub) CSYM(ngen_LinkBlock_cond_Next_stub): mov r1,#0 @@ -92,7 +94,7 @@ CSYM(ngen_LinkBlock_cond_Next_stub): .global CSYM(ngen_LinkBlock_Shared_stub) -.hidden CSYM(ngen_LinkBlock_Shared_stub) +HIDDEN(ngen_LinkBlock_Shared_stub) CSYM(ngen_LinkBlock_Shared_stub): mov r0,lr @@ -104,7 +106,7 @@ CSYM(ngen_LinkBlock_Shared_stub): .global CSYM(ngen_FailedToFindBlock_) -.hidden CSYM(ngen_FailedToFindBlock_) +HIDDEN(ngen_FailedToFindBlock_) CSYM(ngen_FailedToFindBlock_): mov r0,r4 bl CSYM(rdv_FailedToFindBlock) @@ -113,7 +115,7 @@ CSYM(ngen_FailedToFindBlock_): @@@@@@@@@@ ngen_blockcheckfail @@@@@@@@@@ .global CSYM(ngen_blockcheckfail) -.hidden CSYM(ngen_blockcheckfail) +HIDDEN(ngen_blockcheckfail) CSYM(ngen_blockcheckfail): bl CSYM(rdv_BlockCheckFail) bx r0 @@ -129,7 +131,7 @@ CSYM(ngen_blockcheckfail): .global CSYM(ngen_mainloop) -.hidden CSYM(ngen_mainloop) +HIDDEN(ngen_mainloop) CSYM(ngen_mainloop): push { r4-r12,lr } @@ -149,7 +151,7 @@ push { r4-r12,lr } @this code is here for fall-through behavior of do_iter .global CSYM(intc_sched) - .hidden CSYM(intc_sched) + HIDDEN(intc_sched) CSYM(intc_sched): @ next_pc _MUST_ be on ram #if HOST_OS == OS_DARWIN add r11,r11,#SH4_TIMESLICE @@ -168,7 +170,7 @@ do_iter: mov r4,r0 .global CSYM(no_update) -.hidden CSYM(no_update) +HIDDEN(no_update) CSYM(no_update): @ next_pc _MUST_ be on r4 *R4 NOT R0 anymore* sub r2,r8,#33816576 @@ -186,7 +188,7 @@ end_ngen_mainloop: @@@@@@@@@@ ngen_mainloop @@@@@@@@@@ .global CSYM(arm_compilecode) -.hidden CSYM(arm_compilecode) +HIDDEN(arm_compilecode) CSYM(arm_compilecode): bl CSYM(CompileCode) b CSYM(arm_dispatch) @@ -197,7 +199,7 @@ XEntryPoints: .word CSYM(EntryPoints) #endif .global CSYM(arm_mainloop) -.hidden CSYM(arm_mainloop) +HIDDEN(arm_mainloop) CSYM(arm_mainloop): @(cntx,lookup_base,cycles) #if HOST_OS == OS_DARWIN @@ -220,7 +222,7 @@ push {r4,r5,r8,r9,lr} b CSYM(arm_dispatch) .global CSYM(arm_dispatch) -.hidden CSYM(arm_dispatch) +HIDDEN(arm_dispatch) CSYM(arm_dispatch): #ifdef TARGET_IPHONE ldrd r0,r1,[r8,#184] @load: Next PC, interrupt @@ -239,7 +241,7 @@ arm_dofiq: b CSYM(arm_dispatch) .global CSYM(arm_exit) -.hidden CSYM(arm_exit) +HIDDEN(arm_exit) CSYM(arm_exit): str r5,[r8,#192] @if timeslice is over, save remaining cycles #if HOST_OS == OS_DARWIN @@ -252,7 +254,7 @@ CSYM(arm_exit): @matrix mul #ifndef _ANDROID .global CSYM(ftrv_asm) -.hidden CSYM(ftrv_asm) +HIDDEN(ftrv_asm) CSYM(ftrv_asm): @r0=dst,r1=vec,r2=mtx @@ -271,7 +273,7 @@ vstm r0,{d4,d5} bx lr .global CSYM(fipr_asm) -.hidden CSYM(fipr_asm) +HIDDEN(fipr_asm) CSYM(fipr_asm): @ vdot diff --git a/shell/ios/emulator.xcodeproj/project.pbxproj b/shell/ios/emulator.xcodeproj/project.pbxproj index 15cf5c26f..f9a3d2ee8 100644 --- a/shell/ios/emulator.xcodeproj/project.pbxproj +++ b/shell/ios/emulator.xcodeproj/project.pbxproj @@ -15,6 +15,11 @@ 8497BCCA1A41BFBA00EFB9ED /* audiostream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8497BCC51A41BFBA00EFB9ED /* audiostream.cpp */; }; 8497BCCB1A41BFBA00EFB9ED /* ds_audiostream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8497BCC71A41BFBA00EFB9ED /* ds_audiostream.cpp */; }; 8497BCCF1A41BFD800EFB9ED /* coreio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8497BCCD1A41BFD800EFB9ED /* coreio.cpp */; }; + 849C0D621B072C07008BAAA4 /* context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 849C0D601B072C07008BAAA4 /* context.cpp */; }; + 849C0D661B072CF8008BAAA4 /* reios.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 849C0D641B072CF8008BAAA4 /* reios.cpp */; }; + 849C0D6D1B072D14008BAAA4 /* descrambl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 849C0D671B072D14008BAAA4 /* descrambl.cpp */; }; + 849C0D6E1B072D14008BAAA4 /* gdrom_hle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 849C0D691B072D14008BAAA4 /* gdrom_hle.cpp */; }; + 849C0D6F1B072D14008BAAA4 /* reios_elf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 849C0D6B1B072D14008BAAA4 /* reios_elf.cpp */; }; 8703BC3B1A44B8DA00E7E939 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 8703BC371A44B8DA00E7E939 /* Icon-72.png */; }; 8703BC3C1A44B8DA00E7E939 /* Icon-72@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8703BC381A44B8DA00E7E939 /* Icon-72@2x.png */; }; 8703BC3D1A44B8DA00E7E939 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 8703BC391A44B8DA00E7E939 /* Icon.png */; }; @@ -239,6 +244,16 @@ 8497BCC81A41BFBA00EFB9ED /* oslib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oslib.h; sourceTree = ""; }; 8497BCCD1A41BFD800EFB9ED /* coreio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = coreio.cpp; sourceTree = ""; }; 8497BCCE1A41BFD800EFB9ED /* coreio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = coreio.h; sourceTree = ""; }; + 849C0D601B072C07008BAAA4 /* context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = context.cpp; sourceTree = ""; }; + 849C0D611B072C07008BAAA4 /* context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = context.h; sourceTree = ""; }; + 849C0D641B072CF8008BAAA4 /* reios.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = reios.cpp; path = reios/reios.cpp; sourceTree = ""; }; + 849C0D651B072CF8008BAAA4 /* reios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = reios.h; path = reios/reios.h; sourceTree = ""; }; + 849C0D671B072D14008BAAA4 /* descrambl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = descrambl.cpp; path = reios/descrambl.cpp; sourceTree = ""; }; + 849C0D681B072D14008BAAA4 /* descrambl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = descrambl.h; path = reios/descrambl.h; sourceTree = ""; }; + 849C0D691B072D14008BAAA4 /* gdrom_hle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = gdrom_hle.cpp; path = reios/gdrom_hle.cpp; sourceTree = ""; }; + 849C0D6A1B072D14008BAAA4 /* gdrom_hle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = gdrom_hle.h; path = reios/gdrom_hle.h; sourceTree = ""; }; + 849C0D6B1B072D14008BAAA4 /* reios_elf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = reios_elf.cpp; path = reios/reios_elf.cpp; sourceTree = ""; }; + 849C0D6C1B072D14008BAAA4 /* reios_elf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = reios_elf.h; path = reios/reios_elf.h; sourceTree = ""; }; 8703BC371A44B8DA00E7E939 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = ""; }; 8703BC381A44B8DA00E7E939 /* Icon-72@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72@2x.png"; sourceTree = ""; }; 8703BC391A44B8DA00E7E939 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; @@ -612,6 +627,8 @@ 8497BCBB1A41A0E900EFB9ED /* linux */ = { isa = PBXGroup; children = ( + 849C0D601B072C07008BAAA4 /* context.cpp */, + 849C0D611B072C07008BAAA4 /* context.h */, 8497BCBC1A41A0E900EFB9ED /* common.cpp */, 8497BCBD1A41A0E900EFB9ED /* nixprof.cpp */, 8497BCBE1A41A0E900EFB9ED /* typedefs.h */, @@ -641,6 +658,21 @@ path = deps/coreio; sourceTree = ""; }; + 849C0D631B072CE0008BAAA4 /* reios */ = { + isa = PBXGroup; + children = ( + 849C0D671B072D14008BAAA4 /* descrambl.cpp */, + 849C0D681B072D14008BAAA4 /* descrambl.h */, + 849C0D691B072D14008BAAA4 /* gdrom_hle.cpp */, + 849C0D6A1B072D14008BAAA4 /* gdrom_hle.h */, + 849C0D6B1B072D14008BAAA4 /* reios_elf.cpp */, + 849C0D6C1B072D14008BAAA4 /* reios_elf.h */, + 849C0D641B072CF8008BAAA4 /* reios.cpp */, + 849C0D651B072CF8008BAAA4 /* reios.h */, + ); + name = reios; + sourceTree = ""; + }; 8703BC361A44B8DA00E7E939 /* assets */ = { isa = PBXGroup; children = ( @@ -783,6 +815,7 @@ 9C7A393818C806DE0070BB5F /* Emulator Core Code */ = { isa = PBXGroup; children = ( + 849C0D631B072CE0008BAAA4 /* reios */, 8497BCCC1A41BFD800EFB9ED /* coreio */, 8497BCC31A41BFBA00EFB9ED /* oslib */, 8497BCBB1A41A0E900EFB9ED /* linux */, @@ -1481,6 +1514,7 @@ 9C7A3B1018C806E00070BB5F /* maple_devs.cpp in Sources */, 9C7A3AE718C806E00070BB5F /* zip_source_function.c in Sources */, 9C7A3AE918C806E00070BB5F /* zip_stat.c in Sources */, + 849C0D661B072CF8008BAAA4 /* reios.cpp in Sources */, 9C7A3ABF18C806E00070BB5F /* zip_delete.c in Sources */, 9C7A3B0018C806E00070BB5F /* aica.cpp in Sources */, 9C7A3B3318C806E00070BB5F /* sh4_rom.cpp in Sources */, @@ -1508,6 +1542,7 @@ 9C7A3B1418C806E00070BB5F /* drkPvr.cpp in Sources */, 9C7A3AB318C806E00070BB5F /* pngrtran.c in Sources */, 9C7A3AEC18C806E00070BB5F /* zip_strerror.c in Sources */, + 849C0D6F1B072D14008BAAA4 /* reios_elf.cpp in Sources */, 9C7A3AB718C806E00070BB5F /* pngwio.c in Sources */, 8497BCCB1A41BFBA00EFB9ED /* ds_audiostream.cpp in Sources */, 9C7A3B2D18C806E00070BB5F /* ubc.cpp in Sources */, @@ -1558,6 +1593,7 @@ 9C7A3B2018C806E00070BB5F /* shil.cpp in Sources */, 9C7A3B2518C806E00070BB5F /* ccn.cpp in Sources */, 9C7A3B4618C806E00070BB5F /* ngen_arm.S in Sources */, + 849C0D621B072C07008BAAA4 /* context.cpp in Sources */, 9C7A3AD618C806E00070BB5F /* zip_get_file_comment.c in Sources */, 9C7A3AEA18C806E00070BB5F /* zip_stat_index.c in Sources */, 9C7A3ACF18C806E00070BB5F /* zip_filerange_crc.c in Sources */, @@ -1592,6 +1628,7 @@ 9C7A3B0918C806E00070BB5F /* gdrom_response.cpp in Sources */, 9C7A3B2218C806E00070BB5F /* sh4_interpreter.cpp in Sources */, 9C7A3B3818C806E00070BB5F /* gdi.cpp in Sources */, + 849C0D6D1B072D14008BAAA4 /* descrambl.cpp in Sources */, 9C7A3AF018C806E00070BB5F /* zip_unchange_data.c in Sources */, 9C7A3AB218C806E00070BB5F /* pngrio.c in Sources */, 9C7A3AC118C806E00070BB5F /* zip_entry_free.c in Sources */, @@ -1614,6 +1651,7 @@ 9C7A3AF618C806E00070BB5F /* inffast.c in Sources */, 9C7A3B1318C806E00070BB5F /* _vmem.cpp in Sources */, 9C7A3B1118C806E00070BB5F /* maple_helper.cpp in Sources */, + 849C0D6E1B072D14008BAAA4 /* gdrom_hle.cpp in Sources */, 9C7A3AD018C806E00070BB5F /* zip_fopen.c in Sources */, 9C7A3B1718C806E00070BB5F /* pvr_sb_regs.cpp in Sources */, 9C7A3B3918C806E00070BB5F /* ImgReader.cpp in Sources */, From 2d842b9257ce5da3d725165d283b85b3a59c5446 Mon Sep 17 00:00:00 2001 From: Stefanos Kornilios Mitsis Poiitidis Date: Sat, 16 May 2015 01:10:47 -0700 Subject: [PATCH 19/20] Renderer_if: fix norend --- core/hw/pvr/Renderer_if.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/hw/pvr/Renderer_if.cpp b/core/hw/pvr/Renderer_if.cpp index f310e9598..9f334d11c 100644 --- a/core/hw/pvr/Renderer_if.cpp +++ b/core/hw/pvr/Renderer_if.cpp @@ -344,7 +344,7 @@ bool rend_init() { #ifdef NO_REND - rend = rend_norend(); + renderer = rend_norend(); #else #if HOST_OS == OS_WINDOWS From 4ea7398d8a7f038a41d5f24efdc16410283e8dd4 Mon Sep 17 00:00:00 2001 From: ~skmp Date: Sat, 16 May 2015 11:23:31 +0300 Subject: [PATCH 20/20] Linux: fix building --- core/linux-dist/main.cpp | 2 ++ core/linux/common.cpp | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/core/linux-dist/main.cpp b/core/linux-dist/main.cpp index 1549f2966..48d5201cd 100755 --- a/core/linux-dist/main.cpp +++ b/core/linux-dist/main.cpp @@ -198,6 +198,8 @@ bool HandleKb(u32 port) { if (kbfd < 0) return false; + input_event ie; + #if defined(TARGET_GCW0) #define KEY_A 0x1D diff --git a/core/linux/common.cpp b/core/linux/common.cpp index d28c1ed88..422689aa4 100644 --- a/core/linux/common.cpp +++ b/core/linux/common.cpp @@ -1,4 +1,4 @@ - #include "types.h" +#include "types.h" #include "cfg/cfg.h" #if HOST_OS==OS_LINUX || HOST_OS == OS_DARWIN @@ -234,7 +234,7 @@ double os_GetSeconds() return a.tv_sec-tvs_base+a.tv_usec/1000000.0; } -#if !defined(_ANDROID) +#if HOST_OS != OS_LINUX void os_DebugBreak() { __builtin_trap();