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=633eeac293d342bbe79e156cc445e3b737326ae4;hp=3abef7f5050b5c6760e39e813c98bc7666fcb7ce;hb=b79187510fbbf5f73daa13a5c57cc70d09d16acb;hpb=514ed0d98e058596720f94af4af347b609980de9 diff --git a/libpcsxcore/new_dynarec/assem_arm.c b/libpcsxcore/new_dynarec/assem_arm.c index 3abef7f5..633eeac2 100644 --- a/libpcsxcore/new_dynarec/assem_arm.c +++ b/libpcsxcore/new_dynarec/assem_arm.c @@ -142,7 +142,7 @@ add_literal(int addr,int val) literalcount++; } -void kill_pointer(void *stub) +void *kill_pointer(void *stub) { int *ptr=(int *)(stub+4); assert((*ptr&0x0ff00000)==0x05900000); @@ -150,6 +150,7 @@ void kill_pointer(void *stub) int **l_ptr=(void *)ptr+offset+8; int *i_ptr=*l_ptr; set_jump_target((int)i_ptr,(int)stub); + return i_ptr; } int get_pointer(void *stub) @@ -2553,6 +2554,11 @@ do_readstub(int n) rth=get_reg(i_regmap,rt1[i]|64); rt=get_reg(i_regmap,rt1[i]); } +#ifdef PCSX + if(rt<0) + // assume forced dummy read + rt=get_reg(i_regmap,-1); +#endif assert(rs>=0); assert(rt>=0); if(addr<0) addr=rt; @@ -2855,8 +2861,81 @@ inline_writestub(int type, int i, u_int addr, signed char regmap[], int target, do_unalignedwritestub(int n) { + assem_debug("do_unalignedwritestub %x\n",start+stubs[n][3]*4); + literal_pool(256); set_jump_target(stubs[n][1],(int)out); - output_w32(0xef000000); + + int i=stubs[n][3]; + struct regstat *i_regs=(struct regstat *)stubs[n][4]; + int addr=stubs[n][5]; + u_int reglist=stubs[n][7]; + signed char *i_regmap=i_regs->regmap; + int temp2=get_reg(i_regmap,FTEMP); + int rt; + int ds, real_rs; + rt=get_reg(i_regmap,rs2[i]); + assert(rt>=0); + assert(addr>=0); + assert(opcode[i]==0x2a||opcode[i]==0x2e); // SWL/SWR only implemented + reglist|=(1<wasconst); + if(!ds) load_all_consts(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty&~(1<regmap_entry,i_regs->was32,i_regs->wasdirty&cmask&~(1<>rs1[i])&1)<<1)+ds,3); // XXX: can be rm'd? + emit_call((int)&indirect_jump_indexed); + restore_regs(reglist); + + emit_readword((int)&readmem_dword,temp2); + int temp=addr; //hmh + emit_shlimm(addr,3,temp); + emit_andimm(temp,24,temp); +#ifdef BIG_ENDIAN_MIPS + if (opcode[i]==0x2e) // SWR +#else + if (opcode[i]==0x2a) // SWL +#endif + emit_xorimm(temp,24,temp); + emit_movimm(-1,HOST_TEMPREG); + if (opcode[i]==0x2e) { // SWR + emit_bic_lsr(temp2,HOST_TEMPREG,temp,temp2); + emit_orrshr(rt,temp,temp2); + }else{ + emit_bic_lsl(temp2,HOST_TEMPREG,temp,temp2); + emit_orrshl(rt,temp,temp2); + } + emit_readword((int)&address,addr); + emit_writeword(temp2,(int)&word); + //save_regs(reglist); // don't need to, no state changes + emit_shrimm(addr,16,1); + emit_movimm((u_int)writemem,0); + //emit_call((int)&indirect_jump_indexed); + emit_mov(15,14); + emit_readword_dualindexedx4(0,1,15); + emit_readword((int)&Count,HOST_TEMPREG); + emit_readword((int)&next_interupt,2); + emit_addimm(HOST_TEMPREG,-2*stubs[n][6]-2,HOST_TEMPREG); + emit_writeword(2,(int)&last_count); + emit_sub(HOST_TEMPREG,2,cc<0?HOST_TEMPREG:cc); + if(cc<0) { + emit_storereg(CCREG,HOST_TEMPREG); + } + restore_regs(reglist); emit_jmp(stubs[n][2]); // return address }