Skip to content

Commit 3ac29b6

Browse files
committed
simx86: eliminate use of Gen_sim by cpatch cmps/scas.
Code them inline like the other string instructions using the same read functions.
1 parent 1de2c78 commit 3ac29b6

File tree

3 files changed

+41
-26
lines changed

3 files changed

+41
-26
lines changed

src/base/emu-i386/simx86/codegen-sim.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,11 @@ static unsigned char *currentIG = NULL;
8282
/////////////////////////////////////////////////////////////////////////////
8383

8484
/* working registers of the host CPU */
85-
wkreg DR1; // "eax"
86-
wkreg DR2; // "edx"
85+
static wkreg DR1; // "eax"
86+
static wkreg DR2; // "edx"
8787
wkreg AR1; // "edi"
88-
wkreg AR2; // "esi"
89-
wkreg SR1; // "ebp"
88+
static wkreg AR2; // "esi"
89+
static wkreg SR1; // "ebp"
9090
wkreg TR1; // "ecx"
9191
static flgtmp RFL;
9292

@@ -264,7 +264,7 @@ static inline int FlagSync_SZAPC (void)
264264
FlagSync_S() | FlagSync_P();
265265
}
266266

267-
int FlagSync_All (void)
267+
static int FlagSync_All (void)
268268
{
269269
int nf = FlagSync_SZAPC() | FlagSync_O();
270270
if (debug_level('e')>1) e_printf("Sync ALL flags = %04x\n", nf);

src/base/emu-i386/simx86/codegen-sim.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,7 @@ typedef struct {
6666
#define LF_MASK_CF (1U << LF_BIT_CF)
6767
#define LF_MASK_PO (1U << LF_BIT_PO)
6868

69-
extern wkreg DR1; // "eax"
70-
extern wkreg DR2; // "edx"
7169
extern wkreg AR1; // "edi"
72-
extern wkreg AR2; // "esi"
73-
extern wkreg SR1; // "ebp"
7470
extern wkreg TR1; // "ecx"
7571

7672
#define GTRACE0(s) if (debug_level('e')>2) e_printf("(G) %-12s [%s]\n",(s),showmode(mode))
@@ -84,7 +80,6 @@ extern wkreg TR1; // "ecx"
8480
(s),showreg(r1),showreg(r2),(int)(a),(int)(b),showmode(mode))
8581
#define GTRACE5(s,r1,r2,a,b,c) if (debug_level('e')>2) e_printf("(G) %-12s %s %s %08x %08x %08x [%s]\n",\
8682
(s),showreg(r1),showreg(r2),(int)(a),(int)(b),(int)(c),showmode(mode))
87-
extern int FlagSync_All (void);
8883
extern unsigned int Gen_sim(const IGen *IG);
8984
extern dosaddr_t AddrGen_sim(const IGen *IG);
9085
extern void InitGen_sim(void);

src/base/emu-i386/simx86/cpatch.c

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,22 @@ struct rep_stack {
9797
} __attribute__((packed));
9898

9999

100+
#define CMPFLAGS(asmcon,eflags,op1,op2) \
101+
asm volatile("cmp %1, %2; pushf; pop %0\n\t" \
102+
: "=g" (eflags) : #asmcon (op1), #asmcon (op2))
103+
104+
#define SCASLOOP(bitsize,asmcon,eflags,addr,eax,df,ecx,repcond) \
105+
do { \
106+
CMPFLAGS(asmcon,eflags,read_##bitsize(addr),(uint##bitsize##_t)eax); \
107+
addr += df; \
108+
} while (--ecx && (eflags & X86_EFLAGS_ZF)==repcond)
109+
110+
#define CMPSLOOP(bitsize,asmcon,eflags,addr,source,df,ecx,repcond) \
111+
do { \
112+
CMPFLAGS(asmcon,eflags,read_##bitsize(addr),read_##bitsize(source)); \
113+
addr += df; source += df; \
114+
} while (--ecx && (eflags & X86_EFLAGS_ZF)==repcond)
115+
100116
void rep_movs_stos(struct rep_stack *stack)
101117
{
102118
unsigned char *paddr = stack->edi;
@@ -191,26 +207,30 @@ void rep_movs_stos(struct rep_stack *stack)
191207
if (EFLAGS & EFLAGS_DF) addr -= len;
192208
else addr += len;
193209
}
194-
else if ((op & 0xf6) == 0xa6) { /* cmps/scas */
195-
int repmod = (size == 1 ? MBYTE : size == 2 ? DATA16 : 0);
196-
AR1.d = EMUADDR_REL(stack->edi);
197-
TR1.d = stack->ecx;
198-
repmod |= MOVSDST|MREPCOND|(eip[-1]==REPNE? MREPNE:MREP);
210+
else if ((op & 0xf6) == 0xa6 && ecx > 0) { /* cmps/scas */
211+
int df = size * (CPUWORD(Ofs_FLAGS) & EFLAGS_DF? -1:1);
212+
unsigned long repcond = (eip[-1]==REPNE ? 0 : X86_EFLAGS_ZF);
213+
unsigned long eflags;
199214
if ((op & 0xfe) == 0xa6) { /* cmps */
200-
repmod |= MOVSSRC;
201-
AR2.d = EMUADDR_REL(stack->esi);
202-
IGen IG = (IGen){.op = O_MOVS_CmpD, .mode = repmod};
203-
Gen_sim(&IG);
204-
stack->esi = EMU_BASE32(AR2.d);
215+
dosaddr_t source = EMUADDR_REL(stack->esi);
216+
if (size == 1)
217+
CMPSLOOP(8,q,eflags,addr,source,df,ecx,repcond);
218+
else if (size == 2)
219+
CMPSLOOP(16,r,eflags,addr,source,df,ecx,repcond);
220+
else
221+
CMPSLOOP(32,r,eflags,addr,source,df,ecx,repcond);
222+
stack->esi = EMU_BASE32(source);
205223
}
206224
else { /* scas */
207-
DR1.d = stack->eax;
208-
IGen IG = (IGen){.op = O_MOVS_ScaD, .mode = repmod};
209-
Gen_sim(&IG);
225+
unsigned int eax = stack->eax;
226+
if (size == 1)
227+
SCASLOOP(8,q,eflags,addr,eax,df,ecx,repcond);
228+
else if (size == 2)
229+
SCASLOOP(16,r,eflags,addr,eax,df,ecx,repcond);
230+
else
231+
SCASLOOP(32,r,eflags,addr,eax,df,ecx,repcond);
210232
}
211-
addr = AR1.d;
212-
ecx = TR1.d;
213-
stack->eflags = (stack->eflags & ~EFLAGS_CC) | FlagSync_All();
233+
stack->eflags = (stack->eflags & ~EFLAGS_CC) | (eflags & EFLAGS_CC);
214234
}
215235
stack->edi = EMU_BASE32(addr);
216236
stack->ecx = ecx;

0 commit comments

Comments
 (0)