Skip to content

Commit 66b17c7

Browse files
committed
simx86: eliminate TheCPU.basemode, introduce MBIGCS mode flag.
With MBIGCS we can always UNPREFIX, even without basemode being present. Execution now purely uses TheCPU.mode, as a future PR will let JIT code modify CS in protected mode.
1 parent d922d77 commit 66b17c7

File tree

6 files changed

+33
-28
lines changed

6 files changed

+33
-28
lines changed

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,6 @@ unsigned int DoExec_fast(TNode *G)
690690
unsigned char *ecpu = CPUOFFS(0);
691691
unsigned long flg = Exec_pre(ecpu);
692692
unsigned int ePC, mem_ref;
693-
unsigned mode = G->mode;
694693

695694
do {
696695
ePC = Exec(&mem_ref, &flg, ecpu, G->addr, 0);
@@ -706,7 +705,7 @@ unsigned int DoExec_fast(TNode *G)
706705
break;
707706
}
708707
} while (!TheCPU.err2 && (G=FindTree(ePC)) &&
709-
GoodNode(G, mode) && !(G->flags & (F_FPOP|F_INHI)));
708+
GoodNode(G) && !(G->flags & (F_FPOP|F_INHI)));
710709

711710
Exec_post(flg, mem_ref);
712711
sigalrm_pending_w(0);

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@
182182
#define MPOPRM 0x00010000
183183
#define MRETISP 0x00020000
184184
#define MREALA 0x00040000
185+
#define MBIGCS 0x00080000
185186

186187
#define CKSIGN 0x00100000 // check signal: for jumps
187188
// for HOST_ARCH_X86
@@ -281,18 +282,18 @@ void EndGen(void);
281282
extern void fp87_mask_except(void);
282283
extern void fp87_save_except(void);
283284
//
284-
static __inline__ int GoodNode(TNode *G, int mode)
285+
static __inline__ int GoodNode(TNode *G)
285286
{
286287
if (G->cs != LONG_CS) {
287288
/* CS mismatch can confuse relative jump/call */
288289
e_printf("cs mismatch at %08x: old=%x new=%x\n",
289290
G->key, G->cs, LONG_CS);
290291
return 0;
291292
}
292-
if (G->mode != mode) {
293-
/* mode mismatch can be 32/16 or MREALA */
293+
if (G->mode != TheCPU.mode) {
294+
/* mode mismatch can be 32/16(MBIGCS) or MREALA */
294295
e_printf("mode mismatch at %08x: old=%x new=%x\n",
295-
G->key, G->mode, mode);
296+
G->key, G->mode, TheCPU.mode);
296297
return 0;
297298
}
298299
return 1;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -708,7 +708,7 @@ static void Scp2CpuD(cpuctx_t *scp)
708708
InvalidateSegs(); // makes sure real mode segs aren't confused with PM sels
709709
TheCPU.err = SetSegProt(mode&ADDR16,Ofs_CS,&big,_cs);
710710
if (TheCPU.err) goto erseg;
711-
if (big) mode=0; else mode |= DATA16;
711+
if (big) mode=MBIGCS; else mode |= DATA16;
712712

713713
TheCPU.err = SetSegProt(mode&ADDR16,Ofs_DS,&big,_ds);
714714
if (TheCPU.err) goto erseg;

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

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,9 @@ static pthread_t prejit_thr;
5959
static sem_t prejit_sem;
6060
static void *prejit_thread(void *arg);
6161
#if SPEC_PREJIT
62-
static void prejit_run(unsigned int PC);
62+
static void prejit_run(unsigned int PC, unsigned int basemode);
6363
#endif
64-
static unsigned int prejit_PC;
64+
static unsigned int prejit_PC, prejit_mode;
6565
#if PROFILE
6666
int SpecPrejits;
6767
#endif
@@ -176,7 +176,10 @@ static unsigned int do_flush(unsigned P0, unsigned _P0,
176176
} \
177177
}
178178

179-
#define UNPREFIX(m) ((m)&~(DATA16|ADDR16))|(basemode&(DATA16|ADDR16))
179+
static inline unsigned int UNPREFIX(unsigned int m)
180+
{
181+
return (m&~(DATA16|ADDR16))|((m&MBIGCS)?0:(DATA16|ADDR16));
182+
}
180183

181184
/////////////////////////////////////////////////////////////////////////////
182185

