VirtualBox

Changeset 13230

Show
Ignore:
Timestamp:
10/13/08 21:03:16 (3 months ago)
Author:
vboxsync
Message:

further new recompiler work

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/Config.kmk

    r13155 r13230  
    10301030## @todo eliminate these guys. 
    10311031ifdef VBOX_WITH_INTERNAL_NETWORKING 
    1032 DEFS += VBOX_WITH_INTERNAL_NETWORKING 
    1033 endif 
    1034  
     1032 DEFS += VBOX_WITH_INTERNAL_NETWORKING 
     1033endif 
     1034ifdef VBOX_WITH_NEW_RECOMPILER 
     1035 DEFS += VBOX_WITH_NEW_RECOMPILER 
     1036endif 
    10351037 
    10361038# 
  • trunk/include/VBox/vm.h

    r13189 r13230  
    683683        struct REM  s; 
    684684#endif 
     685 
     686#ifdef VBOX_WITH_NEW_RECOMPILER 
     687/* Must be multiple of 32 and coherent with REM_ENV_SIZE from REMInternal.h */ 
    685688#if GC_ARCH_BITS == 32 
    686         char        padding[HC_ARCH_BITS == 32 ? 0x6f00 : 0xbf00];    /* multiple of 32 */ 
    687 #else 
    688         char        padding[HC_ARCH_BITS == 32 ? 0x9f00 : 0xdf00];    /* multiple of 32 */ 
    689 #endif 
     689#define VM_REM_SIZE        (HC_ARCH_BITS == 32 ? 0xff00 : 0xff00) 
     690#else 
     691#define VM_REM_SIZE        (HC_ARCH_BITS == 32 ? 0xff00 : 0xff00) 
     692#endif 
     693#else 
     694#if GC_ARCH_BITS == 32 
     695#define VM_REM_SIZE        (HC_ARCH_BITS == 32 ? 0x6f00 : 0xbf00) 
     696#else 
     697#define VM_REM_SIZE        (HC_ARCH_BITS == 32 ? 0x9f00 : 0xdf00) 
     698#endif 
     699#endif // VBOX_WITH_NEW_RECOMILER 
     700        char        padding[ VM_REM_SIZE];    /* multiple of 32 */ 
    690701    } rem; 
    691702 
  • trunk/src/Makefile.kmk

    r13143 r13230  
    7373 
    7474 ifdef VBOX_WITH_NEW_RECOMPILER 
    75   SUBDIRS += recompiler_new 
     75  SUBDIRS += recompiler_new 
    7676 else 
    7777   SUBDIRS += recompiler 
  • trunk/src/VBox/VMM/REMInternal.h

    r12989 r13230  
    243243#endif 
    244244 
     245#ifdef VBOX_WITH_NEW_RECOMPILER 
     246#if GC_ARCH_BITS == 32 
     247#define REM_ENV_SIZE        (HC_ARCH_BITS == 32 ? 0xff00 : 0xff00) 
     248#else 
     249#define REM_ENV_SIZE        (HC_ARCH_BITS == 32 ? 0xff00 : 0xff00) 
     250#endif 
     251#else 
    245252#if GC_ARCH_BITS == 32 
    246253#define REM_ENV_SIZE        (HC_ARCH_BITS == 32 ? 0x6550 : 0xb4a0) 
     
    248255#define REM_ENV_SIZE        (HC_ARCH_BITS == 32 ? 0x9440 : 0xd4a0) 
    249256#endif 
     257#endif // VBOX_WITH_NEW_RECOMILER 
    250258 
    251259    /** Recompiler CPU state. */ 
  • trunk/src/recompiler_new/Makefile.kmk

    r13184 r13230  
    4141DLLS                 += VBoxREM 
    4242IMPORT_LIBS          += VBoxREMImp 
     43 
     44DEFS                 += VBOX_WITH_NEW_RECOMPILER 
     45 
    4346 
    4447OTHER_CLEAN          += \ 
     
    219222        $(APPEND)    $@ '' 
    220223 
    221 translate-all.c_DEPS =  
    222 translate-op.c_DEPS = $(translate-all.c_DEPS) 
    223 target-i386/translate.c_DEPS = $(translate-all.c_DEPS) 
    224  
    225224# 
    226225# The math testcase as a standalone program for testing and debugging purposes. 
  • trunk/src/recompiler_new/Sun/config.h

    r13184 r13230  
    2929#define TARGET_X86_64 
    3030#endif 
    31  
    32 #define unlikely(cond) RT_UNLIKELY(cond) 
  • trunk/src/recompiler_new/Sun/structs.h

    r11982 r13230  
    230230    REM_OFFSETOF(CPUState, ft0), 
    231231    REM_SIZEOFMEMB(CPUState, ft0), 
    232     REM_OFFSETOF(CPUState, fp_convert), 
    233     REM_SIZEOFMEMB(CPUState, fp_convert), 
    234232    REM_OFFSETOF(CPUState, sse_status), 
    235233    REM_OFFSETOF(CPUState, mxcsr), 
     
    266264    /* cpu-defs.h */ 
    267265    REM_OFFSETOF(CPUState, current_tb), 
    268     REM_OFFSETOF(CPUState, mem_write_pc), 
    269     REM_OFFSETOF(CPUState, mem_write_vaddr), 
     266    REM_OFFSETOF(CPUState, mem_io_pc), 
     267    REM_OFFSETOF(CPUState, mem_io_vaddr), 
    270268    REM_OFFSETOF(CPUState, tlb_table), 
    271269    REM_SIZEOFMEMB(CPUState, tlb_table), 
  • trunk/src/recompiler_new/VBoxRecompiler.c

    r13144 r13230  
    289289     * Init the recompiler. 
    290290     */ 
    291     if (!cpu_x86_init(&pVM->rem.s.Env)) 
     291    if (!cpu_x86_init(&pVM->rem.s.Env, "vbox")) 
    292292    { 
    293293        AssertMsgFailed(("cpu_x86_init failed - impossible!\n")); 
     
    38063806            cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HARD); 
    38073807        else 
    3808             ASMAtomicOrS32(&cpu_single_env->interrupt_request, CPU_INTERRUPT_EXTERNAL_HARD); 
     3808            ASMAtomicOrS32((int32_t volatile *)&cpu_single_env->interrupt_request,  
     3809                           CPU_INTERRUPT_EXTERNAL_HARD); 
    38093810    } 
    38103811} 
     
    38413842            cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT); 
    38423843        else 
    3843             ASMAtomicOrS32(&cpu_single_env->interrupt_request, CPU_INTERRUPT_EXTERNAL_TIMER); 
     3844            ASMAtomicOrS32((int32_t volatile *)&cpu_single_env->interrupt_request,  
     3845                           CPU_INTERRUPT_EXTERNAL_TIMER); 
    38443846    } 
    38453847} 
     
    38603862            cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT); 
    38613863        else 
    3862             ASMAtomicOrS32(&cpu_single_env->interrupt_request, CPU_INTERRUPT_EXTERNAL_DMA); 
     3864            ASMAtomicOrS32((int32_t volatile *)&cpu_single_env->interrupt_request,  
     3865                           CPU_INTERRUPT_EXTERNAL_DMA); 
    38633866    } 
    38643867} 
     
    38793882            cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT); 
    38803883        else 
    3881             ASMAtomicOrS32(&cpu_single_env->interrupt_request, CPU_INTERRUPT_EXTERNAL_EXIT); 
     3884            ASMAtomicOrS32((int32_t volatile *)&cpu_single_env->interrupt_request,  
     3885                           CPU_INTERRUPT_EXTERNAL_EXIT); 
    38823886    } 
    38833887} 
     
    38983902            cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT); 
    38993903        else 
    3900             ASMAtomicOrS32(&cpu_single_env->interrupt_request, CPU_INTERRUPT_EXTERNAL_EXIT); 
     3904            ASMAtomicOrS32((int32_t volatile *)&cpu_single_env->interrupt_request,  
     3905                           CPU_INTERRUPT_EXTERNAL_EXIT); 
    39013906    } 
    39023907} 
  • trunk/src/recompiler_new/cpu-all.h

    r11982 r13230  
    134134#endif 
    135135 
     136typedef union { 
     137    float32 f; 
     138    uint32_t l; 
     139} CPU_FloatU; 
     140 
    136141/* NOTE: arm FPA is horrible as double 32 bit words are stored in big 
    137142   endian ! */ 
     
    152157    uint64_t ll; 
    153158} CPU_DoubleU; 
     159 
     160#ifdef TARGET_SPARC 
     161typedef union { 
     162    float128 q; 
     163#if defined(WORDS_BIGENDIAN) \ 
     164    || (defined(__arm__) && !defined(__VFP_FP__) && !defined(CONFIG_SOFTFLOAT)) 
     165    struct { 
     166        uint32_t upmost; 
     167        uint32_t upper; 
     168        uint32_t lower; 
     169        uint32_t lowest; 
     170    } l; 
     171    struct { 
     172        uint64_t upper; 
     173        uint64_t lower; 
     174    } ll; 
     175#else 
     176    struct { 
     177        uint32_t lowest; 
     178        uint32_t lower; 
     179        uint32_t upper; 
     180        uint32_t upmost; 
     181    } l; 
     182    struct { 
     183        uint64_t lower; 
     184        uint64_t upper; 
     185    } ll; 
     186#endif 
     187} CPU_QuadU; 
     188#endif 
    154189 
    155190/* CPU memory access without any memory or io remapping */ 
     
    831866   code */ 
    832867#define PAGE_WRITE_ORG 0x0010 
     868#define PAGE_RESERVED  0x0020 
    833869 
    834870void page_dump(FILE *f); 
    835871int page_get_flags(target_ulong address); 
    836872void page_set_flags(target_ulong start, target_ulong end, int flags); 
     873int page_check_range(target_ulong start, target_ulong len, int flags); 
    837874void page_unprotect_range(target_ulong data, target_ulong data_size); 
    838875 
     
    908945extern CPUState *first_cpu; 
    909946extern CPUState *cpu_single_env; 
    910 extern int code_copy_enabled; 
     947extern int64_t qemu_icount; 
     948extern int use_icount; 
    911949 
    912950#define CPU_INTERRUPT_EXIT   0x01 /* wants exit from main loop */ 
     
    917955#define CPU_INTERRUPT_HALT   0x20 /* CPU halt wanted */ 
    918956#define CPU_INTERRUPT_SMI    0x40 /* (x86 only) SMI interrupt pending */ 
     957#define CPU_INTERRUPT_DEBUG  0x80 /* Debug event occured.  */ 
     958#define CPU_INTERRUPT_VIRQ   0x100 /* virtual interrupt pending.  */ 
     959#define CPU_INTERRUPT_NMI    0x200 /* NMI pending. */ 
    919960 
    920961#ifdef VBOX 
    921962/** Executes a single instruction. cpu_exec() will normally return EXCP_SINGLE_INSTR. */ 
    922 #define CPU_INTERRUPT_SINGLE_INSTR              0x0200 
     963#define CPU_INTERRUPT_SINGLE_INSTR              0x0400 
    923964/** Executing a CPU_INTERRUPT_SINGLE_INSTR request, quit the cpu_loop. (for exceptions and suchlike) */ 
    924 #define CPU_INTERRUPT_SINGLE_INSTR_IN_FLIGHT    0x0400 
     965#define CPU_INTERRUPT_SINGLE_INSTR_IN_FLIGHT    0x0800 
    925966/** VM execution was interrupted by VMR3Reset, VMR3Suspend or VMR3PowerOff. */ 
    926 #define CPU_INTERRUPT_RC                        0x0800 
     967#define CPU_INTERRUPT_RC                        0x1000 
    927968/** Exit current TB to process an external interrupt request (also in op.c!!) */ 
    928 #define CPU_INTERRUPT_EXTERNAL_EXIT             0x1000 
     969#define CPU_INTERRUPT_EXTERNAL_EXIT             0x2000 
    929970/** Exit current TB to process an external interrupt request (also in op.c!!) */ 
    930 #define CPU_INTERRUPT_EXTERNAL_HARD             0x2000 
     971#define CPU_INTERRUPT_EXTERNAL_HARD             0x4000 
    931972/** Exit current TB to process an external interrupt request (also in op.c!!) */ 
    932 #define CPU_INTERRUPT_EXTERNAL_TIMER            0x4000 
     973#define CPU_INTERRUPT_EXTERNAL_TIMER            0x8000 
    933974/** Exit current TB to process an external interrupt request (also in op.c!!) */ 
    934 #define CPU_INTERRUPT_EXTERNAL_DMA              0x8000 
     975#define CPU_INTERRUPT_EXTERNAL_DMA              0x10000 
    935976#endif /* VBOX */ 
    936977void cpu_interrupt(CPUState *s, int mask); 
    937978void cpu_reset_interrupt(CPUState *env, int mask); 
    938979 
     980int cpu_watchpoint_insert(CPUState *env, target_ulong addr, int type); 
     981int cpu_watchpoint_remove(CPUState *env, target_ulong addr); 
     982void cpu_watchpoint_remove_all(CPUState *env); 
    939983int cpu_breakpoint_insert(CPUState *env, target_ulong pc); 
    940984int cpu_breakpoint_remove(CPUState *env, target_ulong pc); 
     985void cpu_breakpoint_remove_all(CPUState *env); 
     986 
     987#define SSTEP_ENABLE  0x1  /* Enable simulated HW single stepping */ 
     988#define SSTEP_NOIRQ   0x2  /* Do not use IRQ while single stepping */ 
     989#define SSTEP_NOTIMER 0x4  /* Do not Timers while single stepping */ 
     990 
    941991void cpu_single_step(CPUState *env, int enabled); 
    942992void cpu_reset(CPUState *s); 
     
    9811031int cpu_inw(CPUState *env, int addr); 
    9821032int cpu_inl(CPUState *env, int addr); 
     1033#endif 
     1034 
     1035/* address in the RAM (different from a physical address) */ 
     1036#ifdef USE_KQEMU 
     1037typedef uint32_t ram_addr_t; 
     1038#else 
     1039typedef unsigned long ram_addr_t; 
    9831040#endif 
    9841041 
     
    10071064#define IO_MEM_ROM         (1 << IO_MEM_SHIFT) /* hardcoded offset */ 
    10081065#define IO_MEM_UNASSIGNED  (2 << IO_MEM_SHIFT) 
    1009 #define IO_MEM_NOTDIRTY    (4 << IO_MEM_SHIFT) /* used internally, never use directly */ 
     1066#define IO_MEM_NOTDIRTY    (3 << IO_MEM_SHIFT) 
    10101067#if defined(VBOX) && !defined(VBOX_WITH_NEW_PHYS_CODE) 
    10111068#define IO_MEM_RAM_MISSING (5 << IO_MEM_SHIFT) /* used internally, never use directly */ 
     
    10151072   the physical address */ 
    10161073#define IO_MEM_ROMD        (1) 
     1074#define IO_MEM_SUBPAGE     (2) 
     1075#define IO_MEM_SUBWIDTH    (4) 
     1076 
     1077/* Flags stored in the low bits of the TLB virtual address.  These are 
     1078   defined so that fast path ram access is all zeros.  */ 
     1079/* Zero if TLB entry is valid.  */ 
     1080#define TLB_INVALID_MASK   (1 << 3) 
     1081/* Set if TLB entry references a clean RAM page.  The iotlb entry will 
     1082   contain the page physical address.  */ 
     1083#define TLB_NOTDIRTY    (1 << 4) 
     1084/* Set if TLB entry is an IO callback.  */ 
     1085#define TLB_MMIO        (1 << 5) 
    10171086 
    10181087typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, uint32_t value); 
     
    10201089 
    10211090void cpu_register_physical_memory(target_phys_addr_t start_addr, 
    1022                                   unsigned long size, 
    1023                                   unsigned long phys_offset); 
     1091                                  ram_addr_t size, 
     1092                                  ram_addr_t phys_offset); 
    10241093uint32_t cpu_get_physical_page_desc(target_phys_addr_t addr); 
     1094ram_addr_t qemu_ram_alloc(ram_addr_t); 
     1095void qemu_ram_free(ram_addr_t addr); 
    10251096int cpu_register_io_memory(int io_index, 
    10261097                           CPUReadMemoryFunc **mem_read, 
     
    10471118uint64_t ldq_phys(target_phys_addr_t addr); 
    10481119void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val); 
     1120void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val); 
    10491121void stb_phys(target_phys_addr_t addr, uint32_t val); 
    10501122void stw_phys(target_phys_addr_t addr, uint32_t val); 
     
    10591131#define VGA_DIRTY_FLAG  0x01 
    10601132#define CODE_DIRTY_FLAG 0x02 
     1133#define KQEMU_DIRTY_FLAG     0x04 
     1134#define MIGRATION_DIRTY_FLAG 0x08 
    10611135 
    10621136/* read dirty bit (return 0 or 1) */ 
     
    11041178                                     int dirty_flags); 
    11051179void cpu_tlb_update_dirty(CPUState *env); 
     1180 
     1181int cpu_physical_memory_set_dirty_tracking(int enable); 
     1182 
     1183int cpu_physical_memory_get_dirty_tracking(void); 
    11061184 
    11071185void dump_exec_info(FILE *f, 
  • trunk/src/recompiler_new/cpu-defs.h

    r11982 r13230  
    5454typedef uint32_t target_ulong; 
    5555#define TARGET_FMT_lx "%08x" 
     56#define TARGET_FMT_ld "%d" 
     57#define TARGET_FMT_lu "%u" 
    5658#elif TARGET_LONG_SIZE == 8 
    5759typedef int64_t target_long; 
    5860typedef uint64_t target_ulong; 
    5961#define TARGET_FMT_lx "%016" PRIx64 
     62#define TARGET_FMT_ld "%" PRId64 
     63#define TARGET_FMT_lu "%" PRIu64 
    6064#else 
    6165#error TARGET_LONG_SIZE undefined 
     
    7074#if TARGET_PHYS_ADDR_BITS == 32 
    7175typedef uint32_t target_phys_addr_t; 
     76#define TARGET_FMT_plx "%08x" 
    7277#elif TARGET_PHYS_ADDR_BITS == 64 
    7378typedef uint64_t target_phys_addr_t; 
     79#define TARGET_FMT_plx "%016" PRIx64 
    7480#else 
    7581#error TARGET_PHYS_ADDR_BITS undefined 
    7682#endif 
    77  
    78 /* address in the RAM (different from a physical address) */ 
    79 typedef unsigned long ram_addr_t; 
    8083 
    8184#define HOST_LONG_SIZE (HOST_LONG_BITS / 8) 
     
    9295#endif /* VBOX */ 
    9396#define MAX_BREAKPOINTS 32 
     97#define MAX_WATCHPOINTS 32 
    9498 
    9599#define TB_JMP_CACHE_BITS 12 
     
    107111#define CPU_TLB_SIZE (1 << CPU_TLB_BITS) 
    108112 
     113#if TARGET_PHYS_ADDR_BITS == 32 && TARGET_LONG_BITS == 32 
     114#define CPU_TLB_ENTRY_BITS 4 
     115#else 
     116#define CPU_TLB_ENTRY_BITS 5 
     117#endif 
     118 
    109119typedef struct CPUTLBEntry { 
    110     /* bit 31 to TARGET_PAGE_BITS : virtual address  
    111        bit TARGET_PAGE_BITS-1..IO_MEM_SHIFT : if non zero, memory io 
    112                                               zone number 
     120    /* bit TARGET_LONG_BITS to TARGET_PAGE_BITS : virtual address 
     121       bit TARGET_PAGE_BITS-1..4  : Nonzero for accesses that should not 
     122                                    go directly to ram. 
    113123       bit 3                      : indicates that the entry is invalid 
    114124       bit 2..0                   : zero 
     
    117127    target_ulong addr_write;  
    118128    target_ulong addr_code;  
    119     /* addend to virtual address to get physical address */ 
    120     target_phys_addr_t addend;  
     129      /* Addend to virtual address to get physical address.  IO accesses 
     130       use the correcponding iotlb value.  */ 
     131#if TARGET_PHYS_ADDR_BITS == 64 
     132    /* on i386 Linux make sure it is aligned */ 
     133    target_phys_addr_t addend __attribute__((aligned(8))); 
     134#else 
     135    target_phys_addr_t addend; 
     136#endif 
     137    /* padding to get a power of two size */ 
     138    uint8_t dummy[(1 << CPU_TLB_ENTRY_BITS) -  
     139                  (sizeof(target_ulong) * 3 +  
     140                   ((-sizeof(target_ulong) * 3) & (sizeof(target_phys_addr_t) - 1)) +  
     141                   sizeof(target_phys_addr_t))]; 
    121142} CPUTLBEntry; 
     143 
     144#ifdef WORDS_BIGENDIAN 
     145typedef struct icount_decr_u16 { 
     146    uint16_t high; 
     147    uint16_t low; 
     148} icount_decr_u16; 
     149#else 
     150typedef struct icount_decr_u16 { 
     151    uint16_t low; 
     152    uint16_t high; 
     153} icount_decr_u16; 
     154#endif 
     155 
     156 
     157#define CPU_TEMP_BUF_NLONGS 128 
     158#ifdef VBOX 
     159struct TCGContext; 
    122160 
    123161#define CPU_COMMON                                                      \ 
    124162    struct TranslationBlock *current_tb; /* currently executing TB  */  \ 
    125163    /* soft mmu support */                                              \ 
    126     /* in order to avoid passing too many arguments to the memory       \ 
    127        write helpers, we store some rarely used information in the CPU  \ 
     164    /* in order to avoid passing too many arguments to the MMIO         \ 
     165       helpers, we store some rarely used information in the CPU        \ 
    128166       context) */                                                      \ 
    129     unsigned long mem_write_pc; /* host pc at which the memory was      \ 
    130                                    written */                           \ 
    131     target_ulong mem_write_vaddr; /* target virtual addr at which the   \ 
    132                                      memory was written */              \ 
    133     /* 0 = kernel, 1 = user */                                          \ 
    134     CPUTLBEntry tlb_table[2][CPU_TLB_SIZE];                             \ 
     167    unsigned long mem_io_pc; /* host pc at which the memory was         \ 
     168                                accessed */                             \ 
     169    target_ulong mem_io_vaddr; /* target virtual addr at which the      \ 
     170                                     memory was accessed */             \ 
     171    uint32_t halted; /* Nonzero if the CPU is in suspend state */       \ 
     172    uint32_t interrupt_request;                                         \ 
     173    /* The meaning of the MMU modes is defined in the target code. */   \ 
     174    CPUTLBEntry tlb_table[NB_MMU_MODES][CPU_TLB_SIZE];                  \ 
     175    target_phys_addr_t iotlb[NB_MMU_MODES][CPU_TLB_SIZE];               \ 
    135176    struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE];           \ 
     177    /* buffer for temporaries in the code generator */                  \ 
     178    long temp_buf[CPU_TEMP_BUF_NLONGS];                                 \ 
     179                                                                        \ 
     180    int64_t icount_extra; /* Instructions until next timer event.  */   \ 
     181    /* Number of cycles left, with interrupt flag in high bit.          \ 
     182       This allows a single read-compare-cbranch-write sequence to test \ 
     183       for both decrementer underflow and exceptions.  */               \ 
     184    union {                                                             \ 
     185        uint32_t u32;                                                   \ 
     186        icount_decr_u16 u16;                                            \ 
     187    } icount_decr;                                                      \ 
     188    uint32_t can_do_io; /* nonzero if memory mapped IO is safe.  */     \ 
    136189                                                                        \ 
    137190    /* from this point: preserved by CPU reset */                       \ 
     
    141194    int singlestep_enabled;                                             \ 
    142195                                                                        \ 
     196    struct {                                                            \ 
     197        target_ulong vaddr;                                             \ 
     198        int type; /* PAGE_READ/PAGE_WRITE */                            \ 
     199    } watchpoint[MAX_WATCHPOINTS];                                      \ 
     200    int nb_watchpoints;                                                 \ 
     201    int watchpoint_hit;                                                 \ 
     202                                                                        \ 
     203    /* Core interrupt code */                                           \ 
     204    jmp_buf jmp_env;                                                    \ 
     205    int exception_index;                                                \ 
     206                                                                        \ 
     207    int user_mode_only;                                                 \ 
     208                                                                        \ 
    143209    void *next_cpu; /* next CPU sharing TB cache */                     \ 
    144210    int cpu_index; /* CPU index (informative) */                        \ 
     211    int running; /* Nonzero if cpu is currently running(usermode).  */  \ 
    145212    /* user data */                                                     \ 
    146     void *opaque; 
    147  
    148 #endif 
     213    void *opaque;                                                       \ 
     214                                                                        \ 
     215    const char *cpu_model_str;                                          \ 
     216    /* Codegenerator context */                                         \ 
     217    struct TCGContext *tcg_context; 
     218#else 
     219 
     220#define CPU_COMMON                                                      \ 
     221    struct TranslationBlock *current_tb; /* currently executing TB  */  \ 
     222    /* soft mmu support */                                              \ 
     223    /* in order to avoid passing too many arguments to the MMIO         \ 
     224       helpers, we store some rarely used information in the CPU        \ 
     225       context) */                                                      \ 
     226    unsigned long mem_io_pc; /* host pc at which the memory was         \ 
     227                                accessed */                             \ 
     228    target_ulong mem_io_vaddr; /* target virtual addr at which the      \ 
     229                                     memory was accessed */             \ 
     230    uint32_t halted; /* Nonzero if the CPU is in suspend state */       \ 
     231    uint32_t interrupt_request;                                         \ 
     232    /* The meaning of the MMU modes is defined in the target code. */   \ 
     233    CPUTLBEntry tlb_table[NB_MMU_MODES][CPU_TLB_SIZE];                  \ 
     234    target_phys_addr_t iotlb[NB_MMU_MODES][CPU_TLB_SIZE];               \ 
     235    struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE];           \ 
     236    /* buffer for temporaries in the code generator */                  \ 
     237    long temp_buf[CPU_TEMP_BUF_NLONGS];                                 \ 
     238                                                                        \ 
     239    int64_t icount_extra; /* Instructions until next timer event.  */   \ 
     240    /* Number of cycles left, with interrupt flag in high bit.          \ 
     241       This allows a single read-compare-cbranch-write sequence to test \ 
     242       for both decrementer underflow and exceptions.  */               \ 
     243    union {                                                             \ 
     244        uint32_t u32;                                                   \ 
     245        icount_decr_u16 u16;                                            \ 
     246    } icount_decr;                                                      \ 
     247    uint32_t can_do_io; /* nonzero if memory mapped IO is safe.  */     \ 
     248                                                                        \ 
     249    /* from this point: preserved by CPU reset */                       \ 
     250    /* ice debug support */                                             \ 
     251    target_ulong breakpoints[MAX_BREAKPOINTS];                          \ 
     252    int nb_breakpoints;                                                 \ 
     253    int singlestep_enabled;                                             \ 
     254                                                                        \ 
     255    struct {                                                            \ 
     256        target_ulong vaddr;                                             \ 
     257        int type; /* PAGE_READ/PAGE_WRITE */                            \ 
     258    } watchpoint[MAX_WATCHPOINTS];                                      \ 
     259    int nb_watchpoints;                                                 \ 
     260    int watchpoint_hit;                                                 \ 
     261                                                                        \ 
     262    /* Core interrupt code */                                           \ 
     263    jmp_buf jmp_env;                                                    \ 
     264    int exception_index;                                                \ 
     265                                                                        \ 
     266    int user_mode_only;                                                 \ 
     267                                                                        \ 
     268    void *next_cpu; /* next CPU sharing TB cache */                     \ 
     269    int cpu_index; /* CPU index (informative) */                        \ 
     270    int running; /* Nonzero if cpu is currently running(usermode).  */  \ 
     271    /* user data */                                                     \ 
     272    void *opaque;                                                       \ 
     273                                                                        \ 
     274    const char *cpu_model_str;                                           
     275#endif 
     276 
     277#endif 
  • trunk/src/recompiler_new/exec-all.h

    r11982 r13230  
    6767#define DISAS_TB_JUMP 3 /* only pc was modified statically */ 
    6868 
    69 struct TranslationBlock; 
     69typedef struct TranslationBlock TranslationBlock; 
    7070 
    7171/* XXX: make safe guess about sizes */ 
    72 #define MAX_OP_PER_INSTR 32 
     72#define MAX_OP_PER_INSTR 64 
     73/* A Call op needs up to 6 + 2N parameters (N = number of arguments).  */ 
     74#define MAX_OPC_PARAM 10 
    7375#define OPC_BUF_SIZE 512 
    7476#define OPC_MAX_SIZE (OPC_BUF_SIZE - MAX_OP_PER_INSTR) 
    7577 
    76 #define OPPARAM_BUF_SIZE (OPC_BUF_SIZE * 3) 
    77  
    78 extern uint16_t gen_opc_buf[OPC_BUF_SIZE]; 
    79 extern uint32_t gen_opparam_buf[OPPARAM_BUF_SIZE]; 
    80 extern long gen_labels[OPC_BUF_SIZE]; 
    81 extern int nb_gen_labels; 
     78/* Maximum size a TCG op can expand to.  This is complicated because a 
     79   single op may require several host instructions and regirster reloads. 
     80   For now take a wild guess at 128 bytes, which should allow at least 
     81   a couple of fixup instructions per argument.  */ 
     82#define TCG_MAX_OP_SIZE 128 
     83 
     84#define OPPARAM_BUF_SIZE (OPC_BUF_SIZE * MAX_OPC_PARAM) 
     85 
    8286extern target_ulong gen_opc_pc[OPC_BUF_SIZE]; 
    8387extern target_ulong gen_opc_npc[OPC_BUF_SIZE]; 
    8488extern uint8_t gen_opc_cc_op[OPC_BUF_SIZE]; 
    8589extern uint8_t gen_opc_instr_start[OPC_BUF_SIZE]; 
     90extern uint16_t gen_opc_icount[OPC_BUF_SIZE]; 
    8691extern target_ulong gen_opc_jump_pc[2]; 
    8792extern uint32_t gen_opc_hflags[OPC_BUF_SIZE]; 
     
    9297typedef void (GenOpFunc3)(long, long, long); 
    9398 
    94 #if defined(TARGET_I386) 
    95  
    96 void optimize_flags_init(void); 
    97  
    98 #endif 
    99  
     99#ifndef VBOX 
    100100extern FILE *logfile; 
    101101extern int loglevel; 
    102  
    103 int gen_intermediate_code(CPUState *env, struct TranslationBlock *tb); 
    104 int gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb); 
    105 void dump_ops(const uint16_t *opc_buf, const uint32_t *opparam_buf); 
     102#endif 
     103 
     104void gen_intermediate_code(CPUState *env, struct TranslationBlock *tb); 
     105void gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb); 
     106void gen_pc_load(CPUState *env, struct TranslationBlock *tb, 
     107                 unsigned long searched_pc, int pc_pos, void *puc); 
     108 
     109unsigned long code_gen_max_block_size(void); 
     110void cpu_gen_init(void); 
    106111int cpu_gen_code(CPUState *env, struct TranslationBlock *tb, 
    107                  int max_code_size, int *gen_code_size_ptr); 
     112                 int *gen_code_size_ptr); 
    108113int cpu_restore_state(struct TranslationBlock *tb, 
    109114                      CPUState *env, unsigned long searched_pc, 
    110115                      void *puc); 
    111 int cpu_gen_code_copy(CPUState *env, struct TranslationBlock *tb, 
    112                       int max_code_size, int *gen_code_size_ptr); 
    113116int cpu_restore_state_copy(struct TranslationBlock *tb, 
    114117                           CPUState *env, unsigned long searched_pc, 
    115118                           void *puc); 
    116119void cpu_resume_from_signal(CPUState *env1, void *puc); 
     120void cpu_io_recompile(CPUState *env, void *retaddr); 
     121TranslationBlock *tb_gen_code(CPUState *env,  
     122                              target_ulong pc, target_ulong cs_base, int flags, 
     123                              int cflags); 
    117124void cpu_exec_init(CPUState *env); 
    118125int page_unprotect(target_ulong address, unsigned long pc, void *puc); 
    119 void tb_invalidate_phys_page_range(target_ulong start, target_ulong end, 
     126void tb_invalidate_phys_page_range(target_phys_addr_t start, target_phys_addr_t end, 
    120127                                   int is_cpu_write_access); 
    121128void tb_invalidate_page_range(target_ulong start, target_ulong end); 
     
    124131int tlb_set_page_exec(CPUState *env, target_ulong vaddr, 
    125132                      target_phys_addr_t paddr, int prot, 
    126                       int is_user, int is_softmmu); 
    127 static inline int tlb_set_page(CPUState *env, target_ulong vaddr, 
     133                      int mmu_idx, int is_softmmu); 
     134static inline int tlb_set_page(CPUState *env1, target_ulong vaddr, 
    128135                               target_phys_addr_t paddr, int prot, 
    129                                int is_user, int is_softmmu) 
     136                               int mmu_idx, int is_softmmu) 
    130137{ 
    131138    if (prot & PAGE_READ) 
    132139        prot |= PAGE_EXEC; 
    133     return tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu); 
    134 
    135  
    136 #define CODE_GEN_MAX_SIZE        65536 
     140    return tlb_set_page_exec(env1, vaddr, paddr, prot, mmu_idx, is_softmmu); 
     141
     142 
    137143#define CODE_GEN_ALIGN           16 /* must be >= of the size of a icache line */ 
    138144 
     
    140146#define CODE_GEN_PHYS_HASH_SIZE     (1 << CODE_GEN_PHYS_HASH_BITS) 
    141147 
    142 /* maximum total translate dcode allocated */ 
    143  
    144 /* NOTE: the translated code area cannot be too big because on some 
    145    archs the range of "fast" function calls is limited. Here is a 
    146    summary of the ranges: 
    147  
    148    i386  : signed 32 bits 
    149    arm   : signed 26 bits 
    150    ppc   : signed 24 bits 
    151    sparc : signed 32 bits 
    152    alpha : signed 23 bits 
    153 */ 
    154  
    155 #if defined(__alpha__) 
    156 #define CODE_GEN_BUFFER_SIZE     (2 * 1024 * 1024) 
    157 #elif defined(__ia64) 
    158 #define CODE_GEN_BUFFER_SIZE     (4 * 1024 * 1024)      /* range of addl */ 
    159 #elif defined(__powerpc__) 
    160 #define CODE_GEN_BUFFER_SIZE     (6 * 1024 * 1024) 
    161 #else 
    162 #define CODE_GEN_BUFFER_SIZE     (16 * 1024 * 1024) 
    163 #endif 
    164  
    165 //#define CODE_GEN_BUFFER_SIZE     (128 * 1024) 
     148#define MIN_CODE_GEN_BUFFER_SIZE     (1024 * 1024) 
    166149 
    167150/* estimated block size for TB allocation */ 
     
    174157#endif 
    175158 
    176 #define CODE_GEN_MAX_BLOCKS    (CODE_GEN_BUFFER_SIZE / CODE_GEN_AVG_BLOCK_SIZE) 
    177  
    178 #if defined(__powerpc__) 
     159#if defined(__powerpc__) || defined(__x86_64__) || defined(__arm__) 
    179160#define USE_DIRECT_JUMP 
    180161#endif 
     
    182163#define USE_DIRECT_JUMP 
    183164#endif 
     165 
    184166#ifdef VBOX /* bird: not safe in next step because of threading & cpu_interrupt. */ 
    185167#undef USE_DIRECT_JUMP 
    186168#endif /* VBOX */ 
    187169 
    188 typedef struct TranslationBlock { 
     170struct TranslationBlock { 
    189171    target_ulong pc;   /* simulated PC corresponding to this block (EIP + CS base) */ 
    190172    target_ulong cs_base; /* CS base for this block */ 
     
    193175                           size <= TARGET_PAGE_SIZE) */ 
    194176    uint16_t cflags;    /* compile flags */ 
    195 #define CF_CODE_COPY   0x0001 /* block was generated in code copy mode */ 
    196 #define CF_TB_FP_USED  0x0002 /* fp ops are used in the TB */ 
    197 #define CF_FP_USED     0x0004 /* fp ops are used in the TB or in a chained TB */ 
    198 #define CF_SINGLE_INSN 0x0008 /* compile only a single instruction */ 
     177#define CF_COUNT_MASK  0x7fff 
     178#define CF_LAST_IO     0x8000 /* Last insn may be an IO access.  */ 
     179 
    199180#ifdef VBOX 
    200181#define CF_RAW_MODE    0x0010 /* block was generated in raw mode */ 
     
    226207    struct TranslationBlock *jmp_next[2]; 
    227208    struct TranslationBlock *jmp_first; 
    228 } TranslationBlock; 
     209    uint32_t icount; 
     210}; 
    229211 
    230212static inline unsigned int tb_jmp_cache_hash_page(target_ulong pc) 
     
    249231 
    250232TranslationBlock *tb_alloc(target_ulong pc); 
     233void tb_free(TranslationBlock *tb); 
    251234void tb_flush(CPUState *env); 
    252235void tb_link_phys(TranslationBlock *tb, 
    253236                  target_ulong phys_pc, target_ulong phys_page2); 
     237void tb_phys_invalidate(TranslationBlock *tb, target_ulong page_addr); 
    254238 
    255239extern TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE]; 
    256240 
    257 extern uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE]; 
    258241extern uint8_t *code_gen_ptr; 
     242extern int code_gen_max_blocks; 
    259243 
    260244#if defined(USE_DIRECT_JUMP) 
     
    342326#define ASM_OP_LABEL_NAME(n, opname) \ 
    343327    ASM_NAME(__op_label) #n "." ASM_NAME(opname) 
    344  
    345 #if defined(__powerpc__) 
    346  
    347 /* we patch the jump instruction directly */ 
    348 #define GOTO_TB(opname, tbparam, n)\ 
    349 do {\ 
    350     asm volatile (ASM_DATA_SECTION\ 
    351                   ASM_OP_LABEL_NAME(n, opname) ":\n"\ 
    352                   ".long 1f\n"\ 
    353                   ASM_PREVIOUS_SECTION \ 
    354                   "b " ASM_NAME(__op_jmp) #n "\n"\ 
    355                   "1:\n");\ 
    356 } while (0) 
    357  
    358 #elif defined(__i386__) && defined(USE_DIRECT_JUMP) 
    359  
    360 /* we patch the jump instruction directly */ 
    361 #define GOTO_TB(opname, tbparam, n)\ 
    362 do {\ 
    363     asm volatile (".section .data\n"\ 
    364                   ASM_OP_LABEL_NAME(n, opname) ":\n"\ 
    365                   ".long 1f\n"\ 
    366                   ASM_PREVIOUS_SECTION \ 
    367                   "jmp " ASM_NAME(__op_jmp) #n "\n"\ 
    368                   "1:\n");\ 
    369 } while (0) 
    370  
    371 #else 
    372  
    373 /* jump to next block operations (more portable code, does not need 
    374    cache flushing, but slower because of indirect jump) */ 
    375 # ifdef VBOX /* bird: GCC4 (and Ming 3.4.x?) will remove the two unused static 
    376                 variables. I've added a dummy __asm__ statement which reference 
    377                 the two variables to prevent this. */ 
    378 #  if __GNUC__ >= 4 
    379 #   define GOTO_TB(opname, tbparam, n)\ 
    380     do {\ 
    381         static void __attribute__((unused)) *dummy ## n = &&dummy_label ## n;\ 
    382         static void __attribute__((unused)) *__op_label ## n \ 
    383             __asm__(ASM_OP_LABEL_NAME(n, opname)) = &&label ## n;\ 
    384         __asm__ ("" : : "m" (__op_label ## n), "m" (dummy ## n));\ 
    385         goto *(void *)(uintptr_t)(((TranslationBlock *)tbparam)->tb_next[n]);\ 
    386     label ## n: ;\ 
    387     dummy_label ## n: ;\ 
    388     } while (0) 
    389 #  else 
    390 #   define GOTO_TB(opname, tbparam, n)\ 
    391     do {\ 
    392         static void __attribute__((unused)) *dummy ## n = &&dummy_label ## n;\ 
    393         static void __attribute__((unused)) *__op_label ## n \ 
    394             __asm__(ASM_OP_LABEL_NAME(n, opname)) = &&label ## n;\ 
    395         goto *(void *)(uintptr_t)(((TranslationBlock *)tbparam)->tb_next[n]);\ 
    396     label ## n: ;\ 
    397     dummy_label ## n: ;\ 
    398     } while (0) 
    399 #  endif 
    400 # else /* !VBOX */ 
    401 #define GOTO_TB(opname, tbparam, n)\ 
    402 do {\ 
    403     static void __attribute__((unused)) *dummy ## n = &&dummy_label ## n;\ 
    404     static void __attribute__((unused)) *__op_label ## n \ 
    405         __asm__(ASM_OP_LABEL_NAME(n, opname)) = &&label ## n;\ 
    406     goto *(void *)(((TranslationBlock *)tbparam)->tb_next[n]);\ 
    407 label ## n: ;\ 
    408 dummy_label ## n: ;\ 
    409 } while (0) 
    410 # endif /* !VBOX */ 
    411  
    412 #endif 
    413328 
    414329extern CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4]; 
     
    583498              void *retaddr); 
    584