Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 0 additions & 25 deletions src/dynarec/dynarec_native_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,6 @@ static int flagsCacheNeedsTransform(dynarec_native_t* dyn, int ninst) {
int jmp = dyn->insts[ninst].x64.jmp_insts;
if(jmp<0)
return 0;
#if defined(ARM64) || defined(LA64) || defined(PPC64LE)
// df_none is now a defered information
if(dyn->insts[ninst].f_exit==dyn->insts[jmp].f_entry)
return 0;
Expand All @@ -802,28 +801,6 @@ static int flagsCacheNeedsTransform(dynarec_native_t* dyn, int ninst) {
case status_none_pending:
return 1;
}
#else
if(dyn->insts[ninst].f_exit.dfnone) // flags are fully known, nothing we can do more
return 0;
if(dyn->insts[jmp].f_entry.dfnone && !dyn->insts[ninst].f_exit.dfnone && !dyn->insts[jmp].df_notneeded)
return 1;
switch (dyn->insts[jmp].f_entry.pending) {
case SF_UNKNOWN: return 0;
case SF_SET:
if(dyn->insts[ninst].f_exit.pending!=SF_SET && dyn->insts[ninst].f_exit.pending!=SF_SET_PENDING)
return 1;
else
return 0;
case SF_SET_PENDING:
if(dyn->insts[ninst].f_exit.pending==SF_SET_PENDING)
return 0;
return 1;
case SF_PENDING:
if(dyn->insts[ninst].f_exit.pending==SF_PENDING || dyn->insts[ninst].f_exit.pending==SF_SET_PENDING)
return 0;
return (dyn->insts[jmp].f_entry.dfnone == dyn->insts[ninst].f_exit.dfnone)?0:1;
}
#endif
return 0;
}

Expand Down Expand Up @@ -885,7 +862,6 @@ uint8_t geted_ib(dynarec_native_t* dyn, uintptr_t addr, int ninst, uint8_t nexto
}
#undef F8

#if defined(ARM64) || defined(LA64) || defined(PPC64LE)
static void propagate_dfneeded_internal(dynarec_native_t* dyn, int ninst)
{
while(ninst>=0) {
Expand Down Expand Up @@ -937,7 +913,6 @@ void propagate_nodf(dynarec_native_t* dyn)
propagate_nodf_internal(dyn, ninst);
}
}
#endif

