X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=blobdiff_plain;f=libpcsxcore%2Fnew_dynarec%2Fassem_arm.c;h=87490c61786d3f7b68b1110ff7134b67a2759c1d;hp=186d0af40941ea2b28fd4f1b7f9869a571349a15;hb=37387d8b2b8b9705ca42bd7582ed48d88aeafb9b;hpb=e3c6bdb5e46f72f063bb7f588da6588ac1893b17 diff --git a/libpcsxcore/new_dynarec/assem_arm.c b/libpcsxcore/new_dynarec/assem_arm.c index 186d0af4..87490c61 100644 --- a/libpcsxcore/new_dynarec/assem_arm.c +++ b/libpcsxcore/new_dynarec/assem_arm.c @@ -206,7 +206,7 @@ static void *get_pointer(void *stub) { //printf("get_pointer(%x)\n",(int)stub); int *i_ptr=find_extjump_insn(stub); - assert((*i_ptr&0x0f000000)==0x0a000000); + assert((*i_ptr&0x0f000000)==0x0a000000); // b return (u_char *)i_ptr+((*i_ptr<<8)>>6)+8; } @@ -441,6 +441,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 +543,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 +707,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); @@ -1160,6 +1163,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 +1177,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 +1305,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) { @@ -1683,10 +1736,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 +1750,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; @@ -1743,7 +1796,7 @@ static void do_readstub(int n) emit_loadreg(CCREG,2); emit_addimm(cc<0?2:cc,CLOCK_ADJUST((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) @@ -1767,7 +1820,7 @@ static void inline_readstub(enum stub_type type, int i, u_int addr, 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 +1845,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<=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 +1892,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); @@ -1946,26 +1999,26 @@ static void inline_writestub(enum stub_type type, int i, u_int addr, } // this output is parsed by verify_dirty, get_bounds, isclean, get_clean_addr -static void do_dirty_stub_emit_args(u_int arg0) +static void do_dirty_stub_emit_args(u_int arg0, u_int source_len) { #ifndef HAVE_ARMV7 emit_loadlp((int)source, 1); emit_loadlp((int)copy, 2); - emit_loadlp(slen*4, 3); + emit_loadlp(source_len, 3); #else emit_movw(((u_int)source)&0x0000FFFF, 1); emit_movw(((u_int)copy)&0x0000FFFF, 2); emit_movt(((u_int)source)&0xFFFF0000, 1); emit_movt(((u_int)copy)&0xFFFF0000, 2); - emit_movw(slen*4, 3); + emit_movw(source_len, 3); #endif emit_movimm(arg0, 0); } -static void *do_dirty_stub(int i) +static void *do_dirty_stub(int i, u_int source_len) { assem_debug("do_dirty_stub %x\n",start+i*4); - do_dirty_stub_emit_args(start + i*4); + do_dirty_stub_emit_args(start + i*4, source_len); emit_far_call(verify_code); void *entry = out; load_regs_entry(i); @@ -1975,9 +2028,9 @@ static void *do_dirty_stub(int i) return entry; } -static void do_dirty_stub_ds() +static void do_dirty_stub_ds(u_int source_len) { - do_dirty_stub_emit_args(start + 1); + do_dirty_stub_emit_args(start + 1, source_len); emit_far_call(verify_code_ds); } @@ -1986,7 +2039,7 @@ static void do_dirty_stub_ds() static void c2op_prologue(u_int op, int i, const struct regstat *i_regs, u_int reglist) { save_regs_all(reglist); - cop2_call_stall_check(op, i, i_regs, 0); + cop2_do_stall_check(op, i, i_regs, 0); #ifdef PCNT emit_movimm(op, 0); emit_far_call(pcnt_gte_start); @@ -2187,14 +2240,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 +2256,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 +2268,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 +2306,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);