Changeset 13230
- Timestamp:
- 10/13/08 21:03:16 (3 months ago)
- Files:
-
- trunk/Config.kmk (modified) (1 diff)
- trunk/include/VBox/vm.h (modified) (1 diff)
- trunk/src/Makefile.kmk (modified) (1 diff)
- trunk/src/VBox/VMM/REMInternal.h (modified) (2 diffs)
- trunk/src/recompiler_new/Makefile.kmk (modified) (2 diffs)
- trunk/src/recompiler_new/Sun/config.h (modified) (1 diff)
- trunk/src/recompiler_new/Sun/structs.h (modified) (2 diffs)
- trunk/src/recompiler_new/VBoxRecompiler.c (modified) (6 diffs)
- trunk/src/recompiler_new/cpu-all.h (modified) (12 diffs)
- trunk/src/recompiler_new/cpu-defs.h (modified) (6 diffs)
- trunk/src/recompiler_new/exec-all.h (modified) (12 diffs)
- trunk/src/recompiler_new/osdep.h (modified) (1 diff)
- trunk/src/recompiler_new/target-i386/cpu.h (modified) (22 diffs)
- trunk/src/recompiler_new/target-i386/exec.h (modified) (9 diffs)
- trunk/src/recompiler_new/translate-all.c (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/Config.kmk
r13155 r13230 1030 1030 ## @todo eliminate these guys. 1031 1031 ifdef VBOX_WITH_INTERNAL_NETWORKING 1032 DEFS += VBOX_WITH_INTERNAL_NETWORKING 1033 endif 1034 1032 DEFS += VBOX_WITH_INTERNAL_NETWORKING 1033 endif 1034 ifdef VBOX_WITH_NEW_RECOMPILER 1035 DEFS += VBOX_WITH_NEW_RECOMPILER 1036 endif 1035 1037 1036 1038 # trunk/include/VBox/vm.h
r13189 r13230 683 683 struct REM s; 684 684 #endif 685 686 #ifdef VBOX_WITH_NEW_RECOMPILER 687 /* Must be multiple of 32 and coherent with REM_ENV_SIZE from REMInternal.h */ 685 688 #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 */ 690 701 } rem; 691 702 trunk/src/Makefile.kmk
r13143 r13230 73 73 74 74 ifdef VBOX_WITH_NEW_RECOMPILER 75 SUBDIRS += recompiler_new75 SUBDIRS += recompiler_new 76 76 else 77 77 SUBDIRS += recompiler trunk/src/VBox/VMM/REMInternal.h
r12989 r13230 243 243 #endif 244 244 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 245 252 #if GC_ARCH_BITS == 32 246 253 #define REM_ENV_SIZE (HC_ARCH_BITS == 32 ? 0x6550 : 0xb4a0) … … 248 255 #define REM_ENV_SIZE (HC_ARCH_BITS == 32 ? 0x9440 : 0xd4a0) 249 256 #endif 257 #endif // VBOX_WITH_NEW_RECOMILER 250 258 251 259 /** Recompiler CPU state. */ trunk/src/recompiler_new/Makefile.kmk
r13184 r13230 41 41 DLLS += VBoxREM 42 42 IMPORT_LIBS += VBoxREMImp 43 44 DEFS += VBOX_WITH_NEW_RECOMPILER 45 43 46 44 47 OTHER_CLEAN += \ … … 219 222 $(APPEND) $@ '' 220 223 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 225 224 # 226 225 # The math testcase as a standalone program for testing and debugging purposes. trunk/src/recompiler_new/Sun/config.h
r13184 r13230 29 29 #define TARGET_X86_64 30 30 #endif 31 32 #define unlikely(cond) RT_UNLIKELY(cond)trunk/src/recompiler_new/Sun/structs.h
r11982 r13230 230 230 REM_OFFSETOF(CPUState, ft0), 231 231 REM_SIZEOFMEMB(CPUState, ft0), 232 REM_OFFSETOF(CPUState, fp_convert),233 REM_SIZEOFMEMB(CPUState, fp_convert),234 232 REM_OFFSETOF(CPUState, sse_status), 235 233 REM_OFFSETOF(CPUState, mxcsr), … … 266 264 /* cpu-defs.h */ 267 265 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), 270 268 REM_OFFSETOF(CPUState, tlb_table), 271 269 REM_SIZEOFMEMB(CPUState, tlb_table), trunk/src/recompiler_new/VBoxRecompiler.c
r13144 r13230 289 289 * Init the recompiler. 290 290 */ 291 if (!cpu_x86_init(&pVM->rem.s.Env ))291 if (!cpu_x86_init(&pVM->rem.s.Env, "vbox")) 292 292 { 293 293 AssertMsgFailed(("cpu_x86_init failed - impossible!\n")); … … 3806 3806 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HARD); 3807 3807 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); 3809 3810 } 3810 3811 } … … 3841 3842 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT); 3842 3843 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); 3844 3846 } 3845 3847 } … … 3860 3862 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT); 3861 3863 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); 3863 3866 } 3864 3867 } … … 3879 3882 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT); 3880 3883 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); 3882 3886 } 3883 3887 } … … 3898 3902 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT); 3899 3903 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); 3901 3906 } 3902 3907 } trunk/src/recompiler_new/cpu-all.h
r11982 r13230 134 134 #endif 135 135 136 typedef union { 137 float32 f; 138 uint32_t l; 139 } CPU_FloatU; 140 136 141 /* NOTE: arm FPA is horrible as double 32 bit words are stored in big 137 142 endian ! */ … … 152 157 uint64_t ll; 153 158 } CPU_DoubleU; 159 160 #ifdef TARGET_SPARC 161 typedef 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 154 189 155 190 /* CPU memory access without any memory or io remapping */ … … 831 866 code */ 832 867 #define PAGE_WRITE_ORG 0x0010 868 #define PAGE_RESERVED 0x0020 833 869 834 870 void page_dump(FILE *f); 835 871 int page_get_flags(target_ulong address); 836 872 void page_set_flags(target_ulong start, target_ulong end, int flags); 873 int page_check_range(target_ulong start, target_ulong len, int flags); 837 874 void page_unprotect_range(target_ulong data, target_ulong data_size); 838 875 … … 908 945 extern CPUState *first_cpu; 909 946 extern CPUState *cpu_single_env; 910 extern int code_copy_enabled; 947 extern int64_t qemu_icount; 948 extern int use_icount; 911 949 912 950 #define CPU_INTERRUPT_EXIT 0x01 /* wants exit from main loop */ … … 917 955 #define CPU_INTERRUPT_HALT 0x20 /* CPU halt wanted */ 918 956 #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. */ 919 960 920 961 #ifdef VBOX 921 962 /** Executes a single instruction. cpu_exec() will normally return EXCP_SINGLE_INSTR. */ 922 #define CPU_INTERRUPT_SINGLE_INSTR 0x0 200963 #define CPU_INTERRUPT_SINGLE_INSTR 0x0400 923 964 /** Executing a CPU_INTERRUPT_SINGLE_INSTR request, quit the cpu_loop. (for exceptions and suchlike) */ 924 #define CPU_INTERRUPT_SINGLE_INSTR_IN_FLIGHT 0x0 400965 #define CPU_INTERRUPT_SINGLE_INSTR_IN_FLIGHT 0x0800 925 966 /** VM execution was interrupted by VMR3Reset, VMR3Suspend or VMR3PowerOff. */ 926 #define CPU_INTERRUPT_RC 0x 0800967 #define CPU_INTERRUPT_RC 0x1000 927 968 /** Exit current TB to process an external interrupt request (also in op.c!!) */ 928 #define CPU_INTERRUPT_EXTERNAL_EXIT 0x 1000969 #define CPU_INTERRUPT_EXTERNAL_EXIT 0x2000 929 970 /** Exit current TB to process an external interrupt request (also in op.c!!) */ 930 #define CPU_INTERRUPT_EXTERNAL_HARD 0x 2000971 #define CPU_INTERRUPT_EXTERNAL_HARD 0x4000 931 972 /** Exit current TB to process an external interrupt request (also in op.c!!) */ 932 #define CPU_INTERRUPT_EXTERNAL_TIMER 0x 4000973 #define CPU_INTERRUPT_EXTERNAL_TIMER 0x8000 933 974 /** Exit current TB to process an external interrupt request (also in op.c!!) */ 934 #define CPU_INTERRUPT_EXTERNAL_DMA 0x 8000975 #define CPU_INTERRUPT_EXTERNAL_DMA 0x10000 935 976 #endif /* VBOX */ 936 977 void cpu_interrupt(CPUState *s, int mask); 937 978 void cpu_reset_interrupt(CPUState *env, int mask); 938 979 980 int cpu_watchpoint_insert(CPUState *env, target_ulong addr, int type); 981 int cpu_watchpoint_remove(CPUState *env, target_ulong addr); 982 void cpu_watchpoint_remove_all(CPUState *env); 939 983 int cpu_breakpoint_insert(CPUState *env, target_ulong pc); 940 984 int cpu_breakpoint_remove(CPUState *env, target_ulong pc); 985 void 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 941 991 void cpu_single_step(CPUState *env, int enabled); 942 992 void cpu_reset(CPUState *s); … … 981 1031 int cpu_inw(CPUState *env, int addr); 982 1032 int cpu_inl(CPUState *env, int addr); 1033 #endif 1034 1035 /* address in the RAM (different from a physical address) */ 1036 #ifdef USE_KQEMU 1037 typedef uint32_t ram_addr_t; 1038 #else 1039 typedef unsigned long ram_addr_t; 983 1040 #endif 984 1041 … … 1007 1064 #define IO_MEM_ROM (1 << IO_MEM_SHIFT) /* hardcoded offset */ 1008 1065 #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) 1010 1067 #if defined(VBOX) && !defined(VBOX_WITH_NEW_PHYS_CODE) 1011 1068 #define IO_MEM_RAM_MISSING (5 << IO_MEM_SHIFT) /* used internally, never use directly */ … … 1015 1072 the physical address */ 1016 1073 #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) 1017 1086 1018 1087 typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, uint32_t value); … … 1020 1089 1021 1090 void cpu_register_physical_memory(target_phys_addr_t start_addr, 1022 unsigned longsize,1023 unsigned longphys_offset);1091 ram_addr_t size, 1092 ram_addr_t phys_offset); 1024 1093 uint32_t cpu_get_physical_page_desc(target_phys_addr_t addr); 1094 ram_addr_t qemu_ram_alloc(ram_addr_t); 1095 void qemu_ram_free(ram_addr_t addr); 1025 1096 int cpu_register_io_memory(int io_index, 1026 1097 CPUReadMemoryFunc **mem_read, … … 1047 1118 uint64_t ldq_phys(target_phys_addr_t addr); 1048 1119 void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val); 1120 void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val); 1049 1121 void stb_phys(target_phys_addr_t addr, uint32_t val); 1050 1122 void stw_phys(target_phys_addr_t addr, uint32_t val); … … 1059 1131 #define VGA_DIRTY_FLAG 0x01 1060 1132 #define CODE_DIRTY_FLAG 0x02 1133 #define KQEMU_DIRTY_FLAG 0x04 1134 #define MIGRATION_DIRTY_FLAG 0x08 1061 1135 1062 1136 /* read dirty bit (return 0 or 1) */ … … 1104 1178 int dirty_flags); 1105 1179 void cpu_tlb_update_dirty(CPUState *env); 1180 1181 int cpu_physical_memory_set_dirty_tracking(int enable); 1182 1183 int cpu_physical_memory_get_dirty_tracking(void); 1106 1184 1107 1185 void dump_exec_info(FILE *f, trunk/src/recompiler_new/cpu-defs.h
r11982 r13230 54 54 typedef uint32_t target_ulong; 55 55 #define TARGET_FMT_lx "%08x" 56 #define TARGET_FMT_ld "%d" 57 #define TARGET_FMT_lu "%u" 56 58 #elif TARGET_LONG_SIZE == 8 57 59 typedef int64_t target_long; 58 60 typedef uint64_t target_ulong; 59 61 #define TARGET_FMT_lx "%016" PRIx64 62 #define TARGET_FMT_ld "%" PRId64 63 #define TARGET_FMT_lu "%" PRIu64 60 64 #else 61 65 #error TARGET_LONG_SIZE undefined … … 70 74 #if TARGET_PHYS_ADDR_BITS == 32 71 75 typedef uint32_t target_phys_addr_t; 76 #define TARGET_FMT_plx "%08x" 72 77 #elif TARGET_PHYS_ADDR_BITS == 64 73 78 typedef uint64_t target_phys_addr_t; 79 #define TARGET_FMT_plx "%016" PRIx64 74 80 #else 75 81 #error TARGET_PHYS_ADDR_BITS undefined 76 82 #endif 77 78 /* address in the RAM (different from a physical address) */79 typedef unsigned long ram_addr_t;80 83 81 84 #define HOST_LONG_SIZE (HOST_LONG_BITS / 8) … … 92 95 #endif /* VBOX */ 93 96 #define MAX_BREAKPOINTS 32 97 #define MAX_WATCHPOINTS 32 94 98 95 99 #define TB_JMP_CACHE_BITS 12 … … 107 111 #define CPU_TLB_SIZE (1 << CPU_TLB_BITS) 108 112 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 109 119 typedef struct CPUTLBEntry { 110 /* bit 31 to TARGET_PAGE_BITS : virtual address111 bit TARGET_PAGE_BITS-1.. IO_MEM_SHIFT : if non zero, memory io112 zone number120 /* 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. 113 123 bit 3 : indicates that the entry is invalid 114 124 bit 2..0 : zero … … 117 127 target_ulong addr_write; 118 128 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))]; 121 142 } CPUTLBEntry; 143 144 #ifdef WORDS_BIGENDIAN 145 typedef struct icount_decr_u16 { 146 uint16_t high; 147 uint16_t low; 148 } icount_decr_u16; 149 #else 150 typedef 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 159 struct TCGContext; 122 160 123 161 #define CPU_COMMON \ 124 162 struct TranslationBlock *current_tb; /* currently executing TB */ \ 125 163 /* 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 \ 128 166 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]; \ 135 176 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. */ \ 136 189 \ 137 190 /* from this point: preserved by CPU reset */ \ … … 141 194 int singlestep_enabled; \ 142 195 \ 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 \ 143 209 void *next_cpu; /* next CPU sharing TB cache */ \ 144 210 int cpu_index; /* CPU index (informative) */ \ 211 int running; /* Nonzero if cpu is currently running(usermode). */ \ 145 212 /* 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 67 67 #define DISAS_TB_JUMP 3 /* only pc was modified statically */ 68 68 69 structTranslationBlock;69 typedef struct TranslationBlock TranslationBlock; 70 70 71 71 /* 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 73 75 #define OPC_BUF_SIZE 512 74 76 #define OPC_MAX_SIZE (OPC_BUF_SIZE - MAX_OP_PER_INSTR) 75 77 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 82 86 extern target_ulong gen_opc_pc[OPC_BUF_SIZE]; 83 87 extern target_ulong gen_opc_npc[OPC_BUF_SIZE]; 84 88 extern uint8_t gen_opc_cc_op[OPC_BUF_SIZE]; 85 89 extern uint8_t gen_opc_instr_start[OPC_BUF_SIZE]; 90 extern uint16_t gen_opc_icount[OPC_BUF_SIZE]; 86 91 extern target_ulong gen_opc_jump_pc[2]; 87 92 extern uint32_t gen_opc_hflags[OPC_BUF_SIZE]; … … 92 97 typedef void (GenOpFunc3)(long, long, long); 93 98 94 #if defined(TARGET_I386) 95 96 void optimize_flags_init(void); 97 98 #endif 99 99 #ifndef VBOX 100 100 extern FILE *logfile; 101 101 extern 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 104 void gen_intermediate_code(CPUState *env, struct TranslationBlock *tb); 105 void gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb); 106 void gen_pc_load(CPUState *env, struct TranslationBlock *tb, 107 unsigned long searched_pc, int pc_pos, void *puc); 108 109 unsigned long code_gen_max_block_size(void); 110 void cpu_gen_init(void); 106 111 int cpu_gen_code(CPUState *env, struct TranslationBlock *tb, 107 int max_code_size, int*gen_code_size_ptr);112 int *gen_code_size_ptr); 108 113 int cpu_restore_state(struct TranslationBlock *tb, 109 114 CPUState *env, unsigned long searched_pc, 110 115 void *puc); 111 int cpu_gen_code_copy(CPUState *env, struct TranslationBlock *tb,112 int max_code_size, int *gen_code_size_ptr);113 116 int cpu_restore_state_copy(struct TranslationBlock *tb, 114 117 CPUState *env, unsigned long searched_pc, 115 118 void *puc); 116 119 void cpu_resume_from_signal(CPUState *env1, void *puc); 120 void cpu_io_recompile(CPUState *env, void *retaddr); 121 TranslationBlock *tb_gen_code(CPUState *env, 122 target_ulong pc, target_ulong cs_base, int flags, 123 int cflags); 117 124 void cpu_exec_init(CPUState *env); 118 125 int page_unprotect(target_ulong address, unsigned long pc, void *puc); 119 void tb_invalidate_phys_page_range(target_ ulong start, target_ulongend,126 void tb_invalidate_phys_page_range(target_phys_addr_t start, target_phys_addr_t end, 120 127 int is_cpu_write_access); 121 128 void tb_invalidate_page_range(target_ulong start, target_ulong end); … … 124 131 int tlb_set_page_exec(CPUState *env, target_ulong vaddr, 125 132 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); 134 static inline int tlb_set_page(CPUState *env1, target_ulong vaddr, 128 135 target_phys_addr_t paddr, int prot, 129 int is_user, int is_softmmu)136 int mmu_idx, int is_softmmu) 130 137 { 131 138 if (prot & PAGE_READ) 132 139 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 137 143 #define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */ 138 144 … … 140 146 #define CODE_GEN_PHYS_HASH_SIZE (1 << CODE_GEN_PHYS_HASH_BITS) 141 147 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) 166 149 167 150 /* estimated block size for TB allocation */ … … 174 157 #endif 175 158 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__) 179 160 #define USE_DIRECT_JUMP 180 161 #endif … … 182 163 #define USE_DIRECT_JUMP 183 164 #endif 165 184 166 #ifdef VBOX /* bird: not safe in next step because of threading & cpu_interrupt. */ 185 167 #undef USE_DIRECT_JUMP 186 168 #endif /* VBOX */ 187 169 188 typedefstruct TranslationBlock {170 struct TranslationBlock { 189 171 target_ulong pc; /* simulated PC corresponding to this block (EIP + CS base) */ 190 172 target_ulong cs_base; /* CS base for this block */ … … 193 175 size <= TARGET_PAGE_SIZE) */ 194 176 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 199 180 #ifdef VBOX 200 181 #define CF_RAW_MODE 0x0010 /* block was generated in raw mode */ … … 226 207 struct TranslationBlock *jmp_next[2]; 227 208 struct TranslationBlock *jmp_first; 228 } TranslationBlock; 209 uint32_t icount; 210 }; 229 211 230 212 static inline unsigned int tb_jmp_cache_hash_page(target_ulong pc) … … 249 231 250 232 TranslationBlock *tb_alloc(target_ulong pc); 233 void tb_free(TranslationBlock *tb); 251 234 void tb_flush(CPUState *env); 252 235 void tb_link_phys(TranslationBlock *tb, 253 236 target_ulong phys_pc, target_ulong phys_page2); 237 void tb_phys_invalidate(TranslationBlock *tb, target_ulong page_addr); 254 238 255 239 extern TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE]; 256 240 257 extern uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE];258 241 extern uint8_t *code_gen_ptr; 242 extern int code_gen_max_blocks; 259 243 260 244 #if defined(USE_DIRECT_JUMP) … … 342 326 #define ASM_OP_LABEL_NAME(n, opname) \ 343 327 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 #else372 373 /* jump to next block operations (more portable code, does not need374 cache flushing, but slower because of indirect jump) */375 # ifdef VBOX /* bird: GCC4 (and Ming 3.4.x?) will remove the two unused static376 variables. I've added a dummy __asm__ statement which reference377 the two variables to prevent this. */378 # if __GNUC__ >= 4379 # 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 # else390 # 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 # endif400 # 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 #endif413 328 414 329 extern CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4]; … … 583 498 void *retaddr); 584

