new directory structure
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@390 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									853d6f7a83
								
							
						
					
					
						commit
						d3eead2eec
					
				
							
								
								
									
										63
									
								
								cpu-arm.h
									
									
									
									
									
								
							
							
						
						
									
										63
									
								
								cpu-arm.h
									
									
									
									
									
								
							@ -1,63 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 * ARM virtual CPU header
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 *  Copyright (c) 2003 Fabrice Bellard
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This library is free software; you can redistribute it and/or
 | 
					 | 
				
			||||||
 * modify it under the terms of the GNU Lesser General Public
 | 
					 | 
				
			||||||
 * License as published by the Free Software Foundation; either
 | 
					 | 
				
			||||||
 * version 2 of the License, or (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This library is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
					 | 
				
			||||||
 * Lesser General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU Lesser General Public
 | 
					 | 
				
			||||||
 * License along with this library; if not, write to the Free Software
 | 
					 | 
				
			||||||
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#ifndef CPU_ARM_H
 | 
					 | 
				
			||||||
#define CPU_ARM_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "cpu-defs.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define EXCP_UDEF       1   /* undefined instruction */
 | 
					 | 
				
			||||||
#define EXCP_SWI        2   /* software interrupt */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct CPUARMState {
 | 
					 | 
				
			||||||
    uint32_t regs[16];
 | 
					 | 
				
			||||||
    uint32_t cpsr;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    /* cpsr flag cache for faster execution */
 | 
					 | 
				
			||||||
    uint32_t CF; /* 0 or 1 */
 | 
					 | 
				
			||||||
    uint32_t VF; /* V is the bit 31. All other bits are undefined */
 | 
					 | 
				
			||||||
    uint32_t NZF; /* N is bit 31. Z is computed from NZF */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* exception/interrupt handling */
 | 
					 | 
				
			||||||
    jmp_buf jmp_env;
 | 
					 | 
				
			||||||
    int exception_index;
 | 
					 | 
				
			||||||
    int interrupt_request;
 | 
					 | 
				
			||||||
    struct TranslationBlock *current_tb;
 | 
					 | 
				
			||||||
    int user_mode_only;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* user data */
 | 
					 | 
				
			||||||
    void *opaque;
 | 
					 | 
				
			||||||
} CPUARMState;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
CPUARMState *cpu_arm_init(void);
 | 
					 | 
				
			||||||
int cpu_arm_exec(CPUARMState *s);
 | 
					 | 
				
			||||||
void cpu_arm_close(CPUARMState *s);
 | 
					 | 
				
			||||||
/* you can call this signal handler from your SIGBUS and SIGSEGV
 | 
					 | 
				
			||||||
   signal handlers to inform the virtual CPU of exceptions. non zero
 | 
					 | 
				
			||||||
   is returned if the signal was handled by the virtual CPU.  */
 | 
					 | 
				
			||||||
struct siginfo;
 | 
					 | 
				
			||||||
int cpu_arm_signal_handler(int host_signum, struct siginfo *info, 
 | 
					 | 
				
			||||||
                           void *puc);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void cpu_arm_dump_state(CPUARMState *env, FILE *f, int flags);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define TARGET_PAGE_BITS 12
 | 
					 | 
				
			||||||
#include "cpu-all.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
							
								
								
									
										401
									
								
								cpu-i386.h
									
									
									
									
									
								
							
							
						
						
									
										401
									
								
								cpu-i386.h
									
									
									
									
									
								
							@ -1,401 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 * i386 virtual CPU header
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 *  Copyright (c) 2003 Fabrice Bellard
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This library is free software; you can redistribute it and/or
 | 
					 | 
				
			||||||
 * modify it under the terms of the GNU Lesser General Public
 | 
					 | 
				
			||||||
 * License as published by the Free Software Foundation; either
 | 
					 | 
				
			||||||
 * version 2 of the License, or (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This library is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
					 | 
				
			||||||
 * Lesser General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU Lesser General Public
 | 
					 | 
				
			||||||
 * License along with this library; if not, write to the Free Software
 | 
					 | 
				
			||||||
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#ifndef CPU_I386_H
 | 
					 | 
				
			||||||
#define CPU_I386_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "cpu-defs.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define R_EAX 0
 | 
					 | 
				
			||||||
#define R_ECX 1
 | 
					 | 
				
			||||||
#define R_EDX 2
 | 
					 | 
				
			||||||
#define R_EBX 3
 | 
					 | 
				
			||||||
#define R_ESP 4
 | 
					 | 
				
			||||||
#define R_EBP 5
 | 
					 | 
				
			||||||
#define R_ESI 6
 | 
					 | 
				
			||||||
#define R_EDI 7
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define R_AL 0
 | 
					 | 
				
			||||||
#define R_CL 1
 | 
					 | 
				
			||||||
#define R_DL 2
 | 
					 | 
				
			||||||
#define R_BL 3
 | 
					 | 
				
			||||||
#define R_AH 4
 | 
					 | 
				
			||||||
#define R_CH 5
 | 
					 | 
				
			||||||
#define R_DH 6
 | 
					 | 
				
			||||||
#define R_BH 7
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define R_ES 0
 | 
					 | 
				
			||||||
#define R_CS 1
 | 
					 | 
				
			||||||
#define R_SS 2
 | 
					 | 
				
			||||||
#define R_DS 3
 | 
					 | 
				
			||||||
#define R_FS 4
 | 
					 | 
				
			||||||
#define R_GS 5
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* segment descriptor fields */
 | 
					 | 
				
			||||||
#define DESC_G_MASK     (1 << 23)
 | 
					 | 
				
			||||||
#define DESC_B_SHIFT    22
 | 
					 | 
				
			||||||
#define DESC_B_MASK     (1 << DESC_B_SHIFT)
 | 
					 | 
				
			||||||
#define DESC_AVL_MASK   (1 << 20)
 | 
					 | 
				
			||||||
#define DESC_P_MASK     (1 << 15)
 | 
					 | 
				
			||||||
#define DESC_DPL_SHIFT  13
 | 
					 | 
				
			||||||
#define DESC_S_MASK     (1 << 12)
 | 
					 | 
				
			||||||
#define DESC_TYPE_SHIFT 8
 | 
					 | 
				
			||||||
#define DESC_A_MASK     (1 << 8)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define DESC_CS_MASK    (1 << 11)
 | 
					 | 
				
			||||||
#define DESC_C_MASK     (1 << 10)
 | 
					 | 
				
			||||||
#define DESC_R_MASK     (1 << 9)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define DESC_E_MASK     (1 << 10)
 | 
					 | 
				
			||||||
#define DESC_W_MASK     (1 << 9)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* eflags masks */
 | 
					 | 
				
			||||||
#define CC_C   	0x0001
 | 
					 | 
				
			||||||
#define CC_P 	0x0004
 | 
					 | 
				
			||||||
#define CC_A	0x0010
 | 
					 | 
				
			||||||
#define CC_Z	0x0040
 | 
					 | 
				
			||||||
#define CC_S    0x0080
 | 
					 | 
				
			||||||
#define CC_O    0x0800
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define TF_SHIFT   8
 | 
					 | 
				
			||||||
#define IOPL_SHIFT 12
 | 
					 | 
				
			||||||
#define VM_SHIFT   17
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define TF_MASK 		0x00000100
 | 
					 | 
				
			||||||
#define IF_MASK 		0x00000200
 | 
					 | 
				
			||||||
#define DF_MASK 		0x00000400
 | 
					 | 
				
			||||||
#define IOPL_MASK		0x00003000
 | 
					 | 
				
			||||||
#define NT_MASK	         	0x00004000
 | 
					 | 
				
			||||||
#define RF_MASK			0x00010000
 | 
					 | 
				
			||||||
#define VM_MASK			0x00020000
 | 
					 | 
				
			||||||
#define AC_MASK			0x00040000 
 | 
					 | 
				
			||||||
#define VIF_MASK                0x00080000
 | 
					 | 
				
			||||||
#define VIP_MASK                0x00100000
 | 
					 | 
				
			||||||
#define ID_MASK                 0x00200000
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* hidden flags - used internally by qemu to represent additionnal cpu
 | 
					 | 
				
			||||||
   states. Only the CPL and INHIBIT_IRQ are not redundant. We avoid
 | 
					 | 
				
			||||||
   using the IOPL_MASK, TF_MASK and VM_MASK bit position to ease oring
 | 
					 | 
				
			||||||
   with eflags. */
 | 
					 | 
				
			||||||
/* current cpl */
 | 
					 | 
				
			||||||
#define HF_CPL_SHIFT         0
 | 
					 | 
				
			||||||
/* true if soft mmu is being used */
 | 
					 | 
				
			||||||
#define HF_SOFTMMU_SHIFT     2
 | 
					 | 
				
			||||||
/* true if hardware interrupts must be disabled for next instruction */
 | 
					 | 
				
			||||||
#define HF_INHIBIT_IRQ_SHIFT 3
 | 
					 | 
				
			||||||
/* 16 or 32 segments */
 | 
					 | 
				
			||||||
#define HF_CS32_SHIFT        4
 | 
					 | 
				
			||||||
#define HF_SS32_SHIFT        5
 | 
					 | 
				
			||||||
/* zero base for DS, ES and SS */
 | 
					 | 
				
			||||||
#define HF_ADDSEG_SHIFT      6
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define HF_CPL_MASK          (3 << HF_CPL_SHIFT)
 | 
					 | 
				
			||||||
#define HF_SOFTMMU_MASK      (1 << HF_SOFTMMU_SHIFT)
 | 
					 | 
				
			||||||
#define HF_INHIBIT_IRQ_MASK  (1 << HF_INHIBIT_IRQ_SHIFT)
 | 
					 | 
				
			||||||
#define HF_CS32_MASK         (1 << HF_CS32_SHIFT)
 | 
					 | 
				
			||||||
#define HF_SS32_MASK         (1 << HF_SS32_SHIFT)
 | 
					 | 
				
			||||||
#define HF_ADDSEG_MASK       (1 << HF_ADDSEG_SHIFT)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define CR0_PE_MASK  (1 << 0)
 | 
					 | 
				
			||||||
#define CR0_TS_MASK  (1 << 3)
 | 
					 | 
				
			||||||
#define CR0_WP_MASK  (1 << 16)
 | 
					 | 
				
			||||||
#define CR0_AM_MASK  (1 << 18)
 | 
					 | 
				
			||||||
#define CR0_PG_MASK  (1 << 31)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define CR4_VME_MASK  (1 << 0)
 | 
					 | 
				
			||||||
#define CR4_PVI_MASK  (1 << 1)
 | 
					 | 
				
			||||||
#define CR4_TSD_MASK  (1 << 2)
 | 
					 | 
				
			||||||
#define CR4_DE_MASK   (1 << 3)
 | 
					 | 
				
			||||||
#define CR4_PSE_MASK  (1 << 4)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define PG_PRESENT_BIT	0
 | 
					 | 
				
			||||||
#define PG_RW_BIT	1
 | 
					 | 
				
			||||||
#define PG_USER_BIT	2
 | 
					 | 
				
			||||||
#define PG_PWT_BIT	3
 | 
					 | 
				
			||||||
#define PG_PCD_BIT	4
 | 
					 | 
				
			||||||
#define PG_ACCESSED_BIT	5
 | 
					 | 
				
			||||||
#define PG_DIRTY_BIT	6
 | 
					 | 
				
			||||||
#define PG_PSE_BIT	7
 | 
					 | 
				
			||||||
#define PG_GLOBAL_BIT	8
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define PG_PRESENT_MASK  (1 << PG_PRESENT_BIT)
 | 
					 | 
				
			||||||
#define PG_RW_MASK	 (1 << PG_RW_BIT)
 | 
					 | 
				
			||||||
#define PG_USER_MASK	 (1 << PG_USER_BIT)
 | 
					 | 
				
			||||||
#define PG_PWT_MASK	 (1 << PG_PWT_BIT)
 | 
					 | 
				
			||||||
#define PG_PCD_MASK	 (1 << PG_PCD_BIT)
 | 
					 | 
				
			||||||
#define PG_ACCESSED_MASK (1 << PG_ACCESSED_BIT)
 | 
					 | 
				
			||||||
#define PG_DIRTY_MASK	 (1 << PG_DIRTY_BIT)
 | 
					 | 
				
			||||||
#define PG_PSE_MASK	 (1 << PG_PSE_BIT)
 | 
					 | 
				
			||||||
#define PG_GLOBAL_MASK	 (1 << PG_GLOBAL_BIT)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define PG_ERROR_W_BIT     1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define PG_ERROR_P_MASK    0x01
 | 
					 | 
				
			||||||
#define PG_ERROR_W_MASK    (1 << PG_ERROR_W_BIT)
 | 
					 | 
				
			||||||
#define PG_ERROR_U_MASK    0x04
 | 
					 | 
				
			||||||
#define PG_ERROR_RSVD_MASK 0x08
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define MSR_IA32_APICBASE               0x1b
 | 
					 | 
				
			||||||
#define MSR_IA32_APICBASE_BSP           (1<<8)
 | 
					 | 
				
			||||||
#define MSR_IA32_APICBASE_ENABLE        (1<<11)
 | 
					 | 
				
			||||||
#define MSR_IA32_APICBASE_BASE          (0xfffff<<12)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define MSR_IA32_SYSENTER_CS            0x174
 | 
					 | 
				
			||||||
#define MSR_IA32_SYSENTER_ESP           0x175
 | 
					 | 
				
			||||||
#define MSR_IA32_SYSENTER_EIP           0x176
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define EXCP00_DIVZ	0
 | 
					 | 
				
			||||||
#define EXCP01_SSTP	1
 | 
					 | 
				
			||||||
#define EXCP02_NMI	2
 | 
					 | 
				
			||||||
#define EXCP03_INT3	3
 | 
					 | 
				
			||||||
#define EXCP04_INTO	4
 | 
					 | 
				
			||||||
#define EXCP05_BOUND	5
 | 
					 | 
				
			||||||
#define EXCP06_ILLOP	6
 | 
					 | 
				
			||||||
#define EXCP07_PREX	7
 | 
					 | 
				
			||||||
#define EXCP08_DBLE	8
 | 
					 | 
				
			||||||
#define EXCP09_XERR	9
 | 
					 | 
				
			||||||
#define EXCP0A_TSS	10
 | 
					 | 
				
			||||||
#define EXCP0B_NOSEG	11
 | 
					 | 
				
			||||||
#define EXCP0C_STACK	12
 | 
					 | 
				
			||||||
#define EXCP0D_GPF	13
 | 
					 | 
				
			||||||
#define EXCP0E_PAGE	14
 | 
					 | 
				
			||||||
#define EXCP10_COPR	16
 | 
					 | 
				
			||||||
#define EXCP11_ALGN	17
 | 
					 | 
				
			||||||
#define EXCP12_MCHK	18
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum {
 | 
					 | 
				
			||||||
    CC_OP_DYNAMIC, /* must use dynamic code to get cc_op */
 | 
					 | 
				
			||||||
    CC_OP_EFLAGS,  /* all cc are explicitely computed, CC_SRC = flags */
 | 
					 | 
				
			||||||
    CC_OP_MUL, /* modify all flags, C, O = (CC_SRC != 0) */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CC_OP_ADDB, /* modify all flags, CC_DST = res, CC_SRC = src1 */
 | 
					 | 
				
			||||||
    CC_OP_ADDW,
 | 
					 | 
				
			||||||
    CC_OP_ADDL,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CC_OP_ADCB, /* modify all flags, CC_DST = res, CC_SRC = src1 */
 | 
					 | 
				
			||||||
    CC_OP_ADCW,
 | 
					 | 
				
			||||||
    CC_OP_ADCL,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CC_OP_SUBB, /* modify all flags, CC_DST = res, CC_SRC = src1 */
 | 
					 | 
				
			||||||
    CC_OP_SUBW,
 | 
					 | 
				
			||||||
    CC_OP_SUBL,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CC_OP_SBBB, /* modify all flags, CC_DST = res, CC_SRC = src1 */
 | 
					 | 
				
			||||||
    CC_OP_SBBW,
 | 
					 | 
				
			||||||
    CC_OP_SBBL,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CC_OP_LOGICB, /* modify all flags, CC_DST = res */
 | 
					 | 
				
			||||||
    CC_OP_LOGICW,
 | 
					 | 
				
			||||||
    CC_OP_LOGICL,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CC_OP_INCB, /* modify all flags except, CC_DST = res, CC_SRC = C */
 | 
					 | 
				
			||||||
    CC_OP_INCW,
 | 
					 | 
				
			||||||
    CC_OP_INCL,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CC_OP_DECB, /* modify all flags except, CC_DST = res, CC_SRC = C  */
 | 
					 | 
				
			||||||
    CC_OP_DECW,
 | 
					 | 
				
			||||||
    CC_OP_DECL,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CC_OP_SHLB, /* modify all flags, CC_DST = res, CC_SRC.lsb = C */
 | 
					 | 
				
			||||||
    CC_OP_SHLW,
 | 
					 | 
				
			||||||
    CC_OP_SHLL,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CC_OP_SARB, /* modify all flags, CC_DST = res, CC_SRC.lsb = C */
 | 
					 | 
				
			||||||
    CC_OP_SARW,
 | 
					 | 
				
			||||||
    CC_OP_SARL,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CC_OP_NB,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef __i386__
 | 
					 | 
				
			||||||
#define USE_X86LDOUBLE
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef USE_X86LDOUBLE
 | 
					 | 
				
			||||||
typedef long double CPU86_LDouble;
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
typedef double CPU86_LDouble;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct SegmentCache {
 | 
					 | 
				
			||||||
    uint32_t selector;
 | 
					 | 
				
			||||||
    uint8_t *base;
 | 
					 | 
				
			||||||
    uint32_t limit;
 | 
					 | 
				
			||||||
    uint32_t flags;
 | 
					 | 
				
			||||||
} SegmentCache;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct CPUX86State {
 | 
					 | 
				
			||||||
    /* standard registers */
 | 
					 | 
				
			||||||
    uint32_t regs[8];
 | 
					 | 
				
			||||||
    uint32_t eip;
 | 
					 | 
				
			||||||
    uint32_t eflags; /* eflags register. During CPU emulation, CC
 | 
					 | 
				
			||||||
                        flags and DF are set to zero because they are
 | 
					 | 
				
			||||||
                        stored elsewhere */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* emulator internal eflags handling */
 | 
					 | 
				
			||||||
    uint32_t cc_src;
 | 
					 | 
				
			||||||
    uint32_t cc_dst;
 | 
					 | 
				
			||||||
    uint32_t cc_op;
 | 
					 | 
				
			||||||
    int32_t df; /* D flag : 1 if D = 0, -1 if D = 1 */
 | 
					 | 
				
			||||||
    uint32_t hflags; /* hidden flags, see HF_xxx constants */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* FPU state */
 | 
					 | 
				
			||||||
    unsigned int fpstt; /* top of stack index */
 | 
					 | 
				
			||||||
    unsigned int fpus;
 | 
					 | 
				
			||||||
    unsigned int fpuc;
 | 
					 | 
				
			||||||
    uint8_t fptags[8];   /* 0 = valid, 1 = empty */
 | 
					 | 
				
			||||||
    CPU86_LDouble fpregs[8];    
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* emulator internal variables */
 | 
					 | 
				
			||||||
    CPU86_LDouble ft0;
 | 
					 | 
				
			||||||
    union {
 | 
					 | 
				
			||||||
	float f;
 | 
					 | 
				
			||||||
        double d;
 | 
					 | 
				
			||||||
	int i32;
 | 
					 | 
				
			||||||
        int64_t i64;
 | 
					 | 
				
			||||||
    } fp_convert;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    /* segments */
 | 
					 | 
				
			||||||
    SegmentCache segs[6]; /* selector values */
 | 
					 | 
				
			||||||
    SegmentCache ldt;
 | 
					 | 
				
			||||||
    SegmentCache tr;
 | 
					 | 
				
			||||||
    SegmentCache gdt; /* only base and limit are used */
 | 
					 | 
				
			||||||
    SegmentCache idt; /* only base and limit are used */
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    /* sysenter registers */
 | 
					 | 
				
			||||||
    uint32_t sysenter_cs;
 | 
					 | 
				
			||||||
    uint32_t sysenter_esp;
 | 
					 | 
				
			||||||
    uint32_t sysenter_eip;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    /* exception/interrupt handling */
 | 
					 | 
				
			||||||
    jmp_buf jmp_env;
 | 
					 | 
				
			||||||
    int exception_index;
 | 
					 | 
				
			||||||
    int error_code;
 | 
					 | 
				
			||||||
    int exception_is_int;
 | 
					 | 
				
			||||||
    int exception_next_eip;
 | 
					 | 
				
			||||||
    struct TranslationBlock *current_tb; /* currently executing TB */
 | 
					 | 
				
			||||||
    uint32_t cr[5]; /* NOTE: cr1 is unused */
 | 
					 | 
				
			||||||
    uint32_t dr[8]; /* debug registers */
 | 
					 | 
				
			||||||
    int interrupt_request; 
 | 
					 | 
				
			||||||
    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];
 | 
					 | 
				
			||||||
    int nb_breakpoints;
 | 
					 | 
				
			||||||
    int singlestep_enabled;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* user data */
 | 
					 | 
				
			||||||
    void *opaque;
 | 
					 | 
				
			||||||
} CPUX86State;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef IN_OP_I386
 | 
					 | 
				
			||||||
void cpu_x86_outb(CPUX86State *env, int addr, int val);
 | 
					 | 
				
			||||||
void cpu_x86_outw(CPUX86State *env, int addr, int val);
 | 
					 | 
				
			||||||
void cpu_x86_outl(CPUX86State *env, int addr, int val);
 | 
					 | 
				
			||||||
int cpu_x86_inb(CPUX86State *env, int addr);
 | 
					 | 
				
			||||||
int cpu_x86_inw(CPUX86State *env, int addr);
 | 
					 | 
				
			||||||
int cpu_x86_inl(CPUX86State *env, int addr);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
CPUX86State *cpu_x86_init(void);
 | 
					 | 
				
			||||||
int cpu_x86_exec(CPUX86State *s);
 | 
					 | 
				
			||||||
void cpu_x86_close(CPUX86State *s);
 | 
					 | 
				
			||||||
int cpu_x86_get_pic_interrupt(CPUX86State *s);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* this function must always be used to load data in the segment
 | 
					 | 
				
			||||||
   cache: it synchronizes the hflags with the segment cache values */
 | 
					 | 
				
			||||||
static inline void cpu_x86_load_seg_cache(CPUX86State *env, 
 | 
					 | 
				
			||||||
                                          int seg_reg, unsigned int selector,
 | 
					 | 
				
			||||||
                                          uint8_t *base, unsigned int limit, 
 | 
					 | 
				
			||||||
                                          unsigned int flags)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    SegmentCache *sc;
 | 
					 | 
				
			||||||
    unsigned int new_hflags;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    sc = &env->segs[seg_reg];
 | 
					 | 
				
			||||||
    sc->selector = selector;
 | 
					 | 
				
			||||||
    sc->base = base;
 | 
					 | 
				
			||||||
    sc->limit = limit;
 | 
					 | 
				
			||||||
    sc->flags = flags;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* update the hidden flags */
 | 
					 | 
				
			||||||
    new_hflags = (env->segs[R_CS].flags & DESC_B_MASK)
 | 
					 | 
				
			||||||
        >> (DESC_B_SHIFT - HF_CS32_SHIFT);
 | 
					 | 
				
			||||||
    new_hflags |= (env->segs[R_SS].flags & DESC_B_MASK)
 | 
					 | 
				
			||||||
        >> (DESC_B_SHIFT - HF_SS32_SHIFT);
 | 
					 | 
				
			||||||
    if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) {
 | 
					 | 
				
			||||||
        /* XXX: try to avoid this test. The problem comes from the
 | 
					 | 
				
			||||||
           fact that is real mode or vm86 mode we only modify the
 | 
					 | 
				
			||||||
           'base' and 'selector' fields of the segment cache to go
 | 
					 | 
				
			||||||
           faster. A solution may be to force addseg to one in
 | 
					 | 
				
			||||||
           translate-i386.c. */
 | 
					 | 
				
			||||||
        new_hflags |= HF_ADDSEG_MASK;
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        new_hflags |= (((unsigned long)env->segs[R_DS].base | 
 | 
					 | 
				
			||||||
                        (unsigned long)env->segs[R_ES].base |
 | 
					 | 
				
			||||||
                        (unsigned long)env->segs[R_SS].base) != 0) << 
 | 
					 | 
				
			||||||
            HF_ADDSEG_SHIFT;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    env->hflags = (env->hflags & 
 | 
					 | 
				
			||||||
                   ~(HF_CS32_MASK | HF_SS32_MASK | HF_ADDSEG_MASK)) | new_hflags;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* wrapper, just in case memory mappings must be changed */
 | 
					 | 
				
			||||||
static inline void cpu_x86_set_cpl(CPUX86State *s, int cpl)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
#if HF_CPL_MASK == 3
 | 
					 | 
				
			||||||
    s->hflags = (s->hflags & ~HF_CPL_MASK) | cpl;
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
#error HF_CPL_MASK is hardcoded
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* the following helpers are only usable in user mode simulation as
 | 
					 | 
				
			||||||
   they can trigger unexpected exceptions */
 | 
					 | 
				
			||||||
void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector);
 | 
					 | 
				
			||||||
