ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/uae_cpu/compiler/compemu_support.cpp
(Generate patch)

Comparing BasiliskII/src/uae_cpu/compiler/compemu_support.cpp (file contents):
Revision 1.4 by gbeauche, 2002-09-18T11:41:56Z vs.
Revision 1.10 by gbeauche, 2002-10-03T15:05:01Z

# Line 44 | Line 44
44   #endif
45  
46   #ifndef WIN32
47 < #define PROFILE_COMPILE_TIME    1
47 > #define PROFILE_COMPILE_TIME            1
48 > #define PROFILE_UNTRANSLATED_INSNS      1
49   #endif
50  
51   #ifdef WIN32
# Line 69 | Line 70 | static clock_t emul_start_time = 0;
70   static clock_t emul_end_time    = 0;
71   #endif
72  
73 + #if PROFILE_UNTRANSLATED_INSNS
74 + const int untranslated_top_ten = 20;
75 + static uae_u32 raw_cputbl_count[65536] = { 0, };
76 + static uae_u16 opcode_nums[65536];
77 +
78 + static int untranslated_compfn(const void *e1, const void *e2)
79 + {
80 +        return raw_cputbl_count[*(const uae_u16 *)e1] < raw_cputbl_count[*(const uae_u16 *)e2];
81 + }
82 + #endif
83 +
84   compop_func *compfunctbl[65536];
85   compop_func *nfcompfunctbl[65536];
86   cpuop_func *nfcpufunctbl[65536];
87   uae_u8* comp_pc_p;
88  
89 + // From newcpu.cpp
90 + extern bool quit_program;
91 +
92   // gb-- Extra data for Basilisk II/JIT
93   #if JIT_DEBUG
94   static bool             JITDebug                        = false;        // Enable runtime disassemblers through mon?
# Line 88 | Line 103 | static bool            lazy_flush                      = true;         // Fl
103   static bool             avoid_fpu                       = true;         // Flag: compile FPU instructions ?
104   static bool             have_cmov                       = false;        // target has CMOV instructions ?
105   static bool             have_rat_stall          = true;         // target has partial register stalls ?
106 + static bool             tune_alignment          = true;         // Tune code alignments for running CPU ?
107 + static int              align_loops                     = 32;           // Align the start of loops
108 + static int              align_jumps                     = 32;           // Align the start of jumps
109   static int              zero_fd                         = -1;
110   static int              optcount[10]            = {
111          10,             // How often a block has to be executed before it is translated
# Line 104 | Line 122 | struct op_properties {
122   };
123   static op_properties prop[65536];
124  
107 // gb-- Control Flow Predicates
108
125   static inline int end_block(uae_u32 opcode)
126   {
127          return (prop[opcode].cflow & fl_end_block);
128   }
129  
130 < static inline bool may_trap(uae_u32 opcode)
130 > static inline bool is_const_jump(uae_u32 opcode)
131   {
132 <        return (prop[opcode].cflow & fl_trap);
132 >        return (prop[opcode].cflow == fl_const_jump);
133   }
134  
135   uae_u8* start_pc_p;
# Line 491 | Line 507 | static void prepare_block(blockinfo* bi)
507     compiled. If the list of free blockinfos is empty, we allocate a new
508     pool of blockinfos and link the newly created blockinfos altogether
509     into the list of free blockinfos. Otherwise, we simply pop a structure
510 <   of the free list.
510 >   off the free list.
511  
512     Blockinfo are lazily deallocated, i.e. chained altogether in the
513     list of free blockinfos whenvever a translation cache flush (hard or
514     soft) request occurs.
515   */
516  
517 < #if USE_SEPARATE_BIA
518 < const int BLOCKINFO_POOL_SIZE = 128;
519 < struct blockinfo_pool {
520 <        blockinfo bi[BLOCKINFO_POOL_SIZE];
521 <        blockinfo_pool *next;
517 > template< class T >
518 > class LazyBlockAllocator
519 > {
520 >        enum {
521 >                kPoolSize = 1 + 4096 / sizeof(T)
522 >        };
523 >        struct Pool {
524 >                T chunk[kPoolSize];
525 >                Pool * next;
526 >        };
527 >        Pool * mPools;
528 >        T * mChunks;
529 > public:
530 >        LazyBlockAllocator() : mPools(0), mChunks(0) { }
531 >        ~LazyBlockAllocator();
532 >        T * acquire();
533 >        void release(T * const);
534   };
507 static blockinfo_pool * blockinfo_pools = 0;
508 static blockinfo *              free_blockinfos = 0;
509 #endif
535  
536 < static __inline__ blockinfo *alloc_blockinfo(void)
536 > template< class T >
537 > LazyBlockAllocator<T>::~LazyBlockAllocator()
538   {
539 < #if USE_SEPARATE_BIA
540 <        if (!free_blockinfos) {
541 <                // There is no blockinfo struct left, allocate a new
542 <                // pool and link the chunks into the free list
543 <                blockinfo_pool *bi_pool = (blockinfo_pool *)malloc(sizeof(blockinfo_pool));
544 <                for (blockinfo *bi = &bi_pool->bi[0]; bi < &bi_pool->bi[BLOCKINFO_POOL_SIZE]; bi++) {
545 <                        bi->next = free_blockinfos;
546 <                        free_blockinfos = bi;
539 >        Pool * currentPool = mPools;
540 >        while (currentPool) {
541 >                Pool * deadPool = currentPool;
542 >                currentPool = currentPool->next;
543 >                free(deadPool);
544 >        }
545 > }
546 >
547 > template< class T >
548 > T * LazyBlockAllocator<T>::acquire()
549 > {
550 >        if (!mChunks) {
551 >                // There is no chunk left, allocate a new pool and link the
552 >                // chunks into the free list
553 >                Pool * newPool = (Pool *)malloc(sizeof(Pool));
554 >                for (T * chunk = &newPool->chunk[0]; chunk < &newPool->chunk[kPoolSize]; chunk++) {
555 >                        chunk->next = mChunks;
556 >                        mChunks = chunk;
557                  }
558 <                bi_pool->next = blockinfo_pools;
559 <                blockinfo_pools = bi_pool;
558 >                newPool->next = mPools;
559 >                mPools = newPool;
560          }
561 <        blockinfo *bi = free_blockinfos;
562 <        free_blockinfos = bi->next;
563 < #else
528 <        blockinfo *bi = (blockinfo*)current_compile_p;
529 <        current_compile_p += sizeof(blockinfo);
530 < #endif
531 <        return bi;
561 >        T * chunk = mChunks;
562 >        mChunks = chunk->next;
563 >        return chunk;
564   }
565  
566 < static __inline__ void free_blockinfo(blockinfo *bi)
566 > template< class T >
567 > void LazyBlockAllocator<T>::release(T * const chunk)
568 > {
569 >        chunk->next = mChunks;
570 >        mChunks = chunk;
571 > }
572 >
573 > template< class T >
574 > class HardBlockAllocator
575   {
576 + public:
577 +        T * acquire() {
578 +                T * data = (T *)current_compile_p;
579 +                current_compile_p += sizeof(T);
580 +                return data;
581 +        }
582 +
583 +        void release(T * const chunk) {
584 +                // Deallocated on invalidation
585 +        }
586 + };
587 +
588   #if USE_SEPARATE_BIA
589 <        bi->next = free_blockinfos;
590 <        free_blockinfos = bi;
589 > static LazyBlockAllocator<blockinfo> BlockInfoAllocator;
590 > static LazyBlockAllocator<checksum_info> ChecksumInfoAllocator;
591 > #else
592 > static HardBlockAllocator<blockinfo> BlockInfoAllocator;
593 > static HardBlockAllocator<checksum_info> ChecksumInfoAllocator;
594   #endif
595 +
596 + static __inline__ checksum_info *alloc_checksum_info(void)
597 + {
598 +        checksum_info *csi = ChecksumInfoAllocator.acquire();
599 +        csi->next = NULL;
600 +        return csi;
601   }
602  
603 < static void free_blockinfo_pools(void)
603 > static __inline__ void free_checksum_info(checksum_info *csi)
604   {
605 < #if USE_SEPARATE_BIA
606 <        int blockinfo_pool_count = 0;
607 <        blockinfo_pool *curr_pool = blockinfo_pools;
608 <        while (curr_pool) {
609 <                blockinfo_pool_count++;
610 <                blockinfo_pool *dead_pool = curr_pool;
611 <                curr_pool = curr_pool->next;
612 <                free(dead_pool);
605 >        csi->next = NULL;
606 >        ChecksumInfoAllocator.release(csi);
607 > }
608 >
609 > static __inline__ void free_checksum_info_chain(checksum_info *csi)
610 > {
611 >        while (csi != NULL) {
612 >                checksum_info *csi2 = csi->next;
613 >                free_checksum_info(csi);
614 >                csi = csi2;
615          }
616 <        
617 <        uae_u32 blockinfo_pools_size = blockinfo_pool_count * BLOCKINFO_POOL_SIZE * sizeof(blockinfo);
618 <        write_log("### Blockinfo allocation statistics\n");
619 <        write_log("Number of blockinfo pools  : %d\n", blockinfo_pool_count);
620 <        write_log("Total number of blockinfos : %d (%d KB)\n",
621 <                          blockinfo_pool_count * BLOCKINFO_POOL_SIZE,
622 <                          blockinfo_pools_size / 1024);
560 <        write_log("\n");
616 > }
617 >
618 > static __inline__ blockinfo *alloc_blockinfo(void)
619 > {
620 >        blockinfo *bi = BlockInfoAllocator.acquire();
621 > #if USE_CHECKSUM_INFO
622 >        bi->csi = NULL;
623   #endif
624 +        return bi;
625 + }
626 +
627 + static __inline__ void free_blockinfo(blockinfo *bi)
628 + {
629 + #if USE_CHECKSUM_INFO
630 +        free_checksum_info_chain(bi->csi);
631 +        bi->csi = NULL;
632 + #endif
633 +        BlockInfoAllocator.release(bi);
634   }
635  
636   static __inline__ void alloc_blockinfos(void)
# Line 4562 | Line 4634 | void compiler_init(void)
4634          raw_init_cpu();
4635          write_log("<JIT compiler> : target processor has CMOV instructions : %s\n", have_cmov ? "yes" : "no");
4636          write_log("<JIT compiler> : target processor can suffer from partial register stalls : %s\n", have_rat_stall ? "yes" : "no");
4637 +        write_log("<JIT compiler> : alignment for loops, jumps are %d, %d\n", align_loops, align_jumps);
4638          
4639          // Translation cache flush mechanism
4640          lazy_flush = PrefsFindBool("jitlazyflush");
# Line 4572 | Line 4645 | void compiler_init(void)
4645          write_log("<JIT compiler> : register aliasing : %s\n", str_on_off(1));
4646          write_log("<JIT compiler> : FP register aliasing : %s\n", str_on_off(USE_F_ALIAS));
4647          write_log("<JIT compiler> : lazy constant offsetting : %s\n", str_on_off(USE_OFFSET));
4648 +        write_log("<JIT compiler> : block inlining : %s\n", str_on_off(USE_INLINING));
4649          write_log("<JIT compiler> : separate blockinfo allocation : %s\n", str_on_off(USE_SEPARATE_BIA));
4650          
4651          // Build compiler tables
# Line 4579 | Line 4653 | void compiler_init(void)
4653          
4654          initialized = true;
4655          
4656 + #if PROFILE_UNTRANSLATED_INSNS
4657 +        write_log("<JIT compiler> : gather statistics on untranslated insns count\n");
4658 + #endif
4659 +
4660   #if PROFILE_COMPILE_TIME
4661          write_log("<JIT compiler> : gather statistics on translation time\n");
4662          emul_start_time = clock();
# Line 4597 | Line 4675 | void compiler_exit(void)
4675                  compiled_code = 0;
4676          }
4677          
4600        // Deallocate blockinfo pools
4601        free_blockinfo_pools();
4602        
4678   #ifndef WIN32
4679          // Close /dev/zero
4680          if (zero_fd > 0)
# Line 4615 | Line 4690 | void compiler_exit(void)
4690                  100.0*double(compile_time)/double(emul_time));
4691          write_log("\n");
4692   #endif
4693 +
4694 + #if PROFILE_UNTRANSLATED_INSNS
4695 +        uae_u64 untranslated_count = 0;
4696 +        for (int i = 0; i < 65536; i++) {
4697 +                opcode_nums[i] = i;
4698 +                untranslated_count += raw_cputbl_count[i];
4699 +        }
4700 +        write_log("Sorting out untranslated instructions count...\n");
4701 +        qsort(opcode_nums, 65536, sizeof(uae_u16), untranslated_compfn);
4702 +        write_log("\nRank  Opc      Count Name\n");
4703 +        for (int i = 0; i < untranslated_top_ten; i++) {
4704 +                uae_u32 count = raw_cputbl_count[opcode_nums[i]];
4705 +                struct instr *dp;
4706 +                struct mnemolookup *lookup;
4707 +                if (!count)
4708 +                        break;
4709 +                dp = table68k + opcode_nums[i];
4710 +                for (lookup = lookuptab; lookup->mnemo != dp->mnemo; lookup++)
4711 +                        ;
4712 +                write_log("%03d: %04x %10lu %s\n", i, opcode_nums[i], count, lookup->name);
4713 +        }
4714 + #endif
4715   }
4716  
4717   bool compiler_use_jit(void)
# Line 5174 | Line 5271 | extern cpuop_rettype op_illg_1 (uae_u32
5271  
5272   static void calc_checksum(blockinfo* bi, uae_u32* c1, uae_u32* c2)
5273   {
5274 <    uae_u32 k1=0;
5275 <    uae_u32 k2=0;
5179 <    uae_s32 len=bi->len;
5180 <    uae_u32 tmp=bi->min_pcp;
5181 <    uae_u32* pos;
5274 >    uae_u32 k1 = 0;
5275 >    uae_u32 k2 = 0;
5276  
5277 <    len+=(tmp&3);
5278 <    tmp&=(~3);
5279 <    pos=(uae_u32*)tmp;
5277 > #if USE_CHECKSUM_INFO
5278 >    checksum_info *csi = bi->csi;
5279 >        Dif(!csi) abort();
5280 >        while (csi) {
5281 >                uae_s32 len = csi->length;
5282 >                uae_u32 tmp = (uae_u32)csi->start_p;
5283 > #else
5284 >                uae_s32 len = bi->len;
5285 >                uae_u32 tmp = (uae_u32)bi->min_pcp;
5286 > #endif
5287 >                uae_u32*pos;
5288  
5289 <    if (len<0 || len>MAX_CHECKSUM_LEN) {
5290 <        *c1=0;
5291 <        *c2=0;
5292 <    }
5293 <    else {
5294 <        while (len>0) {
5295 <            k1+=*pos;
5296 <            k2^=*pos;
5297 <            pos++;
5298 <            len-=4;
5289 >                len += (tmp & 3);
5290 >                tmp &= ~3;
5291 >                pos = (uae_u32 *)tmp;
5292 >
5293 >                if (len >= 0 && len <= MAX_CHECKSUM_LEN) {
5294 >                        while (len > 0) {
5295 >                                k1 += *pos;
5296 >                                k2 ^= *pos;
5297 >                                pos++;
5298 >                                len -= 4;
5299 >                        }
5300 >                }
5301 >
5302 > #if USE_CHECKSUM_INFO
5303 >                csi = csi->next;
5304          }
5305 <        *c1=k1;
5306 <        *c2=k2;
5307 <    }
5305 > #endif
5306 >
5307 >        *c1 = k1;
5308 >        *c2 = k2;
5309   }
5310  
5311 < static void show_checksum(blockinfo* bi)
5311 > #if 0
5312 > static void show_checksum(CSI_TYPE* csi)
5313   {
5314      uae_u32 k1=0;
5315      uae_u32 k2=0;
5316 <    uae_s32 len=bi->len;
5317 <    uae_u32 tmp=(uae_u32)bi->pc_p;
5316 >    uae_s32 len=CSI_LENGTH(csi);
5317 >    uae_u32 tmp=(uae_u32)CSI_START_P(csi);
5318      uae_u32* pos;
5319  
5320      len+=(tmp&3);
# Line 5224 | Line 5333 | static void show_checksum(blockinfo* bi)
5333          write_log(" bla\n");
5334      }
5335   }
5336 + #endif
5337  
5338  
5339   int check_for_cache_miss(void)
# Line 5277 | Line 5387 | static int called_check_checksum(blockin
5387   static inline int block_check_checksum(blockinfo* bi)
5388   {
5389      uae_u32     c1,c2;
5390 <    int         isgood;
5390 >    bool        isgood;
5391      
5392      if (bi->status!=BI_NEED_CHECK)
5393          return 1;  /* This block is in a checked state */
5394      
5395      checksum_count++;
5396 +
5397      if (bi->c1 || bi->c2)
5398          calc_checksum(bi,&c1,&c2);
5399      else {
5400          c1=c2=1;  /* Make sure it doesn't match */
5401 <    }
5401 >        }
5402      
5403      isgood=(c1==bi->c1 && c2==bi->c2);
5404 +
5405      if (isgood) {
5406          /* This block is still OK. So we reactivate. Of course, that
5407             means we have to move it into the needs-to-be-flushed list */
# Line 5407 | Line 5519 | static __inline__ void create_popalls(vo
5519       registers before jumping back to the various get-out routines.
5520       This generates the code for it.
5521    */
5522 <  popall_do_nothing=current_compile_p;
5522 >  align_target(align_jumps);
5523 >  popall_do_nothing=get_target();
5524    for (i=0;i<N_REGS;i++) {
5525        if (need_to_preserve[i])
5526            raw_pop_l_r(i);
5527    }
5528    raw_jmp((uae_u32)do_nothing);
5416  align_target(32);
5529    
5530 +  align_target(align_jumps);
5531    popall_execute_normal=get_target();
5532    for (i=0;i<N_REGS;i++) {
5533        if (need_to_preserve[i])
5534            raw_pop_l_r(i);
5535    }
5536    raw_jmp((uae_u32)execute_normal);
5424  align_target(32);
5537  
5538 +  align_target(align_jumps);
5539    popall_cache_miss=get_target();
5540    for (i=0;i<N_REGS;i++) {
5541        if (need_to_preserve[i])
5542            raw_pop_l_r(i);
5543    }
5544    raw_jmp((uae_u32)cache_miss);
5432  align_target(32);
5545  
5546 +  align_target(align_jumps);
5547    popall_recompile_block=get_target();
5548    for (i=0;i<N_REGS;i++) {
5549        if (need_to_preserve[i])
5550            raw_pop_l_r(i);
5551    }
5552    raw_jmp((uae_u32)recompile_block);
5553 <  align_target(32);
5554 <  
5553 >
5554 >  align_target(align_jumps);
5555    popall_exec_nostats=get_target();
5556    for (i=0;i<N_REGS;i++) {
5557        if (need_to_preserve[i])
5558            raw_pop_l_r(i);
5559    }
5560    raw_jmp((uae_u32)exec_nostats);
5561 <  align_target(32);
5562 <  
5561 >
5562 >  align_target(align_jumps);
5563    popall_check_checksum=get_target();
5564    for (i=0;i<N_REGS;i++) {
5565        if (need_to_preserve[i])
5566            raw_pop_l_r(i);
5567    }
5568    raw_jmp((uae_u32)check_checksum);
5569 <  align_target(32);
5570 <  
5569 >
5570 >  align_target(align_jumps);
5571    current_compile_p=get_target();
5572   #else
5573    popall_exec_nostats=(void *)exec_nostats;
# Line 5463 | Line 5576 | static __inline__ void create_popalls(vo
5576    popall_recompile_block=(void *)recompile_block;
5577    popall_do_nothing=(void *)do_nothing;
5578    popall_check_checksum=(void *)check_checksum;
5466  pushall_call_handler=get_target();  
5579   #endif
5580  
5581    /* And now, the code to do the matching pushes and then jump
# Line 5479 | Line 5591 | static __inline__ void create_popalls(vo
5591    raw_mov_l_rm(r,(uae_u32)&regs.pc_p);
5592    raw_and_l_ri(r,TAGMASK);
5593    raw_jmp_m_indexed((uae_u32)cache_tags,r,4);
5594 +
5595 + #ifdef X86_ASSEMBLY
5596 +  align_target(align_jumps);
5597 +  m68k_compile_execute = (void (*)(void))get_target();
5598 +  for (i=N_REGS;i--;) {
5599 +          if (need_to_preserve[i])
5600 +                  raw_push_l_r(i);
5601 +  }
5602 +  align_target(align_loops);
5603 +  uae_u32 dispatch_loop = (uae_u32)get_target();
5604 +  r=REG_PC_TMP;
5605 +  raw_mov_l_rm(r,(uae_u32)&regs.pc_p);
5606 +  raw_and_l_ri(r,TAGMASK);
5607 +  raw_call_m_indexed((uae_u32)cache_tags,r,4);
5608 +  raw_cmp_l_mi((uae_u32)&regs.spcflags,0);
5609 +  raw_jcc_b_oponly(NATIVE_CC_EQ);
5610 +  emit_byte(dispatch_loop-((uae_u32)get_target()+1));
5611 +  raw_call((uae_u32)m68k_do_specialties);
5612 +  raw_test_l_rr(REG_RESULT,REG_RESULT);
5613 +  raw_jcc_b_oponly(NATIVE_CC_EQ);
5614 +  emit_byte(dispatch_loop-((uae_u32)get_target()+1));
5615 +  raw_cmp_b_mi((uae_u32)&quit_program,0);
5616 +  raw_jcc_b_oponly(NATIVE_CC_EQ);
5617 +  emit_byte(dispatch_loop-((uae_u32)get_target()+1));
5618 +  for (i=0;i<N_REGS;i++) {
5619 +          if (need_to_preserve[i])
5620 +                  raw_pop_l_r(i);
5621 +  }
5622 +  raw_ret();
5623 + #endif
5624   }
5625  
5626   static __inline__ void reset_lists(void)
# Line 5496 | Line 5638 | static void prepare_block(blockinfo* bi)
5638      int i;
5639  
5640      set_target(current_compile_p);
5641 <    align_target(32);
5641 >    align_target(align_jumps);
5642      bi->direct_pen=(cpuop_func *)get_target();
5643      raw_mov_l_rm(0,(uae_u32)&(bi->pc_p));
5644      raw_mov_l_mr((uae_u32)&regs.pc_p,0);
5645      raw_jmp((uae_u32)popall_execute_normal);
5646  
5647 <    align_target(32);
5647 >    align_target(align_jumps);
5648      bi->direct_pcc=(cpuop_func *)get_target();
5649      raw_mov_l_rm(0,(uae_u32)&(bi->pc_p));
5650      raw_mov_l_mr((uae_u32)&regs.pc_p,0);
5651      raw_jmp((uae_u32)popall_check_checksum);
5510
5511    align_target(32);
5652      current_compile_p=get_target();
5653  
5654      bi->deplist=NULL;
# Line 5561 | Line 5701 | void build_comp(void)
5701          
5702          for (i = 0; tbl[i].opcode < 65536; i++) {
5703                  int cflow = table68k[tbl[i].opcode].cflow;
5704 +                if (USE_INLINING && ((cflow & fl_const_jump) != 0))
5705 +                        cflow = fl_const_jump;
5706 +                else
5707 +                        cflow &= ~fl_const_jump;
5708                  prop[cft_map(tbl[i].opcode)].cflow = cflow;
5709  
5710                  int uses_fpu = tbl[i].specific & 32;
# Line 5854 | Line 5998 | static void compile_block(cpu_history* p
5998          int r;
5999          int was_comp=0;
6000          uae_u8 liveflags[MAXRUN+1];
6001 + #if USE_CHECKSUM_INFO
6002 +        bool trace_in_rom = isinrom((uintptr)pc_hist[0].location);
6003 +        uae_u32 max_pcp=(uae_u32)pc_hist[blocklen - 1].location;
6004 +        uae_u32 min_pcp=max_pcp;
6005 + #else
6006          uae_u32 max_pcp=(uae_u32)pc_hist[0].location;
6007          uae_u32 min_pcp=max_pcp;
6008 + #endif
6009          uae_u32 cl=cacheline(pc_hist[0].location);
6010          void* specflags=(void*)&regs.spcflags;
6011          blockinfo* bi=NULL;
# Line 5899 | Line 6049 | static void compile_block(cpu_history* p
6049          remove_deps(bi); /* We are about to create new code */
6050          bi->optlevel=optlev;
6051          bi->pc_p=(uae_u8*)pc_hist[0].location;
6052 + #if USE_CHECKSUM_INFO
6053 +        free_checksum_info_chain(bi->csi);
6054 +        bi->csi = NULL;
6055 + #endif
6056          
6057          liveflags[blocklen]=0x1f; /* All flags needed afterwards */
6058          i=blocklen;
# Line 5906 | Line 6060 | static void compile_block(cpu_history* p
6060              uae_u16* currpcp=pc_hist[i].location;
6061              uae_u32 op=DO_GET_OPCODE(currpcp);
6062  
6063 + #if USE_CHECKSUM_INFO
6064 +                trace_in_rom = trace_in_rom && isinrom((uintptr)currpcp);
6065 + #if USE_INLINING
6066 +                if (is_const_jump(op)) {
6067 +                        checksum_info *csi = alloc_checksum_info();
6068 +                        csi->start_p = (uae_u8 *)min_pcp;
6069 +                        csi->length = max_pcp - min_pcp + LONGEST_68K_INST;
6070 +                        csi->next = bi->csi;
6071 +                        bi->csi = csi;
6072 +                        max_pcp = (uae_u32)currpcp;
6073 +                }
6074 + #endif
6075 +                min_pcp = (uae_u32)currpcp;
6076 + #else
6077              if ((uae_u32)currpcp<min_pcp)
6078                  min_pcp=(uae_u32)currpcp;
6079              if ((uae_u32)currpcp>max_pcp)
6080                  max_pcp=(uae_u32)currpcp;
6081 + #endif
6082  
6083                  liveflags[i]=((liveflags[i+1]&
6084                                 (~prop[op].set_flags))|
# Line 5918 | Line 6087 | static void compile_block(cpu_history* p
6087                      liveflags[i]&= ~FLAG_Z;
6088          }
6089  
6090 + #if USE_CHECKSUM_INFO
6091 +        checksum_info *csi = alloc_checksum_info();
6092 +        csi->start_p = (uae_u8 *)min_pcp;
6093 +        csi->length = max_pcp - min_pcp + LONGEST_68K_INST;
6094 +        csi->next = bi->csi;
6095 +        bi->csi = csi;
6096 + #endif
6097 +
6098          bi->needed_flags=liveflags[0];
6099  
6100 <        align_target(32);
6100 >        align_target(align_loops);
6101          was_comp=0;
6102  
6103          bi->direct_handler=(cpuop_func *)get_target();
# Line 6007 | Line 6184 | static void compile_block(cpu_history* p
6184                      raw_mov_l_mi((uae_u32)&regs.pc_p,
6185                                   (uae_u32)pc_hist[i].location);
6186                      raw_call((uae_u32)cputbl[opcode]);
6187 + #if PROFILE_UNTRANSLATED_INSNS
6188 +                        // raw_cputbl_count[] is indexed with plain opcode (in m68k order)
6189 +                        raw_add_l_mi((uae_u32)&raw_cputbl_count[cft_map(opcode)],1);
6190 + #endif
6191                      //raw_add_l_mi((uae_u32)&oink,1); // FIXME
6192   #if USE_NORMAL_CALLING_CONVENTION
6193                      raw_inc_sp(4);
# Line 6095 | Line 6276 | static void compile_block(cpu_history* p
6276                  raw_jmp((uae_u32)popall_do_nothing);
6277                  create_jmpdep(bi,0,tba,t1);
6278  
6279 <                align_target(16);
6279 >                align_target(align_jumps);
6280                  /* not-predicted outcome */
6281                  *branchadd=(uae_u32)get_target()-((uae_u32)branchadd+4);
6282                  live=tmp; /* Ouch again */
# Line 6164 | Line 6345 | static void compile_block(cpu_history* p
6345          big_to_small_state(&live,&(bi->env));
6346   #endif
6347  
6348 + #if USE_CHECKSUM_INFO
6349 +        remove_from_list(bi);
6350 +        if (trace_in_rom) {
6351 +                // No need to checksum that block trace on cache invalidation
6352 +                free_checksum_info_chain(bi->csi);
6353 +                bi->csi = NULL;
6354 +                add_to_dormant(bi);
6355 +        }
6356 +        else {
6357 +            calc_checksum(bi,&(bi->c1),&(bi->c2));
6358 +                add_to_active(bi);
6359 +        }
6360 + #else
6361          if (next_pc_p+extra_len>=max_pcp &&
6362              next_pc_p+extra_len<max_pcp+LONGEST_68K_INST)
6363              max_pcp=next_pc_p+extra_len;  /* extra_len covers flags magic */
6364          else
6365              max_pcp+=LONGEST_68K_INST;
6366 +
6367          bi->len=max_pcp-min_pcp;
6368          bi->min_pcp=min_pcp;
6369 <                    
6369 >        
6370          remove_from_list(bi);
6371          if (isinrom(min_pcp) && isinrom(max_pcp)) {
6372              add_to_dormant(bi); /* No need to checksum it on cache flush.
# Line 6182 | Line 6377 | static void compile_block(cpu_history* p
6377              calc_checksum(bi,&(bi->c1),&(bi->c2));
6378              add_to_active(bi);
6379          }
6380 + #endif
6381          
6382          current_cache_size += get_target() - (uae_u8 *)current_compile_p;
6383          
# Line 6201 | Line 6397 | static void compile_block(cpu_history* p
6397   #endif
6398          
6399          log_dump();
6400 <        align_target(32);
6400 >        align_target(align_jumps);
6401  
6402          /* This is the non-direct handler */
6403          bi->handler=
# Line 6217 | Line 6413 | static void compile_block(cpu_history* p
6413  
6414          raw_jmp((uae_u32)bi->direct_handler);
6415  
6220        align_target(32);
6416          current_compile_p=get_target();
6222
6417          raise_in_cl_list(bi);
6418          
6419          /* We will flush soon, anyway, so let's do it now */
# Line 6245 | Line 6439 | void exec_nostats(void)
6439   {
6440          for (;;)  {
6441                  uae_u32 opcode = GET_OPCODE;
6248 #ifdef X86_ASSEMBLY__disable
6249                __asm__ __volatile__("\tpushl %%ebp\n\tcall *%%ebx\n\tpopl %%ebp" /* FIXME */
6250                                                         : : "b" (cpufunctbl[opcode]), "a" (opcode)
6251                                                         : "%edx", "%ecx", "%esi", "%edi",  "%ebp", "memory", "cc");
6252 #else
6442                  (*cpufunctbl[opcode])(opcode);
6254 #endif
6443                  if (end_block(opcode) || SPCFLAGS_TEST(SPCFLAG_ALL)) {
6444                          return; /* We will deal with the spcflags in the caller */
6445                  }
# Line 6276 | Line 6464 | void execute_normal(void)
6464   #if FLIGHT_RECORDER
6465                          m68k_record_step(m68k_getpc());
6466   #endif
6279 #ifdef X86_ASSEMBLY__disable
6280                        __asm__ __volatile__("\tpushl %%ebp\n\tcall *%%ebx\n\tpopl %%ebp" /* FIXME */
6281                                                                 : : "b" (cpufunctbl[opcode]), "a" (opcode)
6282                                                                 : "%edx", "%ecx", "%esi", "%edi", "%ebp", "memory", "cc");
6283 #else
6467                          (*cpufunctbl[opcode])(opcode);
6285 #endif
6468                          if (end_block(opcode) || SPCFLAGS_TEST(SPCFLAG_ALL) || blocklen>=MAXRUN) {
6469                                  compile_block(pc_hist, blocklen);
6470                                  return; /* We will deal with the spcflags in the caller */
# Line 6295 | Line 6477 | void execute_normal(void)
6477  
6478   typedef void (*compiled_handler)(void);
6479  
6480 + #ifdef X86_ASSEMBLY
6481 + void (*m68k_compile_execute)(void) = NULL;
6482 + #else
6483   void m68k_do_compile_execute(void)
6484   {
6485          for (;;) {
6301 #ifdef X86_ASSEMBLY
6302                __asm__ __volatile__("\tpushl %%ebp\n\tcall *%%ebx\n\tpopl %%ebp" /* FIXME */
6303                                                         : : "b" (cache_tags[cacheline(regs.pc_p)].handler)
6304                                                         : "%edx", "%ecx", "%eax", "%esi", "%edi", "%ebp", "memory", "cc");
6305 #else
6486                  ((compiled_handler)(pushall_call_handler))();
6307 #endif
6487                  /* Whenever we return from that, we should check spcflags */
6488                  if (SPCFLAGS_TEST(SPCFLAG_ALL)) {
6489                          if (m68k_do_specialties ())
# Line 6312 | Line 6491 | void m68k_do_compile_execute(void)
6491                  }
6492          }
6493   }
6494 + #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines