Path: blob/master/libmupen64plus/mupen64plus-core/src/r4300/x86/gregimm.c
2 views
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *1* Mupen64plus - gregimm.c *2* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *3* Copyright (C) 2002 Hacktarux *4* *5* This program is free software; you can redistribute it and/or modify *6* it under the terms of the GNU General Public License as published by *7* the Free Software Foundation; either version 2 of the License, or *8* (at your option) any later version. *9* *10* This program is distributed in the hope that it will be useful, *11* but WITHOUT ANY WARRANTY; without even the implied warranty of *12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *13* GNU General Public License for more details. *14* *15* You should have received a copy of the GNU General Public License *16* along with this program; if not, write to the *17* Free Software Foundation, Inc., *18* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *19* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */2021#include <stdio.h>2223#include "assemble.h"24#include "interpret.h"2526#include "r4300/recomph.h"27#include "r4300/recomp.h"28#include "r4300/r4300.h"29#include "r4300/ops.h"30#include "r4300/macros.h"3132#include "memory/memory.h"3334static void genbltz_test(void)35{36int rs_64bit = is64((unsigned int *)dst->f.i.rs);3738if (!rs_64bit)39{40int rs = allocate_register((unsigned int *)dst->f.i.rs);4142cmp_reg32_imm32(rs, 0);43jge_rj(12);44mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 1045jmp_imm_short(10); // 246mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 1047}48else if (rs_64bit == -1)49{50cmp_m32_imm32(((unsigned int *)dst->f.i.rs)+1, 0);51jge_rj(12);52mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 1053jmp_imm_short(10); // 254mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 1055}56else57{58int rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs);5960cmp_reg32_imm32(rs2, 0);61jge_rj(12);62mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 1063jmp_imm_short(10); // 264mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 1065}66}6768void genbltz(void)69{70#ifdef INTERPRET_BLTZ71gencallinterp((unsigned int)cached_interpreter_table.BLTZ, 1);72#else73if (((dst->addr & 0xFFF) == 0xFFC &&74(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)75{76gencallinterp((unsigned int)cached_interpreter_table.BLTZ, 1);77return;78}7980genbltz_test();81gendelayslot();82gentest();83#endif84}8586void genbltz_out(void)87{88#ifdef INTERPRET_BLTZ_OUT89gencallinterp((unsigned int)cached_interpreter_table.BLTZ_OUT, 1);90#else91if (((dst->addr & 0xFFF) == 0xFFC &&92(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)93{94gencallinterp((unsigned int)cached_interpreter_table.BLTZ_OUT, 1);95return;96}9798genbltz_test();99gendelayslot();100gentest_out();101#endif102}103104void genbltz_idle(void)105{106#ifdef INTERPRET_BLTZ_IDLE107gencallinterp((unsigned int)cached_interpreter_table.BLTZ_IDLE, 1);108#else109if (((dst->addr & 0xFFF) == 0xFFC &&110(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)111{112gencallinterp((unsigned int)cached_interpreter_table.BLTZ_IDLE, 1);113return;114}115116genbltz_test();117gentest_idle();118genbltz();119#endif120}121122static void genbgez_test(void)123{124int rs_64bit = is64((unsigned int *)dst->f.i.rs);125126if (!rs_64bit)127{128int rs = allocate_register((unsigned int *)dst->f.i.rs);129130cmp_reg32_imm32(rs, 0);131jl_rj(12);132mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10133jmp_imm_short(10); // 2134mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10135}136else if (rs_64bit == -1)137{138cmp_m32_imm32(((unsigned int *)dst->f.i.rs)+1, 0);139jl_rj(12);140mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10141jmp_imm_short(10); // 2142mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10143}144else145{146int rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs);147148cmp_reg32_imm32(rs2, 0);149jl_rj(12);150mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10151jmp_imm_short(10); // 2152mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10153}154}155156void genbgez(void)157{158#ifdef INTERPRET_BGEZ159gencallinterp((unsigned int)cached_interpreter_table.BGEZ, 1);160#else161if (((dst->addr & 0xFFF) == 0xFFC &&162(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)163{164gencallinterp((unsigned int)cached_interpreter_table.BGEZ, 1);165return;166}167168genbgez_test();169gendelayslot();170gentest();171#endif172}173174void genbgez_out(void)175{176#ifdef INTERPRET_BGEZ_OUT177gencallinterp((unsigned int)cached_interpreter_table.BGEZ_OUT, 1);178#else179if (((dst->addr & 0xFFF) == 0xFFC &&180(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)181{182gencallinterp((unsigned int)cached_interpreter_table.BGEZ_OUT, 1);183return;184}185186genbgez_test();187gendelayslot();188gentest_out();189#endif190}191192void genbgez_idle(void)193{194#ifdef INTERPRET_BGEZ_IDLE195gencallinterp((unsigned int)cached_interpreter_table.BGEZ_IDLE, 1);196#else197if (((dst->addr & 0xFFF) == 0xFFC &&198(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)199{200gencallinterp((unsigned int)cached_interpreter_table.BGEZ_IDLE, 1);201return;202}203204genbgez_test();205gentest_idle();206genbgez();207#endif208}209210void genbltzl(void)211{212#ifdef INTERPRET_BLTZL213gencallinterp((unsigned int)cached_interpreter_table.BLTZL, 1);214#else215if (((dst->addr & 0xFFF) == 0xFFC &&216(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)217{218gencallinterp((unsigned int)cached_interpreter_table.BLTZL, 1);219return;220}221222genbltz_test();223free_all_registers();224gentestl();225#endif226}227228void genbltzl_out(void)229{230#ifdef INTERPRET_BLTZL_OUT231gencallinterp((unsigned int)cached_interpreter_table.BLTZL_OUT, 1);232#else233if (((dst->addr & 0xFFF) == 0xFFC &&234(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)235{236gencallinterp((unsigned int)cached_interpreter_table.BLTZL_OUT, 1);237return;238}239240genbltz_test();241free_all_registers();242gentestl_out();243#endif244}245246void genbltzl_idle(void)247{248#ifdef INTERPRET_BLTZL_IDLE249gencallinterp((unsigned int)cached_interpreter_table.BLTZL_IDLE, 1);250#else251if (((dst->addr & 0xFFF) == 0xFFC &&252(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)253{254gencallinterp((unsigned int)cached_interpreter_table.BLTZL_IDLE, 1);255return;256}257258genbltz_test();259gentest_idle();260genbltzl();261#endif262}263264void genbgezl(void)265{266#ifdef INTERPRET_BGEZL267gencallinterp((unsigned int)cached_interpreter_table.BGEZL, 1);268#else269if (((dst->addr & 0xFFF) == 0xFFC &&270(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)271{272gencallinterp((unsigned int)cached_interpreter_table.BGEZL, 1);273return;274}275276genbgez_test();277free_all_registers();278gentestl();279#endif280}281282void genbgezl_out(void)283{284#ifdef INTERPRET_BGEZL_OUT285gencallinterp((unsigned int)cached_interpreter_table.BGEZL_OUT, 1);286#else287if (((dst->addr & 0xFFF) == 0xFFC &&288(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)289{290gencallinterp((unsigned int)cached_interpreter_table.BGEZL_OUT, 1);291return;292}293294genbgez_test();295free_all_registers();296gentestl_out();297#endif298}299300void genbgezl_idle(void)301{302#ifdef INTERPRET_BGEZL_IDLE303gencallinterp((unsigned int)cached_interpreter_table.BGEZL_IDLE, 1);304#else305if (((dst->addr & 0xFFF) == 0xFFC &&306(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)307{308gencallinterp((unsigned int)cached_interpreter_table.BGEZL_IDLE, 1);309return;310}311312genbgez_test();313gentest_idle();314genbgezl();315#endif316}317318static void genbranchlink(void)319{320int r31_64bit = is64((unsigned int*)®[31]);321322if (!r31_64bit)323{324int r31 = allocate_register_w((unsigned int *)®[31]);325326mov_reg32_imm32(r31, dst->addr+8);327}328else if (r31_64bit == -1)329{330mov_m32_imm32((unsigned int *)®[31], dst->addr + 8);331if (dst->addr & 0x80000000)332mov_m32_imm32(((unsigned int *)®[31])+1, 0xFFFFFFFF);333else334mov_m32_imm32(((unsigned int *)®[31])+1, 0);335}336else337{338int r311 = allocate_64_register1_w((unsigned int *)®[31]);339int r312 = allocate_64_register2_w((unsigned int *)®[31]);340341mov_reg32_imm32(r311, dst->addr+8);342if (dst->addr & 0x80000000)343mov_reg32_imm32(r312, 0xFFFFFFFF);344else345mov_reg32_imm32(r312, 0);346}347}348349void genbltzal(void)350{351#ifdef INTERPRET_BLTZAL352gencallinterp((unsigned int)cached_interpreter_table.BLTZAL, 1);353#else354if (((dst->addr & 0xFFF) == 0xFFC &&355(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)356{357gencallinterp((unsigned int)cached_interpreter_table.BLTZAL, 1);358return;359}360361genbltz_test();362genbranchlink();363gendelayslot();364gentest();365#endif366}367368void genbltzal_out(void)369{370#ifdef INTERPRET_BLTZAL_OUT371gencallinterp((unsigned int)cached_interpreter_table.BLTZAL_OUT, 1);372#else373if (((dst->addr & 0xFFF) == 0xFFC &&374(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)375{376gencallinterp((unsigned int)cached_interpreter_table.BLTZAL_OUT, 1);377return;378}379380genbltz_test();381genbranchlink();382gendelayslot();383gentest_out();384#endif385}386387void genbltzal_idle(void)388{389#ifdef INTERPRET_BLTZAL_IDLE390gencallinterp((unsigned int)cached_interpreter_table.BLTZAL_IDLE, 1);391#else392if (((dst->addr & 0xFFF) == 0xFFC &&393(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)394{395gencallinterp((unsigned int)cached_interpreter_table.BLTZAL_IDLE, 1);396return;397}398399genbltz_test();400genbranchlink();401gentest_idle();402genbltzal();403#endif404}405406void genbgezal(void)407{408#ifdef INTERPRET_BGEZAL409gencallinterp((unsigned int)cached_interpreter_table.BGEZAL, 1);410#else411if (((dst->addr & 0xFFF) == 0xFFC &&412(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)413{414gencallinterp((unsigned int)cached_interpreter_table.BGEZAL, 1);415return;416}417418genbgez_test();419genbranchlink();420gendelayslot();421gentest();422#endif423}424425void genbgezal_out(void)426{427#ifdef INTERPRET_BGEZAL_OUT428gencallinterp((unsigned int)cached_interpreter_table.BGEZAL_OUT, 1);429#else430if (((dst->addr & 0xFFF) == 0xFFC &&431(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)432{433gencallinterp((unsigned int)cached_interpreter_table.BGEZAL_OUT, 1);434return;435}436437genbgez_test();438genbranchlink();439gendelayslot();440gentest_out();441#endif442}443444void genbgezal_idle(void)445{446#ifdef INTERPRET_BGEZAL_IDLE447gencallinterp((unsigned int)cached_interpreter_table.BGEZAL_IDLE, 1);448#else449if (((dst->addr & 0xFFF) == 0xFFC &&450(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)451{452gencallinterp((unsigned int)cached_interpreter_table.BGEZAL_IDLE, 1);453return;454}455456genbgez_test();457genbranchlink();458gentest_idle();459genbgezal();460#endif461}462463void genbltzall(void)464{465#ifdef INTERPRET_BLTZALL466gencallinterp((unsigned int)cached_interpreter_table.BLTZALL, 1);467#else468if (((dst->addr & 0xFFF) == 0xFFC &&469(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)470{471gencallinterp((unsigned int)cached_interpreter_table.BLTZALL, 1);472return;473}474475genbltz_test();476genbranchlink();477free_all_registers();478gentestl();479#endif480}481482void genbltzall_out(void)483{484#ifdef INTERPRET_BLTZALL_OUT485gencallinterp((unsigned int)cached_interpreter_table.BLTZALL_OUT, 1);486#else487if (((dst->addr & 0xFFF) == 0xFFC &&488(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)489{490gencallinterp((unsigned int)cached_interpreter_table.BLTZALL_OUT, 1);491return;492}493494genbltz_test();495genbranchlink();496free_all_registers();497gentestl_out();498#endif499}500501void genbltzall_idle(void)502{503#ifdef INTERPRET_BLTZALL_IDLE504gencallinterp((unsigned int)cached_interpreter_table.BLTZALL_IDLE, 1);505#else506if (((dst->addr & 0xFFF) == 0xFFC &&507(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)508{509gencallinterp((unsigned int)cached_interpreter_table.BLTZALL_IDLE, 1);510return;511}512513genbltz_test();514genbranchlink();515gentest_idle();516genbltzall();517#endif518}519520void genbgezall(void)521{522#ifdef INTERPRET_BGEZALL523gencallinterp((unsigned int)cached_interpreter_table.BGEZALL, 1);524#else525if (((dst->addr & 0xFFF) == 0xFFC &&526(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)527{528gencallinterp((unsigned int)cached_interpreter_table.BGEZALL, 1);529return;530}531532genbgez_test();533genbranchlink();534free_all_registers();535gentestl();536#endif537}538539void genbgezall_out(void)540{541#ifdef INTERPRET_BGEZALL_OUT542gencallinterp((unsigned int)cached_interpreter_table.BGEZALL_OUT, 1);543#else544if (((dst->addr & 0xFFF) == 0xFFC &&545(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)546{547gencallinterp((unsigned int)cached_interpreter_table.BGEZALL_OUT, 1);548return;549}550551genbgez_test();552genbranchlink();553free_all_registers();554gentestl_out();555#endif556}557558void genbgezall_idle(void)559{560#ifdef INTERPRET_BGEZALL_IDLE561gencallinterp((unsigned int)cached_interpreter_table.BGEZALL_IDLE, 1);562#else563if (((dst->addr & 0xFFF) == 0xFFC &&564(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)565{566gencallinterp((unsigned int)cached_interpreter_table.BGEZALL_IDLE, 1);567return;568}569570genbgez_test();571genbranchlink();572gentest_idle();573genbgezall();574#endif575}576577578579