Commit 33417e7025afa5ea1c38c3c2b2ea53d975b5648b

Authored by bellard
1 parent 4021dab0

soft mmu support - Memory I/O API - synthetize string instructions


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@354 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-all.h
@@ -140,6 +140,7 @@ static inline void stfl(void *ptr, float v) @@ -140,6 +140,7 @@ static inline void stfl(void *ptr, float v)
140 stl(ptr, u.i); 140 stl(ptr, u.i);
141 } 141 }
142 142
  143 +
143 #if defined(__arm__) && !defined(WORDS_BIGENDIAN) 144 #if defined(__arm__) && !defined(WORDS_BIGENDIAN)
144 145
145 /* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */ 146 /* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */
@@ -317,6 +318,17 @@ int cpu_breakpoint_insert(CPUState *env, uint32_t pc); @@ -317,6 +318,17 @@ int cpu_breakpoint_insert(CPUState *env, uint32_t pc);
317 int cpu_breakpoint_remove(CPUState *env, uint32_t pc); 318 int cpu_breakpoint_remove(CPUState *env, uint32_t pc);
318 void cpu_single_step(CPUState *env, int enabled); 319 void cpu_single_step(CPUState *env, int enabled);
319 320
  321 +/* memory API */
  322 +
  323 +typedef void CPUWriteMemoryFunc(uint32_t addr, uint32_t value);
  324 +typedef uint32_t CPUReadMemoryFunc(uint32_t addr);
  325 +
  326 +void cpu_register_physical_memory(unsigned long start_addr, unsigned long size,
  327 + long phys_offset);
  328 +int cpu_register_io_memory(int io_index,
  329 + CPUReadMemoryFunc **mem_read,
  330 + CPUWriteMemoryFunc **mem_write);
  331 +
