diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-03-18 20:29:41 +0000 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-03-18 20:29:41 +0000 |
| commit | 4409fb9b2112f3572187b7ba58192d7814118cb1 (patch) | |
| tree | 3e6bcab19ff672cdd694a301c8d20e79db94032d /src | |
| parent | e845d022425f68a7ed629a816ce59f118ffe1556 (diff) | |
| download | box64-4409fb9b2112f3572187b7ba58192d7814118cb1.tar.gz box64-4409fb9b2112f3572187b7ba58192d7814118cb1.zip | |
[RV64_DYNAREC] Fixed Jcc opcodes for large block
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00.c | 5 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_0f.c | 4 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 2 | ||||
| -rw-r--r-- | src/dynarec/rv64/rv64_emitter.h | 11 |
4 files changed, 17 insertions, 5 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00.c b/src/dynarec/rv64/dynarec_rv64_00.c index 3279c179..8fb6a9ae 100644 --- a/src/dynarec/rv64/dynarec_rv64_00.c +++ b/src/dynarec/rv64/dynarec_rv64_00.c @@ -263,7 +263,7 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni CHECK_CACHE()) { \ /* out of the block */ \ i32 = dyn->insts[ninst].epilog-(dyn->native_size); \ - B##NO(x1, i32); \ + B##NO##_safe(x1, i32); \ if(dyn->insts[ninst].x64.jmp_insts==-1) { \ if(!(dyn->insts[ninst].x64.barrier&BARRIER_FLOAT)) \ fpu_purgecache(dyn, ninst, 1, x1, x2, x3); \ @@ -276,7 +276,7 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } else { \ /* inside the block */ \ i32 = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address-(dyn->native_size); \ - B##YES(x1, i32); \ + B##YES##_safe(x1, i32); \ } GOCOND(0x70, "J", "ib"); @@ -891,6 +891,7 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni // inside the block CacheTransform(dyn, ninst, CHECK_CACHE(), x1, x2, x3); tmp = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address-(dyn->native_size); + MESSAGE(1, "Jump to %d / 0x%x\n", tmp, tmp); if(tmp==4) { NOP(); } else { diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c index d8cff1e6..f3ae7063 100644 --- a/src/dynarec/rv64/dynarec_rv64_0f.c +++ b/src/dynarec/rv64/dynarec_rv64_0f.c @@ -187,7 +187,7 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni CHECK_CACHE()) { \ /* out of the block */ \ i32 = dyn->insts[ninst].epilog-(dyn->native_size); \ - B##NO(x1, i32); \ + B##NO##_safe(x1, i32); \ if(dyn->insts[ninst].x64.jmp_insts==-1) { \ if(!(dyn->insts[ninst].x64.barrier&BARRIER_FLOAT)) \ fpu_purgecache(dyn, ninst, 1, x1, x2, x3); \ @@ -200,7 +200,7 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } else { \ /* inside the block */ \ i32 = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address-(dyn->native_size); \ - B##YES(x1, i32); \ + B##YES##_safe(x1, i32); \ } GOCOND(0x80, "J", "Id"); diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index f7b15939..4eae5870 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -412,7 +412,7 @@ } #define GETIP_(A) \ if(dyn->last_ip && ((A)-dyn->last_ip)<2048) { \ - uint64_t _delta_ip = (A)-dyn->last_ip; \ + int64_t _delta_ip = (A)-dyn->last_ip; \ if(_delta_ip) {ADDI(xRIP, xRIP, _delta_ip);} \ } else { \ if((A)<0xffffffff) { \ diff --git a/src/dynarec/rv64/rv64_emitter.h b/src/dynarec/rv64/rv64_emitter.h index a7528827..4a87ecba 100644 --- a/src/dynarec/rv64/rv64_emitter.h +++ b/src/dynarec/rv64/rv64_emitter.h @@ -215,9 +215,20 @@ f28–31 ft8–11 FP temporaries Caller #define BLTU(rs1, rs2, imm13) EMIT(B_type(imm13, rs2, rs1, 0b110, 0b1100011)) #define BGEU(rs1, rs2, imm13) EMIT(B_type(imm13, rs2, rs1, 0b111, 0b1100011)) +// TODO: Find a better way to have conditionnal jumps? +#define BEQ_safe(rs1, rs2, imm) if(imm>=-0x1000 && imm<=0x1000) {BEQ(rs1, rs2, imm); NOP();} else {BNE(rs1, rs2, 8); B(imm);} +#define BNE_safe(rs1, rs2, imm) if(imm>=-0x1000 && imm<=0x1000) {BNE(rs1, rs2, imm); NOP();} else {BEQ(rs1, rs2, 8); B(imm);} +#define BLT_safe(rs1, rs2, imm) if(imm>=-0x1000 && imm<=0x1000) {BLT(rs1, rs2, imm); NOP();} else {BGE(rs2, rs1, 8); B(imm);} +#define BGE_safe(rs1, rs2, imm) if(imm>=-0x1000 && imm<=0x1000) {BGE(rs1, rs2, imm); NOP();} else {BLT(rs2, rs1, 8); B(imm);} +#define BLTU_safe(rs1, rs2, imm) if(imm>=-0x1000 && imm<=0x1000) {BLTU(rs1, rs2, imm); NOP();} else {BGEU(rs2, rs1, 8); B(imm);} +#define BGEU_safe(rs1, rs2, imm) if(imm>=-0x1000 && imm<=0x1000) {BGEU(rs1, rs2, imm); NOP();} else {BLTU(rs2, rs1, 8); B(imm);} + #define BEQZ(rs1, imm13) BEQ(rs1, 0, imm13) #define BNEZ(rs1, imm13) BNE(rs1, 0, imm13) +#define BEQZ_safe(rs1, imm) if(imm>=-0x1000 && imm<=0x1000) {BEQZ(rs1, imm); NOP();} else {BNEZ(rs1, 8); B(imm);} +#define BNEZ_safe(rs1, imm) if(imm>=-0x1000 && imm<=0x1000) {BNEZ(rs1, imm); NOP();} else {BEQZ(rs1, 8); B(imm);} + // rd = 4-bytes[rs1+imm12] signed extended #define LW(rd, rs1, imm12) EMIT(I_type(imm12, rs1, 0b010, rd, 0b0000011)) // rd = 2-bytes[rs1+imm12] signed extended |