X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libpcsxcore%2Fnew_dynarec%2Fassem_arm.c;h=3267cb6b87dc9e18d9b892f601f58f5c1c8997e8;hb=0aeb0cb9d5aee3004954bd18ef5b7ea1f69a0378;hp=4ccd19fe79e7a6ee33401300b03abb6e97420dd6;hpb=3d680478922d5f28e3dbe471308cc27a70e31fdf;p=pcsx_rearmed.git diff --git a/libpcsxcore/new_dynarec/assem_arm.c b/libpcsxcore/new_dynarec/assem_arm.c index 4ccd19fe..3267cb6b 100644 --- a/libpcsxcore/new_dynarec/assem_arm.c +++ b/libpcsxcore/new_dynarec/assem_arm.c @@ -27,12 +27,6 @@ #include "pcnt.h" #include "arm_features.h" -#ifndef __MACH__ -#define CALLER_SAVE_REGS 0x100f -#else -#define CALLER_SAVE_REGS 0x120f -#endif - #define unused __attribute__((unused)) #ifdef DRC_DBG @@ -441,6 +435,13 @@ static void emit_add(int rs1,int rs2,int rt) output_w32(0xe0800000|rd_rn_rm(rt,rs1,rs2)); } +static void emit_adds(int rs1,int rs2,int rt) +{ + assem_debug("adds %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]); + output_w32(0xe0900000|rd_rn_rm(rt,rs1,rs2)); +} +#define emit_adds_ptr emit_adds + static void emit_adcs(int rs1,int rs2,int rt) { assem_debug("adcs %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]); @@ -536,6 +537,7 @@ static void emit_loadreg(int r, int hr) case CCREG: addr = (int)&cycle_count; break; case CSREG: addr = (int)&Status; break; case INVCP: addr = (int)&invc_ptr; break; + case ROREG: addr = (int)&ram_offset; break; default: assert(r < 34); break; } u_int offset = addr-(u_int)&dynarec_local; @@ -699,11 +701,6 @@ static void emit_addimm_and_set_flags(int imm,int rt) } } -static void emit_addimm_no_flags(u_int imm,u_int rt) -{ - emit_addimm(rt,imm,rt); -} - static void emit_addnop(u_int r) { assert(r<16); @@ -952,6 +949,14 @@ static void emit_cmovae_imm(int imm,int rt) output_w32(0x23a00000|rd_rn_rm(rt,0,0)|armval); } +static void emit_cmovs_imm(int imm,int rt) +{ + assem_debug("movmi %s,#%d\n",regname[rt],imm); + u_int armval; + genimm_checked(imm,&armval); + output_w32(0x43a00000|rd_rn_rm(rt,0,0)|armval); +} + static void emit_cmovne_reg(int rs,int rt) { assem_debug("movne %s,%s\n",regname[rt],regname[rs]); @@ -1160,6 +1165,13 @@ static void emit_readword_dualindexedx4(int rs1, int rs2, int rt) assem_debug("ldr %s,%s,%s lsl #2\n",regname[rt],regname[rs1],regname[rs2]); output_w32(0xe7900000|rd_rn_rm(rt,rs1,rs2)|0x100); } +#define emit_readptr_dualindexedx_ptrlen emit_readword_dualindexedx4 + +static void emit_ldr_dualindexed(int rs1, int rs2, int rt) +{ + assem_debug("ldr %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]); + output_w32(0xe7900000|rd_rn_rm(rt,rs1,rs2)); +} static void emit_ldrcc_dualindexed(int rs1, int rs2, int rt) { @@ -1167,30 +1179,72 @@ static void emit_ldrcc_dualindexed(int rs1, int rs2, int rt) output_w32(0x37900000|rd_rn_rm(rt,rs1,rs2)); } +static void emit_ldrb_dualindexed(int rs1, int rs2, int rt) +{ + assem_debug("ldrb %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]); + output_w32(0xe7d00000|rd_rn_rm(rt,rs1,rs2)); +} + static void emit_ldrccb_dualindexed(int rs1, int rs2, int rt) { assem_debug("ldrccb %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]); output_w32(0x37d00000|rd_rn_rm(rt,rs1,rs2)); } +static void emit_ldrsb_dualindexed(int rs1, int rs2, int rt) +{ + assem_debug("ldrsb %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]); + output_w32(0xe19000d0|rd_rn_rm(rt,rs1,rs2)); +} + static void emit_ldrccsb_dualindexed(int rs1, int rs2, int rt) { assem_debug("ldrccsb %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]); output_w32(0x319000d0|rd_rn_rm(rt,rs1,rs2)); } +static void emit_ldrh_dualindexed(int rs1, int rs2, int rt) +{ + assem_debug("ldrh %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]); + output_w32(0xe19000b0|rd_rn_rm(rt,rs1,rs2)); +} + static void emit_ldrcch_dualindexed(int rs1, int rs2, int rt) { assem_debug("ldrcch %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]); output_w32(0x319000b0|rd_rn_rm(rt,rs1,rs2)); } +static void emit_ldrsh_dualindexed(int rs1, int rs2, int rt) +{ + assem_debug("ldrsh %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]); + output_w32(0xe19000f0|rd_rn_rm(rt,rs1,rs2)); +} + static void emit_ldrccsh_dualindexed(int rs1, int rs2, int rt) { assem_debug("ldrccsh %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]); output_w32(0x319000f0|rd_rn_rm(rt,rs1,rs2)); } +static void emit_str_dualindexed(int rs1, int rs2, int rt) +{ + assem_debug("str %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]); + output_w32(0xe7800000|rd_rn_rm(rt,rs1,rs2)); +} + +static void emit_strb_dualindexed(int rs1, int rs2, int rt) +{ + assem_debug("strb %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]); + output_w32(0xe7c00000|rd_rn_rm(rt,rs1,rs2)); +} + +static void emit_strh_dualindexed(int rs1, int rs2, int rt) +{ + assem_debug("strh %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]); + output_w32(0xe18000b0|rd_rn_rm(rt,rs1,rs2)); +} + static void emit_movsbl_indexed(int offset, int rs, int rt) { assert(offset>-256&&offset<256); @@ -1253,6 +1307,7 @@ static void emit_readword(void *addr, int rt) assem_debug("ldr %s,fp+%d\n",regname[rt],offset); output_w32(0xe5900000|rd_rn_rm(rt,FP,0)|offset); } +#define emit_readptr emit_readword static void emit_writeword_indexed(int rt, int offset, int rs) { @@ -1474,14 +1529,6 @@ static void emit_orrne_imm(int rs,int imm,int rt) output_w32(0x13800000|rd_rn_rm(rt,rs,0)|armval); } -static void emit_andne_imm(int rs,int imm,int rt) -{ - u_int armval; - genimm_checked(imm,&armval); - assem_debug("andne %s,%s,#%d\n",regname[rt],regname[rs],imm); - output_w32(0x12000000|rd_rn_rm(rt,rs,0)|armval); -} - static unused void emit_addpl_imm(int rs,int imm,int rt) { u_int armval; @@ -1683,10 +1730,10 @@ static void do_readstub(int n) u_int reglist=stubs[n].e; const signed char *i_regmap=i_regs->regmap; int rt; - if(itype[i]==C1LS||itype[i]==C2LS||itype[i]==LOADLR) { + if(dops[i].itype==C1LS||dops[i].itype==C2LS||dops[i].itype==LOADLR) { rt=get_reg(i_regmap,FTEMP); }else{ - rt=get_reg(i_regmap,rt1[i]); + rt=get_reg(i_regmap,dops[i].rt1); } assert(rs>=0); int r,temp=-1,temp2=HOST_TEMPREG,regs_saved=0; @@ -1697,7 +1744,7 @@ static void do_readstub(int n) temp=r; break; } } - if(rt>=0&&rt1[i]!=0) + if(rt>=0&&dops[i].rt1!=0) reglist&=~(1<=0&&rt1[i]!=0)) { + if(dops[i].itype==C1LS||dops[i].itype==C2LS||(rt>=0&&dops[i].rt1!=0)) { switch(type) { case LOADB_STUB: emit_ldrccsb_dualindexed(temp2,rs,rt); break; case LOADBU_STUB: emit_ldrccb_dualindexed(temp2,rs,rt); break; @@ -1741,9 +1788,9 @@ static void do_readstub(int n) int cc=get_reg(i_regmap,CCREG); if(cc<0) emit_loadreg(CCREG,2); - emit_addimm(cc<0?2:cc,CLOCK_ADJUST((int)stubs[n].d),2); + emit_addimm(cc<0?2:cc,(int)stubs[n].d,2); emit_far_call(handler); - if(itype[i]==C1LS||itype[i]==C2LS||(rt>=0&&rt1[i]!=0)) { + if(dops[i].itype==C1LS||dops[i].itype==C2LS||(rt>=0&&dops[i].rt1!=0)) { mov_loadtype_adj(type,0,rt); } if(restore_jump) @@ -1763,11 +1810,11 @@ static void inline_readstub(enum stub_type type, int i, u_int addr, uintptr_t host_addr = 0; void *handler; int cc=get_reg(regmap,CCREG); - if(pcsx_direct_read(type,addr,CLOCK_ADJUST(adj),cc,target?rs:-1,rt)) + if(pcsx_direct_read(type,addr,adj,cc,target?rs:-1,rt)) return; handler = get_direct_memhandler(mem_rtab, addr, type, &host_addr); if (handler == NULL) { - if(rt<0||rt1[i]==0) + if(rt<0||dops[i].rt1==0) return; if(addr!=host_addr) emit_movimm_from(addr,rs,host_addr,rs); @@ -1792,7 +1839,7 @@ static void inline_readstub(enum stub_type type, int i, u_int addr, } // call a memhandler - if(rt>=0&&rt1[i]!=0) + if(rt>=0&&dops[i].rt1!=0) reglist&=~(1<>12]<<1,1); - emit_addimm(cc<0?2:cc,CLOCK_ADJUST(adj),2); + emit_addimm(cc<0?2:cc,adj,2); } else { emit_readword(&last_count,3); - emit_addimm(cc<0?2:cc,CLOCK_ADJUST(adj),2); + emit_addimm(cc<0?2:cc,adj,2); emit_add(2,3,2); emit_writeword(2,&Count); } emit_far_call(handler); - if(rt>=0&&rt1[i]!=0) { + if(rt>=0&&dops[i].rt1!=0) { switch(type) { case LOADB_STUB: emit_signextend8(0,rt); break; case LOADBU_STUB: emit_andimm(0,0xff,rt); break; @@ -1839,10 +1886,10 @@ static void do_writestub(int n) u_int reglist=stubs[n].e; const signed char *i_regmap=i_regs->regmap; int rt,r; - if(itype[i]==C1LS||itype[i]==C2LS) { + if(dops[i].itype==C1LS||dops[i].itype==C2LS) { rt=get_reg(i_regmap,r=FTEMP); }else{ - rt=get_reg(i_regmap,r=rs2[i]); + rt=get_reg(i_regmap,r=dops[i].rs2); } assert(rs>=0); assert(rt>=0); @@ -1896,10 +1943,10 @@ static void do_writestub(int n) int cc=get_reg(i_regmap,CCREG); if(cc<0) emit_loadreg(CCREG,2); - emit_addimm(cc<0?2:cc,CLOCK_ADJUST((int)stubs[n].d),2); + emit_addimm(cc<0?2:cc,(int)stubs[n].d,2); // returns new cycle_count emit_far_call(handler); - emit_addimm(0,-CLOCK_ADJUST((int)stubs[n].d),cc<0?2:cc); + emit_addimm(0,-(int)stubs[n].d,cc<0?2:cc); if(cc<0) emit_storereg(CCREG,2); if(restore_jump) @@ -1935,11 +1982,11 @@ static void inline_writestub(enum stub_type type, int i, u_int addr, int cc=get_reg(regmap,CCREG); if(cc<0) emit_loadreg(CCREG,2); - emit_addimm(cc<0?2:cc,CLOCK_ADJUST(adj),2); + emit_addimm(cc<0?2:cc,adj,2); emit_movimm((u_int)handler,3); // returns new cycle_count emit_far_call(jump_handler_write_h); - emit_addimm(0,-CLOCK_ADJUST(adj),cc<0?2:cc); + emit_addimm(0,-adj,cc<0?2:cc); if(cc<0) emit_storereg(CCREG,2); restore_regs(reglist); @@ -2153,11 +2200,11 @@ static void c2op_ctc2_31_assemble(signed char sl, signed char temp) static void do_mfc2_31_one(u_int copr,signed char temp) { emit_readword(®_cop2d[copr],temp); - emit_testimm(temp,0x8000); // do we need this? - emit_andne_imm(temp,0,temp); - emit_cmpimm(temp,0xf80); - emit_andimm(temp,0xf80,temp); - emit_cmovae_imm(0xf80,temp); + emit_lsls_imm(temp,16,temp); + emit_cmovs_imm(0,temp); + emit_cmpimm(temp,0xf80<<16); + emit_andimm(temp,0xf80<<16,temp); + emit_cmovae_imm(0xf80<<16,temp); } static void c2op_mfc2_29_assemble(signed char tl, signed char temp) @@ -2167,17 +2214,17 @@ static void c2op_mfc2_29_assemble(signed char tl, signed char temp) temp = HOST_TEMPREG; } do_mfc2_31_one(9,temp); - emit_shrimm(temp,7,tl); + emit_shrimm(temp,7+16,tl); do_mfc2_31_one(10,temp); - emit_orrshr_imm(temp,2,tl); + emit_orrshr_imm(temp,2+16,tl); do_mfc2_31_one(11,temp); - emit_orrshl_imm(temp,3,tl); + emit_orrshr_imm(temp,-3+16,tl); emit_writeword(tl,®_cop2d[29]); if (temp == HOST_TEMPREG) host_tempreg_release(); } -static void multdiv_assemble_arm(int i,struct regstat *i_regs) +static void multdiv_assemble_arm(int i, const struct regstat *i_regs) { // case 0x18: MULT // case 0x19: MULTU @@ -2187,14 +2234,14 @@ static void multdiv_assemble_arm(int i,struct regstat *i_regs) // case 0x1D: DMULTU // case 0x1E: DDIV // case 0x1F: DDIVU - if(rs1[i]&&rs2[i]) + if(dops[i].rs1&&dops[i].rs2) { - if((opcode2[i]&4)==0) // 32-bit + if((dops[i].opcode2&4)==0) // 32-bit { - if(opcode2[i]==0x18) // MULT + if(dops[i].opcode2==0x18) // MULT { - signed char m1=get_reg(i_regs->regmap,rs1[i]); - signed char m2=get_reg(i_regs->regmap,rs2[i]); + signed char m1=get_reg(i_regs->regmap,dops[i].rs1); + signed char m2=get_reg(i_regs->regmap,dops[i].rs2); signed char hi=get_reg(i_regs->regmap,HIREG); signed char lo=get_reg(i_regs->regmap,LOREG); assert(m1>=0); @@ -2203,10 +2250,10 @@ static void multdiv_assemble_arm(int i,struct regstat *i_regs) assert(lo>=0); emit_smull(m1,m2,hi,lo); } - if(opcode2[i]==0x19) // MULTU + if(dops[i].opcode2==0x19) // MULTU { - signed char m1=get_reg(i_regs->regmap,rs1[i]); - signed char m2=get_reg(i_regs->regmap,rs2[i]); + signed char m1=get_reg(i_regs->regmap,dops[i].rs1); + signed char m2=get_reg(i_regs->regmap,dops[i].rs2); signed char hi=get_reg(i_regs->regmap,HIREG); signed char lo=get_reg(i_regs->regmap,LOREG); assert(m1>=0); @@ -2215,10 +2262,10 @@ static void multdiv_assemble_arm(int i,struct regstat *i_regs) assert(lo>=0); emit_umull(m1,m2,hi,lo); } - if(opcode2[i]==0x1A) // DIV + if(dops[i].opcode2==0x1A) // DIV { - signed char d1=get_reg(i_regs->regmap,rs1[i]); - signed char d2=get_reg(i_regs->regmap,rs2[i]); + signed char d1=get_reg(i_regs->regmap,dops[i].rs1); + signed char d2=get_reg(i_regs->regmap,dops[i].rs2); assert(d1>=0); assert(d2>=0); signed char quotient=get_reg(i_regs->regmap,LOREG); @@ -2253,10 +2300,10 @@ static void multdiv_assemble_arm(int i,struct regstat *i_regs) emit_test(d1,d1); emit_negmi(remainder,remainder); } - if(opcode2[i]==0x1B) // DIVU + if(dops[i].opcode2==0x1B) // DIVU { - signed char d1=get_reg(i_regs->regmap,rs1[i]); // dividend - signed char d2=get_reg(i_regs->regmap,rs2[i]); // divisor + signed char d1=get_reg(i_regs->regmap,dops[i].rs1); // dividend + signed char d2=get_reg(i_regs->regmap,dops[i].rs2); // divisor assert(d1>=0); assert(d2>=0); signed char quotient=get_reg(i_regs->regmap,LOREG);