mirror of
https://github.com/ptitSeb/box64.git
synced 2026-11-07 09:26:11 -10:00
[LA64_DYNAREC] Added a dedicated vzero register (#3926)
This commit is contained in:
1 parent
1a2ad946cb
commit
dab3fdc351
15 files changed
+135
-147
No files matched your search
@@ -501,8 +501,7 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
VLDI(v0, 0b0000010000111); // broadcast 0b10000111 as byte
|
||||
VAND_V(v0, v0, q1);
|
||||
VMINI_BU(v0, v0, 0x1f);
|
||||
VXOR_V(v1, v1, v1);
|
||||
VSHUF_B(q0, v1, q0, v0);
|
||||
VSHUF_B(q0, VZERO, q0, v0);
|
||||
break;
|
||||
case 0x01:
|
||||
INST_NAME("PHADDW Gm, Em");
|
||||
@@ -639,27 +638,21 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
nextop = F8;
|
||||
GETGM(q0);
|
||||
GETEM(q1, 0);
|
||||
v0 = fpu_get_scratch(dyn);
|
||||
VXOR_V(v0, v0, v0);
|
||||
VABSD_B(q0, q1, v0);
|
||||
VABSD_B(q0, q1, VZERO);
|
||||
break;
|
||||
case 0x1D:
|
||||
INST_NAME("PABSW Gm, Em");
|
||||
nextop = F8;
|
||||
GETGM(q0);
|
||||
GETEM(q1, 0);
|
||||
v0 = fpu_get_scratch(dyn);
|
||||
VXOR_V(v0, v0, v0);
|
||||
VABSD_H(q0, q1, v0);
|
||||
VABSD_H(q0, q1, VZERO);
|
||||
break;
|
||||
case 0x1E:
|
||||
INST_NAME("PABSD Gm, Em");
|
||||
nextop = F8;
|
||||
GETGM(q0);
|
||||
GETEM(q1, 0);
|
||||
v0 = fpu_get_scratch(dyn);
|
||||
VXOR_V(v0, v0, v0);
|
||||
VABSD_W(q0, q1, v0);
|
||||
VABSD_W(q0, q1, VZERO);
|
||||
break;
|
||||
case 0xC8 ... 0xCD:
|
||||
u8 = nextop;
|
||||
|
||||
@@ -369,8 +369,7 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
VLDI(v0, 0b0000010001111); // broadcast 0b10001111 as byte
|
||||
VAND_V(v0, v0, q1);
|
||||
VMINI_BU(v0, v0, 0x1f);
|
||||
VXOR_V(v1, v1, v1);
|
||||
VSHUF_B(q0, v1, q0, v0);
|
||||
VSHUF_B(q0, VZERO, q0, v0);
|
||||
break;
|
||||
case 0x01:
|
||||
INST_NAME("PHADDW Gx, Ex");
|
||||
@@ -576,18 +575,14 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
nextop = F8;
|
||||
GETEX(q1, 0, 0);
|
||||
GETGX_empty(q0);
|
||||
v0 = fpu_get_scratch(dyn);
|
||||
VXOR_V(v0, v0, v0);
|
||||
VABSD_B(q0, q1, v0);
|
||||
VABSD_B(q0, q1, VZERO);
|
||||
break;
|
||||
case 0x1D:
|
||||
INST_NAME("PABSW Gx, Ex");
|
||||
nextop = F8;
|
||||
GETEX(q1, 0, 0);
|
||||
GETGX_empty(q0);
|
||||
v0 = fpu_get_scratch(dyn);
|
||||
VXOR_V(v0, v0, v0);
|
||||
VABSD_H(q0, q1, v0);
|
||||
VABSD_H(q0, q1, VZERO);
|
||||
break;
|
||||
case 0x1E:
|
||||
INST_NAME("PABSD Gx, Ex");
|
||||
@@ -1247,11 +1242,10 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
VEXTRINS_W(q0, q2, VEXTRINS_IMM_4_0(((u8 >> 4) & 3), 0)); // src index is zero when Ex is mem operand
|
||||
}
|
||||
uint8_t zmask = u8 & 0xf;
|
||||
VXOR_V(q2, q2, q2);
|
||||
if (zmask) {
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
if (zmask & (1 << i)) {
|
||||
VEXTRINS_W(q0, q2, VEXTRINS_IMM_4_0(i, 0));
|
||||
VEXTRINS_W(q0, VZERO, VEXTRINS_IMM_4_0(i, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1277,12 +1271,10 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
u8 = F8;
|
||||
v0 = fpu_get_scratch(dyn);
|
||||
v1 = fpu_get_scratch(dyn);
|
||||
v2 = fpu_get_scratch(dyn);
|
||||
VFMUL_S(v0, q0, q1);
|
||||
VXOR_V(v2, v2, v2);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
if (!(u8 & (1 << (4 + i)))) {
|
||||
VEXTRINS_W(v0, v2, (i << 4));
|
||||
VEXTRINS_W(v0, VZERO, (i << 4));
|
||||
}
|
||||
}
|
||||
VSHUF4I_W(v1, v0, 0b10110001); // v0[a,b,c,d] v1[b,a,d,c]
|
||||
@@ -1292,7 +1284,7 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
VREPLVEI_W(q0, v0, 0);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
if (!(u8 & (1 << i))) {
|
||||
VEXTRINS_W(q0, v2, (i << 4));
|
||||
VEXTRINS_W(q0, VZERO, (i << 4));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1304,12 +1296,10 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
u8 = F8;
|
||||
v0 = fpu_get_scratch(dyn);
|
||||
v1 = fpu_get_scratch(dyn);
|
||||
v2 = fpu_get_scratch(dyn);
|
||||
VFMUL_D(v0, q0, q1);
|
||||
VXOR_V(v2, v2, v2);
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (!(u8 & (1 << (4 + i)))) {
|
||||
VEXTRINS_D(v0, v2, (i << 4));
|
||||
VEXTRINS_D(v0, VZERO, (i << 4));
|
||||
}
|
||||
}
|
||||
VSHUF4I_W(v1, v0, 0b01001110); // v0[a,b] v1[b,a]
|
||||
@@ -1317,7 +1307,7 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
|
||||
VREPLVEI_D(q0, v0, 0);
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (!(u8 & (1 << i))) {
|
||||
VEXTRINS_D(q0, v2, (i << 4));
|
||||
VEXTRINS_D(q0, VZERO, (i << 4));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -8,7 +8,6 @@ static inline void la64_subbytes_lsx(dynarec_la64_t* dyn, int ninst, int dst, in
|
||||
{
|
||||
(void)dyn;
|
||||
(void)ninst;
|
||||
VXOR_V(zero, zero, zero);
|
||||
VANDI_B(t0, dst, 0x0f);
|
||||
VSRLI_B(t1, dst, 4);
|
||||
VLD(tab, x5, 1 * 16);
|
||||
@@ -42,7 +41,6 @@ static inline void la64_subbytes_lasx(dynarec_la64_t* dyn, int ninst, int dst, i
|
||||
{
|
||||
(void)dyn;
|
||||
(void)ninst;
|
||||
XVXOR_V(zero, zero, zero);
|
||||
XVANDI_B(t0, dst, 0x0f);
|
||||
XVSRLI_B(t1, dst, 4);
|
||||
XVLD(tab, x5, 1 * 32);
|
||||
@@ -172,7 +170,7 @@ static inline void la64_aesimc_lasx(dynarec_la64_t* dyn, int ninst, int dst)
|
||||
|
||||
static inline void la64_aeselast_lsx(dynarec_la64_t* dyn, int ninst, int dst)
|
||||
{
|
||||
int zero = fpu_get_scratch(dyn);
|
||||
int zero = VZERO;
|
||||
int t0 = fpu_get_scratch(dyn);
|
||||
int t1 = fpu_get_scratch(dyn);
|
||||
int t2 = fpu_get_scratch(dyn);
|
||||
@@ -187,7 +185,7 @@ static inline void la64_aeselast_lsx(dynarec_la64_t* dyn, int ninst, int dst)
|
||||
|
||||
static inline void la64_aeselast_lasx(dynarec_la64_t* dyn, int ninst, int dst)
|
||||
{
|
||||
int zero = fpu_get_scratch(dyn);
|
||||
int zero = VZERO;
|
||||
int t0 = fpu_get_scratch(dyn);
|
||||
int t1 = fpu_get_scratch(dyn);
|
||||
int t2 = fpu_get_scratch(dyn);
|
||||
@@ -202,43 +200,45 @@ static inline void la64_aeselast_lasx(dynarec_la64_t* dyn, int ninst, int dst)
|
||||
|
||||
static inline void la64_aese_lsx(dynarec_la64_t* dyn, int ninst, int dst)
|
||||
{
|
||||
int zero = fpu_get_scratch(dyn);
|
||||
int zero = VZERO;
|
||||
int t0 = fpu_get_scratch(dyn);
|
||||
int t1 = fpu_get_scratch(dyn);
|
||||
int t2 = fpu_get_scratch(dyn);
|
||||
int t3 = fpu_get_scratch(dyn);
|
||||
int tab = fpu_get_scratch(dyn);
|
||||
int tab_hi = fpu_get_scratch(dyn);
|
||||
|
||||
TABLE64C(x5, const_la64_vpaes_enc_tables);
|
||||
la64_subbytes_lsx(dyn, ninst, dst, zero, t0, t1, t2, t3, tab);
|
||||
VLD(tab, x5, 6 * 16);
|
||||
VSHUF_B(dst, dst, dst, tab);
|
||||
VLD(tab, x5, 7 * 16);
|
||||
VLD(zero, x5, 8 * 16);
|
||||
la64_mixcolumns_xtime_lsx(dyn, ninst, dst, tab, zero, t0, t1, t2, t3);
|
||||
VLD(tab_hi, x5, 8 * 16);
|
||||
la64_mixcolumns_xtime_lsx(dyn, ninst, dst, tab, tab_hi, t0, t1, t2, t3);
|
||||
}
|
||||
|
||||
static inline void la64_aese_lasx(dynarec_la64_t* dyn, int ninst, int dst)
|
||||
{
|
||||
int zero = fpu_get_scratch(dyn);
|
||||
int zero = VZERO;
|
||||
int t0 = fpu_get_scratch(dyn);
|
||||
int t1 = fpu_get_scratch(dyn);
|
||||
int t2 = fpu_get_scratch(dyn);
|
||||
int t3 = fpu_get_scratch(dyn);
|
||||
int tab = fpu_get_scratch(dyn);
|
||||
int tab_hi = fpu_get_scratch(dyn);
|
||||
|
||||
TABLE64C(x5, const_la64_vpaes_enc_tables_xv);
|
||||
la64_subbytes_lasx(dyn, ninst, dst, zero, t0, t1, t2, t3, tab);
|
||||
XVLD(tab, x5, 6 * 32);
|
||||
XVSHUF_B(dst, dst, dst, tab);
|
||||
XVLD(tab, x5, 7 * 32);
|
||||
XVLD(zero, x5, 8 * 32);
|
||||
la64_mixcolumns_xtime_lasx(dyn, ninst, dst, tab, zero, t0, t1, t2, t3);
|
||||
XVLD(tab_hi, x5, 8 * 32);
|
||||
la64_mixcolumns_xtime_lasx(dyn, ninst, dst, tab, tab_hi, t0, t1, t2, t3);
|
||||
}
|
||||
|
||||
static inline void la64_aesdlast_lsx(dynarec_la64_t* dyn, int ninst, int dst)
|
||||
{
|
||||
int zero = fpu_get_scratch(dyn);
|
||||
int zero = VZERO;
|
||||
int t0 = fpu_get_scratch(dyn);
|
||||
int t1 = fpu_get_scratch(dyn);
|
||||
int t2 = fpu_get_scratch(dyn);
|
||||
@@ -249,7 +249,6 @@ static inline void la64_aesdlast_lsx(dynarec_la64_t* dyn, int ninst, int dst)
|
||||
TABLE64C(x5, const_la64_vpaes_dec_tables);
|
||||
VLD(tab, x5, 6 * 16);
|
||||
VSHUF_B(dst, dst, dst, tab);
|
||||
VXOR_V(zero, zero, zero);
|
||||
VXORI_B(dst, dst, 99);
|
||||
VANDI_B(t0, dst, 0x0f);
|
||||
VSRLI_B(t1, dst, 4);
|
||||
@@ -282,7 +281,7 @@ static inline void la64_aesdlast_lsx(dynarec_la64_t* dyn, int ninst, int dst)
|
||||
|
||||
static inline void la64_aesdlast_lasx(dynarec_la64_t* dyn, int ninst, int dst)
|
||||
{
|
||||
int zero = fpu_get_scratch(dyn);
|
||||
int zero = VZERO;
|
||||
int t0 = fpu_get_scratch(dyn);
|
||||
int t1 = fpu_get_scratch(dyn);
|
||||
int t2 = fpu_get_scratch(dyn);
|
||||
@@ -293,7 +292,6 @@ static inline void la64_aesdlast_lasx(dynarec_la64_t* dyn, int ninst, int dst)
|
||||
TABLE64C(x5, const_la64_vpaes_dec_tables_xv);
|
||||
XVLD(tab, x5, 6 * 32);
|
||||
XVSHUF_B(dst, dst, dst, tab);
|
||||
XVXOR_V(zero, zero, zero);
|
||||
XVXORI_B(dst, dst, 99);
|
||||
XVANDI_B(t0, dst, 0x0f);
|
||||
XVSRLI_B(t1, dst, 4);
|
||||
@@ -326,7 +324,7 @@ static inline void la64_aesdlast_lasx(dynarec_la64_t* dyn, int ninst, int dst)
|
||||
|
||||
static inline void la64_aesd_lsx(dynarec_la64_t* dyn, int ninst, int dst)
|
||||
{
|
||||
int zero = fpu_get_scratch(dyn);
|
||||
int zero = VZERO;
|
||||
int t0 = fpu_get_scratch(dyn);
|
||||
int t1 = fpu_get_scratch(dyn);
|
||||
int t2 = fpu_get_scratch(dyn);
|
||||
@@ -337,7 +335,6 @@ static inline void la64_aesd_lsx(dynarec_la64_t* dyn, int ninst, int dst)
|
||||
TABLE64C(x5, const_la64_vpaes_dec_tables);
|
||||
VLD(tab, x5, 6 * 16);
|
||||
VSHUF_B(dst, dst, dst, tab);
|
||||
VXOR_V(zero, zero, zero);
|
||||
VXORI_B(dst, dst, 99);
|
||||
VANDI_B(t0, dst, 0x0f);
|
||||
VSRLI_B(t1, dst, 4);
|
||||
@@ -367,13 +364,13 @@ static inline void la64_aesd_lsx(dynarec_la64_t* dyn, int ninst, int dst)
|
||||
VSHUF_B(t1, zero, tab, t3);
|
||||
VXOR_V(dst, t0, t1);
|
||||
VLD(tab, x5, 7 * 16);
|
||||
VLD(zero, x5, 8 * 16);
|
||||
la64_invmixcolumns_xtime_lsx(dyn, ninst, dst, tab, zero, t0, t1, t2, t3);
|
||||
VLD(t4, x5, 8 * 16);
|
||||
la64_invmixcolumns_xtime_lsx(dyn, ninst, dst, tab, t4, t0, t1, t2, t3);
|
||||
}
|
||||
|
||||
static inline void la64_aesd_lasx(dynarec_la64_t* dyn, int ninst, int dst)
|
||||
{
|
||||
int zero = fpu_get_scratch(dyn);
|
||||
int zero = VZERO;
|
||||
int t0 = fpu_get_scratch(dyn);
|
||||
int t1 = fpu_get_scratch(dyn);
|
||||
int t2 = fpu_get_scratch(dyn);
|
||||
@@ -384,7 +381,6 @@ static inline void la64_aesd_lasx(dynarec_la64_t* dyn, int ninst, int dst)
|
||||
TABLE64C(x5, const_la64_vpaes_dec_tables_xv);
|
||||
XVLD(tab, x5, 6 * 32);
|
||||
XVSHUF_B(dst, dst, dst, tab);
|
||||
XVXOR_V(zero, zero, zero);
|
||||
XVXORI_B(dst, dst, 99);
|
||||
XVANDI_B(t0, dst, 0x0f);
|
||||
XVSRLI_B(t1, dst, 4);
|
||||
@@ -414,13 +410,13 @@ static inline void la64_aesd_lasx(dynarec_la64_t* dyn, int ninst, int dst)
|
||||
XVSHUF_B(t1, zero, tab, t3);
|
||||
XVXOR_V(dst, t0, t1);
|
||||
XVLD(tab, x5, 7 * 32);
|
||||
XVLD(zero, x5, 8 * 32);
|
||||
la64_invmixcolumns_xtime_lasx(dyn, ninst, dst, tab, zero, t0, t1, t2, t3);
|
||||
XVLD(t4, x5, 8 * 32);
|
||||
la64_invmixcolumns_xtime_lasx(dyn, ninst, dst, tab, t4, t0, t1, t2, t3);
|
||||
}
|
||||
|
||||
static inline void la64_aeskeygenassist_lsx(dynarec_la64_t* dyn, int ninst, int dst, uint8_t imm)
|
||||
{
|
||||
int zero = fpu_get_scratch(dyn);
|
||||
int zero = VZERO;
|
||||
int t0 = fpu_get_scratch(dyn);
|
||||
int t1 = fpu_get_scratch(dyn);
|
||||
int t2 = fpu_get_scratch(dyn);
|
||||
|
||||
@@ -506,14 +506,12 @@ uintptr_t dynarec64_AVX_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, in
|
||||
if (vex.v != 0) {
|
||||
UDF();
|
||||
} else {
|
||||
q2 = fpu_get_scratch(dyn);
|
||||
XVXOR_V(q2, q2, q2);
|
||||
for (int i = 0; i < (rex.is32bits ? 8 : 16); ++i) {
|
||||
if (dyn->lsx.avxcache[i].v != -1) {
|
||||
q1 = avx_get_reg(dyn, ninst, x1, i, 1, LSX_AVX_WIDTH_256);
|
||||
XVPERMI_Q(q1, q2, XVPERMI_IMM_4_0(0, 2));
|
||||
XVPERMI_Q(q1, VZERO, XVPERMI_IMM_4_0(0, 2));
|
||||
} else {
|
||||
VST(q2, xEmu, offsetof(x64emu_t, ymm[i]));
|
||||
VST(VZERO, xEmu, offsetof(x64emu_t, ymm[i]));
|
||||
}
|
||||
}
|
||||
SMWRITE2();
|
||||
|
||||
@@ -378,12 +378,11 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
if (BOX64ENV(dynarec_fastround) <= 1) {
|
||||
u8 = sse_setround(dyn, ninst, x6, x4);
|
||||
}
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
if (vex.l) {
|
||||
XVXOR_V(d0, d0, d0);
|
||||
XVFCVT_S_D(v0, d0, v1);
|
||||
XVFCVT_S_D(v0, VZERO, v1);
|
||||
XVPERMI_D(v0, v0, 0b11011000);
|
||||
} else {
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
VFCVT_S_D(d0, v1, v1);
|
||||
XVPICKVE_D(v0, d0, 0);
|
||||
}
|
||||
@@ -1177,12 +1176,11 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
nextop = F8;
|
||||
GETEYxy(v1, 0, 0);
|
||||
GETGYx_empty(v0);
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
d1 = fpu_get_scratch(dyn);
|
||||
if (vex.l) {
|
||||
XVXOR_V(d0, d0, d0);
|
||||
XVFTINTRZ_W_D(d1, d0, v1); // v0 [lo0, lo1, --, --, hi0, hi1, --, -- ]
|
||||
d1 = fpu_get_scratch(dyn);
|
||||
XVFTINTRZ_W_D(d1, VZERO, v1); // v0 [lo0, lo1, --, --, hi0, hi1, --, -- ]
|
||||
if (!BOX64ENV(dynarec_fastround)) {
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
q0 = fpu_get_scratch(dyn);
|
||||
q1 = fpu_get_scratch(dyn);
|
||||
XVLDI(q0, 0b1001110000000); // broadcast 0x80000000 to all
|
||||
@@ -1198,6 +1196,7 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
}
|
||||
XVPERMI_D(v0, v0, 0b11011000);
|
||||
} else {
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
VFTINTRZ_W_D(d0, v1, v1);
|
||||
if (!BOX64ENV(dynarec_fastround)) {
|
||||
q0 = fpu_get_scratch(dyn);
|
||||
|
||||
@@ -63,12 +63,10 @@ uintptr_t dynarec64_AVX_66_0F38(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
nextop = F8;
|
||||
GETGY_empty_VYEY_xy(v0, v1, v2, 0);
|
||||
q0 = fpu_get_scratch(dyn);
|
||||
q1 = fpu_get_scratch(dyn);
|
||||
VLDIxy(q0, 0b0000010001111); // broadcast 0b10001111 as byte
|
||||
VAND_Vxy(q0, q0, v2);
|
||||
VMINIxy(BU, q0, q0, 0x1f);
|
||||
VXOR_Vxy(q1, q1, q1);
|
||||
VSHUF_Bxy(v0, q1, v1, q0);
|
||||
VSHUF_Bxy(v0, VZERO, v1, q0);
|
||||
break;
|
||||
case 0x01:
|
||||
INST_NAME("VPHADDW Gx, Vx, Ex");
|
||||
@@ -346,25 +344,19 @@ uintptr_t dynarec64_AVX_66_0F38(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
INST_NAME("VPABSB Gx, Ex");
|
||||
nextop = F8;
|
||||
GETGY_empty_EY_xy(v0, v1, 0);
|
||||
q0 = fpu_get_scratch(dyn);
|
||||
XVXOR_V(q0, q0, q0);
|
||||
VABSDxy(B, v0, v1, q0);
|
||||
VABSDxy(B, v0, v1, VZERO);
|
||||
break;
|
||||
case 0x1D:
|
||||
INST_NAME("VPABSW Gx, Ex");
|
||||
nextop = F8;
|
||||
GETGY_empty_EY_xy(v0, v1, 0);
|
||||
q0 = fpu_get_scratch(dyn);
|
||||
XVXOR_V(q0, q0, q0);
|
||||
VABSDxy(H, v0, v1, q0);
|
||||
VABSDxy(H, v0, v1, VZERO);
|
||||
break;
|
||||
case 0x1E:
|
||||
INST_NAME("VPABSD Gx, Ex");
|
||||
nextop = F8;
|
||||
GETGY_empty_EY_xy(v0, v1, 0);
|
||||
q0 = fpu_get_scratch(dyn);
|
||||
XVXOR_V(q0, q0, q0);
|
||||
VABSDxy(W, v0, v1, q0);
|
||||
VABSDxy(W, v0, v1, VZERO);
|
||||
break;
|
||||
case 0x20:
|
||||
INST_NAME("VPMOVSXBW Gx, Ex");
|
||||
@@ -498,32 +490,26 @@ uintptr_t dynarec64_AVX_66_0F38(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
INST_NAME("VMASKMOVPS Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
GETGY_empty_VYEY_xy(v0, v1, v2, 0);
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
d1 = fpu_get_scratch(dyn);
|
||||
if (vex.l) {
|
||||
XVXOR_V(d0, d0, d0);
|
||||
XVSLTI_W(d1, v1, 0); // create all-one mask for negetive element.
|
||||
XVBITSEL_V(v0, d0, v2, d1);
|
||||
XVBITSEL_V(v0, VZERO, v2, d1);
|
||||
} else {
|
||||
VXOR_V(d0, d0, d0);
|
||||
VSLTI_W(d1, v1, 0); // create all-one mask for negetive element.
|
||||
VBITSEL_V(v0, d0, v2, d1);
|
||||
VBITSEL_V(v0, VZERO, v2, d1);
|
||||
}
|
||||
break;
|
||||
case 0x2D:
|
||||
INST_NAME("VMASKMOVPD Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
GETGY_empty_VYEY_xy(v0, v1, v2, 0);
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
d1 = fpu_get_scratch(dyn);
|
||||
if (vex.l) {
|
||||
XVXOR_V(d0, d0, d0);
|
||||
XVSLTI_D(d1, v1, 0); // create all-one mask for negetive element.
|
||||
XVBITSEL_V(v0, d0, v2, d1);
|
||||
XVBITSEL_V(v0, VZERO, v2, d1);
|
||||
} else {
|
||||
VXOR_V(d0, d0, d0);
|
||||
VSLTI_D(d1, v1, 0); // create all-one mask for negetive element.
|
||||
VBITSEL_V(v0, d0, v2, d1);
|
||||
VBITSEL_V(v0, VZERO, v2, d1);
|
||||
}
|
||||
break;
|
||||
case 0x2E:
|
||||
@@ -836,24 +822,21 @@ uintptr_t dynarec64_AVX_66_0F38(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
INST_NAME("VPMASKMOVD/Q Gx, Vx, Ex");
|
||||
nextop = F8;
|
||||
GETGY_empty_VYEY_xy(v0, v1, v2, 0);
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
d1 = fpu_get_scratch(dyn);
|
||||
if (vex.l) {
|
||||
XVXOR_V(d0, d0, d0);
|
||||
if (rex.w) {
|
||||
XVSLTI_D(d1, v1, 0);
|
||||
} else {
|
||||
XVSLTI_W(d1, v1, 0);
|
||||
}
|
||||
XVBITSEL_V(v0, d0, v2, d1);
|
||||
XVBITSEL_V(v0, VZERO, v2, d1);
|
||||
} else {
|
||||
VXOR_V(d0, d0, d0);
|
||||
if (rex.w) {
|
||||
VSLTI_D(d1, v1, 0);
|
||||
} else {
|
||||
VSLTI_W(d1, v1, 0);
|
||||
}
|
||||
VBITSEL_V(v0, d0, v2, d1);
|
||||
VBITSEL_V(v0, VZERO, v2, d1);
|
||||
}
|
||||
break;
|
||||
case 0x8E:
|
||||
|
||||
@@ -35,7 +35,7 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
int cacheupd = 0;
|
||||
int v0, v1, v2;
|
||||
int q0, q1, q2;
|
||||
int d0, d1, d2;
|
||||
int d0, d1;
|
||||
int s0;
|
||||
uint64_t tmp64u;
|
||||
int64_t j64;
|
||||
@@ -147,7 +147,6 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
XVXOR_V(v0, v0, v0);
|
||||
break;
|
||||
}
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
uint8_t zero_low = (u8 & 0x8) >> 3;
|
||||
uint8_t zero_up = (u8 & 0x80) >> 7;
|
||||
uint8_t vec_lo = (u8 & 0x2) >> 1;
|
||||
@@ -165,13 +164,12 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
}
|
||||
break;
|
||||
}
|
||||
XVXOR_V(d0, d0, d0);
|
||||
if (zero_low) {
|
||||
XVORI_B(v0, vec_hi ? v2 : v1, 0);
|
||||
XVPERMI_Q(v0, d0, XVPERMI_IMM_4_0(2 + index_hi, 0));
|
||||
XVPERMI_Q(v0, VZERO, XVPERMI_IMM_4_0(2 + index_hi, 0));
|
||||
} else {
|
||||
XVORI_B(v0, vec_lo ? v2 : v1, 0);
|
||||
XVPERMI_Q(v0, d0, XVPERMI_IMM_4_0(0, 2 + index_lo));
|
||||
XVPERMI_Q(v0, VZERO, XVPERMI_IMM_4_0(0, 2 + index_lo));
|
||||
}
|
||||
break;
|
||||
case 0x08:
|
||||
@@ -507,7 +505,6 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
GETEYSD(v1, 1, 1);
|
||||
}
|
||||
u8 = F8;
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
if (u8 & 4) {
|
||||
u8 = sse_setround(dyn, ninst, x4, x5);
|
||||
} else {
|
||||
@@ -517,13 +514,11 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
u8 = x4;
|
||||
}
|
||||
if (vex.l) {
|
||||
XVXOR_V(d0, d0, d0);
|
||||
XVFCVT_H_S(v1, d0, v0);
|
||||
XVFCVT_H_S(v1, VZERO, v0);
|
||||
XVPERMI_D(v1, v1, 0b11011000);
|
||||
PUTEYx(v1);
|
||||
} else {
|
||||
XVXOR_V(d0, d0, d0);
|
||||
VFCVT_H_S(v1, d0, v0);
|
||||
VFCVT_H_S(v1, VZERO, v0);
|
||||
PUTEYSD(v1);
|
||||
}
|
||||
x87_restoreround(dyn, ninst, u8);
|
||||
@@ -573,10 +568,9 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
}
|
||||
uint8_t zmask = u8 & 0xf;
|
||||
if (zmask) {
|
||||
VXOR_V(q1, q1, q1);
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
if (zmask & (1 << i)) {
|
||||
VEXTRINS_W(v0, q1, VEXTRINS_IMM_4_0(i, 0));
|
||||
VEXTRINS_W(v0, VZERO, VEXTRINS_IMM_4_0(i, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -606,12 +600,10 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
u8 = F8;
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
d1 = fpu_get_scratch(dyn);
|
||||
d2 = fpu_get_scratch(dyn);
|
||||
VFMULxy(S, d0, v1, v2);
|
||||
VXOR_Vxy(d2, d2, d2);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
if (!(u8 & (1 << (4 + i)))) {
|
||||
VEXTRINSxy(W, d0, d2, (i << 4));
|
||||
VEXTRINSxy(W, d0, VZERO, (i << 4));
|
||||
}
|
||||
}
|
||||
VSHUF4Ixy(W, d1, d0, 0b10110001); // v0[a,b,c,d] v1[b,a,d,c]
|
||||
@@ -621,7 +613,7 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
VREPLVEIxy(W, v0, d0, 0);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
if (!(u8 & (1 << i))) {
|
||||
VEXTRINSxy(W, v0, d2, (i << 4));
|
||||
VEXTRINSxy(W, v0, VZERO, (i << 4));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -632,12 +624,10 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
u8 = F8;
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
d1 = fpu_get_scratch(dyn);
|
||||
d2 = fpu_get_scratch(dyn);
|
||||
VFMULxy(D, d0, v1, v2);
|
||||
VXOR_Vxy(d2, d2, d2);
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (!(u8 & (1 << (4 + i)))) {
|
||||
VEXTRINSxy(D, d0, d2, (i << 4));
|
||||
VEXTRINSxy(D, d0, VZERO, (i << 4));
|
||||
}
|
||||
}
|
||||
VSHUF4Ixy(W, d1, d0, 0b01001110); // v0[a,b] v1[b,a]
|
||||
@@ -645,7 +635,7 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i
|
||||
VREPLVEIxy(D, v0, d0, 0);
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (!(u8 & (1 << i))) {
|
||||
VEXTRINSxy(D, v0, d2, (i << 4));
|
||||
VEXTRINSxy(D, v0, VZERO, (i << 4));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -202,9 +202,7 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
d1 = fpu_get_scratch(dyn);
|
||||
FSQRT_D(d1, v2);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
VXOR_V(d0, d0, d0);
|
||||
FCMP_D(fcc0, v2, d0, cLT);
|
||||
FCMP_D(fcc0, v2, VZERO, cLT);
|
||||
BCEQZ(fcc0, 4 + 4);
|
||||
FNEG_D(d1, d1);
|
||||
}
|
||||
@@ -438,8 +436,8 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
GETVYx(v1, 0);
|
||||
GETEYSD(v2, 0, 1);
|
||||
GETGYx(v0, 1);
|
||||
q0 = fpu_get_scratch(dyn);
|
||||
u8 = F8;
|
||||
q0 = ((u8 & 0xf) == 0x0b) ? VZERO : fpu_get_scratch(dyn);
|
||||
switch (u8 & 0xf) {
|
||||
case 0x00: VFCMP_D(q0, v1, v2, cEQ); break; // Equal, not unordered
|
||||
case 0x01: VFCMP_D(q0, v1, v2, cLT); break; // Less than
|
||||
@@ -452,7 +450,7 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
case 0x08: VFCMP_D(q0, v1, v2, cUEQ); break; // Equal, or unordered
|
||||
case 0x09: VFCMP_D(q0, v1, v2, cULT); break; // Less than or unordered
|
||||
case 0x0a: VFCMP_D(q0, v1, v2, cULE); break; // Less or equal or unordered
|
||||
case 0x0b: VXOR_V(q0, q0, q0); break; // false
|
||||
case 0x0b: break; // false
|
||||
case 0x0c: VFCMP_D(q0, v1, v2, cNE); break; // Not Eual, ordered
|
||||
case 0x0d: VFCMP_D(q0, v2, v1, cLE); break; // Greater or Equal ordered
|
||||
case 0x0e: VFCMP_D(q0, v2, v1, cLT); break; // Greater ordered
|
||||
@@ -495,18 +493,17 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
GETEYxy(v1, 0, 0);
|
||||
GETGYx_empty(v0);
|
||||
u8 = sse_setround(dyn, ninst, x1, x2);
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
if (vex.l) {
|
||||
if (!BOX64ENV(dynarec_fastround)) {
|
||||
q0 = fpu_get_scratch(dyn);
|
||||
q1 = fpu_get_scratch(dyn);
|
||||
q2 = fpu_get_scratch(dyn);
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
d1 = fpu_get_scratch(dyn);
|
||||
XVFTINT_L_D(q2, v1);
|
||||
XVFCMP_D(d1, v1, v1, cUN); // get NaN mask
|
||||
}
|
||||
XVXOR_V(d0, d0, d0);
|
||||
XVFTINT_W_D(v0, d0, v1); // v0 [lo0, lo1, --, --, hi0, hi1, --, -- ]
|
||||
XVFTINT_W_D(v0, VZERO, v1); // v0 [lo0, lo1, --, --, hi0, hi1, --, -- ]
|
||||
if (!BOX64ENV(dynarec_fastround)) {
|
||||
XVLDI(q0, 0b1001110000000); // broadcast 0x80000000 to all
|
||||
MOV32w(x5, 0x7FFFFFFF);
|
||||
@@ -519,6 +516,7 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
}
|
||||
XVPERMI_D(v0, v0, 0b11011000);
|
||||
} else {
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
VFTINT_W_D(d0, v1, v1);
|
||||
if (!BOX64ENV(dynarec_fastround)) {
|
||||
q0 = fpu_get_scratch(dyn);
|
||||
|
||||
@@ -194,9 +194,7 @@ uintptr_t dynarec64_AVX_F3_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
d1 = fpu_get_scratch(dyn);
|
||||
FSQRT_S(d1, v2);
|
||||
if (!BOX64ENV(dynarec_fastnan)) {
|
||||
d0 = fpu_get_scratch(dyn);
|
||||
VXOR_V(d0, d0, d0);
|
||||
FCMP_S(fcc0, v2, d0, cLT);
|
||||
FCMP_S(fcc0, v2, VZERO, cLT);
|
||||
BCEQZ(fcc0, 4 + 4);
|
||||
FNEG_S(d1, d1);
|
||||
}
|
||||
@@ -475,8 +473,8 @@ uintptr_t dynarec64_AVX_F3_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
GETVYx(v1, 0);
|
||||
GETEYSS(v2, 0, 1);
|
||||
GETGYx(v0, 1);
|
||||
q0 = fpu_get_scratch(dyn);
|
||||
u8 = F8;
|
||||
q0 = ((u8 & 0xf) == 0x0b) ? VZERO : fpu_get_scratch(dyn);
|
||||
switch (u8 & 0xf) {
|
||||
case 0x00: VFCMP_S(q0, v1, v2, cEQ); break; // Equal, not unordered
|
||||
case 0x01: VFCMP_S(q0, v1, v2, cLT); break; // Less than
|
||||
@@ -489,7 +487,7 @@ uintptr_t dynarec64_AVX_F3_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip,
|
||||
case 0x08: VFCMP_S(q0, v1, v2, cUEQ); break; // Equal, or unordered
|
||||
case 0x09: VFCMP_S(q0, v1, v2, cULT); break; // Less than or unordered
|
||||
case 0x0a: VFCMP_S(q0, v1, v2, cULE); break; // Less or equal or unordered
|
||||
case 0x0b: VXOR_V(q0, q0, q0); break; // false
|
||||
case 0x0b: break; // false
|
||||
case 0x0c: VFCMP_S(q0, v1, v2, cNE); break; // Not Eual, ordered
|
||||
case 0x0d: VFCMP_S(q0, v2, v1, cLE); break; // Greater or Equal ordered
|
||||
case 0x0e: VFCMP_S(q0, v2, v1, cLT); break; // Greater ordered
|
||||
|
||||
@@ -35,7 +35,12 @@
|
||||
// Get a FPU scratch reg
|
||||
int fpu_get_scratch(dynarec_la64_t* dyn)
|
||||
{
|
||||
return SCRATCH0 + dyn->lsx.fpu_scratch++; // return an Sx
|
||||
int ret = SCRATCH0 + dyn->lsx.fpu_scratch++; // return an Sx
|
||||
if (ret >= SCRATCH_LIMIT) {
|
||||
dyn->abort = 1;
|
||||
ret = SCRATCH_LIMIT - 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
// Reset scratch regs counter
|
||||
void fpu_reset_scratch(dynarec_la64_t* dyn)
|
||||
@@ -922,4 +927,4 @@ void propagateFpuBarrier(dynarec_la64_t* dyn)
|
||||
last_fpu_used = -1; // reset the last_fpu_used...
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,10 @@
|
||||
|
||||
#include "../dynarec_native_functions.h"
|
||||
|
||||
#define SCRATCH0 24
|
||||
#define SCRATCH0 24
|
||||
#define VZERO 30
|
||||
#define SCRATCH 31
|
||||
#define SCRATCH_LIMIT VZERO
|
||||
|
||||
typedef struct x64emu_s x64emu_t;
|
||||
typedef struct dynarec_la64_s dynarec_la64_t;
|
||||
|
||||
@@ -25,8 +25,6 @@
|
||||
#include "dynarec_la64_functions.h"
|
||||
#include "../dynarec_helper.h"
|
||||
|
||||
#define SCRATCH 31
|
||||
|
||||
/* setup r2 to address pointed by ED, also fixaddress is an optionnal delta in the range [-absmax, +absmax], with delta&mask==0 to be added to ed for LDR/STR */
|
||||
uintptr_t geted(dynarec_la64_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, uint8_t* ed, uint8_t hint, uint8_t scratch, int64_t* fixaddress, rex_t rex, int* l, int i12, int delta)
|
||||
{
|
||||
@@ -545,6 +543,7 @@ void call_c(dynarec_la64_t* dyn, int ninst, la64_consts_t fnc, int reg, int ret,
|
||||
if (arg6) MV(A6, arg6);
|
||||
MV(A0, xEmu);
|
||||
JIRL(xRA, reg, 0);
|
||||
LA64_RESTORE_VZERO();
|
||||
if (ret >= 0) {
|
||||
MV(ret, A0);
|
||||
}
|
||||
@@ -600,6 +599,7 @@ void call_n(dynarec_la64_t* dyn, int ninst, void* fnc, int w)
|
||||
// because native function might be very different on a next run: different function address, different brick, different everything basicaly
|
||||
// and we don't have a relocation mecanism here, it's too complex
|
||||
JIRL(xRA, x3, 0x0);
|
||||
LA64_RESTORE_VZERO();
|
||||
// put return value in x64 regs
|
||||
if (w > 0) {
|
||||
MV(xRAX, A0);
|
||||
@@ -1421,11 +1421,11 @@ void sse_purge07cache(dynarec_la64_t* dyn, int ninst, int s1)
|
||||
if (dyn->lsx.lsxcache[dyn->lsx.avxcache[i].reg].t == LSX_CACHE_YMMW) {
|
||||
VST(dyn->lsx.avxcache[i].reg, xEmu, offsetof(x64emu_t, xmm[i]));
|
||||
if (dyn->lsx.avxcache[i].dirty) {
|
||||
XVXOR_V(SCRATCH, SCRATCH, SCRATCH);
|
||||
VST(VZERO, xEmu, offsetof(x64emu_t, ymm[i]));
|
||||
} else {
|
||||
XVPERMI_Q(SCRATCH, dyn->lsx.avxcache[i].reg, XVPERMI_IMM_4_0(0, 1));
|
||||
VST(SCRATCH, xEmu, offsetof(x64emu_t, ymm[i]));
|
||||
}
|
||||
VST(SCRATCH, xEmu, offsetof(x64emu_t, ymm[i]));
|
||||
fpu_free_reg(dyn, dyn->lsx.avxcache[i].reg);
|
||||
dyn->lsx.avxcache[i].v = -1;
|
||||
} else if (dyn->lsx.lsxcache[dyn->lsx.ssecache[i].reg].t == LSX_CACHE_XMMW) {
|
||||
@@ -1546,11 +1546,11 @@ void avx_forget_reg(dynarec_la64_t* dyn, int ninst, int a)
|
||||
if (dyn->lsx.lsxcache[dyn->lsx.avxcache[a].reg].t == LSX_CACHE_YMMW) {
|
||||
VST(dyn->lsx.avxcache[a].reg, xEmu, offsetof(x64emu_t, xmm[a]));
|
||||
if (dyn->lsx.avxcache[a].dirty) {
|
||||
XVXOR_V(SCRATCH, SCRATCH, SCRATCH);
|
||||
VST(VZERO, xEmu, offsetof(x64emu_t, ymm[a]));
|
||||
} else {
|
||||
XVPERMI_Q(SCRATCH, dyn->lsx.avxcache[a].reg, XVPERMI_IMM_4_0(0, 1));
|
||||
VST(SCRATCH, xEmu, offsetof(x64emu_t, ymm[a]));
|
||||
}
|
||||
VST(SCRATCH, xEmu, offsetof(x64emu_t, ymm[a]));
|
||||
}
|
||||
fpu_free_reg(dyn, dyn->lsx.avxcache[a].reg);
|
||||
dyn->lsx.avxcache[a].v = -1;
|
||||
@@ -1565,12 +1565,12 @@ void avx_reflect_reg(dynarec_la64_t* dyn, int ninst, int a)
|
||||
if (dyn->lsx.lsxcache[dyn->lsx.avxcache[a].reg].t == LSX_CACHE_YMMW) {
|
||||
VST(dyn->lsx.avxcache[a].reg, xEmu, offsetof(x64emu_t, xmm[a]));
|
||||
if (dyn->lsx.avxcache[a].dirty) {
|
||||
XVXOR_V(SCRATCH, SCRATCH, SCRATCH);
|
||||
XVPERMI_Q(dyn->lsx.avxcache[a].reg, SCRATCH, 0b00000010);
|
||||
XVPERMI_Q(dyn->lsx.avxcache[a].reg, VZERO, 0b00000010);
|
||||
VST(VZERO, xEmu, offsetof(x64emu_t, ymm[a]));
|
||||
} else {
|
||||
XVPERMI_Q(SCRATCH, dyn->lsx.avxcache[a].reg, XVPERMI_IMM_4_0(0, 1));
|
||||
VST(SCRATCH, xEmu, offsetof(x64emu_t, ymm[a]));
|
||||
}
|
||||
VST(SCRATCH, xEmu, offsetof(x64emu_t, ymm[a]));
|
||||
dyn->lsx.avxcache[a].dirty = 0;
|
||||
}
|
||||
}
|
||||
@@ -1586,8 +1586,7 @@ void avx_cleancache(dynarec_la64_t* dyn, int ninst)
|
||||
MESSAGE(LOG_DUMP, "\tClean AVX Cache ------\n");
|
||||
++old;
|
||||
}
|
||||
XVXOR_V(SCRATCH, SCRATCH, SCRATCH);
|
||||
XVPERMI_Q(dyn->lsx.avxcache[i].reg, SCRATCH, 0b00000010);
|
||||
XVPERMI_Q(dyn->lsx.avxcache[i].reg, VZERO, 0b00000010);
|
||||
dyn->lsx.avxcache[i].dirty = 0;
|
||||
}
|
||||
}
|
||||
@@ -1610,11 +1609,11 @@ static void avx_purgecache(dynarec_la64_t* dyn, int ninst, int next, int s1)
|
||||
}
|
||||
VST(dyn->lsx.avxcache[i].reg, xEmu, offsetof(x64emu_t, xmm[i]));
|
||||
if (dyn->lsx.avxcache[i].dirty) {
|
||||
XVXOR_V(SCRATCH, SCRATCH, SCRATCH);
|
||||
VST(VZERO, xEmu, offsetof(x64emu_t, ymm[i]));
|
||||
} else {
|
||||
XVPERMI_Q(SCRATCH, dyn->lsx.avxcache[i].reg, XVPERMI_IMM_4_0(0, 1));
|
||||
VST(SCRATCH, xEmu, offsetof(x64emu_t, ymm[i]));
|
||||
}
|
||||
VST(SCRATCH, xEmu, offsetof(x64emu_t, ymm[i]));
|
||||
} else {
|
||||
MESSAGE(LOG_DUMP, "\tAVX Cache for YMM%d is not write, no need to store back %d\n", i, dyn->lsx.lsxcache[dyn->lsx.avxcache[i].reg].t);
|
||||
}
|
||||
@@ -1694,8 +1693,7 @@ void fpu_popcache(dynarec_la64_t* dyn, int ninst, int s1, int not07)
|
||||
VLD(SCRATCH, xEmu, offsetof(x64emu_t, ymm[i]));
|
||||
XVPERMI_Q(dyn->lsx.avxcache[i].reg, SCRATCH, XVPERMI_IMM_4_0(0, 2));
|
||||
} else {
|
||||
XVXOR_V(SCRATCH, SCRATCH, SCRATCH);
|
||||
XVPERMI_Q(dyn->lsx.avxcache[i].reg, SCRATCH, XVPERMI_IMM_4_0(0, 2));
|
||||
XVPERMI_Q(dyn->lsx.avxcache[i].reg, VZERO, XVPERMI_IMM_4_0(0, 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2252,6 +2250,7 @@ static void flagsCacheTransform(dynarec_la64_t* dyn, int ninst, int s1)
|
||||
}
|
||||
TABLE64C(s1, const_updateflags_la64);
|
||||
JIRL(xRA, s1, 0);
|
||||
LA64_RESTORE_VZERO();
|
||||
MARKF2;
|
||||
}
|
||||
MESSAGE(LOG_DUMP, "\t---- Flags fetch\n");
|
||||
@@ -2306,6 +2305,7 @@ void checkCRC(dynarec_la64_t* dyn, int ninst)
|
||||
LD_D(x1, x6, offsetof(dynablock_t, x64_addr));
|
||||
LD_WU(x2, x6, offsetof(dynablock_t, x64_size));
|
||||
JIRL(xRA, x3, 0x0);
|
||||
LA64_RESTORE_VZERO();
|
||||
// done, result in x1, load the stored hash (sign extended, as the crc will also be sign extended)
|
||||
LD_W(x2, x6, offsetof(dynablock_t, hash));
|
||||
// compare computed crc with stored one, jump to continue is equal
|
||||
|
||||
@@ -21,6 +21,15 @@
|
||||
#include "la64_emitter.h"
|
||||
#include "../emu/x64primop.h"
|
||||
#include "dynarec_la64_consts.h"
|
||||
#include "dynarec_la64_functions.h"
|
||||
|
||||
#define LA64_RESTORE_VZERO() \
|
||||
do { \
|
||||
if (cpuext.lasx) \
|
||||
XVXOR_V(VZERO, VZERO, VZERO); \
|
||||
else \
|
||||
VXOR_V(VZERO, VZERO, VZERO); \
|
||||
} while (0)
|
||||
|
||||
#define F8 *(uint8_t*)(addr++)
|
||||
#define F8S *(int8_t*)(addr++)
|
||||
@@ -959,12 +968,13 @@
|
||||
#endif
|
||||
|
||||
#ifndef READFLAGS
|
||||
#define READFLAGS(A) \
|
||||
if ((A) != X_PEND \
|
||||
&& (dyn->f == status_unk)) { \
|
||||
TABLE64C(x6, const_updateflags_la64); \
|
||||
JIRL(xRA, x6, 0); \
|
||||
dyn->f = status_none; \
|
||||
#define READFLAGS(A) \
|
||||
if ((A) != X_PEND \
|
||||
&& (dyn->f == status_unk)) { \
|
||||
TABLE64C(x6, const_updateflags_la64); \
|
||||
JIRL(xRA, x6, 0); \
|
||||
LA64_RESTORE_VZERO(); \
|
||||
dyn->f = status_none; \
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1003,6 +1013,7 @@
|
||||
&& ((dyn->f == status_unk) || (dyn->f == status_set))) { \
|
||||
TABLE64C(x6, const_updateflags_la64); \
|
||||
JIRL(xRA, x6, 0); \
|
||||
LA64_RESTORE_VZERO(); \
|
||||
dyn->f = status_none; \
|
||||
}
|
||||
|
||||
|
||||
@@ -10,9 +10,20 @@
|
||||
.text
|
||||
.align 4
|
||||
|
||||
.extern cpuext
|
||||
.extern LinkNext
|
||||
.extern LinkNextInvalid
|
||||
|
||||
.macro restore_vzero
|
||||
.word 0x71277bde // vxor.v $vr30, $vr30, $vr30
|
||||
la.global $r19, cpuext
|
||||
ldptr.d $r19, $r19, 0
|
||||
andi $r19, $r19, 0x20
|
||||
beqz $r19, 1f
|
||||
.word 0x75277bde // xvxor.v $xr30, $xr30, $xr30
|
||||
1:
|
||||
.endm
|
||||
|
||||
.global la64_next
|
||||
.global la64_next_invalid
|
||||
|
||||
@@ -41,6 +52,7 @@ la64_next:
|
||||
bl LinkNext
|
||||
// preserve return value
|
||||
move $r16, $a0
|
||||
restore_vzero
|
||||
// pop regs
|
||||
ld.d RDI, $sp, 0
|
||||
ld.d RSI, $sp, 8
|
||||
@@ -81,6 +93,7 @@ la64_next_invalid:
|
||||
bl LinkNextInvalid
|
||||
// preserve return value
|
||||
move $r16, $a0
|
||||
restore_vzero
|
||||
// pop regs
|
||||
ld.d RDI, $sp, 0
|
||||
ld.d RSI, $sp, 8
|
||||
|
||||
@@ -12,6 +12,16 @@
|
||||
|
||||
.extern cpuext
|
||||
|
||||
.macro restore_vzero
|
||||
.word 0x71277bde // vxor.v $vr30, $vr30, $vr30
|
||||
la.global $r19, cpuext
|
||||
ldptr.d $r19, $r19, 0
|
||||
andi $r19, $r19, 0x20
|
||||
beqz $r19, 1f
|
||||
.word 0x75277bde // xvxor.v $xr30, $xr30, $xr30
|
||||
1:
|
||||
.endm
|
||||
|
||||
.global la64_prolog
|
||||
la64_prolog:
|
||||
//save all 18 used register
|
||||
@@ -72,5 +82,6 @@ la64_prolog:
|
||||
addi.d $sp, $sp, -16
|
||||
// save old sp into xSavedSP
|
||||
addi.d SavedSP, $sp, 16
|
||||
restore_vzero
|
||||
//jump to function
|
||||
jirl $r0, $r16, 0
|
||||
Reference in new issue
Block a user