Skip to content

Commit

Permalink
new_dynarec: Fix regression on arm64 caused by 26cc980
Browse files Browse the repository at this point in the history
  • Loading branch information
Gillou68310 committed Jan 29, 2019
1 parent ca1888d commit 0666982
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 60 deletions.
21 changes: 6 additions & 15 deletions src/device/r4300/new_dynarec/arm/assem_arm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2245,6 +2245,12 @@ static void emit_addsr12(int rs1,int rs2,int rt)
output_w32(0xe0800620|rd_rn_rm(rt,rs1,rs2));
}

static void emit_addsl2(int rs1,int rs2,int rt)
{
assem_debug("add %s,%s,%s lsl #2",regname[rt],regname[rs1],regname[rs2]);
output_w32(0xe0800100|rd_rn_rm(rt,rs1,rs2));
}

static void emit_callne(int a)
{
assem_debug("blne %x",a);
Expand Down Expand Up @@ -3066,21 +3072,6 @@ static void do_tlb_w_branch_debug(int map, int c, u_int addr, int *jaddr)
}
}

static void gen_addr(int ar, int map) {
if(map>=0) {
assem_debug("add %s,%s,%s lsl #2",regname[ar],regname[ar],regname[map]);
output_w32(0xe0800100|rd_rn_rm(ar,ar,map));
}
}

// This reverses the above operation
static void gen_orig_addr(int ar, int map) {
if(map>=0) {
assem_debug("sub %s,%s,%s lsl #2",regname[ar],regname[ar],regname[map]);
output_w32(0xe0400100|rd_rn_rm(ar,ar,map));
}
}

// Generate the address of the memory_map entry, relative to dynarec_local
static void generate_map_const(u_int addr,int reg) {
//DebugMessage(M64MSG_VERBOSE, "generate_map_const(%x,%s)",addr,regname[reg]);
Expand Down
24 changes: 8 additions & 16 deletions src/device/r4300/new_dynarec/arm64/assem_arm64.c
Original file line number Diff line number Diff line change
Expand Up @@ -1517,7 +1517,8 @@ static void emit_andimm(int rs,int imm,int rt)
static void emit_andimm64(int rs,int64_t imm,int rt)
{
u_int armval;
assert(genimm((uint64_t)imm,64,&armval));
uint32_t ret=genimm((uint64_t)imm,64,&armval);
assert(ret);
assem_debug("and %s,%s,#%d",regname64[rt],regname64[rs],imm);
output_w32(0x92000000|armval<<10|rs<<5|rt);
}
Expand Down Expand Up @@ -2498,6 +2499,12 @@ static void emit_addsr12(int rs1,int rs2,int rt)
output_w32(0x0b400000|rs2<<16|12<<10|rs1<<5|rt);
}

static void emit_addsl2(int rs1,int rs2,int rt)
{
assem_debug("add %s,%s,%s lsl #2",regname64[rt],regname64[rs1],regname64[rs2]);
output_w32(0x8b000000|rs2<<16|2<<10|rs1<<5|rt);
}

#ifdef HAVE_CONDITIONAL_CALL
static void emit_callne(intptr_t a)
{
Expand Down Expand Up @@ -3585,21 +3592,6 @@ static void do_tlb_w_branch_debug(int map, int c, u_int addr, intptr_t *jaddr)
}
}

static void gen_addr(int ar, int map) {
if(map>=0) {
assem_debug("add %s,%s,%s lsl #2",regname64[ar],regname64[ar],regname64[map]);
output_w32(0x8b000000|map<<16|2<<10|ar<<5|ar);
}
}

// This reverses the above operation
static void gen_orig_addr(int ar, int map) {
if(map>=0) {
assem_debug("sub %s,%s,%s lsl #2",regname64[ar],regname64[ar],regname64[map]);
output_w32(0xcb000000|map<<16|2<<10|ar<<5|ar);
}
}

// Generate the address of the memory_map entry, relative to dynarec_local
static void generate_map_const(u_int addr,int tr) {
//DebugMessage(M64MSG_VERBOSE, "generate_map_const(%x,%s)",addr,regname[tr]);
Expand Down
68 changes: 39 additions & 29 deletions src/device/r4300/new_dynarec/new_dynarec.c
Original file line number Diff line number Diff line change
Expand Up @@ -4222,7 +4222,7 @@ static void store_assemble(int i,struct regstat *i_regs)
static void storelr_assemble(int i,struct regstat *i_regs)
{
int s,th,tl;
int temp;
int temp,real_temp;
int temp2;
int map=-1;
int offset;
Expand Down Expand Up @@ -4279,34 +4279,37 @@ static void storelr_assemble(int i,struct regstat *i_regs)
emit_jmp(0);
}
}
real_temp=temp;
#if NEW_DYNAREC >= NEW_DYNAREC_ARM
gen_addr(temp,map);
map=-1;
if(map>=0){
emit_addsl2(real_temp,map,map);
temp=map; map=-1;
}
#endif