320 /* gdb stub API */ 332 /* gdb stub API */
321 extern int gdbstub_fd; 333 extern int gdbstub_fd;
322 CPUState *cpu_gdbstub_get_env(void *opaque); 334 CPUState *cpu_gdbstub_get_env(void *opaque);
cpu-arm.h
@@ -20,12 +20,10 @@ @@ -20,12 +20,10 @@
20 #ifndef CPU_ARM_H 20 #ifndef CPU_ARM_H
21 #define CPU_ARM_H 21 #define CPU_ARM_H
22 22
23 -#include "config.h"  
24 -#include <setjmp.h> 23 +#include "cpu-defs.h"
25 24
26 #define EXCP_UDEF 1 /* undefined instruction */ 25 #define EXCP_UDEF 1 /* undefined instruction */
27 #define EXCP_SWI 2 /* software interrupt */ 26 #define EXCP_SWI 2 /* software interrupt */
28 -#define EXCP_INTERRUPT 256 /* async interruption */  
29 27
30 typedef struct CPUARMState { 28 typedef struct CPUARMState {
31 uint32_t regs[16]; 29 uint32_t regs[16];
cpu-i386.h
@@ -20,8 +20,7 @@ @@ -20,8 +20,7 @@
20 #ifndef CPU_I386_H 20 #ifndef CPU_I386_H
21 #define CPU_I386_H 21 #define CPU_I386_H
22 22
23 -#include "config.h"  
24 -#include <setjmp.h> 23 +#include "cpu-defs.h"
25 24
26 #define R_EAX 0 25 #define R_EAX 0
27 #define R_ECX 1 26 #define R_ECX 1
@@ -153,12 +152,6 @@ @@ -153,12 +152,6 @@
153 #define EXCP11_ALGN 17 152 #define EXCP11_ALGN 17
154 #define EXCP12_MCHK 18 153 #define EXCP12_MCHK 18
155 154
156 -#define EXCP_INTERRUPT 256 /* async interruption */  
157 -#define EXCP_HLT 257 /* hlt instruction reached */  
158 -#define EXCP_DEBUG 258 /* cpu stopped after a breakpoint or singlestep */  
159 -  
160 -#define MAX_BREAKPOINTS 32  
161 -  
162 enum { 155 enum {
163 CC_OP_DYNAMIC, /* must use dynamic code to get cc_op */ 156 CC_OP_DYNAMIC, /* must use dynamic code to get cc_op */
164 CC_OP_EFLAGS, /* all cc are explicitely computed, CC_SRC = flags */ 157 CC_OP_EFLAGS, /* all cc are explicitely computed, CC_SRC = flags */
@@ -257,7 +250,8 @@ typedef struct CPUX86State { @@ -257,7 +250,8 @@ typedef struct CPUX86State {
257 SegmentCache gdt; /* only base and limit are used */ 250 SegmentCache gdt; /* only base and limit are used */
258 SegmentCache idt; /* only base and limit are used */ 251 SegmentCache idt; /* only base and limit are used */
259 int cpl; /* current cpl */ 252 int cpl; /* current cpl */
260 - 253 + int soft_mmu; /* TRUE if soft mmu is being used */
  254 +
261 /* sysenter registers */ 255 /* sysenter registers */
262 uint32_t sysenter_cs; 256 uint32_t sysenter_cs;
263 uint32_t sysenter_esp; 257 uint32_t sysenter_esp;
@@ -275,10 +269,16 @@ typedef struct CPUX86State { @@ -275,10 +269,16 @@ typedef struct CPUX86State {
275 int interrupt_request; 269 int interrupt_request;
276 int user_mode_only; /* user mode only simulation */ 270 int user_mode_only; /* user mode only simulation */
277 271
  272 + /* soft mmu support */
  273 + /* 0 = kernel, 1 = user */
  274 + CPUTLBEntry tlb_read[2][CPU_TLB_SIZE];
  275 + CPUTLBEntry tlb_write[2][CPU_TLB_SIZE];
  276 +
  277 + /* ice debug support */
278 uint32_t breakpoints[MAX_BREAKPOINTS]; 278 uint32_t breakpoints[MAX_BREAKPOINTS];
279 int nb_breakpoints; 279 int nb_breakpoints;
280 int singlestep_enabled; 280 int singlestep_enabled;
281 - 281 +
282 /* user data */ 282 /* user data */
283 void *opaque; 283 void *opaque;
284 } CPUX86State; 284 } CPUX86State;
exec-i386.h
@@ -138,6 +138,7 @@ void cpu_x86_update_cr0(CPUX86State *env); @@ -138,6 +138,7 @@ void cpu_x86_update_cr0(CPUX86State *env);
138 void cpu_x86_update_cr3(CPUX86State *env); 138 void cpu_x86_update_cr3(CPUX86State *env);
139 void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr); 139 void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr);
140 int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write); 140 int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write);
  141 +void tlb_fill(unsigned long addr, int is_write, void *retaddr);
141 void __hidden cpu_lock(void); 142 void __hidden cpu_lock(void);
142 void __hidden cpu_unlock(void); 143 void __hidden cpu_unlock(void);
143 void do_interrupt(int intno, int is_int, int error_code, 144 void do_interrupt(int intno, int is_int, int error_code,
@@ -364,3 +365,52 @@ static inline void load_eflags(int eflags, int update_mask) @@ -364,3 +365,52 @@ static inline void load_eflags(int eflags, int update_mask)
364 env->eflags = (env->eflags & ~update_mask) | 365 env->eflags = (env->eflags & ~update_mask) |
365 (eflags & update_mask); 366 (eflags & update_mask);
366 } 367 }
  368 +
  369 +/* memory access macros */
  370 +
  371 +#define ldul ldl
  372 +#define lduq ldq
  373 +#define ldul_user ldl_user
  374 +#define ldul_kernel ldl_kernel
  375 +
  376 +#define ldub_raw ldub
  377 +#define ldsb_raw ldsb
  378 +#define lduw_raw lduw
  379 +#define ldsw_raw ldsw
  380 +#define ldl_raw ldl
  381 +#define ldq_raw ldq
  382 +
  383 +#define stb_raw stb
  384 +#define stw_raw stw
  385 +#define stl_raw stl
  386 +#define stq_raw stq
  387 +
  388 +#define MEMUSER 0
  389 +#define DATA_SIZE 1
  390 +#include "softmmu_header.h"
  391 +
  392 +#define DATA_SIZE 2
  393 +#include "softmmu_header.h"
  394 +
  395 +#define DATA_SIZE 4
  396 +#include "softmmu_header.h"
  397 +
  398 +#define DATA_SIZE 8
  399 +#include "softmmu_header.h"
  400 +
  401 +#undef MEMUSER
  402 +#define MEMUSER 1
  403 +#define DATA_SIZE 1
  404 +#include "softmmu_header.h"
  405 +
  406 +#define DATA_SIZE 2
  407 +#include "softmmu_header.h"
  408 +
  409 +#define DATA_SIZE 4
  410 +#include "softmmu_header.h"
  411 +
  412 +#define DATA_SIZE 8
  413 +#include "softmmu_header.h"
  414 +
  415 +#undef MEMUSER
  416 +
@@ -68,6 +68,7 @@ typedef struct PageDesc { @@ -68,6 +68,7 @@ typedef struct PageDesc {
68 #define L2_SIZE (1 << L2_BITS) 68 #define L2_SIZE (1 << L2_BITS)
69 69
70 static void tb_invalidate_page(unsigned long address); 70 static void tb_invalidate_page(unsigned long address);
  71 +static void io_mem_init(void);
71 72
72 unsigned long real_host_page_size; 73 unsigned long real_host_page_size;
73 unsigned long host_page_bits; 74 unsigned long host_page_bits;
@@ -76,6 +77,12 @@ unsigned long host_page_mask; @@ -76,6 +77,12 @@ unsigned long host_page_mask;
76 77
77 static PageDesc *l1_map[L1_SIZE]; 78 static PageDesc *l1_map[L1_SIZE];
78 79
  80 +/* io memory support */
  81 +static unsigned long *l1_physmap[L1_SIZE];
  82 +CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
  83 +CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
  84 +static int io_mem_nb;
  85 +
79 static void page_init(void) 86 static void page_init(void)
80 { 87 {
81 /* NOTE: we can always suppose that host_page_size >= 88 /* NOTE: we can always suppose that host_page_size >=
@@ -201,6 +208,7 @@ void cpu_exec_init(void) @@ -201,6 +208,7 @@ void cpu_exec_init(void)
201 if (!code_gen_ptr) { 208 if (!code_gen_ptr) {
202 code_gen_ptr = code_gen_buffer; 209 code_gen_ptr = code_gen_buffer;
203 page_init(); 210 page_init();
  211 + io_mem_init();
204 } 212 }
205 } 213 }
206 214
@@ -744,3 +752,133 @@ void page_unmap(void) @@ -744,3 +752,133 @@ void page_unmap(void)
744 tb_flush(); 752 tb_flush();
745 } 753 }
746 #endif 754 #endif
  755 +
  756 +void tlb_flush(CPUState *env)
  757 +{
  758 +#if defined(TARGET_I386)
  759 + int i;
  760 + for(i = 0; i < CPU_TLB_SIZE; i++) {
  761 + env->tlb_read[0][i].address = -1;
  762 + env->tlb_write[0][i].address = -1;
  763 + env->tlb_read[1][i].address = -1;
  764 + env->tlb_write[1][i].address = -1;
  765 + }
  766 +#endif
  767 +}
  768 +
  769 +void tlb_flush_page(CPUState *env, uint32_t addr)
  770 +{
  771 +#if defined(TARGET_I386)
  772 + int i;
  773 +
  774 + i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  775 + env->tlb_read[0][i].address = -1;
  776 + env->tlb_write[0][i].address = -1;
  777 + env->tlb_read[1][i].address = -1;
  778 + env->tlb_write[1][i].address = -1;
  779 +#endif
  780 +}
  781 +
  782 +static inline unsigned long *physpage_find_alloc(unsigned int page)
  783 +{
  784 + unsigned long **lp, *p;
  785 + unsigned int index, i;
  786 +
  787 + index = page >> TARGET_PAGE_BITS;
  788 + lp = &l1_physmap[index >> L2_BITS];
  789 + p = *lp;
  790 + if (!p) {
  791 + /* allocate if not found */
  792 + p = malloc(sizeof(unsigned long) * L2_SIZE);
  793 + for(i = 0; i < L2_SIZE; i++)
  794 + p[i] = IO_MEM_UNASSIGNED;
  795 + *lp = p;
  796 + }
  797 + return p + (index & (L2_SIZE - 1));
  798 +}
  799 +
  800 +/* return NULL if no page defined (unused memory) */
  801 +unsigned long physpage_find(unsigned long page)
  802 +{
  803 + unsigned long *p;
  804 + unsigned int index;
  805 + index = page >> TARGET_PAGE_BITS;
  806 + p = l1_physmap[index >> L2_BITS];
  807 + if (!p)
  808 + return IO_MEM_UNASSIGNED;
  809 + return p[index & (L2_SIZE - 1)];
  810 +}
  811 +
  812 +/* register physical memory. 'size' must be a multiple of the target
  813 + page size. If (phys_offset & ~TARGET_PAGE_MASK) != 0, then it is an
  814 + io memory page */
  815 +void cpu_register_physical_memory(unsigned long start_addr, unsigned long size,
  816 + long phys_offset)
  817 +{
  818 + unsigned long addr, end_addr;
  819 + unsigned long *p;
  820 +
  821 + end_addr = start_addr + size;
  822 + for(addr = start_addr; addr < end_addr; addr += TARGET_PAGE_SIZE) {
  823 + p = physpage_find_alloc(addr);
  824 + *p = phys_offset;
  825 + if ((phys_offset & ~TARGET_PAGE_MASK) == 0)
  826 + phys_offset += TARGET_PAGE_SIZE;
  827 + }
  828 +}
  829 +
  830 +static uint32_t unassigned_mem_readb(uint32_t addr)
  831 +{
  832 + return 0;
  833 +}
  834 +
  835 +static void unassigned_mem_writeb(uint32_t addr, uint32_t val)
  836 +{
  837 +}
  838 +
  839 +static CPUReadMemoryFunc *unassigned_mem_read[3] = {
  840 + unassigned_mem_readb,
  841 + unassigned_mem_readb,
  842 + unassigned_mem_readb,
  843 +};
  844 +
  845 +static CPUWriteMemoryFunc *unassigned_mem_write[3] = {
  846 + unassigned_mem_writeb,
  847 + unassigned_mem_writeb,
  848 + unassigned_mem_writeb,
  849 +};
  850 +
  851 +
  852 +static void io_mem_init(void)
  853 +{
  854 + io_mem_nb = 1;
  855 + cpu_register_io_memory(0, unassigned_mem_read, unassigned_mem_write);
  856 +}
  857 +
  858 +/* mem_read and mem_write are arrays of functions containing the
  859 + function to access byte (index 0), word (index 1) and dword (index
  860 + 2). All functions must be supplied. If io_index is non zero, the
  861 + corresponding io zone is modified. If it is zero, a new io zone is
  862 + allocated. The return value can be used with
  863 + cpu_register_physical_memory(). (-1) is returned if error. */
  864 +int cpu_register_io_memory(int io_index,
  865 + CPUReadMemoryFunc **mem_read,
  866 + CPUWriteMemoryFunc **mem_write)
  867 +{
  868 + int i;
  869 +
  870 + if (io_index <= 0) {
  871 + if (io_index >= IO_MEM_NB_ENTRIES)
  872 + return -1;
  873 + io_index = io_mem_nb++;
  874 + } else {
  875 + if (io_index >= IO_MEM_NB_ENTRIES)
  876 + return -1;
  877 + }
  878 +
  879 + for(i = 0;i < 3; i++) {
  880 + io_mem_read[io_index][i] = mem_read[i];
  881 + io_mem_write[io_index][i] = mem_write[i];
  882 + }
  883 + return io_index << IO_MEM_SHIFT;
  884 +}
@@ -21,6 +21,17 @@ @@ -21,6 +21,17 @@
21 /* allow to see translation results - the slowdown should be negligible, so we leave it */ 21 /* allow to see translation results - the slowdown should be negligible, so we leave it */
22 #define DEBUG_DISAS 22 #define DEBUG_DISAS
23 23
  24 +#ifndef glue
  25 +#define xglue(x, y) x ## y
  26 +#define glue(x, y) xglue(x, y)
  27 +#define stringify(s) tostring(s)
  28 +#define tostring(s) #s
  29 +#endif
  30 +
  31 +#if GCC_MAJOR < 3
  32 +#define __builtin_expect(x, n) (x)
  33 +#endif
  34 +
24 /* is_jmp field values */ 35 /* is_jmp field values */
25 #define DISAS_NEXT 0 /* next instruction can be analyzed */ 36 #define DISAS_NEXT 0 /* next instruction can be analyzed */
26 #define DISAS_JUMP 1 /* only pc was modified dynamically */ 37 #define DISAS_JUMP 1 /* only pc was modified dynamically */
@@ -44,14 +55,17 @@ extern uint8_t gen_opc_instr_start[OPC_BUF_SIZE]; @@ -44,14 +55,17 @@ extern uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
44 55
45 #if defined(TARGET_I386) 56 #if defined(TARGET_I386)
46 57
47 -#define GEN_FLAG_CODE32_SHIFT 0  
48 -#define GEN_FLAG_ADDSEG_SHIFT 1  
49 -#define GEN_FLAG_SS32_SHIFT 2  
50 -#define GEN_FLAG_VM_SHIFT 3  
51 -#define GEN_FLAG_ST_SHIFT 4  
52 -#define GEN_FLAG_TF_SHIFT 8 /* same position as eflags */  
53 -#define GEN_FLAG_CPL_SHIFT 9  
54 -#define GEN_FLAG_IOPL_SHIFT 12 /* same position as eflags */ 58 +#define GEN_FLAG_CODE32_SHIFT 0
  59 +#define GEN_FLAG_ADDSEG_SHIFT 1
  60 +#define GEN_FLAG_SS32_SHIFT 2
  61 +#define GEN_FLAG_VM_SHIFT 3
  62 +#define GEN_FLAG_ST_SHIFT 4
  63 +#define GEN_FLAG_TF_SHIFT 8 /* same position as eflags */
  64 +#define GEN_FLAG_CPL_SHIFT 9
  65 +#define GEN_FLAG_SOFT_MMU_SHIFT 11
  66 +#define GEN_FLAG_IOPL_SHIFT 12 /* same position as eflags */
  67 +
  68 +void optimize_flags_init(void);
55 69
56 #endif 70 #endif
57 71
@@ -68,6 +82,8 @@ int cpu_restore_state(struct TranslationBlock *tb, @@ -68,6 +82,8 @@ int cpu_restore_state(struct TranslationBlock *tb,
68 void cpu_exec_init(void); 82 void cpu_exec_init(void);
69 int page_unprotect(unsigned long address); 83 int page_unprotect(unsigned long address);
70 void page_unmap(void); 84 void page_unmap(void);
  85 +void tlb_flush_page(CPUState *env, uint32_t addr);
  86 +void tlb_flush(CPUState *env);
71 87
72 #define CODE_GEN_MAX_SIZE 65536 88 #define CODE_GEN_MAX_SIZE 65536
73 #define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */ 89 #define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */
@@ -230,6 +246,17 @@ dummy_label ## n:\ @@ -230,6 +246,17 @@ dummy_label ## n:\
230 246
231 #endif 247 #endif
232 248
  249 +/* physical memory access */
  250 +#define IO_MEM_NB_ENTRIES 256
  251 +#define TLB_INVALID_MASK (1 << 3)
  252 +#define IO_MEM_SHIFT 4
  253 +#define IO_MEM_UNASSIGNED (1 << IO_MEM_SHIFT)
  254 +
  255 +unsigned long physpage_find(unsigned long page);
  256 +
  257 +extern CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
  258 +extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
  259 +
233 #ifdef __powerpc__ 260 #ifdef __powerpc__
234 static inline int testandset (int *p) 261 static inline int testandset (int *p)
235 { 262 {
helper-i386.c
@@ -781,7 +781,7 @@ void helper_lcall_real_T0_T1(int shift, int next_eip) @@ -781,7 +781,7 @@ void helper_lcall_real_T0_T1(int shift, int next_eip)
781 int new_cs, new_eip; 781 int new_cs, new_eip;
782 uint32_t esp, esp_mask; 782 uint32_t esp, esp_mask;
783 uint8_t *ssp; 783 uint8_t *ssp;
784 - 784 +
785 new_cs = T0; 785 new_cs = T0;
786 new_eip = T1; 786 new_eip = T1;
787 esp = env->regs[R_ESP]; 787 esp = env->regs[R_ESP];
@@ -1741,3 +1741,34 @@ void helper_frstor(uint8_t *ptr, int data32) @@ -1741,3 +1741,34 @@ void helper_frstor(uint8_t *ptr, int data32)
1741 } 1741 }
1742 } 1742 }
1743 1743
  1744 +#define SHIFT 0
  1745 +#include "softmmu_template.h"
  1746 +
  1747 +#define SHIFT 1
  1748 +#include "softmmu_template.h"
  1749 +
  1750 +#define SHIFT 2
  1751 +#include "softmmu_template.h"
  1752 +
  1753 +#define SHIFT 3
  1754 +#include "softmmu_template.h"
  1755 +
  1756 +/* try to fill the TLB and return an exception if error */
  1757 +void tlb_fill(unsigned long addr, int is_write, void *retaddr)
  1758 +{
  1759 + TranslationBlock *tb;
  1760 + int ret;
  1761 + unsigned long pc;
  1762 + ret = cpu_x86_handle_mmu_fault(env, addr, is_write);
  1763 + if (ret) {
  1764 + /* now we have a real cpu fault */
  1765 + pc = (unsigned long)retaddr;
  1766 + tb = tb_find_pc(pc);
  1767 + if (tb) {
  1768 + /* the PC is inside the translated code. It means that we have
  1769 + a virtual CPU fault */
  1770 + cpu_restore_state(tb, env, pc);
  1771 + }
  1772 + raise_exception_err(EXCP0E_PAGE, env->error_code);
  1773 + }
  1774 +}
op-i386.c
@@ -376,70 +376,14 @@ void OPPROTO op_andl_A0_ffff(void) @@ -376,70 +376,14 @@ void OPPROTO op_andl_A0_ffff(void)
376 376
377 /* memory access */ 377 /* memory access */
378 378
379 -void OPPROTO op_ldub_T0_A0(void)  
380 -{  
381 - T0 = ldub((uint8_t *)A0);  
382 -}  
383 -  
384 -void OPPROTO op_ldsb_T0_A0(void)  
385 -{  
386 - T0 = ldsb((int8_t *)A0);  
387 -}  
388 -  
389 -void OPPROTO op_lduw_T0_A0(void)  
390 -{  
391 - T0 = lduw((uint8_t *)A0);  
392 -}  
393 -  
394 -void OPPROTO op_ldsw_T0_A0(void)  
395 -{  
396 - T0 = ldsw((int8_t *)A0);  
397 -}  
398 -  
399 -void OPPROTO op_ldl_T0_A0(void)  
400 -{  
401 - T0 = ldl((uint8_t *)A0);  
402 -} 379 +#define MEMSUFFIX
  380 +#include "ops_mem.h"
403 381
404 -void OPPROTO op_ldub_T1_A0(void)  
405 -{  
406 - T1 = ldub((uint8_t *)A0);  
407 -}  
408 -  
409 -void OPPROTO op_ldsb_T1_A0(void)  
410 -{  
411 - T1 = ldsb((int8_t *)A0);  
412 -}  
413 -  
414 -void OPPROTO op_lduw_T1_A0(void)  
415 -{  
416 - T1 = lduw((uint8_t *)A0);  
417 -} 382 +#define MEMSUFFIX _user
  383 +#include "ops_mem.h"
418 384
419 -void OPPROTO op_ldsw_T1_A0(void)  
420 -{  
421 - T1 = ldsw((int8_t *)A0);  
422 -}  
423 -  
424 -void OPPROTO op_ldl_T1_A0(void)  
425 -{  
426 - T1 = ldl((uint8_t *)A0);  
427 -}  
428 -  
429 -void OPPROTO op_stb_T0_A0(void)  
430 -{  
431 - stb((uint8_t *)A0, T0);  
432 -}  
433 -  
434 -void OPPROTO op_stw_T0_A0(void)  
435 -{  
436 - stw((uint8_t *)A0, T0);  
437 -}  
438 -  
439 -void OPPROTO op_stl_T0_A0(void)  
440 -{  
441 - stl((uint8_t *)A0, T0);  
442 -} 385 +#define MEMSUFFIX _kernel
  386 +#include "ops_mem.h"
443 387
444 /* used for bit operations */ 388 /* used for bit operations */
445 389
@@ -635,6 +579,38 @@ void OPPROTO op_movswl_DX_AX(void) @@ -635,6 +579,38 @@ void OPPROTO op_movswl_DX_AX(void)
635 EDX = (EDX & 0xffff0000) | (((int16_t)EAX >> 15) & 0xffff); 579 EDX = (EDX & 0xffff0000) | (((int16_t)EAX >> 15) & 0xffff);
636 } 580 }
637 581
  582 +/* string ops helpers */
  583 +
  584 +void OPPROTO op_addl_ESI_T0(void)
  585 +{
  586 + ESI += T0;
  587 +}
  588 +
  589 +void OPPROTO op_addw_ESI_T0(void)
  590 +{
  591 + ESI = (ESI & ~0xffff) | ((ESI + T0) & 0xffff);
  592 +}
  593 +
  594 +void OPPROTO op_addl_EDI_T0(void)
  595 +{
  596 + EDI += T0;
  597 +}
  598 +
  599 +void OPPROTO op_addw_EDI_T0(void)
  600 +{
  601 + EDI = (EDI & ~0xffff) | ((EDI + T0) & 0xffff);
  602 +}
  603 +
  604 +void OPPROTO op_decl_ECX(void)
  605 +{
  606 + ECX--;
  607 +}
  608 +
  609 +void OPPROTO op_decw_ECX(void)
  610 +{
  611 + ECX = (ECX & ~0xffff) | ((ECX - 1) & 0xffff);
  612 +}
  613 +
638 /* push/pop */ 614 /* push/pop */
639 615
640 void op_pushl_T0(void) 616 void op_pushl_T0(void)
op_string.h
1 1
2 -void OPPROTO glue(glue(op_movs, SUFFIX), STRING_SUFFIX)(void)  
3 -{  
4 - int v, inc;  
5 - v = glue(ldu, SUFFIX)(SI_ADDR);  
6 - glue(st, SUFFIX)(DI_ADDR, v);  
7 - inc = (DF << SHIFT);  
8 - INC_SI();  
9 - INC_DI();  
10 -}  
11 -  
12 -void OPPROTO glue(glue(op_rep_movs, SUFFIX), STRING_SUFFIX)(void)  
13 -{  
14 - int v, inc;  
15 - inc = (DF << SHIFT);  
16 - while (CX != 0) {  
17 - v = glue(ldu, SUFFIX)(SI_ADDR);  
18 - glue(st, SUFFIX)(DI_ADDR, v);  
19 - INC_SI();  
20 - INC_DI();  
21 - DEC_CX();  
22 - }  
23 - FORCE_RET();  
24 -}  
25 -  
26 -void OPPROTO glue(glue(op_stos, SUFFIX), STRING_SUFFIX)(void)  
27 -{  
28 - int inc;  
29 - glue(st, SUFFIX)(DI_ADDR, EAX);  
30 - inc = (DF << SHIFT);  
31 - INC_DI();  
32 -}  
33 -  
34 -void OPPROTO glue(glue(op_rep_stos, SUFFIX), STRING_SUFFIX)(void)  
35 -{  
36 - int inc;  
37 - inc = (DF << SHIFT);  
38 - while (CX != 0) {  
39 - glue(st, SUFFIX)(DI_ADDR, EAX);  
40 - INC_DI();  
41 - DEC_CX();  
42 - }  
43 - FORCE_RET();  
44 -}  
45 -  
46 -void OPPROTO glue(glue(op_lods, SUFFIX), STRING_SUFFIX)(void)  
47 -{  
48 - int v, inc;  
49 - v = glue(ldu, SUFFIX)(SI_ADDR);  
50 -#if SHIFT == 0  
51 - EAX = (EAX & ~0xff) | v;  
52 -#elif SHIFT == 1  
53 - EAX = (EAX & ~0xffff) | v;  
54 -#else  
55 - EAX = v;  
56 -#endif  
57 - inc = (DF << SHIFT);  
58 - INC_SI();  
59 -}  
60 -  
61 -/* don't know if it is used */  
62 -void OPPROTO glue(glue(op_rep_lods, SUFFIX), STRING_SUFFIX)(void)  
63 -{  
64 - int v, inc;  
65 - inc = (DF << SHIFT);  
66 - while (CX != 0) {  
67 - v = glue(ldu, SUFFIX)(SI_ADDR);  
68 -#if SHIFT == 0  
69 - EAX = (EAX & ~0xff) | v;  
70 -#elif SHIFT == 1  
71 - EAX = (EAX & ~0xffff) | v;  
72 -#else  
73 - EAX = v;  
74 -#endif  
75 - INC_SI();  
76 - DEC_CX();  
77 - }  
78 - FORCE_RET();  
79 -}  
80 -  
81 -void OPPROTO glue(glue(op_scas, SUFFIX), STRING_SUFFIX)(void)  
82 -{  
83 - int v, inc;  
84 -  
85 - v = glue(ldu, SUFFIX)(DI_ADDR);  
86 - inc = (DF << SHIFT);  
87 - INC_DI();  
88 - CC_SRC = v;  
89 - CC_DST = EAX - v;  
90 -}  
91 -  
92 void OPPROTO glue(glue(op_repz_scas, SUFFIX), STRING_SUFFIX)(void) 2 void OPPROTO glue(glue(op_repz_scas, SUFFIX), STRING_SUFFIX)(void)
93 { 3 {
94 int v1, v2, inc; 4 int v1, v2, inc;
@@ -133,18 +43,6 @@ void OPPROTO glue(glue(op_repnz_scas, SUFFIX), STRING_SUFFIX)(void) @@ -133,18 +43,6 @@ void OPPROTO glue(glue(op_repnz_scas, SUFFIX), STRING_SUFFIX)(void)
133 FORCE_RET(); 43 FORCE_RET();
134 } 44 }
135 45
136 -void OPPROTO glue(glue(op_cmps, SUFFIX), STRING_SUFFIX)(void)  
137 -{  
138 - int v1, v2, inc;  
139 - v1 = glue(ldu, SUFFIX)(SI_ADDR);  
140 - v2 = glue(ldu, SUFFIX)(DI_ADDR);  
141 - inc = (DF << SHIFT);  
142 - INC_SI();  
143 - INC_DI();  
144 - CC_SRC = v2;  
145 - CC_DST = v1 - v2;  
146 -}  
147 -  
148 void OPPROTO glue(glue(op_repz_cmps, SUFFIX), STRING_SUFFIX)(void) 46 void OPPROTO glue(glue(op_repz_cmps, SUFFIX), STRING_SUFFIX)(void)
149 { 47 {
150 int v1, v2, inc; 48 int v1, v2, inc;
@@ -187,54 +85,6 @@ void OPPROTO glue(glue(op_repnz_cmps, SUFFIX), STRING_SUFFIX)(void) @@ -187,54 +85,6 @@ void OPPROTO glue(glue(op_repnz_cmps, SUFFIX), STRING_SUFFIX)(void)
187 FORCE_RET(); 85 FORCE_RET();
188 } 86 }
189 87
190 -void OPPROTO glue(glue(op_outs, SUFFIX), STRING_SUFFIX)(void)  
191 -{  
192 - int v, dx, inc;  
193 - dx = EDX & 0xffff;  
194 - v = glue(ldu, SUFFIX)(SI_ADDR);  
195 - glue(cpu_x86_out, SUFFIX)(env, dx, v);  
196 - inc = (DF << SHIFT);  
197 - INC_SI();  
198 -}  
199 -  
200 -void OPPROTO glue(glue(op_rep_outs, SUFFIX), STRING_SUFFIX)(void)  
201 -{  
202 - int v, dx, inc;  
203 - inc = (DF << SHIFT);  
204 - dx = EDX & 0xffff;  
205 - while (CX != 0) {  
206 - v = glue(ldu, SUFFIX)(SI_ADDR);  
207 - glue(cpu_x86_out, SUFFIX)(env, dx, v);  
208 - INC_SI();  
209 - DEC_CX();  
210 - }  
211 - FORCE_RET();  
212 -}  
213 -  
214 -void OPPROTO glue(glue(op_ins, SUFFIX), STRING_SUFFIX)(void)  
215 -{  
216 - int v, dx, inc;  
217 - dx = EDX & 0xffff;  
218 - v = glue(cpu_x86_in, SUFFIX)(env, dx);  
219 - glue(st, SUFFIX)(DI_ADDR, v);  
220 - inc = (DF << SHIFT);  
221 - INC_DI();  
222 -}  
223 -  
224 -void OPPROTO glue(glue(op_rep_ins, SUFFIX), STRING_SUFFIX)(void)  
225 -{  
226 - int v, dx, inc;  
227 - inc = (DF << SHIFT);  
228 - dx = EDX & 0xffff;  
229 - while (CX != 0) {  
230 - v = glue(cpu_x86_in, SUFFIX)(env, dx);  
231 - glue(st, SUFFIX)(DI_ADDR, v);  
232 - INC_DI();  
233 - DEC_CX();  
234 - }  
235 - FORCE_RET();  
236 -}  
237 -  
238 #undef STRING_SUFFIX 88 #undef STRING_SUFFIX
239 #undef SI_ADDR 89 #undef SI_ADDR
240 #undef DI_ADDR 90 #undef DI_ADDR
ops_template.h
@@ -547,6 +547,31 @@ void OPPROTO op_update_bt_cc(void) @@ -547,6 +547,31 @@ void OPPROTO op_update_bt_cc(void)
547 #define DEC_CX() ECX = (ECX & ~0xffff) | ((ECX - 1) & 0xffff) 547 #define DEC_CX() ECX = (ECX & ~0xffff) | ((ECX - 1) & 0xffff)
548 #include "op_string.h" 548 #include "op_string.h"
549 549
  550 +void OPPROTO glue(op_movl_T0_Dshift, SUFFIX)(void)
  551 +{
  552 + T0 = DF << SHIFT;
  553 +}
  554 +
  555 +void OPPROTO glue(op_string_jz_sub, SUFFIX)(void)
  556 +{
  557 + if ((DATA_TYPE)CC_DST == 0)
  558 + JUMP_TB(PARAM1, 1, PARAM2);
  559 +}
  560 +
  561 +void OPPROTO glue(op_string_jnz_sub, SUFFIX)(void)
  562 +{
  563 + if ((DATA_TYPE)CC_DST != 0)
  564 + JUMP_TB(PARAM1, 1, PARAM2);
  565 +}
  566 +
  567 +#if DATA_BITS >= 16
  568 +void OPPROTO glue(op_jz_ecx, SUFFIX)(void)
  569 +{
  570 + if ((DATA_TYPE)ECX == 0)
  571 + JUMP_TB(PARAM1, 1, PARAM2);
  572 +}
  573 +#endif
  574 +
550 /* port I/O */ 575 /* port I/O */
551 576
552 void OPPROTO glue(glue(op_out, SUFFIX), _T0_T1)(void) 577 void OPPROTO glue(glue(op_out, SUFFIX), _T0_T1)(void)
@@ -559,6 +584,16 @@ void OPPROTO glue(glue(op_in, SUFFIX), _T0_T1)(void) @@ -559,6 +584,16 @@ void OPPROTO glue(glue(op_in, SUFFIX), _T0_T1)(void)
559 T1 = glue(cpu_x86_in, SUFFIX)(env, T0 & 0xffff); 584 T1 = glue(cpu_x86_in, SUFFIX)(env, T0 & 0xffff);
560 } 585 }
561 586
  587 +void OPPROTO glue(glue(op_in, SUFFIX), _DX_T0)(void)
  588 +{
  589 + T0 = glue(cpu_x86_in, SUFFIX)(env, EDX & 0xffff);
  590 +}
  591 +
  592 +void OPPROTO glue(glue(op_out, SUFFIX), _DX_T0)(void)
  593 +{
  594 + glue(cpu_x86_out, SUFFIX)(env, EDX & 0xffff, T0);
  595 +}
  596 +
562 #undef DATA_BITS 597 #undef DATA_BITS
563 #undef SHIFT_MASK 598 #undef SHIFT_MASK
564 #undef SIGN_MASK 599 #undef SIGN_MASK