diff options
| author | xctan <xctan@cirno.icu> | 2023-03-27 16:00:39 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-03-27 10:00:39 +0200 |
| commit | cca1fd6f1987acc5fe7180a3925bbe8b1f34ccd0 (patch) | |
| tree | e89709c3c7f47d02ff0a7bde36e19102adcaee67 /src | |
| parent | 4fb126635c153b9bda9992e9d9d6483a0ca230f3 (diff) | |
| download | box64-cca1fd6f1987acc5fe7180a3925bbe8b1f34ccd0.tar.gz box64-cca1fd6f1987acc5fe7180a3925bbe8b1f34ccd0.zip | |
[RV64_DYNAREC] Added D8 /0 FADD opcode (#642)
* [RV64_DYNAREC] Fix broken x87_get_cache() * [RV64_DYNAREC] Added D8 /0 FADD opcode
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00.c | 3 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_d8.c | 83 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.c | 1 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 2 | ||||
| -rw-r--r-- | src/dynarec/rv64/rv64_emitter.h | 12 |
5 files changed, 100 insertions, 1 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00.c b/src/dynarec/rv64/dynarec_rv64_00.c index 004707a1..e6bfe91f 100644 --- a/src/dynarec/rv64/dynarec_rv64_00.c +++ b/src/dynarec/rv64/dynarec_rv64_00.c @@ -1433,6 +1433,9 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } break; + case 0xD8: + addr = dynarec64_D8(dyn, addr, ip, ninst, rex, rep, ok, need_epilog); + break; case 0xD9: addr = dynarec64_D9(dyn, addr, ip, ninst, rex, rep, ok, need_epilog); break; diff --git a/src/dynarec/rv64/dynarec_rv64_d8.c b/src/dynarec/rv64/dynarec_rv64_d8.c new file mode 100644 index 00000000..6525245d --- /dev/null +++ b/src/dynarec/rv64/dynarec_rv64_d8.c @@ -0,0 +1,83 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stddef.h> +#include <pthread.h> +#include <errno.h> + +#include "debug.h" +#include "box64context.h" +#include "dynarec.h" +#include "emu/x64emu_private.h" +#include "emu/x64run_private.h" +#include "x64run.h" +#include "x64emu.h" +#include "box64stack.h" +#include "callback.h" +#include "emu/x64run_private.h" +#include "x64trace.h" +#include "emu/x87emu_private.h" +#include "dynarec_native.h" + +#include "rv64_printer.h" +#include "dynarec_rv64_private.h" +#include "dynarec_rv64_helper.h" +#include "dynarec_rv64_functions.h" + + +uintptr_t dynarec64_D8(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog) +{ + (void)ip; (void)rep; (void)need_epilog; + + uint8_t nextop = F8; + uint8_t ed; + uint8_t wback, wb1; + uint8_t u8; + int64_t fixedaddress; + int unscaled; + int v1, v2; + int s0; + int i1, i2, i3; + + MAYUSE(s0); + MAYUSE(v2); + MAYUSE(v1); + + switch(nextop) { + case 0xC0 ... 0xC7: + DEFAULT; + case 0xC8 ... 0xCF: + DEFAULT; + case 0xD0 ... 0xD7: + DEFAULT; + case 0xD8 ... 0xDF: + DEFAULT; + case 0xE0 ... 0xE7: + DEFAULT; + case 0xE8 ... 0xEF: + DEFAULT; + case 0xF0 ... 0xF7: + DEFAULT; + case 0xF8 ... 0xFF: + DEFAULT; + + default: + switch((nextop>>3)&7) { + case 0: + INST_NAME("FADD ST0, float[ED]"); + v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0); + s0 = fpu_get_scratch(dyn); + addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0); + FLW(s0, ed, fixedaddress); + if(ST_IS_F(0)) { + FADDS(v1, v1, s0); + } else { + FCVTDS(s0, s0); + FADDD(v1, v1, s0); + } + break; + default: + DEFAULT; + } + } + return addr; +} diff --git a/src/dynarec/rv64/dynarec_rv64_helper.c b/src/dynarec/rv64/dynarec_rv64_helper.c index f6d576ad..4f074b09 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.c +++ b/src/dynarec/rv64/dynarec_rv64_helper.c @@ -806,6 +806,7 @@ int x87_get_cache(dynarec_rv64_t* dyn, int ninst, int populate, int s1, int s2, ADDI(s2, s2, a); ANDI(s2, s2, 7); } + SLLI(s2, s2, 3); ADD(s1, xEmu, s2); FLD(dyn->e.x87reg[ret], s1, offsetof(x64emu_t, x87)); } diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index a21fa5c0..dad8cde4 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -980,7 +980,7 @@ uintptr_t dynarec64_64(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni //uintptr_t dynarec64_65(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep,int* ok, int* need_epilog); uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); //uintptr_t dynarec64_67(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); -//uintptr_t dynarec64_D8(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); +uintptr_t dynarec64_D8(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); //uintptr_t dynarec64_DA(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); uintptr_t dynarec64_DB(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); diff --git a/src/dynarec/rv64/rv64_emitter.h b/src/dynarec/rv64/rv64_emitter.h index 391c4a3d..1f1b9035 100644 --- a/src/dynarec/rv64/rv64_emitter.h +++ b/src/dynarec/rv64/rv64_emitter.h @@ -397,6 +397,12 @@ f28–31 ft8–11 FP temporaries Caller // RV64F // Convert from signed 64bits to Single #define FCVTSL(frd, rs1) EMIT(R_type(0b1101000, 0b00010, rs1, 0b000, frd, 0b1010011)) +// Convert from unsigned 64bits to Single +#define FCVTSLU(frd, rs1) EMIT(R_type(0b1101000, 0b00011, rs1, 0b000, frd, 0b1010011)) +// Convert from Single to signed 64bits +#define FCVTLS(rd, frs1) EMIT(R_type(0b1100000, 0b00010, frs1, 0b000, rd, 0b1010011)) +// Convert from Single to unsigned 64bits +#define FCVTLUS(rd, frs1) EMIT(R_type(0b1100000, 0b00011, frs1, 0b000, rd, 0b1010011)) // RV32D @@ -438,5 +444,11 @@ f28–31 ft8–11 FP temporaries Caller #define FMVDX(frd, rs1) EMIT(R_type(0b1111001, 0b00000, rs1, 0b000, frd, 0b1010011)) // Convert from signed 64bits to Double #define FCVTDL(frd, rs1) EMIT(R_type(0b1101001, 0b00010, rs1, 0b000, frd, 0b1010011)) +// Convert from unsigned 64bits to Double +#define FCVTDLU(frd, rs1) EMIT(R_type(0b1101001, 0b00011, rs1, 0b000, frd, 0b1010011)) +// Convert from Double to signed 64bits +#define FCVTLD(rd, frs1) EMIT(R_type(0b1100001, 0b00010, frs1, 0b000, rd, 0b1010011)) +// Convert from Double to unsigned 64bits +#define FCVTLUD(rd, frs1) EMIT(R_type(0b1100001, 0b00011, frs1, 0b000, rd, 0b1010011)) #endif //__RV64_EMITTER_H__ |