Skip to content

Commit

Permalink
[ARM64_DYNAREC] Optimized 8bits OR when no flags is needed
Browse files Browse the repository at this point in the history
  • Loading branch information
ptitSeb committed Jan 7, 2025
1 parent 691259e commit a61888e
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 15 deletions.
71 changes: 56 additions & 15 deletions src/dynarec/arm64/dynarec_arm64_00.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,23 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("OR Eb, Gb");
SETFLAGS(X_ALL, SF_SET_PENDING);
nextop = F8;
GETEB(x1, 0);
GETGB(x2);
emit_or8(dyn, ninst, x1, x2, x4, x5);
EBBACK;
UFLAG_IF {
GETEB(x1, 0);
GETGB(x2);
emit_or8(dyn, ninst, x1, x2, x4, x5);
EBBACK;
} else {
if(MODREG) {
GETGB(x2);
CALCEB();
ORRx_REG_LSL(wback, wback, x2, wb2);
} else {
GETEB(x1, 0);
CALCGB();
ORRw_REG_LSR(x1, x1, gb1, 8*gb2);
EBBACK;
}
}
break;
case 0x09:
INST_NAME("OR Ed, Gd");
Expand All @@ -144,10 +157,16 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("OR Gb, Eb");
SETFLAGS(X_ALL, SF_SET_PENDING);
nextop = F8;
GETEB(x2, 0);
GETGB(x1);
emit_or8(dyn, ninst, x1, x2, x3, x4);
GBBACK;
UFLAG_IF {
GETEB(x2, 0);
GETGB(x1);
emit_or8(dyn, ninst, x1, x2, x3, x4);
GBBACK;
} else {
GETEB(x2, 0);
CALCGB();
ORRx_REG_LSL(gb1, gb1, x2, gb2*8);
}
break;
case 0x0B:
INST_NAME("OR Gd, Ed");
Expand All @@ -161,9 +180,19 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("OR AL, Ib");
SETFLAGS(X_ALL, SF_SET_PENDING);
u8 = F8;
UXTBw(x1, xRAX);
emit_or8c(dyn, ninst, x1, u8, x3, x4);
BFIx(xRAX, x1, 0, 8);
UFLAG_IF {
UXTBw(x1, xRAX);
emit_or8c(dyn, ninst, x1, u8, x3, x4);
BFIx(xRAX, x1, 0, 8);
} else {
int mask = convert_bitmask_x(u8);
if(mask)
ORRx_mask(xRAX, xRAX, (mask>>12)&1, mask&0x3F, (mask>>6)&0x3F);
else {
MOV32w(x1, u8);
ORRx_REG(xRAX, xRAX, x1);
}
}
break;
case 0x0D:
INST_NAME("OR EAX, Id");
Expand Down Expand Up @@ -1024,10 +1053,22 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 1: //OR
INST_NAME("OR Eb, Ib");
SETFLAGS(X_ALL, SF_SET_PENDING);
GETEB(x1, 1);
u8 = F8;
emit_or8c(dyn, ninst, x1, u8, x2, x4);
EBBACK;
UFLAG_IF2(|| !MODREG) {
GETEB(x1, 1);
u8 = F8;
emit_or8c(dyn, ninst, x1, u8, x2, x4);
EBBACK;
} else {
CALCEB();
u8 = F8;
int mask = convert_bitmask_x(((uint32_t)u8)<<wb2);
if(mask)
ORRx_mask(wback, wback, (mask>>12)&1, mask&0x3F, (mask>>6)&0x3F);
else {
MOV32w(x1, ((uint32_t)u8)<<wb2);
ORRx_REG(wback, wback, x1);
}
}
break;
case 2: //ADC
INST_NAME("ADC Eb, Ib");
Expand Down
21 changes: 21 additions & 0 deletions src/dynarec/arm64/dynarec_arm64_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,16 @@
#define EWBACKW(w) if(wb1) {STH(w, wback, fixedaddress); SMWRITE();} else {BFIx(wback, w, 0, 16);}
// Write back gd in correct register
#define GWBACK BFIx(TO_NAT(((nextop & 0x38) >> 3) + (rex.r << 3)), gd, 0, 16);
// no fetch version of GETEB for MODREG path only
#define CALCEB() \
if (rex.rex) { \
wback = TO_NAT((nextop & 7) + (rex.b << 3)); \
wb2 = 0; \
} else { \
wback = (nextop & 7); \
wb2 = (wback >> 2) * 8; \
wback = TO_NAT(wback & 3); \
} \
//GETEB will use i for ed, and can use r3 for wback.
#define GETEB(i, D) \
if (MODREG) { \
Expand Down Expand Up @@ -410,6 +420,16 @@
}
// Write eb (ed) back to original register / memory
#define EBBACK if(wb1) {STB(ed, wback, fixedaddress); SMWRITE();} else {BFIx(wback, ed, wb2, 8);}
// no fetch version of GETGB
#define CALCGB() \
if (rex.rex) { \
gb1 = TO_NAT(((nextop & 0x38) >> 3) + (rex.r << 3)); \
gb2 = 0; \
} else { \
gd = (nextop & 0x38) >> 3; \
gb2 = ((gd & 4) << 1); \
gb1 = TO_NAT(gd & 3); \
} \
//GETGB will use i for gd
#define GETGB(i) \
if (rex.rex) { \
Expand Down Expand Up @@ -1169,6 +1189,7 @@
#define UFLAG_RES(A) if(dyn->insts[ninst].x64.gen_flags) {STRxw_U12(A, xEmu, offsetof(x64emu_t, res));}
#define UFLAG_DF(r, A) if(dyn->insts[ninst].x64.gen_flags) {SET_DF(r, A)}
#define UFLAG_IF if(dyn->insts[ninst].x64.gen_flags)
#define UFLAG_IF2(A) if(dyn->insts[ninst].x64.gen_flags A)
#ifndef DEFAULT
#define DEFAULT *ok = -1; BARRIER(2)
#endif
Expand Down

0 comments on commit a61888e

Please sign in to comment.