Skip to content

Commit cdf3890

Browse files
committed
[LA64_DYNAREC] Revert 7586bd4 as it breaks Steam as-is
1 parent 14b660e commit cdf3890

File tree

9 files changed

+100
-117
lines changed

9 files changed

+100
-117
lines changed

src/dynarec/dynarec_native_functions.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,7 @@ static int flagsCacheNeedsTransform(dynarec_native_t* dyn, int ninst) {
720720
int jmp = dyn->insts[ninst].x64.jmp_insts;
721721
if(jmp<0)
722722
return 0;
723-
#if defined(ARM64) || defined(LA64)
723+
#ifdef ARM64
724724
// df_none is now a defered information
725725
if(dyn->insts[ninst].f_exit==dyn->insts[jmp].f_entry)
726726
return 0;

src/dynarec/dynarec_native_pass.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int
4444
int rep = 0; // 0 none, 1=F2 prefix, 2=F3 prefix
4545
int need_epilog = 1;
4646
// Clean up (because there are multiple passes)
47-
#if defined(ARM64) || defined(LA64)
47+
#ifdef ARM64
4848
dyn->f = status_unk;
4949
#else
5050
dyn->f.pending = 0;
@@ -111,7 +111,7 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int
111111
dyn->last_ip = 0;
112112
if(reset_n==-2) {
113113
MESSAGE(LOG_DEBUG, "Reset Caches to zero\n");
114-
#if defined(ARM64) || defined(LA64)
114+
#ifdef ARM64
115115
dyn->f = status_unk;
116116
#else
117117
dyn->f.dfnone = 0;
@@ -128,7 +128,7 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int
128128
}
129129
if(dyn->insts[ninst].x64.barrier&BARRIER_FLAGS) {
130130
MESSAGE(LOG_DEBUG, "Apply Barrier Flags\n");
131-
#if defined(ARM64) || defined(LA64)
131+
#ifdef ARM64
132132
dyn->f = status_unk;
133133
#else
134134
dyn->f.dfnone = 0;
@@ -262,7 +262,7 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int
262262
#endif
263263
}
264264
if(dyn->insts[next].x64.barrier&BARRIER_FLAGS) {
265-
#if defined(ARM64) || defined(LA64)
265+
#ifdef ARM64
266266
dyn->f = status_unk;
267267
#else
268268
dyn->f.pending = 0;
@@ -288,7 +288,7 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int
288288
// we use the 1st predecessor here
289289
if((ninst+1)<dyn->size && !dyn->insts[ninst+1].x64.alive) {
290290
// reset fpu value...
291-
#if defined(ARM64) || defined(LA64)
291+
#ifdef ARM64
292292
dyn->f = status_unk;
293293
#else
294294
dyn->f.dfnone = 0;

src/dynarec/la64/dynarec_la64_00.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2679,7 +2679,7 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
26792679
break;
26802680
case 0xCF:
26812681
INST_NAME("IRET");
2682-
SETFLAGS(X_ALL, SF_SET_DF, NAT_FLAGS_NOFUSION); // Not a hack, EFLAGS are restored
2682+
SETFLAGS(X_ALL, SF_SET_NODF, NAT_FLAGS_NOFUSION); // Not a hack, EFLAGS are restored
26832683
BARRIER(BARRIER_FLOAT);
26842684
iret_to_epilog(dyn, ip, ninst, rex.w);
26852685
*need_epilog = 0;

src/dynarec/la64/dynarec_la64_0f.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,8 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
417417
} else {
418418
INST_NAME("UCOMISS Gx, Ex");
419419
}
420-
SETFLAGS(X_ALL, SF_SET_DF, NAT_FLAGS_NOFUSION);
420+
SETFLAGS(X_ALL, SF_SET, NAT_FLAGS_NOFUSION);
421+
SET_DFNONE();
421422
nextop = F8;
422423
GETGX(d0, 0);
423424
GETEXSS(v0, 0, 0);

src/dynarec/la64/dynarec_la64_functions.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -599,20 +599,17 @@ static const char* Ft[] = { "fa0", "fa1", "fa2", "fa3", "fa4", "fa5", "fa6", "fa
599599
static const char* Vt[] = { "vra0", "vra1", "vra2", "vra3", "vra4", "vra5", "vra6", "vra7", "vrt0", "vrt1", "vrt2", "vrt3", "vrt4", "vrt5", "vrt6", "vrt7", "vrt8", "vrt9", "vrt10", "vrt11", "vrt12", "vrt13", "vrt14", "vrt15", "vrs0", "vrs1", "vrs2", "vrs3", "vrs4", "vrs5", "vrs6", "vrs7" };
600600
static const char* XVt[] = { "xvra0", "xvra1", "xvra2", "xvra3", "xvra4", "xvra5", "xvra6", "xvra7", "xvrt0", "xvrt1", "xvrt2", "xvrt3", "xvrt4", "xvrt5", "xvrt6", "xvrt7", "xvrt8", "xvrt9", "xvrt10", "xvrt11", "xvrt12", "xvrt13", "xvrt14", "xvrt15", "xvrs0", "xvrs1", "xvrs2", "xvrs3", "xvrs4", "xvrs5", "xvrs6", "xvrs7" };
601601

602-
static const char* df_status[] = { "unknown", "set", "none_pending", "none" };
603-
604602
void printf_x64_instruction(dynarec_native_t* dyn, zydis_dec_t* dec, instruction_x64_t* inst, const char* name);
605603
void inst_name_pass3(dynarec_native_t* dyn, int ninst, const char* name, rex_t rex)
606604
{
607605
if (!dyn->need_dump && !BOX64ENV(dynarec_gdbjit) && !BOX64ENV(dynarec_perf_map)) return;
608606

609607
static char buf[4096];
610-
int length = sprintf(buf, "barrier=%d state=%d/%s(%s->%s), %s=%X/%X, use=%X, need=%X/%X, fuse=%d/%d, sm=%d(%d/%d)",
608+
int length = sprintf(buf, "barrier=%d state=%d/%d(%d), %s=%X/%X, use=%X, need=%X/%X, fuse=%d/%d, sm=%d(%d/%d)",
611609
dyn->insts[ninst].x64.barrier,
612610
dyn->insts[ninst].x64.state_flags,
613-
df_status[dyn->f],
614-
df_status[dyn->insts[ninst].f_entry],
615-
df_status[dyn->insts[ninst].f_exit],
611+
dyn->f.pending,
612+
dyn->f.dfnone,
616613
dyn->insts[ninst].x64.may_set ? "may" : "set",
617614
dyn->insts[ninst].x64.set_flags,
618615
dyn->insts[ninst].x64.gen_flags,

src/dynarec/la64/dynarec_la64_helper.c

Lines changed: 13 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,6 @@ void jump_to_epilog(dynarec_la64_t* dyn, uintptr_t ip, int reg, int ninst)
349349
}
350350
TABLE64C(x2, const_epilog);
351351
SMEND();
352-
CHECK_DFNONE(0);
353352
BR(x2);
354353
}
355354

@@ -369,7 +368,6 @@ void jump_to_epilog_fast(dynarec_la64_t* dyn, uintptr_t ip, int reg, int ninst)
369368
}
370369
TABLE64C(x2, const_epilog_fast);
371370
SMEND();
372-
CHECK_DFNONE(0);
373371
BR(x2);
374372
}
375373

@@ -409,7 +407,6 @@ void jump_to_next(dynarec_la64_t* dyn, uintptr_t ip, int reg, int ninst, int is3
409407
if (is32bits)
410408
ip &= 0xffffffffLL;
411409

412-
CHECK_DFNONE(0);
413410
int dest;
414411
if (reg) {
415412
if (reg != xRIP) {
@@ -444,7 +441,6 @@ void ret_to_epilog(dynarec_la64_t* dyn, uintptr_t ip, int ninst, rex_t rex)
444441
MAYUSE(dyn);
445442
MAYUSE(ninst);
446443
MESSAGE(LOG_DUMP, "Ret to epilog\n");
447-
CHECK_DFNONE(0);
448444
POP1z(xRIP);
449445
MVz(x1, xRIP);
450446
SMEND();
@@ -469,7 +465,6 @@ void retn_to_epilog(dynarec_la64_t* dyn, uintptr_t ip, int ninst, rex_t rex, int
469465
MAYUSE(dyn);
470466
MAYUSE(ninst);
471467
MESSAGE(LOG_DUMP, "Retn to epilog\n");
472-
CHECK_DFNONE(0);
473468
POP1z(xRIP);
474469
if (n > 0x7ff) {
475470
MOV64x(x1, n);
@@ -518,7 +513,7 @@ void iret_to_epilog(dynarec_la64_t* dyn, uintptr_t ip, int ninst, int is64bits)
518513
AND(xFlags, xFlags, x1);
519514
ORI(xFlags, xFlags, 0x2);
520515
SPILL_EFLAGS();
521-
FORCE_DFNONE();
516+
SET_DFNONE();
522517
// POP RSP
523518
if (is64bits) {
524519
POP1(x3); // rsp
@@ -545,7 +540,6 @@ void iret_to_epilog(dynarec_la64_t* dyn, uintptr_t ip, int ninst, int is64bits)
545540
void call_c(dynarec_la64_t* dyn, int ninst, la64_consts_t fnc, int reg, int ret, int saveflags, int savereg, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6)
546541
{
547542
MAYUSE(fnc);
548-
CHECK_DFNONE(1);
549543
if (savereg == 0)
550544
savereg = x87pc;
551545
if (saveflags) {
@@ -614,7 +608,6 @@ void call_c(dynarec_la64_t* dyn, int ninst, la64_consts_t fnc, int reg, int ret,
614608
void call_n(dynarec_la64_t* dyn, int ninst, void* fnc, int w)
615609
{
616610
MAYUSE(fnc);
617-
CHECK_DFNONE(1);
618611
fpu_pushcache(dyn, ninst, x3, 1);
619612
ST_D(xRSP, xEmu, offsetof(x64emu_t, regs[_SP]));
620613
ST_D(xRBP, xEmu, offsetof(x64emu_t, regs[_BP]));
@@ -2276,44 +2269,31 @@ static void flagsCacheTransform(dynarec_la64_t* dyn, int ninst, int s1)
22762269
int jmp = dyn->insts[ninst].x64.jmp_insts;
22772270
if (jmp < 0)
22782271
return;
2279-
if (dyn->insts[jmp].f_exit == dyn->insts[jmp].f_entry) // flags will be fully known, nothing we can do more
2272+
if (dyn->f.dfnone || ((dyn->insts[jmp].f_exit.dfnone && !dyn->insts[jmp].f_entry.dfnone) && !dyn->insts[jmp].x64.use_flags)) // flags are fully known, nothing we can do more
22802273
return;
22812274
MESSAGE(LOG_DUMP, "\tFlags fetch ---- ninst=%d -> %d\n", ninst, jmp);
2282-
int go_fetch = 0;
2283-
switch (dyn->insts[jmp].f_entry) {
2284-
case status_unk:
2285-
if (dyn->insts[ninst].f_exit == status_none_pending) {
2286-
FORCE_DFNONE();
2287-
}
2275+
int go = (dyn->insts[jmp].f_entry.dfnone && !dyn->f.dfnone && !dyn->insts[jmp].df_notneeded) ? 1 : 0;
2276+
switch (dyn->insts[jmp].f_entry.pending) {
2277+
case SF_UNKNOWN:
2278+
go = 0;
22882279
break;
2289-
case status_set:
2290-
if (dyn->insts[ninst].f_exit == status_none_pending) {
2291-
FORCE_DFNONE();
2280+
default:
2281+
if (go && !(dyn->insts[jmp].x64.need_before & X_PEND) && (dyn->f.pending != SF_UNKNOWN)) {
2282+
// just clear df flags
2283+
go = 0;
2284+
ST_W(xZR, xEmu, offsetof(x64emu_t, df));
22922285
}
2293-
if (dyn->insts[ninst].f_exit == status_unk)
2294-
go_fetch = 1;
2295-
break;
2296-
case status_none_pending:
2297-
if (dyn->insts[ninst].f_exit != status_none)
2298-
go_fetch = 1;
2299-
break;
2300-
case status_none:
2301-
if (dyn->insts[ninst].f_exit == status_none_pending) {
2302-
FORCE_DFNONE();
2303-
} else
2304-
go_fetch = 1;
23052286
break;
23062287
}
2307-
if (go_fetch) {
2308-
if (dyn->f == status_unk) {
2288+
if (go) {
2289+
if (dyn->f.pending != SF_PENDING) {
23092290
LD_WU(s1, xEmu, offsetof(x64emu_t, df));
23102291
j64 = (GETMARKF2) - (dyn->native_size);
23112292
BEQZ(s1, j64);
23122293
}
23132294
CALL_(const_updateflags, -1, 0, 0, 0);
23142295
MARKF2;
23152296
}
2316-
MESSAGE(LOG_DUMP, "\t---- Flags fetch\n");
23172297
}
23182298

23192299
void CacheTransform(dynarec_la64_t* dyn, int ninst, int cacheupd, int s1, int s2, int s3)

src/dynarec/la64/dynarec_la64_helper.h

Lines changed: 62 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -831,29 +831,36 @@
831831
LOAD_REG(R15);
832832

833833
#define FORCE_DFNONE() ST_W(xZR, xEmu, offsetof(x64emu_t, df))
834-
#define CHECK_DFNONE(N) \
835-
do { \
836-
if (dyn->f == status_none_pending) { \
837-
FORCE_DFNONE(); \
838-
if (N) dyn->f = status_none; \
839-
} \
840-
} while (0)
841834

842-
#define SET_DFNONE() \
843-
do { \
844-
if (!dyn->insts[ninst].x64.may_set && (dyn->f != status_none)) { \
845-
dyn->f = status_none_pending; \
846-
} \
835+
#define SET_DFNONE() \
836+
do { \
837+
if (!dyn->f.dfnone) { \
838+
FORCE_DFNONE(); \
839+
} \
840+
if (!dyn->insts[ninst].x64.may_set) { \
841+
dyn->f.dfnone = 1; \
842+
} \
847843
} while (0)
848844

849-
#define SET_DF(S, N) \
850-
if ((N) != d_none) { \
851-
MOV32w(S, (N)); \
852-
ST_W(S, xEmu, offsetof(x64emu_t, df)); \
853-
dyn->f = status_set; \
854-
} else \
845+
#define SET_DF(S, N) \
846+
if ((N) != d_none) { \
847+
MOV32w(S, (N)); \
848+
ST_W(S, xEmu, offsetof(x64emu_t, df)); \
849+
if (dyn->f.pending == SF_PENDING \
850+
&& dyn->insts[ninst].x64.need_after \
851+
&& !(dyn->insts[ninst].x64.need_after & X_PEND)) { \
852+
CALL_(const_updateflags, -1, 0, 0, 0); \
853+
dyn->f.pending = SF_SET; \
854+
SET_NODF(); \
855+
} \
856+
dyn->f.dfnone = 0; \
857+
} else \
855858
SET_DFNONE()
856859

860+
#define SET_NODF() dyn->f.dfnone = 0
861+
#define SET_DFOK() \
862+
dyn->f.dfnone = 1
863+
857864
#define CLEAR_FLAGS_(s) \
858865
MOV64x(s, (1UL << F_AF) | (1UL << F_CF) | (1UL << F_OF) | (1UL << F_ZF) | (1UL << F_SF) | (1UL << F_PF)); \
859866
ANDN(xFlags, xFlags, s);
@@ -935,11 +942,18 @@
935942
#endif
936943

937944
#ifndef READFLAGS
938-
#define READFLAGS(A) \
939-
if ((A) != X_PEND \
940-
&& (dyn->f == status_unk)) { \
941-
CALL_(const_updateflags, -1, 0, 0, 0); \
942-
dyn->f = status_none; \
945+
#define READFLAGS(A) \
946+
if (((A) != X_PEND && dyn->f.pending != SF_SET) \
947+
&& (dyn->f.pending != SF_SET_PENDING)) { \
948+
if (dyn->f.pending != SF_PENDING) { \
949+
LD_WU(x3, xEmu, offsetof(x64emu_t, df)); \
950+
j64 = (GETMARKF) - (dyn->native_size); \
951+
BEQ(x3, xZR, j64); \
952+
} \
953+
CALL_(const_updateflags, -1, 0, 0, 0); \
954+
MARKF; \
955+
dyn->f.pending = SF_SET; \
956+
SET_DFOK(); \
943957
}
944958
#endif
945959

@@ -973,28 +987,32 @@
973987
#define NAT_FLAGS_ENABLE_SIGN() dyn->insts[ninst].nat_flags_sign = 1
974988

975989
#ifndef SETFLAGS
976-
#define SETFLAGS(A, B, FUSION) \
977-
do { \
978-
if (((B) & SF_SUB) \
979-
&& (dyn->insts[ninst].x64.gen_flags & (~(A)))) \
980-
READFLAGS(((dyn->insts[ninst].x64.gen_flags & X_PEND) ? X_ALL : dyn->insts[ninst].x64.gen_flags) & (~(A))); \
981-
if (dyn->insts[ninst].x64.gen_flags) switch (B) { \
982-
case SF_SET_DF: dyn->f = status_set; break; \
983-
case SF_SET_NODF: SET_DFNONE(); break; \
984-
case SF_SUBSET: \
985-
case SF_SUBSET_PENDING: \
986-
case SF_SET: \
987-
case SF_PENDING: \
988-
case SF_SET_PENDING: \
989-
SET_DFNONE(); \
990-
break; \
991-
} \
992-
else \
993-
SET_DFNONE(); \
994-
dyn->insts[ninst].nat_flags_nofusion = (FUSION); \
995-
} while (0)
990+
#define SETFLAGS(A, B, FUSION) \
991+
if (dyn->f.pending != SF_SET \
992+
&& ((B) & SF_SUB) \
993+
&& (dyn->insts[ninst].x64.gen_flags & (~(A)))) \
994+
READFLAGS(((dyn->insts[ninst].x64.gen_flags & X_PEND) ? X_ALL : dyn->insts[ninst].x64.gen_flags) & (~(A))); \
995+
if (dyn->insts[ninst].x64.gen_flags) switch (B) { \
996+
case SF_SUBSET: \
997+
case SF_SET: dyn->f.pending = SF_SET; break; \
998+
case SF_SET_DF: \
999+
dyn->f.pending = SF_SET; \
1000+
dyn->f.dfnone = 1; \
1001+
break; \
1002+
case SF_SET_NODF: \
1003+
dyn->f.pending = SF_SET; \
1004+
dyn->f.dfnone = 0; \
1005+
break; \
1006+
case SF_PENDING: dyn->f.pending = SF_PENDING; break; \
1007+
case SF_SUBSET_PENDING: \
1008+
case SF_SET_PENDING: \
1009+
dyn->f.pending = (dyn->insts[ninst].x64.gen_flags & X_PEND) ? SF_SET_PENDING : SF_SET; \
1010+
break; \
1011+
} \
1012+
else \
1013+
dyn->f.pending = SF_SET; \
1014+
dyn->insts[ninst].nat_flags_nofusion = (FUSION)
9961015
#endif
997-
9981016
#ifndef JUMP
9991017
#define JUMP(A, C)
10001018
#endif

0 commit comments

Comments
 (0)