if (opcode[i]==0x2C||opcode[i]==0x2D) { // SDL/SDR
temp2=get_reg(i_regs->regmap,FTEMP);
if(!rs2[i]) temp2=th=tl;
}

emit_testimm(temp,2);
emit_testimm(real_temp,2);
case2=(intptr_t)out;
emit_jne(0);
emit_testimm(temp,1);
emit_testimm(real_temp,1);
case1=(intptr_t)out;
emit_jne(0);
// 0
if (opcode[i]==0x2A) { // SWL
emit_writeword_indexed_tlb(tl,0,temp,map);
}
if (opcode[i]==0x2E) { // SWR
else if (opcode[i]==0x2E) { // SWR
emit_writebyte_indexed_tlb(tl,3,temp,map);
}
if (opcode[i]==0x2C) { // SDL
else if (opcode[i]==0x2C) { // SDL
emit_writeword_indexed_tlb(th,0,temp,map);
if(rs2[i]) emit_mov(tl,temp2);
}
if (opcode[i]==0x2D) { // SDR
else if (opcode[i]==0x2D) { // SDR
emit_writebyte_indexed_tlb(tl,3,temp,map);
if(rs2[i]) emit_shldimm(th,tl,24,temp2);
}
Expand All @@ -4322,11 +4325,11 @@ static void storelr_assemble(int i,struct regstat *i_regs)
emit_writebyte_indexed_tlb(tl,1,temp,map);
if(rs2[i]) emit_rorimm(tl,8,tl);
}
if (opcode[i]==0x2E) { // SWR
else if (opcode[i]==0x2E) { // SWR
// Write two lsb into two most significant bytes
emit_writehword_indexed_tlb(tl,1,temp,map);
}
if (opcode[i]==0x2C) { // SDL
else if (opcode[i]==0x2C) { // SDL
if(rs2[i]) emit_shrdimm(tl,th,8,temp2);
// Write 3 msb into three least significant bytes
if(rs2[i]) emit_rorimm(th,8,th);
Expand All @@ -4335,7 +4338,7 @@ static void storelr_assemble(int i,struct regstat *i_regs)
emit_writebyte_indexed_tlb(th,1,temp,map);
if(rs2[i]) emit_rorimm(th,8,th);
}
if (opcode[i]==0x2D) { // SDR
else if (opcode[i]==0x2D) { // SDR
if(rs2[i]) emit_shldimm(th,tl,16,temp2);
// Write two lsb into two most significant bytes
emit_writehword_indexed_tlb(tl,1,temp,map);
Expand All @@ -4344,7 +4347,7 @@ static void storelr_assemble(int i,struct regstat *i_regs)
emit_jmp(0);
// 2
set_jump_target(case2,(intptr_t)out);
emit_testimm(temp,1);
emit_testimm(real_temp,1);
case3=(intptr_t)out;
emit_jne(0);
if (opcode[i]==0x2A) { // SWL
Expand All @@ -4353,21 +4356,21 @@ static void storelr_assemble(int i,struct regstat *i_regs)
emit_writehword_indexed_tlb(tl,-2,temp,map);
if(rs2[i]) emit_rorimm(tl,16,tl);
}
if (opcode[i]==0x2E) { // SWR
else if (opcode[i]==0x2E) { // SWR
// Write 3 lsb into three most significant bytes
emit_writebyte_indexed_tlb(tl,-1,temp,map);
if(rs2[i]) emit_rorimm(tl,8,tl);
emit_writehword_indexed_tlb(tl,0,temp,map);
if(rs2[i]) emit_rorimm(tl,24,tl);
}
if (opcode[i]==0x2C) { // SDL
else if (opcode[i]==0x2C) { // SDL
if(rs2[i]) emit_shrdimm(tl,th,16,temp2);
// Write two msb into two least significant bytes
if(rs2[i]) emit_rorimm(th,16,th);
emit_writehword_indexed_tlb(th,-2,temp,map);
if(rs2[i]) emit_rorimm(th,16,th);
}
if (opcode[i]==0x2D) { // SDR
else if (opcode[i]==0x2D) { // SDR
if(rs2[i]) emit_shldimm(th,tl,8,temp2);
// Write 3 lsb into three most significant bytes
emit_writebyte_indexed_tlb(tl,-1,temp,map);
Expand All @@ -4385,18 +4388,18 @@ static void storelr_assemble(int i,struct regstat *i_regs)
emit_writebyte_indexed_tlb(tl,-3,temp,map);
if(rs2[i]) emit_rorimm(tl,8,tl);
}
if (opcode[i]==0x2E) { // SWR
else if (opcode[i]==0x2E) { // SWR
// Write entire word
emit_writeword_indexed_tlb(tl,-3,temp,map);
}
if (opcode[i]==0x2C) { // SDL
else if (opcode[i]==0x2C) { // SDL
if(rs2[i]) emit_shrdimm(tl,th,24,temp2);
// Write msb into least significant byte
if(rs2[i]) emit_rorimm(th,24,th);
emit_writebyte_indexed_tlb(th,-3,temp,map);
if(rs2[i]) emit_rorimm(th,8,th);
}
if (opcode[i]==0x2D) { // SDR
else if (opcode[i]==0x2D) { // SDR
if(rs2[i]) emit_mov(th,temp2);
// Write entire word
emit_writeword_indexed_tlb(tl,-3,temp,map);
Expand All @@ -4405,44 +4408,51 @@ static void storelr_assemble(int i,struct regstat *i_regs)
set_jump_target(done1,(intptr_t)out);
set_jump_target(done2,(intptr_t)out);
if (opcode[i]==0x2C) { // SDL
emit_testimm(temp,4);
emit_testimm(real_temp,4);
done0=(intptr_t)out;
emit_jne(0);
#if NEW_DYNAREC == NEW_DYNAREC_ARM64
emit_andimm64(temp,~3,temp);
#else
emit_andimm(temp,~3,temp);
#endif
emit_writeword_indexed_tlb(temp2,4,temp,map);
set_jump_target(done0,(intptr_t)out);
}
if (opcode[i]==0x2D) { // SDR
emit_testimm(temp,4);
else if (opcode[i]==0x2D) { // SDR
emit_testimm(real_temp,4);
done0=(intptr_t)out;
emit_jeq(0);
#if NEW_DYNAREC == NEW_DYNAREC_ARM64
emit_andimm64(temp,~3,temp);
#else
emit_andimm(temp,~3,temp);
#endif
emit_writeword_indexed_tlb(temp2,-4,temp,map);
set_jump_target(done0,(intptr_t)out);
}
if(!c||!memtarget)
add_stub(STORELR_STUB,jaddr,(intptr_t)out,0,(intptr_t)i_regs,rs2[i],ccadj[i],reglist);
if(!using_tlb) {
#if NEW_DYNAREC >= NEW_DYNAREC_ARM
map=get_reg(i_regs->regmap,ROREG);
if(map<0) map=HOST_TEMPREG;
gen_orig_addr(temp,map);
if(map>=0) emit_loadreg(ROREG,map);
#endif
#if defined(HOST_IMM8) || defined(NEED_INVC_PTR)
int ir=get_reg(i_regs->regmap,INVCP);
assert(ir>=0);
emit_cmpmem_indexedsr12_reg(ir,temp,1);
emit_cmpmem_indexedsr12_reg(ir,real_temp,1);
#else
emit_cmpmem_indexedsr12_imm((intptr_t)g_dev.r4300.cached_interp.invalid_code,temp,1);
emit_cmpmem_indexedsr12_imm((intptr_t)g_dev.r4300.cached_interp.invalid_code,real_temp,1);
#endif
#if defined(HAVE_CONDITIONAL_CALL) && !defined(DESTRUCTIVE_SHIFT)
emit_callne(invalidate_addr_reg[temp]);
emit_callne(invalidate_addr_reg[real_temp]);
#else
intptr_t jaddr2=(intptr_t)out;
emit_jne(0);
add_stub(INVCODE_STUB,jaddr2,(intptr_t)out,reglist|(1<<HOST_CCREG),temp,0,0,0);
add_stub(INVCODE_STUB,jaddr2,(intptr_t)out,reglist|(1<<HOST_CCREG),real_temp,0,0,0);
#endif
}
if(!c||!memtarget)
add_stub(STORELR_STUB,jaddr,(intptr_t)out,0,(intptr_t)i_regs,rs2[i],ccadj[i],reglist);
}
#endif

Expand Down

0 comments on commit 0666982

Please sign in to comment.