@@ -199,7 +202,8 @@ static int MAKESEG(int mode, int ofs, unsigned short sv)
199202
if (e)
200203
return e;
201204
if (ofs==Ofs_CS) {
202-
if (big) TheCPU.mode &= ~(ADDR16|DATA16);
205+
TheCPU.mode &= ~(ADDR16|DATA16|MBIGCS);
206+
if (big) TheCPU.mode |= MBIGCS;
203207
else TheCPU.mode |= (ADDR16|DATA16);
204208
if (debug_level('e')>1) e_printf("MAKESEG CS: big=%d basemode=%04x\n",big&1,TheCPU.mode);
205209
LONG_CS = _LONG_CS;
@@ -382,6 +386,7 @@ static unsigned int JumpGen(unsigned int P2, int mode, int opc, int pskip,
382386
#if SPEC_PREJIT
383387
int can_speculate = 1;
384388
#endif
389+
unsigned int basemode = UNPREFIX(mode);
385390
TNode *G;
386391
NewIMeta(P0, &_rc);
387392
#if SPEC_PREJIT
@@ -395,7 +400,7 @@ static unsigned int JumpGen(unsigned int P2, int mode, int opc, int pskip,
395400
break;
396401
}
397402
#endif
398-
G = DoClose(_P0, TheCPU.basemode, InstrMeta[0].npc);
403+
G = DoClose(_P0, basemode, InstrMeta[0].npc);
399404
if (!G)
400405
return P0;
401406
if (_flags & FLG_PREJIT) {
@@ -408,12 +413,12 @@ static unsigned int JumpGen(unsigned int P2, int mode, int opc, int pskip,
408413
if (debug_level('e')) {
409414
char *ds;
410415
unsigned short ocs = TheCPU.cs;
411-
ds = e_emu_disasm(EMU_BASE32(P2),(~TheCPU.basemode&3),ocs);
416+
ds = e_emu_disasm(EMU_BASE32(P2),mode&MBIGCS,ocs);
412417
e_printf("prejit after %s\n", ds);
413-
ds = e_emu_disasm(EMU_BASE32(_P0),(~TheCPU.basemode&3),ocs);
418+
ds = e_emu_disasm(EMU_BASE32(_P0),mode&MBIGCS,ocs);
414419
e_printf("prejit at %s\n", ds);
415420
}
416-
prejit_run(_P0);
421+
prejit_run(_P0, basemode);
417422
}
418423
#endif
419424
_P1 = DoExec(G);
@@ -435,7 +440,6 @@ static unsigned int JumpGen(unsigned int P2, int mode, int opc, int pskip,
435440
#if !defined(SINGLESTEP)
436441
static unsigned int FindExecCode(unsigned int PC)
437442
{
438-
int mode = TheCPU.mode;
439443
TNode *G;
440444

441445
/* for a sequence to be found, it must begin with
@@ -446,7 +450,7 @@ static unsigned int FindExecCode(unsigned int PC)
446450
*/
447451
while (!(CEmuStat & (CeS_TRAP|CeS_DRTRAP|CeS_SIGPEND)) &&
448452
(G=FindTree(PC))) {
449-
if (!GoodNode(G, mode)) {
453+
if (!GoodNode(G)) {
450454
InvalidateNodeRange(G->seqbase, G->seqlen, NULL);
451455
return PC;
452456
}
@@ -478,7 +482,7 @@ static unsigned int FindExecCode(unsigned int PC)
478482
/* try fast inner loop if nothing special is going on */
479483
if (!(EFLAGS & TF) && !(CEmuStat & (CeS_INHI)) &&
480484
!debug_level('e') &&
481-
GoodNode(G, mode) && !(G->flags & (F_FPOP|F_INHI)))
485+
GoodNode(G) && !(G->flags & (F_FPOP|F_INHI)))
482486
PC = DoExec_fast(G);
483487
else
484488
#endif
@@ -544,7 +548,6 @@ void Interp86(void)
544548
{
545549
unsigned int ret;
546550

547-
TheCPU.basemode = TheCPU.mode;
548551
TheCPU.err2 = 0;
549552
LONG_CS = _LONG_CS;
550553
ret = _Interp86(LONG_CS + TheCPU.eip, TheCPU.mode);
@@ -611,7 +614,7 @@ static unsigned int interp_pre(unsigned int PC, const int mode, int _flags)
611614
dbug_printf("\n%s",e_print_regs());
612615
char *ds;
613616
unsigned short ocs = TheCPU.cs;
614-
ds = e_emu_disasm(EMU_BASE32(PC),(~mode&3),ocs);
617+
ds = e_emu_disasm(EMU_BASE32(PC),mode&MBIGCS,ocs);
615618
e_printf(" %s\n", ds);
616619
}
617620
return PC;
@@ -687,7 +690,7 @@ static unsigned int _Interp86(unsigned int PC, int basemode)
687690
P0 = PC;
688691
PC = InterpOne(PC, basemode, 0);
689692
/* InterpOne can change CS */
690-
TheCPU.basemode = basemode = TheCPU.mode;
693+
basemode = TheCPU.mode;
691694
if (TheCPU.err) {
692695
if (TheCPU.err == EXCP_RETRY) {
693696
TheCPU.err = 0;
@@ -3495,10 +3498,12 @@ static void _PreJit86(unsigned int PC, int basemode, int flags)
34953498
if (debug_level('e')) {
34963499
char *ds;
34973500
unsigned short ocs = TheCPU.cs;
3498-
ds = e_emu_disasm(EMU_BASE32(PC),(~basemode&3),ocs);
3501+
ds = e_emu_disasm(EMU_BASE32(PC),basemode&MBIGCS,ocs);
34993502
e_printf(" %s\n", ds);
35003503
}
35013504
PC = InterpOne(PC, basemode, flags);
3505+
/* InterpOne can NOT change CS with PreJit, basemode
3506+
stays the same */
35023507
if (TheCPU.err)
35033508
return;
35043509
PC = interp_post(PC, basemode, P0, flags);
@@ -3519,7 +3524,6 @@ void PreJit86(unsigned int PC, int basemode)
35193524
{
35203525
if (e_querymark(PC, 1))
35213526
return;
3522-
TheCPU.basemode = basemode;
35233527
TheCPU.err = 0;
35243528
LONG_CS = _LONG_CS;
35253529
_PreJit86(PC, basemode, FLG_PREJIT);
@@ -3530,7 +3534,8 @@ static void *prejit_thread(void *arg)
35303534
{
35313535
while (1) {
35323536
sem_wait(&prejit_sem);
3533-
_PreJit86(__atomic_load_n(&prejit_PC, __ATOMIC_RELAXED), TheCPU.basemode,
3537+
_PreJit86(__atomic_load_n(&prejit_PC, __ATOMIC_RELAXED),
3538+
__atomic_load_n(&prejit_mode, __ATOMIC_RELAXED),
35343539
FLG_PREJIT | FLG_SPECULATIVE);
35353540
pthread_mutex_lock(&run_mtx);
35363541
prejit_running = 0;
@@ -3541,14 +3546,15 @@ static void *prejit_thread(void *arg)
35413546
}
35423547

35433548
#if SPEC_PREJIT
3544-
static void prejit_run(unsigned int PC)
3549+
static void prejit_run(unsigned int PC, unsigned int basemode)
35453550
{
35463551
if (e_querymark(PC, SAFE_PRJ_GAP))
35473552
return;
35483553
#if PROFILE
35493554
SpecPrejits++;
35503555
#endif
35513556
__atomic_store_n(&prejit_PC, PC, __ATOMIC_RELAXED);
3557+
__atomic_store_n(&prejit_mode, basemode, __ATOMIC_RELAXED);
35523558
pthread_mutex_lock(&run_mtx);
35533559
assert(!prejit_running);
35543560
prejit_running = 1;

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,12 @@ int SetSegReal(unsigned short sel, int ofs)
9797
int SetDataSegProt(unsigned short sel, int ofs)
9898
{
9999
unsigned char big;
100-
int e = SetSegProt(TheCPU.basemode&ADDR16, ofs, &big, sel);
100+
int e = SetSegProt(TheCPU.mode&ADDR16, ofs, &big, sel);
101101
if (e) {
102102
TheCPU.err2 = e;
103103
} else if (ofs==Ofs_SS) {
104104
TheCPU.StackMask = (big? 0xffffffff : 0x0000ffff);
105-
if (debug_level('e')>1) e_printf("MAKESEG SS: big=%d basemode=%04x\n",big&1,TheCPU.basemode);
105+
if (debug_level('e')>1) e_printf("MAKESEG SS: big=%d basemode=%04x\n",big&1,TheCPU.mode);
106106
}
107107
return e;
108108
}

src/base/emu-i386/simx86/syncpu.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ typedef struct {
8080
int err2;
8181
int err;
8282
unsigned int mode;
83-
unsigned int basemode;
8483
unsigned int sreg1;
8584
unsigned int dreg1;
8685
unsigned int xreg1;

0 commit comments

Comments
 (0)