@@ -59,9 +59,9 @@ static pthread_t prejit_thr;
5959static sem_t prejit_sem ;
6060static 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
6666int 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 )
436441static 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 ;
0 commit comments