diff --git a/Makefile.menu2_wii b/Makefile.menu2_wii index e9ba5ee..efa835f 100644 --- a/Makefile.menu2_wii +++ b/Makefile.menu2_wii @@ -7,14 +7,14 @@ AS =powerpc-eabi-as CXXFLAGS = -g -O3 -Wall $(MACHDEP) $(INCLUDE) \ -DCPU_SHUTDOWN -DSPC700_SHUTDOWN -DVAR_CYCLES -DSOUND \ -DNOASM -DNGC -DNOASM -DPIXEL_FORMAT=RGB565 \ - -fno-exceptions -Wno-unused-parameter -pipe \ + -fno-exceptions -Wno-unused-parameter -pipe -flto \ -DUSE_GUI -DWII -DHW_RVL -D__wii__ -DGLN64_GX -DAIDUMP -DUSE_EXPANSION \ -DTHREADED_AUDIO -DUSE_RECOMP_CACHE -DPPC_DYNAREC -DFASTMEM -DMENU_V2\ -DRELEASE #-DSHOW_DEBUG #-DPRINTGECKO #-DPROFILE #-DDEBUGON #-DUSE_TLB_CACHE \ #-DNO_BT -DUSE_ROM_CACHE_L1 -DPRINTGECKO -DGLN64_SDLOG -DEMBEDDED_FONTS -DUSE_EXPANSION -DSHOW_STATS MACHDEP = -DGEKKO -mcpu=750 -meabi -mhard-float -LDFLAGS = $(MACHDEP) -mrvl -Wl,-Map,$(notdir $@).map -Wl,--cref +LDFLAGS = $(MACHDEP) -flto -mrvl -Wl,-Map,$(notdir $@).map -Wl,--cref INCLUDE = -I$(DEVKITPRO)/libogc/include -I$(DEVKITPRO)/portlibs/ppc/include LIBPATHS = -L$(DEVKITPRO)/libogc/lib/wii -L$(DEVKITPRO)/portlibs/ppc/lib diff --git a/gc_memory/dma.c b/gc_memory/dma.c index 52f65ab..109d0f3 100644 --- a/gc_memory/dma.c +++ b/gc_memory/dma.c @@ -250,8 +250,10 @@ void dma_pi_write() /*for (i=0; i<=((longueur+0x800)>>12); i++) invalid_code[(((pi_register.pi_dram_addr_reg&0xFFFFFF)|0x80000000)>>12)+i] = 1;*/ - if ((debug_count+Count) < 0x100000) - { + // Set the RDRAM memory size when copying main ROM code + // (This is just a convenient way to run this code once at the beginning) + if (pi_register.pi_cart_addr_reg == 0x10001000) + { switch(CIC_Chip) { case 1: diff --git a/gc_memory/memory.c b/gc_memory/memory.c index bc78fe8..d7c32e0 100644 --- a/gc_memory/memory.c +++ b/gc_memory/memory.c @@ -198,13 +198,13 @@ void (*rw_pif[8])() = // memory sections -static unsigned long *readrdramreg[0xFFFF]; +static unsigned long *readrdramreg[0x10000]; static unsigned long *readrspreg[0x30]; static unsigned long *readrsp[0x10]; static unsigned long *readmi[0x20]; static unsigned long *readvi[0x40]; static unsigned long *readai[0x20]; -static unsigned long *readpi[0xFFFF]; +static unsigned long *readpi[0x10000]; static unsigned long *readri[0x30]; static unsigned long *readsi[0x20]; static unsigned long *readdp[0x30]; @@ -657,137 +657,56 @@ void free_memory() static void update_MI_init_mode_reg() { - MI_register.init_length = MI_register.w_mi_init_mode_reg & 0x7F; - if (MI_register.w_mi_init_mode_reg & 0x80) - MI_register.init_mode = 0; - if (MI_register.w_mi_init_mode_reg & 0x100) - MI_register.init_mode = 1; - if (MI_register.w_mi_init_mode_reg & 0x200) - MI_register.ebus_test_mode = 0; - if (MI_register.w_mi_init_mode_reg & 0x400) - MI_register.ebus_test_mode = 1; - if (MI_register.w_mi_init_mode_reg & 0x800) + MI_register.mi_init_mode_reg &= ~0x7F; // init_length + MI_register.mi_init_mode_reg |= MI_register.w_mi_init_mode_reg & 0x7F; + if (MI_register.w_mi_init_mode_reg & 0x80) // clear init_mode + MI_register.mi_init_mode_reg &= ~0x80; + if (MI_register.w_mi_init_mode_reg & 0x100) // set init_mode + MI_register.mi_init_mode_reg |= 0x80; + if (MI_register.w_mi_init_mode_reg & 0x200) // clear ebus_test_mode + MI_register.mi_init_mode_reg &= ~0x100; + if (MI_register.w_mi_init_mode_reg & 0x400) // set ebus_test_mode + MI_register.mi_init_mode_reg |= 0x100; + if (MI_register.w_mi_init_mode_reg & 0x800) // clear DP interupt { MI_register.mi_intr_reg &= 0xFFFFFFDF; check_interupt(); } - if (MI_register.w_mi_init_mode_reg & 0x1000) - MI_register.RDRAM_reg_mode=0; - if (MI_register.w_mi_init_mode_reg & 0x2000) - MI_register.RDRAM_reg_mode=1; - MI_register.mi_init_mode_reg = ((MI_register.init_length) | - (MI_register.init_mode << 7) | - (MI_register.ebus_test_mode << 8) | - (MI_register.RDRAM_reg_mode << 9) - ); + if (MI_register.w_mi_init_mode_reg & 0x1000) // clear RDRAM_reg_mode + MI_register.mi_init_mode_reg &= ~0x200; + if (MI_register.w_mi_init_mode_reg & 0x2000) // set RDRAM_reg_mode + MI_register.mi_init_mode_reg |= 0x200; } static void update_MI_intr_mask_reg() { - if (MI_register.w_mi_intr_mask_reg & 0x1) MI_register.SP_intr_mask = 0; - if (MI_register.w_mi_intr_mask_reg & 0x2) MI_register.SP_intr_mask = 1; - if (MI_register.w_mi_intr_mask_reg & 0x4) MI_register.SI_intr_mask = 0; - if (MI_register.w_mi_intr_mask_reg & 0x8) MI_register.SI_intr_mask = 1; - if (MI_register.w_mi_intr_mask_reg & 0x10) MI_register.AI_intr_mask = 0; - if (MI_register.w_mi_intr_mask_reg & 0x20) MI_register.AI_intr_mask = 1; - if (MI_register.w_mi_intr_mask_reg & 0x40) MI_register.VI_intr_mask = 0; - if (MI_register.w_mi_intr_mask_reg & 0x80) MI_register.VI_intr_mask = 1; - if (MI_register.w_mi_intr_mask_reg & 0x100) MI_register.PI_intr_mask = 0; - if (MI_register.w_mi_intr_mask_reg & 0x200) MI_register.PI_intr_mask = 1; - if (MI_register.w_mi_intr_mask_reg & 0x400) MI_register.DP_intr_mask = 0; - if (MI_register.w_mi_intr_mask_reg & 0x800) MI_register.DP_intr_mask = 1; - MI_register.mi_intr_mask_reg = ((MI_register.SP_intr_mask) | - (MI_register.SI_intr_mask << 1) | - (MI_register.AI_intr_mask << 2) | - (MI_register.VI_intr_mask << 3) | - (MI_register.PI_intr_mask << 4) | - (MI_register.DP_intr_mask << 5) - ); + if (MI_register.w_mi_intr_mask_reg & 0x1) MI_register.mi_intr_mask_reg &= ~0x1; // clear SP mask + if (MI_register.w_mi_intr_mask_reg & 0x2) MI_register.mi_intr_mask_reg |= 0x1; // set SP mask + if (MI_register.w_mi_intr_mask_reg & 0x4) MI_register.mi_intr_mask_reg &= ~0x2; // clear SI mask + if (MI_register.w_mi_intr_mask_reg & 0x8) MI_register.mi_intr_mask_reg |= 0x2; // set SI mask + if (MI_register.w_mi_intr_mask_reg & 0x10) MI_register.mi_intr_mask_reg &= ~0x4; // clear AI mask + if (MI_register.w_mi_intr_mask_reg & 0x20) MI_register.mi_intr_mask_reg |= 0x4; // set AI mask + if (MI_register.w_mi_intr_mask_reg & 0x40) MI_register.mi_intr_mask_reg &= ~0x8; // clear VI mask + if (MI_register.w_mi_intr_mask_reg & 0x80) MI_register.mi_intr_mask_reg |= 0x8; // set VI mask + if (MI_register.w_mi_intr_mask_reg & 0x100) MI_register.mi_intr_mask_reg &= ~0x10; // clear PI mask + if (MI_register.w_mi_intr_mask_reg & 0x200) MI_register.mi_intr_mask_reg |= 0x10; // set PI mask + if (MI_register.w_mi_intr_mask_reg & 0x400) MI_register.mi_intr_mask_reg &= ~0x20; // clear DP mask + if (MI_register.w_mi_intr_mask_reg & 0x800) MI_register.mi_intr_mask_reg |= 0x20; // set DP mask } -void update_SP() +static void do_SP_task() { - if (sp_register.w_sp_status_reg & 0x1) - sp_register.halt = 0; - if (sp_register.w_sp_status_reg & 0x2) - sp_register.halt = 1; - if (sp_register.w_sp_status_reg & 0x4) - sp_register.broke = 0; - if (sp_register.w_sp_status_reg & 0x8) - { - MI_register.mi_intr_reg &= 0xFFFFFFFE; - check_interupt(); - } - if (sp_register.w_sp_status_reg & 0x10) - { - MI_register.mi_intr_reg |= 1; - check_interupt(); - } - if (sp_register.w_sp_status_reg & 0x20) - sp_register.single_step = 0; - if (sp_register.w_sp_status_reg & 0x40) - sp_register.single_step = 1; - if (sp_register.w_sp_status_reg & 0x80) - sp_register.intr_break = 0; - if (sp_register.w_sp_status_reg & 0x100) - sp_register.intr_break = 1; - if (sp_register.w_sp_status_reg & 0x200) - sp_register.signal0 = 0; - if (sp_register.w_sp_status_reg & 0x400) - sp_register.signal0 = 1; - if (sp_register.w_sp_status_reg & 0x800) - sp_register.signal1 = 0; - if (sp_register.w_sp_status_reg & 0x1000) - sp_register.signal1 = 1; - if (sp_register.w_sp_status_reg & 0x2000) - sp_register.signal2 = 0; - if (sp_register.w_sp_status_reg & 0x4000) - sp_register.signal2 = 1; - if (sp_register.w_sp_status_reg & 0x8000) - sp_register.signal3 = 0; - if (sp_register.w_sp_status_reg & 0x10000) - sp_register.signal3 = 1; - if (sp_register.w_sp_status_reg & 0x20000) - sp_register.signal4 = 0; - if (sp_register.w_sp_status_reg & 0x40000) - sp_register.signal4 = 1; - if (sp_register.w_sp_status_reg & 0x80000) - sp_register.signal5 = 0; - if (sp_register.w_sp_status_reg & 0x100000) - sp_register.signal5 = 1; - if (sp_register.w_sp_status_reg & 0x200000) - sp_register.signal6 = 0; - if (sp_register.w_sp_status_reg & 0x400000) - sp_register.signal6 = 1; - if (sp_register.w_sp_status_reg & 0x800000) - sp_register.signal7 = 0; - if (sp_register.w_sp_status_reg & 0x1000000) - sp_register.signal7 = 1; - sp_register.sp_status_reg = ((sp_register.halt) | - (sp_register.broke << 1) | - (sp_register.dma_busy << 2) | - (sp_register.dma_full << 3) | - (sp_register.io_full << 4) | - (sp_register.single_step << 5) | - (sp_register.intr_break << 6) | - (sp_register.signal0 << 7) | - (sp_register.signal1 << 8) | - (sp_register.signal2 << 9) | - (sp_register.signal3 << 10) | - (sp_register.signal4 << 11) | - (sp_register.signal5 << 12) | - (sp_register.signal6 << 13) | - (sp_register.signal7 << 14) - ); - //if (get_event(SP_INT)) return; - if (!(sp_register.w_sp_status_reg & 0x1) && - !(sp_register.w_sp_status_reg & 0x4)) return; - if (!sp_register.halt && !sp_register.broke) - { int save_pc = rsp_register.rsp_pc & ~0xFFF; if (SP_DMEM[0xFC0/4] == 1) { + if (dpc_register.dpc_status & 0x2) // DP frozen (DK64, BC) + { + // don't do the task now + // the task will be done when DP is unfreezed (see update_DPC) + return; + } + // unprotecting old frame buffers if(fBGetFrameBufferInfo && fBRead && fBWrite && frameBufferInfos[0].addr) @@ -821,12 +740,6 @@ void update_SP() rsp_register.rsp_pc |= save_pc; new_frame(); - MI_register.mi_intr_reg &= ~0x21; - sp_register.sp_status_reg &= ~0x303; - update_count(); - add_interupt_event(SP_INT, 1000); - add_interupt_event(DP_INT, 1000); - // protecting new frame buffers if(fBGetFrameBufferInfo && fBRead && fBWrite) fBGetFrameBufferInfo(frameBufferInfos); if(fBGetFrameBufferInfo && fBRead && fBWrite && @@ -877,58 +790,99 @@ void update_SP() doRspCycles(100); end_section(AUDIO_SECTION); rsp_register.rsp_pc |= save_pc; - - MI_register.mi_intr_reg &= ~0x1; - sp_register.sp_status_reg &= ~0x303; - update_count(); - //add_interupt_event(SP_INT, 500); - add_interupt_event(SP_INT, 4000); } else { - //printf("other task\n"); rsp_register.rsp_pc &= 0xFFF; doRspCycles(100); rsp_register.rsp_pc |= save_pc; - - MI_register.mi_intr_reg &= ~0x1; - sp_register.sp_status_reg &= ~0x203; - update_count(); - add_interupt_event(SP_INT, 0/*100*/); } - //printf("unknown task type\n"); - /*if (hle) execute_dlist(); - //if (hle) processDList(); - else sp_register.halt = 0;*/ +} + +void update_SP() +{ + if (sp_register.w_sp_status_reg & 0x1) // clear halt + sp_register.sp_status_reg &= ~0x1; + if (sp_register.w_sp_status_reg & 0x2) // set halt + sp_register.sp_status_reg |= 0x1; + if (sp_register.w_sp_status_reg & 0x4) // clear broke + sp_register.sp_status_reg &= ~0x2; + if (sp_register.w_sp_status_reg & 0x8) // clear SP interupt + { + MI_register.mi_intr_reg &= 0xFFFFFFFE; + check_interupt(); + } + if (sp_register.w_sp_status_reg & 0x10) // set SP interupt + { + MI_register.mi_intr_reg |= 1; + check_interupt(); } + if (sp_register.w_sp_status_reg & 0x20) // clear single step + sp_register.sp_status_reg &= ~0x20; + if (sp_register.w_sp_status_reg & 0x40) // set single step + sp_register.sp_status_reg |= 0x20; + if (sp_register.w_sp_status_reg & 0x80) // clear interrupt on break + sp_register.sp_status_reg &= ~0x40; + if (sp_register.w_sp_status_reg & 0x100) // set interrupt on break + sp_register.sp_status_reg |= 0x40; + if (sp_register.w_sp_status_reg & 0x200) // clear signal 0 + sp_register.sp_status_reg &= ~0x80; + if (sp_register.w_sp_status_reg & 0x400) // set signal 0 + sp_register.sp_status_reg |= 0x80; + if (sp_register.w_sp_status_reg & 0x800) // clear signal 1 + sp_register.sp_status_reg &= ~0x100; + if (sp_register.w_sp_status_reg & 0x1000) // set signal 1 + sp_register.sp_status_reg |= 0x100; + if (sp_register.w_sp_status_reg & 0x2000) // clear signal 2 + sp_register.sp_status_reg &= ~0x200; + if (sp_register.w_sp_status_reg & 0x4000) // set signal 2 + sp_register.sp_status_reg |= 0x200; + if (sp_register.w_sp_status_reg & 0x8000) // clear signal 3 + sp_register.sp_status_reg &= ~0x400; + if (sp_register.w_sp_status_reg & 0x10000) // set signal 3 + sp_register.sp_status_reg |= 0x400; + if (sp_register.w_sp_status_reg & 0x20000) // clear signal 4 + sp_register.sp_status_reg &= ~0x800; + if (sp_register.w_sp_status_reg & 0x40000) // set signal 4 + sp_register.sp_status_reg |= 0x800; + if (sp_register.w_sp_status_reg & 0x80000) // clear signal 5 + sp_register.sp_status_reg &= ~0x1000; + if (sp_register.w_sp_status_reg & 0x100000) // set signal 5 + sp_register.sp_status_reg |= 0x1000; + if (sp_register.w_sp_status_reg & 0x200000) // clear signal 6 + sp_register.sp_status_reg &= ~0x2000; + if (sp_register.w_sp_status_reg & 0x400000) // set signal 6 + sp_register.sp_status_reg |= 0x2000; + if (sp_register.w_sp_status_reg & 0x800000) // clear signal 7 + sp_register.sp_status_reg &= ~0x4000; + if (sp_register.w_sp_status_reg & 0x1000000) // set signal 7 + sp_register.sp_status_reg |= 0x4000; + + if (!(sp_register.w_sp_status_reg & 0x1) && + !(sp_register.w_sp_status_reg & 0x4)) return; + if (!(sp_register.sp_status_reg & 0x3)) // !halt && !broke + do_SP_task(); } void update_DPC() { - if (dpc_register.w_dpc_status & 0x1) - dpc_register.xbus_dmem_dma = 0; - if (dpc_register.w_dpc_status & 0x2) - dpc_register.xbus_dmem_dma = 1; - if (dpc_register.w_dpc_status & 0x4) - dpc_register.freeze = 0; - if (dpc_register.w_dpc_status & 0x8) - dpc_register.freeze = 1; - if (dpc_register.w_dpc_status & 0x10) - dpc_register.flush = 0; - if (dpc_register.w_dpc_status & 0x20) - dpc_register.flush = 1; - dpc_register.dpc_status = ((dpc_register.xbus_dmem_dma) | - (dpc_register.freeze << 1) | - (dpc_register.flush << 2) | - (dpc_register.start_glck << 3) | - (dpc_register.tmem_busy << 4) | - (dpc_register.pipe_busy << 5) | - (dpc_register.cmd_busy << 6) | - (dpc_register.cbuf_busy << 7) | - (dpc_register.dma_busy << 8) | - (dpc_register.end_valid << 9) | - (dpc_register.start_valid << 10) - ); + if (dpc_register.w_dpc_status & 0x1) // clear xbus_dmem_dma + dpc_register.dpc_status &= ~0x1; + if (dpc_register.w_dpc_status & 0x2) // set xbus_dmem_dma + dpc_register.dpc_status |= 0x1; + if (dpc_register.w_dpc_status & 0x4) // clear freeze + { + dpc_register.dpc_status &= ~0x2; + // see do_SP_task for more info + if (!(sp_register.sp_status_reg & 0x3)) // !halt && !broke + do_SP_task(); + } + if (dpc_register.w_dpc_status & 0x8) // set freeze + dpc_register.dpc_status |= 0x2; + if (dpc_register.w_dpc_status & 0x10) // clear flush + dpc_register.dpc_status &= ~0x4; + if (dpc_register.w_dpc_status & 0x20) // set flush + dpc_register.dpc_status |= 0x4; } void read_nothing() diff --git a/glN64_GX/VI.cpp b/glN64_GX/VI.cpp index 41e1fe9..e674238 100644 --- a/glN64_GX/VI.cpp +++ b/glN64_GX/VI.cpp @@ -126,6 +126,9 @@ void VI_UpdateScreen() } glFinish(); #else // !__GX__ + //Hack for OOT + extern u32 subscreen_address; + if(subscreen_address) RDRAM[subscreen_address] = 2; if (renderCpuFramebuffer) { //Only render N64 framebuffer in RDRAM and not EFB diff --git a/libgui/GraphicsGX.cpp b/libgui/GraphicsGX.cpp index 4a3fa9f..b2825a0 100644 --- a/libgui/GraphicsGX.cpp +++ b/libgui/GraphicsGX.cpp @@ -49,7 +49,7 @@ Graphics::Graphics(GXRModeObj *rmode) VIDEO_Init(); //vmode = VIDEO_GetPreferredMode(NULL); vmode = VIDEO_GetPreferredMode(&vmode_phys); -#if 0 +#if 1 if(CONF_GetAspectRatio()) { vmode->viWidth = 678; vmode->viXOrigin = (VI_MAX_WIDTH_PAL - 678) / 2; diff --git a/libgui/Gui.cpp b/libgui/Gui.cpp index 6826b96..bf321b4 100644 --- a/libgui/Gui.cpp +++ b/libgui/Gui.cpp @@ -122,12 +122,19 @@ void Gui::draw() else //Return to Loader/WiiFlow { #ifdef WII - if(dvd_hard_init) { - DI_Close(); - } + if(dvd_hard_init) { + DI_Close(); + } #endif void (*rld)() = (void (*)()) 0x80001800; - rld(); + #define HBC_STUB 0x53545542 + #define HBC_HAXX 0x48415858 + //Load HBC Stub if STUBAXX signature is present + if(*(volatile unsigned int*)0x80001804 == HBC_STUB && + *(volatile unsigned int*)0x80001808 == HBC_HAXX) + rld(); + else + SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0); } } diff --git a/main/rom_gc.c b/main/rom_gc.c index fbc27d6..55784e8 100644 --- a/main/rom_gc.c +++ b/main/rom_gc.c @@ -157,7 +157,7 @@ void byte_swap(char* buffer, unsigned int length){ } } } - +u32 subscreen_address; /* Loads the ROM into the ROM cache */ int rom_read(fileBrowser_file* file){ @@ -200,6 +200,48 @@ int rom_read(fileBrowser_file* file){ //Set VI limit based on ROM header InitTimer(); + //Hack for OOT + subscreen_address = 0; + if (strncmp((char *)ROM_HEADER->nom, "THE LEGEND OF ZELDA", 19) == 0) { + if (sl(ROM_HEADER->CRC1) == 0xEC7011B7 && sl(ROM_HEADER->CRC2) == 0x7616D72B) { + // Legend of Zelda, The - Ocarina of Time (U) + (J) (V1.0) + subscreen_address = 0x1DA5CB; + } else if (sl(ROM_HEADER->CRC1) == 0xD43DA81F && sl(ROM_HEADER->CRC2) == 0x021E1E19) { + // Legend of Zelda, The - Ocarina of Time (U) + (J) (V1.1) + subscreen_address = 0x1DA78B; + } else if (sl(ROM_HEADER->CRC1) == 0x693BA2AE && sl(ROM_HEADER->CRC2) == 0xB7F14E9F) { + // Legend of Zelda, The - Ocarina of Time (U) + (J) (V1.2) + subscreen_address = 0x1DAE8B; + } else if (sl(ROM_HEADER->CRC1) == 0xB044B569 && sl(ROM_HEADER->CRC2) == 0x373C1985) { + // Legend of Zelda, The - Ocarina of Time (E) (V1.0) + subscreen_address = 0x1D860B; + } else if (sl(ROM_HEADER->CRC1) == 0xB2055FBD && sl(ROM_HEADER->CRC2) == 0x0BAB4E0C) { + // Legend of Zelda, The - Ocarina of Time (E) (V1.1) + subscreen_address = 0x1D864B; + // GC Versions + } else if (sl(ROM_HEADER->CRC1) == 0x1D4136F3 && sl(ROM_HEADER->CRC2) == 0xAF63EEA9) { + // Legend of Zelda, The - Ocarina of Time - Master Quest (E) (GC Version) + subscreen_address = 0x1D8F4B; + } else if (sl(ROM_HEADER->CRC1) == 0x09465AC3 && sl(ROM_HEADER->CRC2) == 0xF8CB501B) { + // Legend of Zelda, The - Ocarina of Time (E) (GC Version) + subscreen_address = 0x1D8F8B; + } else if (sl(ROM_HEADER->CRC1) == 0xF3DD35BA && sl(ROM_HEADER->CRC2) == 0x4152E075) { + // Legend of Zelda, The - Ocarina of Time (U) (GC Version) + subscreen_address = 0x1DB78B; + } else if (sl(ROM_HEADER->CRC1) == 0xF034001A && sl(ROM_HEADER->CRC2) == 0xAE47ED06) { + // Legend of Zelda, The - Ocarina of Time - Master Quest (U) (GC Version) + subscreen_address = 0x1DB74B; + } else if (sl(ROM_HEADER->CRC1) == 0xF7F52DB8 && sl(ROM_HEADER->CRC2) == 0x2195E636) { + // Zelda no Densetsu - Toki no Ocarina - Zelda Collection Version (J) (GC Version) + subscreen_address = 0x1DB78B; + } else if (sl(ROM_HEADER->CRC1) == 0xF611F4BA && sl(ROM_HEADER->CRC2) == 0xC584135C) { + // Zelda no Densetsu - Toki no Ocarina GC (J) (GC Version) + subscreen_address = 0x1DB78B; + } else if (sl(ROM_HEADER->CRC1) == 0xF43B45BA && sl(ROM_HEADER->CRC2) == 0x2F0E9B6F) { + // Zelda no Densetsu - Toki no Ocarina GC Ura (J) (GC Version) + subscreen_address = 0x1DB78B; + } + } return ret; } diff --git a/r4300/ppc/MIPS-to-PPC.c b/r4300/ppc/MIPS-to-PPC.c index 6543e12..f7804e6 100644 --- a/r4300/ppc/MIPS-to-PPC.c +++ b/r4300/ppc/MIPS-to-PPC.c @@ -31,6 +31,7 @@ #include "Register-Cache.h" #include "Interpreter.h" #include "Wrappers.h" +#include "../../gc_memory/memory.h" #include #include @@ -47,6 +48,7 @@ static void genJumpTo(unsigned int loc, unsigned int type); static void genUpdateCount(int checkCount); static void genCheckFP(void); void genCallDynaMem(memType type, int base, short immed); +static int genCallDynaMemVM(int rs_reg, int rt_reg, memType type, int immed); void RecompCache_Update(PowerPC_func*); static int inline mips_is_jump(MIPS_instr); void jump_to(unsigned int); @@ -118,7 +120,7 @@ static inline int signExtend(int value, int size){ } static void genCmp64(int cr, int _ra, int _rb){ - PowerPC_instr ppc; + if(getRegisterMapping(_ra) == MAPPING_32 || getRegisterMapping(_rb) == MAPPING_32){ @@ -126,42 +128,34 @@ static void genCmp64(int cr, int _ra, int _rb){ // as 32-bit, only compare the 32-bit values int ra = mapRegister(_ra), rb = mapRegister(_rb); - GEN_CMP(ppc, ra, rb, 4); - set_next_dst(ppc); + EMIT_CMP(ra, rb, 4); } else { RegMapping ra = mapRegister64(_ra), rb = mapRegister64(_rb); - GEN_CMP(ppc, ra.hi, rb.hi, 4); - set_next_dst(ppc); + EMIT_CMP(ra.hi, rb.hi, 4); // Skip low word comparison if high words are mismatched - GEN_BNE(ppc, 4, 2, 0, 0); - set_next_dst(ppc); + EMIT_BNE(4, 2, 0, 0); // Compare low words if hi words don't match - GEN_CMPL(ppc, ra.lo, rb.lo, 4); - set_next_dst(ppc); + EMIT_CMPL(ra.lo, rb.lo, 4); } } static void genCmpi64(int cr, int _ra, short immed){ - PowerPC_instr ppc; + if(getRegisterMapping(_ra) == MAPPING_32){ // If we've mapped this register as 32-bit, don't bother with 64-bit int ra = mapRegister(_ra); - GEN_CMPI(ppc, ra, immed, 4); - set_next_dst(ppc); + EMIT_CMPI(ra, immed, 4); } else { RegMapping ra = mapRegister64(_ra); - GEN_CMPI(ppc, ra.hi, (immed&0x8000) ? ~0 : 0, 4); - set_next_dst(ppc); + EMIT_CMPI(ra.hi, (immed&0x8000) ? ~0 : 0, 4); // Skip low word comparison if high words are mismatched - GEN_BNE(ppc, 4, 2, 0, 0); - set_next_dst(ppc); + EMIT_BNE(4, 2, 0, 0); // Compare low words if hi words don't match - GEN_CMPLI(ppc, ra.lo, immed, 4); - set_next_dst(ppc); + EMIT_CMPLI(ra.lo, immed, 4); } } @@ -172,7 +166,7 @@ typedef enum { NONE=0, EQ, NE, LT, GT, LE, GE } condition; // link: if nonzero, branch and link // likely: if nonzero, the delay slot will only be executed when cond is true static int branch(int offset, condition cond, int link, int likely){ - PowerPC_instr ppc; + int likely_id; // Condition codes for bc (and their negations) int bo, bi, nbo; @@ -206,11 +200,9 @@ static int branch(int offset, condition cond, int link, int likely){ // Set LR to next instruction int lr = mapRegisterNew(MIPS_REG_LR); // lis lr, pc@ha(0) - GEN_LIS(ppc, lr, (get_src_pc()+8)>>16); - set_next_dst(ppc); + EMIT_LIS(lr, (get_src_pc()+8)>>16); // la lr, pc@l(lr) - GEN_ORI(ppc, lr, lr, get_src_pc()+8); - set_next_dst(ppc); + EMIT_ORI(lr, lr, get_src_pc()+8); flushRegisters(); } @@ -218,8 +210,7 @@ static int branch(int offset, condition cond, int link, int likely){ if(likely){ // b[!cond] likely_id = add_jump_special(0); - GEN_BC(ppc, likely_id, 0, 0, nbo, bi); - set_next_dst(ppc); + EMIT_BC(likely_id, 0, 0, nbo, bi); } // Check the delay slot, and note how big it is @@ -228,13 +219,10 @@ static int branch(int offset, condition cond, int link, int likely){ int delaySlot = get_curr_dst() - preDelay; #ifdef COMPARE_CORE - GEN_LI(ppc, 4, 0, 1); - set_next_dst(ppc); + EMIT_LI(4, 1); if(likely){ - GEN_B(ppc, 2, 0, 0); - set_next_dst(ppc); - GEN_LI(ppc, 4, 0, 0); - set_next_dst(ppc); + EMIT_B(2, 0); + EMIT_LI(4, 0); set_jump_special(likely_id, delaySlot+2+1); } @@ -251,56 +239,41 @@ static int branch(int offset, condition cond, int link, int likely){ // b[!cond] // Note: if there's a delay slot, I will branch to the branch over it - GEN_BC(ppc, JUMPTO_OFF_SIZE+1, 0, 0, nbo, bi); - set_next_dst(ppc); + EMIT_BC(JUMPTO_OFF_SIZE+1, 0, 0, nbo, bi); genJumpTo(offset, JUMPTO_OFF); // The branch isn't taken, but we need to check interrupts // Load the address of the next instruction - GEN_LIS(ppc, 3, (get_src_pc()+4)>>16); - set_next_dst(ppc); - GEN_ORI(ppc, 3, 3, get_src_pc()+4); - set_next_dst(ppc); + EMIT_LIS(3, (get_src_pc()+4)>>16); + EMIT_ORI(3, 3, get_src_pc()+4); // If taking the interrupt, return to the trampoline - GEN_BLELR(ppc, 2, 0); - set_next_dst(ppc); + EMIT_BLELR(2, 0); #ifndef INTERPRET_BRANCH } else { // last_addr = naddr if(cond != NONE){ - GEN_BC(ppc, 4, 0, 0, bo, bi); - set_next_dst(ppc); - GEN_LIS(ppc, 3, (get_src_pc()+4)>>16); - set_next_dst(ppc); - GEN_ORI(ppc, 3, 3, get_src_pc()+4); - set_next_dst(ppc); - GEN_B(ppc, 3, 0, 0); - set_next_dst(ppc); + EMIT_BC(4, 0, 0, bo, bi); + EMIT_LIS(3, (get_src_pc()+4)>>16); + EMIT_ORI(3, 3, get_src_pc()+4); + EMIT_B(3, 0, 0); } - GEN_LIS(ppc, 3, (get_src_pc() + (offset<<2))>>16); - set_next_dst(ppc); - GEN_ORI(ppc, 3, 3, get_src_pc() + (offset<<2)); - set_next_dst(ppc); - GEN_STW(ppc, 3, 0, DYNAREG_LADDR); - set_next_dst(ppc); + EMIT_LIS(3, (get_src_pc() + (offset<<2))>>16); + EMIT_ORI(3, 3, get_src_pc() + (offset<<2)); + EMIT_STW(3, 0, DYNAREG_LADDR); // If taking the interrupt, return to the trampoline - GEN_BLELR(ppc, 2, 0); - set_next_dst(ppc); + EMIT_BLELR(2, 0); // The actual branch #if 0 // FIXME: Reenable this when blocks are small enough to BC within // Make sure that pass2 uses BD/LI as appropriate - GEN_BC(ppc, add_jump(offset, 0, 0), 0, 0, bo, bi); - set_next_dst(ppc); + EMIT_BC(add_jump(offset, 0, 0), 0, 0, bo, bi); #else - GEN_BC(ppc, 2, 0, 0, nbo, bi); - set_next_dst(ppc); - GEN_B(ppc, add_jump(offset, 0, 0), 0, 0); - set_next_dst(ppc); + EMIT_BC(2, 0, 0, nbo, bi); + EMIT_B(add_jump(offset, 0, 0), 0, 0); #endif } @@ -313,8 +286,7 @@ static int branch(int offset, condition cond, int link, int likely){ if(is_j_dst() && !is_j_out(0, 0)){ // Step over the already executed delay slot if the branch isn't taken // b delaySlot+1 - GEN_B(ppc, delaySlot+1, 0, 0); - set_next_dst(ppc); + EMIT_B(delaySlot+1, 0, 0); unget_last_src(); delaySlotNext = 2; @@ -328,7 +300,6 @@ static int branch(int offset, condition cond, int link, int likely){ #endif } - static int (*gen_ops[64])(MIPS_instr); int convert(void){ @@ -338,7 +309,7 @@ int convert(void){ MIPS_instr mips = get_next_src(); int result = gen_ops[MIPS_GET_OPCODE(mips)](mips); - + if(needFlush) flushRegisters(); return result; } @@ -350,7 +321,7 @@ static int NI(){ // -- Primary Opcodes -- static int J(MIPS_instr mips){ - PowerPC_instr ppc; + unsigned int naddr = (MIPS_GET_LI(mips)<<2)|((get_src_pc()+4)&0xf0000000); if(naddr == get_src_pc() || CANT_COMPILE_DELAY()){ @@ -368,8 +339,7 @@ static int J(MIPS_instr mips){ int delaySlot = get_curr_dst() - preDelay; #ifdef COMPARE_CORE - GEN_LI(ppc, 4, 0, 1); - set_next_dst(ppc); + EMIT_LI(4, 0, 1); #endif // Sets cr2 to (next_interupt ? Count) genUpdateCount(1); @@ -382,21 +352,16 @@ static int J(MIPS_instr mips){ genJumpTo(MIPS_GET_LI(mips), JUMPTO_ADDR); } else { // last_addr = naddr - GEN_LIS(ppc, 3, naddr>>16); - set_next_dst(ppc); - GEN_ORI(ppc, 3, 3, naddr); - set_next_dst(ppc); - GEN_STW(ppc, 3, 0, DYNAREG_LADDR); - set_next_dst(ppc); + EMIT_LIS(3, naddr>>16); + EMIT_ORI(3, 3, naddr); + EMIT_STW(3, 0, DYNAREG_LADDR); // if(next_interupt <= Count) return; - GEN_BLELR(ppc, 2, 0); - set_next_dst(ppc); + EMIT_BLELR(2, 0); // Even though this is an absolute branch // in pass 2, we generate a relative branch - GEN_B(ppc, add_jump(MIPS_GET_LI(mips), 1, 0), 0, 0); - set_next_dst(ppc); + EMIT_B(add_jump(MIPS_GET_LI(mips), 1, 0), 0, 0); } #endif @@ -412,7 +377,7 @@ static int J(MIPS_instr mips){ } static int JAL(MIPS_instr mips){ - PowerPC_instr ppc; + unsigned int naddr = (MIPS_GET_LI(mips)<<2)|((get_src_pc()+4)&0xf0000000); if(CANT_COMPILE_DELAY()){ @@ -429,8 +394,7 @@ static int JAL(MIPS_instr mips){ int delaySlot = get_curr_dst() - preDelay; #ifdef COMPARE_CORE - GEN_LI(ppc, 4, 0, 1); - set_next_dst(ppc); + EMIT_LI(4, 1); #endif // Sets cr2 to (next_interupt ? Count) genUpdateCount(1); @@ -438,11 +402,9 @@ static int JAL(MIPS_instr mips){ // Set LR to next instruction int lr = mapRegisterNew(MIPS_REG_LR); // lis lr, pc@ha(0) - GEN_LIS(ppc, lr, (get_src_pc()+4)>>16); - set_next_dst(ppc); + EMIT_LIS(lr, (get_src_pc()+4)>>16); // la lr, pc@l(lr) - GEN_ORI(ppc, lr, lr, get_src_pc()+4); - set_next_dst(ppc); + EMIT_ORI(lr, lr, get_src_pc()+4); flushRegisters(); @@ -454,21 +416,16 @@ static int JAL(MIPS_instr mips){ genJumpTo(MIPS_GET_LI(mips), JUMPTO_ADDR); } else { // last_addr = naddr - GEN_LIS(ppc, 3, naddr>>16); - set_next_dst(ppc); - GEN_ORI(ppc, 3, 3, naddr); - set_next_dst(ppc); - GEN_STW(ppc, 3, 0, DYNAREG_LADDR); - set_next_dst(ppc); + EMIT_LIS(3, naddr>>16); + EMIT_ORI(3, 3, naddr); + EMIT_STW(3, 0, DYNAREG_LADDR); /// if(next_interupt <= Count) return; - GEN_BLELR(ppc, 2, 0); - set_next_dst(ppc); + EMIT_BLELR(2, 0); // Even though this is an absolute branch // in pass 2, we generate a relative branch - GEN_B(ppc, add_jump(MIPS_GET_LI(mips), 1, 0), 0, 0); - set_next_dst(ppc); + EMIT_B(add_jump(MIPS_GET_LI(mips), 1, 0), 0, 0); } #endif @@ -484,7 +441,7 @@ static int JAL(MIPS_instr mips){ } static int BEQ(MIPS_instr mips){ - PowerPC_instr ppc; + if((MIPS_GET_IMMED(mips) == 0xffff && MIPS_GET_RA(mips) == MIPS_GET_RB(mips)) || @@ -500,7 +457,7 @@ static int BEQ(MIPS_instr mips){ } static int BNE(MIPS_instr mips){ - PowerPC_instr ppc; + if(CANT_COMPILE_DELAY()){ genCallInterp(mips); @@ -513,7 +470,7 @@ static int BNE(MIPS_instr mips){ } static int BLEZ(MIPS_instr mips){ - PowerPC_instr ppc; + if(CANT_COMPILE_DELAY()){ genCallInterp(mips); @@ -526,7 +483,7 @@ static int BLEZ(MIPS_instr mips){ } static int BGTZ(MIPS_instr mips){ - PowerPC_instr ppc; + if(CANT_COMPILE_DELAY()){ genCallInterp(mips); @@ -539,13 +496,12 @@ static int BGTZ(MIPS_instr mips){ } static int ADDIU(MIPS_instr mips){ - PowerPC_instr ppc; + int rs = mapRegister( MIPS_GET_RS(mips) ); - GEN_ADDI(ppc, + EMIT_ADDI( mapRegisterNew( MIPS_GET_RT(mips) ), rs, MIPS_GET_IMMED(mips)); - set_next_dst(ppc); return CONVERT_SUCCESS; } @@ -554,7 +510,7 @@ static int ADDI(MIPS_instr mips){ } static int SLTI(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_SLTI genCallInterp(mips); return INTERPRETED; @@ -565,23 +521,17 @@ static int SLTI(MIPS_instr mips){ int tmp = (rs == rt) ? mapRegisterTemp() : rt; // tmp = immed (sign extended) - GEN_ADDI(ppc, tmp, 0, MIPS_GET_IMMED(mips)); - set_next_dst(ppc); + EMIT_ADDI(tmp, 0, MIPS_GET_IMMED(mips)); // carry = rs < immed ? 0 : 1 (unsigned) - GEN_SUBFC(ppc, 0, tmp, rs); - set_next_dst(ppc); + EMIT_SUBFC(0, tmp, rs); // rt = ~(rs ^ immed) - GEN_EQV(ppc, rt, tmp, rs); - set_next_dst(ppc); + EMIT_EQV(rt, tmp, rs); // rt = sign(rs) == sign(immed) ? 1 : 0 - GEN_SRWI(ppc, rt, rt, 31); - set_next_dst(ppc); + EMIT_SRWI(rt, rt, 31); // rt += carry - GEN_ADDZE(ppc, rt, rt); - set_next_dst(ppc); + EMIT_ADDZE(rt, rt); // rt &= 1 ( = (sign(rs) == sign(immed)) xor (rs < immed (unsigned)) ) - GEN_RLWINM(ppc, rt, rt, 0, 31, 31); - set_next_dst(ppc); + EMIT_RLWINM(rt, rt, 0, 31, 31); if(rs == rt) unmapRegisterTemp(tmp); @@ -590,7 +540,7 @@ static int SLTI(MIPS_instr mips){ } static int SLTIU(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_SLTIU genCallInterp(mips); return INTERPRETED; @@ -600,71 +550,61 @@ static int SLTIU(MIPS_instr mips){ int rt = mapRegisterNew( MIPS_GET_RT(mips) ); // r0 = EXTS(immed) - GEN_ADDI(ppc, 0, 0, MIPS_GET_IMMED(mips)); - set_next_dst(ppc); + EMIT_ADDI(0, 0, MIPS_GET_IMMED(mips)); // carry = rs < immed ? 0 : 1 - GEN_SUBFC(ppc, rt, 0, rs); - set_next_dst(ppc); + EMIT_SUBFC(rt, 0, rs); // rt = carry - 1 ( = rs < immed ? -1 : 0 ) - GEN_SUBFE(ppc, rt, rt, rt); - set_next_dst(ppc); + EMIT_SUBFE(rt, rt, rt); // rt = !carry ( = rs < immed ? 1 : 0 ) - GEN_NEG(ppc, rt, rt); - set_next_dst(ppc); + EMIT_NEG(rt, rt); return CONVERT_SUCCESS; #endif } static int ANDI(MIPS_instr mips){ - PowerPC_instr ppc; + int rs = mapRegister( MIPS_GET_RS(mips) ); int rt = mapRegisterNew( MIPS_GET_RT(mips) ); - GEN_ANDI(ppc, rt, rs, MIPS_GET_IMMED(mips)); - set_next_dst(ppc); + EMIT_ANDI(rt, rs, MIPS_GET_IMMED(mips)); return CONVERT_SUCCESS; } static int ORI(MIPS_instr mips){ - PowerPC_instr ppc; + RegMapping rs = mapRegister64( MIPS_GET_RS(mips) ); RegMapping rt = mapRegister64New( MIPS_GET_RT(mips) ); - GEN_OR(ppc, rt.hi, rs.hi, rs.hi); - set_next_dst(ppc); - GEN_ORI(ppc, rt.lo, rs.lo, MIPS_GET_IMMED(mips)); - set_next_dst(ppc); + EMIT_OR(rt.hi, rs.hi, rs.hi); + EMIT_ORI(rt.lo, rs.lo, MIPS_GET_IMMED(mips)); return CONVERT_SUCCESS; } static int XORI(MIPS_instr mips){ - PowerPC_instr ppc; + RegMapping rs = mapRegister64( MIPS_GET_RS(mips) ); RegMapping rt = mapRegister64New( MIPS_GET_RT(mips) ); - GEN_OR(ppc, rt.hi, rs.hi, rs.hi); - set_next_dst(ppc); - GEN_XORI(ppc, rt.lo, rs.lo, MIPS_GET_IMMED(mips)); - set_next_dst(ppc); + EMIT_OR(rt.hi, rs.hi, rs.hi); + EMIT_XORI(rt.lo, rs.lo, MIPS_GET_IMMED(mips)); return CONVERT_SUCCESS; } static int LUI(MIPS_instr mips){ - PowerPC_instr ppc; - GEN_LIS(ppc, + + EMIT_LIS( mapRegisterNew( MIPS_GET_RT(mips) ), MIPS_GET_IMMED(mips)); - set_next_dst(ppc); return CONVERT_SUCCESS; } static int BEQL(MIPS_instr mips){ - PowerPC_instr ppc; + if(CANT_COMPILE_DELAY()){ genCallInterp(mips); @@ -677,7 +617,7 @@ static int BEQL(MIPS_instr mips){ } static int BNEL(MIPS_instr mips){ - PowerPC_instr ppc; + if(CANT_COMPILE_DELAY()){ genCallInterp(mips); @@ -690,7 +630,7 @@ static int BNEL(MIPS_instr mips){ } static int BLEZL(MIPS_instr mips){ - PowerPC_instr ppc; + if(CANT_COMPILE_DELAY()){ genCallInterp(mips); @@ -703,7 +643,7 @@ static int BLEZL(MIPS_instr mips){ } static int BGTZL(MIPS_instr mips){ - PowerPC_instr ppc; + if(CANT_COMPILE_DELAY()){ genCallInterp(mips); @@ -716,7 +656,7 @@ static int BGTZL(MIPS_instr mips){ } static int DADDIU(MIPS_instr mips){ - PowerPC_instr ppc; + #if defined(INTERPRET_DW) || defined(INTERPRET_DADDIU) genCallInterp(mips); return INTERPRETED; @@ -726,14 +666,11 @@ static int DADDIU(MIPS_instr mips){ RegMapping rt = mapRegister64New( MIPS_GET_RT(mips) ); // Sign extend the immediate for the MSW - GEN_ADDI(ppc, 0, 0, (MIPS_GET_IMMED(mips)&0x8000) ? ~0 : 0); - set_next_dst(ppc); + EMIT_ADDI(0, 0, (MIPS_GET_IMMED(mips)&0x8000) ? ~0 : 0); // Add the immediate to the LSW - GEN_ADDIC(ppc, rt.lo, rs.lo, MIPS_GET_IMMED(mips)); - set_next_dst(ppc); + EMIT_ADDIC(rt.lo, rs.lo, MIPS_GET_IMMED(mips)); // Add the MSW with the sign-extension and the carry - GEN_ADDE(ppc, rt.hi, rs.hi, 0); - set_next_dst(ppc); + EMIT_ADDE(rt.hi, rs.hi, 0); return CONVERT_SUCCESS; #endif @@ -744,7 +681,7 @@ static int DADDI(MIPS_instr mips){ } static int LDL(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_LDL genCallInterp(mips); return INTERPRETED; @@ -755,7 +692,7 @@ static int LDL(MIPS_instr mips){ } static int LDR(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_LDR genCallInterp(mips); return INTERPRETED; @@ -766,148 +703,25 @@ static int LDR(MIPS_instr mips){ } static int LB(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_LB genCallInterp(mips); return INTERPRETED; -#else // INTERPRET_LB - - flushRegisters(); - reset_code_addr(); - - int rd = mapRegisterTemp(); // r3 = rd - int base = mapRegister( MIPS_GET_RS(mips) ); // r4 = addr - - invalidateRegisters(); - -#ifdef FASTMEM - // If base in physical memory -#ifdef USE_EXPANSION - GEN_LIS(ppc, 0, 0x8080); -#else - GEN_LIS(ppc, 0, 0x8040); -#endif - set_next_dst(ppc); - GEN_CMP(ppc, base, 0, 1); - set_next_dst(ppc); - GEN_BGE(ppc, 1, 9, 0, 0); - set_next_dst(ppc); - - // Use rdram -#ifdef USE_EXPANSION - // Mask sp with 0x007FFFFF - GEN_RLWINM(ppc, base, base, 0, 9, 31); - set_next_dst(ppc); -#else - // Mask sp with 0x003FFFFF - GEN_RLWINM(ppc, base, base, 0, 10, 31); - set_next_dst(ppc); -#endif - // Add rdram pointer - GEN_ADD(ppc, base, DYNAREG_RDRAM, base); - set_next_dst(ppc); - // Perform the actual load - GEN_LBZ(ppc, 3, MIPS_GET_IMMED(mips), base); - set_next_dst(ppc); - // extsb rt - GEN_EXTSB(ppc, 3, 3); - set_next_dst(ppc); - // Have the value in r3 stored to rt - mapRegisterNew( MIPS_GET_RT(mips) ); - flushRegisters(); - // Skip over else - int not_fastmem_id = add_jump_special(1); - GEN_B(ppc, not_fastmem_id, 0, 0); - set_next_dst(ppc); - PowerPC_instr* preCall = get_curr_dst(); -#endif // FASTMEM - - // load into rt - GEN_LI(ppc, 3, 0, MIPS_GET_RT(mips)); - set_next_dst(ppc); - - genCallDynaMem(MEM_LB, base, MIPS_GET_IMMED(mips)); - -#ifdef FASTMEM - int callSize = get_curr_dst() - preCall; - set_jump_special(not_fastmem_id, callSize+1); -#endif - - return CONVERT_SUCCESS; #endif + return genCallDynaMemVM(MIPS_GET_RS(mips),MIPS_GET_RT(mips),MEM_LB,MIPS_GET_IMMED(mips)); } static int LH(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_LH genCallInterp(mips); return INTERPRETED; -#else // INTERPRET_LH - - flushRegisters(); - reset_code_addr(); - - int rd = mapRegisterTemp(); // r3 = rd - int base = mapRegister( MIPS_GET_RS(mips) ); // r4 = addr - - invalidateRegisters(); - -#ifdef FASTMEM - // If base in physical memory -#ifdef USE_EXPANSION - GEN_LIS(ppc, 0, 0x8080); -#else - GEN_LIS(ppc, 0, 0x8040); -#endif - set_next_dst(ppc); - GEN_CMP(ppc, base, 0, 1); - set_next_dst(ppc); - GEN_BGE(ppc, 1, 8, 0, 0); - set_next_dst(ppc); - - // Use rdram -#ifdef USE_EXPANSION - // Mask sp with 0x007FFFFF - GEN_RLWINM(ppc, base, base, 0, 9, 31); - set_next_dst(ppc); -#else - // Mask sp with 0x003FFFFF - GEN_RLWINM(ppc, base, base, 0, 10, 31); - set_next_dst(ppc); -#endif - // Add rdram pointer - GEN_ADD(ppc, base, DYNAREG_RDRAM, base); - set_next_dst(ppc); - // Perform the actual load - GEN_LHA(ppc, 3, MIPS_GET_IMMED(mips), base); - set_next_dst(ppc); - // Have the value in r3 stored to rt - mapRegisterNew( MIPS_GET_RT(mips) ); - flushRegisters(); - // Skip over else - int not_fastmem_id = add_jump_special(1); - GEN_B(ppc, not_fastmem_id, 0, 0); - set_next_dst(ppc); - PowerPC_instr* preCall = get_curr_dst(); -#endif // FASTMEM - - // load into rt - GEN_LI(ppc, 3, 0, MIPS_GET_RT(mips)); - set_next_dst(ppc); - - genCallDynaMem(MEM_LH, base, MIPS_GET_IMMED(mips)); - -#ifdef FASTMEM - int callSize = get_curr_dst() - preCall; - set_jump_special(not_fastmem_id, callSize+1); -#endif - - return CONVERT_SUCCESS; #endif + return genCallDynaMemVM(MIPS_GET_RS(mips),MIPS_GET_RT(mips),MEM_LH,MIPS_GET_IMMED(mips)); } static int LWL(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_LWL genCallInterp(mips); return INTERPRETED; @@ -918,214 +732,34 @@ static int LWL(MIPS_instr mips){ } static int LW(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_LW genCallInterp(mips); return INTERPRETED; -#else // INTERPRET_LW - - flushRegisters(); - reset_code_addr(); - - int rd = mapRegisterTemp(); // r3 = rd - int base = mapRegister( MIPS_GET_RS(mips) ); // r4 = addr - - invalidateRegisters(); - -#ifdef FASTMEM - // If base in physical memory -#ifdef USE_EXPANSION - GEN_LIS(ppc, 0, 0x8080); -#else - GEN_LIS(ppc, 0, 0x8040); -#endif - set_next_dst(ppc); - GEN_CMP(ppc, base, 0, 1); - set_next_dst(ppc); - GEN_BGE(ppc, 1, 8, 0, 0); - set_next_dst(ppc); - - // Use rdram -#ifdef USE_EXPANSION - // Mask sp with 0x007FFFFF - GEN_RLWINM(ppc, base, base, 0, 9, 31); - set_next_dst(ppc); -#else - // Mask sp with 0x003FFFFF - GEN_RLWINM(ppc, base, base, 0, 10, 31); - set_next_dst(ppc); -#endif - // Add rdram pointer - GEN_ADD(ppc, base, DYNAREG_RDRAM, base); - set_next_dst(ppc); - // Perform the actual load - GEN_LWZ(ppc, 3, MIPS_GET_IMMED(mips), base); - set_next_dst(ppc); - // Have the value in r3 stored to rt - mapRegisterNew( MIPS_GET_RT(mips) ); - flushRegisters(); - // Skip over else - int not_fastmem_id = add_jump_special(1); - GEN_B(ppc, not_fastmem_id, 0, 0); - set_next_dst(ppc); - PowerPC_instr* preCall = get_curr_dst(); -#endif // FASTMEM - - // load into rt - GEN_LI(ppc, 3, 0, MIPS_GET_RT(mips)); - set_next_dst(ppc); - - genCallDynaMem(MEM_LW, base, MIPS_GET_IMMED(mips)); - -#ifdef FASTMEM - int callSize = get_curr_dst() - preCall; - set_jump_special(not_fastmem_id, callSize+1); -#endif - - return CONVERT_SUCCESS; #endif + return genCallDynaMemVM(MIPS_GET_RS(mips),MIPS_GET_RT(mips),MEM_LW,MIPS_GET_IMMED(mips)); } static int LBU(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_LBU genCallInterp(mips); return INTERPRETED; -#else // INTERPRET_LBU - - flushRegisters(); - reset_code_addr(); - - int rd = mapRegisterTemp(); // r3 = rd - int base = mapRegister( MIPS_GET_RS(mips) ); // r4 = addr - - invalidateRegisters(); - -#ifdef FASTMEM - // If base in physical memory -#ifdef USE_EXPANSION - GEN_LIS(ppc, 0, 0x8080); -#else - GEN_LIS(ppc, 0, 0x8040); -#endif - set_next_dst(ppc); - GEN_CMP(ppc, base, 0, 1); - set_next_dst(ppc); - GEN_BGE(ppc, 1, 8, 0, 0); - set_next_dst(ppc); - - // Use rdram -#ifdef USE_EXPANSION - // Mask sp with 0x007FFFFF - GEN_RLWINM(ppc, base, base, 0, 9, 31); - set_next_dst(ppc); -#else - // Mask sp with 0x003FFFFF - GEN_RLWINM(ppc, base, base, 0, 10, 31); - set_next_dst(ppc); -#endif - // Add rdram pointer - GEN_ADD(ppc, base, DYNAREG_RDRAM, base); - set_next_dst(ppc); - // Perform the actual load - GEN_LBZ(ppc, 3, MIPS_GET_IMMED(mips), base); - set_next_dst(ppc); - // Have the value in r3 stored to rt - mapRegisterNew( MIPS_GET_RT(mips) ); - flushRegisters(); - // Skip over else - int not_fastmem_id = add_jump_special(1); - GEN_B(ppc, not_fastmem_id, 0, 0); - set_next_dst(ppc); - PowerPC_instr* preCall = get_curr_dst(); -#endif // FASTMEM - - // load into rt - GEN_LI(ppc, 3, 0, MIPS_GET_RT(mips)); - set_next_dst(ppc); - - genCallDynaMem(MEM_LBU, base, MIPS_GET_IMMED(mips)); - -#ifdef FASTMEM - int callSize = get_curr_dst() - preCall; - set_jump_special(not_fastmem_id, callSize+1); -#endif - - return CONVERT_SUCCESS; #endif + return genCallDynaMemVM(MIPS_GET_RS(mips),MIPS_GET_RT(mips),MEM_LBU,MIPS_GET_IMMED(mips)); } static int LHU(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_LHU genCallInterp(mips); return INTERPRETED; -#else // INTERPRET_LHU - - flushRegisters(); - reset_code_addr(); - - int rd = mapRegisterTemp(); // r3 = rd - int base = mapRegister( MIPS_GET_RS(mips) ); // r4 = addr - - invalidateRegisters(); - -#ifdef FASTMEM - // If base in physical memory -#ifdef USE_EXPANSION - GEN_LIS(ppc, 0, 0x8080); -#else - GEN_LIS(ppc, 0, 0x8040); -#endif - set_next_dst(ppc); - GEN_CMP(ppc, base, 0, 1); - set_next_dst(ppc); - GEN_BGE(ppc, 1, 8, 0, 0); - set_next_dst(ppc); - - // Use rdram -#ifdef USE_EXPANSION - // Mask sp with 0x007FFFFF - GEN_RLWINM(ppc, base, base, 0, 9, 31); - set_next_dst(ppc); -#else - // Mask sp with 0x003FFFFF - GEN_RLWINM(ppc, base, base, 0, 10, 31); - set_next_dst(ppc); -#endif - // Add rdram pointer - GEN_ADD(ppc, base, DYNAREG_RDRAM, base); - set_next_dst(ppc); - // Perform the actual load - GEN_LHZ(ppc, 3, MIPS_GET_IMMED(mips), base); - set_next_dst(ppc); - // Have the value in r3 stored to rt - mapRegisterNew( MIPS_GET_RT(mips) ); - flushRegisters(); - // Skip over else - int not_fastmem_id = add_jump_special(1); - GEN_B(ppc, not_fastmem_id, 0, 0); - set_next_dst(ppc); - PowerPC_instr* preCall = get_curr_dst(); -#endif // FASTMEM - - // load into rt - GEN_LI(ppc, 3, 0, MIPS_GET_RT(mips)); - set_next_dst(ppc); - - genCallDynaMem(MEM_LHU, base, MIPS_GET_IMMED(mips)); - -#ifdef FASTMEM - int callSize = get_curr_dst() - preCall; - set_jump_special(not_fastmem_id, callSize+1); -#endif - - return CONVERT_SUCCESS; #endif + return genCallDynaMemVM(MIPS_GET_RS(mips),MIPS_GET_RT(mips),MEM_LHU,MIPS_GET_IMMED(mips)); } static int LWR(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_LWR genCallInterp(mips); return INTERPRETED; @@ -1136,80 +770,25 @@ static int LWR(MIPS_instr mips){ } static int LWU(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_LWU genCallInterp(mips); return INTERPRETED; -#else // INTERPRET_LWU - - flushRegisters(); - reset_code_addr(); - - int rd = mapRegisterTemp(); // r3 = rd - int base = mapRegister( MIPS_GET_RS(mips) ); // r4 = addr - - invalidateRegisters(); - -#ifdef FASTMEM - // If base in physical memory -#ifdef USE_EXPANSION - GEN_LIS(ppc, 0, 0x8080); -#else - GEN_LIS(ppc, 0, 0x8040); #endif - set_next_dst(ppc); - GEN_CMP(ppc, base, 0, 1); - set_next_dst(ppc); - GEN_BGE(ppc, 1, 8, 0, 0); - set_next_dst(ppc); - - // Use rdram -#ifdef USE_EXPANSION - // Mask sp with 0x007FFFFF - GEN_RLWINM(ppc, base, base, 0, 9, 31); - set_next_dst(ppc); -#else - // Mask sp with 0x003FFFFF - GEN_RLWINM(ppc, base, base, 0, 10, 31); - set_next_dst(ppc); -#endif - // Add rdram pointer - GEN_ADD(ppc, base, DYNAREG_RDRAM, base); - set_next_dst(ppc); - // Create a mapping for this value - RegMapping value = mapRegister64New( MIPS_GET_RT(mips) ); - // Perform the actual load - GEN_LWZ(ppc, value.lo, MIPS_GET_IMMED(mips), base); - set_next_dst(ppc); - // Zero out the upper word - GEN_LI(ppc, value.hi, 0, 0); - set_next_dst(ppc); - // Write the value out to reg - flushRegisters(); - // Skip over else - int not_fastmem_id = add_jump_special(1); - GEN_B(ppc, not_fastmem_id, 0, 0); - set_next_dst(ppc); - PowerPC_instr* preCall = get_curr_dst(); -#endif // FASTMEM - - // load into rt - GEN_LI(ppc, 3, 0, MIPS_GET_RT(mips)); - set_next_dst(ppc); - - genCallDynaMem(MEM_LWU, base, MIPS_GET_IMMED(mips)); + return genCallDynaMemVM(MIPS_GET_RS(mips),MIPS_GET_RT(mips),MEM_LWU,MIPS_GET_IMMED(mips)); +} -#ifdef FASTMEM - int callSize = get_curr_dst() - preCall; - set_jump_special(not_fastmem_id, callSize+1); -#endif +static int LD(MIPS_instr mips){ - return CONVERT_SUCCESS; +#ifdef INTERPRET_LD + genCallInterp(mips); + return INTERPRETED; #endif + return genCallDynaMemVM(MIPS_GET_RS(mips),MIPS_GET_RT(mips),MEM_LD,MIPS_GET_IMMED(mips)); } static int SB(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_SB genCallInterp(mips); return INTERPRETED; @@ -1222,8 +801,7 @@ static int SB(MIPS_instr mips){ mapRegister( MIPS_GET_RT(mips) ); // r3 = value } else { mapRegisterTemp(); - GEN_LI(ppc, 3, 0, 0); // r3 = 0 - set_next_dst(ppc); + EMIT_LI(3, 0); // r3 = 0 } int base = mapRegister( MIPS_GET_RS(mips) ); // r4 = addr @@ -1236,7 +814,7 @@ static int SB(MIPS_instr mips){ } static int SH(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_SH genCallInterp(mips); return INTERPRETED; @@ -1249,8 +827,7 @@ static int SH(MIPS_instr mips){ mapRegister( MIPS_GET_RT(mips) ); // r3 = value } else { mapRegisterTemp(); - GEN_LI(ppc, 3, 0, 0); // r3 = 0 - set_next_dst(ppc); + EMIT_LI(3, 0); // r3 = 0 } int base = mapRegister( MIPS_GET_RS(mips) ); // r4 = addr @@ -1263,7 +840,7 @@ static int SH(MIPS_instr mips){ } static int SWL(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_SWL genCallInterp(mips); return INTERPRETED; @@ -1274,7 +851,7 @@ static int SWL(MIPS_instr mips){ } static int SW(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_SW genCallInterp(mips); return INTERPRETED; @@ -1287,8 +864,7 @@ static int SW(MIPS_instr mips){ mapRegister( MIPS_GET_RT(mips) ); // r3 = value } else { mapRegisterTemp(); - GEN_LI(ppc, 3, 0, 0); // r3 = 0 - set_next_dst(ppc); + EMIT_LI(3, 0); // r3 = 0 } int base = mapRegister( MIPS_GET_RS(mips) ); // r4 = addr @@ -1301,7 +877,7 @@ static int SW(MIPS_instr mips){ } static int SDL(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_SDL genCallInterp(mips); return INTERPRETED; @@ -1312,7 +888,7 @@ static int SDL(MIPS_instr mips){ } static int SDR(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_SDR genCallInterp(mips); return INTERPRETED; @@ -1323,7 +899,7 @@ static int SDR(MIPS_instr mips){ } static int SWR(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_SWR genCallInterp(mips); return INTERPRETED; @@ -1333,80 +909,8 @@ static int SWR(MIPS_instr mips){ #endif } -static int LD(MIPS_instr mips){ - PowerPC_instr ppc; -#ifdef INTERPRET_LD - genCallInterp(mips); - return INTERPRETED; -#else // INTERPRET_LD - - flushRegisters(); - reset_code_addr(); - - int rd = mapRegisterTemp(); // r3 = rd - int base = mapRegister( MIPS_GET_RS(mips) ); // r4 = addr - - invalidateRegisters(); - -#ifdef FASTMEM - // If base in physical memory -#ifdef USE_EXPANSION - GEN_LIS(ppc, 0, 0x8080); -#else - GEN_LIS(ppc, 0, 0x8040); -#endif - set_next_dst(ppc); - GEN_CMP(ppc, base, 0, 1); - set_next_dst(ppc); - GEN_BGE(ppc, 1, 8, 0, 0); - set_next_dst(ppc); - - // Use rdram -#ifdef USE_EXPANSION - // Mask sp with 0x007FFFFF - GEN_RLWINM(ppc, base, base, 0, 9, 31); - set_next_dst(ppc); -#else - // Mask sp with 0x003FFFFF - GEN_RLWINM(ppc, base, base, 0, 10, 31); - set_next_dst(ppc); -#endif - // Add rdram pointer - GEN_ADD(ppc, base, DYNAREG_RDRAM, base); - set_next_dst(ppc); - // Create a mapping for this value - RegMapping value = mapRegister64New( MIPS_GET_RT(mips) ); - // Perform the actual load - GEN_LWZ(ppc, value.lo, MIPS_GET_IMMED(mips)+4, base); - set_next_dst(ppc); - GEN_LWZ(ppc, value.hi, MIPS_GET_IMMED(mips), base); - set_next_dst(ppc); - // Write the value out to reg - flushRegisters(); - // Skip over else - int not_fastmem_id = add_jump_special(1); - GEN_B(ppc, not_fastmem_id, 0, 0); - set_next_dst(ppc); - PowerPC_instr* preCall = get_curr_dst(); -#endif // FASTMEM - - // load into rt - GEN_LI(ppc, 3, 0, MIPS_GET_RT(mips)); - set_next_dst(ppc); - - genCallDynaMem(MEM_LD, base, MIPS_GET_IMMED(mips)); - -#ifdef FASTMEM - int callSize = get_curr_dst() - preCall; - set_jump_special(not_fastmem_id, callSize+1); -#endif - - return CONVERT_SUCCESS; -#endif -} - static int SD(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_SD genCallInterp(mips); return INTERPRETED; @@ -1421,8 +925,7 @@ static int SD(MIPS_instr mips){ invalidateRegisters(); // store from rt - GEN_LI(ppc, 3, 0, MIPS_GET_RT(mips)); - set_next_dst(ppc); + EMIT_LI(3, MIPS_GET_RT(mips)); genCallDynaMem(MEM_SD, base, MIPS_GET_IMMED(mips)); @@ -1430,8 +933,10 @@ static int SD(MIPS_instr mips){ #endif } +extern long long int reg_cop1_fgr_64[32]; + static int LWC1(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_LWC1 genCallInterp(mips); return INTERPRETED; @@ -1451,48 +956,44 @@ static int LWC1(MIPS_instr mips){ #ifdef FASTMEM // If base in physical memory #ifdef USE_EXPANSION - GEN_LIS(ppc, 0, 0x8080); + EMIT_LIS(0, 0x8080); #else - GEN_LIS(ppc, 0, 0x8040); + EMIT_LIS(0, 0x8040); #endif - set_next_dst(ppc); - GEN_CMP(ppc, base, 0, 1); - set_next_dst(ppc); - GEN_BGE(ppc, 1, 7, 0, 0); - set_next_dst(ppc); + EMIT_CMP(base, 0, 1); + EMIT_BGE(1, 7, 0, 0); // Use rdram #ifdef USE_EXPANSION // Mask sp with 0x007FFFFF - GEN_RLWINM(ppc, base, base, 0, 9, 31); - set_next_dst(ppc); + EMIT_RLWINM(base, base, 0, 9, 31); #else // Mask sp with 0x003FFFFF - GEN_RLWINM(ppc, base, base, 0, 10, 31); - set_next_dst(ppc); + EMIT_RLWINM(base, base, 0, 10, 31); #endif // Add rdram pointer - GEN_ADD(ppc, base, DYNAREG_RDRAM, base); - set_next_dst(ppc); + EMIT_ADD(base, DYNAREG_RDRAM, base); // Perform the actual load - GEN_LWZ(ppc, 3, MIPS_GET_IMMED(mips), base); - set_next_dst(ppc); + EMIT_LWZ(3, MIPS_GET_IMMED(mips), base); +#if 1 // addr = reg_cop1_simple[frt] - GEN_LWZ(ppc, addr, MIPS_GET_RT(mips)*4, DYNAREG_FPR_32); - set_next_dst(ppc); + EMIT_LWZ(addr, MIPS_GET_RT(mips)*4, DYNAREG_FPR_32); + // *addr = frs + EMIT_STW(3, 0, addr); +#else + unsigned int copregaddr=((unsigned int)reg_cop1_fgr_64)+(MIPS_GET_RT(mips)>>1)*8+4-(MIPS_GET_RT(mips)&1); + EMIT_LIS(addr,HA(copregaddr)); // *addr = frs - GEN_STW(ppc, 3, 0, addr); - set_next_dst(ppc); + EMIT_STW(3, copregaddr , addr); +#endif // Skip over else int not_fastmem_id = add_jump_special(1); - GEN_B(ppc, not_fastmem_id, 0, 0); - set_next_dst(ppc); + EMIT_B(not_fastmem_id, 0, 0); PowerPC_instr* preCall = get_curr_dst(); #endif // FASTMEM // load into frt - GEN_LI(ppc, 3, 0, MIPS_GET_RT(mips)); - set_next_dst(ppc); + EMIT_LI(3, MIPS_GET_RT(mips)); genCallDynaMem(MEM_LWC1, base, MIPS_GET_IMMED(mips)); @@ -1506,7 +1007,7 @@ static int LWC1(MIPS_instr mips){ } static int LDC1(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_LDC1 genCallInterp(mips); return INTERPRETED; @@ -1526,52 +1027,39 @@ static int LDC1(MIPS_instr mips){ #ifdef FASTMEM // If base in physical memory #ifdef USE_EXPANSION - GEN_LIS(ppc, 0, 0x8080); + EMIT_LIS(0, 0x8080); #else - GEN_LIS(ppc, 0, 0x8040); + EMIT_LIS(0, 0x8040); #endif - set_next_dst(ppc); - GEN_CMP(ppc, base, 0, 1); - set_next_dst(ppc); - GEN_BGE(ppc, 1, 9, 0, 0); - set_next_dst(ppc); + EMIT_CMP(base, 0, 1); + EMIT_BGE(1, 9, 0, 0); // Use rdram #ifdef USE_EXPANSION // Mask sp with 0x007FFFFF - GEN_RLWINM(ppc, base, base, 0, 9, 31); - set_next_dst(ppc); + EMIT_RLWINM(base, base, 0, 9, 31); #else // Mask sp with 0x003FFFFF - GEN_RLWINM(ppc, base, base, 0, 10, 31); - set_next_dst(ppc); + EMIT_RLWINM(base, base, 0, 10, 31); #endif // Add rdram pointer - GEN_ADD(ppc, base, DYNAREG_RDRAM, base); - set_next_dst(ppc); + EMIT_ADD(base, DYNAREG_RDRAM, base); // Perform the actual load - GEN_LWZ(ppc, 3, MIPS_GET_IMMED(mips), base); - set_next_dst(ppc); - GEN_LWZ(ppc, 6, MIPS_GET_IMMED(mips)+4, base); - set_next_dst(ppc); + EMIT_LWZ(3, MIPS_GET_IMMED(mips), base); + EMIT_LWZ(6, MIPS_GET_IMMED(mips)+4, base); // addr = reg_cop1_double[frt] - GEN_LWZ(ppc, addr, MIPS_GET_RT(mips)*4, DYNAREG_FPR_64); - set_next_dst(ppc); + EMIT_LWZ(addr, MIPS_GET_RT(mips)*4, DYNAREG_FPR_64); // *addr = frs - GEN_STW(ppc, 3, 0, addr); - set_next_dst(ppc); - GEN_STW(ppc, 6, 4, addr); - set_next_dst(ppc); + EMIT_STW(3, 0, addr); + EMIT_STW(6, 4, addr); // Skip over else int not_fastmem_id = add_jump_special(1); - GEN_B(ppc, not_fastmem_id, 0, 0); - set_next_dst(ppc); + EMIT_B(not_fastmem_id, 0, 0); PowerPC_instr* preCall = get_curr_dst(); #endif // FASTMEM // load into frt - GEN_LI(ppc, 3, 0, MIPS_GET_RT(mips)); - set_next_dst(ppc); + EMIT_LI(3, MIPS_GET_RT(mips)); genCallDynaMem(MEM_LDC1, base, MIPS_GET_IMMED(mips)); @@ -1585,7 +1073,7 @@ static int LDC1(MIPS_instr mips){ } static int SWC1(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_SWC1 genCallInterp(mips); return INTERPRETED; @@ -1602,17 +1090,16 @@ static int SWC1(MIPS_instr mips){ invalidateRegisters(); // store from rt - GEN_LI(ppc, 3, 0, MIPS_GET_RT(mips)); - set_next_dst(ppc); - + EMIT_LI(3, MIPS_GET_RT(mips)); + genCallDynaMem(MEM_SWC1, base, MIPS_GET_IMMED(mips)); - + return CONVERT_SUCCESS; #endif } static int SDC1(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_SDC1 genCallInterp(mips); return INTERPRETED; @@ -1629,8 +1116,7 @@ static int SDC1(MIPS_instr mips){ invalidateRegisters(); // store from rt - GEN_LI(ppc, 3, 0, MIPS_GET_RT(mips)); - set_next_dst(ppc); + EMIT_LI(3, MIPS_GET_RT(mips)); genCallDynaMem(MEM_SDC1, base, MIPS_GET_IMMED(mips)); @@ -1643,7 +1129,7 @@ static int CACHE(MIPS_instr mips){ } static int LL(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_LL genCallInterp(mips); return INTERPRETED; @@ -1654,7 +1140,7 @@ static int LL(MIPS_instr mips){ } static int SC(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_SC genCallInterp(mips); return INTERPRETED; @@ -1667,82 +1153,73 @@ static int SC(MIPS_instr mips){ // -- Special Functions -- static int SLL(MIPS_instr mips){ - PowerPC_instr ppc; + int rt = mapRegister( MIPS_GET_RT(mips) ); int rd = mapRegisterNew( MIPS_GET_RD(mips) ); - GEN_SLWI(ppc, rd, rt, MIPS_GET_SA(mips)); - set_next_dst(ppc); + EMIT_SLWI(rd, rt, MIPS_GET_SA(mips)); return CONVERT_SUCCESS; } static int SRL(MIPS_instr mips){ - PowerPC_instr ppc; + int rt = mapRegister( MIPS_GET_RT(mips) ); int rd = mapRegisterNew( MIPS_GET_RD(mips) ); - GEN_SRWI(ppc, rd, rt, MIPS_GET_SA(mips)); - set_next_dst(ppc); + EMIT_SRWI(rd, rt, MIPS_GET_SA(mips)); return CONVERT_SUCCESS; } static int SRA(MIPS_instr mips){ - PowerPC_instr ppc; + int rt = mapRegister( MIPS_GET_RT(mips) ); int rd = mapRegisterNew( MIPS_GET_RD(mips) ); - GEN_SRAWI(ppc, rd, rt, MIPS_GET_SA(mips)); - set_next_dst(ppc); + EMIT_SRAWI(rd, rt, MIPS_GET_SA(mips)); return CONVERT_SUCCESS; } static int SLLV(MIPS_instr mips){ - PowerPC_instr ppc; + int rt = mapRegister( MIPS_GET_RT(mips) ); int rs = mapRegister( MIPS_GET_RS(mips) ); int rd = mapRegisterNew( MIPS_GET_RD(mips) ); - GEN_RLWINM(ppc, 0, rs, 0, 27, 31); // Mask the lower 5-bits of rs - set_next_dst(ppc); - GEN_SLW(ppc, rd, rt, 0); - set_next_dst(ppc); + EMIT_RLWINM(0, rs, 0, 27, 31); // Mask the lower 5-bits of rs + EMIT_SLW(rd, rt, 0); return CONVERT_SUCCESS; } static int SRLV(MIPS_instr mips){ - PowerPC_instr ppc; + int rt = mapRegister( MIPS_GET_RT(mips) ); int rs = mapRegister( MIPS_GET_RS(mips) ); int rd = mapRegisterNew( MIPS_GET_RD(mips) ); - GEN_RLWINM(ppc, 0, rs, 0, 27, 31); // Mask the lower 5-bits of rs - set_next_dst(ppc); - GEN_SRW(ppc, rd, rt, 0); - set_next_dst(ppc); + EMIT_RLWINM(0, rs, 0, 27, 31); // Mask the lower 5-bits of rs + EMIT_SRW(rd, rt, 0); return CONVERT_SUCCESS; } static int SRAV(MIPS_instr mips){ - PowerPC_instr ppc; + int rt = mapRegister( MIPS_GET_RT(mips) ); int rs = mapRegister( MIPS_GET_RS(mips) ); int rd = mapRegisterNew( MIPS_GET_RD(mips) ); - GEN_RLWINM(ppc, 0, rs, 0, 27, 31); // Mask the lower 5-bits of rs - set_next_dst(ppc); - GEN_SRAW(ppc, rd, rt, 0); - set_next_dst(ppc); + EMIT_RLWINM(0, rs, 0, 27, 31); // Mask the lower 5-bits of rs + EMIT_SRAW(rd, rt, 0); return CONVERT_SUCCESS; } static int JR(MIPS_instr mips){ - PowerPC_instr ppc; + if(CANT_COMPILE_DELAY()){ genCallInterp(mips); @@ -1758,8 +1235,7 @@ static int JR(MIPS_instr mips){ int delaySlot = get_curr_dst() - preDelay; #ifdef COMPARE_CORE - GEN_LI(ppc, 4, 0, 1); - set_next_dst(ppc); + EMIT_LI(4, 1); #endif genUpdateCount(0); @@ -1781,7 +1257,7 @@ static int JR(MIPS_instr mips){ } static int JALR(MIPS_instr mips){ - PowerPC_instr ppc; + if(CANT_COMPILE_DELAY()){ genCallInterp(mips); @@ -1797,19 +1273,16 @@ static int JALR(MIPS_instr mips){ int delaySlot = get_curr_dst() - preDelay; #ifdef COMPARE_CORE - GEN_LI(ppc, 4, 0, 1); - set_next_dst(ppc); + EMIT_LI(4, 1); #endif genUpdateCount(0); // Set LR to next instruction int rd = mapRegisterNew(MIPS_GET_RD(mips)); // lis lr, pc@ha(0) - GEN_LIS(ppc, rd, (get_src_pc()+4)>>16); - set_next_dst(ppc); + EMIT_LIS(rd, (get_src_pc()+4)>>16); // la lr, pc@l(lr) - GEN_ORI(ppc, rd, rd, get_src_pc()+4); - set_next_dst(ppc); + EMIT_ORI(rd, rd, get_src_pc()+4); flushRegisters(); @@ -1831,7 +1304,7 @@ static int JALR(MIPS_instr mips){ } static int SYSCALL(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_SYSCALL genCallInterp(mips); return INTERPRETED; @@ -1842,7 +1315,7 @@ static int SYSCALL(MIPS_instr mips){ } static int BREAK(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_BREAK genCallInterp(mips); return INTERPRETED; @@ -1852,7 +1325,7 @@ static int BREAK(MIPS_instr mips){ } static int SYNC(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_SYNC genCallInterp(mips); return INTERPRETED; @@ -1862,7 +1335,7 @@ static int SYNC(MIPS_instr mips){ } static int MFHI(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_HILO genCallInterp(mips); return INTERPRETED; @@ -1872,17 +1345,15 @@ static int MFHI(MIPS_instr mips){ RegMapping rd = mapRegister64New( MIPS_GET_RD(mips) ); // mr rd, hi - GEN_OR(ppc, rd.lo, hi.lo, hi.lo); - set_next_dst(ppc); - GEN_OR(ppc, rd.hi, hi.hi, hi.hi); - set_next_dst(ppc); + EMIT_OR(rd.lo, hi.lo, hi.lo); + EMIT_OR(rd.hi, hi.hi, hi.hi); return CONVERT_SUCCESS; #endif } static int MTHI(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_HILO genCallInterp(mips); return INTERPRETED; @@ -1892,17 +1363,15 @@ static int MTHI(MIPS_instr mips){ RegMapping hi = mapRegister64New( MIPS_REG_HI ); // mr hi, rs - GEN_OR(ppc, hi.lo, rs.lo, rs.lo); - set_next_dst(ppc); - GEN_OR(ppc, hi.hi, rs.hi, rs.hi); - set_next_dst(ppc); + EMIT_OR(hi.lo, rs.lo, rs.lo); + EMIT_OR(hi.hi, rs.hi, rs.hi); return CONVERT_SUCCESS; #endif } static int MFLO(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_HILO genCallInterp(mips); return INTERPRETED; @@ -1912,17 +1381,15 @@ static int MFLO(MIPS_instr mips){ RegMapping rd = mapRegister64New( MIPS_GET_RD(mips) ); // mr rd, lo - GEN_OR(ppc, rd.lo, lo.lo, lo.lo); - set_next_dst(ppc); - GEN_OR(ppc, rd.hi, lo.hi, lo.hi); - set_next_dst(ppc); + EMIT_OR(rd.lo, lo.lo, lo.lo); + EMIT_OR(rd.hi, lo.hi, lo.hi); return CONVERT_SUCCESS; #endif } static int MTLO(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_HILO genCallInterp(mips); return INTERPRETED; @@ -1932,17 +1399,15 @@ static int MTLO(MIPS_instr mips){ RegMapping lo = mapRegister64New( MIPS_REG_LO ); // mr lo, rs - GEN_OR(ppc, lo.lo, rs.lo, rs.lo); - set_next_dst(ppc); - GEN_OR(ppc, lo.hi, rs.hi, rs.hi); - set_next_dst(ppc); + EMIT_OR(lo.lo, rs.lo, rs.lo); + EMIT_OR(lo.hi, rs.hi, rs.hi); return CONVERT_SUCCESS; #endif } static int MULT(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_MULT genCallInterp(mips); return INTERPRETED; @@ -1955,18 +1420,14 @@ static int MULT(MIPS_instr mips){ // Don't multiply if they're using r0 if(MIPS_GET_RS(mips) && MIPS_GET_RT(mips)){ // mullw lo, rs, rt - GEN_MULLW(ppc, lo, rs, rt); - set_next_dst(ppc); + EMIT_MULLW(lo, rs, rt); // mulhw hi, rs, rt - GEN_MULHW(ppc, hi, rs, rt); - set_next_dst(ppc); + EMIT_MULHW(hi, rs, rt); } else { // li lo, 0 - GEN_LI(ppc, lo, 0, 0); - set_next_dst(ppc); + EMIT_LI(lo, 0); // li hi, 0 - GEN_LI(ppc, hi, 0, 0); - set_next_dst(ppc); + EMIT_LI(hi, 0); } return CONVERT_SUCCESS; @@ -1974,7 +1435,7 @@ static int MULT(MIPS_instr mips){ } static int MULTU(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_MULTU genCallInterp(mips); return INTERPRETED; @@ -1987,18 +1448,14 @@ static int MULTU(MIPS_instr mips){ // Don't multiply if they're using r0 if(MIPS_GET_RS(mips) && MIPS_GET_RT(mips)){ // mullw lo, rs, rt - GEN_MULLW(ppc, lo, rs, rt); - set_next_dst(ppc); + EMIT_MULLW(lo, rs, rt); // mulhwu hi, rs, rt - GEN_MULHWU(ppc, hi, rs, rt); - set_next_dst(ppc); + EMIT_MULHWU(hi, rs, rt); } else { // li lo, 0 - GEN_LI(ppc, lo, 0, 0); - set_next_dst(ppc); + EMIT_LI(lo, 0); // li hi, 0 - GEN_LI(ppc, hi, 0, 0); - set_next_dst(ppc); + EMIT_LI(hi, 0); } return CONVERT_SUCCESS; @@ -2006,7 +1463,7 @@ static int MULTU(MIPS_instr mips){ } static int DIV(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_DIV genCallInterp(mips); return INTERPRETED; @@ -2021,17 +1478,14 @@ static int DIV(MIPS_instr mips){ // Don't divide if they're using r0 if(MIPS_GET_RS(mips) && MIPS_GET_RT(mips)){ // divw lo, rs, rt - GEN_DIVW(ppc, lo, rs, rt); - set_next_dst(ppc); + EMIT_DIVW(lo, rs, rt); // This is how you perform a mod in PPC // divw lo, rs, rt // NOTE: We already did that // mullw hi, lo, rt - GEN_MULLW(ppc, hi, lo, rt); - set_next_dst(ppc); + EMIT_MULLW(hi, lo, rt); // subf hi, hi, rs - GEN_SUBF(ppc, hi, hi, rs); - set_next_dst(ppc); + EMIT_SUBF(hi, hi, rs); } return CONVERT_SUCCESS; @@ -2039,7 +1493,7 @@ static int DIV(MIPS_instr mips){ } static int DIVU(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_DIVU genCallInterp(mips); return INTERPRETED; @@ -2054,17 +1508,14 @@ static int DIVU(MIPS_instr mips){ // Don't divide if they're using r0 if(MIPS_GET_RS(mips) && MIPS_GET_RT(mips)){ // divwu lo, rs, rt - GEN_DIVWU(ppc, lo, rs, rt); - set_next_dst(ppc); + EMIT_DIVWU(lo, rs, rt); // This is how you perform a mod in PPC // divw lo, rs, rt // NOTE: We already did that // mullw hi, lo, rt - GEN_MULLW(ppc, hi, lo, rt); - set_next_dst(ppc); + EMIT_MULLW(hi, lo, rt); // subf hi, hi, rs - GEN_SUBF(ppc, hi, hi, rs); - set_next_dst(ppc); + EMIT_SUBF(hi, hi, rs); } return CONVERT_SUCCESS; @@ -2072,7 +1523,7 @@ static int DIVU(MIPS_instr mips){ } static int DSLLV(MIPS_instr mips){ - PowerPC_instr ppc; + #if defined(INTERPRET_DW) || defined(INTERPRET_DSLLV) genCallInterp(mips); return INTERPRETED; @@ -2084,32 +1535,23 @@ static int DSLLV(MIPS_instr mips){ RegMapping rd = mapRegister64New( MIPS_GET_RD(mips) ); // Mask off the shift amount (0x3f) - GEN_RLWINM(ppc, sa, rs, 0, 26, 31); - set_next_dst(ppc); + EMIT_RLWINM(sa, rs, 0, 26, 31); // Shift the MSW - GEN_SLW(ppc, rd.hi, rt.hi, sa); - set_next_dst(ppc); + EMIT_SLW(rd.hi, rt.hi, sa); // Calculate 32-sh - GEN_SUBFIC(ppc, 0, sa, 32); - set_next_dst(ppc); + EMIT_SUBFIC(0, sa, 32); // Extract the bits that will be shifted out the LSW (sh < 32) - GEN_SRW(ppc, 0, rt.lo, 0); - set_next_dst(ppc); + EMIT_SRW(0, rt.lo, 0); // Insert the bits into the MSW - GEN_OR(ppc, rd.hi, rd.hi, 0); - set_next_dst(ppc); + EMIT_OR(rd.hi, rd.hi, 0); // Calculate sh-32 - GEN_ADDI(ppc, 0, sa, -32); - set_next_dst(ppc); + EMIT_ADDI(0, sa, -32); // Extract the bits that will be shifted out the LSW (sh > 31) - GEN_SLW(ppc, 0, rt.lo, 0); - set_next_dst(ppc); + EMIT_SLW(0, rt.lo, 0); // Insert the bits into the MSW - GEN_OR(ppc, rd.hi, rd.hi, 0); - set_next_dst(ppc); + EMIT_OR(rd.hi, rd.hi, 0); // Shift the LSW - GEN_SLW(ppc, rd.lo, rt.lo, sa); - set_next_dst(ppc); + EMIT_SLW(rd.lo, rt.lo, sa); unmapRegisterTemp(sa); @@ -2118,7 +1560,7 @@ static int DSLLV(MIPS_instr mips){ } static int DSRLV(MIPS_instr mips){ - PowerPC_instr ppc; + #if defined(INTERPRET_DW) || defined(INTERPRET_DSRLV) genCallInterp(mips); return INTERPRETED; @@ -2130,32 +1572,23 @@ static int DSRLV(MIPS_instr mips){ RegMapping rd = mapRegister64New( MIPS_GET_RD(mips) ); // Mask off the shift amount (0x3f) - GEN_RLWINM(ppc, sa, rs, 0, 26, 31); - set_next_dst(ppc); + EMIT_RLWINM(sa, rs, 0, 26, 31); // Shift the LSW - GEN_SRW(ppc, rd.lo, rt.lo, sa); - set_next_dst(ppc); + EMIT_SRW(rd.lo, rt.lo, sa); // Calculate 32-sh - GEN_SUBFIC(ppc, 0, sa, 32); - set_next_dst(ppc); + EMIT_SUBFIC(0, sa, 32); // Extract the bits that will be shifted out the MSW (sh < 32) - GEN_SLW(ppc, 0, rt.hi, 0); - set_next_dst(ppc); + EMIT_SLW(0, rt.hi, 0); // Insert the bits into the LSW - GEN_OR(ppc, rd.lo, rd.lo, 0); - set_next_dst(ppc); + EMIT_OR(rd.lo, rd.lo, 0); // Calculate sh-32 - GEN_ADDI(ppc, 0, sa, -32); - set_next_dst(ppc); + EMIT_ADDI(0, sa, -32); // Extract the bits that will be shifted out the MSW (sh > 31) - GEN_SRW(ppc, 0, rt.hi, 0); - set_next_dst(ppc); + EMIT_SRW(0, rt.hi, 0); // Insert the bits into the LSW - GEN_OR(ppc, rd.lo, rd.lo, 0); - set_next_dst(ppc); + EMIT_OR(rd.lo, rd.lo, 0); // Shift the MSW - GEN_SRW(ppc, rd.hi, rt.hi, sa); - set_next_dst(ppc); + EMIT_SRW(rd.hi, rt.hi, sa); unmapRegisterTemp(sa); @@ -2164,7 +1597,7 @@ static int DSRLV(MIPS_instr mips){ } static int DSRAV(MIPS_instr mips){ - PowerPC_instr ppc; + #if defined(INTERPRET_DW) || defined(INTERPRET_DSRAV) genCallInterp(mips); return INTERPRETED; @@ -2176,41 +1609,29 @@ static int DSRAV(MIPS_instr mips){ RegMapping rd = mapRegister64New( MIPS_GET_RD(mips) ); // Mask off the shift amount (0x3f) - GEN_RLWINM(ppc, sa, rs, 0, 26, 31); - set_next_dst(ppc); + EMIT_RLWINM(sa, rs, 0, 26, 31); // Check whether the shift amount is < 32 - GEN_CMPI(ppc, sa, 32, 1); - set_next_dst(ppc); + EMIT_CMPI(sa, 32, 1); // Shift the LSW - GEN_SRW(ppc, rd.lo, rt.lo, sa); - set_next_dst(ppc); + EMIT_SRW(rd.lo, rt.lo, sa); // Skip over this code if sh >= 32 - GEN_BGE(ppc, 1, 5, 0, 0); - set_next_dst(ppc); + EMIT_BGE(1, 5, 0, 0); // Calculate 32-sh - GEN_SUBFIC(ppc, 0, sa, 32); - set_next_dst(ppc); + EMIT_SUBFIC(0, sa, 32); // Extract the bits that will be shifted out the MSW (sh < 32) - GEN_SLW(ppc, 0, rt.hi, 0); - set_next_dst(ppc); + EMIT_SLW(0, rt.hi, 0); // Insert the bits into the LSW - GEN_OR(ppc, rd.lo, rd.lo, 0); - set_next_dst(ppc); + EMIT_OR(rd.lo, rd.lo, 0); // Skip over the else - GEN_B(ppc, 4, 0, 0); - set_next_dst(ppc); + EMIT_B(4, 0, 0); // Calculate sh-32 - GEN_ADDI(ppc, 0, sa, -32); - set_next_dst(ppc); + EMIT_ADDI(0, sa, -32); // Extract the bits that will be shifted out the MSW (sh > 31) - GEN_SRAW(ppc, 0, rt.hi, 0); - set_next_dst(ppc); + EMIT_SRAW(0, rt.hi, 0); // Insert the bits into the LSW - GEN_OR(ppc, rd.lo, rd.lo, 0); - set_next_dst(ppc); + EMIT_OR(rd.lo, rd.lo, 0); // Shift the MSW - GEN_SRAW(ppc, rd.hi, rt.hi, sa); - set_next_dst(ppc); + EMIT_SRAW(rd.hi, rt.hi, sa); unmapRegisterTemp(sa); @@ -2219,7 +1640,7 @@ static int DSRAV(MIPS_instr mips){ } static int DMULT(MIPS_instr mips){ - PowerPC_instr ppc; + #if defined(INTERPRET_DW) || defined(INTERPRET_DMULT) genCallInterp(mips); return INTERPRETED; @@ -2230,7 +1651,7 @@ static int DMULT(MIPS_instr mips){ } static int DMULTU(MIPS_instr mips){ - PowerPC_instr ppc; + #if defined(INTERPRET_DW) || defined(INTERPRET_DMULTU) genCallInterp(mips); return INTERPRETED; @@ -2241,7 +1662,7 @@ static int DMULTU(MIPS_instr mips){ } static int DDIV(MIPS_instr mips){ - PowerPC_instr ppc; + #if defined(INTERPRET_DW) || defined(INTERPRET_DDIV) genCallInterp(mips); return INTERPRETED; @@ -2252,7 +1673,7 @@ static int DDIV(MIPS_instr mips){ } static int DDIVU(MIPS_instr mips){ - PowerPC_instr ppc; + #if defined(INTERPRET_DW) || defined(INTERPRET_DDIVU) genCallInterp(mips); return INTERPRETED; @@ -2263,7 +1684,7 @@ static int DDIVU(MIPS_instr mips){ } static int DADDU(MIPS_instr mips){ - PowerPC_instr ppc; + #if defined(INTERPRET_DW) || defined(INTERPRET_DADDU) genCallInterp(mips); return INTERPRETED; @@ -2273,10 +1694,8 @@ static int DADDU(MIPS_instr mips){ RegMapping rt = mapRegister64( MIPS_GET_RT(mips) ); RegMapping rd = mapRegister64New( MIPS_GET_RD(mips) ); - GEN_ADDC(ppc, rd.lo, rs.lo, rt.lo); - set_next_dst(ppc); - GEN_ADDE(ppc, rd.hi, rs.hi, rt.hi); - set_next_dst(ppc); + EMIT_ADDC(rd.lo, rs.lo, rt.lo); + EMIT_ADDE(rd.hi, rs.hi, rt.hi); return CONVERT_SUCCESS; #endif @@ -2287,7 +1706,7 @@ static int DADD(MIPS_instr mips){ } static int DSUBU(MIPS_instr mips){ - PowerPC_instr ppc; + #if defined(INTERPRET_DW) || defined(INTERPRET_DSUBU) genCallInterp(mips); return INTERPRETED; @@ -2297,10 +1716,8 @@ static int DSUBU(MIPS_instr mips){ RegMapping rt = mapRegister64( MIPS_GET_RT(mips) ); RegMapping rd = mapRegister64New( MIPS_GET_RD(mips) ); - GEN_SUBFC(ppc, rd.lo, rt.lo, rs.lo); - set_next_dst(ppc); - GEN_SUBFE(ppc, rd.hi, rt.hi, rs.hi); - set_next_dst(ppc); + EMIT_SUBFC(rd.lo, rt.lo, rs.lo); + EMIT_SUBFE(rd.hi, rt.hi, rs.hi); return CONVERT_SUCCESS; #endif @@ -2311,7 +1728,7 @@ static int DSUB(MIPS_instr mips){ } static int DSLL(MIPS_instr mips){ - PowerPC_instr ppc; + #if defined(INTERPRET_DW) || defined(INTERPRET_DSLL) genCallInterp(mips); return INTERPRETED; @@ -2323,23 +1740,17 @@ static int DSLL(MIPS_instr mips){ if(sa){ // Shift MSW left by SA - GEN_SLWI(ppc, rd.hi, rt.hi, sa); - set_next_dst(ppc); + EMIT_SLWI(rd.hi, rt.hi, sa); // Extract the bits shifted out of the LSW - GEN_RLWINM(ppc, 0, rt.lo, sa, 32-sa, 31); - set_next_dst(ppc); + EMIT_RLWINM(0, rt.lo, sa, 32-sa, 31); // Insert those bits into the MSW - GEN_OR(ppc, rd.hi, rd.hi, 0); - set_next_dst(ppc); + EMIT_OR(rd.hi, rd.hi, 0); // Shift LSW left by SA - GEN_SLWI(ppc, rd.lo, rt.lo, sa); - set_next_dst(ppc); + EMIT_SLWI(rd.lo, rt.lo, sa); } else { // Copy over the register - GEN_ADDI(ppc, rd.hi, rt.hi, 0); - set_next_dst(ppc); - GEN_ADDI(ppc, rd.lo, rt.lo, 0); - set_next_dst(ppc); + EMIT_ADDI(rd.hi, rt.hi, 0); + EMIT_ADDI(rd.lo, rt.lo, 0); } return CONVERT_SUCCESS; @@ -2347,7 +1758,7 @@ static int DSLL(MIPS_instr mips){ } static int DSRL(MIPS_instr mips){ - PowerPC_instr ppc; + #if defined(INTERPRET_DW) || defined(INTERPRET_DSRL) genCallInterp(mips); return INTERPRETED; @@ -2359,23 +1770,17 @@ static int DSRL(MIPS_instr mips){ if(sa){ // Shift LSW right by SA - GEN_SRWI(ppc, rd.lo, rt.lo, sa); - set_next_dst(ppc); + EMIT_SRWI(rd.lo, rt.lo, sa); // Extract the bits shifted out of the MSW - GEN_RLWINM(ppc, 0, rt.hi, 32-sa, 0, sa-1); - set_next_dst(ppc); + EMIT_RLWINM(0, rt.hi, 32-sa, 0, sa-1); // Insert those bits into the LSW - GEN_OR(ppc, rd.lo, rd.lo, 0); - set_next_dst(ppc); + EMIT_OR(rd.lo, rd.lo, 0); // Shift MSW right by SA - GEN_SRWI(ppc, rd.hi, rt.hi, sa); - set_next_dst(ppc); + EMIT_SRWI(rd.hi, rt.hi, sa); } else { // Copy over the register - GEN_ADDI(ppc, rd.hi, rt.hi, 0); - set_next_dst(ppc); - GEN_ADDI(ppc, rd.lo, rt.lo, 0); - set_next_dst(ppc); + EMIT_ADDI(rd.hi, rt.hi, 0); + EMIT_ADDI(rd.lo, rt.lo, 0); } return CONVERT_SUCCESS; @@ -2383,7 +1788,7 @@ static int DSRL(MIPS_instr mips){ } static int DSRA(MIPS_instr mips){ - PowerPC_instr ppc; + #if defined(INTERPRET_DW) || defined(INTERPRET_DSRA) genCallInterp(mips); return INTERPRETED; @@ -2395,23 +1800,17 @@ static int DSRA(MIPS_instr mips){ if(sa){ // Shift LSW right by SA - GEN_SRWI(ppc, rd.lo, rt.lo, sa); - set_next_dst(ppc); + EMIT_SRWI(rd.lo, rt.lo, sa); // Extract the bits shifted out of the MSW - GEN_RLWINM(ppc, 0, rt.hi, 32-sa, 0, sa-1); - set_next_dst(ppc); + EMIT_RLWINM(0, rt.hi, 32-sa, 0, sa-1); // Insert those bits into the LSW - GEN_OR(ppc, rd.lo, rd.lo, 0); - set_next_dst(ppc); + EMIT_OR(rd.lo, rd.lo, 0); // Shift (arithmetically) MSW right by SA - GEN_SRAWI(ppc, rd.hi, rt.hi, sa); - set_next_dst(ppc); + EMIT_SRAWI(rd.hi, rt.hi, sa); } else { // Copy over the register - GEN_ADDI(ppc, rd.hi, rt.hi, 0); - set_next_dst(ppc); - GEN_ADDI(ppc, rd.lo, rt.lo, 0); - set_next_dst(ppc); + EMIT_ADDI(rd.hi, rt.hi, 0); + EMIT_ADDI(rd.lo, rt.lo, 0); } return CONVERT_SUCCESS; @@ -2419,7 +1818,7 @@ static int DSRA(MIPS_instr mips){ } static int DSLL32(MIPS_instr mips){ - PowerPC_instr ppc; + #if defined(INTERPRET_DW) || defined(INTERPRET_DSLL32) genCallInterp(mips); return INTERPRETED; @@ -2430,18 +1829,16 @@ static int DSLL32(MIPS_instr mips){ int sa = MIPS_GET_SA(mips); // Shift LSW into MSW and by SA - GEN_SLWI(ppc, rd.hi, rt.lo, sa); - set_next_dst(ppc); + EMIT_SLWI(rd.hi, rt.lo, sa); // Clear out LSW - GEN_ADDI(ppc, rd.lo, 0, 0); - set_next_dst(ppc); + EMIT_ADDI(rd.lo, 0, 0); return CONVERT_SUCCESS; #endif } static int DSRL32(MIPS_instr mips){ - PowerPC_instr ppc; + #if defined(INTERPRET_DW) || defined(INTERPRET_DSRL32) genCallInterp(mips); return INTERPRETED; @@ -2452,18 +1849,16 @@ static int DSRL32(MIPS_instr mips){ int sa = MIPS_GET_SA(mips); // Shift MSW into LSW and by SA - GEN_SRWI(ppc, rd.lo, rt.hi, sa); - set_next_dst(ppc); + EMIT_SRWI(rd.lo, rt.hi, sa); // Clear out MSW - GEN_ADDI(ppc, rd.hi, 0, 0); - set_next_dst(ppc); + EMIT_ADDI(rd.hi, 0, 0); return CONVERT_SUCCESS; #endif } static int DSRA32(MIPS_instr mips){ - PowerPC_instr ppc; + #if defined(INTERPRET_DW) || defined(INTERPRET_DSRA32) genCallInterp(mips); return INTERPRETED; @@ -2474,25 +1869,22 @@ static int DSRA32(MIPS_instr mips){ int sa = MIPS_GET_SA(mips); // Shift (arithmetically) MSW into LSW and by SA - GEN_SRAWI(ppc, rd.lo, rt.hi, sa); - set_next_dst(ppc); + EMIT_SRAWI(rd.lo, rt.hi, sa); // Fill MSW with sign of MSW - GEN_SRAWI(ppc, rd.hi, rt.hi, 31); - set_next_dst(ppc); + EMIT_SRAWI(rd.hi, rt.hi, 31); return CONVERT_SUCCESS; #endif } static int ADDU(MIPS_instr mips){ - PowerPC_instr ppc; + int rt = mapRegister( MIPS_GET_RT(mips) ); int rs = mapRegister( MIPS_GET_RS(mips) ); - GEN_ADD(ppc, + EMIT_ADD( mapRegisterNew( MIPS_GET_RD(mips) ), rs, rt); - set_next_dst(ppc); return CONVERT_SUCCESS; } @@ -2502,14 +1894,13 @@ static int ADD(MIPS_instr mips){ } static int SUBU(MIPS_instr mips){ - PowerPC_instr ppc; + int rt = mapRegister( MIPS_GET_RT(mips) ); int rs = mapRegister( MIPS_GET_RS(mips) ); - GEN_SUB(ppc, + EMIT_SUB( mapRegisterNew( MIPS_GET_RD(mips) ), rs, rt); - set_next_dst(ppc); return CONVERT_SUCCESS; } @@ -2519,63 +1910,55 @@ static int SUB(MIPS_instr mips){ } static int AND(MIPS_instr mips){ - PowerPC_instr ppc; + RegMapping rt = mapRegister64( MIPS_GET_RT(mips) ); RegMapping rs = mapRegister64( MIPS_GET_RS(mips) ); RegMapping rd = mapRegister64New( MIPS_GET_RD(mips) ); - GEN_AND(ppc, rd.hi, rs.hi, rt.hi); - set_next_dst(ppc); - GEN_AND(ppc, rd.lo, rs.lo, rt.lo); - set_next_dst(ppc); + EMIT_AND(rd.hi, rs.hi, rt.hi); + EMIT_AND(rd.lo, rs.lo, rt.lo); return CONVERT_SUCCESS; } static int OR(MIPS_instr mips){ - PowerPC_instr ppc; + RegMapping rt = mapRegister64( MIPS_GET_RT(mips) ); RegMapping rs = mapRegister64( MIPS_GET_RS(mips) ); RegMapping rd = mapRegister64New( MIPS_GET_RD(mips) ); - GEN_OR(ppc, rd.hi, rs.hi, rt.hi); - set_next_dst(ppc); - GEN_OR(ppc, rd.lo, rs.lo, rt.lo); - set_next_dst(ppc); + EMIT_OR(rd.hi, rs.hi, rt.hi); + EMIT_OR(rd.lo, rs.lo, rt.lo); return CONVERT_SUCCESS; } static int XOR(MIPS_instr mips){ - PowerPC_instr ppc; + RegMapping rt = mapRegister64( MIPS_GET_RT(mips) ); RegMapping rs = mapRegister64( MIPS_GET_RS(mips) ); RegMapping rd = mapRegister64New( MIPS_GET_RD(mips) ); - GEN_XOR(ppc, rd.hi, rs.hi, rt.hi); - set_next_dst(ppc); - GEN_XOR(ppc, rd.lo, rs.lo, rt.lo); - set_next_dst(ppc); + EMIT_XOR(rd.hi, rs.hi, rt.hi); + EMIT_XOR(rd.lo, rs.lo, rt.lo); return CONVERT_SUCCESS; } static int NOR(MIPS_instr mips){ - PowerPC_instr ppc; + RegMapping rt = mapRegister64( MIPS_GET_RT(mips) ); RegMapping rs = mapRegister64( MIPS_GET_RS(mips) ); RegMapping rd = mapRegister64New( MIPS_GET_RD(mips) ); - GEN_NOR(ppc, rd.hi, rs.hi, rt.hi); - set_next_dst(ppc); - GEN_NOR(ppc, rd.lo, rs.lo, rt.lo); - set_next_dst(ppc); + EMIT_NOR(rd.hi, rs.hi, rt.hi); + EMIT_NOR(rd.lo, rs.lo, rt.lo); return CONVERT_SUCCESS; } static int SLT(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_SLT genCallInterp(mips); return INTERPRETED; @@ -2586,27 +1969,22 @@ static int SLT(MIPS_instr mips){ int rd = mapRegisterNew( MIPS_GET_RD(mips) ); // carry = rs < rt ? 0 : 1 (unsigned) - GEN_SUBFC(ppc, 0, rt, rs); - set_next_dst(ppc); + EMIT_SUBFC(0, rt, rs); // rd = ~(rs ^ rt) - GEN_EQV(ppc, rd, rt, rs); - set_next_dst(ppc); + EMIT_EQV(rd, rt, rs); // rd = sign(rs) == sign(rt) ? 1 : 0 - GEN_SRWI(ppc, rd, rd, 31); - set_next_dst(ppc); + EMIT_SRWI(rd, rd, 31); // rd += carry - GEN_ADDZE(ppc, rd, rd); - set_next_dst(ppc); + EMIT_ADDZE(rd, rd); // rt &= 1 ( = (sign(rs) == sign(rt)) xor (rs < rt (unsigned)) ) - GEN_RLWINM(ppc, rd, rd, 0, 31, 31); - set_next_dst(ppc); + EMIT_RLWINM(rd, rd, 0, 31, 31); return CONVERT_SUCCESS; #endif } static int SLTU(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_SLTU genCallInterp(mips); return INTERPRETED; @@ -2616,21 +1994,18 @@ static int SLTU(MIPS_instr mips){ int rs = mapRegister( MIPS_GET_RS(mips) ); int rd = mapRegisterNew( MIPS_GET_RD(mips) ); // carry = rs < rt ? 0 : 1 - GEN_SUBFC(ppc, rd, rt, rs); - set_next_dst(ppc); + EMIT_SUBFC(rd, rt, rs); // rd = carry - 1 ( = rs < rt ? -1 : 0 ) - GEN_SUBFE(ppc, rd, rd, rd); - set_next_dst(ppc); + EMIT_SUBFE(rd, rd, rd); // rd = !carry ( = rs < rt ? 1 : 0 ) - GEN_NEG(ppc, rd, rd); - set_next_dst(ppc); + EMIT_NEG(rd, rd); return CONVERT_SUCCESS; #endif } static int TEQ(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_TRAPS genCallInterp(mips); return INTERPRETED; @@ -2661,7 +2036,7 @@ static int SPECIAL(MIPS_instr mips){ // BLTZ, BGEZ, BLTZL, BGEZL, BLZAL, BGEZAL, BLTZALL, BGEZALL // It's less work to handle them all in one function static int REGIMM(MIPS_instr mips){ - PowerPC_instr ppc; + int which = MIPS_GET_RT(mips); int cond = which & 1; // t = GE, f = LT int likely = which & 2; @@ -2682,7 +2057,7 @@ static int REGIMM(MIPS_instr mips){ // -- COP0 Instructions -- static int TLBR(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_TLBR genCallInterp(mips); return INTERPRETED; @@ -2692,7 +2067,7 @@ static int TLBR(MIPS_instr mips){ } static int TLBWI(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_TLBWI genCallInterp(mips); return INTERPRETED; @@ -2702,7 +2077,7 @@ static int TLBWI(MIPS_instr mips){ } static int TLBWR(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_TLBWR genCallInterp(mips); return INTERPRETED; @@ -2712,7 +2087,7 @@ static int TLBWR(MIPS_instr mips){ } static int TLBP(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_TLBP genCallInterp(mips); return INTERPRETED; @@ -2722,7 +2097,7 @@ static int TLBP(MIPS_instr mips){ } static int ERET(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_ERET genCallInterp(mips); return INTERPRETED; @@ -2732,35 +2107,32 @@ static int ERET(MIPS_instr mips){ genUpdateCount(0); // Load Status - GEN_LWZ(ppc, 3, 12*4, DYNAREG_COP0); - set_next_dst(ppc); + EMIT_LWZ(3, 12*4, DYNAREG_COP0); // Load upper address of llbit - GEN_LIS(ppc, 4, extractUpper16(&llbit)); - set_next_dst(ppc); + EMIT_LIS(4, extractUpper16(&llbit)); // Status & 0xFFFFFFFD - GEN_RLWINM(ppc, 3, 3, 0, 31, 29); - set_next_dst(ppc); + EMIT_RLWINM(3, 3, 0, 31, 29); // llbit = 0 - GEN_STW(ppc, DYNAREG_ZERO, extractLower16(&llbit), 4); - set_next_dst(ppc); + EMIT_STW(DYNAREG_ZERO, extractLower16(&llbit), 4); // Store updated Status - GEN_STW(ppc, 3, 12*4, DYNAREG_COP0); - set_next_dst(ppc); + EMIT_STW(3, 12*4, DYNAREG_COP0); // check_interupt() - GEN_B(ppc, add_jump(&check_interupt, 1, 1), 0, 1); - set_next_dst(ppc); +#if 1 + EMIT_B(add_jump(&check_interupt, 1, 1), 0, 1); +#else + EMIT_LIS(12, ((unsigned int)&check_interupt)>>16); + EMIT_ORI(12, 12, (unsigned int)&check_interupt); + EMIT_MTCTR(12); + EMIT_BCTRL(ppc); +#endif // Load the old LR - GEN_LWZ(ppc, 0, DYNAOFF_LR, 1); - set_next_dst(ppc); + EMIT_LWZ(0, DYNAOFF_LR, 1); // interp_addr = EPC - GEN_LWZ(ppc, 3, 14*4, DYNAREG_COP0); - set_next_dst(ppc); + EMIT_LWZ(3, 14*4, DYNAREG_COP0); // Restore the LR - GEN_MTLR(ppc, 0); - set_next_dst(ppc); + EMIT_MTLR(0); // Return to trampoline with EPC - GEN_BLR(ppc, 0); - set_next_dst(ppc); + EMIT_BLR(0); return CONVERT_SUCCESS; #endif @@ -2779,7 +2151,7 @@ static int (*gen_tlb[64])(MIPS_instr) = }; static int MFC0(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_MFC0 genCallInterp(mips); return INTERPRETED; @@ -2787,15 +2159,14 @@ static int MFC0(MIPS_instr mips){ int rt = mapRegisterNew(MIPS_GET_RT(mips)); // *rt = reg_cop0[rd] - GEN_LWZ(ppc, rt, MIPS_GET_RD(mips)*4, DYNAREG_COP0); - set_next_dst(ppc); + EMIT_LWZ(rt, MIPS_GET_RD(mips)*4, DYNAREG_COP0); return CONVERT_SUCCESS; #endif } static int MTC0(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_MTC0 genCallInterp(mips); return INTERPRETED; @@ -2809,82 +2180,65 @@ static int MTC0(MIPS_instr mips){ case 0: // Index rrt = mapRegister(rt); // r0 = rt & 0x8000003F - GEN_RLWINM(ppc, 0, rrt, 0, 26, 0); - set_next_dst(ppc); + EMIT_RLWINM(0, rrt, 0, 26, 0); // reg_cop0[rd] = r0 - GEN_STW(ppc, 0, rd*4, DYNAREG_COP0); - set_next_dst(ppc); + EMIT_STW(0, rd*4, DYNAREG_COP0); return CONVERT_SUCCESS; case 2: // EntryLo0 case 3: // EntryLo1 rrt = mapRegister(rt); // r0 = rt & 0x3FFFFFFF - GEN_RLWINM(ppc, 0, rrt, 0, 2, 31); - set_next_dst(ppc); + EMIT_RLWINM(0, rrt, 0, 2, 31); // reg_cop0[rd] = r0 - GEN_STW(ppc, 0, rd*4, DYNAREG_COP0); - set_next_dst(ppc); + EMIT_STW(0, rd*4, DYNAREG_COP0); return CONVERT_SUCCESS; case 4: // Context rrt = mapRegister(rt), tmp = mapRegisterTemp(); // tmp = reg_cop0[rd] - GEN_LWZ(ppc, tmp, rd*4, DYNAREG_COP0); - set_next_dst(ppc); + EMIT_LWZ(tmp, rd*4, DYNAREG_COP0); // r0 = rt & 0xFF800000 - GEN_RLWINM(ppc, 0, rrt, 0, 0, 8); - set_next_dst(ppc); + EMIT_RLWINM(0, rrt, 0, 0, 8); // tmp &= 0x007FFFF0 - GEN_RLWINM(ppc, tmp, tmp, 0, 9, 27); - set_next_dst(ppc); + EMIT_RLWINM(tmp, tmp, 0, 9, 27); // tmp |= r0 - GEN_OR(ppc, tmp, tmp, 0); - set_next_dst(ppc); + EMIT_OR(tmp, tmp, 0); // reg_cop0[rd] = tmp - GEN_STW(ppc, tmp, rd*4, DYNAREG_COP0); - set_next_dst(ppc); + EMIT_STW(tmp, rd*4, DYNAREG_COP0); return CONVERT_SUCCESS; case 5: // PageMask rrt = mapRegister(rt); // r0 = rt & 0x01FFE000 - GEN_RLWINM(ppc, 0, rrt, 0, 7, 18); - set_next_dst(ppc); + EMIT_RLWINM(0, rrt, 0, 7, 18); // reg_cop0[rd] = r0 - GEN_STW(ppc, 0, rd*4, DYNAREG_COP0); - set_next_dst(ppc); + EMIT_STW(0, rd*4, DYNAREG_COP0); return CONVERT_SUCCESS; case 6: // Wired rrt = mapRegister(rt); // r0 = 31 - GEN_ADDI(ppc, 0, 0, 31); - set_next_dst(ppc); + EMIT_ADDI(0, 0, 31); // reg_cop0[rd] = rt - GEN_STW(ppc, rrt, rd*4, DYNAREG_COP0); - set_next_dst(ppc); + EMIT_STW(rrt, rd*4, DYNAREG_COP0); // reg_cop0[1] = r0 - GEN_STW(ppc, 0, 1*4, DYNAREG_COP0); - set_next_dst(ppc); + EMIT_STW(0, 1*4, DYNAREG_COP0); return CONVERT_SUCCESS; case 10: // EntryHi rrt = mapRegister(rt); // r0 = rt & 0xFFFFE0FF - GEN_RLWINM(ppc, 0, rrt, 0, 24, 18); - set_next_dst(ppc); + EMIT_RLWINM(0, rrt, 0, 24, 18); // reg_cop0[rd] = r0 - GEN_STW(ppc, 0, rd*4, DYNAREG_COP0); - set_next_dst(ppc); + EMIT_STW(0, rd*4, DYNAREG_COP0); return CONVERT_SUCCESS; case 13: // Cause rrt = mapRegister(rt); // TODO: Ensure that rrt == 0? // reg_cop0[rd] = rt - GEN_STW(ppc, rrt, rd*4, DYNAREG_COP0); - set_next_dst(ppc); + EMIT_STW(rrt, rd*4, DYNAREG_COP0); return CONVERT_SUCCESS; case 14: // EPC @@ -2893,24 +2247,20 @@ static int MTC0(MIPS_instr mips){ case 19: // WatchHi rrt = mapRegister(rt); // reg_cop0[rd] = rt - GEN_STW(ppc, rrt, rd*4, DYNAREG_COP0); - set_next_dst(ppc); + EMIT_STW(rrt, rd*4, DYNAREG_COP0); return CONVERT_SUCCESS; case 28: // TagLo rrt = mapRegister(rt); // r0 = rt & 0x0FFFFFC0 - GEN_RLWINM(ppc, 0, rrt, 0, 4, 25); - set_next_dst(ppc); + EMIT_RLWINM(0, rrt, 0, 4, 25); // reg_cop0[rd] = r0 - GEN_STW(ppc, 0, rd*4, DYNAREG_COP0); - set_next_dst(ppc); + EMIT_STW(0, rd*4, DYNAREG_COP0); return CONVERT_SUCCESS; case 29: // TagHi // reg_cop0[rd] = 0 - GEN_STW(ppc, DYNAREG_ZERO, rd*4, DYNAREG_COP0); - set_next_dst(ppc); + EMIT_STW(DYNAREG_ZERO, rd*4, DYNAREG_COP0); return CONVERT_SUCCESS; case 1: // Random @@ -2932,7 +2282,7 @@ static int MTC0(MIPS_instr mips){ } static int TLB(MIPS_instr mips){ - PowerPC_instr ppc; + #ifdef INTERPRET_TLB genCallInterp(mips); return INTERPRETED; @@ -2961,7 +2311,7 @@ static int COP0(MIPS_instr mips){ // -- COP1 Instructions -- static int MFC1(MIPS_instr mips){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_MFC1) genCallInterp(mips); return INTERPRETED; @@ -2974,18 +2324,16 @@ static int MFC1(MIPS_instr mips){ flushFPR(fs); // rt = reg_cop1_simple[fs] - GEN_LWZ(ppc, rt, fs*4, DYNAREG_FPR_32); - set_next_dst(ppc); + EMIT_LWZ(rt, fs*4, DYNAREG_FPR_32); // rt = *rt - GEN_LWZ(ppc, rt, 0, rt); - set_next_dst(ppc); + EMIT_LWZ(rt, 0, rt); return CONVERT_SUCCESS; #endif } static int DMFC1(MIPS_instr mips){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_DMFC1) genCallInterp(mips); return INTERPRETED; @@ -2999,14 +2347,11 @@ static int DMFC1(MIPS_instr mips){ flushFPR(fs); // addr = reg_cop1_double[fs] - GEN_LWZ(ppc, addr, fs*4, DYNAREG_FPR_64); - set_next_dst(ppc); + EMIT_LWZ(addr, fs*4, DYNAREG_FPR_64); // rt[hi] = *addr - GEN_LWZ(ppc, rt.hi, 0, addr); - set_next_dst(ppc); + EMIT_LWZ(rt.hi, 0, addr); // rt[lo] = *(addr+4) - GEN_LWZ(ppc, rt.lo, 4, addr); - set_next_dst(ppc); + EMIT_LWZ(rt.lo, 4, addr); unmapRegisterTemp(addr); @@ -3015,7 +2360,7 @@ static int DMFC1(MIPS_instr mips){ } static int CFC1(MIPS_instr mips){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_CFC1) genCallInterp(mips); return INTERPRETED; @@ -3026,13 +2371,11 @@ static int CFC1(MIPS_instr mips){ if(MIPS_GET_FS(mips) == 31){ int rt = mapRegisterNew( MIPS_GET_RT(mips) ); - GEN_LWZ(ppc, rt, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_LWZ(rt, 0, DYNAREG_FCR31); } else if(MIPS_GET_FS(mips) == 0){ int rt = mapRegisterNew( MIPS_GET_RT(mips) ); - GEN_LI(ppc, rt, 0, 0x511); - set_next_dst(ppc); + EMIT_LI(rt, 0x511); } return CONVERT_SUCCESS; @@ -3040,7 +2383,7 @@ static int CFC1(MIPS_instr mips){ } static int MTC1(MIPS_instr mips){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_MTC1) genCallInterp(mips); return INTERPRETED; @@ -3054,11 +2397,9 @@ static int MTC1(MIPS_instr mips){ invalidateFPR(fs); // addr = reg_cop1_simple[fs] - GEN_LWZ(ppc, addr, fs*4, DYNAREG_FPR_32); - set_next_dst(ppc); + EMIT_LWZ(addr, fs*4, DYNAREG_FPR_32); // *addr = rt - GEN_STW(ppc, rt, 0, addr); - set_next_dst(ppc); + EMIT_STW(rt, 0, addr); unmapRegisterTemp(addr); @@ -3067,7 +2408,7 @@ static int MTC1(MIPS_instr mips){ } static int DMTC1(MIPS_instr mips){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_DMTC1) genCallInterp(mips); return INTERPRETED; @@ -3080,12 +2421,9 @@ static int DMTC1(MIPS_instr mips){ int addr = mapRegisterTemp(); invalidateFPR(fs); - GEN_LWZ(ppc, addr, fs*4, DYNAREG_FPR_64); - set_next_dst(ppc); - GEN_STW(ppc, rt.hi, 0, addr); - set_next_dst(ppc); - GEN_STW(ppc, rt.lo, 4, addr); - set_next_dst(ppc); + EMIT_LWZ(addr, fs*4, DYNAREG_FPR_64); + EMIT_STW(rt.hi, 0, addr); + EMIT_STW(rt.lo, 4, addr); unmapRegisterTemp(addr); @@ -3094,7 +2432,7 @@ static int DMTC1(MIPS_instr mips){ } static int CTC1(MIPS_instr mips){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_CTC1) genCallInterp(mips); return INTERPRETED; @@ -3105,8 +2443,7 @@ static int CTC1(MIPS_instr mips){ if(MIPS_GET_FS(mips) == 31){ int rt = mapRegister( MIPS_GET_RT(mips) ); - GEN_STW(ppc, rt, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_STW(rt, 0, DYNAREG_FCR31); } return CONVERT_SUCCESS; @@ -3114,7 +2451,7 @@ static int CTC1(MIPS_instr mips){ } static int BC(MIPS_instr mips){ - PowerPC_instr ppc; + #if defined(INTERPRET_BC) genCallInterp(mips); return INTERPRETED; @@ -3130,12 +2467,9 @@ static int BC(MIPS_instr mips){ int cond = mips & 0x00010000; int likely = mips & 0x00020000; - GEN_LWZ(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); - GEN_RLWINM(ppc, 0, 0, 9, 31, 31); - set_next_dst(ppc); - GEN_CMPI(ppc, 0, 0, 4); - set_next_dst(ppc); + EMIT_LWZ(0, 0, DYNAREG_FCR31); + EMIT_RLWINM(0, 0, 9, 31, 31); + EMIT_CMPI(0, 0, 4); return branch(signExtend(MIPS_GET_IMMED(mips),16), cond?NE:EQ, 0, likely); #endif @@ -3143,7 +2477,7 @@ static int BC(MIPS_instr mips){ // -- Floating Point Arithmetic -- static int ADD_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_ADD) genCallInterp(mips); return INTERPRETED; @@ -3155,15 +2489,14 @@ static int ADD_FP(MIPS_instr mips, int dbl){ int ft = mapFPR( MIPS_GET_FT(mips), dbl ); int fd = mapFPRNew( MIPS_GET_FD(mips), dbl ); - GEN_FADD(ppc, fd, fs, ft, dbl); - set_next_dst(ppc); + EMIT_FADD(fd, fs, ft, dbl); return CONVERT_SUCCESS; #endif } static int SUB_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_SUB) genCallInterp(mips); return INTERPRETED; @@ -3175,15 +2508,14 @@ static int SUB_FP(MIPS_instr mips, int dbl){ int ft = mapFPR( MIPS_GET_FT(mips), dbl ); int fd = mapFPRNew( MIPS_GET_FD(mips), dbl ); - GEN_FSUB(ppc, fd, fs, ft, dbl); - set_next_dst(ppc); + EMIT_FSUB(fd, fs, ft, dbl); return CONVERT_SUCCESS; #endif } static int MUL_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_MUL) genCallInterp(mips); return INTERPRETED; @@ -3195,15 +2527,14 @@ static int MUL_FP(MIPS_instr mips, int dbl){ int ft = mapFPR( MIPS_GET_FT(mips), dbl ); int fd = mapFPRNew( MIPS_GET_FD(mips), dbl ); - GEN_FMUL(ppc, fd, fs, ft, dbl); - set_next_dst(ppc); + EMIT_FMUL(fd, fs, ft, dbl); return CONVERT_SUCCESS; #endif } static int DIV_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_DIV) genCallInterp(mips); return INTERPRETED; @@ -3215,15 +2546,14 @@ static int DIV_FP(MIPS_instr mips, int dbl){ int ft = mapFPR( MIPS_GET_FT(mips), dbl ); int fd = mapFPRNew( MIPS_GET_FD(mips), dbl ); - GEN_FDIV(ppc, fd, fs, ft, dbl); - set_next_dst(ppc); + EMIT_FDIV(fd, fs, ft, dbl); return CONVERT_SUCCESS; #endif } static int SQRT_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_SQRT) genCallInterp(mips); return INTERPRETED; @@ -3236,24 +2566,28 @@ static int SQRT_FP(MIPS_instr mips, int dbl){ invalidateRegisters(); // call sqrt - GEN_B(ppc, add_jump(dbl ? &sqrt : &sqrtf, 1, 1), 0, 1); - set_next_dst(ppc); - +#if 1 + EMIT_B(add_jump(dbl ? &sqrt : &sqrtf, 1, 1), 0, 1); +#else + EMIT_LIS(12, ((unsigned int)(dbl ? &sqrt : &sqrtf))>>16); + EMIT_ORI(12, 12, (unsigned int)(dbl ? &sqrt : &sqrtf)); + EMIT_MTCTR(12); + EMIT_BCTRL(ppc); +#endif + mapFPRNew( MIPS_GET_FD(mips), dbl ); // maps to f1 (FP return) // Load old LR - GEN_LWZ(ppc, 0, DYNAOFF_LR, 1); - set_next_dst(ppc); + EMIT_LWZ(0, DYNAOFF_LR, 1); // Restore LR - GEN_MTLR(ppc, 0); - set_next_dst(ppc); + EMIT_MTLR(0); return CONVERT_SUCCESS; #endif } static int ABS_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_ABS) genCallInterp(mips); return INTERPRETED; @@ -3264,15 +2598,14 @@ static int ABS_FP(MIPS_instr mips, int dbl){ int fs = mapFPR( MIPS_GET_FS(mips), dbl ); int fd = mapFPRNew( MIPS_GET_FD(mips), dbl ); - GEN_FABS(ppc, fd, fs); - set_next_dst(ppc); + EMIT_FABS(fd, fs); return CONVERT_SUCCESS; #endif } static int MOV_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_MOV) genCallInterp(mips); return INTERPRETED; @@ -3283,15 +2616,14 @@ static int MOV_FP(MIPS_instr mips, int dbl){ int fs = mapFPR( MIPS_GET_FS(mips), dbl ); int fd = mapFPRNew( MIPS_GET_FD(mips), dbl ); - GEN_FMR(ppc, fd, fs); - set_next_dst(ppc); + EMIT_FMR(fd, fs); return CONVERT_SUCCESS; #endif } static int NEG_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_NEG) genCallInterp(mips); return INTERPRETED; @@ -3302,8 +2634,7 @@ static int NEG_FP(MIPS_instr mips, int dbl){ int fs = mapFPR( MIPS_GET_FS(mips), dbl ); int fd = mapFPRNew( MIPS_GET_FD(mips), dbl ); - GEN_FNEG(ppc, fd, fs); - set_next_dst(ppc); + EMIT_FNEG(fd, fs); return CONVERT_SUCCESS; #endif @@ -3315,21 +2646,19 @@ static int NEG_FP(MIPS_instr mips, int dbl){ #define PPC_ROUNDING_CEIL 2 #define PPC_ROUNDING_FLOOR 3 static void set_rounding(int rounding_mode){ - PowerPC_instr ppc; + - GEN_MTFSFI(ppc, 7, rounding_mode); - set_next_dst(ppc); + EMIT_MTFSFI(7, rounding_mode); } static void set_rounding_reg(int fs){ - PowerPC_instr ppc; + - GEN_MTFSF(ppc, 1, fs); - set_next_dst(ppc); + EMIT_MTFSF(1, fs); } static int ROUND_L_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_ROUND_L) genCallInterp(mips); return INTERPRETED; @@ -3343,35 +2672,43 @@ static int ROUND_L_FP(MIPS_instr mips, int dbl){ invalidateFPR( MIPS_GET_FS(mips) ); // round - GEN_B(ppc, add_jump(dbl ? &round : &roundf, 1, 1), 0, 1); - set_next_dst(ppc); +#if 1 + EMIT_B(add_jump(dbl ? &round : &roundf, 1, 1), 0, 1); +#else + EMIT_LIS(12, ((unsigned int)(dbl ? &round : &roundf))>>16); + EMIT_ORI(12, 12, (unsigned int)(dbl ? &round : &roundf)); + EMIT_MTCTR(12); + EMIT_BCTRL(ppc); +#endif + // convert - GEN_B(ppc, add_jump(dbl ? &__fixdfdi : &__fixsfdi, 1, 1), 0, 1); - set_next_dst(ppc); +#if 1 + EMIT_B(add_jump(dbl ? &__fixdfdi : &__fixsfdi, 1, 1), 0, 1); +#else + EMIT_LIS(12, ((unsigned int)(dbl ? &__fixdfdi : &__fixsfdi))>>16); + EMIT_ORI(12, 12, (unsigned int)(dbl ? &__fixdfdi : &__fixsfdi)); + EMIT_MTCTR(12); + EMIT_BCTRL(ppc); +#endif int addr = 5; // Use r5 for the addr (to not clobber r3/r4) // addr = reg_cop1_double[fd] - GEN_LWZ(ppc, addr, fd*4, DYNAREG_FPR_64); - set_next_dst(ppc); + EMIT_LWZ(addr, fd*4, DYNAREG_FPR_64); // Load old LR - GEN_LWZ(ppc, 0, DYNAOFF_LR, 1); - set_next_dst(ppc); + EMIT_LWZ(0, DYNAOFF_LR, 1); // stw r3, 0(addr) - GEN_STW(ppc, 3, 0, addr); - set_next_dst(ppc); + EMIT_STW(3, 0, addr); // Restore LR - GEN_MTLR(ppc, 0); - set_next_dst(ppc); + EMIT_MTLR(0); // stw r4, 4(addr) - GEN_STW(ppc, 4, 4, addr); - set_next_dst(ppc); + EMIT_STW(4, 4, addr); return CONVERT_SUCCESS; #endif } static int TRUNC_L_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_TRUNC_L) genCallInterp(mips); return INTERPRETED; @@ -3385,32 +2722,33 @@ static int TRUNC_L_FP(MIPS_instr mips, int dbl){ invalidateFPR( MIPS_GET_FS(mips) ); // convert - GEN_B(ppc, add_jump(dbl ? &__fixdfdi : &__fixsfdi, 1, 1), 0, 1); - set_next_dst(ppc); +#if 1 + EMIT_B(add_jump(dbl ? &__fixdfdi : &__fixsfdi, 1, 1), 0, 1); +#else + EMIT_LIS(12, ((unsigned int)(dbl ? &__fixdfdi : &__fixsfdi))>>16); + EMIT_ORI(12, 12, (unsigned int)(dbl ? &__fixdfdi : &__fixsfdi)); + EMIT_MTCTR(12); + EMIT_BCTRL(ppc); +#endif int addr = 5; // Use r5 for the addr (to not clobber r3/r4) // addr = reg_cop1_double[fd] - GEN_LWZ(ppc, addr, fd*4, DYNAREG_FPR_64); - set_next_dst(ppc); + EMIT_LWZ(addr, fd*4, DYNAREG_FPR_64); // Load old LR - GEN_LWZ(ppc, 0, DYNAOFF_LR, 1); - set_next_dst(ppc); + EMIT_LWZ(0, DYNAOFF_LR, 1); // stw r3, 0(addr) - GEN_STW(ppc, 3, 0, addr); - set_next_dst(ppc); + EMIT_STW(3, 0, addr); // Restore LR - GEN_MTLR(ppc, 0); - set_next_dst(ppc); + EMIT_MTLR(0); // stw r4, 4(addr) - GEN_STW(ppc, 4, 4, addr); - set_next_dst(ppc); + EMIT_STW(4, 4, addr); return CONVERT_SUCCESS; #endif } static int CEIL_L_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_CEIL_L) genCallInterp(mips); return INTERPRETED; @@ -3424,35 +2762,42 @@ static int CEIL_L_FP(MIPS_instr mips, int dbl){ invalidateFPR( MIPS_GET_FS(mips) ); // ceil - GEN_B(ppc, add_jump(dbl ? &ceil : &ceilf, 1, 1), 0, 1); - set_next_dst(ppc); +#if 1 + EMIT_B(add_jump(dbl ? &ceil : &ceilf, 1, 1), 0, 1); +#else + EMIT_LIS(12, ((unsigned int)(dbl ? &ceil : &ceilf))>>16); + EMIT_ORI(12, 12, (unsigned int)(dbl ? &ceil : &ceilf)); + EMIT_MTCTR(12); + EMIT_BCTRL(ppc); +#endif // convert - GEN_B(ppc, add_jump(dbl ? &__fixdfdi : &__fixsfdi, 1, 1), 0, 1); - set_next_dst(ppc); +#if 1 + EMIT_B(add_jump(dbl ? &__fixdfdi : &__fixsfdi, 1, 1), 0, 1); +#else + EMIT_LIS(12, ((unsigned int)(dbl ? &__fixdfdi : &__fixsfdi))>>16); + EMIT_ORI(12, 12, (unsigned int)(dbl ? &__fixdfdi : &__fixsfdi)); + EMIT_MTCTR(12); + EMIT_BCTRL(ppc); +#endif int addr = 5; // Use r5 for the addr (to not clobber r3/r4) // addr = reg_cop1_double[fd] - GEN_LWZ(ppc, addr, fd*4, DYNAREG_FPR_64); - set_next_dst(ppc); + EMIT_LWZ(addr, fd*4, DYNAREG_FPR_64); // Load old LR - GEN_LWZ(ppc, 0, DYNAOFF_LR, 1); - set_next_dst(ppc); + EMIT_LWZ(0, DYNAOFF_LR, 1); // stw r3, 0(addr) - GEN_STW(ppc, 3, 0, addr); - set_next_dst(ppc); + EMIT_STW(3, 0, addr); // Restore LR - GEN_MTLR(ppc, 0); - set_next_dst(ppc); + EMIT_MTLR(0); // stw r4, 4(addr) - GEN_STW(ppc, 4, 4, addr); - set_next_dst(ppc); + EMIT_STW(4, 4, addr); return CONVERT_SUCCESS; #endif } static int FLOOR_L_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_FLOOR_L) genCallInterp(mips); return INTERPRETED; @@ -3466,35 +2811,42 @@ static int FLOOR_L_FP(MIPS_instr mips, int dbl){ invalidateFPR( MIPS_GET_FS(mips) ); // round - GEN_B(ppc, add_jump(dbl ? &floor : &floorf, 1, 1), 0, 1); - set_next_dst(ppc); +#if 1 + EMIT_B(add_jump(dbl ? &floor : &floorf, 1, 1), 0, 1); +#else + EMIT_LIS(12, ((unsigned int)(dbl ? &floor : &floorf))>>16); + EMIT_ORI(12, 12, (unsigned int)(dbl ? &floor : &floorf)); + EMIT_MTCTR(12); + EMIT_BCTRL(ppc); +#endif // convert - GEN_B(ppc, add_jump(dbl ? &__fixdfdi : &__fixsfdi, 1, 1), 0, 1); - set_next_dst(ppc); +#if 1 + EMIT_B(add_jump(dbl ? &__fixdfdi : &__fixsfdi, 1, 1), 0, 1); +#else + EMIT_LIS(12, ((unsigned int)(dbl ? &__fixdfdi : &__fixsfdi))>>16); + EMIT_ORI(12, 12, (unsigned int)(dbl ? &__fixdfdi : &__fixsfdi)); + EMIT_MTCTR(12); + EMIT_BCTRL(ppc); +#endif int addr = 5; // Use r5 for the addr (to not clobber r3/r4) // addr = reg_cop1_double[fd] - GEN_LWZ(ppc, addr, fd*4, DYNAREG_FPR_64); - set_next_dst(ppc); + EMIT_LWZ(addr, fd*4, DYNAREG_FPR_64); // Load old LR - GEN_LWZ(ppc, 0, DYNAOFF_LR, 1); - set_next_dst(ppc); + EMIT_LWZ(0, DYNAOFF_LR, 1); // stw r3, 0(addr) - GEN_STW(ppc, 3, 0, addr); - set_next_dst(ppc); + EMIT_STW(3, 0, addr); // Restore LR - GEN_MTLR(ppc, 0); - set_next_dst(ppc); + EMIT_MTLR(0); // stw r4, 4(addr) - GEN_STW(ppc, 4, 4, addr); - set_next_dst(ppc); + EMIT_STW(4, 4, addr); return CONVERT_SUCCESS; #endif } static int ROUND_W_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_ROUND_W) genCallInterp(mips); return INTERPRETED; @@ -3510,14 +2862,11 @@ static int ROUND_W_FP(MIPS_instr mips, int dbl){ int addr = mapRegisterTemp(); // fctiw f0, fs - GEN_FCTIW(ppc, 0, fs); - set_next_dst(ppc); + EMIT_FCTIW(0, fs); // addr = reg_cop1_simple[fd] - GEN_LWZ(ppc, addr, fd*4, DYNAREG_FPR_32); - set_next_dst(ppc); + EMIT_LWZ(addr, fd*4, DYNAREG_FPR_32); // stfiwx f0, 0, addr - GEN_STFIWX(ppc, 0, 0, addr); - set_next_dst(ppc); + EMIT_STFIWX(0, 0, addr); unmapRegisterTemp(addr); @@ -3526,7 +2875,7 @@ static int ROUND_W_FP(MIPS_instr mips, int dbl){ } static int TRUNC_W_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_TRUNC_W) genCallInterp(mips); return INTERPRETED; @@ -3540,14 +2889,11 @@ static int TRUNC_W_FP(MIPS_instr mips, int dbl){ int addr = mapRegisterTemp(); // fctiwz f0, fs - GEN_FCTIWZ(ppc, 0, fs); - set_next_dst(ppc); + EMIT_FCTIWZ(0, fs); // addr = reg_cop1_simple[fd] - GEN_LWZ(ppc, addr, fd*4, DYNAREG_FPR_32); - set_next_dst(ppc); + EMIT_LWZ(addr, fd*4, DYNAREG_FPR_32); // stfiwx f0, 0, addr - GEN_STFIWX(ppc, 0, 0, addr); - set_next_dst(ppc); + EMIT_STFIWX(0, 0, addr); unmapRegisterTemp(addr); @@ -3556,7 +2902,7 @@ static int TRUNC_W_FP(MIPS_instr mips, int dbl){ } static int CEIL_W_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_CEIL_W) genCallInterp(mips); return INTERPRETED; @@ -3572,14 +2918,11 @@ static int CEIL_W_FP(MIPS_instr mips, int dbl){ int addr = mapRegisterTemp(); // fctiw f0, fs - GEN_FCTIW(ppc, 0, fs); - set_next_dst(ppc); + EMIT_FCTIW(0, fs); // addr = reg_cop1_simple[fd] - GEN_LWZ(ppc, addr, fd*4, DYNAREG_FPR_32); - set_next_dst(ppc); + EMIT_LWZ(addr, fd*4, DYNAREG_FPR_32); // stfiwx f0, 0, addr - GEN_STFIWX(ppc, 0, 0, addr); - set_next_dst(ppc); + EMIT_STFIWX(0, 0, addr); unmapRegisterTemp(addr); @@ -3590,7 +2933,7 @@ static int CEIL_W_FP(MIPS_instr mips, int dbl){ } static int FLOOR_W_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_FLOOR_W) genCallInterp(mips); return INTERPRETED; @@ -3606,14 +2949,11 @@ static int FLOOR_W_FP(MIPS_instr mips, int dbl){ int addr = mapRegisterTemp(); // fctiw f0, fs - GEN_FCTIW(ppc, 0, fs); - set_next_dst(ppc); + EMIT_FCTIW(0, fs); // addr = reg_cop1_simple[fd] - GEN_LWZ(ppc, addr, fd*4, DYNAREG_FPR_32); - set_next_dst(ppc); + EMIT_LWZ(addr, fd*4, DYNAREG_FPR_32); // stfiwx f0, 0, addr - GEN_STFIWX(ppc, 0, 0, addr); - set_next_dst(ppc); + EMIT_STFIWX(0, 0, addr); unmapRegisterTemp(addr); @@ -3624,7 +2964,7 @@ static int FLOOR_W_FP(MIPS_instr mips, int dbl){ } static int CVT_S_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_CVT_S) genCallInterp(mips); return INTERPRETED; @@ -3635,15 +2975,14 @@ static int CVT_S_FP(MIPS_instr mips, int dbl){ int fs = mapFPR( MIPS_GET_FS(mips), dbl ); int fd = mapFPRNew( MIPS_GET_FD(mips), 0 ); - GEN_FMR(ppc, fd, fs); - set_next_dst(ppc); + EMIT_FMR(fd, fs); return CONVERT_SUCCESS; #endif } static int CVT_D_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_CVT_D) genCallInterp(mips); return INTERPRETED; @@ -3654,15 +2993,14 @@ static int CVT_D_FP(MIPS_instr mips, int dbl){ int fs = mapFPR( MIPS_GET_FS(mips), dbl ); int fd = mapFPRNew( MIPS_GET_FD(mips), 1 ); - GEN_FMR(ppc, fd, fs); - set_next_dst(ppc); + EMIT_FMR(fd, fs); return CONVERT_SUCCESS; #endif } static int CVT_W_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_CVT_W) genCallInterp(mips); return INTERPRETED; @@ -3671,8 +3009,7 @@ static int CVT_W_FP(MIPS_instr mips, int dbl){ genCheckFP(); // Set rounding mode according to FCR31 - GEN_LFD(ppc, 0, -4, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_LFD(0, -4, DYNAREG_FCR31); // FIXME: Here I have the potential to disable IEEE mode // and enable inexact exceptions @@ -3684,14 +3021,11 @@ static int CVT_W_FP(MIPS_instr mips, int dbl){ int addr = mapRegisterTemp(); // fctiw f0, fs - GEN_FCTIW(ppc, 0, fs); - set_next_dst(ppc); + EMIT_FCTIW(0, fs); // addr = reg_cop1_simple[fd] - GEN_LWZ(ppc, addr, fd*4, DYNAREG_FPR_32); - set_next_dst(ppc); + EMIT_LWZ(addr, fd*4, DYNAREG_FPR_32); // stfiwx f0, 0, addr - GEN_STFIWX(ppc, 0, 0, addr); - set_next_dst(ppc); + EMIT_STFIWX(0, 0, addr); unmapRegisterTemp(addr); @@ -3702,7 +3036,7 @@ static int CVT_W_FP(MIPS_instr mips, int dbl){ } static int CVT_L_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_CVT_L) genCallInterp(mips); return INTERPRETED; @@ -3717,25 +3051,26 @@ static int CVT_L_FP(MIPS_instr mips, int dbl){ // FIXME: I'm fairly certain this will always trunc // convert - GEN_B(ppc, add_jump(dbl ? &__fixdfdi : &__fixsfdi, 1, 1), 0, 1); - set_next_dst(ppc); +#if 1 + EMIT_B(add_jump(dbl ? &__fixdfdi : &__fixsfdi, 1, 1), 0, 1); +#else + EMIT_LIS(12, ((unsigned int)(dbl ? &__fixdfdi : &__fixsfdi))>>16); + EMIT_ORI(12, 12, (unsigned int)(dbl ? &__fixdfdi : &__fixsfdi)); + EMIT_MTCTR(12); + EMIT_BCTRL(ppc); +#endif int addr = 5; // Use r5 for the addr (to not clobber r3/r4) // addr = reg_cop1_double[fd] - GEN_LWZ(ppc, addr, fd*4, DYNAREG_FPR_64); - set_next_dst(ppc); + EMIT_LWZ(addr, fd*4, DYNAREG_FPR_64); // Load old LR - GEN_LWZ(ppc, 0, DYNAOFF_LR, 1); - set_next_dst(ppc); + EMIT_LWZ(0, DYNAOFF_LR, 1); // stw r3, 0(addr) - GEN_STW(ppc, 3, 0, addr); - set_next_dst(ppc); + EMIT_STW(3, 0, addr); // Restore LR - GEN_MTLR(ppc, 0); - set_next_dst(ppc); + EMIT_MTLR(0); // stw r4, 4(addr) - GEN_STW(ppc, 4, 4, addr); - set_next_dst(ppc); + EMIT_STW(4, 4, addr); return CONVERT_SUCCESS; #endif @@ -3743,7 +3078,7 @@ static int CVT_L_FP(MIPS_instr mips, int dbl){ // -- Floating Point Comparisons -- static int C_F_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_C_F) genCallInterp(mips); return INTERPRETED; @@ -3752,21 +3087,18 @@ static int C_F_FP(MIPS_instr mips, int dbl){ genCheckFP(); // lwz r0, 0(&fcr31) - GEN_LWZ(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_LWZ(0, 0, DYNAREG_FCR31); // and r0, r0, 0xff7fffff (clear cond) - GEN_RLWINM(ppc, 0, 0, 0, 9, 7); - set_next_dst(ppc); + EMIT_RLWINM(0, 0, 0, 9, 7); // stw r0, 0(&fcr31) - GEN_STW(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_STW(0, 0, DYNAREG_FCR31); return CONVERT_SUCCESS; #endif } static int C_UN_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_C_UN) genCallInterp(mips); return INTERPRETED; @@ -3778,30 +3110,24 @@ static int C_UN_FP(MIPS_instr mips, int dbl){ int ft = mapFPR( MIPS_GET_FT(mips), dbl ); // lwz r0, 0(&fcr31) - GEN_LWZ(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_LWZ(0, 0, DYNAREG_FCR31); // fcmpu cr0, fs, ft - GEN_FCMPU(ppc, fs, ft, 0); - set_next_dst(ppc); + EMIT_FCMPU(fs, ft, 0); // and r0, r0, 0xff7fffff (clear cond) - GEN_RLWINM(ppc, 0, 0, 0, 9, 7); - set_next_dst(ppc); + EMIT_RLWINM(0, 0, 0, 9, 7); // bord cr0, 2 (past setting cond) - GEN_BC(ppc, 2, 0, 0, 0x4, 3); - set_next_dst(ppc); + EMIT_BC(2, 0, 0, 0x4, 3); // oris r0, r0, 0x0080 (set cond) - GEN_ORIS(ppc, 0, 0, 0x0080); - set_next_dst(ppc); + EMIT_ORIS(0, 0, 0x0080); // stw r0, 0(&fcr31) - GEN_STW(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_STW(0, 0, DYNAREG_FCR31); return CONVERT_SUCCESS; #endif } static int C_EQ_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_C_EQ) genCallInterp(mips); return INTERPRETED; @@ -3813,30 +3139,24 @@ static int C_EQ_FP(MIPS_instr mips, int dbl){ int ft = mapFPR( MIPS_GET_FT(mips), dbl ); // lwz r0, 0(&fcr31) - GEN_LWZ(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_LWZ(0, 0, DYNAREG_FCR31); // fcmpu cr0, fs, ft - GEN_FCMPU(ppc, fs, ft, 0); - set_next_dst(ppc); + EMIT_FCMPU(fs, ft, 0); // and r0, r0, 0xff7fffff (clear cond) - GEN_RLWINM(ppc, 0, 0, 0, 9, 7); - set_next_dst(ppc); + EMIT_RLWINM(0, 0, 0, 9, 7); // bne cr0, 2 (past setting cond) - GEN_BNE(ppc, 0, 2, 0, 0); - set_next_dst(ppc); + EMIT_BNE(0, 2, 0, 0); // oris r0, r0, 0x0080 (set cond) - GEN_ORIS(ppc, 0, 0, 0x0080); - set_next_dst(ppc); + EMIT_ORIS(0, 0, 0x0080); // stw r0, 0(&fcr31) - GEN_STW(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_STW(0, 0, DYNAREG_FCR31); return CONVERT_SUCCESS; #endif } static int C_UEQ_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_C_UEQ) genCallInterp(mips); return INTERPRETED; @@ -3848,33 +3168,26 @@ static int C_UEQ_FP(MIPS_instr mips, int dbl){ int ft = mapFPR( MIPS_GET_FT(mips), dbl ); // lwz r0, 0(&fcr31) - GEN_LWZ(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_LWZ(0, 0, DYNAREG_FCR31); // fcmpu cr0, fs, ft - GEN_FCMPU(ppc, fs, ft, 0); - set_next_dst(ppc); + EMIT_FCMPU(fs, ft, 0); // and r0, r0, 0xff7fffff (clear cond) - GEN_RLWINM(ppc, 0, 0, 0, 9, 7); - set_next_dst(ppc); + EMIT_RLWINM(0, 0, 0, 9, 7); // cror cr0[eq], cr0[eq], cr0[un] - GEN_CROR(ppc, 2, 2, 3); - set_next_dst(ppc); + EMIT_CROR(2, 2, 3); // bne cr0, 2 (past setting cond) - GEN_BNE(ppc, 0, 2, 0, 0); - set_next_dst(ppc); + EMIT_BNE(0, 2, 0, 0); // oris r0, r0, 0x0080 (set cond) - GEN_ORIS(ppc, 0, 0, 0x0080); - set_next_dst(ppc); + EMIT_ORIS(0, 0, 0x0080); // stw r0, 0(&fcr31) - GEN_STW(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_STW(0, 0, DYNAREG_FCR31); return CONVERT_SUCCESS; #endif } static int C_OLT_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_C_OLT) genCallInterp(mips); return INTERPRETED; @@ -3886,30 +3199,24 @@ static int C_OLT_FP(MIPS_instr mips, int dbl){ int ft = mapFPR( MIPS_GET_FT(mips), dbl ); // lwz r0, 0(&fcr31) - GEN_LWZ(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_LWZ(0, 0, DYNAREG_FCR31); // fcmpu cr0, fs, ft - GEN_FCMPU(ppc, fs, ft, 0); - set_next_dst(ppc); + EMIT_FCMPU(fs, ft, 0); // and r0, r0, 0xff7fffff (clear cond) - GEN_RLWINM(ppc, 0, 0, 0, 9, 7); - set_next_dst(ppc); + EMIT_RLWINM(0, 0, 0, 9, 7); // bge cr0, 2 (past setting cond) - GEN_BGE(ppc, 0, 2, 0, 0); - set_next_dst(ppc); + EMIT_BGE(0, 2, 0, 0); // oris r0, r0, 0x0080 (set cond) - GEN_ORIS(ppc, 0, 0, 0x0080); - set_next_dst(ppc); + EMIT_ORIS(0, 0, 0x0080); // stw r0, 0(&fcr31) - GEN_STW(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_STW(0, 0, DYNAREG_FCR31); return CONVERT_SUCCESS; #endif } static int C_ULT_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_C_ULT) genCallInterp(mips); return INTERPRETED; @@ -3921,33 +3228,26 @@ static int C_ULT_FP(MIPS_instr mips, int dbl){ int ft = mapFPR( MIPS_GET_FT(mips), dbl ); // lwz r0, 0(&fcr31) - GEN_LWZ(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_LWZ(0, 0, DYNAREG_FCR31); // fcmpu cr0, fs, ft - GEN_FCMPU(ppc, fs, ft, 0); - set_next_dst(ppc); + EMIT_FCMPU(fs, ft, 0); // and r0, r0, 0xff7fffff (clear cond) - GEN_RLWINM(ppc, 0, 0, 0, 9, 7); - set_next_dst(ppc); + EMIT_RLWINM(0, 0, 0, 9, 7); // cror cr0[lt], cr0[lt], cr0[un] - GEN_CROR(ppc, 0, 0, 3); - set_next_dst(ppc); + EMIT_CROR(0, 0, 3); // bge cr0, 2 (past setting cond) - GEN_BGE(ppc, 0, 2, 0, 0); - set_next_dst(ppc); + EMIT_BGE(0, 2, 0, 0); // oris r0, r0, 0x0080 (set cond) - GEN_ORIS(ppc, 0, 0, 0x0080); - set_next_dst(ppc); + EMIT_ORIS(0, 0, 0x0080); // stw r0, 0(&fcr31) - GEN_STW(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_STW(0, 0, DYNAREG_FCR31); return CONVERT_SUCCESS; #endif } static int C_OLE_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_C_OLE) genCallInterp(mips); return INTERPRETED; @@ -3959,33 +3259,26 @@ static int C_OLE_FP(MIPS_instr mips, int dbl){ int ft = mapFPR( MIPS_GET_FT(mips), dbl ); // lwz r0, 0(&fcr31) - GEN_LWZ(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_LWZ(0, 0, DYNAREG_FCR31); // fcmpu cr0, fs, ft - GEN_FCMPU(ppc, fs, ft, 0); - set_next_dst(ppc); + EMIT_FCMPU(fs, ft, 0); // and r0, r0, 0xff7fffff (clear cond) - GEN_RLWINM(ppc, 0, 0, 0, 9, 7); - set_next_dst(ppc); + EMIT_RLWINM(0, 0, 0, 9, 7); // cror cr0[gt], cr0[gt], cr0[un] - GEN_CROR(ppc, 1, 1, 3); - set_next_dst(ppc); + EMIT_CROR(1, 1, 3); // bgt cr0, 2 (past setting cond) - GEN_BGT(ppc, 0, 2, 0, 0); - set_next_dst(ppc); + EMIT_BGT(0, 2, 0, 0); // oris r0, r0, 0x0080 (set cond) - GEN_ORIS(ppc, 0, 0, 0x0080); - set_next_dst(ppc); + EMIT_ORIS(0, 0, 0x0080); // stw r0, 0(&fcr31) - GEN_STW(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_STW(0, 0, DYNAREG_FCR31); return CONVERT_SUCCESS; #endif } static int C_ULE_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_C_ULE) genCallInterp(mips); return INTERPRETED; @@ -3997,30 +3290,24 @@ static int C_ULE_FP(MIPS_instr mips, int dbl){ int ft = mapFPR( MIPS_GET_FT(mips), dbl ); // lwz r0, 0(&fcr31) - GEN_LWZ(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_LWZ(0, 0, DYNAREG_FCR31); // fcmpu cr0, fs, ft - GEN_FCMPU(ppc, fs, ft, 0); - set_next_dst(ppc); + EMIT_FCMPU(fs, ft, 0); // and r0, r0, 0xff7fffff (clear cond) - GEN_RLWINM(ppc, 0, 0, 0, 9, 7); - set_next_dst(ppc); + EMIT_RLWINM(0, 0, 0, 9, 7); // bgt cr0, 2 (past setting cond) - GEN_BGT(ppc, 0, 2, 0, 0); - set_next_dst(ppc); + EMIT_BGT(0, 2, 0, 0); // oris r0, r0, 0x0080 (set cond) - GEN_ORIS(ppc, 0, 0, 0x0080); - set_next_dst(ppc); + EMIT_ORIS(0, 0, 0x0080); // stw r0, 0(&fcr31) - GEN_STW(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_STW(0, 0, DYNAREG_FCR31); return CONVERT_SUCCESS; #endif } static int C_SF_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_C_SF) genCallInterp(mips); return INTERPRETED; @@ -4029,21 +3316,18 @@ static int C_SF_FP(MIPS_instr mips, int dbl){ genCheckFP(); // lwz r0, 0(&fcr31) - GEN_LWZ(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_LWZ(0, 0, DYNAREG_FCR31); // and r0, r0, 0xff7fffff (clear cond) - GEN_RLWINM(ppc, 0, 0, 0, 9, 7); - set_next_dst(ppc); + EMIT_RLWINM(0, 0, 0, 9, 7); // stw r0, 0(&fcr31) - GEN_STW(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_STW(0, 0, DYNAREG_FCR31); return CONVERT_SUCCESS; #endif } static int C_NGLE_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_C_NGLE) genCallInterp(mips); return INTERPRETED; @@ -4052,21 +3336,18 @@ static int C_NGLE_FP(MIPS_instr mips, int dbl){ genCheckFP(); // lwz r0, 0(&fcr31) - GEN_LWZ(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_LWZ(0, 0, DYNAREG_FCR31); // and r0, r0, 0xff7fffff (clear cond) - GEN_RLWINM(ppc, 0, 0, 0, 9, 7); - set_next_dst(ppc); + EMIT_RLWINM(0, 0, 0, 9, 7); // stw r0, 0(&fcr31) - GEN_STW(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_STW(0, 0, DYNAREG_FCR31); return CONVERT_SUCCESS; #endif } static int C_SEQ_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_C_SEQ) genCallInterp(mips); return INTERPRETED; @@ -4078,30 +3359,24 @@ static int C_SEQ_FP(MIPS_instr mips, int dbl){ int ft = mapFPR( MIPS_GET_FT(mips), dbl ); // lwz r0, 0(&fcr31) - GEN_LWZ(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_LWZ(0, 0, DYNAREG_FCR31); // fcmpu cr0, fs, ft - GEN_FCMPU(ppc, fs, ft, 0); - set_next_dst(ppc); + EMIT_FCMPU(fs, ft, 0); // and r0, r0, 0xff7fffff (clear cond) - GEN_RLWINM(ppc, 0, 0, 0, 9, 7); - set_next_dst(ppc); + EMIT_RLWINM(0, 0, 0, 9, 7); // bne cr0, 2 (past setting cond) - GEN_BNE(ppc, 0, 2, 0, 0); - set_next_dst(ppc); + EMIT_BNE(0, 2, 0, 0); // oris r0, r0, 0x0080 (set cond) - GEN_ORIS(ppc, 0, 0, 0x0080); - set_next_dst(ppc); + EMIT_ORIS(0, 0, 0x0080); // stw r0, 0(&fcr31) - GEN_STW(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_STW(0, 0, DYNAREG_FCR31); return CONVERT_SUCCESS; #endif } static int C_NGL_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_C_NGL) genCallInterp(mips); return INTERPRETED; @@ -4113,30 +3388,24 @@ static int C_NGL_FP(MIPS_instr mips, int dbl){ int ft = mapFPR( MIPS_GET_FT(mips), dbl ); // lwz r0, 0(&fcr31) - GEN_LWZ(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_LWZ(0, 0, DYNAREG_FCR31); // fcmpu cr0, fs, ft - GEN_FCMPU(ppc, fs, ft, 0); - set_next_dst(ppc); + EMIT_FCMPU(fs, ft, 0); // and r0, r0, 0xff7fffff (clear cond) - GEN_RLWINM(ppc, 0, 0, 0, 9, 7); - set_next_dst(ppc); + EMIT_RLWINM(0, 0, 0, 9, 7); // bne cr0, 2 (past setting cond) - GEN_BNE(ppc, 0, 2, 0, 0); - set_next_dst(ppc); + EMIT_BNE(0, 2, 0, 0); // oris r0, r0, 0x0080 (set cond) - GEN_ORIS(ppc, 0, 0, 0x0080); - set_next_dst(ppc); + EMIT_ORIS(0, 0, 0x0080); // stw r0, 0(&fcr31) - GEN_STW(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_STW(0, 0, DYNAREG_FCR31); return CONVERT_SUCCESS; #endif } static int C_LT_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_C_LT) genCallInterp(mips); return INTERPRETED; @@ -4148,30 +3417,24 @@ static int C_LT_FP(MIPS_instr mips, int dbl){ int ft = mapFPR( MIPS_GET_FT(mips), dbl ); // lwz r0, 0(&fcr31) - GEN_LWZ(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_LWZ(0, 0, DYNAREG_FCR31); // fcmpu cr0, fs, ft - GEN_FCMPU(ppc, fs, ft, 0); - set_next_dst(ppc); + EMIT_FCMPU(fs, ft, 0); // and r0, r0, 0xff7fffff (clear cond) - GEN_RLWINM(ppc, 0, 0, 0, 9, 7); - set_next_dst(ppc); + EMIT_RLWINM(0, 0, 0, 9, 7); // bge cr0, 2 (past setting cond) - GEN_BGE(ppc, 0, 2, 0, 0); - set_next_dst(ppc); + EMIT_BGE(0, 2, 0, 0); // oris r0, r0, 0x0080 (set cond) - GEN_ORIS(ppc, 0, 0, 0x0080); - set_next_dst(ppc); + EMIT_ORIS(0, 0, 0x0080); // stw r0, 0(&fcr31) - GEN_STW(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_STW(0, 0, DYNAREG_FCR31); return CONVERT_SUCCESS; #endif } static int C_NGE_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_C_NGE) genCallInterp(mips); return INTERPRETED; @@ -4183,30 +3446,24 @@ static int C_NGE_FP(MIPS_instr mips, int dbl){ int ft = mapFPR( MIPS_GET_FT(mips), dbl ); // lwz r0, 0(&fcr31) - GEN_LWZ(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_LWZ(0, 0, DYNAREG_FCR31); // fcmpu cr0, fs, ft - GEN_FCMPU(ppc, fs, ft, 0); - set_next_dst(ppc); + EMIT_FCMPU(fs, ft, 0); // and r0, r0, 0xff7fffff (clear cond) - GEN_RLWINM(ppc, 0, 0, 0, 9, 7); - set_next_dst(ppc); + EMIT_RLWINM(0, 0, 0, 9, 7); // bge cr0, 2 (past setting cond) - GEN_BGE(ppc, 0, 2, 0, 0); - set_next_dst(ppc); + EMIT_BGE(0, 2, 0, 0); // oris r0, r0, 0x0080 (set cond) - GEN_ORIS(ppc, 0, 0, 0x0080); - set_next_dst(ppc); + EMIT_ORIS(0, 0, 0x0080); // stw r0, 0(&fcr31) - GEN_STW(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_STW(0, 0, DYNAREG_FCR31); return CONVERT_SUCCESS; #endif } static int C_LE_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_C_LE) genCallInterp(mips); return INTERPRETED; @@ -4218,30 +3475,24 @@ static int C_LE_FP(MIPS_instr mips, int dbl){ int ft = mapFPR( MIPS_GET_FT(mips), dbl ); // lwz r0, 0(&fcr31) - GEN_LWZ(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_LWZ(0, 0, DYNAREG_FCR31); // fcmpu cr0, fs, ft - GEN_FCMPU(ppc, fs, ft, 0); - set_next_dst(ppc); + EMIT_FCMPU(fs, ft, 0); // and r0, r0, 0xff7fffff (clear cond) - GEN_RLWINM(ppc, 0, 0, 0, 9, 7); - set_next_dst(ppc); + EMIT_RLWINM(0, 0, 0, 9, 7); // bgt cr0, 2 (past setting cond) - GEN_BGT(ppc, 0, 2, 0, 0); - set_next_dst(ppc); + EMIT_BGT(0, 2, 0, 0); // oris r0, r0, 0x0080 (set cond) - GEN_ORIS(ppc, 0, 0, 0x0080); - set_next_dst(ppc); + EMIT_ORIS(0, 0, 0x0080); // stw r0, 0(&fcr31) - GEN_STW(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_STW(0, 0, DYNAREG_FCR31); return CONVERT_SUCCESS; #endif } static int C_NGT_FP(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + #if defined(INTERPRET_FP) || defined(INTERPRET_FP_C_NGT) genCallInterp(mips); return INTERPRETED; @@ -4253,23 +3504,17 @@ static int C_NGT_FP(MIPS_instr mips, int dbl){ int ft = mapFPR( MIPS_GET_FT(mips), dbl ); // lwz r0, 0(&fcr31) - GEN_LWZ(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_LWZ(0, 0, DYNAREG_FCR31); // fcmpu cr0, fs, ft - GEN_FCMPU(ppc, fs, ft, 0); - set_next_dst(ppc); + EMIT_FCMPU(fs, ft, 0); // and r0, r0, 0xff7fffff (clear cond) - GEN_RLWINM(ppc, 0, 0, 0, 9, 7); - set_next_dst(ppc); + EMIT_RLWINM(0, 0, 0, 9, 7); // bgt cr0, 2 (past setting cond) - GEN_BGT(ppc, 0, 2, 0, 0); - set_next_dst(ppc); + EMIT_BGT(0, 2, 0, 0); // oris r0, r0, 0x0080 (set cond) - GEN_ORIS(ppc, 0, 0, 0x0080); - set_next_dst(ppc); + EMIT_ORIS(0, 0, 0x0080); // stw r0, 0(&fcr31) - GEN_STW(ppc, 0, 0, DYNAREG_FCR31); - set_next_dst(ppc); + EMIT_STW(0, 0, DYNAREG_FCR31); return CONVERT_SUCCESS; #endif @@ -4306,7 +3551,7 @@ static int D(MIPS_instr mips){ } static int CVT_FP_W(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + genCheckFP(); @@ -4317,39 +3562,28 @@ static int CVT_FP_W(MIPS_instr mips, int dbl){ // Get the integer value into a GPR // tmp = fpr32[fs] - GEN_LWZ(ppc, tmp, fs*4, DYNAREG_FPR_32); - set_next_dst(ppc); + EMIT_LWZ(tmp, fs*4, DYNAREG_FPR_32); // tmp = *tmp (src) - GEN_LWZ(ppc, tmp, 0, tmp); - set_next_dst(ppc); + EMIT_LWZ(tmp, 0, tmp); // lis r0, 0x4330 - GEN_LIS(ppc, 0, 0x4330); - set_next_dst(ppc); + EMIT_LIS(0, 0x4330); // stw r0, -8(r1) - GEN_STW(ppc, 0, -8, 1); - set_next_dst(ppc); + EMIT_STW(0, -8, 1); // lis r0, 0x8000 - GEN_LIS(ppc, 0, 0x8000); - set_next_dst(ppc); + EMIT_LIS(0, 0x8000); // stw r0, -4(r1) - GEN_STW(ppc, 0, -4, 1); - set_next_dst(ppc); + EMIT_STW(0, -4, 1); // xor r0, src, 0x80000000 - GEN_XOR(ppc, 0, tmp, 0); - set_next_dst(ppc); + EMIT_XOR(0, tmp, 0); // lfd f0, -8(r1) - GEN_LFD(ppc, 0, -8, 1); - set_next_dst(ppc); + EMIT_LFD(0, -8, 1); // stw r0 -4(r1) - GEN_STW(ppc, 0, -4, 1); - set_next_dst(ppc); + EMIT_STW(0, -4, 1); // lfd fd, -8(r1) - GEN_LFD(ppc, fd, -8, 1); - set_next_dst(ppc); + EMIT_LFD(fd, -8, 1); // fsub fd, fd, f0 - GEN_FSUB(ppc, fd, fd, 0, dbl); - set_next_dst(ppc); + EMIT_FSUB(fd, fd, 0, dbl); unmapRegisterTemp(tmp); @@ -4371,7 +3605,7 @@ static int W(MIPS_instr mips){ } static int CVT_FP_L(MIPS_instr mips, int dbl){ - PowerPC_instr ppc; + genCheckFP(); @@ -4383,25 +3617,26 @@ static int CVT_FP_L(MIPS_instr mips, int dbl){ // Get the long value into GPRs // lo = fpr64[fs] - GEN_LWZ(ppc, lo, fs*4, DYNAREG_FPR_64); - set_next_dst(ppc); + EMIT_LWZ(lo, fs*4, DYNAREG_FPR_64); // hi = *lo (hi word) - GEN_LWZ(ppc, hi, 0, lo); - set_next_dst(ppc); + EMIT_LWZ(hi, 0, lo); // lo = *(lo+4) (lo word) - GEN_LWZ(ppc, lo, 4, lo); - set_next_dst(ppc); + EMIT_LWZ(lo, 4, lo); // convert - GEN_B(ppc, add_jump(dbl ? &__floatdidf : &__floatdisf, 1, 1), 0, 1); - set_next_dst(ppc); +#if 1 + EMIT_B(add_jump(dbl ? &__floatdidf : &__floatdisf, 1, 1), 0, 1); +#else + EMIT_LIS(12, ((unsigned int)(dbl ? &__floatdidf : &__floatdisf))>>16); + EMIT_ORI(12, 12, (unsigned int)(dbl ? &__floatdidf : &__floatdisf)); + EMIT_MTCTR(12); + EMIT_BCTRL(ppc); +#endif // Load old LR - GEN_LWZ(ppc, 0, DYNAOFF_LR, 1); - set_next_dst(ppc); + EMIT_LWZ(0, DYNAOFF_LR, 1); // Restore LR - GEN_MTLR(ppc, 0); - set_next_dst(ppc); + EMIT_MTLR(0); unmapRegisterTemp(hi); unmapRegisterTemp(lo); @@ -4454,39 +3689,34 @@ static void genCallInterp(MIPS_instr mips){ flushRegisters(); reset_code_addr(); // Pass in whether this instruction is in the delay slot - GEN_LI(ppc, 5, 0, isDelaySlot ? 1 : 0); - set_next_dst(ppc); + EMIT_LI(5, isDelaySlot ? 1 : 0); // Move the address of decodeNInterpret to ctr for a bctr - //GEN_MTCTR(ppc, DYNAREG_INTERP); - //set_next_dst(ppc); + //EMIT_MTCTR(DYNAREG_INTERP); // Load our argument into r3 (mips) - GEN_LIS(ppc, 3, mips>>16); - set_next_dst(ppc); + EMIT_LIS(3, mips>>16); // Load the current PC as the second arg - GEN_LIS(ppc, 4, get_src_pc()>>16); - set_next_dst(ppc); + EMIT_LIS(4, get_src_pc()>>16); // Load the lower halves of mips and PC - GEN_ORI(ppc, 3, 3, mips); - set_next_dst(ppc); - GEN_ORI(ppc, 4, 4, get_src_pc()); - set_next_dst(ppc); + EMIT_ORI(3, 3, mips); + EMIT_ORI(4, 4, get_src_pc()); // Branch to decodeNInterpret - //GEN_BCTRL(ppc); - GEN_B(ppc, add_jump(&decodeNInterpret, 1, 1), 0, 1); - set_next_dst(ppc); +#if 1 + EMIT_B(add_jump(&decodeNInterpret, 1, 1), 0, 1); +#else + EMIT_LIS(12, ((unsigned int)&decodeNInterpret)>>16); + EMIT_ORI(12, 12, (unsigned int)&decodeNInterpret); + EMIT_MTCTR(12); + EMIT_BCTRL(ppc); +#endif // Load the old LR - GEN_LWZ(ppc, 0, DYNAOFF_LR, 1); - set_next_dst(ppc); + EMIT_LWZ(0, DYNAOFF_LR, 1); // Check if the PC changed - GEN_CMPI(ppc, 3, 0, 6); - set_next_dst(ppc); + EMIT_CMPI(3, 0, 6); // Restore the LR - GEN_MTLR(ppc, 0); - set_next_dst(ppc); + EMIT_MTLR(0); // if decodeNInterpret returned an address // jumpTo it - GEN_BNELR(ppc, 6, 0); - set_next_dst(ppc); + EMIT_BNELR(6, 0); if(mips_is_jump(mips)) delaySlotNext = 2; } @@ -4496,43 +3726,43 @@ static void genJumpTo(unsigned int loc, unsigned int type){ if(type == JUMPTO_REG){ // Load the register as the return value - GEN_LWZ(ppc, 3, loc*8+4, DYNAREG_REG); - set_next_dst(ppc); + EMIT_LWZ(3, loc*8+4, DYNAREG_REG); } else { // Calculate the destination address loc <<= 2; if(type == JUMPTO_OFF) loc += get_src_pc(); else loc |= get_src_pc() & 0xf0000000; // Create space to load destination func* - GEN_ORI(ppc, 0, 0, 0); - set_next_dst(ppc); - set_next_dst(ppc); + EMIT_ORI(0, 0, 0); + EMIT_ORI(0, 0, 0); // Move func* into r3 as argument - GEN_ADDI(ppc, 3, DYNAREG_FUNC, 0); - set_next_dst(ppc); + EMIT_ADDI(3, DYNAREG_FUNC, 0); // Call RecompCache_Update(func) - GEN_B(ppc, add_jump(&RecompCache_Update, 1, 1), 0, 1); - set_next_dst(ppc); +#if 1 + EMIT_B(add_jump(RecompCache_Update, 1, 1), 0, 1); +#else + EMIT_LIS(12, ((unsigned int)&RecompCache_Update)>>16); + EMIT_ORI(12, 12, (unsigned int)&RecompCache_Update); + EMIT_MTCTR(12); + EMIT_BCTRL(ppc); +#endif // Restore LR - GEN_LWZ(ppc, 0, DYNAOFF_LR, 1); - set_next_dst(ppc); - GEN_MTLR(ppc, 0); - set_next_dst(ppc); + EMIT_LWZ(0, DYNAOFF_LR, 1); + EMIT_MTLR(0); // Load the address as the return value - GEN_LIS(ppc, 3, loc >> 16); - set_next_dst(ppc); - GEN_ORI(ppc, 3, 3, loc); - set_next_dst(ppc); + EMIT_LIS(3, loc >> 16); + EMIT_ORI(3, 3, loc); // Since we could be linking, return on interrupt - GEN_BLELR(ppc, 2, 0); - set_next_dst(ppc); + EMIT_BLELR(2, 0); // Store last_addr for linking - GEN_STW(ppc, 3, 0, DYNAREG_LADDR); - set_next_dst(ppc); + EMIT_STW(3, 0, DYNAREG_LADDR); } - GEN_BLR(ppc, (type != JUMPTO_REG)); - set_next_dst(ppc); + EMIT_BLR((type != JUMPTO_REG)); + //TODO See why + EMIT_ORI(0, 0, 0); + EMIT_ORI(0, 0, 0); + EMIT_ORI(0, 0, 0); } // Updates Count, and sets cr2 to (next_interupt ? Count) @@ -4542,106 +3772,92 @@ static void genUpdateCount(int checkCount){ // Dynarec inlined code equivalent: int tmp = mapRegisterTemp(); // lis tmp, pc >> 16 - GEN_LIS(ppc, tmp, (get_src_pc()+4)>>16); - set_next_dst(ppc); + EMIT_LIS(tmp, (get_src_pc()+4)>>16); // lwz r0, 0(&last_addr) // r0 = last_addr - GEN_LWZ(ppc, 0, 0, DYNAREG_LADDR); - set_next_dst(ppc); + EMIT_LWZ(0, 0, DYNAREG_LADDR); // ori tmp, tmp, pc & 0xffff // tmp = pc - GEN_ORI(ppc, tmp, tmp, get_src_pc()+4); - set_next_dst(ppc); + EMIT_ORI(tmp, tmp, get_src_pc()+4); // stw tmp, 0(&last_addr) // last_addr = pc - GEN_STW(ppc, tmp, 0, DYNAREG_LADDR); - set_next_dst(ppc); + EMIT_STW(tmp, 0, DYNAREG_LADDR); // subf r0, r0, tmp // r0 = pc - last_addr - GEN_SUBF(ppc, 0, 0, tmp); - set_next_dst(ppc); + EMIT_SUBF(0, 0, tmp); // lwz tmp, 9*4(reg_cop0) // tmp = Count - GEN_LWZ(ppc, tmp, 9*4, DYNAREG_COP0); - set_next_dst(ppc); + EMIT_LWZ(tmp, 9*4, DYNAREG_COP0); // srwi r0, r0, 1 // r0 = (pc - last_addr)/2 - GEN_SRWI(ppc, 0, 0, 1); - set_next_dst(ppc); + EMIT_SRWI(0, 0, 1); // add r0, r0, tmp // r0 += Count - GEN_ADD(ppc, 0, 0, tmp); - set_next_dst(ppc); + EMIT_ADD(0, 0, tmp); if(checkCount){ // lwz tmp, 0(&next_interupt) // tmp = next_interupt - GEN_LWZ(ppc, tmp, 0, DYNAREG_NINTR); - set_next_dst(ppc); + EMIT_LWZ(tmp, 0, DYNAREG_NINTR); } // stw r0, 9*4(reg_cop0) // Count = r0 - GEN_STW(ppc, 0, 9*4, DYNAREG_COP0); - set_next_dst(ppc); + EMIT_STW(0, 9*4, DYNAREG_COP0); if(checkCount){ // cmpl cr2, tmp, r0 // cr2 = next_interupt ? Count - GEN_CMPL(ppc, tmp, 0, 2); - set_next_dst(ppc); + EMIT_CMPL(tmp, 0, 2); } // Free tmp register unmapRegisterTemp(tmp); #else // Load the current PC as the argument - GEN_LIS(ppc, 3, (get_src_pc()+4)>>16); - set_next_dst(ppc); - GEN_ORI(ppc, 3, 3, get_src_pc()+4); - set_next_dst(ppc); + EMIT_LIS(3, (get_src_pc()+4)>>16); + EMIT_ORI(3, 3, get_src_pc()+4); // Call dyna_update_count - GEN_B(ppc, add_jump(&dyna_update_count, 1, 1), 0, 1); - set_next_dst(ppc); +#if 1 + EMIT_B(add_jump(&dyna_update_count, 1, 1), 0, 1); +#else + EMIT_LIS(12, ((unsigned int)&dyna_update_count)>>16); + EMIT_ORI(12, 12, (unsigned int)&dyna_update_count); + EMIT_MTCTR(12); + EMIT_BCTRL(ppc); +#endif // Load the lr - GEN_LWZ(ppc, 0, DYNAOFF_LR, 1); - set_next_dst(ppc); - GEN_MTLR(ppc, 0); - set_next_dst(ppc); + EMIT_LWZ(0, DYNAOFF_LR, 1); + EMIT_MTLR(0); if(checkCount){ // If next_interupt <= Count (cr2) - GEN_CMPI(ppc, 3, 0, 2); - set_next_dst(ppc); + EMIT_CMPI(3, 0, 2); } #endif } // Check whether we need to take a FP unavailable exception static void genCheckFP(void){ - PowerPC_instr ppc; + if(FP_need_check || isDelaySlot){ flushRegisters(); reset_code_addr(); // lwz r0, 12*4(reg_cop0) - GEN_LWZ(ppc, 0, 12*4, DYNAREG_COP0); - set_next_dst(ppc); + EMIT_LWZ(0, 12*4, DYNAREG_COP0); // andis. r0, r0, 0x2000 - GEN_ANDIS(ppc, 0, 0, 0x2000); - set_next_dst(ppc); + EMIT_ANDIS(0, 0, 0x2000); // bne cr0, end - GEN_BNE(ppc, 0, 8, 0, 0); - set_next_dst(ppc); + EMIT_BNE(0, 8, 0, 0); +// EMIT_BNE(0, 11, 0, 0); // Move &dyna_check_cop1_unusable to ctr for call - //GEN_MTCTR(ppc, DYNAREG_CHKFP); - //set_next_dst(ppc); + //EMIT_MTCTR(DYNAREG_CHKFP); // Load the current PC as arg 1 (upper half) - GEN_LIS(ppc, 3, get_src_pc()>>16); - set_next_dst(ppc); + EMIT_LIS(3, get_src_pc()>>16); // Pass in whether this instruction is in the delay slot as arg 2 - GEN_LI(ppc, 4, 0, isDelaySlot ? 1 : 0); - set_next_dst(ppc); + EMIT_LI(4, isDelaySlot ? 1 : 0); // Current PC (lower half) - GEN_ORI(ppc, 3, 3, get_src_pc()); - set_next_dst(ppc); + EMIT_ORI(3, 3, get_src_pc()); // Call dyna_check_cop1_unusable - //GEN_BCTRL(ppc); - GEN_B(ppc, add_jump(&dyna_check_cop1_unusable, 1, 1), 0, 1); - set_next_dst(ppc); +#if 1 + EMIT_B(add_jump(&dyna_check_cop1_unusable, 1, 1), 0, 1); +#else + EMIT_LIS(12, ((unsigned int)&dyna_check_cop1_unusable)>>16); + EMIT_ORI(12, 12, (unsigned int)&dyna_check_cop1_unusable); + EMIT_MTCTR(12); + EMIT_BCTRL(ppc); +#endif // Load the old LR - GEN_LWZ(ppc, 0, DYNAOFF_LR, 1); - set_next_dst(ppc); + EMIT_LWZ(0, DYNAOFF_LR, 1); // Restore the LR - GEN_MTLR(ppc, 0); - set_next_dst(ppc); + EMIT_MTLR(0); // Return to trampoline - GEN_BLR(ppc, 0); - set_next_dst(ppc); + EMIT_BLR(0); // Don't check for the rest of this mapping // Unless this instruction is in a delay slot FP_need_check = isDelaySlot; @@ -4649,38 +3865,140 @@ static void genCheckFP(void){ } void genCallDynaMem(memType type, int base, short immed){ - PowerPC_instr ppc; + // PRE: value to store, or register # to load into should be in r3 // Pass PC as arg 4 (upper half) - GEN_LIS(ppc, 6, (get_src_pc()+4)>>16); - set_next_dst(ppc); + EMIT_LIS(6, (get_src_pc()+4)>>16); // addr = base + immed (arg 2) - GEN_ADDI(ppc, 4, base, immed); - set_next_dst(ppc); + EMIT_ADDI(4, base, immed); // type passed as arg 3 - GEN_LI(ppc, 5, 0, type); - set_next_dst(ppc); + EMIT_LI(5, type); // Lower half of PC - GEN_ORI(ppc, 6, 6, get_src_pc()+4); - set_next_dst(ppc); + EMIT_ORI(6, 6, get_src_pc()+4); // isDelaySlot as arg 5 - GEN_LI(ppc, 7, 0, isDelaySlot ? 1 : 0); - set_next_dst(ppc); + EMIT_LI(7, isDelaySlot ? 1 : 0); // call dyna_mem - GEN_B(ppc, add_jump(&dyna_mem, 1, 1), 0, 1); - set_next_dst(ppc); +#if 1 + EMIT_B(add_jump(&dyna_mem, 1, 1), 0, 1); +#else + EMIT_LIS(12, ((unsigned int)&dyna_mem)>>16); + EMIT_ORI(12, 12, (unsigned int)&dyna_mem); + EMIT_MTCTR(12); + EMIT_BCTRL(ppc); +#endif // Load old LR - GEN_LWZ(ppc, 0, DYNAOFF_LR, 1); - set_next_dst(ppc); + EMIT_LWZ(0, DYNAOFF_LR, 1); // Check whether we need to take an interrupt - GEN_CMPI(ppc, 3, 0, 6); - set_next_dst(ppc); + EMIT_CMPI(3, 0, 6); // Restore LR - GEN_MTLR(ppc, 0); - set_next_dst(ppc); + EMIT_MTLR(0); // If so, return to trampoline - GEN_BNELR(ppc, 6, 0); - set_next_dst(ppc); + EMIT_BNELR(6, 0); +} + +static int genCallDynaMemVM(int rs_reg, int rt_reg, memType type, int immed){ + + flushRegisters(); + reset_code_addr(); + + int rd = mapRegisterTemp(); // r3 = rd + int base = mapRegister( rs_reg ); // r4 = addr + flushRegisters(); + + // If base in physical memory +#ifdef USE_EXPANSION + EMIT_LIS(0, 0x8080); +#else + EMIT_LIS(0, 0x8040); +#endif + EMIT_CMP(base, 0, 1); + + int to_slow_id = add_jump_special(0); + EMIT_BGE(1, to_slow_id, 0, 0); + PowerPC_instr* ts_preCall = get_curr_dst(); + + // Use rdram +#ifdef USE_EXPANSION + // Mask sp with 0x007FFFFF + EMIT_RLWINM(base, base, 0, 9, 31); +#else + // Mask sp with 0x003FFFFF + EMIT_RLWINM(base, base, 0, 10, 31); +#endif + // Add rdram pointer + EMIT_ADD(base, DYNAREG_RDRAM, base); + +/* EMIT_LIS(0,0x4000); + EMIT_RLWIMI(base,0,0,1);*/ + + // Perform the actual load + switch (type) + { + case MEM_LB: + EMIT_LBZ(3, immed, base); + EMIT_EXTSB(3,3); + mapRegisterNew( rt_reg ); + break; + case MEM_LBU: + EMIT_LBZ(3, immed, base); + mapRegisterNew( rt_reg ); + break; + case MEM_LH: + EMIT_LHA(3, immed, base); + mapRegisterNew( rt_reg ); + break; + case MEM_LHU: + EMIT_LHZ(3, immed, base) + mapRegisterNew( rt_reg ); + break; + case MEM_LW: + EMIT_LWZ(3, immed, base); + mapRegisterNew( rt_reg ); + break; + case MEM_LWU: + { + // Create a mapping for this value + RegMapping value = mapRegister64New( rt_reg ); + // Perform the actual load + EMIT_LWZ(value.lo, immed, base); + // Zero out the upper word + EMIT_LI(value.hi, 0); + break; + } + case MEM_LD: + { + // Create a mapping for this value + RegMapping value = mapRegister64New( rt_reg ); + // Perform the actual load + EMIT_LWZ(value.lo, immed+4, base); + EMIT_LWZ(value.hi, immed, base); + break; + } + default: + assert(0); + } + + flushRegisters(); + + // Skip over else + int not_fastmem_id = add_jump_special(1); + EMIT_B(not_fastmem_id, 0, 0); + PowerPC_instr* preCall = get_curr_dst(); + + int ts_callSize = get_curr_dst() - ts_preCall; + set_jump_special(to_slow_id, ts_callSize+1); + + invalidateRegisters(); + + // load into rt + EMIT_LI(3, rt_reg); + + genCallDynaMem(type, base, immed); + + int callSize = get_curr_dst() - preCall; + set_jump_special(not_fastmem_id, callSize+1); + + return CONVERT_SUCCESS; } static int mips_is_jump(MIPS_instr instr){ @@ -4704,4 +4022,3 @@ static int mips_is_jump(MIPS_instr instr){ (opcode == MIPS_OPCODE_COP1 && format == MIPS_FRMT_BC) ); } - diff --git a/r4300/ppc/PowerPC.h b/r4300/ppc/PowerPC.h index f8155f4..190e99f 100644 --- a/r4300/ppc/PowerPC.h +++ b/r4300/ppc/PowerPC.h @@ -32,6 +32,9 @@ #ifndef POWERPC_H #define POWERPC_H + +#define HA(x) ((x)&0x8000?(x>>16)+1:(x>>16)) + // type definitions typedef unsigned int PowerPC_instr; @@ -391,6 +394,17 @@ PowerPC_instr Instruction(int opcode, ...); #define PPC_FUNC_XOR 316 +// condition flags + +#define PPC_CC_T 0xc +#define PPC_CC_F 0x4 +#define PPC_CC_A 0x14 + +#define PPC_CC_NEG 0 +#define PPC_CC_POS 1 +#define PPC_CC_ZER 2 +#define PPC_CC_OVR 3 + // Registers #define R0 0 #define R1 1 @@ -460,13 +474,15 @@ PowerPC_instr Instruction(int opcode, ...); #define GEN_LIS(ppc,rd,immed) \ GEN_ADDIS(ppc,rd,0,immed) -#define GEN_LI(ppc,rd,rs,immed) \ +#define GEN_LI(ppc,rd,immed) \ { ppc = NEW_PPC_INSTR(); \ PPC_SET_OPCODE(ppc, PPC_OPCODE_ADDI); \ PPC_SET_RD (ppc, (rd)); \ - PPC_SET_RA (ppc, (rs)); \ + PPC_SET_RA (ppc, 0); \ PPC_SET_IMMED (ppc, (immed)); } +#define GEN_LI2(ppc,rd,ra,immed) GEN_LI(ppc,rd,immed) + #define GEN_LWZ(ppc,rd,immed,ra) \ { ppc = NEW_PPC_INSTR(); \ PPC_SET_OPCODE(ppc, PPC_OPCODE_LWZ); \ @@ -509,6 +525,13 @@ PowerPC_instr Instruction(int opcode, ...); PPC_SET_RA (ppc, (rd)); \ PPC_SET_RD (ppc, (rs)); } +#define GEN_EXTSW(ppc,rd,rs) \ + { ppc = NEW_PPC_INSTR(); \ + PPC_SET_OPCODE(ppc, PPC_OPCODE_X); \ + PPC_SET_FUNC (ppc, PPC_FUNC_EXTSW); \ + PPC_SET_RA (ppc, (rd)); \ + PPC_SET_RD (ppc, (rs)); } + #define GEN_STB(ppc,rs,immed,ra) \ { ppc = NEW_PPC_INSTR(); \ PPC_SET_OPCODE(ppc, PPC_OPCODE_STB); \ @@ -543,6 +566,14 @@ PowerPC_instr Instruction(int opcode, ...); PPC_SET_LK (ppc, 1); \ PPC_SET_BO (ppc, 0x14); } +#define GEN_BCCTR(ppc,bo,bi,lk) \ + { ppc = NEW_PPC_INSTR(); \ + PPC_SET_OPCODE(ppc, PPC_OPCODE_XL); \ + PPC_SET_FUNC (ppc, PPC_FUNC_BCCTR); \ + PPC_SET_LK (ppc, lk); \ + PPC_SET_BO (ppc, bo); \ + PPC_SET_BI (ppc, bi); } + #define GEN_CMP(ppc,ra,rb,cr) \ { ppc = NEW_PPC_INSTR(); \ PPC_SET_OPCODE(ppc, PPC_OPCODE_X); \ @@ -634,6 +665,15 @@ PowerPC_instr Instruction(int opcode, ...); PPC_SET_MB (ppc, (mb)); \ PPC_SET_ME (ppc, (me)); } +#define GEN_RLWIMI(ppc,rd,ra,sh,mb,me) \ + { ppc = NEW_PPC_INSTR(); \ + PPC_SET_OPCODE(ppc, PPC_OPCODE_RLWIMI); \ + PPC_SET_RA (ppc, (rd)); \ + PPC_SET_RD (ppc, (ra)); \ + PPC_SET_SH (ppc, (sh)); \ + PPC_SET_MB (ppc, (mb)); \ + PPC_SET_ME (ppc, (me)); } + #define GEN_SRWI(ppc,rd,ra,sh) \ GEN_RLWINM(ppc, rd, ra, 32-sh, sh, 31) @@ -693,6 +733,13 @@ PowerPC_instr Instruction(int opcode, ...); PPC_SET_RD (ppc, (ra)); \ PPC_SET_IMMED (ppc, (immed)); } +#define GEN_XORIS(ppc,rd,ra,immed) \ + { ppc = NEW_PPC_INSTR(); \ + PPC_SET_OPCODE(ppc, PPC_OPCODE_XORIS); \ + PPC_SET_RA (ppc, (rd)); \ + PPC_SET_RD (ppc, (ra)); \ + PPC_SET_IMMED (ppc, (immed)); } + #define GEN_MULLW(ppc,rd,ra,rb) \ { ppc = NEW_PPC_INSTR(); \ PPC_SET_OPCODE(ppc, PPC_OPCODE_X); \ @@ -783,6 +830,22 @@ PowerPC_instr Instruction(int opcode, ...); PPC_SET_RD (ppc, (ra)); \ PPC_SET_RB (ppc, (rb)); } +#define GEN_NAND(ppc,rd,ra,rb) \ + { ppc = NEW_PPC_INSTR(); \ + PPC_SET_OPCODE(ppc, PPC_OPCODE_X); \ + PPC_SET_FUNC (ppc, PPC_FUNC_NAND); \ + PPC_SET_RA (ppc, (rd)); \ + PPC_SET_RD (ppc, (ra)); \ + PPC_SET_RB (ppc, (rb)); } + +#define GEN_ANDC(ppc,rd,ra,rb) \ + { ppc = NEW_PPC_INSTR(); \ + PPC_SET_OPCODE(ppc, PPC_OPCODE_X); \ + PPC_SET_FUNC (ppc, PPC_FUNC_ANDC); \ + PPC_SET_RA (ppc, (rd)); \ + PPC_SET_RD (ppc, (ra)); \ + PPC_SET_RB (ppc, (rb)); } + #define GEN_NOR(ppc,rd,ra,rb) \ { ppc = NEW_PPC_INSTR(); \ PPC_SET_OPCODE(ppc, PPC_OPCODE_X); \ @@ -947,6 +1010,20 @@ PowerPC_instr Instruction(int opcode, ...); PPC_SET_RD (ppc, (fd)); \ PPC_SET_RB (ppc, (fs)); } +#define GEN_FCFID(ppc,fd,fs) \ + { ppc = NEW_PPC_INSTR(); \ + PPC_SET_OPCODE(ppc, PPC_OPCODE_FPD); \ + PPC_SET_FUNC (ppc, PPC_FUNC_FCFID); \ + PPC_SET_RD (ppc, (fd)); \ + PPC_SET_RB (ppc, (fs)); } + +#define GEN_FRSP(ppc,fd,fs) \ + { ppc = NEW_PPC_INSTR(); \ + PPC_SET_OPCODE(ppc, PPC_OPCODE_FPD); \ + PPC_SET_FUNC (ppc, PPC_FUNC_FRSP); \ + PPC_SET_RD (ppc, (fd)); \ + PPC_SET_RB (ppc, (fs)); } + #define GEN_FMR(ppc,fd,fs) \ { ppc = NEW_PPC_INSTR(); \ PPC_SET_OPCODE(ppc, PPC_OPCODE_FPD); \ @@ -1012,6 +1089,20 @@ PowerPC_instr Instruction(int opcode, ...); PPC_SET_RD (ppc, (fd)); \ PPC_SET_RB (ppc, (fs)); } +#define GEN_FSQRT(ppc,fd,fs) \ + { ppc = NEW_PPC_INSTR(); \ + PPC_SET_OPCODE(ppc, PPC_OPCODE_FPD); \ + PPC_SET_FUNC (ppc, PPC_FUNC_FSQRT); \ + PPC_SET_RD (ppc, (fd)); \ + PPC_SET_RB (ppc, (fs)); } + +#define GEN_FSQRTS(ppc,fd,fs) \ + { ppc = NEW_PPC_INSTR(); \ + PPC_SET_OPCODE(ppc, PPC_OPCODE_FPS); \ + PPC_SET_FUNC (ppc, PPC_FUNC_FSQRT); \ + PPC_SET_RD (ppc, (fd)); \ + PPC_SET_RB (ppc, (fs)); } + #define GEN_FSEL(ppc,fd,fa,fb,fc) \ { ppc = NEW_PPC_INSTR(); \ PPC_SET_OPCODE(ppc, PPC_OPCODE_FPD); \ @@ -1028,14 +1119,41 @@ PowerPC_instr Instruction(int opcode, ...); PPC_SET_RD (ppc, (fd)); \ PPC_SET_RB (ppc, (fs)); } -#define GEN_FNMSUB(ppc,fd,fa,fb,fc) \ +#define GEN_FNMSUB(ppc,fd,fa,fc,fb) \ { ppc = NEW_PPC_INSTR(); \ PPC_SET_OPCODE(ppc, PPC_OPCODE_FPD); \ PPC_SET_FUNC (ppc, PPC_FUNC_FNMSUB); \ PPC_SET_RD (ppc, (fd)); \ PPC_SET_RA (ppc, (fa)); \ - PPC_SET_RB (ppc, (fc)); \ - PPC_SET_RC (ppc, (fb)); } + PPC_SET_RB (ppc, (fb)); \ + PPC_SET_RC (ppc, (fc)); } + +#define GEN_FNMSUBS(ppc,fd,fa,fc,fb) \ + { ppc = NEW_PPC_INSTR(); \ + PPC_SET_OPCODE(ppc, PPC_OPCODE_FPS); \ + PPC_SET_FUNC (ppc, PPC_FUNC_FNMSUB); \ + PPC_SET_RD (ppc, (fd)); \ + PPC_SET_RA (ppc, (fa)); \ + PPC_SET_RB (ppc, (fb)); \ + PPC_SET_RC (ppc, (fc)); } + +#define GEN_FMADD(ppc,fd,fa,fc,fb) \ + { ppc = NEW_PPC_INSTR(); \ + PPC_SET_OPCODE(ppc, PPC_OPCODE_FPD); \ + PPC_SET_FUNC (ppc, PPC_FUNC_FMADD); \ + PPC_SET_RD (ppc, (fd)); \ + PPC_SET_RA (ppc, (fa)); \ + PPC_SET_RB (ppc, (fb)); \ + PPC_SET_RC (ppc, (fc)); } + +#define GEN_FMADDS(ppc,fd,fa,fc,fb) \ + { ppc = NEW_PPC_INSTR(); \ + PPC_SET_OPCODE(ppc, PPC_OPCODE_FPS); \ + PPC_SET_FUNC (ppc, PPC_FUNC_FMADD); \ + PPC_SET_RD (ppc, (fd)); \ + PPC_SET_RA (ppc, (fa)); \ + PPC_SET_RB (ppc, (fb)); \ + PPC_SET_RC (ppc, (fc)); } #define GEN_BCLR(ppc,lk,bo,bi) \ { ppc = NEW_PPC_INSTR(); \ @@ -1079,4 +1197,24 @@ PowerPC_instr Instruction(int opcode, ...); PPC_SET_RA (ppc, (ca)); \ PPC_SET_RB (ppc, (cb)); } -#endif +#define GEN_CRNOR(ppc,cd,ca,cb) \ + { ppc = NEW_PPC_INSTR(); \ + PPC_SET_OPCODE(ppc, PPC_OPCODE_XL); \ + PPC_SET_FUNC (ppc, PPC_FUNC_CRNOR); \ + PPC_SET_RD (ppc, (cd)); \ + PPC_SET_RA (ppc, (ca)); \ + PPC_SET_RB (ppc, (cb)); } + +#define GEN_MFCR(ppc,rt) \ + { ppc = NEW_PPC_INSTR(); \ + PPC_SET_OPCODE(ppc, PPC_OPCODE_X); \ + PPC_SET_FUNC (ppc, PPC_FUNC_MFCR); \ + PPC_SET_RD (ppc, (rt)); } + +#define GEN_MCRXR(ppc,bf) \ + { ppc = NEW_PPC_INSTR(); \ + PPC_SET_OPCODE(ppc, PPC_OPCODE_X); \ + PPC_SET_FUNC (ppc, PPC_FUNC_MCRXR); \ + PPC_SET_CRF (ppc, (bf)); } + +#endif \ No newline at end of file diff --git a/r4300/ppc/Recompile.c b/r4300/ppc/Recompile.c index 489e999..1856446 100644 --- a/r4300/ppc/Recompile.c +++ b/r4300/ppc/Recompile.c @@ -86,7 +86,11 @@ int has_next_src(void){ return (src_last-src) > 0; } int is_j_dst(void){ return isJmpDst[(get_src_pc()&0xfff)>>2]; } // Returns the MIPS PC unsigned int get_src_pc(void){ return addr_first + ((src-1-src_first)<<2); } + void set_next_dst(PowerPC_instr i){ *(dst++) = i; ++code_length; } +void dbg_dst(int line,const char * func){printf("####### %p %s %d\n",dst,func,line);} + + // Adjusts the code_addr for the current instruction to account for flushes void reset_code_addr(void){ if(src<=src_last) code_addr[src-1-src_first] = dst; } @@ -553,28 +557,19 @@ void dyna_stop(){ } void jump_to_func(){ jump_to(jump_to_address); } static void genJumpPad(void){ - PowerPC_instr ppc = NEW_PPC_INSTR(); - // noCheckInterrupt = 1 - GEN_LIS(ppc, 3, (unsigned int)(&noCheckInterrupt)>>16); - set_next_dst(ppc); - GEN_ORI(ppc, 3, 3, (unsigned int)(&noCheckInterrupt)); - set_next_dst(ppc); - GEN_LI(ppc, 0, 0, 1); - set_next_dst(ppc); - GEN_STW(ppc, 0, 0, 3); - set_next_dst(ppc); + EMIT_LIS(3, (unsigned int)(&noCheckInterrupt)>>16); + EMIT_ORI(3, 3, (unsigned int)(&noCheckInterrupt)); + EMIT_LI(0, 1); + EMIT_STW(0, 0, 3); // Set the next address to the first address in the next block if // we've really reached the end of the block, not jumped to the pad - GEN_LIS(ppc, 3, (get_src_pc()+4)>>16); - set_next_dst(ppc); - GEN_ORI(ppc, 3, 3, get_src_pc()+4); - set_next_dst(ppc); + EMIT_LIS(3, (get_src_pc()+4)>>16); + EMIT_ORI(3, 3, get_src_pc()+4); // return destination - GEN_BLR(ppc,0); - set_next_dst(ppc); + EMIT_BLR(0); } void invalidate_block(PowerPC_block* ppc_block){ @@ -607,4 +602,4 @@ void clear_freed_funcs(void){ free(node); } freed_funcs = NULL; -} +} \ No newline at end of file diff --git a/r4300/ppc/Recompile.h b/r4300/ppc/Recompile.h index 174ac1e..aa656ca 100644 --- a/r4300/ppc/Recompile.h +++ b/r4300/ppc/Recompile.h @@ -113,5 +113,227 @@ extern PowerPC_block *blocks[0x100000]; #endif #endif +#define EMIT_B(dst,aa,lk) \ +{PowerPC_instr ppc;GEN_B(ppc,dst,aa,lk);set_next_dst(ppc);} +#define EMIT_MTCTR(rs) \ +{PowerPC_instr ppc;GEN_MTCTR(ppc,rs);set_next_dst(ppc);} +#define EMIT_MFCTR(rd) \ +{PowerPC_instr ppc;GEN_MFCTR(ppc,rd);set_next_dst(ppc);} +#define EMIT_ADDIS(rd,ra,immed) \ +{PowerPC_instr ppc;GEN_ADDIS(ppc,rd,ra,immed);set_next_dst(ppc);} +#define EMIT_LIS(rd,immed) \ +{PowerPC_instr ppc;GEN_LIS(ppc,rd,immed);set_next_dst(ppc);} +#define EMIT_LI(rd,immed) \ +{PowerPC_instr ppc;GEN_LI(ppc,rd,immed);set_next_dst(ppc);} +#define EMIT_LWZ(rd,immed,ra) \ +{PowerPC_instr ppc;GEN_LWZ(ppc,rd,immed,ra);set_next_dst(ppc);} +#define EMIT_LHZ(rd,immed,ra) \ +{PowerPC_instr ppc;GEN_LHZ(ppc,rd,immed,ra);set_next_dst(ppc);} +#define EMIT_LHA(rd,immed,ra) \ +{PowerPC_instr ppc;GEN_LHA(ppc,rd,immed,ra);set_next_dst(ppc);} +#define EMIT_LBZ(rd,immed,ra) \ +{PowerPC_instr ppc;GEN_LBZ(ppc,rd,immed,ra);set_next_dst(ppc);} +#define EMIT_EXTSB(rd,rs) \ +{PowerPC_instr ppc;GEN_EXTSB(ppc,rd,rs);set_next_dst(ppc);} +#define EMIT_EXTSH(rd,rs) \ +{PowerPC_instr ppc;GEN_EXTSH(ppc,rd,rs);set_next_dst(ppc);} +#define EMIT_EXTSW(rd,rs) \ +{PowerPC_instr ppc;GEN_EXTSW(ppc,rd,rs);set_next_dst(ppc);} +#define EMIT_STB(rs,immed,ra) \ +{PowerPC_instr ppc;GEN_STB(ppc,rs,immed,ra);set_next_dst(ppc);} +#define EMIT_STH(rs,immed,ra) \ +{PowerPC_instr ppc;GEN_STH(ppc,rs,immed,ra);set_next_dst(ppc);} +#define EMIT_STW(rs,immed,ra) \ +{PowerPC_instr ppc;GEN_STW(ppc,rs,immed,ra);set_next_dst(ppc);} +#define EMIT_BCTR(ppce) \ +{PowerPC_instr ppc;GEN_BCTR(ppc);set_next_dst(ppc);} +#define EMIT_BCTRL(ppce) \ +{PowerPC_instr ppc;GEN_BCTRL(ppc);set_next_dst(ppc);} +#define EMIT_BCCTR(bo,bi,lk) \ +{PowerPC_instr ppc;GEN_BCCTR(ppc,bo,bi,lk);set_next_dst(ppc);} +#define EMIT_CMP(ra,rb,cr) \ +{PowerPC_instr ppc;GEN_CMP(ppc,ra,rb,cr);set_next_dst(ppc);} +#define EMIT_CMPL(ra,rb,cr) \ +{PowerPC_instr ppc;GEN_CMPL(ppc,ra,rb,cr);set_next_dst(ppc);} +#define EMIT_CMPI(ra,immed,cr) \ +{PowerPC_instr ppc;GEN_CMPI(ppc,ra,immed,cr);set_next_dst(ppc);} +#define EMIT_CMPLI(ra,immed,cr) \ +{PowerPC_instr ppc;GEN_CMPLI(ppc,ra,immed,cr);set_next_dst(ppc);} +#define EMIT_BC(dst,aa,lk,bo,bi) \ +{PowerPC_instr ppc;GEN_BC(ppc,dst,aa,lk,bo,bi);set_next_dst(ppc);} +#define EMIT_BNE(cr,dst,aa,lk) \ +{PowerPC_instr ppc;GEN_BNE(ppc,cr,dst,aa,lk);set_next_dst(ppc);} +#define EMIT_BEQ(cr,dst,aa,lk) \ +{PowerPC_instr ppc;GEN_BEQ(ppc,cr,dst,aa,lk);set_next_dst(ppc);} +#define EMIT_BGT(cr,dst,aa,lk) \ +{PowerPC_instr ppc;GEN_BGT(ppc,cr,dst,aa,lk);set_next_dst(ppc);} +#define EMIT_BLE(cr,dst,aa,lk) \ +{PowerPC_instr ppc;GEN_BLE(ppc,cr,dst,aa,lk);set_next_dst(ppc);} +#define EMIT_BGE(cr,dst,aa,lk) \ +{PowerPC_instr ppc;GEN_BGE(ppc,cr,dst,aa,lk);set_next_dst(ppc);} +#define EMIT_BLT(cr,dst,aa,lk) \ +{PowerPC_instr ppc;GEN_BLT(ppc,cr,dst,aa,lk);set_next_dst(ppc);} +#define EMIT_ADDI(rd,ra,immed) \ +{PowerPC_instr ppc;GEN_ADDI(ppc,rd,ra,immed);set_next_dst(ppc);} +#define EMIT_RLWINM(rd,ra,sh,mb,me) \ +{PowerPC_instr ppc;GEN_RLWINM(ppc,rd,ra,sh,mb,me);set_next_dst(ppc);} +#define EMIT_RLWIMI(rd,ra,sh,mb,me) \ +{PowerPC_instr ppc;GEN_RLWIMI(ppc,rd,ra,sh,mb,me);set_next_dst(ppc);} +#define EMIT_SRWI(rd,ra,sh) \ +{PowerPC_instr ppc;GEN_SRWI(ppc,rd,ra,sh);set_next_dst(ppc);} +#define EMIT_SLWI(rd,ra,sh) \ +{PowerPC_instr ppc;GEN_SLWI(ppc,rd,ra,sh);set_next_dst(ppc);} +#define EMIT_SRAWI(rd,ra,sh) \ +{PowerPC_instr ppc;GEN_SRAWI(ppc,rd,ra,sh);set_next_dst(ppc);} +#define EMIT_SLW(rd,ra,rb) \ +{PowerPC_instr ppc;GEN_SLW(ppc,rd,ra,rb);set_next_dst(ppc);} +#define EMIT_SRW(rd,ra,rb) \ +{PowerPC_instr ppc;GEN_SRW(ppc,rd,ra,rb);set_next_dst(ppc);} +#define EMIT_SRAW(rd,ra,rb) \ +{PowerPC_instr ppc;GEN_SRAW(ppc,rd,ra,rb);set_next_dst(ppc);} +#define EMIT_ANDI(rd,ra,immed) \ +{PowerPC_instr ppc;GEN_ANDI(ppc,rd,ra,immed);set_next_dst(ppc);} +#define EMIT_ORI(rd,ra,immed) \ +{PowerPC_instr ppc;GEN_ORI(ppc,rd,ra,immed);set_next_dst(ppc);} +#define EMIT_XORI(rd,ra,immed) \ +{PowerPC_instr ppc;GEN_XORI(ppc,rd,ra,immed);set_next_dst(ppc);} +#define EMIT_XORIS(rd,ra,immed) \ +{PowerPC_instr ppc;GEN_XORIS(ppc,rd,ra,immed);set_next_dst(ppc);} +#define EMIT_MULLW(rd,ra,rb) \ +{PowerPC_instr ppc;GEN_MULLW(ppc,rd,ra,rb);set_next_dst(ppc);} +#define EMIT_MULHW(rd,ra,rb) \ +{PowerPC_instr ppc;GEN_MULHW(ppc,rd,ra,rb);set_next_dst(ppc);} +#define EMIT_MULHWU(rd,ra,rb) \ +{PowerPC_instr ppc;GEN_MULHWU(ppc,rd,ra,rb);set_next_dst(ppc);} +#define EMIT_DIVW(rd,ra,rb) \ +{PowerPC_instr ppc;GEN_DIVW(ppc,rd,ra,rb);set_next_dst(ppc);} +#define EMIT_DIVWU(rd,ra,rb) \ +{PowerPC_instr ppc;GEN_DIVWU(ppc,rd,ra,rb);set_next_dst(ppc);} +#define EMIT_ADD(rd,ra,rb) \ +{PowerPC_instr ppc;GEN_ADD(ppc,rd,ra,rb);set_next_dst(ppc);} +#define EMIT_SUBF(rd,ra,rb) \ +{PowerPC_instr ppc;GEN_SUBF(ppc,rd,ra,rb);set_next_dst(ppc);} +#define EMIT_SUBFC(rd,ra,rb) \ +{PowerPC_instr ppc;GEN_SUBFC(ppc,rd,ra,rb);set_next_dst(ppc);} +#define EMIT_SUBFE(rd,ra,rb) \ +{PowerPC_instr ppc;GEN_SUBFE(ppc,rd,ra,rb);set_next_dst(ppc);} +#define EMIT_ADDIC(rd,ra,immed) \ +{PowerPC_instr ppc;GEN_ADDIC(ppc,rd,ra,immed);set_next_dst(ppc);} +#define EMIT_SUB(rd,ra,rb) \ +{PowerPC_instr ppc;GEN_SUB(ppc,rd,ra,rb);set_next_dst(ppc);} +#define EMIT_AND(rd,ra,rb) \ +{PowerPC_instr ppc;GEN_AND(ppc,rd,ra,rb);set_next_dst(ppc);} +#define EMIT_NAND(rd,ra,rb) \ +{PowerPC_instr ppc;GEN_NAND(ppc,rd,ra,rb);set_next_dst(ppc);} +#define EMIT_ANDC(rd,ra,rb) \ +{PowerPC_instr ppc;GEN_ANDC(ppc,rd,ra,rb);set_next_dst(ppc);} +#define EMIT_NOR(rd,ra,rb) \ +{PowerPC_instr ppc;GEN_NOR(ppc,rd,ra,rb);set_next_dst(ppc);} +#define EMIT_OR(rd,ra,rb) \ +{PowerPC_instr ppc;GEN_OR(ppc,rd,ra,rb);set_next_dst(ppc);} +#define EMIT_XOR(rd,ra,rb) \ +{PowerPC_instr ppc;GEN_XOR(ppc,rd,ra,rb);set_next_dst(ppc);} +#define EMIT_BLR(lk) \ +{PowerPC_instr ppc;GEN_BLR(ppc,lk);set_next_dst(ppc);} +#define EMIT_MTLR(rs) \ +{PowerPC_instr ppc;GEN_MTLR(ppc,rs);set_next_dst(ppc);} +#define EMIT_MFLR(rd) \ +{PowerPC_instr ppc;GEN_MFLR(ppc,rd);set_next_dst(ppc);} +#define EMIT_MTCR(rs) \ +{PowerPC_instr ppc;GEN_MTCR(ppc,rs);set_next_dst(ppc);} +#define EMIT_NEG(rd,rs) \ +{PowerPC_instr ppc;GEN_NEG(ppc,rd,rs);set_next_dst(ppc);} +#define EMIT_EQV(rd,ra,rb) \ +{PowerPC_instr ppc;GEN_EQV(ppc,rd,ra,rb);set_next_dst(ppc);} +#define EMIT_ADDZE(rd,rs) \ +{PowerPC_instr ppc;GEN_ADDZE(ppc,rd,rs);set_next_dst(ppc);} +#define EMIT_ADDC(rd,ra,rb) \ +{PowerPC_instr ppc;GEN_ADDC(ppc,rd,ra,rb);set_next_dst(ppc);} +#define EMIT_ADDE(rd,ra,rb) \ +{PowerPC_instr ppc;GEN_ADDE(ppc,rd,ra,rb);set_next_dst(ppc);} +#define EMIT_SUBFIC(rd,ra,immed) \ +{PowerPC_instr ppc;GEN_SUBFIC(ppc,rd,ra,immed);set_next_dst(ppc);} +#define EMIT_STFD(fs,immed,rb) \ +{PowerPC_instr ppc;GEN_STFD(ppc,fs,immed,rb);set_next_dst(ppc);} +#define EMIT_STFS(fs,immed,rb) \ +{PowerPC_instr ppc;GEN_STFS(ppc,fs,immed,rb);set_next_dst(ppc);} +#define EMIT_LFD(fd,immed,rb) \ +{PowerPC_instr ppc;GEN_LFD(ppc,fd,immed,rb);set_next_dst(ppc);} +#define EMIT_LFS(fd,immed,rb) \ +{PowerPC_instr ppc;GEN_LFS(ppc,fd,immed,rb);set_next_dst(ppc);} +#define EMIT_FADD(fd,fa,fb,dbl) \ +{PowerPC_instr ppc;GEN_FADD(ppc,fd,fa,fb,dbl);set_next_dst(ppc);} +#define EMIT_FSUB(fd,fa,fb,dbl) \ +{PowerPC_instr ppc;GEN_FSUB(ppc,fd,fa,fb,dbl);set_next_dst(ppc);} +#define EMIT_FMUL(fd,fa,fb,dbl) \ +{PowerPC_instr ppc;GEN_FMUL(ppc,fd,fa,fb,dbl);set_next_dst(ppc);} +#define EMIT_FDIV(fd,fa,fb,dbl) \ +{PowerPC_instr ppc;GEN_FDIV(ppc,fd,fa,fb,dbl);set_next_dst(ppc);} +#define EMIT_FABS(fd,fs) \ +{PowerPC_instr ppc;GEN_FABS(ppc,fd,fs);set_next_dst(ppc);} +#define EMIT_FCFID(fd,fs) \ +{PowerPC_instr ppc;GEN_FCFID(ppc,fd,fs);set_next_dst(ppc);} +#define EMIT_FRSP(fd,fs) \ +{PowerPC_instr ppc;GEN_FRSP(ppc,fd,fs);set_next_dst(ppc);} +#define EMIT_FMR(fd,fs) \ +{PowerPC_instr ppc;GEN_FMR(ppc,fd,fs);set_next_dst(ppc);} +#define EMIT_FNEG(fd,fs) \ +{PowerPC_instr ppc;GEN_FNEG(ppc,fd,fs);set_next_dst(ppc);} +#define EMIT_FCTIW(fd,fs) \ +{PowerPC_instr ppc;GEN_FCTIW(ppc,fd,fs);set_next_dst(ppc);} +#define EMIT_FCTIWZ(fd,fs) \ +{PowerPC_instr ppc;GEN_FCTIWZ(ppc,fd,fs);set_next_dst(ppc);} +#define EMIT_STFIWX(fs,ra,rb) \ +{PowerPC_instr ppc;GEN_STFIWX(ppc,fs,ra,rb);set_next_dst(ppc);} +#define EMIT_MTFSFI(field,immed) \ +{PowerPC_instr ppc;GEN_MTFSFI(ppc,field,immed);set_next_dst(ppc);} +#define EMIT_MTFSF(fields,fs) \ +{PowerPC_instr ppc;GEN_MTFSF(ppc,fields,fs);set_next_dst(ppc);} +#define EMIT_FCMPU(fa,fb,cr) \ +{PowerPC_instr ppc;GEN_FCMPU(ppc,fa,fb,cr);set_next_dst(ppc);} +#define EMIT_FRSQRTE(fd,fs) \ +{PowerPC_instr ppc;GEN_FRSQRTE(ppc,fd,fs);set_next_dst(ppc);} +#define EMIT_FSQRT(fd,fs) \ +{PowerPC_instr ppc;GEN_FSQRT(ppc,fd,fs);set_next_dst(ppc);} +#define EMIT_FSQRTS(fd,fs) \ +{PowerPC_instr ppc;GEN_FSQRTS(ppc,fd,fs);set_next_dst(ppc);} +#define EMIT_FSEL(fd,fa,fb,fc) \ +{PowerPC_instr ppc;GEN_FSEL(ppc,fd,fa,fb,fc);set_next_dst(ppc);} +#define EMIT_FRES(fd,fs) \ +{PowerPC_instr ppc;GEN_FRES(ppc,fd,fs);set_next_dst(ppc);} +#define EMIT_FNMSUB(fd,fa,fc,fb) \ +{PowerPC_instr ppc;GEN_FNMSUB(ppc,fd,fa,fc,fb);set_next_dst(ppc);} +#define EMIT_FNMSUBS(fd,fa,fc,fb) \ +{PowerPC_instr ppc;GEN_FNMSUBS(ppc,fd,fa,fc,fb);set_next_dst(ppc);} +#define EMIT_FMADD(fd,fa,fc,fb) \ +{PowerPC_instr ppc;GEN_FMADD(ppc,fd,fa,fc,fb);set_next_dst(ppc);} +#define EMIT_FMADDS(fd,fa,fc,fb) \ +{PowerPC_instr ppc;GEN_FMADDS(ppc,fd,fa,fc,fb);set_next_dst(ppc);} +#define EMIT_BCLR(lk,bo,bi) \ +{PowerPC_instr ppc;GEN_BCLR(ppc,lk,bo,bi);set_next_dst(ppc);} +#define EMIT_BNELR(cr,lk) \ +{PowerPC_instr ppc;GEN_BNELR(ppc,cr,lk);set_next_dst(ppc);} +#define EMIT_BLELR(cr,lk) \ +{PowerPC_instr ppc;GEN_BLELR(ppc,cr,lk);set_next_dst(ppc);} +#define EMIT_ANDIS(rd,ra,immed) \ +{PowerPC_instr ppc;GEN_ANDIS(ppc,rd,ra,immed);set_next_dst(ppc);} +#define EMIT_ORIS(rd,rs,immed) \ +{PowerPC_instr ppc;GEN_ORIS(ppc,rd,rs,immed);set_next_dst(ppc);} +#define EMIT_CROR(cd,ca,cb) \ +{PowerPC_instr ppc;GEN_CROR(ppc,cd,ca,cb);set_next_dst(ppc);} +#define EMIT_CRNOR(cd,ca,cb) \ +{PowerPC_instr ppc;GEN_CRNOR(ppc,cd,ca,cb);set_next_dst(ppc);} +#define EMIT_MFCR(rt) \ +{PowerPC_instr ppc;GEN_MFCR(ppc,rt);set_next_dst(ppc);} +#define EMIT_MCRXR(bf) \ +{PowerPC_instr ppc;GEN_MCRXR(ppc,bf);set_next_dst(ppc);} + +#define EMIT_LVX(vd,ra,rb) \ +{PowerPC_instr ppc=0x7C0000CE;PPC_SET_RD(ppc,vd);PPC_SET_RA(ppc,ra);PPC_SET_RB(ppc,rb);set_next_dst(ppc);} +#define EMIT_STVX(vs,ra,rb) \ +{PowerPC_instr ppc=0x7C0001CE;PPC_SET_RD(ppc,vs);PPC_SET_RA(ppc,ra);PPC_SET_RB(ppc,rb);set_next_dst(ppc);} +#define EMIT_VOR(vd,va,vb) \ +{PowerPC_instr ppc=0x10000484;PPC_SET_RD(ppc,vd);PPC_SET_RA(ppc,va);PPC_SET_RB(ppc,vb);set_next_dst(ppc);} + #endif diff --git a/r4300/ppc/Register-Cache.c b/r4300/ppc/Register-Cache.c index cbbf5f5..2d15a4f 100644 --- a/r4300/ppc/Register-Cache.c +++ b/r4300/ppc/Register-Cache.c @@ -48,22 +48,17 @@ static int availableRegs[32]; // Actually perform the store for a dirty register mapping static void _flushRegister(int reg){ - PowerPC_instr ppc; if(regMap[reg].map.hi >= 0){ // Simply store the mapped MSW - GEN_STW(ppc, regMap[reg].map.hi, reg*8, DYNAREG_REG); - set_next_dst(ppc); + EMIT_STW(regMap[reg].map.hi, reg*8, DYNAREG_REG); } else { // Sign extend to 64-bits - GEN_SRAWI(ppc, 0, regMap[reg].map.lo, 31); - set_next_dst(ppc); + EMIT_SRAWI(0, regMap[reg].map.lo, 31); // Store the MSW - GEN_STW(ppc, 0, reg*8, DYNAREG_REG); - set_next_dst(ppc); + EMIT_STW(0, reg*8, DYNAREG_REG); } // Store the LSW - GEN_STW(ppc, regMap[reg].map.lo, reg*8+4, DYNAREG_REG); - set_next_dst(ppc); + EMIT_STW(regMap[reg].map.lo, reg*8+4, DYNAREG_REG); } // Find an available HW reg or -1 for none static int getAvailableHWReg(void){ @@ -161,7 +156,6 @@ RegMapping mapRegister64New(int reg){ } int mapRegister(int reg){ - PowerPC_instr ppc; if(!reg) return DYNAREG_ZERO; // Return r0 mapped to r14 regMap[reg].lru = nextLRUVal++; // If its already been mapped, just return that value @@ -174,8 +168,7 @@ int mapRegister(int reg){ // Iterate over the HW registers and find one that's available int available = getAvailableHWReg(); if(available >= 0){ - GEN_LWZ(ppc, available, reg*8+4, DYNAREG_REG); - set_next_dst(ppc); + EMIT_LWZ(available, reg*8+4, DYNAREG_REG); return regMap[reg].map.lo = available; } @@ -183,14 +176,12 @@ int mapRegister(int reg){ RegMapping lru = flushLRURegister(); if(lru.hi >= 0) availableRegs[lru.hi] = 1; // And load the registers value to the register we flushed - GEN_LWZ(ppc, lru.lo, reg*8+4, DYNAREG_REG); - set_next_dst(ppc); + EMIT_LWZ(lru.lo, reg*8+4, DYNAREG_REG); return regMap[reg].map.lo = lru.lo; } RegMapping mapRegister64(int reg){ - PowerPC_instr ppc; if(!reg) return (RegMapping){ DYNAREG_ZERO, DYNAREG_ZERO }; regMap[reg].lru = nextLRUVal++; // If its already been mapped, just return that value @@ -207,8 +198,7 @@ RegMapping mapRegister64(int reg){ regMap[reg].map.hi = lru.lo; } // Sign extend to 64-bits - GEN_SRAWI(ppc, regMap[reg].map.hi, regMap[reg].map.lo, 31); - set_next_dst(ppc); + EMIT_SRAWI(regMap[reg].map.hi, regMap[reg].map.lo, 31); } // Return the mapping return regMap[reg].map; @@ -232,10 +222,8 @@ RegMapping mapRegister64(int reg){ regMap[reg].map.hi = lru.lo; } // Load the values into the registers - GEN_LWZ(ppc, regMap[reg].map.hi, reg*8, DYNAREG_REG); - set_next_dst(ppc); - GEN_LWZ(ppc, regMap[reg].map.lo, reg*8+4, DYNAREG_REG); - set_next_dst(ppc); + EMIT_LWZ(regMap[reg].map.hi, reg*8, DYNAREG_REG); + EMIT_LWZ(regMap[reg].map.lo, reg*8+4, DYNAREG_REG); // Return the mapping return regMap[reg].map; } @@ -287,20 +275,15 @@ static int availableFPRs[32]; // Actually perform the store for a dirty register mapping static void _flushFPR(int reg){ - PowerPC_instr ppc; // Store the register to memory (indirectly) int addr = mapRegisterTemp(); if(fprMap[reg].dbl){ - GEN_LWZ(ppc, addr, reg*4, DYNAREG_FPR_64); - set_next_dst(ppc); - GEN_STFD(ppc, fprMap[reg].map, 0, addr); - set_next_dst(ppc); + EMIT_LWZ(addr, reg*4, DYNAREG_FPR_64); + EMIT_STFD(fprMap[reg].map, 0, addr); } else { - GEN_LWZ(ppc, addr, reg*4, DYNAREG_FPR_32); - set_next_dst(ppc); - GEN_STFS(ppc, fprMap[reg].map, 0, addr); - set_next_dst(ppc); + EMIT_LWZ(addr, reg*4, DYNAREG_FPR_32); + EMIT_STFS(fprMap[reg].map, 0, addr); } unmapRegisterTemp(addr); @@ -351,8 +334,6 @@ int mapFPRNew(int fpr, int dbl){ } int mapFPR(int fpr, int dbl){ - PowerPC_instr ppc; - fprMap[fpr].lru = nextLRUValFPR++; fprMap[fpr].dbl = dbl; // Set whether this is a double-precision @@ -370,15 +351,11 @@ int mapFPR(int fpr, int dbl){ int addr = mapRegisterTemp(); if(dbl){ - GEN_LWZ(ppc, addr, fpr*4, DYNAREG_FPR_64); - set_next_dst(ppc); - GEN_LFD(ppc, fprMap[fpr].map, 0, addr); - set_next_dst(ppc); + EMIT_LWZ(addr, fpr*4, DYNAREG_FPR_64); + EMIT_LFD(fprMap[fpr].map, 0, addr); } else { - GEN_LWZ(ppc, addr, fpr*4, DYNAREG_FPR_32); - set_next_dst(ppc); - GEN_LFS(ppc, fprMap[fpr].map, 0, addr); - set_next_dst(ppc); + EMIT_LWZ(addr, fpr*4, DYNAREG_FPR_32); + EMIT_LFS(fprMap[fpr].map, 0, addr); } unmapRegisterTemp(addr); @@ -469,4 +446,3 @@ int mapFPRTemp(void){ void unmapFPRTemp(int fpr){ availableFPRs[fpr] = 1; } -