void cpu_x86_fsave(CPUX86State *s, uint8_t *ptr, int data32);
 | 
					 | 
				
			||||||
void cpu_x86_frstor(CPUX86State *s, uint8_t *ptr, int data32);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* you can call this signal handler from your SIGBUS and SIGSEGV
 | 
					 | 
				
			||||||
   signal handlers to inform the virtual CPU of exceptions. non zero
 | 
					 | 
				
			||||||
   is returned if the signal was handled by the virtual CPU.  */
 | 
					 | 
				
			||||||
struct siginfo;
 | 
					 | 
				
			||||||
int cpu_x86_signal_handler(int host_signum, struct siginfo *info, 
 | 
					 | 
				
			||||||
                           void *puc);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* MMU defines */
 | 
					 | 
				
			||||||
void cpu_x86_init_mmu(CPUX86State *env);
 | 
					 | 
				
			||||||
extern int phys_ram_size;
 | 
					 | 
				
			||||||
extern int phys_ram_fd;
 | 
					 | 
				
			||||||
extern uint8_t *phys_ram_base;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* used to debug */
 | 
					 | 
				
			||||||
#define X86_DUMP_FPU  0x0001 /* dump FPU state too */
 | 
					 | 
				
			||||||
#define X86_DUMP_CCOP 0x0002 /* dump qemu flag cache */
 | 
					 | 
				
			||||||
void cpu_x86_dump_state(CPUX86State *env, FILE *f, int flags);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define TARGET_PAGE_BITS 12
 | 
					 | 
				
			||||||
