diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2023-03-22 14:45:57 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-03-22 07:45:57 +0100 |
| commit | da88b872790f838ad85f979a7153658bf746479a (patch) | |
| tree | b2208597269496685efef03c8f81ee2465ac80d3 /src | |
| parent | 900f38779da63d30625c6951291ce0e39ff3c598 (diff) | |
| download | box64-da88b872790f838ad85f979a7153658bf746479a.tar.gz box64-da88b872790f838ad85f979a7153658bf746479a.zip | |
[RV64_DYNAREC] Added AB STOSD opcode (#611)
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00.c | 26 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 16 |
2 files changed, 40 insertions, 2 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00.c b/src/dynarec/rv64/dynarec_rv64_00.c index b6153b06..9b0c4a63 100644 --- a/src/dynarec/rv64/dynarec_rv64_00.c +++ b/src/dynarec/rv64/dynarec_rv64_00.c @@ -644,7 +644,31 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni MOV64xw(x2, i64); emit_test32(dyn, ninst, rex, xRAX, x2, x3, x4, x5); break; - + case 0xAB: + if(rep) { + INST_NAME("REP STOSD"); + CBZ_NEXT(xRCX); + ANDI(x1, xFlags, 1<<F_DF); + BNEZ_MARK2(x1); + MARK; // Part with DF==0 + SDxw(xRAX, xRDI, 0); + ADDI(xRDI, xRDI, rex.w?8:4); + ADDI(xRCX, xRCX, -1); + BNEZ_MARK(xRCX); + B_NEXT_nocond; + MARK2; // Part with DF==1 + SDxw(xRAX, xRDI, 0); + ADDI(xRDI, xRDI, rex.w?-8:-4); + ADDI(xRCX, xRCX, -1); + BNEZ_MARK2(xRCX); + // done + } else { + INST_NAME("STOSD"); + GETDIR(x3, x1, rex.w?8:4); + SDxw(xRAX, xRDI, 0); + ADD(xRDI, xRDI, x3); + } + break; case 0xB0: case 0xB1: case 0xB2: diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index e8e2cf6c..fd369085 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -244,6 +244,14 @@ OR(wback, wback, ed); \ } +// Get direction with size Z and based of F_DF flag, on register r ready for load/store fetching +// using s as scratch. +#define GETDIR(r, s, Z) \ + MOV32w(r, Z); /* mask=1<<10 */ \ + ANDI(s, xFlags, 1<<F_DF); \ + BEQZ(s, 8); \ + SUB(r, xZR, r); \ + // CALL will use x6 for the call address. Return value can be put in ret (unless ret is -1) // R0 will not be pushed/popd if ret is -2 #define CALL(F, ret) call_c(dyn, ninst, F, x6, ret, 1, 0) @@ -275,6 +283,8 @@ #define BEQ_MARK(reg1, reg2) Bxx_gen(EQ, MARK, reg1, reg2) // Branch to MARK if reg1!=reg2 (use j64) #define BNE_MARK(reg1, reg2) Bxx_gen(NE, MARK, reg1, reg2) +// Branch to MARK if reg1!=0 (use j64) +#define BNEZ_MARK(reg) BNE_MARK(reg, xZR) // Branch to MARK if reg1<reg2 (use j64) #define BLT_MARK(reg1, reg2) Bxx_gen(LT, MARK, reg1, reg2) // Branch to MARK if reg1>=reg2 (use j64) @@ -283,12 +293,16 @@ #define BEQ_MARK2(reg1, reg2) Bxx_gen(EQ, MARK2, reg1,reg2) // Branch to MARK2 if reg1!=reg2 (use j64) #define BNE_MARK2(reg1, reg2) Bxx_gen(NE, MARK2, reg1,reg2) -// Branch to MARK2 if reg1<>reg2 (use j64) +// Branch to MARK2 if reg1!=0 (use j64) +#define BNEZ_MARK2(reg) BNE_MARK2(reg, xZR) +// Branch to MARK2 if reg1<reg2 (use j64) #define BLT_MARK2(reg1, reg2) Bxx_gen(LT, MARK2, reg1,reg2) // Branch to MARK3 if reg1==reg2 (use j64) #define BEQ_MARK3(reg1, reg2) Bxx_gen(EQ, MARK3, reg1, reg2) // Branch to MARK3 if reg1!=reg2 (use j64) #define BNE_MARK3(reg1, reg2) Bxx_gen(NE, MARK3, reg1, reg2) +// Branch to MARK3 if reg1!=0 (use j64) +#define BNEZ_MARK3(reg) BNE_MARK3(reg, xZR) // Branch to MARKLOCK if reg1!=reg2 (use j64) #define BNE_MARKLOCK(reg1, reg2) Bxx_gen(NE, MARKLOCK, reg1, reg2) // Branch to MARKLOCK if reg1!=0 (use j64) |