X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libpcsxcore%2Fnew_dynarec%2Fassem_arm.c;h=70798effe39c1646377b3d897c4b35910c04a8de;hb=HEAD;hp=a7bdfbda66e5178c0efc8fe4fa034c104f33a129;hpb=de6dbc5289bc76996ad4e3133e0eeb90e13b2ed4;p=pcsx_rearmed.git diff --git a/libpcsxcore/new_dynarec/assem_arm.c b/libpcsxcore/new_dynarec/assem_arm.c index a7bdfbda..aabf1c25 100644 --- a/libpcsxcore/new_dynarec/assem_arm.c +++ b/libpcsxcore/new_dynarec/assem_arm.c @@ -19,6 +19,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +#include // ffs #define FLAGLESS #include "../gte.h" #undef FLAGLESS @@ -27,6 +28,10 @@ #include "pcnt.h" #include "arm_features.h" +#ifdef TC_WRITE_OFFSET +#error "not implemented" +#endif + #ifdef DRC_DBG #pragma GCC diagnostic ignored "-Wunused-function" #pragma GCC diagnostic ignored "-Wunused-variable" @@ -81,31 +86,40 @@ void invalidate_addr_r9(); void invalidate_addr_r10(); void invalidate_addr_r12(); -const u_int invalidate_addr_reg[16] = { - (int)invalidate_addr_r0, - (int)invalidate_addr_r1, - (int)invalidate_addr_r2, - (int)invalidate_addr_r3, - (int)invalidate_addr_r4, - (int)invalidate_addr_r5, - (int)invalidate_addr_r6, - (int)invalidate_addr_r7, - (int)invalidate_addr_r8, - (int)invalidate_addr_r9, - (int)invalidate_addr_r10, +const void *invalidate_addr_reg[16] = { + invalidate_addr_r0, + invalidate_addr_r1, + invalidate_addr_r2, + invalidate_addr_r3, + invalidate_addr_r4, + invalidate_addr_r5, + invalidate_addr_r6, + invalidate_addr_r7, + invalidate_addr_r8, + invalidate_addr_r9, + invalidate_addr_r10, 0, - (int)invalidate_addr_r12, + invalidate_addr_r12, 0, 0, - 0}; + 0 +}; /* Linker */ +static void set_jump_target_far1(u_int *insn, void *target) +{ + u_int ni = *insn & 0xff000000; + ni |= (((u_int)target - (u_int)insn - 8u) << 6) >> 8; + assert((ni & 0x0e000000) == 0x0a000000); + *insn = ni; +} + static void set_jump_target(void *addr, void *target_) { - u_int target = (u_int)target_; - u_char *ptr = addr; - u_int *ptr2=(u_int *)ptr; + const u_int target = (u_int)target_; + const u_char *ptr = addr; + u_int *ptr2 = (u_int *)ptr; if(ptr[3]==0xe2) { assert((target-(u_int)ptr2-8)<1024); assert(((uintptr_t)addr&3)==0); @@ -128,8 +142,7 @@ static void set_jump_target(void *addr, void *target_) else *ptr2=(0x7A000000)|(((target-(u_int)ptr2-8)<<6)>>8); } else { - assert((ptr[3]&0x0e)==0xa); - *ptr2=(*ptr2&0xFF000000)|(((target-(u_int)ptr2-8)<<6)>>8); + set_jump_target_far1(ptr2, target_); } } @@ -188,20 +201,6 @@ static void *find_extjump_insn(void *stub) return *l_ptr; } -// find where external branch is liked to using addr of it's stub: -// get address that insn one after stub loads (dyna_linker arg1), -// treat it as a pointer to branch insn, -// return addr where that branch jumps to -#if 0 -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); // b - return (u_char *)i_ptr+((*i_ptr<<8)>>6)+8; -} -#endif - // Allocate a specific ARM register. static void alloc_arm_reg(struct regstat *cur,int i,signed char reg,int hr) { @@ -217,21 +216,31 @@ static void alloc_arm_reg(struct regstat *cur,int i,signed char reg,int hr) } } - cur->regmap[hr]=reg; - cur->dirty&=~(1<dirty|=dirty<isconst&=~(1<regmap[hr] < 0 || !((cur->noevict >> hr) & 1)); + cur->regmap[hr] = reg; + cur->dirty &= ~(1 << hr); + cur->dirty |= dirty << hr; + cur->isconst &= ~(1u << hr); + cur->noevict |= 1u << hr; } // Alloc cycle count into dedicated register -static void alloc_cc(struct regstat *cur,int i) +static void alloc_cc(struct regstat *cur, int i) { - alloc_arm_reg(cur,i,CCREG,HOST_CCREG); + alloc_arm_reg(cur, i, CCREG, HOST_CCREG); +} + +static void alloc_cc_optional(struct regstat *cur, int i) +{ + if (cur->regmap[HOST_CCREG] < 0) { + alloc_arm_reg(cur, i, CCREG, HOST_CCREG); + cur->noevict &= ~(1u << HOST_CCREG); + } } /* Assembler */ -static unused char regname[16][4] = { +static attr_unused char regname[16][4] = { "r0", "r1", "r2", @@ -307,7 +316,7 @@ static u_int genjmp(u_int addr) return ((u_int)offset>>2)&0xffffff; } -static unused void emit_breakpoint(void) +static attr_unused void emit_breakpoint(void) { assem_debug("bkpt #0\n"); //output_w32(0xe1200070); @@ -459,15 +468,15 @@ static void emit_loadreg(int r, int hr) static void emit_storereg(int r, int hr) { assert(hr != EXCLUDE_REG); - int addr = (int)&psxRegs.GPR.r[r]; + void *addr; switch (r) { //case HIREG: addr = &hi; break; //case LOREG: addr = &lo; break; - case CCREG: addr = (int)&cycle_count; break; - default: assert(r < 34); break; + case CCREG: addr = &cycle_count; break; + default: assert(r < 34u); addr = &psxRegs.GPR.r[r]; break; } - u_int offset = addr-(u_int)&dynarec_local; - assert(offset<4096); + uintptr_t offset = (char *)addr - (char *)&dynarec_local; + assert(offset < 4096u); assem_debug("str %s,fp+%d # r%d\n",regname[hr],offset,r); output_w32(0xe5800000|rd_rn_rm(hr,FP,0)|offset); } @@ -719,7 +728,7 @@ static void emit_lsls_imm(int rs,int imm,int rt) output_w32(0xe1b00000|rd_rn_rm(rt,0,rs)|(imm<<7)); } -static unused void emit_lslpls_imm(int rs,int imm,int rt) +static attr_unused void emit_lslpls_imm(int rs,int imm,int rt) { assert(imm>0); assert(imm<32); @@ -801,7 +810,7 @@ static void emit_sar(u_int rs,u_int shift,u_int rt) output_w32(0xe1a00000|rd_rn_rm(rt,0,rs)|0x50|(shift<<8)); } -static unused void emit_orrshl(u_int rs,u_int shift,u_int rt) +static attr_unused void emit_orrshl(u_int rs,u_int shift,u_int rt) { assert(rs<16); assert(rt<16); @@ -810,7 +819,7 @@ static unused void emit_orrshl(u_int rs,u_int shift,u_int rt) output_w32(0xe1800000|rd_rn_rm(rt,rt,rs)|0x10|(shift<<8)); } -static unused void emit_orrshr(u_int rs,u_int shift,u_int rt) +static attr_unused void emit_orrshr(u_int rs,u_int shift,u_int rt) { assert(rs<16); assert(rt<16); @@ -881,7 +890,7 @@ static void emit_cmovs_imm(int imm,int rt) output_w32(0x43a00000|rd_rn_rm(rt,0,0)|armval); } -static unused void emit_cmovne_reg(int rs,int rt) +static attr_unused void emit_cmovne_reg(int rs,int rt) { assem_debug("movne %s,%s\n",regname[rt],regname[rs]); output_w32(0x11a00000|rd_rn_rm(rt,0,rs)); @@ -976,7 +985,7 @@ static int can_jump_or_call(const void *a) static void emit_call(const void *a_) { int a = (int)a_; - assem_debug("bl %x (%x+%x)%s\n",a,(int)out,a-(int)out-8,func_name(a_)); + assem_debug("bl %p%s\n", log_addr(a), func_name(a_)); u_int offset=genjmp(a); output_w32(0xeb000000|offset); } @@ -984,7 +993,7 @@ static void emit_call(const void *a_) static void emit_jmp(const void *a_) { int a = (int)a_; - assem_debug("b %x (%x+%x)%s\n",a,(int)out,a-(int)out-8,func_name(a_)); + assem_debug("b %p%s\n", log_addr(a_), func_name(a_)); u_int offset=genjmp(a); output_w32(0xea000000|offset); } @@ -992,7 +1001,7 @@ static void emit_jmp(const void *a_) static void emit_jne(const void *a_) { int a = (int)a_; - assem_debug("bne %x\n",a); + assem_debug("bne %p\n", log_addr(a_)); u_int offset=genjmp(a); output_w32(0x1a000000|offset); } @@ -1000,7 +1009,7 @@ static void emit_jne(const void *a_) static void emit_jeq(const void *a_) { int a = (int)a_; - assem_debug("beq %x\n",a); + assem_debug("beq %p\n", log_addr(a_)); u_int offset=genjmp(a); output_w32(0x0a000000|offset); } @@ -1008,7 +1017,7 @@ static void emit_jeq(const void *a_) static void emit_js(const void *a_) { int a = (int)a_; - assem_debug("bmi %x\n",a); + assem_debug("bmi %p\n", log_addr(a_)); u_int offset=genjmp(a); output_w32(0x4a000000|offset); } @@ -1016,7 +1025,7 @@ static void emit_js(const void *a_) static void emit_jns(const void *a_) { int a = (int)a_; - assem_debug("bpl %x\n",a); + assem_debug("bpl %p\n", log_addr(a_)); u_int offset=genjmp(a); output_w32(0x5a000000|offset); } @@ -1024,7 +1033,7 @@ static void emit_jns(const void *a_) static void emit_jl(const void *a_) { int a = (int)a_; - assem_debug("blt %x\n",a); + assem_debug("blt %p\n", log_addr(a_)); u_int offset=genjmp(a); output_w32(0xba000000|offset); } @@ -1032,7 +1041,7 @@ static void emit_jl(const void *a_) static void emit_jge(const void *a_) { int a = (int)a_; - assem_debug("bge %x\n",a); + assem_debug("bge %p\n", log_addr(a_)); u_int offset=genjmp(a); output_w32(0xaa000000|offset); } @@ -1040,7 +1049,7 @@ static void emit_jge(const void *a_) static void emit_jo(const void *a_) { int a = (int)a_; - assem_debug("bvs %x\n",a); + assem_debug("bvs %p\n", log_addr(a_)); u_int offset=genjmp(a); output_w32(0x6a000000|offset); } @@ -1048,7 +1057,7 @@ static void emit_jo(const void *a_) static void emit_jno(const void *a_) { int a = (int)a_; - assem_debug("bvc %x\n",a); + assem_debug("bvc %p\n", log_addr(a_)); u_int offset=genjmp(a); output_w32(0x7a000000|offset); } @@ -1056,7 +1065,7 @@ static void emit_jno(const void *a_) static void emit_jc(const void *a_) { int a = (int)a_; - assem_debug("bcs %x\n",a); + assem_debug("bcs %p\n", log_addr(a_)); u_int offset=genjmp(a); output_w32(0x2a000000|offset); } @@ -1064,7 +1073,7 @@ static void emit_jc(const void *a_) static void emit_jcc(const void *a_) { int a = (int)a_; - assem_debug("bcc %x\n",a); + assem_debug("bcc %p\n", log_addr(a_)); u_int offset=genjmp(a); output_w32(0x3a000000|offset); } @@ -1078,7 +1087,7 @@ static void *emit_cbz(int rs, const void *a) return ret; } -static unused void emit_callreg(u_int r) +static attr_unused void emit_callreg(u_int r) { assert(r<15); assem_debug("blx %s\n",regname[r]); @@ -1393,7 +1402,7 @@ static void emit_teq(int rs, int rt) output_w32(0xe1300000|rd_rn_rm(0,rs,rt)); } -static unused void emit_rsbimm(int rs, int imm, int rt) +static attr_unused void emit_rsbimm(int rs, int imm, int rt) { u_int armval; genimm_checked(imm,&armval); @@ -1443,15 +1452,16 @@ static void emit_ldrb_indexedsr12_reg(int base, int r, int rt) output_w32(0xe7d00000|rd_rn_rm(rt,base,r)|0x620); } -static void emit_callne(int a) +static void emit_callne(const void *a_) { - assem_debug("blne %x\n",a); + int a = (int)a_; + assem_debug("blne %p\n", log_addr(a_)); u_int offset=genjmp(a); output_w32(0x1b000000|offset); } // Used to preload hash table entries -static unused void emit_prefetchreg(int r) +static attr_unused void emit_prefetchreg(int r) { assem_debug("pld %s\n",regname[r]); output_w32(0xf5d0f000|rd_rn_rm(0,r,0)); @@ -1473,7 +1483,7 @@ static void emit_orrne_imm(int rs,int imm,int rt) output_w32(0x13800000|rd_rn_rm(rt,rs,0)|armval); } -static unused void emit_addpl_imm(int rs,int imm,int rt) +static attr_unused void emit_addpl_imm(int rs,int imm,int rt) { u_int armval; genimm_checked(imm,&armval); @@ -1481,10 +1491,11 @@ static unused void emit_addpl_imm(int rs,int imm,int rt) output_w32(0x52800000|rd_rn_rm(rt,rs,0)|armval); } -static void emit_jno_unlikely(int a) +static void emit_jno_unlikely(void *a_) { - //emit_jno(a); - assem_debug("addvc pc,pc,#? (%x)\n",/*a-(int)out-8,*/a); + //emit_jno(a_); + assert(a_ == NULL); + assem_debug("addvc pc,pc,#? (%p)\n", /*a-(int)out-8,*/ log_addr(a_)); output_w32(0x72800000|rd_rn_rm(15,15,0)); } @@ -1572,7 +1583,7 @@ static void literal_pool_jumpover(int n) set_jump_target(jaddr, out); } -// parsed by get_pointer, find_extjump_insn +// parsed by find_extjump_insn, check_extjump2 static void emit_extjump(u_char *addr, u_int target) { u_char *ptr=(u_char *)addr; @@ -1654,7 +1665,7 @@ static void mov_loadtype_adj(enum stub_type type,int rs,int rt) static void do_readstub(int n) { - assem_debug("do_readstub %x\n",start+stubs[n].a*4); + assem_debug("do_readstub %p\n", log_addr(start + stubs[n].a*4)); literal_pool(256); set_jump_target(stubs[n].addr, out); enum stub_type type=stubs[n].type; @@ -1724,6 +1735,14 @@ static void do_readstub(int n) emit_loadreg(CCREG,2); emit_addimm(cc<0?2:cc,(int)stubs[n].d,2); emit_far_call(handler); +#if 0 + if (type == LOADW_STUB) { + // new cycle_count returned in r2 + emit_addimm(2, -(int)stubs[n].d, cc<0?2:cc); + if (cc < 0) + emit_storereg(CCREG, 2); + } +#endif if(dops[i].itype==C2LS||(rt>=0&&dops[i].rt1!=0)) { mov_loadtype_adj(type,0,rt); } @@ -1794,6 +1813,14 @@ static void inline_readstub(enum stub_type type, int i, u_int addr, emit_far_call(handler); +#if 0 + if (type == LOADW_STUB) { + // new cycle_count returned in r2 + emit_addimm(2, -adj, cc<0?2:cc); + if (cc < 0) + emit_storereg(CCREG, 2); + } +#endif if(rt>=0&&dops[i].rt1!=0) { switch(type) { case LOADB_STUB: emit_signextend8(0,rt); break; @@ -1809,7 +1836,7 @@ static void inline_readstub(enum stub_type type, int i, u_int addr, static void do_writestub(int n) { - assem_debug("do_writestub %x\n",start+stubs[n].a*4); + assem_debug("do_writestub %p\n", log_addr(start + stubs[n].a*4)); literal_pool(256); set_jump_target(stubs[n].addr, out); enum stub_type type=stubs[n].type; @@ -1877,9 +1904,9 @@ static void do_writestub(int n) if(cc<0) emit_loadreg(CCREG,2); emit_addimm(cc<0?2:cc,(int)stubs[n].d,2); - // returns new cycle_count emit_far_call(handler); - emit_addimm(0,-(int)stubs[n].d,cc<0?2:cc); + // new cycle_count returned in r2 + emit_addimm(2,-(int)stubs[n].d,cc<0?2:cc); if(cc<0) emit_storereg(CCREG,2); if(restore_jump) @@ -1917,9 +1944,9 @@ static void inline_writestub(enum stub_type type, int i, u_int addr, emit_loadreg(CCREG,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,-adj,cc<0?2:cc); + // new cycle_count returned in r2 + emit_addimm(2,-adj,cc<0?2:cc); if(cc<0) emit_storereg(CCREG,2); restore_regs(reglist);