#include "cpu-all.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif /* CPU_I386_H */
 | 
					 | 
				
			||||||
							
								
								
									
										40
									
								
								exec-arm.h
									
									
									
									
									
								
							
							
						
						
									
										40
									
								
								exec-arm.h
									
									
									
									
									
								
							@ -1,40 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 *  ARM execution defines
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 *  Copyright (c) 2003 Fabrice Bellard
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This library is free software; you can redistribute it and/or
 | 
					 | 
				
			||||||
 * modify it under the terms of the GNU Lesser General Public
 | 
					 | 
				
			||||||
 * License as published by the Free Software Foundation; either
 | 
					 | 
				
			||||||
 * version 2 of the License, or (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This library is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
					 | 
				
			||||||
 * Lesser General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU Lesser General Public
 | 
					 | 
				
			||||||
 * License along with this library; if not, write to the Free Software
 | 
					 | 
				
			||||||
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#include "dyngen-exec.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
register struct CPUARMState *env asm(AREG0);
 | 
					 | 
				
			||||||
register uint32_t T0 asm(AREG1);
 | 
					 | 
				
			||||||
register uint32_t T1 asm(AREG2);
 | 
					 | 
				
			||||||
register uint32_t T2 asm(AREG3);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "cpu-arm.h"
 | 
					 | 
				
			||||||
#include "exec.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void cpu_lock(void);
 | 
					 | 
				
			||||||
void cpu_unlock(void);
 | 
					 | 
				
			||||||
void cpu_loop_exit(void);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline int compute_cpsr(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int ZF;
 | 
					 | 
				
			||||||
    ZF = (env->NZF == 0);
 | 
					 | 
				
			||||||
    return env->cpsr | (env->NZF & 0x80000000) | (ZF << 30) | 
 | 
					 | 
				
			||||||
        (env->CF << 29) | ((env->VF & 0x80000000) >> 3);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										416
									
								
								exec-i386.h
									
									
									
									
									
								
							
							
						
						
									
										416
									
								
								exec-i386.h
									
									
									
									
									
								
							@ -1,416 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 *  i386 execution defines 
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 *  Copyright (c) 2003 Fabrice Bellard
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This library is free software; you can redistribute it and/or
 | 
					 | 
				
			||||||
 * modify it under the terms of the GNU Lesser General Public
 | 
					 | 
				
			||||||
 * License as published by the Free Software Foundation; either
 | 
					 | 
				
			||||||
 * version 2 of the License, or (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This library is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
					 | 
				
			||||||
 * Lesser General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU Lesser General Public
 | 
					 | 
				
			||||||
 * License along with this library; if not, write to the Free Software
 | 
					 | 
				
			||||||
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#include "dyngen-exec.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* at least 4 register variables are defines */
 | 
					 | 
				
			||||||
register struct CPUX86State *env asm(AREG0);
 | 
					 | 
				
			||||||
register uint32_t T0 asm(AREG1);
 | 
					 | 
				
			||||||
register uint32_t T1 asm(AREG2);
 | 
					 | 
				
			||||||
register uint32_t T2 asm(AREG3);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define A0 T2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* if more registers are available, we define some registers too */
 | 
					 | 
				
			||||||
#ifdef AREG4
 | 
					 | 
				
			||||||
register uint32_t EAX asm(AREG4);
 | 
					 | 
				
			||||||
#define reg_EAX
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef AREG5
 | 
					 | 
				
			||||||
register uint32_t ESP asm(AREG5);
 | 
					 | 
				
			||||||
#define reg_ESP
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef AREG6
 | 
					 | 
				
			||||||
register uint32_t EBP asm(AREG6);
 | 
					 | 
				
			||||||
#define reg_EBP
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef AREG7
 | 
					 | 
				
			||||||
register uint32_t ECX asm(AREG7);
 | 
					 | 
				
			||||||
#define reg_ECX
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef AREG8
 | 
					 | 
				
			||||||
register uint32_t EDX asm(AREG8);
 | 
					 | 
				
			||||||
#define reg_EDX
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef AREG9
 | 
					 | 
				
			||||||
register uint32_t EBX asm(AREG9);
 | 
					 | 
				
			||||||
#define reg_EBX
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef AREG10
 | 
					 | 
				
			||||||
register uint32_t ESI asm(AREG10);
 | 
					 | 
				
			||||||
#define reg_ESI
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef AREG11
 | 
					 | 
				
			||||||
register uint32_t EDI asm(AREG11);
 | 
					 | 
				
			||||||
#define reg_EDI
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern FILE *logfile;
 | 
					 | 
				
			||||||
extern int loglevel;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef reg_EAX
 | 
					 | 
				
			||||||
#define EAX (env->regs[R_EAX])
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#ifndef reg_ECX
 | 
					 | 
				
			||||||
#define ECX (env->regs[R_ECX])
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#ifndef reg_EDX
 | 
					 | 
				
			||||||
#define EDX (env->regs[R_EDX])
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#ifndef reg_EBX
 | 
					 | 
				
			||||||
#define EBX (env->regs[R_EBX])
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#ifndef reg_ESP
 | 
					 | 
				
			||||||
#define ESP (env->regs[R_ESP])
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#ifndef reg_EBP
 | 
					 | 
				
			||||||
#define EBP (env->regs[R_EBP])
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#ifndef reg_ESI
 | 
					 | 
				
			||||||
#define ESI (env->regs[R_ESI])
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#ifndef reg_EDI
 | 
					 | 
				
			||||||
#define EDI (env->regs[R_EDI])
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#define EIP  (env->eip)
 | 
					 | 
				
			||||||
#define DF  (env->df)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define CC_SRC (env->cc_src)
 | 
					 | 
				
			||||||
#define CC_DST (env->cc_dst)
 | 
					 | 
				
			||||||
#define CC_OP  (env->cc_op)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* float macros */
 | 
					 | 
				
			||||||
#define FT0    (env->ft0)
 | 
					 | 
				
			||||||
#define ST0    (env->fpregs[env->fpstt])
 | 
					 | 
				
			||||||
#define ST(n)  (env->fpregs[(env->fpstt + (n)) & 7])
 | 
					 | 
				
			||||||
#define ST1    ST(1)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef USE_FP_CONVERT
 | 
					 | 
				
			||||||
#define FP_CONVERT  (env->fp_convert)
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "cpu-i386.h"
 | 
					 | 
				
			||||||
#include "exec.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct CCTable {
 | 
					 | 
				
			||||||
    int (*compute_all)(void); /* return all the flags */
 | 
					 | 
				
			||||||
    int (*compute_c)(void);  /* return the C flag */
 | 
					 | 
				
			||||||
} CCTable;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern CCTable cc_table[];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void load_seg(int seg_reg, int selector, unsigned cur_eip);
 | 
					 | 
				
			||||||
void helper_ljmp_protected_T0_T1(void);
 | 
					 | 
				
			||||||
void helper_lcall_real_T0_T1(int shift, int next_eip);
 | 
					 | 
				
			||||||
void helper_lcall_protected_T0_T1(int shift, int next_eip);
 | 
					 | 
				
			||||||
void helper_iret_real(int shift);
 | 
					 | 
				
			||||||
void helper_iret_protected(int shift);
 | 
					 | 
				
			||||||
void helper_lret_protected(int shift, int addend);
 | 
					 | 
				
			||||||
void helper_lldt_T0(void);
 | 
					 | 
				
			||||||
void helper_ltr_T0(void);
 | 
					 | 
				
			||||||
void helper_movl_crN_T0(int reg);
 | 
					 | 
				
			||||||
void helper_movl_drN_T0(int reg);
 | 
					 | 
				
			||||||
void helper_invlpg(unsigned int addr);
 | 
					 | 
				
			||||||
void cpu_x86_update_cr0(CPUX86State *env);
 | 
					 | 
				
			||||||
void cpu_x86_update_cr3(CPUX86State *env);
 | 
					 | 
				
			||||||
void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr);
 | 
					 | 
				
			||||||
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_unlock(void);
 | 
					 | 
				
			||||||
void do_interrupt(int intno, int is_int, int error_code, 
 | 
					 | 
				
			||||||
                  unsigned int next_eip, int is_hw);
 | 
					 | 
				
			||||||
void do_interrupt_user(int intno, int is_int, int error_code, 
 | 
					 | 
				
			||||||
                       unsigned int next_eip);
 | 
					 | 
				
			||||||
void raise_interrupt(int intno, int is_int, int error_code, 
 | 
					 | 
				
			||||||
                     unsigned int next_eip);
 | 
					 | 
				
			||||||
void raise_exception_err(int exception_index, int error_code);
 | 
					 | 
				
			||||||
void raise_exception(int exception_index);
 | 
					 | 
				
			||||||
void __hidden cpu_loop_exit(void);
 | 
					 | 
				
			||||||
void helper_fsave(uint8_t *ptr, int data32);
 | 
					 | 
				
			||||||
void helper_frstor(uint8_t *ptr, int data32);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_movl_eflags_T0(void);
 | 
					 | 
				
			||||||
void OPPROTO op_movl_T0_eflags(void);
 | 
					 | 
				
			||||||
void raise_interrupt(int intno, int is_int, int error_code, 
 | 
					 | 
				
			||||||
                     unsigned int next_eip);
 | 
					 | 
				
			||||||
void raise_exception_err(int exception_index, int error_code);
 | 
					 | 
				
			||||||
void raise_exception(int exception_index);
 | 
					 | 
				
			||||||
void helper_divl_EAX_T0(uint32_t eip);
 | 
					 | 
				
			||||||
void helper_idivl_EAX_T0(uint32_t eip);
 | 
					 | 
				
			||||||
void helper_cmpxchg8b(void);
 | 
					 | 
				
			||||||
void helper_cpuid(void);
 | 
					 | 
				
			||||||
void helper_rdtsc(void);
 | 
					 | 
				
			||||||
void helper_rdmsr(void);
 | 
					 | 
				
			||||||
void helper_wrmsr(void);
 | 
					 | 
				
			||||||
void helper_lsl(void);
 | 
					 | 
				
			||||||
void helper_lar(void);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef USE_X86LDOUBLE
 | 
					 | 
				
			||||||
/* use long double functions */
 | 
					 | 
				
			||||||
#define lrint lrintl
 | 
					 | 
				
			||||||
#define llrint llrintl
 | 
					 | 
				
			||||||
#define fabs fabsl
 | 
					 | 
				
			||||||
#define sin sinl
 | 
					 | 
				
			||||||
#define cos cosl
 | 
					 | 
				
			||||||
#define sqrt sqrtl
 | 
					 | 
				
			||||||
#define pow powl
 | 
					 | 
				
			||||||
#define log logl
 | 
					 | 
				
			||||||
#define tan tanl
 | 
					 | 
				
			||||||
#define atan2 atan2l
 | 
					 | 
				
			||||||
#define floor floorl
 | 
					 | 
				
			||||||
#define ceil ceill
 | 
					 | 
				
			||||||
#define rint rintl
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern int lrint(CPU86_LDouble x);
 | 
					 | 
				
			||||||
extern int64_t llrint(CPU86_LDouble x);
 | 
					 | 
				
			||||||
extern CPU86_LDouble fabs(CPU86_LDouble x);
 | 
					 | 
				
			||||||
extern CPU86_LDouble sin(CPU86_LDouble x);
 | 
					 | 
				
			||||||
extern CPU86_LDouble cos(CPU86_LDouble x);
 | 
					 | 
				
			||||||
extern CPU86_LDouble sqrt(CPU86_LDouble x);
 | 
					 | 
				
			||||||
extern CPU86_LDouble pow(CPU86_LDouble, CPU86_LDouble);
 | 
					 | 
				
			||||||
extern CPU86_LDouble log(CPU86_LDouble x);
 | 
					 | 
				
			||||||
extern CPU86_LDouble tan(CPU86_LDouble x);
 | 
					 | 
				
			||||||
extern CPU86_LDouble atan2(CPU86_LDouble, CPU86_LDouble);
 | 
					 | 
				
			||||||
extern CPU86_LDouble floor(CPU86_LDouble x);
 | 
					 | 
				
			||||||
extern CPU86_LDouble ceil(CPU86_LDouble x);
 | 
					 | 
				
			||||||
extern CPU86_LDouble rint(CPU86_LDouble x);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define RC_MASK         0xc00
 | 
					 | 
				
			||||||
#define RC_NEAR		0x000
 | 
					 | 
				
			||||||
#define RC_DOWN		0x400
 | 
					 | 
				
			||||||
#define RC_UP		0x800
 | 
					 | 
				
			||||||
#define RC_CHOP		0xc00
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define MAXTAN 9223372036854775808.0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef __arm__
 | 
					 | 
				
			||||||
/* we have no way to do correct rounding - a FPU emulator is needed */
 | 
					 | 
				
			||||||
#define FE_DOWNWARD   FE_TONEAREST
 | 
					 | 
				
			||||||
#define FE_UPWARD     FE_TONEAREST
 | 
					 | 
				
			||||||
#define FE_TOWARDZERO FE_TONEAREST
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef USE_X86LDOUBLE
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* only for x86 */
 | 
					 | 
				
			||||||
typedef union {
 | 
					 | 
				
			||||||
    long double d;
 | 
					 | 
				
			||||||
    struct {
 | 
					 | 
				
			||||||
        unsigned long long lower;
 | 
					 | 
				
			||||||
        unsigned short upper;
 | 
					 | 
				
			||||||
    } l;
 | 
					 | 
				
			||||||
} CPU86_LDoubleU;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* the following deal with x86 long double-precision numbers */
 | 
					 | 
				
			||||||
#define MAXEXPD 0x7fff
 | 
					 | 
				
			||||||
#define EXPBIAS 16383
 | 
					 | 
				
			||||||
#define EXPD(fp)	(fp.l.upper & 0x7fff)
 | 
					 | 
				
			||||||
#define SIGND(fp)	((fp.l.upper) & 0x8000)
 | 
					 | 
				
			||||||
#define MANTD(fp)       (fp.l.lower)
 | 
					 | 
				
			||||||
#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7fff)) | EXPBIAS
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */
 | 
					 | 
				
			||||||
typedef union {
 | 
					 | 
				
			||||||
    double d;
 | 
					 | 
				
			||||||
#if !defined(WORDS_BIGENDIAN) && !defined(__arm__)
 | 
					 | 
				
			||||||
    struct {
 | 
					 | 
				
			||||||
        uint32_t lower;
 | 
					 | 
				
			||||||
        int32_t upper;
 | 
					 | 
				
			||||||
    } l;
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
    struct {
 | 
					 | 
				
			||||||
        int32_t upper;
 | 
					 | 
				
			||||||
        uint32_t lower;
 | 
					 | 
				
			||||||
    } l;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#ifndef __arm__
 | 
					 | 
				
			||||||
    int64_t ll;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
} CPU86_LDoubleU;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* the following deal with IEEE double-precision numbers */
 | 
					 | 
				
			||||||
#define MAXEXPD 0x7ff
 | 
					 | 
				
			||||||
#define EXPBIAS 1023
 | 
					 | 
				
			||||||
#define EXPD(fp)	(((fp.l.upper) >> 20) & 0x7FF)
 | 
					 | 
				
			||||||
#define SIGND(fp)	((fp.l.upper) & 0x80000000)
 | 
					 | 
				
			||||||
#ifdef __arm__
 | 
					 | 
				
			||||||
#define MANTD(fp)	(fp.l.lower | ((uint64_t)(fp.l.upper & ((1 << 20) - 1)) << 32))
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
#define MANTD(fp)	(fp.ll & ((1LL << 52) - 1))
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7ff << 20)) | (EXPBIAS << 20)
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void fpush(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    env->fpstt = (env->fpstt - 1) & 7;
 | 
					 | 
				
			||||||
    env->fptags[env->fpstt] = 0; /* validate stack entry */
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void fpop(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    env->fptags[env->fpstt] = 1; /* invvalidate stack entry */
 | 
					 | 
				
			||||||
    env->fpstt = (env->fpstt + 1) & 7;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef USE_X86LDOUBLE
 | 
					 | 
				
			||||||
static inline CPU86_LDouble helper_fldt(uint8_t *ptr)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    CPU86_LDoubleU temp;
 | 
					 | 
				
			||||||
    int upper, e;
 | 
					 | 
				
			||||||
    uint64_t ll;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* mantissa */
 | 
					 | 
				
			||||||
    upper = lduw(ptr + 8);
 | 
					 | 
				
			||||||
    /* XXX: handle overflow ? */
 | 
					 | 
				
			||||||
    e = (upper & 0x7fff) - 16383 + EXPBIAS; /* exponent */
 | 
					 | 
				
			||||||
    e |= (upper >> 4) & 0x800; /* sign */
 | 
					 | 
				
			||||||
    ll = (ldq(ptr) >> 11) & ((1LL << 52) - 1);
 | 
					 | 
				
			||||||
#ifdef __arm__
 | 
					 | 
				
			||||||
    temp.l.upper = (e << 20) | (ll >> 32);
 | 
					 | 
				
			||||||
    temp.l.lower = ll;
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
    temp.ll = ll | ((uint64_t)e << 52);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    return temp.d;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void helper_fstt(CPU86_LDouble f, uint8_t *ptr)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    CPU86_LDoubleU temp;
 | 
					 | 
				
			||||||
    int e;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    temp.d = f;
 | 
					 | 
				
			||||||
    /* mantissa */
 | 
					 | 
				
			||||||
    stq(ptr, (MANTD(temp) << 11) | (1LL << 63));
 | 
					 | 
				
			||||||
    /* exponent + sign */
 | 
					 | 
				
			||||||
    e = EXPD(temp) - EXPBIAS + 16383;
 | 
					 | 
				
			||||||
    e |= SIGND(temp) >> 16;
 | 
					 | 
				
			||||||
    stw(ptr + 8, e);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const CPU86_LDouble f15rk[7];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void helper_fldt_ST0_A0(void);
 | 
					 | 
				
			||||||
void helper_fstt_ST0_A0(void);
 | 
					 | 
				
			||||||
void helper_fbld_ST0_A0(void);
 | 
					 | 
				
			||||||
void helper_fbst_ST0_A0(void);
 | 
					 | 
				
			||||||
void helper_f2xm1(void);
 | 
					 | 
				
			||||||
void helper_fyl2x(void);
 | 
					 | 
				
			||||||
void helper_fptan(void);
 | 
					 | 
				
			||||||
void helper_fpatan(void);
 | 
					 | 
				
			||||||
void helper_fxtract(void);
 | 
					 | 
				
			||||||
void helper_fprem1(void);
 | 
					 | 
				
			||||||
void helper_fprem(void);
 | 
					 | 
				
			||||||
void helper_fyl2xp1(void);
 | 
					 | 
				
			||||||
void helper_fsqrt(void);
 | 
					 | 
				
			||||||
void helper_fsincos(void);
 | 
					 | 
				
			||||||
void helper_frndint(void);
 | 
					 | 
				
			||||||
void helper_fscale(void);
 | 
					 | 
				
			||||||
void helper_fsin(void);
 | 
					 | 
				
			||||||
void helper_fcos(void);
 | 
					 | 
				
			||||||
void helper_fxam_ST0(void);
 | 
					 | 
				
			||||||
void helper_fstenv(uint8_t *ptr, int data32);
 | 
					 | 
				
			||||||
void helper_fldenv(uint8_t *ptr, int data32);
 | 
					 | 
				
			||||||
void helper_fsave(uint8_t *ptr, int data32);
 | 
					 | 
				
			||||||
void helper_frstor(uint8_t *ptr, int data32);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const uint8_t parity_table[256];
 | 
					 | 
				
			||||||
const uint8_t rclw_table[32];
 | 
					 | 
				
			||||||
const uint8_t rclb_table[32];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline uint32_t compute_eflags(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define FL_UPDATE_MASK32 (TF_MASK | AC_MASK | ID_MASK)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define FL_UPDATE_CPL0_MASK (TF_MASK | IF_MASK | IOPL_MASK | NT_MASK | \
 | 
					 | 
				
			||||||
                             RF_MASK | AC_MASK | ID_MASK)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* NOTE: CC_OP must be modified manually to CC_OP_EFLAGS */
 | 
					 | 
				
			||||||
static inline void load_eflags(int eflags, int update_mask)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
 | 
					 | 
				
			||||||
    DF = 1 - (2 * ((eflags >> 10) & 1));
 | 
					 | 
				
			||||||
    env->eflags = (env->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
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
							
								
								
									
										1803
									
								
								helper-i386.c
									
									
									
									
									
								
							
							
						
						
									
										1803
									
								
								helper-i386.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										390
									
								
								helper2-i386.c
									
									
									
									
									
								
							
							
						
						
									
										390
									
								
								helper2-i386.c
									
									
									
									
									
								
							@ -1,390 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 *  i386 helpers (without register variable usage)
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 *  Copyright (c) 2003 Fabrice Bellard
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This library is free software; you can redistribute it and/or
 | 
					 | 
				
			||||||
 * modify it under the terms of the GNU Lesser General Public
 | 
					 | 
				
			||||||
 * License as published by the Free Software Foundation; either
 | 
					 | 
				
			||||||
 * version 2 of the License, or (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This library is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
					 | 
				
			||||||
 * Lesser General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU Lesser General Public
 | 
					 | 
				
			||||||
 * License along with this library; if not, write to the Free Software
 | 
					 | 
				
			||||||
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#include <stdarg.h>
 | 
					 | 
				
			||||||
#include <stdlib.h>
 | 
					 | 
				
			||||||
#include <stdio.h>
 | 
					 | 
				
			||||||
#include <string.h>
 | 
					 | 
				
			||||||
#include <inttypes.h>
 | 
					 | 
				
			||||||
#include <signal.h>
 | 
					 | 
				
			||||||
#include <assert.h>
 | 
					 | 
				
			||||||
#include <sys/mman.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "cpu-i386.h"
 | 
					 | 
				
			||||||
#include "exec.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//#define DEBUG_MMU
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
CPUX86State *cpu_x86_init(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    CPUX86State *env;
 | 
					 | 
				
			||||||
    int i;
 | 
					 | 
				
			||||||
    static int inited;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    cpu_exec_init();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    env = malloc(sizeof(CPUX86State));
 | 
					 | 
				
			||||||
    if (!env)
 | 
					 | 
				
			||||||
        return NULL;
 | 
					 | 
				
			||||||
    memset(env, 0, sizeof(CPUX86State));
 | 
					 | 
				
			||||||
    /* basic FPU init */
 | 
					 | 
				
			||||||
    for(i = 0;i < 8; i++)
 | 
					 | 
				
			||||||
        env->fptags[i] = 1;
 | 
					 | 
				
			||||||
    env->fpuc = 0x37f;
 | 
					 | 
				
			||||||
    /* flags setup : we activate the IRQs by default as in user mode */
 | 
					 | 
				
			||||||
    env->eflags = 0x2 | IF_MASK;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    tlb_flush(env);
 | 
					 | 
				
			||||||
#ifdef CONFIG_SOFTMMU
 | 
					 | 
				
			||||||
    env->hflags |= HF_SOFTMMU_MASK;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    /* init various static tables */
 | 
					 | 
				
			||||||
    if (!inited) {
 | 
					 | 
				
			||||||
        inited = 1;
 | 
					 | 
				
			||||||
        optimize_flags_init();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return env;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void cpu_x86_close(CPUX86State *env)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    free(env);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/***********************************************************/
 | 
					 | 
				
			||||||
/* x86 debug */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const char *cc_op_str[] = {
 | 
					 | 
				
			||||||
    "DYNAMIC",
 | 
					 | 
				
			||||||
    "EFLAGS",
 | 
					 | 
				
			||||||
    "MUL",
 | 
					 | 
				
			||||||
    "ADDB",
 | 
					 | 
				
			||||||
    "ADDW",
 | 
					 | 
				
			||||||
    "ADDL",
 | 
					 | 
				
			||||||
    "ADCB",
 | 
					 | 
				
			||||||
    "ADCW",
 | 
					 | 
				
			||||||
    "ADCL",
 | 
					 | 
				
			||||||
    "SUBB",
 | 
					 | 
				
			||||||
    "SUBW",
 | 
					 | 
				
			||||||
    "SUBL",
 | 
					 | 
				
			||||||
    "SBBB",
 | 
					 | 
				
			||||||
    "SBBW",
 | 
					 | 
				
			||||||
    "SBBL",
 | 
					 | 
				
			||||||
    "LOGICB",
 | 
					 | 
				
			||||||
    "LOGICW",
 | 
					 | 
				
			||||||
    "LOGICL",
 | 
					 | 
				
			||||||
    "INCB",
 | 
					 | 
				
			||||||
    "INCW",
 | 
					 | 
				
			||||||
    "INCL",
 | 
					 | 
				
			||||||
    "DECB",
 | 
					 | 
				
			||||||
    "DECW",
 | 
					 | 
				
			||||||
    "DECL",
 | 
					 | 
				
			||||||
    "SHLB",
 | 
					 | 
				
			||||||
    "SHLW",
 | 
					 | 
				
			||||||
    "SHLL",
 | 
					 | 
				
			||||||
    "SARB",
 | 
					 | 
				
			||||||
    "SARW",
 | 
					 | 
				
			||||||
    "SARL",
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void cpu_x86_dump_state(CPUX86State *env, FILE *f, int flags)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int eflags;
 | 
					 | 
				
			||||||
    char cc_op_name[32];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    eflags = env->eflags;
 | 
					 | 
				
			||||||
    fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
 | 
					 | 
				
			||||||
            "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
 | 
					 | 
				
			||||||
            "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c]\n",
 | 
					 | 
				
			||||||
            env->regs[R_EAX], env->regs[R_EBX], env->regs[R_ECX], env->regs[R_EDX], 
 | 
					 | 
				
			||||||
            env->regs[R_ESI], env->regs[R_EDI], env->regs[R_EBP], env->regs[R_ESP], 
 | 
					 | 
				
			||||||
            env->eip, eflags,
 | 
					 | 
				
			||||||
            eflags & DF_MASK ? 'D' : '-',
 | 
					 | 
				
			||||||
            eflags & CC_O ? 'O' : '-',
 | 
					 | 
				
			||||||
            eflags & CC_S ? 'S' : '-',
 | 
					 | 
				
			||||||
            eflags & CC_Z ? 'Z' : '-',
 | 
					 | 
				
			||||||
            eflags & CC_A ? 'A' : '-',
 | 
					 | 
				
			||||||
            eflags & CC_P ? 'P' : '-',
 | 
					 | 
				
			||||||
            eflags & CC_C ? 'C' : '-');
 | 
					 | 
				
			||||||
    fprintf(f, "CS=%04x SS=%04x DS=%04x ES=%04x FS=%04x GS=%04x\n",
 | 
					 | 
				
			||||||
            env->segs[R_CS].selector,
 | 
					 | 
				
			||||||
            env->segs[R_SS].selector,
 | 
					 | 
				
			||||||
            env->segs[R_DS].selector,
 | 
					 | 
				
			||||||
            env->segs[R_ES].selector,
 | 
					 | 
				
			||||||
            env->segs[R_FS].selector,
 | 
					 | 
				
			||||||
            env->segs[R_GS].selector);
 | 
					 | 
				
			||||||
    if (flags & X86_DUMP_CCOP) {
 | 
					 | 
				
			||||||
        if ((unsigned)env->cc_op < CC_OP_NB)
 | 
					 | 
				
			||||||
            strcpy(cc_op_name, cc_op_str[env->cc_op]);
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
            snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);
 | 
					 | 
				
			||||||
        fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",
 | 
					 | 
				
			||||||
                env->cc_src, env->cc_dst, cc_op_name);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (flags & X86_DUMP_FPU) {
 | 
					 | 
				
			||||||
        fprintf(f, "ST0=%f ST1=%f ST2=%f ST3=%f\n", 
 | 
					 | 
				
			||||||
                (double)env->fpregs[0], 
 | 
					 | 
				
			||||||
                (double)env->fpregs[1], 
 | 
					 | 
				
			||||||
                (double)env->fpregs[2], 
 | 
					 | 
				
			||||||
                (double)env->fpregs[3]);
 | 
					 | 
				
			||||||
        fprintf(f, "ST4=%f ST5=%f ST6=%f ST7=%f\n", 
 | 
					 | 
				
			||||||
                (double)env->fpregs[4], 
 | 
					 | 
				
			||||||
                (double)env->fpregs[5], 
 | 
					 | 
				
			||||||
                (double)env->fpregs[7], 
 | 
					 | 
				
			||||||
                (double)env->fpregs[8]);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/***********************************************************/
 | 
					 | 
				
			||||||
/* x86 mmu */
 | 
					 | 
				
			||||||
/* XXX: add PGE support */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* called when cr3 or PG bit are modified */
 | 
					 | 
				
			||||||
static int last_pg_state = -1;
 | 
					 | 
				
			||||||
static int last_pe_state = 0;
 | 
					 | 
				
			||||||
int phys_ram_size;
 | 
					 | 
				
			||||||
int phys_ram_fd;
 | 
					 | 
				
			||||||
uint8_t *phys_ram_base;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void cpu_x86_update_cr0(CPUX86State *env)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int pg_state, pe_state;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef DEBUG_MMU
 | 
					 | 
				
			||||||
    printf("CR0 update: CR0=0x%08x\n", env->cr[0]);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    pg_state = env->cr[0] & CR0_PG_MASK;
 | 
					 | 
				
			||||||
    if (pg_state != last_pg_state) {
 | 
					 | 
				
			||||||
        page_unmap();
 | 
					 | 
				
			||||||
        tlb_flush(env);
 | 
					 | 
				
			||||||
        last_pg_state = pg_state;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    pe_state = env->cr[0] & CR0_PE_MASK;
 | 
					 | 
				
			||||||
    if (last_pe_state != pe_state) {
 | 
					 | 
				
			||||||
        tb_flush();
 | 
					 | 
				
			||||||
        last_pe_state = pe_state;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void cpu_x86_update_cr3(CPUX86State *env)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if (env->cr[0] & CR0_PG_MASK) {
 | 
					 | 
				
			||||||
#if defined(DEBUG_MMU)
 | 
					 | 
				
			||||||
        printf("CR3 update: CR3=%08x\n", env->cr[3]);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        page_unmap();
 | 
					 | 
				
			||||||
        tlb_flush(env);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void cpu_x86_init_mmu(CPUX86State *env)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    last_pg_state = -1;
 | 
					 | 
				
			||||||
    cpu_x86_update_cr0(env);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* XXX: also flush 4MB pages */
 | 
					 | 
				
			||||||
void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int flags;
 | 
					 | 
				
			||||||
    unsigned long virt_addr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    tlb_flush_page(env, addr);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    flags = page_get_flags(addr);
 | 
					 | 
				
			||||||
    if (flags & PAGE_VALID) {
 | 
					 | 
				
			||||||
        virt_addr = addr & ~0xfff;
 | 
					 | 
				
			||||||
        munmap((void *)virt_addr, 4096);
 | 
					 | 
				
			||||||
        page_set_flags(virt_addr, virt_addr + 4096, 0);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* return value:
 | 
					 | 
				
			||||||
   -1 = cannot handle fault 
 | 
					 | 
				
			||||||
   0  = nothing more to do 
 | 
					 | 
				
			||||||
   1  = generate PF fault
 | 
					 | 
				
			||||||
   2  = soft MMU activation required for this block
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    uint8_t *pde_ptr, *pte_ptr;
 | 
					 | 
				
			||||||
    uint32_t pde, pte, virt_addr;
 | 
					 | 
				
			||||||
    int cpl, error_code, is_dirty, is_user, prot, page_size, ret;
 | 
					 | 
				
			||||||
    unsigned long pd;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    cpl = env->hflags & HF_CPL_MASK;
 | 
					 | 
				
			||||||
    is_user = (cpl == 3);
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
#ifdef DEBUG_MMU
 | 
					 | 
				
			||||||
    printf("MMU fault: addr=0x%08x w=%d u=%d eip=%08x\n", 
 | 
					 | 
				
			||||||
           addr, is_write, is_user, env->eip);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (env->user_mode_only) {
 | 
					 | 
				
			||||||
        /* user mode only emulation */
 | 
					 | 
				
			||||||
        error_code = 0;
 | 
					 | 
				
			||||||
        goto do_fault;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!(env->cr[0] & CR0_PG_MASK)) {
 | 
					 | 
				
			||||||
        pte = addr;
 | 
					 | 
				
			||||||
        virt_addr = addr & ~0xfff;
 | 
					 | 
				
			||||||
        prot = PROT_READ | PROT_WRITE;
 | 
					 | 
				
			||||||
        page_size = 4096;
 | 
					 | 
				
			||||||
        goto do_mapping;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* page directory entry */
 | 
					 | 
				
			||||||
    pde_ptr = phys_ram_base + ((env->cr[3] & ~0xfff) + ((addr >> 20) & ~3));
 | 
					 | 
				
			||||||
    pde = ldl(pde_ptr);
 | 
					 | 
				
			||||||
    if (!(pde & PG_PRESENT_MASK)) {
 | 
					 | 
				
			||||||
        error_code = 0;
 | 
					 | 
				
			||||||
        goto do_fault;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (is_user) {
 | 
					 | 
				
			||||||
        if (!(pde & PG_USER_MASK))
 | 
					 | 
				
			||||||
            goto do_fault_protect;
 | 
					 | 
				
			||||||
        if (is_write && !(pde & PG_RW_MASK))
 | 
					 | 
				
			||||||
            goto do_fault_protect;
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        if ((env->cr[0] & CR0_WP_MASK) && (pde & PG_USER_MASK) &&
 | 
					 | 
				
			||||||
            is_write && !(pde & PG_RW_MASK)) 
 | 
					 | 
				
			||||||
            goto do_fault_protect;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    /* if PSE bit is set, then we use a 4MB page */
 | 
					 | 
				
			||||||
    if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
 | 
					 | 
				
			||||||
        is_dirty = is_write && !(pde & PG_DIRTY_MASK);
 | 
					 | 
				
			||||||
        if (!(pde & PG_ACCESSED_MASK)) {
 | 
					 | 
				
			||||||
            pde |= PG_ACCESSED_MASK;
 | 
					 | 
				
			||||||
            if (is_dirty)
 | 
					 | 
				
			||||||
                pde |= PG_DIRTY_MASK;
 | 
					 | 
				
			||||||
            stl(pde_ptr, pde);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        pte = pde & ~0x003ff000; /* align to 4MB */
 | 
					 | 
				
			||||||
        page_size = 4096 * 1024;
 | 
					 | 
				
			||||||
        virt_addr = addr & ~0x003fffff;
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        if (!(pde & PG_ACCESSED_MASK)) {
 | 
					 | 
				
			||||||
            pde |= PG_ACCESSED_MASK;
 | 
					 | 
				
			||||||
            stl(pde_ptr, pde);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /* page directory entry */
 | 
					 | 
				
			||||||
        pte_ptr = phys_ram_base + ((pde & ~0xfff) + ((addr >> 10) & 0xffc));
 | 
					 | 
				
			||||||
        pte = ldl(pte_ptr);
 | 
					 | 
				
			||||||
        if (!(pte & PG_PRESENT_MASK)) {
 | 
					 | 
				
			||||||
            error_code = 0;
 | 
					 | 
				
			||||||
            goto do_fault;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (is_user) {
 | 
					 | 
				
			||||||
            if (!(pte & PG_USER_MASK))
 | 
					 | 
				
			||||||
                goto do_fault_protect;
 | 
					 | 
				
			||||||
            if (is_write && !(pte & PG_RW_MASK))
 | 
					 | 
				
			||||||
                goto do_fault_protect;
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            if ((env->cr[0] & CR0_WP_MASK) && (pte & PG_USER_MASK) &&
 | 
					 | 
				
			||||||
                is_write && !(pte & PG_RW_MASK)) 
 | 
					 | 
				
			||||||
                goto do_fault_protect;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        is_dirty = is_write && !(pte & PG_DIRTY_MASK);
 | 
					 | 
				
			||||||
        if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
 | 
					 | 
				
			||||||
            pte |= PG_ACCESSED_MASK;
 | 
					 | 
				
			||||||
            if (is_dirty)
 | 
					 | 
				
			||||||
                pte |= PG_DIRTY_MASK;
 | 
					 | 
				
			||||||
            stl(pte_ptr, pte);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        page_size = 4096;
 | 
					 | 
				
			||||||
        virt_addr = addr & ~0xfff;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    /* the page can be put in the TLB */
 | 
					 | 
				
			||||||
    prot = PROT_READ;
 | 
					 | 
				
			||||||
    if (is_user) {
 | 
					 | 
				
			||||||
        if (pte & PG_RW_MASK)
 | 
					 | 
				
			||||||
            prot |= PROT_WRITE;
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        if (!(env->cr[0] & CR0_WP_MASK) || !(pte & PG_USER_MASK) ||
 | 
					 | 
				
			||||||
            (pte & PG_RW_MASK))
 | 
					 | 
				
			||||||
            prot |= PROT_WRITE;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
 do_mapping:
 | 
					 | 
				
			||||||
    if (env->hflags & HF_SOFTMMU_MASK) {
 | 
					 | 
				
			||||||
        unsigned long paddr, vaddr, address, addend, page_offset;
 | 
					 | 
				
			||||||
        int index;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /* software MMU case. Even if 4MB pages, we map only one 4KB
 | 
					 | 
				
			||||||
           page in the cache to avoid filling it too fast */
 | 
					 | 
				
			||||||
        page_offset = (addr & ~0xfff) & (page_size - 1);
 | 
					 | 
				
			||||||
        paddr = (pte & ~0xfff) + page_offset;
 | 
					 | 
				
			||||||
        vaddr = virt_addr + page_offset;
 | 
					 | 
				
			||||||
        index = (addr >> 12) & (CPU_TLB_SIZE - 1);
 | 
					 | 
				
			||||||
        pd = physpage_find(paddr);
 | 
					 | 
				
			||||||
        if (pd & 0xfff) {
 | 
					 | 
				
			||||||
            /* IO memory case */
 | 
					 | 
				
			||||||
            address = vaddr | pd;
 | 
					 | 
				
			||||||
            addend = paddr;
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            /* standard memory */
 | 
					 | 
				
			||||||
            address = vaddr;
 | 
					 | 
				
			||||||
            addend = (unsigned long)phys_ram_base + pd;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        addend -= vaddr;
 | 
					 | 
				
			||||||
        env->tlb_read[is_user][index].address = address;
 | 
					 | 
				
			||||||
        env->tlb_read[is_user][index].addend = addend;
 | 
					 | 
				
			||||||
        if (prot & PROT_WRITE) {
 | 
					 | 
				
			||||||
            env->tlb_write[is_user][index].address = address;
 | 
					 | 
				
			||||||
            env->tlb_write[is_user][index].addend = addend;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    ret = 0;
 | 
					 | 
				
			||||||
    /* XXX: incorrect for 4MB pages */
 | 
					 | 
				
			||||||
    pd = physpage_find(pte & ~0xfff);
 | 
					 | 
				
			||||||
    if ((pd & 0xfff) != 0) {
 | 
					 | 
				
			||||||
        /* IO access: no mapping is done as it will be handled by the
 | 
					 | 
				
			||||||
           soft MMU */
 | 
					 | 
				
			||||||
        if (!(env->hflags & HF_SOFTMMU_MASK))
 | 
					 | 
				
			||||||
            ret = 2;
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        void *map_addr;
 | 
					 | 
				
			||||||
        map_addr = mmap((void *)virt_addr, page_size, prot, 
 | 
					 | 
				
			||||||
                        MAP_SHARED | MAP_FIXED, phys_ram_fd, pd);
 | 
					 | 
				
			||||||
        if (map_addr == MAP_FAILED) {
 | 
					 | 
				
			||||||
            fprintf(stderr, 
 | 
					 | 
				
			||||||
                    "mmap failed when mapped physical address 0x%08x to virtual address 0x%08x\n",
 | 
					 | 
				
			||||||
                    pte & ~0xfff, virt_addr);
 | 
					 | 
				
			||||||
            exit(1);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
#ifdef DEBUG_MMU
 | 
					 | 
				
			||||||
        printf("mmaping 0x%08x to virt 0x%08x pse=%d\n", 
 | 
					 | 
				
			||||||
               pte & ~0xfff, virt_addr, (page_size != 4096));
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        page_set_flags(virt_addr, virt_addr + page_size, 
 | 
					 | 
				
			||||||
                       PAGE_VALID | PAGE_EXEC | prot);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return ret;
 | 
					 | 
				
			||||||
 do_fault_protect:
 | 
					 | 
				
			||||||
    error_code = PG_ERROR_P_MASK;
 | 
					 | 
				
			||||||
 do_fault:
 | 
					 | 
				
			||||||
    env->cr[2] = addr;
 | 
					 | 
				
			||||||
    env->error_code = (is_write << PG_ERROR_W_BIT) | error_code;
 | 
					 | 
				
			||||||
    if (is_user)
 | 
					 | 
				
			||||||
        env->error_code |= PG_ERROR_U_MASK;
 | 
					 | 
				
			||||||
    return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,48 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 *  ARM micro operations (templates for various register related
 | 
					 | 
				
			||||||
 *  operations)
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 *  Copyright (c) 2003 Fabrice Bellard
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This library is free software; you can redistribute it and/or
 | 
					 | 
				
			||||||
 * modify it under the terms of the GNU Lesser General Public
 | 
					 | 
				
			||||||
 * License as published by the Free Software Foundation; either
 | 
					 | 
				
			||||||
 * version 2 of the License, or (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This library is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
					 | 
				
			||||||
 * Lesser General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU Lesser General Public
 | 
					 | 
				
			||||||
 * License along with this library; if not, write to the Free Software
 | 
					 | 
				
			||||||
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(op_movl_T0_, REGNAME)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = REG;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(op_movl_T1_, REGNAME)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T1 = REG;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(op_movl_T2_, REGNAME)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T2 = REG;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_movl_, REGNAME), _T0)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    REG = T0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_movl_, REGNAME), _T1)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    REG = T1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#undef REG
 | 
					 | 
				
			||||||
#undef REGNAME
 | 
					 | 
				
			||||||
							
								
								
									
										673
									
								
								op-arm.c
									
									
									
									
									
								
							
							
						
						
									
										673
									
								
								op-arm.c
									
									
									
									
									
								
							@ -1,673 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 *  ARM micro operations
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 *  Copyright (c) 2003 Fabrice Bellard
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This library is free software; you can redistribute it and/or
 | 
					 | 
				
			||||||
 * modify it under the terms of the GNU Lesser General Public
 | 
					 | 
				
			||||||
 * License as published by the Free Software Foundation; either
 | 
					 | 
				
			||||||
 * version 2 of the License, or (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This library is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
					 | 
				
			||||||
 * Lesser General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU Lesser General Public
 | 
					 | 
				
			||||||
 * License along with this library; if not, write to the Free Software
 | 
					 | 
				
			||||||
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#include "exec-arm.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define REGNAME r0
 | 
					 | 
				
			||||||
#define REG (env->regs[0])
 | 
					 | 
				
			||||||
#include "op-arm-template.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define REGNAME r1
 | 
					 | 
				
			||||||
#define REG (env->regs[1])
 | 
					 | 
				
			||||||
#include "op-arm-template.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define REGNAME r2
 | 
					 | 
				
			||||||
#define REG (env->regs[2])
 | 
					 | 
				
			||||||
#include "op-arm-template.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define REGNAME r3
 | 
					 | 
				
			||||||
#define REG (env->regs[3])
 | 
					 | 
				
			||||||
#include "op-arm-template.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define REGNAME r4
 | 
					 | 
				
			||||||
#define REG (env->regs[4])
 | 
					 | 
				
			||||||
#include "op-arm-template.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define REGNAME r5
 | 
					 | 
				
			||||||
#define REG (env->regs[5])
 | 
					 | 
				
			||||||
#include "op-arm-template.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define REGNAME r6
 | 
					 | 
				
			||||||
#define REG (env->regs[6])
 | 
					 | 
				
			||||||
#include "op-arm-template.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define REGNAME r7
 | 
					 | 
				
			||||||
#define REG (env->regs[7])
 | 
					 | 
				
			||||||
#include "op-arm-template.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define REGNAME r8
 | 
					 | 
				
			||||||
#define REG (env->regs[8])
 | 
					 | 
				
			||||||
#include "op-arm-template.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define REGNAME r9
 | 
					 | 
				
			||||||
#define REG (env->regs[9])
 | 
					 | 
				
			||||||
#include "op-arm-template.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define REGNAME r10
 | 
					 | 
				
			||||||
#define REG (env->regs[10])
 | 
					 | 
				
			||||||
#include "op-arm-template.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define REGNAME r11
 | 
					 | 
				
			||||||
#define REG (env->regs[11])
 | 
					 | 
				
			||||||
#include "op-arm-template.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define REGNAME r12
 | 
					 | 
				
			||||||
#define REG (env->regs[12])
 | 
					 | 
				
			||||||
#include "op-arm-template.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define REGNAME r13
 | 
					 | 
				
			||||||
#define REG (env->regs[13])
 | 
					 | 
				
			||||||
#include "op-arm-template.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define REGNAME r14
 | 
					 | 
				
			||||||
#define REG (env->regs[14])
 | 
					 | 
				
			||||||
#include "op-arm-template.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define REGNAME r15
 | 
					 | 
				
			||||||
#define REG (env->regs[15])
 | 
					 | 
				
			||||||
#include "op-arm-template.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_movl_T0_0(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_movl_T0_im(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = PARAM1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_movl_T1_im(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T1 = PARAM1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_movl_T2_im(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T2 = PARAM1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_addl_T1_im(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T1 += PARAM1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_addl_T1_T2(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T1 += T2;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_subl_T1_T2(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T1 -= T2;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_addl_T0_T1(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 += T1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_addl_T0_T1_cc(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    unsigned int src1;
 | 
					 | 
				
			||||||
    src1 = T0;
 | 
					 | 
				
			||||||
    T0 += T1;
 | 
					 | 
				
			||||||
    env->NZF = T0;
 | 
					 | 
				
			||||||
    env->CF = T0 < src1;
 | 
					 | 
				
			||||||
    env->VF = (src1 ^ T1 ^ -1) & (src1 ^ T0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_adcl_T0_T1(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 += T1 + env->CF;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_adcl_T0_T1_cc(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    unsigned int src1;
 | 
					 | 
				
			||||||
    src1 = T0;
 | 
					 | 
				
			||||||
    if (!env->CF) {
 | 
					 | 
				
			||||||
        T0 += T1;
 | 
					 | 
				
			||||||
        env->CF = T0 < src1;
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        T0 += T1 + 1;
 | 
					 | 
				
			||||||
        env->CF = T0 <= src1;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    env->VF = (src1 ^ T1 ^ -1) & (src1 ^ T0);
 | 
					 | 
				
			||||||
    env->NZF = T0;
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define OPSUB(sub, sbc, res, T0, T1)            \
 | 
					 | 
				
			||||||
                                                \
 | 
					 | 
				
			||||||
void OPPROTO op_ ## sub ## l_T0_T1(void)        \
 | 
					 | 
				
			||||||
{                                               \
 | 
					 | 
				
			||||||
    res = T0 - T1;                              \
 | 
					 | 
				
			||||||
}                                               \
 | 
					 | 
				
			||||||
                                                \
 | 
					 | 
				
			||||||
void OPPROTO op_ ## sub ## l_T0_T1_cc(void)     \
 | 
					 | 
				
			||||||
{                                               \
 | 
					 | 
				
			||||||
    unsigned int src1;                          \
 | 
					 | 
				
			||||||
    src1 = T0;                                  \
 | 
					 | 
				
			||||||
    T0 -= T1;                                   \
 | 
					 | 
				
			||||||
    env->NZF = T0;                              \
 | 
					 | 
				
			||||||
    env->CF = src1 >= T1;                       \
 | 
					 | 
				
			||||||
    env->VF = (src1 ^ T1) & (src1 ^ T0);        \
 | 
					 | 
				
			||||||
    res = T0;                                   \
 | 
					 | 
				
			||||||
}                                               \
 | 
					 | 
				
			||||||
                                                \
 | 
					 | 
				
			||||||
void OPPROTO op_ ## sbc ## l_T0_T1(void)        \
 | 
					 | 
				
			||||||
{                                               \
 | 
					 | 
				
			||||||
    res = T0 - T1 + env->CF - 1;                \
 | 
					 | 
				
			||||||
}                                               \
 | 
					 | 
				
			||||||
                                                \
 | 
					 | 
				
			||||||
void OPPROTO op_ ## sbc ## l_T0_T1_cc(void)     \
 | 
					 | 
				
			||||||
{                                               \
 | 
					 | 
				
			||||||
    unsigned int src1;                          \
 | 
					 | 
				
			||||||
    src1 = T0;                                  \
 | 
					 | 
				
			||||||
    if (!env->CF) {                             \
 | 
					 | 
				
			||||||
        T0 = T0 - T1 - 1;                       \
 | 
					 | 
				
			||||||
        env->CF = src1 >= T1;                   \
 | 
					 | 
				
			||||||
    } else {                                    \
 | 
					 | 
				
			||||||
        T0 = T0 - T1;                           \
 | 
					 | 
				
			||||||
        env->CF = src1 > T1;                    \
 | 
					 | 
				
			||||||
    }                                           \
 | 
					 | 
				
			||||||
    env->VF = (src1 ^ T1) & (src1 ^ T0);        \
 | 
					 | 
				
			||||||
    env->NZF = T0;                              \
 | 
					 | 
				
			||||||
    res = T0;                                   \
 | 
					 | 
				
			||||||
    FORCE_RET();                                \
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
OPSUB(sub, sbc, T0, T0, T1)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
OPSUB(rsb, rsc, T0, T1, T0)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_andl_T0_T1(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 &= T1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_xorl_T0_T1(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 ^= T1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_orl_T0_T1(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 |= T1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_bicl_T0_T1(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 &= ~T1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_notl_T1(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T1 = ~T1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_logic_T0_cc(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    env->NZF = T0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_logic_T1_cc(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    env->NZF = T1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define EIP (env->regs[15])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_test_eq(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if (env->NZF == 0)
 | 
					 | 
				
			||||||
        JUMP_TB(op_test_eq, PARAM1, 0, PARAM2);
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_test_ne(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if (env->NZF != 0)
 | 
					 | 
				
			||||||
        JUMP_TB(op_test_ne, PARAM1, 0, PARAM2);
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_test_cs(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if (env->CF != 0)
 | 
					 | 
				
			||||||
        JUMP_TB(op_test_cs, PARAM1, 0, PARAM2);
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_test_cc(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if (env->CF == 0)
 | 
					 | 
				
			||||||
        JUMP_TB(op_test_cc, PARAM1, 0, PARAM2);
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_test_mi(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if ((env->NZF & 0x80000000) != 0)
 | 
					 | 
				
			||||||
        JUMP_TB(op_test_mi, PARAM1, 0, PARAM2);
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_test_pl(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if ((env->NZF & 0x80000000) == 0)
 | 
					 | 
				
			||||||
        JUMP_TB(op_test_pl, PARAM1, 0, PARAM2);
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_test_vs(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if ((env->VF & 0x80000000) != 0)
 | 
					 | 
				
			||||||
        JUMP_TB(op_test_vs, PARAM1, 0, PARAM2);
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_test_vc(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if ((env->VF & 0x80000000) == 0)
 | 
					 | 
				
			||||||
        JUMP_TB(op_test_vc, PARAM1, 0, PARAM2);
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_test_hi(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if (env->CF != 0 && env->NZF != 0)
 | 
					 | 
				
			||||||
        JUMP_TB(op_test_hi, PARAM1, 0, PARAM2);
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_test_ls(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if (env->CF == 0 || env->NZF == 0)
 | 
					 | 
				
			||||||
        JUMP_TB(op_test_ls, PARAM1, 0, PARAM2);
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_test_ge(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if (((env->VF ^ env->NZF) & 0x80000000) == 0)
 | 
					 | 
				
			||||||
        JUMP_TB(op_test_ge, PARAM1, 0, PARAM2);
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_test_lt(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if (((env->VF ^ env->NZF) & 0x80000000) != 0)
 | 
					 | 
				
			||||||
        JUMP_TB(op_test_lt, PARAM1, 0, PARAM2);
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_test_gt(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if (env->NZF != 0 && ((env->VF ^ env->NZF) & 0x80000000) == 0)
 | 
					 | 
				
			||||||
        JUMP_TB(op_test_gt, PARAM1, 0, PARAM2);
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_test_le(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if (env->NZF == 0 || ((env->VF ^ env->NZF) & 0x80000000) != 0)
 | 
					 | 
				
			||||||
        JUMP_TB(op_test_le, PARAM1, 0, PARAM2);
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_jmp(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    JUMP_TB(op_jmp, PARAM1, 1, PARAM2);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_exit_tb(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    EXIT_TB();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_movl_T0_psr(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = compute_cpsr();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* NOTE: N = 1 and Z = 1 cannot be stored currently */
 | 
					 | 
				
			||||||
void OPPROTO op_movl_psr_T0(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    unsigned int psr;
 | 
					 | 
				
			||||||
    psr = T0;
 | 
					 | 
				
			||||||
    env->CF = (psr >> 29) & 1;
 | 
					 | 
				
			||||||
    env->NZF = (psr & 0xc0000000) ^ 0x40000000;
 | 
					 | 
				
			||||||
    env->VF = (psr << 3) & 0x80000000;
 | 
					 | 
				
			||||||
    /* for user mode we do not update other state info */
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_mul_T0_T1(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = T0 * T1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* 64 bit unsigned mul */
 | 
					 | 
				
			||||||
void OPPROTO op_mull_T0_T1(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    uint64_t res;
 | 
					 | 
				
			||||||
    res = T0 * T1;
 | 
					 | 
				
			||||||
    T1 = res >> 32;
 | 
					 | 
				
			||||||
    T0 = res;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* 64 bit signed mul */
 | 
					 | 
				
			||||||
void OPPROTO op_imull_T0_T1(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    uint64_t res;
 | 
					 | 
				
			||||||
    res = (int32_t)T0 * (int32_t)T1;
 | 
					 | 
				
			||||||
    T1 = res >> 32;
 | 
					 | 
				
			||||||
    T0 = res;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_addq_T0_T1(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    uint64_t res;
 | 
					 | 
				
			||||||
    res = ((uint64_t)T1 << 32) | T0;
 | 
					 | 
				
			||||||
    res += ((uint64_t)(env->regs[PARAM2]) << 32) | (env->regs[PARAM1]);
 | 
					 | 
				
			||||||
    T1 = res >> 32;
 | 
					 | 
				
			||||||
    T0 = res;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_logicq_cc(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    env->NZF = (T1 & 0x80000000) | ((T0 | T1) != 0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* memory access */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_ldub_T0_T1(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = ldub((void *)T1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_ldsb_T0_T1(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = ldsb((void *)T1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_lduw_T0_T1(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = lduw((void *)T1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_ldsw_T0_T1(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = ldsw((void *)T1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_ldl_T0_T1(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = ldl((void *)T1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_stb_T0_T1(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    stb((void *)T1, T0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_stw_T0_T1(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    stw((void *)T1, T0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_stl_T0_T1(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    stl((void *)T1, T0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_swpb_T0_T1(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int tmp;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    cpu_lock();
 | 
					 | 
				
			||||||
    tmp = ldub((void *)T1);
 | 
					 | 
				
			||||||
    stb((void *)T1, T0);
 | 
					 | 
				
			||||||
    T0 = tmp;
 | 
					 | 
				
			||||||
    cpu_unlock();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_swpl_T0_T1(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int tmp;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    cpu_lock();
 | 
					 | 
				
			||||||
    tmp = ldl((void *)T1);
 | 
					 | 
				
			||||||
    stl((void *)T1, T0);
 | 
					 | 
				
			||||||
    T0 = tmp;
 | 
					 | 
				
			||||||
    cpu_unlock();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* shifts */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* T1 based */
 | 
					 | 
				
			||||||
void OPPROTO op_shll_T1_im(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T1 = T1 << PARAM1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_shrl_T1_im(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T1 = (uint32_t)T1 >> PARAM1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_sarl_T1_im(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T1 = (int32_t)T1 >> PARAM1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_rorl_T1_im(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int shift;
 | 
					 | 
				
			||||||
    shift = PARAM1;
 | 
					 | 
				
			||||||
    T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* T1 based, set C flag */
 | 
					 | 
				
			||||||
void OPPROTO op_shll_T1_im_cc(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    env->CF = (T1 >> (32 - PARAM1)) & 1;
 | 
					 | 
				
			||||||
    T1 = T1 << PARAM1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_shrl_T1_im_cc(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    env->CF = (T1 >> (PARAM1 - 1)) & 1;
 | 
					 | 
				
			||||||
    T1 = (uint32_t)T1 >> PARAM1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_sarl_T1_im_cc(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    env->CF = (T1 >> (PARAM1 - 1)) & 1;
 | 
					 | 
				
			||||||
    T1 = (int32_t)T1 >> PARAM1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_rorl_T1_im_cc(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int shift;
 | 
					 | 
				
			||||||
    shift = PARAM1;
 | 
					 | 
				
			||||||
    env->CF = (T1 >> (shift - 1)) & 1;
 | 
					 | 
				
			||||||
    T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* T2 based */
 | 
					 | 
				
			||||||
void OPPROTO op_shll_T2_im(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T2 = T2 << PARAM1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_shrl_T2_im(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T2 = (uint32_t)T2 >> PARAM1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_sarl_T2_im(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T2 = (int32_t)T2 >> PARAM1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_rorl_T2_im(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int shift;
 | 
					 | 
				
			||||||
    shift = PARAM1;
 | 
					 | 
				
			||||||
    T2 = ((uint32_t)T2 >> shift) | (T2 << (32 - shift));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* T1 based, use T0 as shift count */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_shll_T1_T0(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int shift;
 | 
					 | 
				
			||||||
    shift = T0 & 0xff;
 | 
					 | 
				
			||||||
    if (shift >= 32)
 | 
					 | 
				
			||||||
        T1 = 0;
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
        T1 = T1 << shift;
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_shrl_T1_T0(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int shift;
 | 
					 | 
				
			||||||
    shift = T0 & 0xff;
 | 
					 | 
				
			||||||
    if (shift >= 32)
 | 
					 | 
				
			||||||
        T1 = 0;
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
        T1 = (uint32_t)T1 >> shift;
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_sarl_T1_T0(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int shift;
 | 
					 | 
				
			||||||
    shift = T0 & 0xff;
 | 
					 | 
				
			||||||
    if (shift >= 32)
 | 
					 | 
				
			||||||
        shift = 31;
 | 
					 | 
				
			||||||
    T1 = (int32_t)T1 >> shift;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_rorl_T1_T0(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int shift;
 | 
					 | 
				
			||||||
    shift = T0 & 0x1f;
 | 
					 | 
				
			||||||
    if (shift) {
 | 
					 | 
				
			||||||
        T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* T1 based, use T0 as shift count and compute CF */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_shll_T1_T0_cc(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int shift;
 | 
					 | 
				
			||||||
    shift = T0 & 0xff;
 | 
					 | 
				
			||||||
    if (shift >= 32) {
 | 
					 | 
				
			||||||
        if (shift == 32)
 | 
					 | 
				
			||||||
            env->CF = T1 & 1;
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
            env->CF = 0;
 | 
					 | 
				
			||||||
        T1 = 0;
 | 
					 | 
				
			||||||
    } else if (shift != 0) {
 | 
					 | 
				
			||||||
        env->CF = (T1 >> (32 - shift)) & 1;
 | 
					 | 
				
			||||||
        T1 = T1 << shift;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_shrl_T1_T0_cc(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int shift;
 | 
					 | 
				
			||||||
    shift = T0 & 0xff;
 | 
					 | 
				
			||||||
    if (shift >= 32) {
 | 
					 | 
				
			||||||
        if (shift == 32)
 | 
					 | 
				
			||||||
            env->CF = (T1 >> 31) & 1;
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
            env->CF = 0;
 | 
					 | 
				
			||||||
        T1 = 0;
 | 
					 | 
				
			||||||
    } else if (shift != 0) {
 | 
					 | 
				
			||||||
        env->CF = (T1 >> (shift - 1)) & 1;
 | 
					 | 
				
			||||||
        T1 = (uint32_t)T1 >> shift;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_sarl_T1_T0_cc(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int shift;
 | 
					 | 
				
			||||||
    shift = T0 & 0xff;
 | 
					 | 
				
			||||||
    if (shift >= 32) {
 | 
					 | 
				
			||||||
        env->CF = (T1 >> 31) & 1;
 | 
					 | 
				
			||||||
        T1 = (int32_t)T1 >> 31;
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        env->CF = (T1 >> (shift - 1)) & 1;
 | 
					 | 
				
			||||||
        T1 = (int32_t)T1 >> shift;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_rorl_T1_T0_cc(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int shift1, shift;
 | 
					 | 
				
			||||||
    shift1 = T0 & 0xff;
 | 
					 | 
				
			||||||
    shift = shift1 & 0x1f;
 | 
					 | 
				
			||||||
    if (shift == 0) {
 | 
					 | 
				
			||||||
        if (shift1 != 0)
 | 
					 | 
				
			||||||
            env->CF = (T1 >> 31) & 1;
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        env->CF = (T1 >> (shift - 1)) & 1;
 | 
					 | 
				
			||||||
        T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* exceptions */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_swi(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    env->exception_index = EXCP_SWI;
 | 
					 | 
				
			||||||
    cpu_loop_exit();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_undef_insn(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    env->exception_index = EXCP_UDEF;
 | 
					 | 
				
			||||||
    cpu_loop_exit();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* thread support */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void cpu_lock(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    spin_lock(&global_cpu_lock);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void cpu_unlock(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    spin_unlock(&global_cpu_lock);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
							
								
								
									
										134
									
								
								opreg_template.h
									
									
									
									
									
								
							
							
						
						
									
										134
									
								
								opreg_template.h
									
									
									
									
									
								
							@ -1,134 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 *  i386 micro operations (templates for various register related
 | 
					 | 
				
			||||||
 *  operations)
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 *  Copyright (c) 2003 Fabrice Bellard
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This library is free software; you can redistribute it and/or
 | 
					 | 
				
			||||||
 * modify it under the terms of the GNU Lesser General Public
 | 
					 | 
				
			||||||
 * License as published by the Free Software Foundation; either
 | 
					 | 
				
			||||||
 * version 2 of the License, or (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This library is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
					 | 
				
			||||||
 * Lesser General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU Lesser General Public
 | 
					 | 
				
			||||||
 * License along with this library; if not, write to the Free Software
 | 
					 | 
				
			||||||
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void OPPROTO glue(op_movl_A0,REGNAME)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    A0 = REG;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(op_addl_A0,REGNAME)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    A0 += REG;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_addl_A0,REGNAME),_s1)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    A0 += REG << 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_addl_A0,REGNAME),_s2)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    A0 += REG << 2;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_addl_A0,REGNAME),_s3)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    A0 += REG << 3;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(op_movl_T0,REGNAME)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = REG;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(op_movl_T1,REGNAME)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T1 = REG;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(op_movh_T0,REGNAME)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = REG >> 8;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(op_movh_T1,REGNAME)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T1 = REG >> 8;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_movl,REGNAME),_T0)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    REG = T0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_movl,REGNAME),_T1)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    REG = T1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_movl,REGNAME),_A0)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    REG = A0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* mov T1 to REG if T0 is true */
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_cmovw,REGNAME),_T1_T0)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if (T0)
 | 
					 | 
				
			||||||
        REG = (REG & 0xffff0000) | (T1 & 0xffff);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_cmovl,REGNAME),_T1_T0)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if (T0)
 | 
					 | 
				
			||||||
        REG = T1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* NOTE: T0 high order bits are ignored */
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_movw,REGNAME),_T0)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    REG = (REG & 0xffff0000) | (T0 & 0xffff);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* NOTE: T0 high order bits are ignored */
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_movw,REGNAME),_T1)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    REG = (REG & 0xffff0000) | (T1 & 0xffff);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* NOTE: A0 high order bits are ignored */
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_movw,REGNAME),_A0)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    REG = (REG & 0xffff0000) | (A0 & 0xffff);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* NOTE: T0 high order bits are ignored */
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_movb,REGNAME),_T0)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    REG = (REG & 0xffffff00) | (T0 & 0xff);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* NOTE: T0 high order bits are ignored */
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_movh,REGNAME),_T0)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    REG = (REG & 0xffff00ff) | ((T0 & 0xff) << 8);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* NOTE: T1 high order bits are ignored */
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_movb,REGNAME),_T1)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    REG = (REG & 0xffffff00) | (T1 & 0xff);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* NOTE: T1 high order bits are ignored */
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_movh,REGNAME),_T1)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    REG = (REG & 0xffff00ff) | ((T1 & 0xff) << 8);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										66
									
								
								ops_mem.h
									
									
									
									
									
								
							
							
						
						
									
										66
									
								
								ops_mem.h
									
									
									
									
									
								
							@ -1,66 +0,0 @@
 | 
				
			|||||||
void OPPROTO glue(glue(op_ldub, MEMSUFFIX), _T0_A0)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = glue(ldub, MEMSUFFIX)((uint8_t *)A0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_ldsb, MEMSUFFIX), _T0_A0)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = glue(ldsb, MEMSUFFIX)((int8_t *)A0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_lduw, MEMSUFFIX), _T0_A0)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = glue(lduw, MEMSUFFIX)((uint8_t *)A0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_ldsw, MEMSUFFIX), _T0_A0)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = glue(ldsw, MEMSUFFIX)((int8_t *)A0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_ldl, MEMSUFFIX), _T0_A0)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = glue(ldl, MEMSUFFIX)((uint8_t *)A0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_ldub, MEMSUFFIX), _T1_A0)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T1 = glue(ldub, MEMSUFFIX)((uint8_t *)A0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_ldsb, MEMSUFFIX), _T1_A0)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T1 = glue(ldsb, MEMSUFFIX)((int8_t *)A0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_lduw, MEMSUFFIX), _T1_A0)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T1 = glue(lduw, MEMSUFFIX)((uint8_t *)A0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_ldsw, MEMSUFFIX), _T1_A0)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T1 = glue(ldsw, MEMSUFFIX)((int8_t *)A0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_ldl, MEMSUFFIX), _T1_A0)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T1 = glue(ldl, MEMSUFFIX)((uint8_t *)A0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_stb, MEMSUFFIX), _T0_A0)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    glue(stb, MEMSUFFIX)((uint8_t *)A0, T0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_stw, MEMSUFFIX), _T0_A0)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    glue(stw, MEMSUFFIX)((uint8_t *)A0, T0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_stl, MEMSUFFIX), _T0_A0)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    glue(stl, MEMSUFFIX)((uint8_t *)A0, T0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#undef MEMSUFFIX
 | 
					 | 
				
			||||||
							
								
								
									
										617
									
								
								ops_template.h
									
									
									
									
									
								
							
							
						
						
									
										617
									
								
								ops_template.h
									
									
									
									
									
								
							@ -1,617 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 *  i386 micro operations (included several times to generate
 | 
					 | 
				
			||||||
 *  different operand sizes)
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 *  Copyright (c) 2003 Fabrice Bellard
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This library is free software; you can redistribute it and/or
 | 
					 | 
				
			||||||
 * modify it under the terms of the GNU Lesser General Public
 | 
					 | 
				
			||||||
 * License as published by the Free Software Foundation; either
 | 
					 | 
				
			||||||
 * version 2 of the License, or (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This library is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
					 | 
				
			||||||
 * Lesser General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU Lesser General Public
 | 
					 | 
				
			||||||
 * License along with this library; if not, write to the Free Software
 | 
					 | 
				
			||||||
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define DATA_BITS (1 << (3 + SHIFT))
 | 
					 | 
				
			||||||
#define SHIFT_MASK (DATA_BITS - 1)
 | 
					 | 
				
			||||||
#define SIGN_MASK (1 << (DATA_BITS - 1))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if DATA_BITS == 8
 | 
					 | 
				
			||||||
#define SUFFIX b
 | 
					 | 
				
			||||||
#define DATA_TYPE uint8_t
 | 
					 | 
				
			||||||
#define DATA_STYPE int8_t
 | 
					 | 
				
			||||||
#define DATA_MASK 0xff
 | 
					 | 
				
			||||||
#elif DATA_BITS == 16
 | 
					 | 
				
			||||||
#define SUFFIX w
 | 
					 | 
				
			||||||
#define DATA_TYPE uint16_t
 | 
					 | 
				
			||||||
#define DATA_STYPE int16_t
 | 
					 | 
				
			||||||
#define DATA_MASK 0xffff
 | 
					 | 
				
			||||||
#elif DATA_BITS == 32
 | 
					 | 
				
			||||||
#define SUFFIX l
 | 
					 | 
				
			||||||
#define DATA_TYPE uint32_t
 | 
					 | 
				
			||||||
#define DATA_STYPE int32_t
 | 
					 | 
				
			||||||
#define DATA_MASK 0xffffffff
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
#error unhandled operand size
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* dynamic flags computation */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int glue(compute_all_add, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int cf, pf, af, zf, sf, of;
 | 
					 | 
				
			||||||
    int src1, src2;
 | 
					 | 
				
			||||||
    src1 = CC_SRC;
 | 
					 | 
				
			||||||
    src2 = CC_DST - CC_SRC;
 | 
					 | 
				
			||||||
    cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1;
 | 
					 | 
				
			||||||
    pf = parity_table[(uint8_t)CC_DST];
 | 
					 | 
				
			||||||
    af = (CC_DST ^ src1 ^ src2) & 0x10;
 | 
					 | 
				
			||||||
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
 | 
					 | 
				
			||||||
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
 | 
					 | 
				
			||||||
    of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
 | 
					 | 
				
			||||||
    return cf | pf | af | zf | sf | of;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int glue(compute_c_add, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int src1, cf;
 | 
					 | 
				
			||||||
    src1 = CC_SRC;
 | 
					 | 
				
			||||||
    cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1;
 | 
					 | 
				
			||||||
    return cf;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int glue(compute_all_adc, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int cf, pf, af, zf, sf, of;
 | 
					 | 
				
			||||||
    int src1, src2;
 | 
					 | 
				
			||||||
    src1 = CC_SRC;
 | 
					 | 
				
			||||||
    src2 = CC_DST - CC_SRC - 1;
 | 
					 | 
				
			||||||
    cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
 | 
					 | 
				
			||||||
    pf = parity_table[(uint8_t)CC_DST];
 | 
					 | 
				
			||||||
    af = (CC_DST ^ src1 ^ src2) & 0x10;
 | 
					 | 
				
			||||||
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
 | 
					 | 
				
			||||||
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
 | 
					 | 
				
			||||||
    of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
 | 
					 | 
				
			||||||
    return cf | pf | af | zf | sf | of;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int glue(compute_c_adc, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int src1, cf;
 | 
					 | 
				
			||||||
    src1 = CC_SRC;
 | 
					 | 
				
			||||||
    cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
 | 
					 | 
				
			||||||
    return cf;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int glue(compute_all_sub, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int cf, pf, af, zf, sf, of;
 | 
					 | 
				
			||||||
    int src1, src2;
 | 
					 | 
				
			||||||
    src1 = CC_DST + CC_SRC;
 | 
					 | 
				
			||||||
    src2 = CC_SRC;
 | 
					 | 
				
			||||||
    cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
 | 
					 | 
				
			||||||
    pf = parity_table[(uint8_t)CC_DST];
 | 
					 | 
				
			||||||
    af = (CC_DST ^ src1 ^ src2) & 0x10;
 | 
					 | 
				
			||||||
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
 | 
					 | 
				
			||||||
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
 | 
					 | 
				
			||||||
    of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
 | 
					 | 
				
			||||||
    return cf | pf | af | zf | sf | of;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int glue(compute_c_sub, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int src1, src2, cf;
 | 
					 | 
				
			||||||
    src1 = CC_DST + CC_SRC;
 | 
					 | 
				
			||||||
    src2 = CC_SRC;
 | 
					 | 
				
			||||||
    cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
 | 
					 | 
				
			||||||
    return cf;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int glue(compute_all_sbb, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int cf, pf, af, zf, sf, of;
 | 
					 | 
				
			||||||
    int src1, src2;
 | 
					 | 
				
			||||||
    src1 = CC_DST + CC_SRC + 1;
 | 
					 | 
				
			||||||
    src2 = CC_SRC;
 | 
					 | 
				
			||||||
    cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
 | 
					 | 
				
			||||||
    pf = parity_table[(uint8_t)CC_DST];
 | 
					 | 
				
			||||||
    af = (CC_DST ^ src1 ^ src2) & 0x10;
 | 
					 | 
				
			||||||
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
 | 
					 | 
				
			||||||
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
 | 
					 | 
				
			||||||
    of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
 | 
					 | 
				
			||||||
    return cf | pf | af | zf | sf | of;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int glue(compute_c_sbb, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int src1, src2, cf;
 | 
					 | 
				
			||||||
    src1 = CC_DST + CC_SRC + 1;
 | 
					 | 
				
			||||||
    src2 = CC_SRC;
 | 
					 | 
				
			||||||
    cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
 | 
					 | 
				
			||||||
    return cf;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int glue(compute_all_logic, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int cf, pf, af, zf, sf, of;
 | 
					 | 
				
			||||||
    cf = 0;
 | 
					 | 
				
			||||||
    pf = parity_table[(uint8_t)CC_DST];
 | 
					 | 
				
			||||||
    af = 0;
 | 
					 | 
				
			||||||
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
 | 
					 | 
				
			||||||
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
 | 
					 | 
				
			||||||
    of = 0;
 | 
					 | 
				
			||||||
    return cf | pf | af | zf | sf | of;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int glue(compute_c_logic, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int glue(compute_all_inc, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int cf, pf, af, zf, sf, of;
 | 
					 | 
				
			||||||
    int src1, src2;
 | 
					 | 
				
			||||||
    src1 = CC_DST - 1;
 | 
					 | 
				
			||||||
    src2 = 1;
 | 
					 | 
				
			||||||
    cf = CC_SRC;
 | 
					 | 
				
			||||||
    pf = parity_table[(uint8_t)CC_DST];
 | 
					 | 
				
			||||||
    af = (CC_DST ^ src1 ^ src2) & 0x10;
 | 
					 | 
				
			||||||
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
 | 
					 | 
				
			||||||
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
 | 
					 | 
				
			||||||
    of = ((CC_DST & DATA_MASK) == SIGN_MASK) << 11;
 | 
					 | 
				
			||||||
    return cf | pf | af | zf | sf | of;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if DATA_BITS == 32
 | 
					 | 
				
			||||||
static int glue(compute_c_inc, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return CC_SRC;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int glue(compute_all_dec, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int cf, pf, af, zf, sf, of;
 | 
					 | 
				
			||||||
    int src1, src2;
 | 
					 | 
				
			||||||
    src1 = CC_DST + 1;
 | 
					 | 
				
			||||||
    src2 = 1;
 | 
					 | 
				
			||||||
    cf = CC_SRC;
 | 
					 | 
				
			||||||
    pf = parity_table[(uint8_t)CC_DST];
 | 
					 | 
				
			||||||
    af = (CC_DST ^ src1 ^ src2) & 0x10;
 | 
					 | 
				
			||||||
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
 | 
					 | 
				
			||||||
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
 | 
					 | 
				
			||||||
    of = ((CC_DST & DATA_MASK) == ((uint32_t)SIGN_MASK - 1)) << 11;
 | 
					 | 
				
			||||||
    return cf | pf | af | zf | sf | of;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int glue(compute_all_shl, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int cf, pf, af, zf, sf, of;
 | 
					 | 
				
			||||||
    cf = (CC_SRC >> (DATA_BITS - 1)) & CC_C;
 | 
					 | 
				
			||||||
    pf = parity_table[(uint8_t)CC_DST];
 | 
					 | 
				
			||||||
    af = 0; /* undefined */
 | 
					 | 
				
			||||||
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
 | 
					 | 
				
			||||||
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
 | 
					 | 
				
			||||||
    /* of is defined if shift count == 1 */
 | 
					 | 
				
			||||||
    of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O;
 | 
					 | 
				
			||||||
    return cf | pf | af | zf | sf | of;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int glue(compute_c_shl, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return (CC_SRC >> (DATA_BITS - 1)) & CC_C;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if DATA_BITS == 32
 | 
					 | 
				
			||||||
static int glue(compute_c_sar, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return CC_SRC & 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int glue(compute_all_sar, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int cf, pf, af, zf, sf, of;
 | 
					 | 
				
			||||||
    cf = CC_SRC & 1;
 | 
					 | 
				
			||||||
    pf = parity_table[(uint8_t)CC_DST];
 | 
					 | 
				
			||||||
    af = 0; /* undefined */
 | 
					 | 
				
			||||||
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
 | 
					 | 
				
			||||||
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
 | 
					 | 
				
			||||||
    /* of is defined if shift count == 1 */
 | 
					 | 
				
			||||||
    of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O; 
 | 
					 | 
				
			||||||
    return cf | pf | af | zf | sf | of;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* various optimized jumps cases */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(op_jb_sub, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int src1, src2;
 | 
					 | 
				
			||||||
    src1 = CC_DST + CC_SRC;
 | 
					 | 
				
			||||||
    src2 = CC_SRC;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if ((DATA_TYPE)src1 < (DATA_TYPE)src2)
 | 
					 | 
				
			||||||
        JUMP_TB(glue(op_jb_sub, SUFFIX), PARAM1, 0, PARAM2);
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
        JUMP_TB(glue(op_jb_sub, SUFFIX), PARAM1, 1, PARAM3);
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(op_jz_sub, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if ((DATA_TYPE)CC_DST == 0)
 | 
					 | 
				
			||||||
        JUMP_TB(glue(op_jz_sub, SUFFIX), PARAM1, 0, PARAM2);
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
        JUMP_TB(glue(op_jz_sub, SUFFIX), PARAM1, 1, PARAM3);
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(op_jbe_sub, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int src1, src2;
 | 
					 | 
				
			||||||
    src1 = CC_DST + CC_SRC;
 | 
					 | 
				
			||||||
    src2 = CC_SRC;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if ((DATA_TYPE)src1 <= (DATA_TYPE)src2)
 | 
					 | 
				
			||||||
        JUMP_TB(glue(op_jbe_sub, SUFFIX), PARAM1, 0, PARAM2);
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
        JUMP_TB(glue(op_jbe_sub, SUFFIX), PARAM1, 1, PARAM3);
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(op_js_sub, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if (CC_DST & SIGN_MASK)
 | 
					 | 
				
			||||||
        JUMP_TB(glue(op_js_sub, SUFFIX), PARAM1, 0, PARAM2);
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
        JUMP_TB(glue(op_js_sub, SUFFIX), PARAM1, 1, PARAM3);
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(op_jl_sub, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int src1, src2;
 | 
					 | 
				
			||||||
    src1 = CC_DST + CC_SRC;
 | 
					 | 
				
			||||||
    src2 = CC_SRC;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if ((DATA_STYPE)src1 < (DATA_STYPE)src2)
 | 
					 | 
				
			||||||
        JUMP_TB(glue(op_jl_sub, SUFFIX), PARAM1, 0, PARAM2);
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
        JUMP_TB(glue(op_jl_sub, SUFFIX), PARAM1, 1, PARAM3);
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(op_jle_sub, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int src1, src2;
 | 
					 | 
				
			||||||
    src1 = CC_DST + CC_SRC;
 | 
					 | 
				
			||||||
    src2 = CC_SRC;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if ((DATA_STYPE)src1 <= (DATA_STYPE)src2)
 | 
					 | 
				
			||||||
        JUMP_TB(glue(op_jle_sub, SUFFIX), PARAM1, 0, PARAM2);
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
        JUMP_TB(glue(op_jle_sub, SUFFIX), PARAM1, 1, PARAM3);
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* oldies */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if DATA_BITS >= 16
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(op_loopnz, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    unsigned int tmp;
 | 
					 | 
				
			||||||
    int eflags;
 | 
					 | 
				
			||||||
    eflags = cc_table[CC_OP].compute_all();
 | 
					 | 
				
			||||||
    tmp = (ECX - 1) & DATA_MASK;
 | 
					 | 
				
			||||||
    ECX = (ECX & ~DATA_MASK) | tmp;
 | 
					 | 
				
			||||||
    if (tmp != 0 && !(eflags & CC_Z))
 | 
					 | 
				
			||||||
        EIP = PARAM1;
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
        EIP = PARAM2;
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(op_loopz, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    unsigned int tmp;
 | 
					 | 
				
			||||||
    int eflags;
 | 
					 | 
				
			||||||
    eflags = cc_table[CC_OP].compute_all();
 | 
					 | 
				
			||||||
    tmp = (ECX - 1) & DATA_MASK;
 | 
					 | 
				
			||||||
    ECX = (ECX & ~DATA_MASK) | tmp;
 | 
					 | 
				
			||||||
    if (tmp != 0 && (eflags & CC_Z))
 | 
					 | 
				
			||||||
        EIP = PARAM1;
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
        EIP = PARAM2;
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(op_loop, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    unsigned int tmp;
 | 
					 | 
				
			||||||
    tmp = (ECX - 1) & DATA_MASK;
 | 
					 | 
				
			||||||
    ECX = (ECX & ~DATA_MASK) | tmp;
 | 
					 | 
				
			||||||
    if (tmp != 0)
 | 
					 | 
				
			||||||
        EIP = PARAM1;
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
        EIP = PARAM2;
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(op_jecxz, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if ((DATA_TYPE)ECX == 0)
 | 
					 | 
				
			||||||
        EIP = PARAM1;
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
        EIP = PARAM2;
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* various optimized set cases */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(op_setb_T0_sub, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int src1, src2;
 | 
					 | 
				
			||||||
    src1 = CC_DST + CC_SRC;
 | 
					 | 
				
			||||||
    src2 = CC_SRC;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    T0 = ((DATA_TYPE)src1 < (DATA_TYPE)src2);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(op_setz_T0_sub, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = ((DATA_TYPE)CC_DST == 0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(op_setbe_T0_sub, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int src1, src2;
 | 
					 | 
				
			||||||
    src1 = CC_DST + CC_SRC;
 | 
					 | 
				
			||||||
    src2 = CC_SRC;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    T0 = ((DATA_TYPE)src1 <= (DATA_TYPE)src2);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(op_sets_T0_sub, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = lshift(CC_DST, -(DATA_BITS - 1)) & 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(op_setl_T0_sub, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int src1, src2;
 | 
					 | 
				
			||||||
    src1 = CC_DST + CC_SRC;
 | 
					 | 
				
			||||||
    src2 = CC_SRC;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    T0 = ((DATA_STYPE)src1 < (DATA_STYPE)src2);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(op_setle_T0_sub, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int src1, src2;
 | 
					 | 
				
			||||||
    src1 = CC_DST + CC_SRC;
 | 
					 | 
				
			||||||
    src2 = CC_SRC;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    T0 = ((DATA_STYPE)src1 <= (DATA_STYPE)src2);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* shifts */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int count;
 | 
					 | 
				
			||||||
    count = T1 & 0x1f;
 | 
					 | 
				
			||||||
    T0 = T0 << count;
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int count;
 | 
					 | 
				
			||||||
    count = T1 & 0x1f;
 | 
					 | 
				
			||||||
    T0 &= DATA_MASK;
 | 
					 | 
				
			||||||
    T0 = T0 >> count;
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int count, src;
 | 
					 | 
				
			||||||
    count = T1 & 0x1f;
 | 
					 | 
				
			||||||
    src = (DATA_STYPE)T0;
 | 
					 | 
				
			||||||
    T0 = src >> count;
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#undef MEM_WRITE
 | 
					 | 
				
			||||||
#include "ops_template_mem.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define MEM_WRITE
 | 
					 | 
				
			||||||
#include "ops_template_mem.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* bit operations */
 | 
					 | 
				
			||||||
#if DATA_BITS >= 16
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_bt, SUFFIX), _T0_T1_cc)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int count;
 | 
					 | 
				
			||||||
    count = T1 & SHIFT_MASK;
 | 
					 | 
				
			||||||
    CC_SRC = T0 >> count;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_bts, SUFFIX), _T0_T1_cc)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int count;
 | 
					 | 
				
			||||||
    count = T1 & SHIFT_MASK;
 | 
					 | 
				
			||||||
    T1 = T0 >> count;
 | 
					 | 
				
			||||||
    T0 |= (1 << count);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_btr, SUFFIX), _T0_T1_cc)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int count;
 | 
					 | 
				
			||||||
    count = T1 & SHIFT_MASK;
 | 
					 | 
				
			||||||
    T1 = T0 >> count;
 | 
					 | 
				
			||||||
    T0 &= ~(1 << count);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_btc, SUFFIX), _T0_T1_cc)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int count;
 | 
					 | 
				
			||||||
    count = T1 & SHIFT_MASK;
 | 
					 | 
				
			||||||
    T1 = T0 >> count;
 | 
					 | 
				
			||||||
    T0 ^= (1 << count);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_bsf, SUFFIX), _T0_cc)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int res, count;
 | 
					 | 
				
			||||||
    res = T0 & DATA_MASK;
 | 
					 | 
				
			||||||
    if (res != 0) {
 | 
					 | 
				
			||||||
        count = 0;
 | 
					 | 
				
			||||||
        while ((res & 1) == 0) {
 | 
					 | 
				
			||||||
            count++;
 | 
					 | 
				
			||||||
            res >>= 1;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        T0 = count;
 | 
					 | 
				
			||||||
        CC_DST = 1; /* ZF = 1 */
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        CC_DST = 0; /* ZF = 1 */
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_bsr, SUFFIX), _T0_cc)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int res, count;
 | 
					 | 
				
			||||||
    res = T0 & DATA_MASK;
 | 
					 | 
				
			||||||
    if (res != 0) {
 | 
					 | 
				
			||||||
        count = DATA_BITS - 1;
 | 
					 | 
				
			||||||
        while ((res & SIGN_MASK) == 0) {
 | 
					 | 
				
			||||||
            count--;
 | 
					 | 
				
			||||||
            res <<= 1;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        T0 = count;
 | 
					 | 
				
			||||||
        CC_DST = 1; /* ZF = 1 */
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        CC_DST = 0; /* ZF = 1 */
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if DATA_BITS == 32
 | 
					 | 
				
			||||||
void OPPROTO op_update_bt_cc(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    CC_SRC = T1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* string operations */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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_TB2(glue(op_string_jz_sub, SUFFIX), PARAM1, 1);
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(op_string_jnz_sub, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if ((DATA_TYPE)CC_DST != 0)
 | 
					 | 
				
			||||||
        JUMP_TB2(glue(op_string_jnz_sub, SUFFIX), PARAM1, 1);
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_string_jz_sub, SUFFIX), _im)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if ((DATA_TYPE)CC_DST == 0) {
 | 
					 | 
				
			||||||
        EIP = PARAM1;
 | 
					 | 
				
			||||||
        if (env->eflags & TF_MASK) {
 | 
					 | 
				
			||||||
            raise_exception(EXCP01_SSTP);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        T0 = 0;
 | 
					 | 
				
			||||||
        EXIT_TB();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_string_jnz_sub, SUFFIX), _im)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if ((DATA_TYPE)CC_DST != 0) {
 | 
					 | 
				
			||||||
        EIP = PARAM1;
 | 
					 | 
				
			||||||
        if (env->eflags & TF_MASK) {
 | 
					 | 
				
			||||||
            raise_exception(EXCP01_SSTP);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        T0 = 0;
 | 
					 | 
				
			||||||
        EXIT_TB();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if DATA_BITS >= 16
 | 
					 | 
				
			||||||
void OPPROTO glue(op_jz_ecx, SUFFIX)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if ((DATA_TYPE)ECX == 0)
 | 
					 | 
				
			||||||
        JUMP_TB(glue(op_jz_ecx, SUFFIX), PARAM1, 1, PARAM2);
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_jz_ecx, SUFFIX), _im)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if ((DATA_TYPE)ECX == 0) {
 | 
					 | 
				
			||||||
        EIP = PARAM1;
 | 
					 | 
				
			||||||
        if (env->eflags & TF_MASK) {
 | 
					 | 
				
			||||||
            raise_exception(EXCP01_SSTP);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        T0 = 0;
 | 
					 | 
				
			||||||
        EXIT_TB();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* port I/O */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_out, SUFFIX), _T0_T1)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    glue(cpu_x86_out, SUFFIX)(env, T0 & 0xffff, T1 & DATA_MASK);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_in, SUFFIX), _T0_T1)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    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 SHIFT_MASK
 | 
					 | 
				
			||||||
#undef SIGN_MASK
 | 
					 | 
				
			||||||
#undef DATA_TYPE
 | 
					 | 
				
			||||||
#undef DATA_STYPE
 | 
					 | 
				
			||||||
#undef DATA_MASK
 | 
					 | 
				
			||||||
#undef SUFFIX
 | 
					 | 
				
			||||||
@ -1,429 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 *  i386 micro operations (included several times to generate
 | 
					 | 
				
			||||||
 *  different operand sizes)
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 *  Copyright (c) 2003 Fabrice Bellard
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This library is free software; you can redistribute it and/or
 | 
					 | 
				
			||||||
 * modify it under the terms of the GNU Lesser General Public
 | 
					 | 
				
			||||||
 * License as published by the Free Software Foundation; either
 | 
					 | 
				
			||||||
 * version 2 of the License, or (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This library is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
					 | 
				
			||||||
 * Lesser General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU Lesser General Public
 | 
					 | 
				
			||||||
 * License along with this library; if not, write to the Free Software
 | 
					 | 
				
			||||||
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#ifdef MEM_WRITE
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if DATA_BITS == 8
 | 
					 | 
				
			||||||
#define MEM_SUFFIX b_mem
 | 
					 | 
				
			||||||
#elif DATA_BITS == 16
 | 
					 | 
				
			||||||
#define MEM_SUFFIX w_mem
 | 
					 | 
				
			||||||
#elif DATA_BITS == 32
 | 
					 | 
				
			||||||
#define MEM_SUFFIX l_mem
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define MEM_SUFFIX SUFFIX
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_rol, MEM_SUFFIX), _T0_T1_cc)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int count, src;
 | 
					 | 
				
			||||||
    count = T1 & SHIFT_MASK;
 | 
					 | 
				
			||||||
    if (count) {
 | 
					 | 
				
			||||||
        src = T0;
 | 
					 | 
				
			||||||
        T0 &= DATA_MASK;
 | 
					 | 
				
			||||||
        T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
 | 
					 | 
				
			||||||
#ifdef MEM_WRITE
 | 
					 | 
				
			||||||
        glue(st, SUFFIX)((uint8_t *)A0, T0);
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
        /* gcc 3.2 workaround. This is really a bug in gcc. */
 | 
					 | 
				
			||||||
        asm volatile("" : : "r" (T0));
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        CC_SRC = (cc_table[CC_OP].compute_all() & ~(CC_O | CC_C)) | 
 | 
					 | 
				
			||||||
            (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) | 
 | 
					 | 
				
			||||||
            (T0 & CC_C);
 | 
					 | 
				
			||||||
        CC_OP = CC_OP_EFLAGS;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_ror, MEM_SUFFIX), _T0_T1_cc)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int count, src;
 | 
					 | 
				
			||||||
    count = T1 & SHIFT_MASK;
 | 
					 | 
				
			||||||
    if (count) {
 | 
					 | 
				
			||||||
        src = T0;
 | 
					 | 
				
			||||||
        T0 &= DATA_MASK;
 | 
					 | 
				
			||||||
        T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
 | 
					 | 
				
			||||||
#ifdef MEM_WRITE
 | 
					 | 
				
			||||||
        glue(st, SUFFIX)((uint8_t *)A0, T0);
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
        /* gcc 3.2 workaround. This is really a bug in gcc. */
 | 
					 | 
				
			||||||
        asm volatile("" : : "r" (T0));
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        CC_SRC = (cc_table[CC_OP].compute_all() & ~(CC_O | CC_C)) |
 | 
					 | 
				
			||||||
            (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) | 
 | 
					 | 
				
			||||||
            ((T0 >> (DATA_BITS - 1)) & CC_C);
 | 
					 | 
				
			||||||
        CC_OP = CC_OP_EFLAGS;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_rol, MEM_SUFFIX), _T0_T1)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int count;
 | 
					 | 
				
			||||||
    count = T1 & SHIFT_MASK;
 | 
					 | 
				
			||||||
    if (count) {
 | 
					 | 
				
			||||||
        T0 &= DATA_MASK;
 | 
					 | 
				
			||||||
        T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
 | 
					 | 
				
			||||||
#ifdef MEM_WRITE
 | 
					 | 
				
			||||||
        glue(st, SUFFIX)((uint8_t *)A0, T0);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_ror, MEM_SUFFIX), _T0_T1)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int count;
 | 
					 | 
				
			||||||
    count = T1 & SHIFT_MASK;
 | 
					 | 
				
			||||||
    if (count) {
 | 
					 | 
				
			||||||
        T0 &= DATA_MASK;
 | 
					 | 
				
			||||||
        T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
 | 
					 | 
				
			||||||
#ifdef MEM_WRITE
 | 
					 | 
				
			||||||
        glue(st, SUFFIX)((uint8_t *)A0, T0);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_rcl, MEM_SUFFIX), _T0_T1_cc)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int count, res, eflags;
 | 
					 | 
				
			||||||
    unsigned int src;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    count = T1 & 0x1f;
 | 
					 | 
				
			||||||
#if DATA_BITS == 16
 | 
					 | 
				
			||||||
    count = rclw_table[count];
 | 
					 | 
				
			||||||
#elif DATA_BITS == 8
 | 
					 | 
				
			||||||
    count = rclb_table[count];
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    if (count) {
 | 
					 | 
				
			||||||
        eflags = cc_table[CC_OP].compute_all();
 | 
					 | 
				
			||||||
        T0 &= DATA_MASK;
 | 
					 | 
				
			||||||
        src = T0;
 | 
					 | 
				
			||||||
        res = (T0 << count) | ((eflags & CC_C) << (count - 1));
 | 
					 | 
				
			||||||
        if (count > 1)
 | 
					 | 
				
			||||||
            res |= T0 >> (DATA_BITS + 1 - count);
 | 
					 | 
				
			||||||
        T0 = res;
 | 
					 | 
				
			||||||
#ifdef MEM_WRITE
 | 
					 | 
				
			||||||
        glue(st, SUFFIX)((uint8_t *)A0, T0);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        CC_SRC = (eflags & ~(CC_C | CC_O)) |
 | 
					 | 
				
			||||||
            (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) | 
 | 
					 | 
				
			||||||
            ((src >> (DATA_BITS - count)) & CC_C);
 | 
					 | 
				
			||||||
        CC_OP = CC_OP_EFLAGS;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_rcr, MEM_SUFFIX), _T0_T1_cc)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int count, res, eflags;
 | 
					 | 
				
			||||||
    unsigned int src;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    count = T1 & 0x1f;
 | 
					 | 
				
			||||||
#if DATA_BITS == 16
 | 
					 | 
				
			||||||
    count = rclw_table[count];
 | 
					 | 
				
			||||||
#elif DATA_BITS == 8
 | 
					 | 
				
			||||||
    count = rclb_table[count];
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    if (count) {
 | 
					 | 
				
			||||||
        eflags = cc_table[CC_OP].compute_all();
 | 
					 | 
				
			||||||
        T0 &= DATA_MASK;
 | 
					 | 
				
			||||||
        src = T0;
 | 
					 | 
				
			||||||
        res = (T0 >> count) | ((eflags & CC_C) << (DATA_BITS - count));
 | 
					 | 
				
			||||||
        if (count > 1)
 | 
					 | 
				
			||||||
            res |= T0 << (DATA_BITS + 1 - count);
 | 
					 | 
				
			||||||
        T0 = res;
 | 
					 | 
				
			||||||
#ifdef MEM_WRITE
 | 
					 | 
				
			||||||
        glue(st, SUFFIX)((uint8_t *)A0, T0);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        CC_SRC = (eflags & ~(CC_C | CC_O)) |
 | 
					 | 
				
			||||||
            (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) | 
 | 
					 | 
				
			||||||
            ((src >> (count - 1)) & CC_C);
 | 
					 | 
				
			||||||
        CC_OP = CC_OP_EFLAGS;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_shl, MEM_SUFFIX), _T0_T1_cc)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int count, src;
 | 
					 | 
				
			||||||
    count = T1 & 0x1f;
 | 
					 | 
				
			||||||
    if (count) {
 | 
					 | 
				
			||||||
        src = (DATA_TYPE)T0 << (count - 1);
 | 
					 | 
				
			||||||
        T0 = T0 << count;
 | 
					 | 
				
			||||||
#ifdef MEM_WRITE
 | 
					 | 
				
			||||||
        glue(st, SUFFIX)((uint8_t *)A0, T0);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        CC_SRC = src;
 | 
					 | 
				
			||||||
        CC_DST = T0;
 | 
					 | 
				
			||||||
        CC_OP = CC_OP_SHLB + SHIFT;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_shr, MEM_SUFFIX), _T0_T1_cc)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int count, src;
 | 
					 | 
				
			||||||
    count = T1 & 0x1f;
 | 
					 | 
				
			||||||
    if (count) {
 | 
					 | 
				
			||||||
        T0 &= DATA_MASK;
 | 
					 | 
				
			||||||
        src = T0 >> (count - 1);
 | 
					 | 
				
			||||||
        T0 = T0 >> count;
 | 
					 | 
				
			||||||
#ifdef MEM_WRITE
 | 
					 | 
				
			||||||
        glue(st, SUFFIX)((uint8_t *)A0, T0);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        CC_SRC = src;
 | 
					 | 
				
			||||||
        CC_DST = T0;
 | 
					 | 
				
			||||||
        CC_OP = CC_OP_SARB + SHIFT;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_sar, MEM_SUFFIX), _T0_T1_cc)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int count, src;
 | 
					 | 
				
			||||||
    count = T1 & 0x1f;
 | 
					 | 
				
			||||||
    if (count) {
 | 
					 | 
				
			||||||
        src = (DATA_STYPE)T0;
 | 
					 | 
				
			||||||
        T0 = src >> count;
 | 
					 | 
				
			||||||
        src = src >> (count - 1);
 | 
					 | 
				
			||||||
#ifdef MEM_WRITE
 | 
					 | 
				
			||||||
        glue(st, SUFFIX)((uint8_t *)A0, T0);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        CC_SRC = src;
 | 
					 | 
				
			||||||
        CC_DST = T0;
 | 
					 | 
				
			||||||
        CC_OP = CC_OP_SARB + SHIFT;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if DATA_BITS == 16
 | 
					 | 
				
			||||||
/* XXX: overflow flag might be incorrect in some cases in shldw */
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_im_cc)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int count;
 | 
					 | 
				
			||||||
    unsigned int res, tmp;
 | 
					 | 
				
			||||||
    count = PARAM1;
 | 
					 | 
				
			||||||
    T1 &= 0xffff;
 | 
					 | 
				
			||||||
    res = T1 | (T0 << 16);
 | 
					 | 
				
			||||||
    tmp = res >> (32 - count);
 | 
					 | 
				
			||||||
    res <<= count;
 | 
					 | 
				
			||||||
    if (count > 16)
 | 
					 | 
				
			||||||
        res |= T1 << (count - 16);
 | 
					 | 
				
			||||||
    T0 = res >> 16;
 | 
					 | 
				
			||||||
#ifdef MEM_WRITE
 | 
					 | 
				
			||||||
    glue(st, SUFFIX)((uint8_t *)A0, T0);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    CC_SRC = tmp;
 | 
					 | 
				
			||||||
    CC_DST = T0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int count;
 | 
					 | 
				
			||||||
    unsigned int res, tmp;
 | 
					 | 
				
			||||||
    count = ECX & 0x1f;
 | 
					 | 
				
			||||||
    if (count) {
 | 
					 | 
				
			||||||
        T1 &= 0xffff;
 | 
					 | 
				
			||||||
        res = T1 | (T0 << 16);
 | 
					 | 
				
			||||||
        tmp = res >> (32 - count);
 | 
					 | 
				
			||||||
        res <<= count;
 | 
					 | 
				
			||||||
        if (count > 16)
 | 
					 | 
				
			||||||
          res |= T1 << (count - 16);
 | 
					 | 
				
			||||||
        T0 = res >> 16;
 | 
					 | 
				
			||||||
#ifdef MEM_WRITE
 | 
					 | 
				
			||||||
        glue(st, SUFFIX)((uint8_t *)A0, T0);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        CC_SRC = tmp;
 | 
					 | 
				
			||||||
        CC_DST = T0;
 | 
					 | 
				
			||||||
        CC_OP = CC_OP_SARB + SHIFT;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_im_cc)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int count;
 | 
					 | 
				
			||||||
    unsigned int res, tmp;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    count = PARAM1;
 | 
					 | 
				
			||||||
    res = (T0 & 0xffff) | (T1 << 16);
 | 
					 | 
				
			||||||
    tmp = res >> (count - 1);
 | 
					 | 
				
			||||||
    res >>= count;
 | 
					 | 
				
			||||||
    if (count > 16)
 | 
					 | 
				
			||||||
        res |= T1 << (32 - count);
 | 
					 | 
				
			||||||
    T0 = res;
 | 
					 | 
				
			||||||
#ifdef MEM_WRITE
 | 
					 | 
				
			||||||
    glue(st, SUFFIX)((uint8_t *)A0, T0);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    CC_SRC = tmp;
 | 
					 | 
				
			||||||
    CC_DST = T0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int count;
 | 
					 | 
				
			||||||
    unsigned int res, tmp;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    count = ECX & 0x1f;
 | 
					 | 
				
			||||||
    if (count) {
 | 
					 | 
				
			||||||
        res = (T0 & 0xffff) | (T1 << 16);
 | 
					 | 
				
			||||||
        tmp = res >> (count - 1);
 | 
					 | 
				
			||||||
        res >>= count;
 | 
					 | 
				
			||||||
        if (count > 16)
 | 
					 | 
				
			||||||
            res |= T1 << (32 - count);
 | 
					 | 
				
			||||||
        T0 = res;
 | 
					 | 
				
			||||||
#ifdef MEM_WRITE
 | 
					 | 
				
			||||||
        glue(st, SUFFIX)((uint8_t *)A0, T0);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        CC_SRC = tmp;
 | 
					 | 
				
			||||||
        CC_DST = T0;
 | 
					 | 
				
			||||||
        CC_OP = CC_OP_SARB + SHIFT;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if DATA_BITS == 32
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_im_cc)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int count, tmp;
 | 
					 | 
				
			||||||
    count = PARAM1;
 | 
					 | 
				
			||||||
    T0 &= DATA_MASK;
 | 
					 | 
				
			||||||
    T1 &= DATA_MASK;
 | 
					 | 
				
			||||||
    tmp = T0 << (count - 1);
 | 
					 | 
				
			||||||
    T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
 | 
					 | 
				
			||||||
#ifdef MEM_WRITE
 | 
					 | 
				
			||||||
    glue(st, SUFFIX)((uint8_t *)A0, T0);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    CC_SRC = tmp;
 | 
					 | 
				
			||||||
    CC_DST = T0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int count, tmp;
 | 
					 | 
				
			||||||
    count = ECX & 0x1f;
 | 
					 | 
				
			||||||
    if (count) {
 | 
					 | 
				
			||||||
        T0 &= DATA_MASK;
 | 
					 | 
				
			||||||
        T1 &= DATA_MASK;
 | 
					 | 
				
			||||||
        tmp = T0 << (count - 1);
 | 
					 | 
				
			||||||
        T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
 | 
					 | 
				
			||||||
#ifdef MEM_WRITE
 | 
					 | 
				
			||||||
        glue(st, SUFFIX)((uint8_t *)A0, T0);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        CC_SRC = tmp;
 | 
					 | 
				
			||||||
        CC_DST = T0;
 | 
					 | 
				
			||||||
        CC_OP = CC_OP_SHLB + SHIFT;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_im_cc)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int count, tmp;
 | 
					 | 
				
			||||||
    count = PARAM1;
 | 
					 | 
				
			||||||
    T0 &= DATA_MASK;
 | 
					 | 
				
			||||||
    T1 &= DATA_MASK;
 | 
					 | 
				
			||||||
    tmp = T0 >> (count - 1);
 | 
					 | 
				
			||||||
    T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
 | 
					 | 
				
			||||||
#ifdef MEM_WRITE
 | 
					 | 
				
			||||||
    glue(st, SUFFIX)((uint8_t *)A0, T0);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    CC_SRC = tmp;
 | 
					 | 
				
			||||||
    CC_DST = T0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int count, tmp;
 | 
					 | 
				
			||||||
    count = ECX & 0x1f;
 | 
					 | 
				
			||||||
    if (count) {
 | 
					 | 
				
			||||||
        T0 &= DATA_MASK;
 | 
					 | 
				
			||||||
        T1 &= DATA_MASK;
 | 
					 | 
				
			||||||
        tmp = T0 >> (count - 1);
 | 
					 | 
				
			||||||
        T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
 | 
					 | 
				
			||||||
#ifdef MEM_WRITE
 | 
					 | 
				
			||||||
        glue(st, SUFFIX)((uint8_t *)A0, T0);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        CC_SRC = tmp;
 | 
					 | 
				
			||||||
        CC_DST = T0;
 | 
					 | 
				
			||||||
        CC_OP = CC_OP_SARB + SHIFT;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* carry add/sub (we only need to set CC_OP differently) */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_adc, MEM_SUFFIX), _T0_T1_cc)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int cf;
 | 
					 | 
				
			||||||
    cf = cc_table[CC_OP].compute_c();
 | 
					 | 
				
			||||||
    T0 = T0 + T1 + cf;
 | 
					 | 
				
			||||||
#ifdef MEM_WRITE
 | 
					 | 
				
			||||||
    glue(st, SUFFIX)((uint8_t *)A0, T0);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    CC_SRC = T1;
 | 
					 | 
				
			||||||
    CC_DST = T0;
 | 
					 | 
				
			||||||
    CC_OP = CC_OP_ADDB + SHIFT + cf * 3;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_sbb, MEM_SUFFIX), _T0_T1_cc)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int cf;
 | 
					 | 
				
			||||||
    cf = cc_table[CC_OP].compute_c();
 | 
					 | 
				
			||||||
    T0 = T0 - T1 - cf;
 | 
					 | 
				
			||||||
#ifdef MEM_WRITE
 | 
					 | 
				
			||||||
    glue(st, SUFFIX)((uint8_t *)A0, T0);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    CC_SRC = T1;
 | 
					 | 
				
			||||||
    CC_DST = T0;
 | 
					 | 
				
			||||||
    CC_OP = CC_OP_SUBB + SHIFT + cf * 3;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO glue(glue(op_cmpxchg, MEM_SUFFIX), _T0_T1_EAX_cc)(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    unsigned int src, dst;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    src = T0;
 | 
					 | 
				
			||||||
    dst = EAX - T0;
 | 
					 | 
				
			||||||
    if ((DATA_TYPE)dst == 0) {
 | 
					 | 
				
			||||||
        T0 = T1;
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        EAX = (EAX & ~DATA_MASK) | (T0 & DATA_MASK);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
#ifdef MEM_WRITE
 | 
					 | 
				
			||||||
    glue(st, SUFFIX)((uint8_t *)A0, T0);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    CC_SRC = src;
 | 
					 | 
				
			||||||
    CC_DST = dst;
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#undef MEM_SUFFIX
 | 
					 | 
				
			||||||
#undef MEM_WRITE
 | 
					 | 
				
			||||||
@ -1,28 +0,0 @@
 | 
				
			|||||||
 | 
					 | 
				
			||||||
/* this struct defines the way the registers are stored on the
 | 
					 | 
				
			||||||
   stack during a system call. */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct target_pt_regs {
 | 
					 | 
				
			||||||
    target_long uregs[18];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define ARM_cpsr	uregs[16]
 | 
					 | 
				
			||||||
#define ARM_pc		uregs[15]
 | 
					 | 
				
			||||||
#define ARM_lr		uregs[14]
 | 
					 | 
				
			||||||
#define ARM_sp		uregs[13]
 | 
					 | 
				
			||||||
#define ARM_ip		uregs[12]
 | 
					 | 
				
			||||||
#define ARM_fp		uregs[11]
 | 
					 | 
				
			||||||
#define ARM_r10		uregs[10]
 | 
					 | 
				
			||||||
#define ARM_r9		uregs[9]
 | 
					 | 
				
			||||||
#define ARM_r8		uregs[8]
 | 
					 | 
				
			||||||
#define ARM_r7		uregs[7]
 | 
					 | 
				
			||||||
#define ARM_r6		uregs[6]
 | 
					 | 
				
			||||||
#define ARM_r5		uregs[5]
 | 
					 | 
				
			||||||
#define ARM_r4		uregs[4]
 | 
					 | 
				
			||||||
#define ARM_r3		uregs[3]
 | 
					 | 
				
			||||||
#define ARM_r2		uregs[2]
 | 
					 | 
				
			||||||
#define ARM_r1		uregs[1]
 | 
					 | 
				
			||||||
#define ARM_r0		uregs[0]
 | 
					 | 
				
			||||||
#define ARM_ORIG_r0	uregs[17]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define ARM_SYSCALL_BASE	0x900000
 | 
					 | 
				
			||||||
							
								
								
									
										220
									
								
								syscall-i386.h
									
									
									
									
									
								
							
							
						
						
									
										220
									
								
								syscall-i386.h
									
									
									
									
									
								
							@ -1,220 +0,0 @@
 | 
				
			|||||||
/* default linux values for the selectors */
 | 
					 | 
				
			||||||
#define __USER_CS	(0x23)
 | 
					 | 
				
			||||||
#define __USER_DS	(0x2B)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct target_pt_regs {
 | 
					 | 
				
			||||||
	long ebx;
 | 
					 | 
				
			||||||
	long ecx;
 | 
					 | 
				
			||||||
	long edx;
 | 
					 | 
				
			||||||
	long esi;
 | 
					 | 
				
			||||||
	long edi;
 | 
					 | 
				
			||||||
	long ebp;
 | 
					 | 
				
			||||||
	long eax;
 | 
					 | 
				
			||||||
	int  xds;
 | 
					 | 
				
			||||||
	int  xes;
 | 
					 | 
				
			||||||
	long orig_eax;
 | 
					 | 
				
			||||||
	long eip;
 | 
					 | 
				
			||||||
	int  xcs;
 | 
					 | 
				
			||||||
	long eflags;
 | 
					 | 
				
			||||||
	long esp;
 | 
					 | 
				
			||||||
	int  xss;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* ioctls */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define TARGET_LDT_ENTRIES      8192
 | 
					 | 
				
			||||||
#define TARGET_LDT_ENTRY_SIZE	8
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define TARGET_GDT_ENTRY_TLS_ENTRIES   3
 | 
					 | 
				
			||||||
#define TARGET_GDT_ENTRY_TLS_MIN       6
 | 
					 | 
				
			||||||
#define TARGET_GDT_ENTRY_TLS_MAX       (TARGET_GDT_ENTRY_TLS_MIN + TARGET_GDT_ENTRY_TLS_ENTRIES - 1)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct target_modify_ldt_ldt_s {
 | 
					 | 
				
			||||||
    unsigned int  entry_number;
 | 
					 | 
				
			||||||
    target_ulong base_addr;
 | 
					 | 
				
			||||||
    unsigned int limit;
 | 
					 | 
				
			||||||
    unsigned int flags;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* vm86 defines */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define TARGET_BIOSSEG		0x0f000
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define TARGET_CPU_086		0
 | 
					 | 
				
			||||||
#define TARGET_CPU_186		1
 | 
					 | 
				
			||||||
#define TARGET_CPU_286		2
 | 
					 | 
				
			||||||
#define TARGET_CPU_386		3
 | 
					 | 
				
			||||||
#define TARGET_CPU_486		4
 | 
					 | 
				
			||||||
#define TARGET_CPU_586		5
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define TARGET_VM86_SIGNAL	0	/* return due to signal */
 | 
					 | 
				
			||||||
#define TARGET_VM86_UNKNOWN	1	/* unhandled GP fault - IO-instruction or similar */
 | 
					 | 
				
			||||||
#define TARGET_VM86_INTx	2	/* int3/int x instruction (ARG = x) */
 | 
					 | 
				
			||||||
#define TARGET_VM86_STI	3	/* sti/popf/iret instruction enabled virtual interrupts */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Additional return values when invoking new vm86()
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define TARGET_VM86_PICRETURN	4	/* return due to pending PIC request */
 | 
					 | 
				
			||||||
#define TARGET_VM86_TRAP	6	/* return due to DOS-debugger request */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * function codes when invoking new vm86()
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define TARGET_VM86_PLUS_INSTALL_CHECK	0
 | 
					 | 
				
			||||||
#define TARGET_VM86_ENTER		1
 | 
					 | 
				
			||||||
#define TARGET_VM86_ENTER_NO_BYPASS	2
 | 
					 | 
				
			||||||
#define	TARGET_VM86_REQUEST_IRQ	3
 | 
					 | 
				
			||||||
#define TARGET_VM86_FREE_IRQ		4
 | 
					 | 
				
			||||||
#define TARGET_VM86_GET_IRQ_BITS	5
 | 
					 | 
				
			||||||
#define TARGET_VM86_GET_AND_RESET_IRQ	6
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * This is the stack-layout seen by the user space program when we have
 | 
					 | 
				
			||||||
 * done a translation of "SAVE_ALL" from vm86 mode. The real kernel layout
 | 
					 | 
				
			||||||
 * is 'kernel_vm86_regs' (see below).
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct target_vm86_regs {
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * normal regs, with special meaning for the segment descriptors..
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
	target_long ebx;
 | 
					 | 
				
			||||||
	target_long ecx;
 | 
					 | 
				
			||||||
	target_long edx;
 | 
					 | 
				
			||||||
	target_long esi;
 | 
					 | 
				
			||||||
	target_long edi;
 | 
					 | 
				
			||||||
	target_long ebp;
 | 
					 | 
				
			||||||
	target_long eax;
 | 
					 | 
				
			||||||
	target_long __null_ds;
 | 
					 | 
				
			||||||
	target_long __null_es;
 | 
					 | 
				
			||||||
	target_long __null_fs;
 | 
					 | 
				
			||||||
	target_long __null_gs;
 | 
					 | 
				
			||||||
	target_long orig_eax;
 | 
					 | 
				
			||||||
	target_long eip;
 | 
					 | 
				
			||||||
	unsigned short cs, __csh;
 | 
					 | 
				
			||||||
	target_long eflags;
 | 
					 | 
				
			||||||
	target_long esp;
 | 
					 | 
				
			||||||
	unsigned short ss, __ssh;
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * these are specific to v86 mode:
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
	unsigned short es, __esh;
 | 
					 | 
				
			||||||
	unsigned short ds, __dsh;
 | 
					 | 
				
			||||||
	unsigned short fs, __fsh;
 | 
					 | 
				
			||||||
	unsigned short gs, __gsh;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct target_revectored_struct {
 | 
					 | 
				
			||||||
	target_ulong __map[8];			/* 256 bits */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct target_vm86_struct {
 | 
					 | 
				
			||||||
	struct target_vm86_regs regs;
 | 
					 | 
				
			||||||
	target_ulong flags;
 | 
					 | 
				
			||||||
	target_ulong screen_bitmap;
 | 
					 | 
				
			||||||
	target_ulong cpu_type;
 | 
					 | 
				
			||||||
	struct target_revectored_struct int_revectored;
 | 
					 | 
				
			||||||
	struct target_revectored_struct int21_revectored;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * flags masks
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define TARGET_VM86_SCREEN_BITMAP	0x0001
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct target_vm86plus_info_struct {
 | 
					 | 
				
			||||||
        target_ulong flags;
 | 
					 | 
				
			||||||
#define TARGET_force_return_for_pic (1 << 0)
 | 
					 | 
				
			||||||
#define TARGET_vm86dbg_active       (1 << 1)  /* for debugger */
 | 
					 | 
				
			||||||
#define TARGET_vm86dbg_TFpendig     (1 << 2)  /* for debugger */
 | 
					 | 
				
			||||||
#define TARGET_is_vm86pus           (1 << 31) /* for vm86 internal use */
 | 
					 | 
				
			||||||
	unsigned char vm86dbg_intxxtab[32];   /* for debugger */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct target_vm86plus_struct {
 | 
					 | 
				
			||||||
	struct target_vm86_regs regs;
 | 
					 | 
				
			||||||
	target_ulong flags;
 | 
					 | 
				
			||||||
	target_ulong screen_bitmap;
 | 
					 | 
				
			||||||
	target_ulong cpu_type;
 | 
					 | 
				
			||||||
	struct target_revectored_struct int_revectored;
 | 
					 | 
				
			||||||
	struct target_revectored_struct int21_revectored;
 | 
					 | 
				
			||||||
	struct target_vm86plus_info_struct vm86plus;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* ipcs */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define TARGET_SEMOP           1
 | 
					 | 
				
			||||||
#define TARGET_SEMGET          2
 | 
					 | 
				
			||||||
#define TARGET_SEMCTL          3 
 | 
					 | 
				
			||||||
#define TARGET_MSGSND          11 
 | 
					 | 
				
			||||||
#define TARGET_MSGRCV          12
 | 
					 | 
				
			||||||
#define TARGET_MSGGET          13
 | 
					 | 
				
			||||||
#define TARGET_MSGCTL          14
 | 
					 | 
				
			||||||
#define TARGET_SHMAT           21
 | 
					 | 
				
			||||||
#define TARGET_SHMDT           22
 | 
					 | 
				
			||||||
#define TARGET_SHMGET          23
 | 
					 | 
				
			||||||
#define TARGET_SHMCTL          24
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct target_msgbuf {
 | 
					 | 
				
			||||||
	int mtype;
 | 
					 | 
				
			||||||
	char mtext[1];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct target_ipc_kludge {
 | 
					 | 
				
			||||||
	unsigned int	msgp;	/* Really (struct msgbuf *) */
 | 
					 | 
				
			||||||
	int msgtyp;
 | 
					 | 
				
			||||||
};	
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct target_ipc_perm {
 | 
					 | 
				
			||||||
	int	key;
 | 
					 | 
				
			||||||
	unsigned short	uid;
 | 
					 | 
				
			||||||
	unsigned short	gid;
 | 
					 | 
				
			||||||
	unsigned short	cuid;
 | 
					 | 
				
			||||||
	unsigned short	cgid;
 | 
					 | 
				
			||||||
	unsigned short	mode;
 | 
					 | 
				
			||||||
	unsigned short	seq;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct target_msqid_ds {
 | 
					 | 
				
			||||||
	struct target_ipc_perm	msg_perm;
 | 
					 | 
				
			||||||
	unsigned int		msg_first;	/* really struct target_msg* */
 | 
					 | 
				
			||||||
	unsigned int		msg_last;	/* really struct target_msg* */
 | 
					 | 
				
			||||||
	unsigned int		msg_stime;	/* really target_time_t */
 | 
					 | 
				
			||||||
	unsigned int		msg_rtime;	/* really target_time_t */
 | 
					 | 
				
			||||||
	unsigned int		msg_ctime;	/* really target_time_t */
 | 
					 | 
				
			||||||
	unsigned int		wwait;		/* really struct wait_queue* */
 | 
					 | 
				
			||||||
	unsigned int		rwait;		/* really struct wait_queue* */
 | 
					 | 
				
			||||||
	unsigned short		msg_cbytes;
 | 
					 | 
				
			||||||
	unsigned short		msg_qnum;
 | 
					 | 
				
			||||||
	unsigned short		msg_qbytes;
 | 
					 | 
				
			||||||
	unsigned short		msg_lspid;
 | 
					 | 
				
			||||||
	unsigned short		msg_lrpid;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct target_shmid_ds {
 | 
					 | 
				
			||||||
	struct target_ipc_perm	shm_perm;
 | 
					 | 
				
			||||||
	int			shm_segsz;
 | 
					 | 
				
			||||||
	unsigned int		shm_atime;	/* really target_time_t */
 | 
					 | 
				
			||||||
	unsigned int		shm_dtime;	/* really target_time_t */
 | 
					 | 
				
			||||||
	unsigned int		shm_ctime;	/* really target_time_t */
 | 
					 | 
				
			||||||
	unsigned short		shm_cpid;
 | 
					 | 
				
			||||||
	unsigned short		shm_lpid;
 | 
					 | 
				
			||||||
	short			shm_nattch;
 | 
					 | 
				
			||||||
	unsigned short		shm_npages;
 | 
					 | 
				
			||||||
	unsigned long		*shm_pages;
 | 
					 | 
				
			||||||
	void 			*attaches;	/* really struct shm_desc * */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define TARGET_IPC_RMID	0
 | 
					 | 
				
			||||||
#define TARGET_IPC_SET	1
 | 
					 | 
				
			||||||
#define TARGET_IPC_STAT	2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
union target_semun {
 | 
					 | 
				
			||||||
    int val;
 | 
					 | 
				
			||||||
    unsigned int buf;	/* really struct semid_ds * */
 | 
					 | 
				
			||||||
    unsigned int array; /* really unsigned short * */
 | 
					 | 
				
			||||||
    unsigned int __buf;	/* really struct seminfo * */
 | 
					 | 
				
			||||||
    unsigned int __pad;	/* really void* */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@ -26,34 +26,19 @@
 | 
				
			|||||||
#include "config.h"
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define IN_OP_I386
 | 
					#define IN_OP_I386
 | 
				
			||||||
#if defined(TARGET_I386)
 | 
					#include "cpu.h"
 | 
				
			||||||
#include "cpu-i386.h"
 | 
					#include "exec-all.h"
 | 
				
			||||||
#define OPC_CPU_H "opc-i386.h"
 | 
					 | 
				
			||||||
#elif defined(TARGET_ARM)
 | 
					 | 
				
			||||||
#include "cpu-arm.h"
 | 
					 | 
				
			||||||
#define OPC_CPU_H "opc-arm.h"
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
#error unsupported target CPU
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "exec.h"
 | 
					 | 
				
			||||||
#include "disas.h"
 | 
					#include "disas.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum {
 | 
					enum {
 | 
				
			||||||
#define DEF(s, n, copy_size) INDEX_op_ ## s,
 | 
					#define DEF(s, n, copy_size) INDEX_op_ ## s,
 | 
				
			||||||
#include OPC_CPU_H
 | 
					#include "opc.h"
 | 
				
			||||||
#undef DEF
 | 
					#undef DEF
 | 
				
			||||||
    NB_OPS,
 | 
					    NB_OPS,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "dyngen.h"
 | 
					#include "dyngen.h"
 | 
				
			||||||
#if defined(TARGET_I386)
 | 
					#include "op.h"
 | 
				
			||||||
#include "op-i386.h"
 | 
					 | 
				
			||||||
#elif defined(TARGET_ARM)
 | 
					 | 
				
			||||||
#include "op-arm.h"
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
#error unsupported target CPU
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint16_t gen_opc_buf[OPC_BUF_SIZE];
 | 
					uint16_t gen_opc_buf[OPC_BUF_SIZE];
 | 
				
			||||||
uint32_t gen_opparam_buf[OPPARAM_BUF_SIZE];
 | 
					uint32_t gen_opparam_buf[OPPARAM_BUF_SIZE];
 | 
				
			||||||
@ -66,13 +51,13 @@ uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
 | 
				
			|||||||
#ifdef DEBUG_DISAS
 | 
					#ifdef DEBUG_DISAS
 | 
				
			||||||
static const char *op_str[] = {
 | 
					static const char *op_str[] = {
 | 
				
			||||||
#define DEF(s, n, copy_size) #s,
 | 
					#define DEF(s, n, copy_size) #s,
 | 
				
			||||||
#include OPC_CPU_H
 | 
					#include "opc.h"
 | 
				
			||||||
#undef DEF
 | 
					#undef DEF
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static uint8_t op_nb_args[] = {
 | 
					static uint8_t op_nb_args[] = {
 | 
				
			||||||
#define DEF(s, n, copy_size) n,
 | 
					#define DEF(s, n, copy_size) n,
 | 
				
			||||||
#include OPC_CPU_H
 | 
					#include "opc.h"
 | 
				
			||||||
#undef DEF
 | 
					#undef DEF
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -146,7 +131,7 @@ int cpu_gen_code(CPUState *env, TranslationBlock *tb,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static const unsigned short opc_copy_size[] = {
 | 
					static const unsigned short opc_copy_size[] = {
 | 
				
			||||||
#define DEF(s, n, copy_size) copy_size,
 | 
					#define DEF(s, n, copy_size) copy_size,
 | 
				
			||||||
#include OPC_CPU_H
 | 
					#include "opc.h"
 | 
				
			||||||
#undef DEF
 | 
					#undef DEF
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -204,6 +189,8 @@ int cpu_restore_state(TranslationBlock *tb,
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
#elif defined(TARGET_ARM)
 | 
					#elif defined(TARGET_ARM)
 | 
				
			||||||
    env->regs[15] = gen_opc_pc[j];
 | 
					    env->regs[15] = gen_opc_pc[j];
 | 
				
			||||||
 | 
					#elif defined(TARGET_SPARC)
 | 
				
			||||||
 | 
						env->pc = gen_opc_pc[j];
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										903
									
								
								translate-arm.c
									
									
									
									
									
								
							
							
						
						
									
										903
									
								
								translate-arm.c
									
									
									
									
									
								
							@ -1,903 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 *  ARM translation
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 *  Copyright (c) 2003 Fabrice Bellard
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This library is free software; you can redistribute it and/or
 | 
					 | 
				
			||||||
 * modify it under the terms of the GNU Lesser General Public
 | 
					 | 
				
			||||||
 * License as published by the Free Software Foundation; either
 | 
					 | 
				
			||||||
 * version 2 of the License, or (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This library is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
					 | 
				
			||||||
 * Lesser General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU Lesser General Public
 | 
					 | 
				
			||||||
 * License along with this library; if not, write to the Free Software
 | 
					 | 
				
			||||||
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#include <stdarg.h>
 | 
					 | 
				
			||||||
#include <stdlib.h>
 | 
					 | 
				
			||||||
#include <stdio.h>
 | 
					 | 
				
			||||||
#include <string.h>
 | 
					 | 
				
			||||||
#include <inttypes.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "cpu-arm.h"
 | 
					 | 
				
			||||||
#include "exec.h"
 | 
					 | 
				
			||||||
#include "disas.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* internal defines */
 | 
					 | 
				
			||||||
typedef struct DisasContext {
 | 
					 | 
				
			||||||
    uint8_t *pc;
 | 
					 | 
				
			||||||
    int is_jmp;
 | 
					 | 
				
			||||||
    struct TranslationBlock *tb;
 | 
					 | 
				
			||||||
} DisasContext;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define DISAS_JUMP_NEXT 4
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* XXX: move that elsewhere */
 | 
					 | 
				
			||||||
static uint16_t *gen_opc_ptr;
 | 
					 | 
				
			||||||
static uint32_t *gen_opparam_ptr;
 | 
					 | 
				
			||||||
extern FILE *logfile;
 | 
					 | 
				
			||||||
extern int loglevel;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum {
 | 
					 | 
				
			||||||
#define DEF(s, n, copy_size) INDEX_op_ ## s,
 | 
					 | 
				
			||||||
#include "opc-arm.h"
 | 
					 | 
				
			||||||
#undef DEF
 | 
					 | 
				
			||||||
    NB_OPS,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "gen-op-arm.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef void (GenOpFunc)(void);
 | 
					 | 
				
			||||||
typedef void (GenOpFunc1)(long);
 | 
					 | 
				
			||||||
typedef void (GenOpFunc2)(long, long);
 | 
					 | 
				
			||||||
typedef void (GenOpFunc3)(long, long, long);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static GenOpFunc2 *gen_test_cc[14] = {
 | 
					 | 
				
			||||||
    gen_op_test_eq,
 | 
					 | 
				
			||||||
    gen_op_test_ne,
 | 
					 | 
				
			||||||
    gen_op_test_cs,
 | 
					 | 
				
			||||||
    gen_op_test_cc,
 | 
					 | 
				
			||||||
    gen_op_test_mi,
 | 
					 | 
				
			||||||
    gen_op_test_pl,
 | 
					 | 
				
			||||||
    gen_op_test_vs,
 | 
					 | 
				
			||||||
    gen_op_test_vc,
 | 
					 | 
				
			||||||
    gen_op_test_hi,
 | 
					 | 
				
			||||||
    gen_op_test_ls,
 | 
					 | 
				
			||||||
    gen_op_test_ge,
 | 
					 | 
				
			||||||
    gen_op_test_lt,
 | 
					 | 
				
			||||||
    gen_op_test_gt,
 | 
					 | 
				
			||||||
    gen_op_test_le,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const uint8_t table_logic_cc[16] = {
 | 
					 | 
				
			||||||
    1, /* and */
 | 
					 | 
				
			||||||
    1, /* xor */
 | 
					 | 
				
			||||||
    0, /* sub */
 | 
					 | 
				
			||||||
    0, /* rsb */
 | 
					 | 
				
			||||||
    0, /* add */
 | 
					 | 
				
			||||||
    0, /* adc */
 | 
					 | 
				
			||||||
    0, /* sbc */
 | 
					 | 
				
			||||||
    0, /* rsc */
 | 
					 | 
				
			||||||
    1, /* andl */
 | 
					 | 
				
			||||||
    1, /* xorl */
 | 
					 | 
				
			||||||
    0, /* cmp */
 | 
					 | 
				
			||||||
    0, /* cmn */
 | 
					 | 
				
			||||||
    1, /* orr */
 | 
					 | 
				
			||||||
    1, /* mov */
 | 
					 | 
				
			||||||
    1, /* bic */
 | 
					 | 
				
			||||||
    1, /* mvn */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
static GenOpFunc1 *gen_shift_T1_im[4] = {
 | 
					 | 
				
			||||||
    gen_op_shll_T1_im,
 | 
					 | 
				
			||||||
    gen_op_shrl_T1_im,
 | 
					 | 
				
			||||||
    gen_op_sarl_T1_im,
 | 
					 | 
				
			||||||
    gen_op_rorl_T1_im,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static GenOpFunc1 *gen_shift_T2_im[4] = {
 | 
					 | 
				
			||||||
    gen_op_shll_T2_im,
 | 
					 | 
				
			||||||
    gen_op_shrl_T2_im,
 | 
					 | 
				
			||||||
    gen_op_sarl_T2_im,
 | 
					 | 
				
			||||||
    gen_op_rorl_T2_im,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static GenOpFunc1 *gen_shift_T1_im_cc[4] = {
 | 
					 | 
				
			||||||
    gen_op_shll_T1_im_cc,
 | 
					 | 
				
			||||||
    gen_op_shrl_T1_im_cc,
 | 
					 | 
				
			||||||
    gen_op_sarl_T1_im_cc,
 | 
					 | 
				
			||||||
    gen_op_rorl_T1_im_cc,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static GenOpFunc *gen_shift_T1_T0[4] = {
 | 
					 | 
				
			||||||
    gen_op_shll_T1_T0,
 | 
					 | 
				
			||||||
    gen_op_shrl_T1_T0,
 | 
					 | 
				
			||||||
    gen_op_sarl_T1_T0,
 | 
					 | 
				
			||||||
    gen_op_rorl_T1_T0,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static GenOpFunc *gen_shift_T1_T0_cc[4] = {
 | 
					 | 
				
			||||||
    gen_op_shll_T1_T0_cc,
 | 
					 | 
				
			||||||
    gen_op_shrl_T1_T0_cc,
 | 
					 | 
				
			||||||
    gen_op_sarl_T1_T0_cc,
 | 
					 | 
				
			||||||
    gen_op_rorl_T1_T0_cc,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static GenOpFunc *gen_op_movl_TN_reg[3][16] = {
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        gen_op_movl_T0_r0,
 | 
					 | 
				
			||||||
        gen_op_movl_T0_r1,
 | 
					 | 
				
			||||||
        gen_op_movl_T0_r2,
 | 
					 | 
				
			||||||
        gen_op_movl_T0_r3,
 | 
					 | 
				
			||||||
        gen_op_movl_T0_r4,
 | 
					 | 
				
			||||||
        gen_op_movl_T0_r5,
 | 
					 | 
				
			||||||
        gen_op_movl_T0_r6,
 | 
					 | 
				
			||||||
        gen_op_movl_T0_r7,
 | 
					 | 
				
			||||||
        gen_op_movl_T0_r8,
 | 
					 | 
				
			||||||
        gen_op_movl_T0_r9,
 | 
					 | 
				
			||||||
        gen_op_movl_T0_r10,
 | 
					 | 
				
			||||||
        gen_op_movl_T0_r11,
 | 
					 | 
				
			||||||
        gen_op_movl_T0_r12,
 | 
					 | 
				
			||||||
        gen_op_movl_T0_r13,
 | 
					 | 
				
			||||||
        gen_op_movl_T0_r14,
 | 
					 | 
				
			||||||
        gen_op_movl_T0_r15,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        gen_op_movl_T1_r0,
 | 
					 | 
				
			||||||
        gen_op_movl_T1_r1,
 | 
					 | 
				
			||||||
        gen_op_movl_T1_r2,
 | 
					 | 
				
			||||||
        gen_op_movl_T1_r3,
 | 
					 | 
				
			||||||
        gen_op_movl_T1_r4,
 | 
					 | 
				
			||||||
        gen_op_movl_T1_r5,
 | 
					 | 
				
			||||||
        gen_op_movl_T1_r6,
 | 
					 | 
				
			||||||
        gen_op_movl_T1_r7,
 | 
					 | 
				
			||||||
        gen_op_movl_T1_r8,
 | 
					 | 
				
			||||||
        gen_op_movl_T1_r9,
 | 
					 | 
				
			||||||
        gen_op_movl_T1_r10,
 | 
					 | 
				
			||||||
        gen_op_movl_T1_r11,
 | 
					 | 
				
			||||||
        gen_op_movl_T1_r12,
 | 
					 | 
				
			||||||
        gen_op_movl_T1_r13,
 | 
					 | 
				
			||||||
        gen_op_movl_T1_r14,
 | 
					 | 
				
			||||||
        gen_op_movl_T1_r15,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        gen_op_movl_T2_r0,
 | 
					 | 
				
			||||||
        gen_op_movl_T2_r1,
 | 
					 | 
				
			||||||
        gen_op_movl_T2_r2,
 | 
					 | 
				
			||||||
        gen_op_movl_T2_r3,
 | 
					 | 
				
			||||||
        gen_op_movl_T2_r4,
 | 
					 | 
				
			||||||
        gen_op_movl_T2_r5,
 | 
					 | 
				
			||||||
        gen_op_movl_T2_r6,
 | 
					 | 
				
			||||||
        gen_op_movl_T2_r7,
 | 
					 | 
				
			||||||
        gen_op_movl_T2_r8,
 | 
					 | 
				
			||||||
        gen_op_movl_T2_r9,
 | 
					 | 
				
			||||||
        gen_op_movl_T2_r10,
 | 
					 | 
				
			||||||
        gen_op_movl_T2_r11,
 | 
					 | 
				
			||||||
        gen_op_movl_T2_r12,
 | 
					 | 
				
			||||||
        gen_op_movl_T2_r13,
 | 
					 | 
				
			||||||
        gen_op_movl_T2_r14,
 | 
					 | 
				
			||||||
        gen_op_movl_T2_r15,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static GenOpFunc *gen_op_movl_reg_TN[2][16] = {
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        gen_op_movl_r0_T0,
 | 
					 | 
				
			||||||
        gen_op_movl_r1_T0,
 | 
					 | 
				
			||||||
        gen_op_movl_r2_T0,
 | 
					 | 
				
			||||||
        gen_op_movl_r3_T0,
 | 
					 | 
				
			||||||
        gen_op_movl_r4_T0,
 | 
					 | 
				
			||||||
        gen_op_movl_r5_T0,
 | 
					 | 
				
			||||||
        gen_op_movl_r6_T0,
 | 
					 | 
				
			||||||
        gen_op_movl_r7_T0,
 | 
					 | 
				
			||||||
        gen_op_movl_r8_T0,
 | 
					 | 
				
			||||||
        gen_op_movl_r9_T0,
 | 
					 | 
				
			||||||
        gen_op_movl_r10_T0,
 | 
					 | 
				
			||||||
        gen_op_movl_r11_T0,
 | 
					 | 
				
			||||||
        gen_op_movl_r12_T0,
 | 
					 | 
				
			||||||
        gen_op_movl_r13_T0,
 | 
					 | 
				
			||||||
        gen_op_movl_r14_T0,
 | 
					 | 
				
			||||||
        gen_op_movl_r15_T0,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        gen_op_movl_r0_T1,
 | 
					 | 
				
			||||||
        gen_op_movl_r1_T1,
 | 
					 | 
				
			||||||
        gen_op_movl_r2_T1,
 | 
					 | 
				
			||||||
        gen_op_movl_r3_T1,
 | 
					 | 
				
			||||||
        gen_op_movl_r4_T1,
 | 
					 | 
				
			||||||
        gen_op_movl_r5_T1,
 | 
					 | 
				
			||||||
        gen_op_movl_r6_T1,
 | 
					 | 
				
			||||||
        gen_op_movl_r7_T1,
 | 
					 | 
				
			||||||
        gen_op_movl_r8_T1,
 | 
					 | 
				
			||||||
        gen_op_movl_r9_T1,
 | 
					 | 
				
			||||||
        gen_op_movl_r10_T1,
 | 
					 | 
				
			||||||
        gen_op_movl_r11_T1,
 | 
					 | 
				
			||||||
        gen_op_movl_r12_T1,
 | 
					 | 
				
			||||||
        gen_op_movl_r13_T1,
 | 
					 | 
				
			||||||
        gen_op_movl_r14_T1,
 | 
					 | 
				
			||||||
        gen_op_movl_r15_T1,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static GenOpFunc1 *gen_op_movl_TN_im[3] = {
 | 
					 | 
				
			||||||
    gen_op_movl_T0_im,
 | 
					 | 
				
			||||||
    gen_op_movl_T1_im,
 | 
					 | 
				
			||||||
    gen_op_movl_T2_im,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void gen_movl_TN_reg(DisasContext *s, int reg, int t)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int val;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (reg == 15) {
 | 
					 | 
				
			||||||
        /* normaly, since we updated PC, we need only to add 4 */
 | 
					 | 
				
			||||||
        val = (long)s->pc + 4;
 | 
					 | 
				
			||||||
        gen_op_movl_TN_im[t](val);
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        gen_op_movl_TN_reg[t][reg]();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void gen_movl_T0_reg(DisasContext *s, int reg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    gen_movl_TN_reg(s, reg, 0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void gen_movl_T1_reg(DisasContext *s, int reg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    gen_movl_TN_reg(s, reg, 1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void gen_movl_T2_reg(DisasContext *s, int reg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    gen_movl_TN_reg(s, reg, 2);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void gen_movl_reg_TN(DisasContext *s, int reg, int t)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    gen_op_movl_reg_TN[t][reg]();
 | 
					 | 
				
			||||||
    if (reg == 15) {
 | 
					 | 
				
			||||||
        s->is_jmp = DISAS_JUMP;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void gen_movl_reg_T0(DisasContext *s, int reg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    gen_movl_reg_TN(s, reg, 0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void gen_movl_reg_T1(DisasContext *s, int reg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    gen_movl_reg_TN(s, reg, 1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int val, rm, shift;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!(insn & (1 << 25))) {
 | 
					 | 
				
			||||||
        /* immediate */
 | 
					 | 
				
			||||||
        val = insn & 0xfff;
 | 
					 | 
				
			||||||
        if (!(insn & (1 << 23)))
 | 
					 | 
				
			||||||
            val = -val;
 | 
					 | 
				
			||||||
        gen_op_addl_T1_im(val);
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        /* shift/register */
 | 
					 | 
				
			||||||
        rm = (insn) & 0xf;
 | 
					 | 
				
			||||||
        shift = (insn >> 7) & 0x1f;
 | 
					 | 
				
			||||||
        gen_movl_T2_reg(s, rm);
 | 
					 | 
				
			||||||
        if (shift != 0) {
 | 
					 | 
				
			||||||
            gen_shift_T2_im[(insn >> 5) & 3](shift);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (!(insn & (1 << 23)))
 | 
					 | 
				
			||||||
            gen_op_subl_T1_T2();
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
            gen_op_addl_T1_T2();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int val, rm;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    if (insn & (1 << 22)) {
 | 
					 | 
				
			||||||
        /* immediate */
 | 
					 | 
				
			||||||
        val = (insn & 0xf) | ((insn >> 4) & 0xf0);
 | 
					 | 
				
			||||||
        if (!(insn & (1 << 23)))
 | 
					 | 
				
			||||||
            val = -val;
 | 
					 | 
				
			||||||
        gen_op_addl_T1_im(val);
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        /* register */
 | 
					 | 
				
			||||||
        rm = (insn) & 0xf;
 | 
					 | 
				
			||||||
        gen_movl_T2_reg(s, rm);
 | 
					 | 
				
			||||||
        if (!(insn & (1 << 23)))
 | 
					 | 
				
			||||||
            gen_op_subl_T1_T2();
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
            gen_op_addl_T1_T2();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void disas_arm_insn(DisasContext *s)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    insn = ldl(s->pc);
 | 
					 | 
				
			||||||
    s->pc += 4;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    cond = insn >> 28;
 | 
					 | 
				
			||||||
    if (cond == 0xf)
 | 
					 | 
				
			||||||
        goto illegal_op;
 | 
					 | 
				
			||||||
    if (cond != 0xe) {
 | 
					 | 
				
			||||||
        /* if not always execute, we generate a conditional jump to
 | 
					 | 
				
			||||||
           next instruction */
 | 
					 | 
				
			||||||
        gen_test_cc[cond ^ 1]((long)s->tb, (long)s->pc);
 | 
					 | 
				
			||||||
        s->is_jmp = DISAS_JUMP_NEXT;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (((insn & 0x0e000000) == 0 &&
 | 
					 | 
				
			||||||
         (insn & 0x00000090) != 0x90) ||
 | 
					 | 
				
			||||||
        ((insn & 0x0e000000) == (1 << 25))) {
 | 
					 | 
				
			||||||
        int set_cc, logic_cc, shiftop;
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        op1 = (insn >> 21) & 0xf;
 | 
					 | 
				
			||||||
        set_cc = (insn >> 20) & 1;
 | 
					 | 
				
			||||||
        logic_cc = table_logic_cc[op1] & set_cc;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /* data processing instruction */
 | 
					 | 
				
			||||||
        if (insn & (1 << 25)) {
 | 
					 | 
				
			||||||
            /* immediate operand */
 | 
					 | 
				
			||||||
            val = insn & 0xff;
 | 
					 | 
				
			||||||
            shift = ((insn >> 8) & 0xf) * 2;
 | 
					 | 
				
			||||||
            if (shift)
 | 
					 | 
				
			||||||
                val = (val >> shift) | (val << (32 - shift));
 | 
					 | 
				
			||||||
            gen_op_movl_T1_im(val);
 | 
					 | 
				
			||||||
            /* XXX: is CF modified ? */
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            /* register */
 | 
					 | 
				
			||||||
            rm = (insn) & 0xf;
 | 
					 | 
				
			||||||
            gen_movl_T1_reg(s, rm);
 | 
					 | 
				
			||||||
            shiftop = (insn >> 5) & 3;
 | 
					 | 
				
			||||||
            if (!(insn & (1 << 4))) {
 | 
					 | 
				
			||||||
                shift = (insn >> 7) & 0x1f;
 | 
					 | 
				
			||||||
                if (shift != 0) {
 | 
					 | 
				
			||||||
                    if (logic_cc) {
 | 
					 | 
				
			||||||
                        gen_shift_T1_im_cc[shiftop](shift);
 | 
					 | 
				
			||||||
                    } else {
 | 
					 | 
				
			||||||
                        gen_shift_T1_im[shiftop](shift);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                rs = (insn >> 8) & 0xf;
 | 
					 | 
				
			||||||
                gen_movl_T0_reg(s, rs);
 | 
					 | 
				
			||||||
                if (logic_cc) {
 | 
					 | 
				
			||||||
                    gen_shift_T1_T0_cc[shiftop]();
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    gen_shift_T1_T0[shiftop]();
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (op1 != 0x0f && op1 != 0x0d) {
 | 
					 | 
				
			||||||
            rn = (insn >> 16) & 0xf;
 | 
					 | 
				
			||||||
            gen_movl_T0_reg(s, rn);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        rd = (insn >> 12) & 0xf;
 | 
					 | 
				
			||||||
        switch(op1) {
 | 
					 | 
				
			||||||
        case 0x00:
 | 
					 | 
				
			||||||
            gen_op_andl_T0_T1();
 | 
					 | 
				
			||||||
            gen_movl_reg_T0(s, rd);
 | 
					 | 
				
			||||||
            if (logic_cc)
 | 
					 | 
				
			||||||
                gen_op_logic_T0_cc();
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x01:
 | 
					 | 
				
			||||||
            gen_op_xorl_T0_T1();
 | 
					 | 
				
			||||||
            gen_movl_reg_T0(s, rd);
 | 
					 | 
				
			||||||
            if (logic_cc)
 | 
					 | 
				
			||||||
                gen_op_logic_T0_cc();
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x02:
 | 
					 | 
				
			||||||
            if (set_cc)
 | 
					 | 
				
			||||||
                gen_op_subl_T0_T1_cc();
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
                gen_op_subl_T0_T1();
 | 
					 | 
				
			||||||
            gen_movl_reg_T0(s, rd);
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x03:
 | 
					 | 
				
			||||||
            if (set_cc)
 | 
					 | 
				
			||||||
                gen_op_rsbl_T0_T1_cc();
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
                gen_op_rsbl_T0_T1();
 | 
					 | 
				
			||||||
            gen_movl_reg_T0(s, rd);
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x04:
 | 
					 | 
				
			||||||
            if (set_cc)
 | 
					 | 
				
			||||||
                gen_op_addl_T0_T1_cc();
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
                gen_op_addl_T0_T1();
 | 
					 | 
				
			||||||
            gen_movl_reg_T0(s, rd);
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x05:
 | 
					 | 
				
			||||||
            if (set_cc)
 | 
					 | 
				
			||||||
                gen_op_adcl_T0_T1_cc();
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
                gen_op_adcl_T0_T1();
 | 
					 | 
				
			||||||
            gen_movl_reg_T0(s, rd);
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x06:
 | 
					 | 
				
			||||||
            if (set_cc)
 | 
					 | 
				
			||||||
                gen_op_sbcl_T0_T1_cc();
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
                gen_op_sbcl_T0_T1();
 | 
					 | 
				
			||||||
            gen_movl_reg_T0(s, rd);
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x07:
 | 
					 | 
				
			||||||
            if (set_cc)
 | 
					 | 
				
			||||||
                gen_op_rscl_T0_T1_cc();
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
                gen_op_rscl_T0_T1();
 | 
					 | 
				
			||||||
            gen_movl_reg_T0(s, rd);
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x08:
 | 
					 | 
				
			||||||
            if (set_cc) {
 | 
					 | 
				
			||||||
                gen_op_andl_T0_T1();
 | 
					 | 
				
			||||||
                gen_op_logic_T0_cc();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x09:
 | 
					 | 
				
			||||||
            if (set_cc) {
 | 
					 | 
				
			||||||
                gen_op_xorl_T0_T1();
 | 
					 | 
				
			||||||
                gen_op_logic_T0_cc();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x0a:
 | 
					 | 
				
			||||||
            if (set_cc) {
 | 
					 | 
				
			||||||
                gen_op_subl_T0_T1_cc();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x0b:
 | 
					 | 
				
			||||||
            if (set_cc) {
 | 
					 | 
				
			||||||
                gen_op_addl_T0_T1_cc();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x0c:
 | 
					 | 
				
			||||||
            gen_op_orl_T0_T1();
 | 
					 | 
				
			||||||
            gen_movl_reg_T0(s, rd);
 | 
					 | 
				
			||||||
            if (logic_cc)
 | 
					 | 
				
			||||||
                gen_op_logic_T0_cc();
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x0d:
 | 
					 | 
				
			||||||
            gen_movl_reg_T1(s, rd);
 | 
					 | 
				
			||||||
            if (logic_cc)
 | 
					 | 
				
			||||||
                gen_op_logic_T1_cc();
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x0e:
 | 
					 | 
				
			||||||
            gen_op_bicl_T0_T1();
 | 
					 | 
				
			||||||
            gen_movl_reg_T0(s, rd);
 | 
					 | 
				
			||||||
            if (logic_cc)
 | 
					 | 
				
			||||||
                gen_op_logic_T0_cc();
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        default:
 | 
					 | 
				
			||||||
        case 0x0f:
 | 
					 | 
				
			||||||
            gen_op_notl_T1();
 | 
					 | 
				
			||||||
            gen_movl_reg_T1(s, rd);
 | 
					 | 
				
			||||||
            if (logic_cc)
 | 
					 | 
				
			||||||
                gen_op_logic_T1_cc();
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        /* other instructions */
 | 
					 | 
				
			||||||
        op1 = (insn >> 24) & 0xf;
 | 
					 | 
				
			||||||
        switch(op1) {
 | 
					 | 
				
			||||||
        case 0x0:
 | 
					 | 
				
			||||||
        case 0x1:
 | 
					 | 
				
			||||||
            sh = (insn >> 5) & 3;
 | 
					 | 
				
			||||||
            if (sh == 0) {
 | 
					 | 
				
			||||||
                if (op1 == 0x0) {
 | 
					 | 
				
			||||||
                    rd = (insn >> 16) & 0xf;
 | 
					 | 
				
			||||||
                    rn = (insn >> 12) & 0xf;
 | 
					 | 
				
			||||||
                    rs = (insn >> 8) & 0xf;
 | 
					 | 
				
			||||||
                    rm = (insn) & 0xf;
 | 
					 | 
				
			||||||
                    if (!(insn & (1 << 23))) {
 | 
					 | 
				
			||||||
                        /* 32 bit mul */
 | 
					 | 
				
			||||||
                        gen_movl_T0_reg(s, rs);
 | 
					 | 
				
			||||||
                        gen_movl_T1_reg(s, rm);
 | 
					 | 
				
			||||||
                        gen_op_mul_T0_T1();
 | 
					 | 
				
			||||||
                        if (insn & (1 << 21)) {
 | 
					 | 
				
			||||||
                            gen_movl_T1_reg(s, rn);
 | 
					 | 
				
			||||||
                            gen_op_addl_T0_T1();
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        if (insn & (1 << 20)) 
 | 
					 | 
				
			||||||
                            gen_op_logic_T0_cc();
 | 
					 | 
				
			||||||
                        gen_movl_reg_T0(s, rd);
 | 
					 | 
				
			||||||
                    } else {
 | 
					 | 
				
			||||||
                        /* 64 bit mul */
 | 
					 | 
				
			||||||
                        gen_movl_T0_reg(s, rs);
 | 
					 | 
				
			||||||
                        gen_movl_T1_reg(s, rm);
 | 
					 | 
				
			||||||
                        if (insn & (1 << 22)) 
 | 
					 | 
				
			||||||
                            gen_op_mull_T0_T1();
 | 
					 | 
				
			||||||
                        else
 | 
					 | 
				
			||||||
                            gen_op_imull_T0_T1();
 | 
					 | 
				
			||||||
                        if (insn & (1 << 21)) 
 | 
					 | 
				
			||||||
                            gen_op_addq_T0_T1(rn, rd);
 | 
					 | 
				
			||||||
                        if (insn & (1 << 20)) 
 | 
					 | 
				
			||||||
                            gen_op_logicq_cc();
 | 
					 | 
				
			||||||
                        gen_movl_reg_T0(s, rn);
 | 
					 | 
				
			||||||
                        gen_movl_reg_T1(s, rd);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    /* SWP instruction */
 | 
					 | 
				
			||||||
                    rn = (insn >> 16) & 0xf;
 | 
					 | 
				
			||||||
                    rd = (insn >> 12) & 0xf;
 | 
					 | 
				
			||||||
                    rm = (insn) & 0xf;
 | 
					 | 
				
			||||||
                    
 | 
					 | 
				
			||||||
                    gen_movl_T0_reg(s, rm);
 | 
					 | 
				
			||||||
                    gen_movl_T1_reg(s, rn);
 | 
					 | 
				
			||||||
                    if (insn & (1 << 22)) {
 | 
					 | 
				
			||||||
                        gen_op_swpb_T0_T1();
 | 
					 | 
				
			||||||
                    } else {
 | 
					 | 
				
			||||||
                        gen_op_swpl_T0_T1();
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    gen_movl_reg_T0(s, rd);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                /* load/store half word */
 | 
					 | 
				
			||||||
                rn = (insn >> 16) & 0xf;
 | 
					 | 
				
			||||||
                rd = (insn >> 12) & 0xf;
 | 
					 | 
				
			||||||
                gen_movl_T1_reg(s, rn);
 | 
					 | 
				
			||||||
                if (insn & (1 << 25))
 | 
					 | 
				
			||||||
                    gen_add_datah_offset(s, insn);
 | 
					 | 
				
			||||||
                if (insn & (1 << 20)) {
 | 
					 | 
				
			||||||
                    /* load */
 | 
					 | 
				
			||||||
                    switch(sh) {
 | 
					 | 
				
			||||||
                    case 1:
 | 
					 | 
				
			||||||
                        gen_op_lduw_T0_T1();
 | 
					 | 
				
			||||||
                        break;
 | 
					 | 
				
			||||||
                    case 2:
 | 
					 | 
				
			||||||
                        gen_op_ldsb_T0_T1();
 | 
					 | 
				
			||||||
                        break;
 | 
					 | 
				
			||||||
                    default:
 | 
					 | 
				
			||||||
                    case 3:
 | 
					 | 
				
			||||||
                        gen_op_ldsw_T0_T1();
 | 
					 | 
				
			||||||
                        break;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    /* store */
 | 
					 | 
				
			||||||
                    gen_op_stw_T0_T1();
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                if (!(insn & (1 << 24))) {
 | 
					 | 
				
			||||||
                    gen_add_datah_offset(s, insn);
 | 
					 | 
				
			||||||
                    gen_movl_reg_T1(s, rn);
 | 
					 | 
				
			||||||
                } else if (insn & (1 << 21)) {
 | 
					 | 
				
			||||||
                    gen_movl_reg_T1(s, rn);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x4:
 | 
					 | 
				
			||||||
        case 0x5:
 | 
					 | 
				
			||||||
        case 0x6:
 | 
					 | 
				
			||||||
        case 0x7:
 | 
					 | 
				
			||||||
            /* load/store byte/word */
 | 
					 | 
				
			||||||
            rn = (insn >> 16) & 0xf;
 | 
					 | 
				
			||||||
            rd = (insn >> 12) & 0xf;
 | 
					 | 
				
			||||||
            gen_movl_T1_reg(s, rn);
 | 
					 | 
				
			||||||
            if (insn & (1 << 24))
 | 
					 | 
				
			||||||
                gen_add_data_offset(s, insn);
 | 
					 | 
				
			||||||
            if (insn & (1 << 20)) {
 | 
					 | 
				
			||||||
                /* load */
 | 
					 | 
				
			||||||
                if (insn & (1 << 22))
 | 
					 | 
				
			||||||
                    gen_op_ldub_T0_T1();
 | 
					 | 
				
			||||||
                else
 | 
					 | 
				
			||||||
                    gen_op_ldl_T0_T1();
 | 
					 | 
				
			||||||
                gen_movl_reg_T0(s, rd);
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                /* store */
 | 
					 | 
				
			||||||
                gen_movl_T0_reg(s, rd);
 | 
					 | 
				
			||||||
                if (insn & (1 << 22))
 | 
					 | 
				
			||||||
                    gen_op_stb_T0_T1();
 | 
					 | 
				
			||||||
                else
 | 
					 | 
				
			||||||
                    gen_op_stl_T0_T1();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if (!(insn & (1 << 24))) {
 | 
					 | 
				
			||||||
                gen_add_data_offset(s, insn);
 | 
					 | 
				
			||||||
                gen_movl_reg_T1(s, rn);
 | 
					 | 
				
			||||||
            } else if (insn & (1 << 21))
 | 
					 | 
				
			||||||
                gen_movl_reg_T1(s, rn); {
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x08:
 | 
					 | 
				
			||||||
        case 0x09:
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                int j, n;
 | 
					 | 
				
			||||||
                /* load/store multiple words */
 | 
					 | 
				
			||||||
                /* XXX: store correct base if write back */
 | 
					 | 
				
			||||||
                if (insn & (1 << 22))
 | 
					 | 
				
			||||||
                    goto illegal_op; /* only usable in supervisor mode */
 | 
					 | 
				
			||||||
                rn = (insn >> 16) & 0xf;
 | 
					 | 
				
			||||||
                gen_movl_T1_reg(s, rn);
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                /* compute total size */
 | 
					 | 
				
			||||||
                n = 0;
 | 
					 | 
				
			||||||
                for(i=0;i<16;i++) {
 | 
					 | 
				
			||||||
                    if (insn & (1 << i))
 | 
					 | 
				
			||||||
                        n++;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                /* XXX: test invalid n == 0 case ? */
 | 
					 | 
				
			||||||
                if (insn & (1 << 23)) {
 | 
					 | 
				
			||||||
                    if (insn & (1 << 24)) {
 | 
					 | 
				
			||||||
                        /* pre increment */
 | 
					 | 
				
			||||||
                        gen_op_addl_T1_im(4);
 | 
					 | 
				
			||||||
                    } else {
 | 
					 | 
				
			||||||
                        /* post increment */
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    if (insn & (1 << 24)) {
 | 
					 | 
				
			||||||
                        /* pre decrement */
 | 
					 | 
				
			||||||
                        gen_op_addl_T1_im(-(n * 4));
 | 
					 | 
				
			||||||
                    } else {
 | 
					 | 
				
			||||||
                        /* post decrement */
 | 
					 | 
				
			||||||
                        if (n != 1)
 | 
					 | 
				
			||||||
                            gen_op_addl_T1_im(-((n - 1) * 4));
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                j = 0;
 | 
					 | 
				
			||||||
                for(i=0;i<16;i++) {
 | 
					 | 
				
			||||||
                    if (insn & (1 << i)) {
 | 
					 | 
				
			||||||
                        if (insn & (1 << 20)) {
 | 
					 | 
				
			||||||
                            /* load */
 | 
					 | 
				
			||||||
                            gen_op_ldl_T0_T1();
 | 
					 | 
				
			||||||
                            gen_movl_reg_T0(s, i);
 | 
					 | 
				
			||||||
                        } else {
 | 
					 | 
				
			||||||
                            /* store */
 | 
					 | 
				
			||||||
                            if (i == 15) {
 | 
					 | 
				
			||||||
                                /* special case: r15 = PC + 12 */
 | 
					 | 
				
			||||||
                                val = (long)s->pc + 8;
 | 
					 | 
				
			||||||
                                gen_op_movl_TN_im[0](val);
 | 
					 | 
				
			||||||
                            } else {
 | 
					 | 
				
			||||||
                                gen_movl_T0_reg(s, i);
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                            gen_op_stl_T0_T1();
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        j++;
 | 
					 | 
				
			||||||
                        /* no need to add after the last transfer */
 | 
					 | 
				
			||||||
                        if (j != n)
 | 
					 | 
				
			||||||
                            gen_op_addl_T1_im(4);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                if (insn & (1 << 21)) {
 | 
					 | 
				
			||||||
                    /* write back */
 | 
					 | 
				
			||||||
                    if (insn & (1 << 23)) {
 | 
					 | 
				
			||||||
                        if (insn & (1 << 24)) {
 | 
					 | 
				
			||||||
                            /* pre increment */
 | 
					 | 
				
			||||||
                        } else {
 | 
					 | 
				
			||||||
                            /* post increment */
 | 
					 | 
				
			||||||
                            gen_op_addl_T1_im(4);
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    } else {
 | 
					 | 
				
			||||||
                        if (insn & (1 << 24)) {
 | 
					 | 
				
			||||||
                            /* pre decrement */
 | 
					 | 
				
			||||||
                            if (n != 1)
 | 
					 | 
				
			||||||
                                gen_op_addl_T1_im(-((n - 1) * 4));
 | 
					 | 
				
			||||||
                        } else {
 | 
					 | 
				
			||||||
                            /* post decrement */
 | 
					 | 
				
			||||||
                            gen_op_addl_T1_im(-(n * 4));
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    gen_movl_reg_T1(s, rn);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0xa:
 | 
					 | 
				
			||||||
        case 0xb:
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                int offset;
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                /* branch (and link) */
 | 
					 | 
				
			||||||
                val = (int)s->pc;
 | 
					 | 
				
			||||||
                if (insn & (1 << 24)) {
 | 
					 | 
				
			||||||
                    gen_op_movl_T0_im(val);
 | 
					 | 
				
			||||||
                    gen_op_movl_reg_TN[0][14]();
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                offset = (((int)insn << 8) >> 8);
 | 
					 | 
				
			||||||
                val += (offset << 2) + 4;
 | 
					 | 
				
			||||||
                gen_op_jmp((long)s->tb, val);
 | 
					 | 
				
			||||||
                s->is_jmp = DISAS_TB_JUMP;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0xf:
 | 
					 | 
				
			||||||
            /* swi */
 | 
					 | 
				
			||||||
            gen_op_movl_T0_im((long)s->pc);
 | 
					 | 
				
			||||||
            gen_op_movl_reg_TN[0][15]();
 | 
					 | 
				
			||||||
            gen_op_swi();
 | 
					 | 
				
			||||||
            s->is_jmp = DISAS_JUMP;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0xc:
 | 
					 | 
				
			||||||
        case 0xd:
 | 
					 | 
				
			||||||
            rd = (insn >> 12) & 0x7;
 | 
					 | 
				
			||||||
            rn = (insn >> 16) & 0xf;
 | 
					 | 
				
			||||||
            gen_movl_T1_reg(s, rn);
 | 
					 | 
				
			||||||
            val = (insn) & 0xff;
 | 
					 | 
				
			||||||
            if (!(insn & (1 << 23)))
 | 
					 | 
				
			||||||
                val = -val;
 | 
					 | 
				
			||||||
            switch((insn >> 8) & 0xf) {
 | 
					 | 
				
			||||||
            case 0x1:
 | 
					 | 
				
			||||||
                /* load/store */
 | 
					 | 
				
			||||||
                if ((insn & (1 << 24)))
 | 
					 | 
				
			||||||
                    gen_op_addl_T1_im(val);
 | 
					 | 
				
			||||||
                /* XXX: do it */
 | 
					 | 
				
			||||||
                if (!(insn & (1 << 24)))
 | 
					 | 
				
			||||||
                    gen_op_addl_T1_im(val);
 | 
					 | 
				
			||||||
                if (insn & (1 << 21))
 | 
					 | 
				
			||||||
                    gen_movl_reg_T1(s, rn);
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            case 0x2:
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    int n, i;
 | 
					 | 
				
			||||||
                    /* load store multiple */
 | 
					 | 
				
			||||||
                    if ((insn & (1 << 24)))
 | 
					 | 
				
			||||||
                        gen_op_addl_T1_im(val);
 | 
					 | 
				
			||||||
                    switch(insn & 0x00408000) {
 | 
					 | 
				
			||||||
                    case 0x00008000: n = 1; break;
 | 
					 | 
				
			||||||
                    case 0x00400000: n = 2; break;
 | 
					 | 
				
			||||||
                    case 0x00408000: n = 3; break;
 | 
					 | 
				
			||||||
                    default: n = 4; break;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    for(i = 0;i < n; i++) {
 | 
					 | 
				
			||||||
                        /* XXX: do it */
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    if (!(insn & (1 << 24)))
 | 
					 | 
				
			||||||
                        gen_op_addl_T1_im(val);
 | 
					 | 
				
			||||||
                    if (insn & (1 << 21))
 | 
					 | 
				
			||||||
                        gen_movl_reg_T1(s, rn);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            default:
 | 
					 | 
				
			||||||
                goto illegal_op;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 0x0e:
 | 
					 | 
				
			||||||
            /* float ops */
 | 
					 | 
				
			||||||
            /* XXX: do it */
 | 
					 | 
				
			||||||
            switch((insn >> 20) & 0xf) {
 | 
					 | 
				
			||||||
            case 0x2: /* wfs */
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            case 0x3: /* rfs */
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            case 0x4: /* wfc */
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            case 0x5: /* rfc */
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            default:
 | 
					 | 
				
			||||||
                goto illegal_op;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        default:
 | 
					 | 
				
			||||||
        illegal_op:
 | 
					 | 
				
			||||||
            gen_op_movl_T0_im((long)s->pc - 4);
 | 
					 | 
				
			||||||
            gen_op_movl_reg_TN[0][15]();
 | 
					 | 
				
			||||||
            gen_op_undef_insn();
 | 
					 | 
				
			||||||
            s->is_jmp = DISAS_JUMP;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
 | 
					 | 
				
			||||||
   basic block 'tb'. If search_pc is TRUE, also generate PC
 | 
					 | 
				
			||||||
   information for each intermediate instruction. */
 | 
					 | 
				
			||||||
static inline int gen_intermediate_code_internal(CPUState *env, 
 | 
					 | 
				
			||||||
                                                 TranslationBlock *tb, 
 | 
					 | 
				
			||||||
                                                 int search_pc)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    DisasContext dc1, *dc = &dc1;
 | 
					 | 
				
			||||||
    uint16_t *gen_opc_end;
 | 
					 | 
				
			||||||
    int j, lj;
 | 
					 | 
				
			||||||
    uint8_t *pc_start;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    /* generate intermediate code */
 | 
					 | 
				
			||||||
    pc_start = (uint8_t *)tb->pc;
 | 
					 | 
				
			||||||
       
 | 
					 | 
				
			||||||
    dc->tb = tb;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    gen_opc_ptr = gen_opc_buf;
 | 
					 | 
				
			||||||
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
 | 
					 | 
				
			||||||
    gen_opparam_ptr = gen_opparam_buf;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dc->is_jmp = DISAS_NEXT;
 | 
					 | 
				
			||||||
    dc->pc = pc_start;
 | 
					 | 
				
			||||||
    lj = -1;
 | 
					 | 
				
			||||||
    do {
 | 
					 | 
				
			||||||
        if (search_pc) {
 | 
					 | 
				
			||||||
            j = gen_opc_ptr - gen_opc_buf;
 | 
					 | 
				
			||||||
            if (lj < j) {
 | 
					 | 
				
			||||||
                lj++;
 | 
					 | 
				
			||||||
                while (lj < j)
 | 
					 | 
				
			||||||
                    gen_opc_instr_start[lj++] = 0;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            gen_opc_pc[lj] = (uint32_t)dc->pc;
 | 
					 | 
				
			||||||
            gen_opc_instr_start[lj] = 1;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        disas_arm_insn(dc);
 | 
					 | 
				
			||||||
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end && 
 | 
					 | 
				
			||||||
             (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
 | 
					 | 
				
			||||||
    switch(dc->is_jmp) {
 | 
					 | 
				
			||||||
    case DISAS_JUMP_NEXT:
 | 
					 | 
				
			||||||
    case DISAS_NEXT:
 | 
					 | 
				
			||||||
        gen_op_jmp((long)dc->tb, (long)dc->pc);
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
    default:
 | 
					 | 
				
			||||||
    case DISAS_JUMP:
 | 
					 | 
				
			||||||
        /* indicate that the hash table must be used to find the next TB */
 | 
					 | 
				
			||||||
        gen_op_movl_T0_0();
 | 
					 | 
				
			||||||
        gen_op_exit_tb();
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
    case DISAS_TB_JUMP:
 | 
					 | 
				
			||||||
        /* nothing more to generate */
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    *gen_opc_ptr = INDEX_op_end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef DEBUG_DISAS
 | 
					 | 
				
			||||||
    if (loglevel) {
 | 
					 | 
				
			||||||
        fprintf(logfile, "----------------\n");
 | 
					 | 
				
			||||||
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
 | 
					 | 
				
			||||||
	disas(logfile, pc_start, dc->pc - pc_start, 0, 0);
 | 
					 | 
				
			||||||
        fprintf(logfile, "\n");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        fprintf(logfile, "OP:\n");
 | 
					 | 
				
			||||||
        dump_ops(gen_opc_buf, gen_opparam_buf);
 | 
					 | 
				
			||||||
        fprintf(logfile, "\n");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    if (!search_pc)
 | 
					 | 
				
			||||||
        tb->size = dc->pc - pc_start;
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int gen_intermediate_code(CPUState *env, TranslationBlock *tb)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return gen_intermediate_code_internal(env, tb, 0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return gen_intermediate_code_internal(env, tb, 1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
CPUARMState *cpu_arm_init(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    CPUARMState *env;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    cpu_exec_init();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    env = malloc(sizeof(CPUARMState));
 | 
					 | 
				
			||||||
    if (!env)
 | 
					 | 
				
			||||||
        return NULL;
 | 
					 | 
				
			||||||
    memset(env, 0, sizeof(CPUARMState));
 | 
					 | 
				
			||||||
    return env;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void cpu_arm_close(CPUARMState *env)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    free(env);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void cpu_arm_dump_state(CPUARMState *env, FILE *f, int flags)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int i;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for(i=0;i<16;i++) {
 | 
					 | 
				
			||||||
        fprintf(f, "R%02d=%08x", i, env->regs[i]);
 | 
					 | 
				
			||||||
        if ((i % 4) == 3)
 | 
					 | 
				
			||||||
            fprintf(f, "\n");
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
            fprintf(f, " ");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    fprintf(f, "PSR=%08x %c%c%c%c\n", 
 | 
					 | 
				
			||||||
            env->cpsr, 
 | 
					 | 
				
			||||||
            env->cpsr & (1 << 31) ? 'N' : '-',
 | 
					 | 
				
			||||||
            env->cpsr & (1 << 30) ? 'Z' : '-',
 | 
					 | 
				
			||||||
            env->cpsr & (1 << 29) ? 'C' : '-',
 | 
					 | 
				
			||||||
            env->cpsr & (1 << 28) ? 'V' : '-');
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										4487
									
								
								translate-i386.c
									
									
									
									
									
								
							
							
						
						
									
										4487
									
								
								translate-i386.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user