void x64disas_add_register_mapping_annotations(char* buf, const char* disas, const register_mapping_t* mappings, size_t mappings_sz)
{
Expand Down
27 changes: 1 addition & 26 deletions src/dynarec/dynarec_native_pass.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,7 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int
int rep = 0; // 0 none, 1=F2 prefix, 2=F3 prefix
int need_epilog = 1;
// Clean up (because there are multiple passes)
#if defined(ARM64) || defined(LA64) || defined(PPC64LE)
dyn->f = status_unk;
#else
dyn->f.pending = 0;
dyn->f.dfnone = 0;
#endif
dyn->forward = 0;
dyn->forward_to = 0;
dyn->forward_size = 0;
Expand Down Expand Up @@ -184,12 +179,7 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int
dyn->last_ip = 0;
if(reset_n==-2) {
MESSAGE(LOG_DEBUG, "Reset Caches to zero\n");
#if defined(ARM64) || defined(LA64) || defined(PPC64LE)
dyn->f = status_unk;
#else
dyn->f.dfnone = 0;
dyn->f.pending = 0;
#endif
fpu_reset(dyn);
ARCH_RESET();
} else {
Expand All @@ -201,12 +191,7 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int
}
if(dyn->insts[ninst].x64.barrier&BARRIER_FLAGS) {
MESSAGE(LOG_DEBUG, "Apply Barrier Flags\n");
#if defined(ARM64) || defined(LA64) || defined(PPC64LE)
dyn->f = status_unk;
#else
dyn->f.dfnone = 0;
dyn->f.pending = 0;
#endif
}
}
reset_n = -1;
Expand Down Expand Up @@ -340,13 +325,8 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int
fpu_purgecache(dyn, ninst, 0, x1, x2, x3, 0);
#endif
}
if(dyn->insts[next].x64.barrier&BARRIER_FLAGS) {
#if defined(ARM64) || defined(LA64) || defined(PPC64LE)
if (dyn->insts[next].x64.barrier & BARRIER_FLAGS) {
dyn->f = status_unk;
#else
dyn->f.pending = 0;
dyn->f.dfnone = 0;
#endif
dyn->last_ip = 0;
}
}
Expand All @@ -367,12 +347,7 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int
// we use the 1st predecessor here
if((ninst+1)<dyn->size && !dyn->insts[ninst+1].x64.alive) {
// reset fpu value...
#if defined(ARM64) || defined(LA64) || defined(PPC64LE)
dyn->f = status_unk;
#else
dyn->f.dfnone = 0;
dyn->f.pending = 0;
#endif
fpu_reset(dyn);
while((ninst+1)<dyn->size && !dyn->insts[ninst+1].x64.alive) {
// may need to skip opcodes to advance
Expand Down
86 changes: 66 additions & 20 deletions src/dynarec/rv64/dynarec_rv64_00_1.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,37 +221,60 @@ uintptr_t dynarec64_00_1(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
break;
case 0x69:
INST_NAME("IMUL Gd, Ed, Id");
SETFLAGS(X_ALL, SF_PENDING, NAT_FLAGS_NOFUSION);
SETFLAGS(X_ALL, SF_SET_NODF, NAT_FLAGS_NOFUSION);
nextop = F8;
GETGD;
GETED(4);
i64 = F32S;
MOV64x(x4, i64);
CLEAR_FLAGS();
if (rex.w) {
// 64bits imul
UFLAG_IF {
MULH(x3, ed, x4);
MUL(gd, ed, x4);
UFLAG_OP1(x3);
UFLAG_RES(gd);
UFLAG_DF(x3, d_imul64);
SET_DFNONE();
IFX (X_CF | X_OF) {
SRAI(x5, gd, 63);
XOR(x3, x3, x5);
SNEZ(x3, x3);
IFX (X_CF) OR(xFlags, xFlags, x3); // F_CF == 0
IFX (X_OF) {
SLLI(x3, x3, F_OF2);
OR(xFlags, xFlags, x3);
}
}
} else {
MULxw(gd, ed, x4);
}
} else {
// 32bits imul
UFLAG_IF {
SEXT_W(x3, ed);
MUL(gd, x3, x4);
UFLAG_RES(gd);
SRLI(x3, gd, 32);
UFLAG_OP1(x3);
UFLAG_DF(x3, d_imul32);
MUL(x5, x3, x4);
SET_DFNONE();
IFX (X_CF | X_OF) {
SEXT_W(x3, x5);
XOR(x3, x5, x3);
SNEZ(x3, x3);
IFX (X_CF) OR(xFlags, xFlags, x3); // F_CF == 0
IFX (X_OF) {
SLLI(x3, x3, F_OF2);
OR(xFlags, xFlags, x3);
}
}
ZEXTW2(gd, x5);
} else {
MULxw(gd, ed, x4);
ZEROUP(gd);
}
ZEROUP(gd);
}
IFX (X_SF) {
SRLI(x5, gd, rex.w ? 63 : 31);
SLLI(x5, x5, F_SF);
OR(xFlags, xFlags, x5);
}
IFX (X_PF) emit_pf(dyn, ninst, gd, x3, x4);
break;
case 0x6A:
INST_NAME("PUSH Ib");
Expand All @@ -265,37 +288,60 @@ uintptr_t dynarec64_00_1(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
break;
case 0x6B:
INST_NAME("IMUL Gd, Ed, Ib");
SETFLAGS(X_ALL, SF_PENDING, NAT_FLAGS_NOFUSION);
SETFLAGS(X_ALL, SF_SET_NODF, NAT_FLAGS_NOFUSION);
nextop = F8;
GETGD;
GETED(1);
i64 = F8S;
MOV64x(x4, i64);
CLEAR_FLAGS();
if (rex.w) {
// 64bits imul
UFLAG_IF {
MULH(x3, ed, x4);
MUL(gd, ed, x4);
UFLAG_OP1(x3);
UFLAG_RES(gd);
UFLAG_DF(x3, d_imul64);
SET_DFNONE();
IFX (X_CF | X_OF) {
SRAI(x5, gd, 63);
XOR(x3, x3, x5);
SNEZ(x3, x3);
IFX (X_CF) OR(xFlags, xFlags, x3); // F_CF == 0
IFX (X_OF) {
SLLI(x3, x3, F_OF2);
OR(xFlags, xFlags, x3);
}
}
} else {
MUL(gd, ed, x4);
}
} else {
// 32bits imul
UFLAG_IF {
SEXT_W(x3, ed);
MUL(gd, x3, x4);
UFLAG_RES(gd);
SRLI(x3, gd, 32);
UFLAG_OP1(x3);
UFLAG_DF(x3, d_imul32);
MUL(x5, x3, x4); // full 64bits product
SET_DFNONE();
IFX (X_CF | X_OF) {
SEXT_W(x3, x5);
XOR(x3, x5, x3);
SNEZ(x3, x3);
IFX (X_CF) OR(xFlags, xFlags, x3); // F_CF == 0
IFX (X_OF) {
SLLI(x3, x3, F_OF2);
OR(xFlags, xFlags, x3);
}
}
ZEXTW2(gd, x5);
} else {
MULW(gd, ed, x4);
ZEROUP(gd);
}
ZEROUP(gd);
}
IFX (X_SF) {
SRLI(x5, gd, rex.w ? 63 : 31);
SLLI(x5, x5, F_SF);
OR(xFlags, xFlags, x5);
}
IFX (X_PF) emit_pf(dyn, ninst, gd, x3, x4);
break;

case 0x6C:
Expand Down
44 changes: 38 additions & 6 deletions src/dynarec/rv64/dynarec_rv64_00_3.c
Original file line number Diff line number Diff line change
Expand Up @@ -1374,30 +1374,62 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
break;
case 4:
INST_NAME("MUL AL, Ed");
SETFLAGS(X_ALL, SF_PENDING, NAT_FLAGS_NOFUSION);
SETFLAGS(X_ALL, SF_SET_NODF, NAT_FLAGS_NOFUSION);
GETEB(x1, 0);
ANDI(x2, xRAX, 0xff);
MULW(x1, x2, x1);
UFLAG_RES(x1);
SET_DFNONE();
CLEAR_FLAGS();
IFX (X_CF | X_OF) {
SRLI(x3, x1, 8);
SNEZ(x3, x3);
IFX (X_CF) OR(xFlags, xFlags, x3); // F_CF == 0
IFX (X_OF) {
SLLI(x3, x3, F_OF2);
OR(xFlags, xFlags, x3);
}
}
LUI(x2, 0xffff0);
AND(xRAX, xRAX, x2);
ZEXTH(x1, x1);
OR(xRAX, xRAX, x1);
UFLAG_DF(x1, d_mul8);
IFX (X_SF) {
SRLI(x3, xRAX, 7);
SLLI(x3, x3, F_SF);
OR(xFlags, xFlags, x3);
}
IFX (X_PF) emit_pf(dyn, ninst, xRAX, x3, x4);
break;
case 5:
INST_NAME("IMUL AL, Eb");
SETFLAGS(X_ALL, SF_PENDING, NAT_FLAGS_NOFUSION);
SETFLAGS(X_ALL, SF_SET_NODF, NAT_FLAGS_NOFUSION);
GETSEB(x1, 0);
SLLI(x2, xRAX, 56);
SRAI(x2, x2, 56);
MULW(x1, x2, x1);
UFLAG_RES(x1);
SET_DFNONE();
CLEAR_FLAGS();
IFX (X_CF | X_OF) {
SLLI(x3, x1, 48);
SRAI(x3, x3, 48); // x3 = SignExtend16(result)
XOR(x3, x3, x1);
SNEZ(x3, x3);
IFX (X_CF) OR(xFlags, xFlags, x3); // F_CF == 0
IFX (X_OF) {
SLLI(x3, x3, F_OF2);
OR(xFlags, xFlags, x3);
}
}
LUI(x2, 0xffff0);
AND(xRAX, xRAX, x2);
ZEXTH(x1, x1);
OR(xRAX, xRAX, x1);
UFLAG_DF(x1, d_imul8);
IFX (X_SF) {
SRLI(x3, xRAX, 7);
SLLI(x3, x3, F_SF);
OR(xFlags, xFlags, x3);
}
IFX (X_PF) emit_pf(dyn, ninst, xRAX, x3, x4);
break;
case 6:
INST_NAME("DIV Eb");
Expand Down
Loading
Loading