From 281065b5d409cb2be2d87a37f561a96fff495ccc Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Wed, 15 Mar 2023 21:43:00 +0000 Subject: [RV64_DYNAREC] Added CC (and NativeCall) opcode, and shuffle around some xFlags /xRIP and x6 mapping --- src/dynarec/rv64/dynarec_rv64_00.c | 59 ++++++++++++++++++++++++++++++++++ src/dynarec/rv64/dynarec_rv64_helper.h | 4 +++ src/dynarec/rv64/rv64_emitter.h | 8 ++--- src/dynarec/rv64/rv64_epilog.S | 14 ++++---- src/dynarec/rv64/rv64_next.S | 7 ++-- src/dynarec/rv64/rv64_prolog.S | 16 ++++----- 6 files changed, 84 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/dynarec/rv64/dynarec_rv64_00.c b/src/dynarec/rv64/dynarec_rv64_00.c index 6bdb9c1b..0adae90a 100644 --- a/src/dynarec/rv64/dynarec_rv64_00.c +++ b/src/dynarec/rv64/dynarec_rv64_00.c @@ -259,6 +259,65 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } break; + case 0xCC: + SETFLAGS(X_ALL, SF_SET); // Hack, set all flags (to an unknown state...) + if(PK(0)=='S' && PK(1)=='C') { + addr+=2; + BARRIER(BARRIER_FLOAT); + INST_NAME("Special Box64 instruction"); + if((PK64(0)==0)) + { + addr+=8; + MESSAGE(LOG_DEBUG, "Exit x64 Emu\n"); + //GETIP(ip+1+2); // no use + //STORE_XEMU_REGS(xRIP); // no need, done in epilog + MOV64x(x1, 1); + SW(x1, xEmu, offsetof(x64emu_t, quit)); + *ok = 0; + *need_epilog = 1; + } else { + MESSAGE(LOG_DUMP, "Native Call to %s\n", GetNativeName(GetNativeFnc(ip))); + //x87_forget(dyn, ninst, x3, x4, 0); + //sse_purge07cache(dyn, ninst, x3); + tmp = isSimpleWrapper(*(wrapper_t*)(addr)); + if((box64_log<2 && !cycle_log) && tmp) { + //GETIP(ip+3+8+8); // read the 0xCC + call_n(dyn, ninst, *(void**)(addr+8), tmp); + addr+=8+8; + } else { + GETIP(ip+1); // read the 0xCC + STORE_XEMU_CALL(); + ADDI(x1, xEmu, (uint32_t)offsetof(x64emu_t, ip)); // setup addr as &emu->ip + CALL_S(x64Int3, -1); + LOAD_XEMU_CALL(); + addr+=8+8; + TABLE64(x3, addr); // expected return address + BNE_MARK(xRIP, x3); + LW(w1, xEmu, offsetof(x64emu_t, quit)); + CBZ_NEXT(w1); + MARK; + LOAD_XEMU_REM(); + jump_to_epilog(dyn, 0, xRIP, ninst); + } + } + } else { + #if 1 + INST_NAME("INT 3"); + // check if TRAP signal is handled + LD(x1, xEmu, offsetof(x64emu_t, context)); + MOV64x(x2, offsetof(box64context_t, signals[SIGTRAP])); + ADD(x2, x2, x1); + LD(x3, x2, 0); + CBNZ_NEXT(x3); + MOV64x(x1, SIGTRAP); + CALL_(raise, -1, 0); + break; + #else + DEFAULT; + #endif + } + break; + case 0xE8: INST_NAME("CALL Id"); i32 = F32S; diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index c50a3e20..e08b2e49 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -133,6 +133,10 @@ #define CBZ_NEXT(reg1) \ j64 = (dyn->insts)?(dyn->insts[ninst].epilog-(dyn->native_size)):0; \ BEQ(reg1, xZR, j64) +// Branch to NEXT if reg1!=0 (use j64) +#define CBNZ_NEXT(reg1) \ + j64 = (dyn->insts)?(dyn->insts[ninst].epilog-(dyn->native_size)):0; \ + BNE(reg1, xZR, j64) #define IFX(A) if((dyn->insts[ninst].x64.gen_flags&(A))) #define IFX_PENDOR0 if((dyn->insts[ninst].x64.gen_flags&(X_PEND) || !dyn->insts[ninst].x64.gen_flags)) diff --git a/src/dynarec/rv64/rv64_emitter.h b/src/dynarec/rv64/rv64_emitter.h index 566613fe..24f36f52 100644 --- a/src/dynarec/rv64/rv64_emitter.h +++ b/src/dynarec/rv64/rv64_emitter.h @@ -46,8 +46,8 @@ f28–31 ft8–11 FP temporaries Caller #define xR13 29 #define xR14 30 #define xR15 31 -#define xFlags 5 -#define xRIP 6 +#define xFlags 8 +#define xRIP 7 // 32bits version #define wEAX xRAX @@ -73,9 +73,9 @@ f28–31 ft8–11 FP temporaries Caller #define x3 13 #define x4 14 #define x5 15 -#define x6 8 +#define x6 6 // used to clear the upper 32bits -#define xMASK 7 +#define xMASK 5 // 32bits version of scratch #define w1 x1 #define w2 x2 diff --git a/src/dynarec/rv64/rv64_epilog.S b/src/dynarec/rv64/rv64_epilog.S index cf40153c..fcaf646a 100644 --- a/src/dynarec/rv64/rv64_epilog.S +++ b/src/dynarec/rv64/rv64_epilog.S @@ -26,13 +26,13 @@ rv64_epilog: sd x30, 112(a0) sd x31, 120(a0) // adjust flags bit 5 -> bit 11 - li x7, ~(1<<11) - and x5, x5, x7 - andi x7, x5, 1<<5 - slli x7, x7, 11-5 - or x5, x5, x7 - sd x5, 128(a0) //xFlags - sd x6, 136(a0) // put back reg value in emu, including EIP (so x27 must be EIP now) + li x5, ~(1<<11) + and x8, x8, x5 + andi x5, x8, 1<<5 + slli x5, x5, 11-5 + or x8, x8, x5 + sd x8, 128(a0) //xFlags + sd x7, 136(a0) // put back reg value in emu, including EIP (so x27 must be EIP now) //restore all used register ld ra, (sp) // save ra ld x8, 8(sp) // save fp diff --git a/src/dynarec/rv64/rv64_next.S b/src/dynarec/rv64/rv64_next.S index d9cab836..ce34bb7f 100644 --- a/src/dynarec/rv64/rv64_next.S +++ b/src/dynarec/rv64/rv64_next.S @@ -18,7 +18,7 @@ rv64_next: sd a0, (sp) sd a1, 8(sp) sd x5, 16(sp) - sd x6, 24(sp) + sd x7, 24(sp) sd x16, 32(sp) sd x17, 40(sp) sd x28, 48(sp) @@ -38,7 +38,7 @@ rv64_next: ld a0, (sp) ld a1, 8(sp) ld x5, 16(sp) - ld x6, 24(sp) + ld x7, 24(sp) ld x16, 32(sp) ld x17, 40(sp) ld x28, 48(sp) @@ -46,9 +46,6 @@ rv64_next: ld x30, 64(sp) ld x31, 72(sp) addi sp, sp, (8 * 10) - // setup xMASK - xori x7, x0, -1 - srli x7, x7, 32 // return offset is jump address jr a3 diff --git a/src/dynarec/rv64/rv64_prolog.S b/src/dynarec/rv64/rv64_prolog.S index dd99cfec..06d275b7 100644 --- a/src/dynarec/rv64/rv64_prolog.S +++ b/src/dynarec/rv64/rv64_prolog.S @@ -44,15 +44,15 @@ rv64_prolog: ld x29, 104(a0) ld x30, 112(a0) ld x31, 120(a0) - ld x5, 128(a0) //xFlags - ld x6, 136(a0) // xRIP + ld x8, 128(a0) //xFlags + ld x7, 136(a0) // xRIP // // adjust flags bit 11 -> bit 5 - andi x5, x5, ~(1<<5) // probably not usefull? - srli x7, x5, 11-5 - andi x7, x7, 1<<5 - or x5, x5, x7 + andi x8, x8, ~(1<<5) // probably not usefull? + srli x5, x8, 11-5 + andi x5, x5, 1<<5 + or x8, x8, x5 // setup xMASK - xori x7, x0, -1 - srli x7, x7, 32 + xori x5, x0, -1 + srli x5, x5, 32 // jump to block jalr a1 -- cgit 1.4.1