diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2022-10-22 10:23:24 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2022-10-22 10:23:24 +0200 |
| commit | 21161ae38e0299e1072e061649925171b770d325 (patch) | |
| tree | 279fa0a7eac5b16466ecb0ff41ad91696f6bc348 /src | |
| parent | aa074d71219b7b233735242400a10a70bff18d3b (diff) | |
| download | box64-21161ae38e0299e1072e061649925171b770d325.tar.gz box64-21161ae38e0299e1072e061649925171b770d325.zip | |
[DYNAREC] Added DE opcodes
Diffstat (limited to 'src')
| -rwxr-xr-x | src/dynarec/arm64/arm64_emitter.h | 28 | ||||
| -rwxr-xr-x | src/dynarec/arm64/dynarec_arm64_00.c | 4 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_de.c | 284 | ||||
| -rwxr-xr-x | src/dynarec/arm64/dynarec_arm64_helper.h | 2 |
4 files changed, 303 insertions, 15 deletions
diff --git a/src/dynarec/arm64/arm64_emitter.h b/src/dynarec/arm64/arm64_emitter.h index 4b7d985a..fd714800 100755 --- a/src/dynarec/arm64/arm64_emitter.h +++ b/src/dynarec/arm64/arm64_emitter.h @@ -683,7 +683,9 @@ // VLDR #define VMEM_gen(size, opc, imm12, Rn, Rt) ((size)<<30 | 0b111<<27 | 1<<26 | 0b01<<24 | (opc)<<22 | (imm12)<<10 | (Rn)<<5 | (Rt)) -// imm14 must be 3-aligned +// imm13 must be 1-aligned +#define VLDR16_U12(Ht, Rn, imm13) EMIT(VMEM_gen(0b01, 0b01, ((uint32_t)((imm13)>>1))&0xfff, Rn, Ht)) +// imm14 must be 2-aligned #define VLDR32_U12(Dt, Rn, imm14) EMIT(VMEM_gen(0b10, 0b01, ((uint32_t)((imm14)>>2))&0xfff, Rn, Dt)) // imm15 must be 3-aligned #define VLDR64_U12(Dt, Rn, imm15) EMIT(VMEM_gen(0b11, 0b01, ((uint32_t)((imm15)>>3))&0xfff, Rn, Dt)) @@ -695,22 +697,22 @@ #define VSTR64_U12(Dt, Rn, imm15) EMIT(VMEM_gen(0b11, 0b00, ((uint32_t)(imm15>>3))&0xfff, Rn, Dt)) // imm16 must be 4-aligned #define VSTR128_U12(Qt, Rn, imm16) EMIT(VMEM_gen(0b00, 0b10, ((uint32_t)((imm16)>>4))&0xfff, Rn, Qt)) -// (imm14) must be 1-aligned -#define VSTR16_U12(Ht, Rn, imm14) EMIT(VMEM_gen(0b01, 0b00, ((uint32_t)(imm14>>1))&0xfff, Rn, Ht)) +// (imm13) must be 1-aligned +#define VSTR16_U12(Ht, Rn, imm13) EMIT(VMEM_gen(0b01, 0b00, ((uint32_t)(imm13>>1))&0xfff, Rn, Ht)) #define VMEMUR_vector(size, opc, imm9, Rn, Rt) ((size)<<30 | 0b111<<27 | 1<<26 | (opc)<<22 | (imm9)<<12 | (Rn)<<5 | (Rt)) // signed offset, no alignement! -#define VLDR8_I9(Vt, Rn, imm9) EMIT(VMEMUR(0b00, 0b01, (imm9)&0b111111111, Rn, Vt)) -#define VLDR16_I9(Vt, Rn, imm9) EMIT(VMEMUR(0b01, 0b01, (imm9)&0b111111111, Rn, Vt)) -#define VLDR32_I9(Vt, Rn, imm9) EMIT(VMEMUR(0b10, 0b01, (imm9)&0b111111111, Rn, Vt)) -#define VLDR64_I9(Vt, Rn, imm9) EMIT(VMEMUR(0b11, 0b01, (imm9)&0b111111111, Rn, Vt)) -#define VLDR128_I9(Vt, Rn, imm9) EMIT(VMEMUR(0b00, 0b11, (imm9)&0b111111111, Rn, Vt)) +#define VLDR8_I9(Vt, Rn, imm9) EMIT(VMEMUR_vector(0b00, 0b01, (imm9)&0b111111111, Rn, Vt)) +#define VLDR16_I9(Vt, Rn, imm9) EMIT(VMEMUR_vector(0b01, 0b01, (imm9)&0b111111111, Rn, Vt)) +#define VLDR32_I9(Vt, Rn, imm9) EMIT(VMEMUR_vector(0b10, 0b01, (imm9)&0b111111111, Rn, Vt)) +#define VLDR64_I9(Vt, Rn, imm9) EMIT(VMEMUR_vector(0b11, 0b01, (imm9)&0b111111111, Rn, Vt)) +#define VLDR128_I9(Vt, Rn, imm9) EMIT(VMEMUR_vector(0b00, 0b11, (imm9)&0b111111111, Rn, Vt)) // signed offset, no alignement! -#define VSTR8_I9(Vt, Rn, imm9) EMIT(VMEMUR(0b00, 0b00, (imm9)&0b111111111, Rn, Vt)) -#define VSTR16_I9(Vt, Rn, imm9) EMIT(VMEMUR(0b01, 0b00, (imm9)&0b111111111, Rn, Vt)) -#define VSTR32_I9(Vt, Rn, imm9) EMIT(VMEMUR(0b10, 0b00, (imm9)&0b111111111, Rn, Vt)) -#define VSTR64_I9(Vt, Rn, imm9) EMIT(VMEMUR(0b11, 0b00, (imm9)&0b111111111, Rn, Vt)) -#define VSTR128_I9(Vt, Rn, imm9) EMIT(VMEMUR(0b00, 0b10, (imm9)&0b111111111, Rn, Vt)) +#define VSTR8_I9(Vt, Rn, imm9) EMIT(VMEMUR_vector(0b00, 0b00, (imm9)&0b111111111, Rn, Vt)) +#define VSTR16_I9(Vt, Rn, imm9) EMIT(VMEMUR_vector(0b01, 0b00, (imm9)&0b111111111, Rn, Vt)) +#define VSTR32_I9(Vt, Rn, imm9) EMIT(VMEMUR_vector(0b10, 0b00, (imm9)&0b111111111, Rn, Vt)) +#define VSTR64_I9(Vt, Rn, imm9) EMIT(VMEMUR_vector(0b11, 0b00, (imm9)&0b111111111, Rn, Vt)) +#define VSTR128_I9(Vt, Rn, imm9) EMIT(VMEMUR_vector(0b00, 0b10, (imm9)&0b111111111, Rn, Vt)) #define VMEMW_gen(size, opc, imm9, op2, Rn, Rt) ((size)<<30 | 0b111<<27 | 1<<26 | (opc)<<22 | (imm9)<<12 | (op2)<<10 | 0b01<<10 | (Rn)<<5 | (Rt)) #define VLDR64_S9_postindex(Rt, Rn, imm9) EMIT(VMEMW_gen(0b11, 0b01, (imm9)&0x1ff, 0b01, Rn, Rt)) diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c index b662c0e1..4cdb7bea 100755 --- a/src/dynarec/arm64/dynarec_arm64_00.c +++ b/src/dynarec/arm64/dynarec_arm64_00.c @@ -2016,7 +2016,9 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0xDD: addr = dynarec64_DD(dyn, addr, ip, ninst, rex, rep, ok, need_epilog); break; - + case 0xDE: + addr = dynarec64_DE(dyn, addr, ip, ninst, rex, rep, ok, need_epilog); + break; case 0xDF: addr = dynarec64_DF(dyn, addr, ip, ninst, rex, rep, ok, need_epilog); break; diff --git a/src/dynarec/arm64/dynarec_arm64_de.c b/src/dynarec/arm64/dynarec_arm64_de.c new file mode 100644 index 00000000..ae7fccb7 --- /dev/null +++ b/src/dynarec/arm64/dynarec_arm64_de.c @@ -0,0 +1,284 @@ +#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 "arm64_printer.h" +#include "dynarec_arm64_private.h" +#include "dynarec_arm64_helper.h" +#include "dynarec_arm64_functions.h" + + +uintptr_t dynarec64_DE(dynarec_arm_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 wback; + int64_t fixedaddress; + int v1, v2; + + MAYUSE(v2); + MAYUSE(v1); + + switch(nextop) { + case 0xC0: + case 0xC1: + case 0xC2: + case 0xC3: + case 0xC4: + case 0xC5: + case 0xC6: + case 0xC7: + INST_NAME("FADDP STx, ST0"); + v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7)); + v1 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7)); + if(ST_IS_F(0)) { + FADDS(v1, v1, v2); + } else { + FADDD(v1, v1, v2); + } + x87_do_pop(dyn, ninst, x3); + break; + case 0xC8: + case 0xC9: + case 0xCA: + case 0xCB: + case 0xCC: + case 0xCD: + case 0xCE: + case 0xCF: + INST_NAME("FMULP STx, ST0"); + v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7)); + v1 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7)); + if(ST_IS_F(0)) { + FMULS(v1, v1, v2); + } else { + FMULD(v1, v1, v2); + } + x87_do_pop(dyn, ninst, x3); + break; + case 0xD0: + case 0xD1: + case 0xD2: + case 0xD3: + case 0xD4: + case 0xD5: + case 0xD6: + case 0xD7: + INST_NAME("FCOMP ST0, STx"); //yep + v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7)); + v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7)); + if(ST_IS_F(0)) { + FCMPS(v1, v2); + } else { + FCMPD(v1, v2); + } + FCOM(x1, x2, x3); + x87_do_pop(dyn, ninst, x3); + break; + case 0xD9: + INST_NAME("FCOMPP ST0, STx"); + v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7)); + v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7)); + if(ST_IS_F(0)) { + FCMPS(v1, v2); + } else { + FCMPD(v1, v2); + } + FCOM(x1, x2, x3); + x87_do_pop(dyn, ninst, x3); + x87_do_pop(dyn, ninst, x3); + break; + case 0xE0: + case 0xE1: + case 0xE2: + case 0xE3: + case 0xE4: + case 0xE5: + case 0xE6: + case 0xE7: + INST_NAME("FSUBRP STx, ST0"); + v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7)); + v1 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7)); + if(ST_IS_F(0)) { + FSUBS(v1, v2, v1); + } else { + FSUBD(v1, v2, v1); + } + x87_do_pop(dyn, ninst, x3); + break; + case 0xE8: + case 0xE9: + case 0xEA: + case 0xEB: + case 0xEC: + case 0xED: + case 0xEE: + case 0xEF: + INST_NAME("FSUBP STx, ST0"); + v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7)); + v1 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7)); + if(ST_IS_F(0)) { + FSUBS(v1, v1, v2); + } else { + FSUBD(v1, v1, v2); + } + x87_do_pop(dyn, ninst, x3); + break; + case 0xF0: + case 0xF1: + case 0xF2: + case 0xF3: + case 0xF4: + case 0xF5: + case 0xF6: + case 0xF7: + INST_NAME("FDIVRP STx, ST0"); + v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7)); + v1 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7)); + if(ST_IS_F(0)) { + FDIVS(v1, v2, v1); + } else { + FDIVD(v1, v2, v1); + } + x87_do_pop(dyn, ninst, x3); + break; + case 0xF8: + case 0xF9: + case 0xFA: + case 0xFB: + case 0xFC: + case 0xFD: + case 0xFE: + case 0xFF: + INST_NAME("FDIVP STx, ST0"); + v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7)); + v1 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7)); + if(ST_IS_F(0)) { + FDIVS(v1, v1, v2); + } else { + FDIVD(v1, v1, v2); + } + x87_do_pop(dyn, ninst, x3); + break; + case 0xD8: + case 0xDA: + case 0xDB: + case 0xDC: + case 0xDD: + case 0xDE: + case 0xDF: + return 0; + default: + switch((nextop>>3)&7) { + case 0: + INST_NAME("FIADD ST0, word[ED]"); + v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D); + v2 = fpu_get_scratch(dyn); + addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<1, 1, rex, NULL, 0, 0); + VLDR16_U12(v2, wback, fixedaddress); + SXTL_16(v2, v2); + SXTL_32(v2, v2); + SCVTFDD(v2, v2); + FADDD(v1, v1, v2); + break; + case 1: + INST_NAME("FIMUL ST0, word[ED]"); + v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D); + v2 = fpu_get_scratch(dyn); + addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<1, 1, rex, NULL, 0, 0); + VLDR16_U12(v2, wback, fixedaddress); + SXTL_16(v2, v2); + SXTL_32(v2, v2); + SCVTFDD(v2, v2); + FMULD(v1, v1, v2); + break; + case 2: + INST_NAME("FICOM ST0, word[ED]"); + v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D); + v2 = fpu_get_scratch(dyn); + addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<1, 1, rex, NULL, 0, 0); + VLDR16_U12(v2, wback, fixedaddress); + SXTL_16(v2, v2); + SXTL_32(v2, v2); + SCVTFDD(v2, v2); + FCMPD(v1, v2); + FCOM(x1, x2, x3); + break; + case 3: + INST_NAME("FICOMP ST0, word[ED]"); + v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D); + v2 = fpu_get_scratch(dyn); + addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<1, 1, rex, NULL, 0, 0); + VLDR16_U12(v2, wback, fixedaddress); + SXTL_16(v2, v2); + SXTL_32(v2, v2); + SCVTFDD(v2, v2); + FCMPD(v1, v2); + FCOM(x1, x2, x3); + x87_do_pop(dyn, ninst, x3); + break; + case 4: + INST_NAME("FISUB ST0, word[ED]"); + v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D); + v2 = fpu_get_scratch(dyn); + addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<1, 1, rex, NULL, 0, 0); + VLDR16_U12(v2, wback, fixedaddress); + SXTL_16(v2, v2); + SXTL_32(v2, v2); + SCVTFDD(v2, v2); + FSUBD(v1, v1, v2); + break; + case 5: + INST_NAME("FISUBR ST0, word[ED]"); + v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D); + v2 = fpu_get_scratch(dyn); + addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<1, 1, rex, NULL, 0, 0); + VLDR16_U12(v2, wback, fixedaddress); + SXTL_16(v2, v2); + SXTL_32(v2, v2); + SCVTFDD(v2, v2); + FSUBD(v1, v2, v1); + break; + case 6: + INST_NAME("FIDIV ST0, word[ED]"); + v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D); + v2 = fpu_get_scratch(dyn); + addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<1, 1, rex, NULL, 0, 0); + VLDR16_U12(v2, wback, fixedaddress); + SXTL_16(v2, v2); + SXTL_32(v2, v2); + SCVTFDD(v2, v2); + FDIVD(v1, v1, v2); + break; + case 7: + INST_NAME("FIDIVR ST0, word[ED]"); + v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D); + v2 = fpu_get_scratch(dyn); + addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<1, 1, rex, NULL, 0, 0); + VLDR16_U12(v2, wback, fixedaddress); + SXTL_16(v2, v2); + SXTL_32(v2, v2); + SCVTFDD(v2, v2); + FDIVD(v1, v2, v1); + break; + } + } + return addr; +} diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h index 6472989a..ef9508cd 100755 --- a/src/dynarec/arm64/dynarec_arm64_helper.h +++ b/src/dynarec/arm64/dynarec_arm64_helper.h @@ -1060,7 +1060,7 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); uintptr_t dynarec64_DD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); -//uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); +uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); |