diff options
Diffstat (limited to 'src')
| -rwxr-xr-x | src/dynarec/arm64_printer.c | 17 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_00.c | 11 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_0f.c | 36 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_660f.c | 4 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_f20f.c | 72 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_f30f.c | 72 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_helper.h | 8 |
7 files changed, 212 insertions, 8 deletions
diff --git a/src/dynarec/arm64_printer.c b/src/dynarec/arm64_printer.c index ed179df0..b0b1849a 100755 --- a/src/dynarec/arm64_printer.c +++ b/src/dynarec/arm64_printer.c @@ -717,7 +717,22 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr) snprintf(buff, sizeof(buff), "VORR %c%d, %c%d, %c%d", q, Rd, q, Rn, q, Rm); return buff; } - + // UMOV + if(isMask(opcode, "0Q001110000rrrrr001111nnnnnddddd", &a)) { + char q = a.Q?'Q':'D'; + char s = '?'; + int sz=0; + if(a.Q==0 && immr&1) {s='B'; sz=0; } + else if(a.Q==0 && (immr&3)==2) {s='H'; sz=1; } + else if(a.Q==0 && (immr&7)==4) {s='S'; sz=2; } + else if(a.Q==1 && (immr&15)==8) {s='D'; sz=3; } + int index = (immr)>>(sz+1); + if(sz>2) + snprintf(buff, sizeof(buff), "MOV %s, %c%d.%c[%d]", a.Q?Xt[Rd]:Wt[Rd], q, Rn, s, index); + else + snprintf(buff, sizeof(buff), "UMOV %s, %c%d.%c[%d]", a.Q?Xt[Rd]:Wt[Rd], q, Rn, s, index); + return buff; + } // VEOR if(isMask(opcode, "0Q101110001mmmmm000111nnnnnddddd", &a)) { char q = a.Q?'Q':'D'; diff --git a/src/dynarec/dynarec_arm64_00.c b/src/dynarec/dynarec_arm64_00.c index dcf74f1c..fbd258b4 100755 --- a/src/dynarec/dynarec_arm64_00.c +++ b/src/dynarec/dynarec_arm64_00.c @@ -159,7 +159,16 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 0x0F: - addr = dynarec64_0F(dyn, addr, ip, ninst, rex, rep, ok, need_epilog); + switch(rep) { + case 1: + addr = dynarec64_F20F(dyn, addr, ip, ninst, rex, ok, need_epilog); + break; + case 2: + addr = dynarec64_F30F(dyn, addr, ip, ninst, rex, ok, need_epilog); + break; + default: + addr = dynarec64_0F(dyn, addr, ip, ninst, rex, rep, ok, need_epilog); + } break; case 0x10: INST_NAME("ADC Eb, Gb"); diff --git a/src/dynarec/dynarec_arm64_0f.c b/src/dynarec/dynarec_arm64_0f.c index bc7da54d..3f869b9d 100755 --- a/src/dynarec/dynarec_arm64_0f.c +++ b/src/dynarec/dynarec_arm64_0f.c @@ -83,6 +83,42 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin + case 0x10: + INST_NAME("MOVUPS Gx,Ex"); + nextop = F8; + gd = ((nextop&0x38)>>3) + (rex.r<<3); + if(MODREG) { + ed = (nextop&7)+(rex.b<<3); + v1 = sse_get_reg(dyn, ninst, x1, ed); + v0 = sse_get_reg_empty(dyn, ninst, x1, gd); + VMOVQ(v0, v1); + } else { + v0 = sse_get_reg_empty(dyn, ninst, x1, gd); + addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0xff0<<3, 7, rex, 0, 0); + LDRx_U12(x2, ed, fixedaddress); + VMOVQDfrom(v0, 0, x2); + LDRx_U12(x2, ed, fixedaddress+8); + VMOVQDfrom(v0, 1, x2); + } + break; + case 0x11: + INST_NAME("MOVUPS Ex,Gx"); + nextop = F8; + gd = ((nextop&0x38)>>3) + (rex.r<<3); + v0 = sse_get_reg(dyn, ninst, x1, gd); + if(MODREG) { + ed = (nextop&7)+(rex.b<<3); + v1 = sse_get_reg_empty(dyn, ninst, x1, ed); + VMOVQ(v1, v0); + } else { + addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0xff0<<3, 7, rex, 0, 0); + VMOVQDto(x2, v0, 0); + STRx_U12(x2, ed, fixedaddress); + VMOVQDto(x2, v0, 1); + LDRx_U12(x2, ed, fixedaddress+8); + } + break; + case 0x1F: INST_NAME("NOP (multibyte)"); nextop = F8; diff --git a/src/dynarec/dynarec_arm64_660f.c b/src/dynarec/dynarec_arm64_660f.c index 7dafc606..6069c3ef 100755 --- a/src/dynarec/dynarec_arm64_660f.c +++ b/src/dynarec/dynarec_arm64_660f.c @@ -106,7 +106,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n gd = ((nextop&0x38)>>3)+(rex.r<<3); v0 = sse_get_reg(dyn, ninst, x1, gd); if(rex.w) { - if((nextop&0xC0)==0xC0) { + if(MODREG) { ed = xRAX + (nextop&7) + (rex.b<<3); VMOVQDto(ed, v0, 0); } else { @@ -115,7 +115,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n STRx_U12(x2, ed, fixedaddress); } } else { - if((nextop&0xC0)==0xC0) { + if(MODREG) { ed = xRAX + (nextop&7) + (rex.b<<3); VMOVSto(ed, v0, 0); } else { diff --git a/src/dynarec/dynarec_arm64_f20f.c b/src/dynarec/dynarec_arm64_f20f.c new file mode 100755 index 00000000..e8708a12 --- /dev/null +++ b/src/dynarec/dynarec_arm64_f20f.c @@ -0,0 +1,72 @@ +#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 "dynarec_arm64.h" +#include "dynarec_arm64_private.h" +#include "arm64_printer.h" + +#include "dynarec_arm64_functions.h" +#include "dynarec_arm64_helper.h" + +// Get Ex as a double, not a quad (warning, x2 and x3 may get used) +#define GETEX(a) \ + if((nextop&0xC0)==0xC0) { \ + a = sse_get_reg(dyn, ninst, x1, nextop&7); \ + } else { \ + parity = getedparity(dyn, ninst, addr, nextop, 3); \ + a = fpu_get_scratch_double(dyn); \ + if(parity) { \ + addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 1023, 3); \ + VLDR_64(a, ed, fixedaddress); \ + } else { \ + addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 4095-4, 0);\ + LDR_IMM9(x2, ed, fixedaddress+0); \ + LDR_IMM9(x3, ed, fixedaddress+4); \ + VMOVtoV_D(a, x2, x3); \ + } \ + } + +uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog) +{ + uint8_t opcode = F8; + uint8_t nextop, u8; + int32_t i32, j32; + uint8_t gd, ed; + uint8_t wback, wb1; + uint8_t eb1, eb2; + int v0, v1; + int q0, q1; + int d0; + int s0; + int fixedaddress; + int parity; + + MAYUSE(d0); + MAYUSE(q1); + MAYUSE(eb1); + MAYUSE(eb2); + MAYUSE(j32); + + switch(opcode) { + + + default: + DEFAULT; + } + return addr; +} + diff --git a/src/dynarec/dynarec_arm64_f30f.c b/src/dynarec/dynarec_arm64_f30f.c new file mode 100755 index 00000000..68b22031 --- /dev/null +++ b/src/dynarec/dynarec_arm64_f30f.c @@ -0,0 +1,72 @@ +#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 "dynarec_arm64.h" +#include "dynarec_arm64_private.h" +#include "arm64_printer.h" + +#include "dynarec_arm64_functions.h" +#include "dynarec_arm64_helper.h" + +// Get Ex as a double, not a quad (warning, x2 and x3 may get used) +#define GETEX(a) \ + if((nextop&0xC0)==0xC0) { \ + a = sse_get_reg(dyn, ninst, x1, nextop&7); \ + } else { \ + parity = getedparity(dyn, ninst, addr, nextop, 3); \ + a = fpu_get_scratch_double(dyn); \ + if(parity) { \ + addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 1023, 3); \ + VLDR_64(a, ed, fixedaddress); \ + } else { \ + addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 4095-4, 0);\ + LDR_IMM9(x2, ed, fixedaddress+0); \ + LDR_IMM9(x3, ed, fixedaddress+4); \ + VMOVtoV_D(a, x2, x3); \ + } \ + } + +uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog) +{ + uint8_t opcode = F8; + uint8_t nextop, u8; + int32_t i32, j32; + uint8_t gd, ed; + uint8_t wback, wb1; + uint8_t eb1, eb2; + int v0, v1; + int q0, q1; + int d0; + int s0; + int fixedaddress; + int parity; + + MAYUSE(d0); + MAYUSE(q1); + MAYUSE(eb1); + MAYUSE(eb2); + MAYUSE(j32); + + switch(opcode) { + + + default: + DEFAULT; + } + return addr; +} + diff --git a/src/dynarec/dynarec_arm64_helper.h b/src/dynarec/dynarec_arm64_helper.h index 46febe3a..c814d89f 100755 --- a/src/dynarec/dynarec_arm64_helper.h +++ b/src/dynarec/dynarec_arm64_helper.h @@ -758,8 +758,8 @@ void fpu_popcache(dynarec_arm_t* dyn, int ninst, int s1); uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, int* ok, int* need_epilog); uintptr_t dynarec64_0F(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_FS(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_GS(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_FS(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_GS(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_66(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_67(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_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep int* ok, int* need_epilog); @@ -772,8 +772,8 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin //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); -//uintptr_t dynarec64_F20F(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_F30F(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_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog); +uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog); #if STEP < 2 #define PASS2(A) |