Skip to content

Commit 7e15f0e

Browse files
authored
[LA64_DYNAREC] Refined rcr8/16 /imm opcodes (#3316)
1 parent 1e73fe6 commit 7e15f0e

File tree

3 files changed

+67
-30
lines changed

3 files changed

+67
-30
lines changed

src/dynarec/la64/dynarec_la64_00.c

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2202,14 +2202,18 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
22022202
break;
22032203
case 3:
22042204
INST_NAME("RCR Eb, Ib");
2205-
MESSAGE(LOG_DUMP, "Need Optimization\n");
2206-
READFLAGS(X_CF);
2207-
SETFLAGS(X_OF | X_CF, SF_SET_DF, NAT_FLAGS_NOFUSION);
2208-
GETEB(x1, 1);
2209-
u8 = F8 & 0x1f;
2210-
MOV32w(x2, u8);
2211-
CALL_(const_rcr8, ed, x3, x1, x2);
2212-
EBBACK();
2205+
u8 = geted_ib(dyn, addr, ninst, nextop) & 0x1f;
2206+
if (u8) {
2207+
READFLAGS(X_CF);
2208+
SETFLAGS(X_OF | X_CF, SF_SUBSET, NAT_FLAGS_FUSION); // removed PENDING on purpose
2209+
GETEB(x1, 1);
2210+
u8 = F8 & 0x1f;
2211+
emit_rcr8c(dyn, ninst, x1, u8, x4, x5);
2212+
EBBACK();
2213+
} else {
2214+
FAKEED;
2215+
F8;
2216+
}
22132217
break;
22142218
case 4:
22152219
case 6:
@@ -2757,12 +2761,15 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
27572761
case 3:
27582762
if (opcode == 0xD0) {
27592763
INST_NAME("RCR Eb, 1");
2760-
GETEB(x1, 0);
2761-
MOV32w(x2, 1);
27622764
READFLAGS(X_CF);
2763-
SETFLAGS(X_OF | X_CF, SF_SET_DF, NAT_FLAGS_NOFUSION);
2765+
SETFLAGS(X_OF | X_CF, SF_SUBSET, NAT_FLAGS_FUSION); // removed PENDING on purpose
2766+
GETEB(x1, 0);
2767+
emit_rcr8c(dyn, ninst, ed, 1, x4, x5);
2768+
EBBACK();
2769+
break;
27642770
} else {
27652771
INST_NAME("RCR Eb, CL");
2772+
MESSAGE(LOG_DUMP, "Need Optimization\n");
27662773
GETEB(x1, 0);
27672774
ANDI(x2, xRCX, 0x1f);
27682775
if (BOX64DRENV(dynarec_safeflags) > 1) {
@@ -2771,11 +2778,10 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
27712778
READFLAGS(X_CF);
27722779
}
27732780
SETFLAGS(X_OF | X_CF, SF_SET_DF, NAT_FLAGS_NOFUSION);
2781+
CALL_(const_rcr8, ed, x3, x1, x2);
2782+
EBBACK();
2783+
break;
27742784
}
2775-
MESSAGE(LOG_DUMP, "Need Optimization\n");
2776-
CALL_(const_rcr8, ed, x3, x1, x2);
2777-
EBBACK();
2778-
break;
27792785
case 4:
27802786
case 6:
27812787
if (opcode == 0xD0) {

src/dynarec/la64/dynarec_la64_emit_shift.c

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1629,11 +1629,43 @@ void emit_rcl16c(dynarec_la64_t* dyn, int ninst, int s1, uint32_t c, int s3, int
16291629
if (dyn->insts[ninst].nat_flags_fusion) NAT_FLAGS_OPS(s1, xZR, s3, xZR);
16301630
}
16311631

1632+
// emit RCR8 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
1633+
void emit_rcr8c(dynarec_la64_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4)
1634+
{
1635+
c %= 9;
1636+
if (!c) return;
1637+
1638+
IFXORNAT (X_ALL) SET_DFNONE();
1639+
RESTORE_EFLAGS(s3);
1640+
IFX (X_OF) {
1641+
SRLI_D(s3, s1, 7);
1642+
XOR(s3, s3, xFlags);
1643+
BSTRINS_D(xFlags, s3, F_OF, F_OF);
1644+
}
1645+
1646+
if (c) {
1647+
BSTRINS_D(s1, xFlags, 8, 8); // insert CF to bit 8
1648+
IFX (X_CF) {
1649+
BSTRPICK_D(s3, s1, c - 1, c - 1);
1650+
BSTRINS_D(xFlags, s3, F_CF, F_CF);
1651+
}
1652+
if (c > 1) {
1653+
SLLI_D(s3, s1, 9);
1654+
OR(s1, s1, s3);
1655+
}
1656+
SRLI_D(s1, s1, c);
1657+
}
1658+
1659+
IFXA (X_ALL, cpuext.lbt) SPILL_EFLAGS();
1660+
if (dyn->insts[ninst].nat_flags_fusion) NAT_FLAGS_OPS(s1, xZR, s3, xZR);
1661+
}
1662+
16321663
// emit RCR16 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
16331664
void emit_rcr16c(dynarec_la64_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4)
16341665
{
1635-
if (!(c % 17)) return;
16361666
c %= 17;
1667+
if (!c) return;
1668+
16371669
IFXORNAT (X_ALL) SET_DFNONE();
16381670
RESTORE_EFLAGS(s3);
16391671
IFX (X_OF) {
@@ -1642,20 +1674,17 @@ void emit_rcr16c(dynarec_la64_t* dyn, int ninst, int s1, uint32_t c, int s3, int
16421674
BSTRINS_D(xFlags, s3, F_OF, F_OF);
16431675
}
16441676

1645-
1646-
ANDI(s3, xFlags, 1 << F_CF);
1647-
SLLI_D(s3, s3, 16);
1648-
OR(s1, s1, s3); // insert CF to bit 16
1649-
1650-
SRLI_D(s3, s1, c);
1651-
SLLI_D(s1, s1, 17 - c);
1652-
OR(s1, s1, s3);
1653-
SLLI_D(s4, s1, 47);
1654-
BSTRPICK_D(s1, s1, 15, 0);
1655-
1656-
IFX (X_CF) {
1657-
SRLI_D(s4, s4, 63);
1658-
BSTRINS_D(xFlags, s4, F_CF, F_CF);
1677+
if (c) {
1678+
BSTRINS_D(s1, xFlags, 16, 16); // insert CF to bit 16
1679+
IFX (X_CF) {
1680+
BSTRPICK_D(s3, s1, c - 1, c - 1);
1681+
BSTRINS_D(xFlags, s3, F_CF, F_CF);
1682+
}
1683+
if (c > 1) {
1684+
SLLI_D(s3, s1, 17);
1685+
OR(s1, s1, s3);
1686+
}
1687+
SRLI_D(s1, s1, c);
16591688
}
16601689

16611690
IFXA (X_ALL, cpuext.lbt) SPILL_EFLAGS();

src/dynarec/la64/dynarec_la64_helper.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1242,6 +1242,7 @@
12421242
#define emit_rol32 STEPNAME(emit_rol32)
12431243
#define emit_rol32c STEPNAME(emit_rol32c)
12441244
#define emit_rcl16c STEPNAME(emit_rcl16c)
1245+
#define emit_rcr8c STEPNAME(emit_rcr8c)
12451246
#define emit_rcr16c STEPNAME(emit_rcr16c)
12461247
#define emit_ror16c STEPNAME(emit_ror16c)
12471248
#define emit_shld16c STEPNAME(emit_shld16c)
@@ -1399,6 +1400,7 @@ void emit_rol16c(dynarec_la64_t* dyn, int ninst, int s1, uint32_t c, int s3, int
13991400
void emit_rol32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4);
14001401
void emit_rol32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4);
14011402
void emit_rcl16c(dynarec_la64_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4);
1403+
void emit_rcr8c(dynarec_la64_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4);
14021404
void emit_rcr16c(dynarec_la64_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4);
14031405
void emit_ror16c(dynarec_la64_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4);
14041406
void emit_shrd16c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, uint32_t c, int s3, int s4, int s5);

0 commit comments

Comments
 (0)