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
This commit is contained in:
		
							parent
							
								
									4021dab059
								
							
						
					
					
						commit
						33417e7025
					
				
							
								
								
									
										12
									
								
								cpu-all.h
								
								
								
								
							
							
						
						
									
										12
									
								
								cpu-all.h
								
								
								
								
							| 
						 | 
					@ -140,6 +140,7 @@ static inline void stfl(void *ptr, float v)
 | 
				
			||||||
    stl(ptr, u.i);
 | 
					    stl(ptr, u.i);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(__arm__) && !defined(WORDS_BIGENDIAN)
 | 
					#if defined(__arm__) && !defined(WORDS_BIGENDIAN)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */
 | 
					/* 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);
 | 
				
			||||||
int cpu_breakpoint_remove(CPUState *env, uint32_t pc);
 | 
					int cpu_breakpoint_remove(CPUState *env, uint32_t pc);
 | 
				
			||||||
void cpu_single_step(CPUState *env, int enabled);
 | 
					void cpu_single_step(CPUState *env, int enabled);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* memory API */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef void CPUWriteMemoryFunc(uint32_t addr, uint32_t value);
 | 
				
			||||||
 | 
					typedef uint32_t CPUReadMemoryFunc(uint32_t addr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void cpu_register_physical_memory(unsigned long start_addr, unsigned long size,
 | 
				
			||||||
 | 
					                                  long phys_offset);
 | 
				
			||||||
 | 
					int cpu_register_io_memory(int io_index,
 | 
				
			||||||
 | 
					                           CPUReadMemoryFunc **mem_read,
 | 
				
			||||||
 | 
					                           CPUWriteMemoryFunc **mem_write);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* gdb stub API */
 | 
					/* gdb stub API */
 | 
				
			||||||
extern int gdbstub_fd;
 | 
					extern int gdbstub_fd;
 | 
				
			||||||
CPUState *cpu_gdbstub_get_env(void *opaque);
 | 
					CPUState *cpu_gdbstub_get_env(void *opaque);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,12 +20,10 @@
 | 
				
			||||||
#ifndef CPU_ARM_H
 | 
					#ifndef CPU_ARM_H
 | 
				
			||||||
#define CPU_ARM_H
 | 
					#define CPU_ARM_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "config.h"
 | 
					#include "cpu-defs.h"
 | 
				
			||||||
#include <setjmp.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define EXCP_UDEF       1   /* undefined instruction */
 | 
					#define EXCP_UDEF       1   /* undefined instruction */
 | 
				
			||||||
#define EXCP_SWI        2   /* software interrupt */
 | 
					#define EXCP_SWI        2   /* software interrupt */
 | 
				
			||||||
#define EXCP_INTERRUPT 	256 /* async interruption */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct CPUARMState {
 | 
					typedef struct CPUARMState {
 | 
				
			||||||
    uint32_t regs[16];
 | 
					    uint32_t regs[16];
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										16
									
								
								cpu-i386.h
								
								
								
								
							
							
						
						
									
										16
									
								
								cpu-i386.h
								
								
								
								
							| 
						 | 
					@ -20,8 +20,7 @@
 | 
				
			||||||
#ifndef CPU_I386_H
 | 
					#ifndef CPU_I386_H
 | 
				
			||||||
#define CPU_I386_H
 | 
					#define CPU_I386_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "config.h"
 | 
					#include "cpu-defs.h"
 | 
				
			||||||
#include <setjmp.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define R_EAX 0
 | 
					#define R_EAX 0
 | 
				
			||||||
#define R_ECX 1
 | 
					#define R_ECX 1
 | 
				
			||||||
| 
						 | 
					@ -153,12 +152,6 @@
 | 
				
			||||||
#define EXCP11_ALGN	17
 | 
					#define EXCP11_ALGN	17
 | 
				
			||||||
#define EXCP12_MCHK	18
 | 
					#define EXCP12_MCHK	18
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define EXCP_INTERRUPT 	256 /* async interruption */
 | 
					 | 
				
			||||||
#define EXCP_HLT        257 /* hlt instruction reached */
 | 
					 | 
				
			||||||
#define EXCP_DEBUG      258 /* cpu stopped after a breakpoint or singlestep */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define MAX_BREAKPOINTS 32
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum {
 | 
					enum {
 | 
				
			||||||
    CC_OP_DYNAMIC, /* must use dynamic code to get cc_op */
 | 
					    CC_OP_DYNAMIC, /* must use dynamic code to get cc_op */
 | 
				
			||||||
    CC_OP_EFLAGS,  /* all cc are explicitely computed, CC_SRC = flags */
 | 
					    CC_OP_EFLAGS,  /* all cc are explicitely computed, CC_SRC = flags */
 | 
				
			||||||
| 
						 | 
					@ -257,6 +250,7 @@ typedef struct CPUX86State {
 | 
				
			||||||
    SegmentCache gdt; /* only base and limit are used */
 | 
					    SegmentCache gdt; /* only base and limit are used */
 | 
				
			||||||
    SegmentCache idt; /* only base and limit are used */
 | 
					    SegmentCache idt; /* only base and limit are used */
 | 
				
			||||||
    int cpl;          /* current cpl */
 | 
					    int cpl;          /* current cpl */
 | 
				
			||||||
 | 
					    int soft_mmu;     /* TRUE if soft mmu is being used */
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    /* sysenter registers */
 | 
					    /* sysenter registers */
 | 
				
			||||||
    uint32_t sysenter_cs;
 | 
					    uint32_t sysenter_cs;
 | 
				
			||||||
| 
						 | 
					@ -275,6 +269,12 @@ typedef struct CPUX86State {
 | 
				
			||||||
    int interrupt_request; 
 | 
					    int interrupt_request; 
 | 
				
			||||||
    int user_mode_only; /* user mode only simulation */
 | 
					    int user_mode_only; /* user mode only simulation */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* soft mmu support */
 | 
				
			||||||
 | 
					    /* 0 = kernel, 1 = user */
 | 
				
			||||||
 | 
					    CPUTLBEntry tlb_read[2][CPU_TLB_SIZE];
 | 
				
			||||||
 | 
					    CPUTLBEntry tlb_write[2][CPU_TLB_SIZE];
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /* ice debug support */
 | 
				
			||||||
    uint32_t breakpoints[MAX_BREAKPOINTS];
 | 
					    uint32_t breakpoints[MAX_BREAKPOINTS];
 | 
				
			||||||
    int nb_breakpoints;
 | 
					    int nb_breakpoints;
 | 
				
			||||||
    int singlestep_enabled;
 | 
					    int singlestep_enabled;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										50
									
								
								exec-i386.h
								
								
								
								
							
							
						
						
									
										50
									
								
								exec-i386.h
								
								
								
								
							| 
						 | 
					@ -138,6 +138,7 @@ void cpu_x86_update_cr0(CPUX86State *env);
 | 
				
			||||||
void cpu_x86_update_cr3(CPUX86State *env);
 | 
					void cpu_x86_update_cr3(CPUX86State *env);
 | 
				
			||||||
void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr);
 | 
					void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr);
 | 
				
			||||||
int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write);
 | 
					int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write);
 | 
				
			||||||
 | 
					void tlb_fill(unsigned long addr, int is_write, void *retaddr);
 | 
				
			||||||
void __hidden cpu_lock(void);
 | 
					void __hidden cpu_lock(void);
 | 
				
			||||||
void __hidden cpu_unlock(void);
 | 
					void __hidden cpu_unlock(void);
 | 
				
			||||||
void do_interrupt(int intno, int is_int, int error_code, 
 | 
					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)
 | 
				
			||||||
    env->eflags = (env->eflags & ~update_mask) | 
 | 
					    env->eflags = (env->eflags & ~update_mask) | 
 | 
				
			||||||
        (eflags & update_mask);
 | 
					        (eflags & update_mask);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* memory access macros */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ldul ldl
 | 
				
			||||||
 | 
					#define lduq ldq
 | 
				
			||||||
 | 
					#define ldul_user ldl_user
 | 
				
			||||||
 | 
					#define ldul_kernel ldl_kernel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ldub_raw ldub
 | 
				
			||||||
 | 
					#define ldsb_raw ldsb
 | 
				
			||||||
 | 
					#define lduw_raw lduw
 | 
				
			||||||
 | 
					#define ldsw_raw ldsw
 | 
				
			||||||
 | 
					#define ldl_raw ldl
 | 
				
			||||||
 | 
					#define ldq_raw ldq
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define stb_raw stb
 | 
				
			||||||
 | 
					#define stw_raw stw
 | 
				
			||||||
 | 
					#define stl_raw stl
 | 
				
			||||||
 | 
					#define stq_raw stq
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MEMUSER 0
 | 
				
			||||||
 | 
					#define DATA_SIZE 1
 | 
				
			||||||
 | 
					#include "softmmu_header.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DATA_SIZE 2
 | 
				
			||||||
 | 
					#include "softmmu_header.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DATA_SIZE 4
 | 
				
			||||||
 | 
					#include "softmmu_header.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DATA_SIZE 8
 | 
				
			||||||
 | 
					#include "softmmu_header.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#undef MEMUSER
 | 
				
			||||||
 | 
					#define MEMUSER 1
 | 
				
			||||||
 | 
					#define DATA_SIZE 1
 | 
				
			||||||
 | 
					#include "softmmu_header.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DATA_SIZE 2
 | 
				
			||||||
 | 
					#include "softmmu_header.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DATA_SIZE 4
 | 
				
			||||||
 | 
					#include "softmmu_header.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DATA_SIZE 8
 | 
				
			||||||
 | 
					#include "softmmu_header.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#undef MEMUSER
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										138
									
								
								exec.c
								
								
								
								
							
							
						
						
									
										138
									
								
								exec.c
								
								
								
								
							| 
						 | 
					@ -68,6 +68,7 @@ typedef struct PageDesc {
 | 
				
			||||||
#define L2_SIZE (1 << L2_BITS)
 | 
					#define L2_SIZE (1 << L2_BITS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void tb_invalidate_page(unsigned long address);
 | 
					static void tb_invalidate_page(unsigned long address);
 | 
				
			||||||
 | 
					static void io_mem_init(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned long real_host_page_size;
 | 
					unsigned long real_host_page_size;
 | 
				
			||||||
unsigned long host_page_bits;
 | 
					unsigned long host_page_bits;
 | 
				
			||||||
| 
						 | 
					@ -76,6 +77,12 @@ unsigned long host_page_mask;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PageDesc *l1_map[L1_SIZE];
 | 
					static PageDesc *l1_map[L1_SIZE];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* io memory support */
 | 
				
			||||||
 | 
					static unsigned long *l1_physmap[L1_SIZE];
 | 
				
			||||||
 | 
					CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
 | 
				
			||||||
 | 
					CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
 | 
				
			||||||
 | 
					static int io_mem_nb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void page_init(void)
 | 
					static void page_init(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /* NOTE: we can always suppose that host_page_size >=
 | 
					    /* NOTE: we can always suppose that host_page_size >=
 | 
				
			||||||
| 
						 | 
					@ -201,6 +208,7 @@ void cpu_exec_init(void)
 | 
				
			||||||
    if (!code_gen_ptr) {
 | 
					    if (!code_gen_ptr) {
 | 
				
			||||||
        code_gen_ptr = code_gen_buffer;
 | 
					        code_gen_ptr = code_gen_buffer;
 | 
				
			||||||
        page_init();
 | 
					        page_init();
 | 
				
			||||||
 | 
					        io_mem_init();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -744,3 +752,133 @@ void page_unmap(void)
 | 
				
			||||||
    tb_flush();
 | 
					    tb_flush();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void tlb_flush(CPUState *env)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if defined(TARGET_I386)
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    for(i = 0; i < CPU_TLB_SIZE; i++) {
 | 
				
			||||||
 | 
					        env->tlb_read[0][i].address = -1;
 | 
				
			||||||
 | 
					        env->tlb_write[0][i].address = -1;
 | 
				
			||||||
 | 
					        env->tlb_read[1][i].address = -1;
 | 
				
			||||||
 | 
					        env->tlb_write[1][i].address = -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void tlb_flush_page(CPUState *env, uint32_t addr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if defined(TARGET_I386)
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
 | 
				
			||||||
 | 
					    env->tlb_read[0][i].address = -1;
 | 
				
			||||||
 | 
					    env->tlb_write[0][i].address = -1;
 | 
				
			||||||
 | 
					    env->tlb_read[1][i].address = -1;
 | 
				
			||||||
 | 
					    env->tlb_write[1][i].address = -1;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline unsigned long *physpage_find_alloc(unsigned int page)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    unsigned long **lp, *p;
 | 
				
			||||||
 | 
					    unsigned int index, i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    index = page >> TARGET_PAGE_BITS;
 | 
				
			||||||
 | 
					    lp = &l1_physmap[index >> L2_BITS];
 | 
				
			||||||
 | 
					    p = *lp;
 | 
				
			||||||
 | 
					    if (!p) {
 | 
				
			||||||
 | 
					        /* allocate if not found */
 | 
				
			||||||
 | 
					        p = malloc(sizeof(unsigned long) * L2_SIZE);
 | 
				
			||||||
 | 
					        for(i = 0; i < L2_SIZE; i++)
 | 
				
			||||||
 | 
					            p[i] = IO_MEM_UNASSIGNED;
 | 
				
			||||||
 | 
					        *lp = p;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return p + (index & (L2_SIZE - 1));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* return NULL if no page defined (unused memory) */
 | 
				
			||||||
 | 
					unsigned long physpage_find(unsigned long page)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    unsigned long *p;
 | 
				
			||||||
 | 
					    unsigned int index;
 | 
				
			||||||
 | 
					    index = page >> TARGET_PAGE_BITS;
 | 
				
			||||||
 | 
					    p = l1_physmap[index >> L2_BITS];
 | 
				
			||||||
 | 
					    if (!p)
 | 
				
			||||||
 | 
					        return IO_MEM_UNASSIGNED;
 | 
				
			||||||
 | 
					    return p[index & (L2_SIZE - 1)];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* register physical memory. 'size' must be a multiple of the target
 | 
				
			||||||
 | 
					   page size. If (phys_offset & ~TARGET_PAGE_MASK) != 0, then it is an
 | 
				
			||||||
 | 
					   io memory page */
 | 
				
			||||||
 | 
					void cpu_register_physical_memory(unsigned long start_addr, unsigned long size,
 | 
				
			||||||
 | 
					                                  long phys_offset)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    unsigned long addr, end_addr;
 | 
				
			||||||
 | 
					    unsigned long *p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    end_addr = start_addr + size;
 | 
				
			||||||
 | 
					    for(addr = start_addr; addr < end_addr; addr += TARGET_PAGE_SIZE) {
 | 
				
			||||||
 | 
					        p = physpage_find_alloc(addr);
 | 
				
			||||||
 | 
					        *p = phys_offset;
 | 
				
			||||||
 | 
					        if ((phys_offset & ~TARGET_PAGE_MASK) == 0)
 | 
				
			||||||
 | 
					            phys_offset += TARGET_PAGE_SIZE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint32_t unassigned_mem_readb(uint32_t addr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void unassigned_mem_writeb(uint32_t addr, uint32_t val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static CPUReadMemoryFunc *unassigned_mem_read[3] = {
 | 
				
			||||||
 | 
					    unassigned_mem_readb,
 | 
				
			||||||
 | 
					    unassigned_mem_readb,
 | 
				
			||||||
 | 
					    unassigned_mem_readb,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static CPUWriteMemoryFunc *unassigned_mem_write[3] = {
 | 
				
			||||||
 | 
					    unassigned_mem_writeb,
 | 
				
			||||||
 | 
					    unassigned_mem_writeb,
 | 
				
			||||||
 | 
					    unassigned_mem_writeb,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void io_mem_init(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    io_mem_nb = 1;
 | 
				
			||||||
 | 
					    cpu_register_io_memory(0, unassigned_mem_read, unassigned_mem_write);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* mem_read and mem_write are arrays of functions containing the
 | 
				
			||||||
 | 
					   function to access byte (index 0), word (index 1) and dword (index
 | 
				
			||||||
 | 
					   2). All functions must be supplied. If io_index is non zero, the
 | 
				
			||||||
 | 
					   corresponding io zone is modified. If it is zero, a new io zone is
 | 
				
			||||||
 | 
					   allocated. The return value can be used with
 | 
				
			||||||
 | 
					   cpu_register_physical_memory(). (-1) is returned if error. */
 | 
				
			||||||
 | 
					int cpu_register_io_memory(int io_index,
 | 
				
			||||||
 | 
					                           CPUReadMemoryFunc **mem_read,
 | 
				
			||||||
 | 
					                           CPUWriteMemoryFunc **mem_write)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (io_index <= 0) {
 | 
				
			||||||
 | 
					        if (io_index >= IO_MEM_NB_ENTRIES)
 | 
				
			||||||
 | 
					            return -1;
 | 
				
			||||||
 | 
					        io_index = io_mem_nb++;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        if (io_index >= IO_MEM_NB_ENTRIES)
 | 
				
			||||||
 | 
					            return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    for(i = 0;i < 3; i++) {
 | 
				
			||||||
 | 
					        io_mem_read[io_index][i] = mem_read[i];
 | 
				
			||||||
 | 
					        io_mem_write[io_index][i] = mem_write[i];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return io_index << IO_MEM_SHIFT;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										27
									
								
								exec.h
								
								
								
								
							
							
						
						
									
										27
									
								
								exec.h
								
								
								
								
							| 
						 | 
					@ -21,6 +21,17 @@
 | 
				
			||||||
/* allow to see translation results - the slowdown should be negligible, so we leave it */
 | 
					/* allow to see translation results - the slowdown should be negligible, so we leave it */
 | 
				
			||||||
#define DEBUG_DISAS
 | 
					#define DEBUG_DISAS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef glue
 | 
				
			||||||
 | 
					#define xglue(x, y) x ## y
 | 
				
			||||||
 | 
					#define glue(x, y) xglue(x, y)
 | 
				
			||||||
 | 
					#define stringify(s)	tostring(s)
 | 
				
			||||||
 | 
					#define tostring(s)	#s
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if GCC_MAJOR < 3
 | 
				
			||||||
 | 
					#define __builtin_expect(x, n) (x)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* is_jmp field values */
 | 
					/* is_jmp field values */
 | 
				
			||||||
#define DISAS_NEXT    0 /* next instruction can be analyzed */
 | 
					#define DISAS_NEXT    0 /* next instruction can be analyzed */
 | 
				
			||||||
#define DISAS_JUMP    1 /* only pc was modified dynamically */
 | 
					#define DISAS_JUMP    1 /* only pc was modified dynamically */
 | 
				
			||||||
| 
						 | 
					@ -51,8 +62,11 @@ extern uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
 | 
				
			||||||
#define GEN_FLAG_ST_SHIFT        4
 | 
					#define GEN_FLAG_ST_SHIFT        4
 | 
				
			||||||
#define GEN_FLAG_TF_SHIFT        8 /* same position as eflags */
 | 
					#define GEN_FLAG_TF_SHIFT        8 /* same position as eflags */
 | 
				
			||||||
#define GEN_FLAG_CPL_SHIFT       9
 | 
					#define GEN_FLAG_CPL_SHIFT       9
 | 
				
			||||||
 | 
					#define GEN_FLAG_SOFT_MMU_SHIFT 11
 | 
				
			||||||
#define GEN_FLAG_IOPL_SHIFT     12 /* same position as eflags */
 | 
					#define GEN_FLAG_IOPL_SHIFT     12 /* same position as eflags */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void optimize_flags_init(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern FILE *logfile;
 | 
					extern FILE *logfile;
 | 
				
			||||||
| 
						 | 
					@ -68,6 +82,8 @@ int cpu_restore_state(struct TranslationBlock *tb,
 | 
				
			||||||
void cpu_exec_init(void);
 | 
					void cpu_exec_init(void);
 | 
				
			||||||
int page_unprotect(unsigned long address);
 | 
					int page_unprotect(unsigned long address);
 | 
				
			||||||
void page_unmap(void);
 | 
					void page_unmap(void);
 | 
				
			||||||
 | 
					void tlb_flush_page(CPUState *env, uint32_t addr);
 | 
				
			||||||
 | 
					void tlb_flush(CPUState *env);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define CODE_GEN_MAX_SIZE        65536
 | 
					#define CODE_GEN_MAX_SIZE        65536
 | 
				
			||||||
#define CODE_GEN_ALIGN           16 /* must be >= of the size of a icache line */
 | 
					#define CODE_GEN_ALIGN           16 /* must be >= of the size of a icache line */
 | 
				
			||||||
| 
						 | 
					@ -230,6 +246,17 @@ dummy_label ## n:\
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* physical memory access */
 | 
				
			||||||
 | 
					#define IO_MEM_NB_ENTRIES  256
 | 
				
			||||||
 | 
					#define TLB_INVALID_MASK   (1 << 3)
 | 
				
			||||||
 | 
					#define IO_MEM_SHIFT       4
 | 
				
			||||||
 | 
					#define IO_MEM_UNASSIGNED  (1 << IO_MEM_SHIFT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned long physpage_find(unsigned long page);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
 | 
				
			||||||
 | 
					extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __powerpc__
 | 
					#ifdef __powerpc__
 | 
				
			||||||
static inline int testandset (int *p)
 | 
					static inline int testandset (int *p)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1741,3 +1741,34 @@ void helper_frstor(uint8_t *ptr, int data32)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SHIFT 0
 | 
				
			||||||
 | 
					#include "softmmu_template.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SHIFT 1
 | 
				
			||||||
 | 
					#include "softmmu_template.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SHIFT 2
 | 
				
			||||||
 | 
					#include "softmmu_template.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SHIFT 3
 | 
				
			||||||
 | 
					#include "softmmu_template.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* try to fill the TLB and return an exception if error */
 | 
				
			||||||
 | 
					void tlb_fill(unsigned long addr, int is_write, void *retaddr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    TranslationBlock *tb;
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					    unsigned long pc;
 | 
				
			||||||
 | 
					    ret = cpu_x86_handle_mmu_fault(env, addr, is_write);
 | 
				
			||||||
 | 
					    if (ret) {
 | 
				
			||||||
 | 
					        /* now we have a real cpu fault */
 | 
				
			||||||
 | 
					        pc = (unsigned long)retaddr;
 | 
				
			||||||
 | 
					        tb = tb_find_pc(pc);
 | 
				
			||||||
 | 
					        if (tb) {
 | 
				
			||||||
 | 
					            /* the PC is inside the translated code. It means that we have
 | 
				
			||||||
 | 
					               a virtual CPU fault */
 | 
				
			||||||
 | 
					            cpu_restore_state(tb, env, pc);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        raise_exception_err(EXCP0E_PAGE, env->error_code);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										100
									
								
								op-i386.c
								
								
								
								
							
							
						
						
									
										100
									
								
								op-i386.c
								
								
								
								
							| 
						 | 
					@ -376,70 +376,14 @@ void OPPROTO op_andl_A0_ffff(void)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* memory access */
 | 
					/* memory access */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void OPPROTO op_ldub_T0_A0(void)
 | 
					#define MEMSUFFIX
 | 
				
			||||||
{
 | 
					#include "ops_mem.h"
 | 
				
			||||||
    T0 = ldub((uint8_t *)A0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
void OPPROTO op_ldsb_T0_A0(void)
 | 
					#define MEMSUFFIX _user
 | 
				
			||||||
{
 | 
					#include "ops_mem.h"
 | 
				
			||||||
    T0 = ldsb((int8_t *)A0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
void OPPROTO op_lduw_T0_A0(void)
 | 
					#define MEMSUFFIX _kernel
 | 
				
			||||||
{
 | 
					#include "ops_mem.h"
 | 
				
			||||||
    T0 = lduw((uint8_t *)A0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_ldsw_T0_A0(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = ldsw((int8_t *)A0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_ldl_T0_A0(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = ldl((uint8_t *)A0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_ldub_T1_A0(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T1 = ldub((uint8_t *)A0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_ldsb_T1_A0(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T1 = ldsb((int8_t *)A0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_lduw_T1_A0(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T1 = lduw((uint8_t *)A0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_ldsw_T1_A0(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T1 = ldsw((int8_t *)A0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_ldl_T1_A0(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T1 = ldl((uint8_t *)A0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_stb_T0_A0(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    stb((uint8_t *)A0, T0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_stw_T0_A0(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    stw((uint8_t *)A0, T0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_stl_T0_A0(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    stl((uint8_t *)A0, T0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* used for bit operations */
 | 
					/* used for bit operations */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -635,6 +579,38 @@ void OPPROTO op_movswl_DX_AX(void)
 | 
				
			||||||
    EDX = (EDX & 0xffff0000) | (((int16_t)EAX >> 15) & 0xffff);
 | 
					    EDX = (EDX & 0xffff0000) | (((int16_t)EAX >> 15) & 0xffff);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* string ops helpers */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OPPROTO op_addl_ESI_T0(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ESI += T0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OPPROTO op_addw_ESI_T0(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ESI = (ESI & ~0xffff) | ((ESI + T0) & 0xffff);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OPPROTO op_addl_EDI_T0(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EDI += T0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OPPROTO op_addw_EDI_T0(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EDI = (EDI & ~0xffff) | ((EDI + T0) & 0xffff);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OPPROTO op_decl_ECX(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ECX--;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OPPROTO op_decw_ECX(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ECX = (ECX & ~0xffff) | ((ECX - 1) & 0xffff);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* push/pop */
 | 
					/* push/pop */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void op_pushl_T0(void)
 | 
					void op_pushl_T0(void)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										150
									
								
								op_string.h
								
								
								
								
							
							
						
						
									
										150
									
								
								op_string.h
								
								
								
								
							| 
						 | 
					@ -1,94 +1,4 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void OPPROTO glue(glue(op_movs, SUFFIX), STRING_SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int v, inc;
 | 
					 | 
				
			||||||
    v = glue(ldu, SUFFIX)(SI_ADDR);
 | 
					 | 
				
			||||||
    glue(st, SUFFIX)(DI_ADDR, v);
 | 
					 | 
				
			||||||
    inc = (DF << SHIFT);
 | 
					 | 
				
			||||||
    INC_SI();
 | 
					 | 
				
			||||||
    INC_DI();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_rep_movs, SUFFIX), STRING_SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int v, inc;
 | 
					 | 
				
			||||||
    inc = (DF << SHIFT);
 | 
					 | 
				
			||||||
    while (CX != 0) {
 | 
					 | 
				
			||||||
        v = glue(ldu, SUFFIX)(SI_ADDR);
 | 
					 | 
				
			||||||
        glue(st, SUFFIX)(DI_ADDR, v);
 | 
					 | 
				
			||||||
        INC_SI();
 | 
					 | 
				
			||||||
        INC_DI();
 | 
					 | 
				
			||||||
        DEC_CX();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_stos, SUFFIX), STRING_SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int inc;
 | 
					 | 
				
			||||||
    glue(st, SUFFIX)(DI_ADDR, EAX);
 | 
					 | 
				
			||||||
    inc = (DF << SHIFT);
 | 
					 | 
				
			||||||
    INC_DI();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_rep_stos, SUFFIX), STRING_SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int inc;
 | 
					 | 
				
			||||||
    inc = (DF << SHIFT);
 | 
					 | 
				
			||||||
    while (CX != 0) {
 | 
					 | 
				
			||||||
        glue(st, SUFFIX)(DI_ADDR, EAX);
 | 
					 | 
				
			||||||
        INC_DI();
 | 
					 | 
				
			||||||
        DEC_CX();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_lods, SUFFIX), STRING_SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int v, inc;
 | 
					 | 
				
			||||||
    v = glue(ldu, SUFFIX)(SI_ADDR);
 | 
					 | 
				
			||||||
#if SHIFT == 0
 | 
					 | 
				
			||||||
    EAX = (EAX & ~0xff) | v;
 | 
					 | 
				
			||||||
#elif SHIFT == 1
 | 
					 | 
				
			||||||
    EAX = (EAX & ~0xffff) | v;
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
    EAX = v;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    inc = (DF << SHIFT);
 | 
					 | 
				
			||||||
    INC_SI();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* don't know if it is used */
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_rep_lods, SUFFIX), STRING_SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int v, inc;
 | 
					 | 
				
			||||||
    inc = (DF << SHIFT);
 | 
					 | 
				
			||||||
    while (CX != 0) {
 | 
					 | 
				
			||||||
        v = glue(ldu, SUFFIX)(SI_ADDR);
 | 
					 | 
				
			||||||
#if SHIFT == 0
 | 
					 | 
				
			||||||
        EAX = (EAX & ~0xff) | v;
 | 
					 | 
				
			||||||
#elif SHIFT == 1
 | 
					 | 
				
			||||||
        EAX = (EAX & ~0xffff) | v;
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
        EAX = v;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        INC_SI();
 | 
					 | 
				
			||||||
        DEC_CX();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_scas, SUFFIX), STRING_SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int v, inc;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    v = glue(ldu, SUFFIX)(DI_ADDR);
 | 
					 | 
				
			||||||
    inc = (DF << SHIFT);
 | 
					 | 
				
			||||||
    INC_DI();
 | 
					 | 
				
			||||||
    CC_SRC = v;
 | 
					 | 
				
			||||||
    CC_DST = EAX - v;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_repz_scas, SUFFIX), STRING_SUFFIX)(void)
 | 
					void OPPROTO glue(glue(op_repz_scas, SUFFIX), STRING_SUFFIX)(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int v1, v2, inc;
 | 
					    int v1, v2, inc;
 | 
				
			||||||
| 
						 | 
					@ -133,18 +43,6 @@ void OPPROTO glue(glue(op_repnz_scas, SUFFIX), STRING_SUFFIX)(void)
 | 
				
			||||||
    FORCE_RET();
 | 
					    FORCE_RET();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void OPPROTO glue(glue(op_cmps, SUFFIX), STRING_SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int v1, v2, inc;
 | 
					 | 
				
			||||||
    v1 = glue(ldu, SUFFIX)(SI_ADDR);
 | 
					 | 
				
			||||||
    v2 = glue(ldu, SUFFIX)(DI_ADDR);
 | 
					 | 
				
			||||||
    inc = (DF << SHIFT);
 | 
					 | 
				
			||||||
    INC_SI();
 | 
					 | 
				
			||||||
    INC_DI();
 | 
					 | 
				
			||||||
    CC_SRC = v2;
 | 
					 | 
				
			||||||
    CC_DST = v1 - v2;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_repz_cmps, SUFFIX), STRING_SUFFIX)(void)
 | 
					void OPPROTO glue(glue(op_repz_cmps, SUFFIX), STRING_SUFFIX)(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int v1, v2, inc;
 | 
					    int v1, v2, inc;
 | 
				
			||||||
| 
						 | 
					@ -187,54 +85,6 @@ void OPPROTO glue(glue(op_repnz_cmps, SUFFIX), STRING_SUFFIX)(void)
 | 
				
			||||||
    FORCE_RET();
 | 
					    FORCE_RET();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void OPPROTO glue(glue(op_outs, SUFFIX), STRING_SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int v, dx, inc;
 | 
					 | 
				
			||||||
    dx = EDX & 0xffff;
 | 
					 | 
				
			||||||
    v = glue(ldu, SUFFIX)(SI_ADDR);
 | 
					 | 
				
			||||||
    glue(cpu_x86_out, SUFFIX)(env, dx, v);
 | 
					 | 
				
			||||||
    inc = (DF << SHIFT);
 | 
					 | 
				
			||||||
    INC_SI();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_rep_outs, SUFFIX), STRING_SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int v, dx, inc;
 | 
					 | 
				
			||||||
    inc = (DF << SHIFT);
 | 
					 | 
				
			||||||
    dx = EDX & 0xffff;
 | 
					 | 
				
			||||||
    while (CX != 0) {
 | 
					 | 
				
			||||||
        v = glue(ldu, SUFFIX)(SI_ADDR);
 | 
					 | 
				
			||||||
        glue(cpu_x86_out, SUFFIX)(env, dx, v);
 | 
					 | 
				
			||||||
        INC_SI();
 | 
					 | 
				
			||||||
        DEC_CX();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_ins, SUFFIX), STRING_SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int v, dx, inc;
 | 
					 | 
				
			||||||
    dx = EDX & 0xffff;
 | 
					 | 
				
			||||||
    v = glue(cpu_x86_in, SUFFIX)(env, dx);
 | 
					 | 
				
			||||||
    glue(st, SUFFIX)(DI_ADDR, v);
 | 
					 | 
				
			||||||
    inc = (DF << SHIFT);
 | 
					 | 
				
			||||||
    INC_DI();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_rep_ins, SUFFIX), STRING_SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int v, dx, inc;
 | 
					 | 
				
			||||||
    inc = (DF << SHIFT);
 | 
					 | 
				
			||||||
    dx = EDX & 0xffff;
 | 
					 | 
				
			||||||
    while (CX != 0) {
 | 
					 | 
				
			||||||
        v = glue(cpu_x86_in, SUFFIX)(env, dx);
 | 
					 | 
				
			||||||
        glue(st, SUFFIX)(DI_ADDR, v);
 | 
					 | 
				
			||||||
        INC_DI();
 | 
					 | 
				
			||||||
        DEC_CX();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#undef STRING_SUFFIX
 | 
					#undef STRING_SUFFIX
 | 
				
			||||||
#undef SI_ADDR
 | 
					#undef SI_ADDR
 | 
				
			||||||
#undef DI_ADDR
 | 
					#undef DI_ADDR
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -547,6 +547,31 @@ void OPPROTO op_update_bt_cc(void)
 | 
				
			||||||
#define DEC_CX() ECX = (ECX & ~0xffff) | ((ECX - 1) & 0xffff)
 | 
					#define DEC_CX() ECX = (ECX & ~0xffff) | ((ECX - 1) & 0xffff)
 | 
				
			||||||
#include "op_string.h"
 | 
					#include "op_string.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OPPROTO glue(op_movl_T0_Dshift, SUFFIX)(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    T0 = DF << SHIFT;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OPPROTO glue(op_string_jz_sub, SUFFIX)(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if ((DATA_TYPE)CC_DST == 0)
 | 
				
			||||||
 | 
					        JUMP_TB(PARAM1, 1, PARAM2);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OPPROTO glue(op_string_jnz_sub, SUFFIX)(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if ((DATA_TYPE)CC_DST != 0)
 | 
				
			||||||
 | 
					        JUMP_TB(PARAM1, 1, PARAM2);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if DATA_BITS >= 16
 | 
				
			||||||
 | 
					void OPPROTO glue(op_jz_ecx, SUFFIX)(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if ((DATA_TYPE)ECX == 0)
 | 
				
			||||||
 | 
					        JUMP_TB(PARAM1, 1, PARAM2);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* port I/O */
 | 
					/* port I/O */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void OPPROTO glue(glue(op_out, SUFFIX), _T0_T1)(void)
 | 
					void OPPROTO glue(glue(op_out, SUFFIX), _T0_T1)(void)
 | 
				
			||||||
| 
						 | 
					@ -559,6 +584,16 @@ void OPPROTO glue(glue(op_in, SUFFIX), _T0_T1)(void)
 | 
				
			||||||
    T1 = glue(cpu_x86_in, SUFFIX)(env, T0 & 0xffff);
 | 
					    T1 = glue(cpu_x86_in, SUFFIX)(env, T0 & 0xffff);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OPPROTO glue(glue(op_in, SUFFIX), _DX_T0)(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    T0 = glue(cpu_x86_in, SUFFIX)(env, EDX & 0xffff);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OPPROTO glue(glue(op_out, SUFFIX), _DX_T0)(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    glue(cpu_x86_out, SUFFIX)(env, EDX & 0xffff, T0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#undef DATA_BITS
 | 
					#undef DATA_BITS
 | 
				
			||||||
#undef SHIFT_MASK
 | 
					#undef SHIFT_MASK
 | 
				
			||||||
#undef SIGN_MASK
 | 
					#undef SIGN_MASK
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue