Skip to content

Commit 861786e

Browse files
committed
simx86: handle RETl/RETlisp more efficiently.
Using O_POP1/O_POP2/O_POP2/O_POP3 in both rm and pm. It's ok to pop into TheCPU.eip as that gets recomputed when there is a fault anyway. Had to add RETlisp functionality to O_POP2.
1 parent c595db3 commit 861786e

File tree

4 files changed

+38
-34
lines changed

4 files changed

+38
-34
lines changed

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2067,7 +2067,8 @@ static unsigned int Gen_sim(const IGen *IG, dosaddr_t mem_ref)
20672067
wkreg AR2;
20682068
unsigned int o = (mode & MNOREG) ? 0 : IG->p0;
20692069
long stackm = CPULONG(Ofs_STACKM);
2070-
GTRACE1("O_POP2",o);
2070+
int imm16 = (mode&MRETISP) ? IG->p0 : 0;
2071+
GTRACE2("O_POP2",o,imm16);
20712072
AR2.d = CPULONG(Ofs_XSS);
20722073
#ifndef STACK_WRAP_MP /* mask before incrementing */
20732074
SR1.d &= stackm;
@@ -2076,13 +2077,13 @@ static unsigned int Gen_sim(const IGen *IG, dosaddr_t mem_ref)
20762077
DR1.w.l = sim_read_word(AR2.d + SR1.d);
20772078
if (!(mode & MNOREG))
20782079
CPUWORD(o) = DR1.w.l;
2079-
SR1.d += 2;
2080+
SR1.d += 2 + imm16;
20802081
}
20812082
else {
20822083
DR1.d = sim_read_dword(AR2.d + SR1.d);
20832084
if (!(mode & MNOREG))
20842085
CPULONG(o) = DR1.d;
2085-
SR1.d += 4;
2086+
SR1.d += 4 + imm16;
20862087
}
20872088
#ifdef STACK_WRAP_MP /* mask after incrementing */
20882089
SR1.d &= stackm;

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1501,7 +1501,7 @@ arith0: {
15011501
0x8d,0x14,0x0e,
15021502
// movw (%%edx,%%ebp,1),%%ax
15031503
0x66,0x8b,0x04,0x2a,
1504-
/*0a*/ // leal 2(%%esi),%%esi
1504+
// leal 2(%%esi),%%esi
15051505
0x8d,0x76,0x02,
15061506
#ifdef STACK_WRAP_MP /* mask after incrementing */
15071507
// andl StackMask(%%ebx),%%esi
@@ -1517,7 +1517,7 @@ arith0: {
15171517
0x8d,0x14,0x0e,
15181518
// movl (%%edx,%%ebp,1),%%eax
15191519
0x90,0x8b,0x04,0x2a,
1520-
/*0a*/ // leal 4(%%esi),%%esi
1520+
// leal 4(%%esi),%%esi
15211521
0x8d,0x76,0x04,
15221522
#ifdef STACK_WRAP_MP /* mask after incrementing */
15231523
// andl StackMask(%%ebx),%%esi
@@ -1532,6 +1532,14 @@ arith0: {
15321532
// first do address calculation, then pop,
15331533
// then store data, and last adjust stack
15341534
GNX(Cp, p, sz);
1535+
if (mode & MRETISP) {
1536+
// leal IG->p0(%%esi),%%esi
1537+
G2M(0x8d,0xb6,Cp); G4(IG->p0,Cp);
1538+
#ifdef STACK_WRAP_MP /* mask after incrementing */
1539+
// andl StackMask(%%ebx),%%esi
1540+
G3M(0x23,0x73,Ofs_STACKM,Cp);
1541+
#endif
1542+
}
15351543
if (!(mode & MNOREG)) {
15361544
// mov{wl} %%{e}ax,offs(%%ebx)
15371545
Gen66(mode, Cp); G3M(0x89,0x43,IG->p0,Cp);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ void Gen(int op, int mode, ...)
269269
break;
270270

271271
case O_POP2:
272-
if (!(mode & MNOREG))
272+
if (!(mode & MNOREG) || (mode && MRETISP))
273273
IG->p0 = va_arg(ap,unsigned int);
274274
break;
275275

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

Lines changed: 23 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -388,8 +388,6 @@ static unsigned int _JumpGen(unsigned int P2, int mode, int opc,
388388
Gen(JLOOP_LINK, mode, opc, j_t, j_nt);
389389
break;
390390
case RETl: case RETlisp: // far ret, indirect
391-
if (REALADDR()) AddrGen(A_SR_SH4, mode, Ofs_CS, Ofs_XCS);
392-
/* fall through */
393391
case JMPli: case CALLli: case INT: // far jmp/call, indirect
394392
Gen(L_REG, mode, Ofs_EIP);
395393
/* fall through */
@@ -1860,23 +1858,21 @@ intop3b: { int op = ArOpsFR[D_MO(opc)];
18601858
/*c9*/ case LEAVE:
18611859
Gen(O_LEAVE, _mode); PC++;
18621860
break;
1863-
/*ca*/ case RETlisp: /* restartable */
1864-
if (!REALADDR()) {
1865-
/* pop from stack without adjusting esp */
1866-
Gen(O_POP1, _mode);
1867-
Gen(O_POP2, _mode|MNOREG);
1868-
Gen(O_POP2, _mode|MNOREG);
1861+
/*ca*/ case RETlisp: { /* restartable */
1862+
/* pop from stack without adjusting esp before A_SR_* */
1863+
int dr = (signed short)FetchW(PC+1);
1864+
Gen(O_POP1, _mode);
1865+
Gen(O_POP2, _mode, Ofs_EIP);
1866+
Gen(O_POP2, _mode|MNOREG|MRETISP, dr);
1867+
if (REALADDR())
1868+
AddrGen(A_SR_SH4, _mode, Ofs_CS, Ofs_XCS);
1869+
else
18691870
AddrGen(A_SR_PROT, _mode, Ofs_CS, P0);
1870-
}
1871-
{
1872-
int dr = (signed short)FetchW(PC+1);
1873-
Gen(O_POP, _mode);
1874-
Gen(S_REG, _mode, Ofs_EIP);
1875-
Gen(O_POP, _mode|MRETISP, dr);
1876-
PC = JumpGen(PC, _mode, opc, 3, P0, _flags);
1877-
if (debug_level('e')>2)
1878-
e_printf("RET_%d: ret=%08x\n",dr,TheCPU.eip);
1879-
if (TheCPU.err) return PC;
1871+
Gen(O_POP3, _mode);
1872+
PC = JumpGen(PC, _mode, opc, 3, P0, _flags);
1873+
if (debug_level('e')>2)
1874+
e_printf("RET_%d: ret=%08x\n",dr,TheCPU.eip);
1875+
if (TheCPU.err) return PC;
18801876
}
18811877
break;
18821878
/*cc*/ case INT3:
@@ -1963,16 +1959,15 @@ intop3b: { int op = ArOpsFR[D_MO(opc)];
19631959
}
19641960

19651961
/*cb*/ case RETl:
1966-
if (!REALADDR()) {
1967-
/* pop from stack without adjusting esp */
1968-
Gen(O_POP1, _mode);
1969-
Gen(O_POP2, _mode|MNOREG);
1970-
Gen(O_POP2, _mode|MNOREG);
1971-
AddrGen(A_SR_PROT, _mode, Ofs_CS, P0);
1972-
}
1973-
Gen(O_POP, _mode);
1974-
Gen(S_REG, _mode, Ofs_EIP);
1975-
Gen(O_POP, _mode);
1962+
/* pop from stack without adjusting esp before A_SR_* */
1963+
Gen(O_POP1, _mode);
1964+
Gen(O_POP2, _mode, Ofs_EIP);
1965+
Gen(O_POP2, _mode|MNOREG);
1966+
if (REALADDR())
1967+
AddrGen(A_SR_SH4, _mode, Ofs_CS, Ofs_XCS);
1968+
else
1969+
AddrGen(A_SR_PROT, _mode, Ofs_CS, P0);
1970+
Gen(O_POP3, _mode);
19761971
PC = JumpGen(PC, _mode, opc, 1, P0, _flags);
19771972
if (debug_level('e')>1)
19781973
e_printf("RET_FAR: ret=%04x:%08x\n",TheCPU.cs,TheCPU.eip);

0 commit comments

Comments
 (0)