Commit d3eead2eec2f74fded2bed2cb8c21fd8404aeeb9

Authored by bellard
1 parent 853d6f7a

new directory structure


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@390 c046a42c-6fe2-441c-8c8c-71466251a162

Too many changes to show.

To preserve performance only 9 of 20 files are displayed.

cpu-arm.h deleted 100644 → 0
1 -/*  
2 - * ARM virtual CPU header  
3 - *  
4 - * Copyright (c) 2003 Fabrice Bellard  
5 - *  
6 - * This library is free software; you can redistribute it and/or  
7 - * modify it under the terms of the GNU Lesser General Public  
8 - * License as published by the Free Software Foundation; either  
9 - * version 2 of the License, or (at your option) any later version.  
10 - *  
11 - * This library is distributed in the hope that it will be useful,  
12 - * but WITHOUT ANY WARRANTY; without even the implied warranty of  
13 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  
14 - * Lesser General Public License for more details.  
15 - *  
16 - * You should have received a copy of the GNU Lesser General Public  
17 - * License along with this library; if not, write to the Free Software  
18 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA  
19 - */  
20 -#ifndef CPU_ARM_H  
21 -#define CPU_ARM_H  
22 -  
23 -#include "cpu-defs.h"  
24 -  
25 -#define EXCP_UDEF 1 /* undefined instruction */  
26 -#define EXCP_SWI 2 /* software interrupt */  
27 -  
28 -typedef struct CPUARMState {  
29 - uint32_t regs[16];  
30 - uint32_t cpsr;  
31 -  
32 - /* cpsr flag cache for faster execution */  
33 - uint32_t CF; /* 0 or 1 */  
34 - uint32_t VF; /* V is the bit 31. All other bits are undefined */  
35 - uint32_t NZF; /* N is bit 31. Z is computed from NZF */  
36 -  
37 - /* exception/interrupt handling */  
38 - jmp_buf jmp_env;  
39 - int exception_index;  
40 - int interrupt_request;  
41 - struct TranslationBlock *current_tb;  
42 - int user_mode_only;  
43 -  
44 - /* user data */  
45 - void *opaque;  
46 -} CPUARMState;  
47 -  
48 -CPUARMState *cpu_arm_init(void);  
49 -int cpu_arm_exec(CPUARMState *s);  
50 -void cpu_arm_close(CPUARMState *s);  
51 -/* you can call this signal handler from your SIGBUS and SIGSEGV  
52 - signal handlers to inform the virtual CPU of exceptions. non zero  
53 - is returned if the signal was handled by the virtual CPU. */  
54 -struct siginfo;  
55 -int cpu_arm_signal_handler(int host_signum, struct siginfo *info,  
56 - void *puc);  
57 -  
58 -void cpu_arm_dump_state(CPUARMState *env, FILE *f, int flags);  
59 -  
60 -#define TARGET_PAGE_BITS 12  
61 -#include "cpu-all.h"  
62 -  
63 -#endif  
cpu-i386.h deleted 100644 → 0
1 -/*  
2 - * i386 virtual CPU header  
3 - *  
4 - * Copyright (c) 2003 Fabrice Bellard  
5 - *  
6 - * This library is free software; you can redistribute it and/or  
7 - * modify it under the terms of the GNU Lesser General Public  
8 - * License as published by the Free Software Foundation; either  
9 - * version 2 of the License, or (at your option) any later version.  
10 - *  
11 - * This library is distributed in the hope that it will be useful,  
12 - * but WITHOUT ANY WARRANTY; without even the implied warranty of  
13 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  
14 - * Lesser General Public License for more details.  
15 - *  
16 - * You should have received a copy of the GNU Lesser General Public  
17 - * License along with this library; if not, write to the Free Software  
18 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA  
19 - */  
20 -#ifndef CPU_I386_H  
21 -#define CPU_I386_H  
22 -  
23 -#include "cpu-defs.h"  
24 -  
25 -#define R_EAX 0  
26 -#define R_ECX 1  
27 -#define R_EDX 2  
28 -#define R_EBX 3  
29 -#define R_ESP 4  
30 -#define R_EBP 5  
31 -#define R_ESI 6  
32 -#define R_EDI 7  
33 -  
34 -#define R_AL 0  
35 -#define R_CL 1  
36 -#define R_DL 2  
37 -#define R_BL 3  
38 -#define R_AH 4  
39 -#define R_CH 5  
40 -#define R_DH 6  
41 -#define R_BH 7  
42 -  
43 -#define R_ES 0  
44 -#define R_CS 1  
45 -#define R_SS 2  
46 -#define R_DS 3  
47 -#define R_FS 4  
48 -#define R_GS 5  
49 -  
50 -/* segment descriptor fields */  
51 -#define DESC_G_MASK (1 << 23)  
52 -#define DESC_B_SHIFT 22  
53 -#define DESC_B_MASK (1 << DESC_B_SHIFT)  
54 -#define DESC_AVL_MASK (1 << 20)  
55 -#define DESC_P_MASK (1 << 15)  
56 -#define DESC_DPL_SHIFT 13  
57 -#define DESC_S_MASK (1 << 12)  
58 -#define DESC_TYPE_SHIFT 8  
59 -#define DESC_A_MASK (1 << 8)  
60 -  
61 -#define DESC_CS_MASK (1 << 11)  
62 -#define DESC_C_MASK (1 << 10)  
63 -#define DESC_R_MASK (1 << 9)  
64 -  
65 -#define DESC_E_MASK (1 << 10)  
66 -#define DESC_W_MASK (1 << 9)  
67 -  
68 -/* eflags masks */  
69 -#define CC_C 0x0001  
70 -#define CC_P 0x0004  
71 -#define CC_A 0x0010  
72 -#define CC_Z 0x0040  
73 -#define CC_S 0x0080  
74 -#define CC_O 0x0800  
75 -  
76 -#define TF_SHIFT 8  
77 -#define IOPL_SHIFT 12  
78 -#define VM_SHIFT 17  
79 -  
80 -#define TF_MASK 0x00000100  
81 -#define IF_MASK 0x00000200  
82 -#define DF_MASK 0x00000400  
83 -#define IOPL_MASK 0x00003000  
84 -#define NT_MASK 0x00004000  
85 -#define RF_MASK 0x00010000  
86 -#define VM_MASK 0x00020000  
87 -#define AC_MASK 0x00040000  
88 -#define VIF_MASK 0x00080000  
89 -#define VIP_MASK 0x00100000  
90 -#define ID_MASK 0x00200000  
91 -  
92 -/* hidden flags - used internally by qemu to represent additionnal cpu  
93 - states. Only the CPL and INHIBIT_IRQ are not redundant. We avoid  
94 - using the IOPL_MASK, TF_MASK and VM_MASK bit position to ease oring  
95 - with eflags. */  
96 -/* current cpl */  
97 -#define HF_CPL_SHIFT 0  
98 -/* true if soft mmu is being used */  
99 -#define HF_SOFTMMU_SHIFT 2  
100 -/* true if hardware interrupts must be disabled for next instruction */  
101 -#define HF_INHIBIT_IRQ_SHIFT 3  
102 -/* 16 or 32 segments */  
103 -#define HF_CS32_SHIFT 4  
104 -#define HF_SS32_SHIFT 5  
105 -/* zero base for DS, ES and SS */  
106 -#define HF_ADDSEG_SHIFT 6  
107 -  
108 -#define HF_CPL_MASK (3 << HF_CPL_SHIFT)  
109 -#define HF_SOFTMMU_MASK (1 << HF_SOFTMMU_SHIFT)  
110 -#define HF_INHIBIT_IRQ_MASK (1 << HF_INHIBIT_IRQ_SHIFT)  
111 -#define HF_CS32_MASK (1 << HF_CS32_SHIFT)  
112 -#define HF_SS32_MASK (1 << HF_SS32_SHIFT)  
113 -#define HF_ADDSEG_MASK (1 << HF_ADDSEG_SHIFT)  
114 -  
115 -#define CR0_PE_MASK (1 << 0)  
116 -#define CR0_TS_MASK (1 << 3)  
117 -#define CR0_WP_MASK (1 << 16)  
118 -#define CR0_AM_MASK (1 << 18)  
119 -#define CR0_PG_MASK (1 << 31)  
120 -  
121 -#define CR4_VME_MASK (1 << 0)  
122 -#define CR4_PVI_MASK (1 << 1)  
123 -#define CR4_TSD_MASK (1 << 2)  
124 -#define CR4_DE_MASK (1 << 3)  
125 -#define CR4_PSE_MASK (1 << 4)  
126 -  
127 -#define PG_PRESENT_BIT 0  
128 -#define PG_RW_BIT 1  
129 -#define PG_USER_BIT 2  
130 -#define PG_PWT_BIT 3  
131 -#define PG_PCD_BIT 4  
132 -#define PG_ACCESSED_BIT 5  
133 -#define PG_DIRTY_BIT 6  
134 -#define PG_PSE_BIT 7  
135 -#define PG_GLOBAL_BIT 8  
136 -  
137 -#define PG_PRESENT_MASK (1 << PG_PRESENT_BIT)  
138 -#define PG_RW_MASK (1 << PG_RW_BIT)  
139 -#define PG_USER_MASK (1 << PG_USER_BIT)  
140 -#define PG_PWT_MASK (1 << PG_PWT_BIT)  
141 -#define PG_PCD_MASK (1 << PG_PCD_BIT)  
142 -#define PG_ACCESSED_MASK (1 << PG_ACCESSED_BIT)  
143 -#define PG_DIRTY_MASK (1 << PG_DIRTY_BIT)  
144 -#define PG_PSE_MASK (1 << PG_PSE_BIT)  
145 -#define PG_GLOBAL_MASK (1 << PG_GLOBAL_BIT)  
146 -  
147 -#define PG_ERROR_W_BIT 1  
148 -  
149 -#define PG_ERROR_P_MASK 0x01  
150 -#define PG_ERROR_W_MASK (1 << PG_ERROR_W_BIT)  
151 -#define PG_ERROR_U_MASK 0x04  
152 -#define PG_ERROR_RSVD_MASK 0x08  
153 -  
154 -#define MSR_IA32_APICBASE 0x1b  
155 -#define MSR_IA32_APICBASE_BSP (1<<8)  
156 -#define MSR_IA32_APICBASE_ENABLE (1<<11)  
157 -#define MSR_IA32_APICBASE_BASE (0xfffff<<12)  
158 -  
159 -#define MSR_IA32_SYSENTER_CS 0x174  
160 -#define MSR_IA32_SYSENTER_ESP 0x175  
161 -#define MSR_IA32_SYSENTER_EIP 0x176  
162 -  
163 -#define EXCP00_DIVZ 0  
164 -#define EXCP01_SSTP 1  
165 -#define EXCP02_NMI 2  
166 -#define EXCP03_INT3 3  
167 -#define EXCP04_INTO 4  
168 -#define EXCP05_BOUND 5  
169 -#define EXCP06_ILLOP 6  
170 -#define EXCP07_PREX 7  
171 -#define EXCP08_DBLE 8  
172 -#define EXCP09_XERR 9  
173 -#define EXCP0A_TSS 10  
174 -#define EXCP0B_NOSEG 11  
175 -#define EXCP0C_STACK 12  
176 -#define EXCP0D_GPF 13  
177 -#define EXCP0E_PAGE 14  
178 -#define EXCP10_COPR 16  
179 -#define EXCP11_ALGN 17  
180 -#define EXCP12_MCHK 18  
181 -  
182 -enum {  
183 - CC_OP_DYNAMIC, /* must use dynamic code to get cc_op */  
184 - CC_OP_EFLAGS, /* all cc are explicitely computed, CC_SRC = flags */  
185 - CC_OP_MUL, /* modify all flags, C, O = (CC_SRC != 0) */  
186 -  
187 - CC_OP_ADDB, /* modify all flags, CC_DST = res, CC_SRC = src1 */  
188 - CC_OP_ADDW,  
189 - CC_OP_ADDL,  
190 -  
191 - CC_OP_ADCB, /* modify all flags, CC_DST = res, CC_SRC = src1 */  
192 - CC_OP_ADCW,  
193 - CC_OP_ADCL,  
194 -  
195 - CC_OP_SUBB, /* modify all flags, CC_DST = res, CC_SRC = src1 */  
196 - CC_OP_SUBW,  
197 - CC_OP_SUBL,  
198 -  
199 - CC_OP_SBBB, /* modify all flags, CC_DST = res, CC_SRC = src1 */  
200 - CC_OP_SBBW,  
201 - CC_OP_SBBL,  
202 -  
203 - CC_OP_LOGICB, /* modify all flags, CC_DST = res */  
204 - CC_OP_LOGICW,  
205 - CC_OP_LOGICL,  
206 -  
207 - CC_OP_INCB, /* modify all flags except, CC_DST = res, CC_SRC = C */  
208 - CC_OP_INCW,  
209 - CC_OP_INCL,  
210 -  
211 - CC_OP_DECB, /* modify all flags except, CC_DST = res, CC_SRC = C */  
212 - CC_OP_DECW,  
213 - CC_OP_DECL,  
214 -  
215 - CC_OP_SHLB, /* modify all flags, CC_DST = res, CC_SRC.lsb = C */  
216 - CC_OP_SHLW,  
217 - CC_OP_SHLL,  
218 -  
219 - CC_OP_SARB, /* modify all flags, CC_DST = res, CC_SRC.lsb = C */  
220 - CC_OP_SARW,  
221 - CC_OP_SARL,  
222 -  
223 - CC_OP_NB,  
224 -};  
225 -  
226 -#ifdef __i386__  
227 -#define USE_X86LDOUBLE  
228 -#endif  
229 -  
230 -#ifdef USE_X86LDOUBLE  
231 -typedef long double CPU86_LDouble;  
232 -#else  
233 -typedef double CPU86_LDouble;  
234 -#endif  
235 -  
236 -typedef struct SegmentCache {  
237 - uint32_t selector;  
238 - uint8_t *base;  
239 - uint32_t limit;  
240 - uint32_t flags;  
241 -} SegmentCache;  
242 -  
243 -typedef struct CPUX86State {  
244 - /* standard registers */  
245 - uint32_t regs[8];  
246 - uint32_t eip;  
247 - uint32_t eflags; /* eflags register. During CPU emulation, CC  
248 - flags and DF are set to zero because they are  
249 - stored elsewhere */  
250 -  
251 - /* emulator internal eflags handling */  
252 - uint32_t cc_src;  
253 - uint32_t cc_dst;  
254 - uint32_t cc_op;  
255 - int32_t df; /* D flag : 1 if D = 0, -1 if D = 1 */  
256 - uint32_t hflags; /* hidden flags, see HF_xxx constants */  
257 -  
258 - /* FPU state */  
259 - unsigned int fpstt; /* top of stack index */  
260 - unsigned int fpus;  
261 - unsigned int fpuc;  
262 - uint8_t fptags[8]; /* 0 = valid, 1 = empty */  
263 - CPU86_LDouble fpregs[8];  
264 -  
265 - /* emulator internal variables */  
266 - CPU86_LDouble ft0;  
267 - union {  
268 - float f;  
269 - double d;  
270 - int i32;  
271 - int64_t i64;  
272 - } fp_convert;  
273 -  
274 - /* segments */  
275 - SegmentCache segs[6]; /* selector values */  
276 - SegmentCache ldt;  
277 - SegmentCache tr;  
278 - SegmentCache gdt; /* only base and limit are used */  
279 - SegmentCache idt; /* only base and limit are used */  
280 -  
281 - /* sysenter registers */  
282 - uint32_t sysenter_cs;  
283 - uint32_t sysenter_esp;  
284 - uint32_t sysenter_eip;  
285 -  
286 - /* exception/interrupt handling */  
287 - jmp_buf jmp_env;  
288 - int exception_index;  
289 - int error_code;  
290 - int exception_is_int;  
291 - int exception_next_eip;  
292 - struct TranslationBlock *current_tb; /* currently executing TB */  
293 - uint32_t cr[5]; /* NOTE: cr1 is unused */  
294 - uint32_t dr[8]; /* debug registers */  
295 - int interrupt_request;  
296 - int user_mode_only; /* user mode only simulation */  
297 -  
298 - /* soft mmu support */  
299 - /* 0 = kernel, 1 = user */  
300 - CPUTLBEntry tlb_read[2][CPU_TLB_SIZE];  
301 - CPUTLBEntry tlb_write[2][CPU_TLB_SIZE];  
302 -  
303 - /* ice debug support */  
304 - uint32_t breakpoints[MAX_BREAKPOINTS];  
305 - int nb_breakpoints;  
306 - int singlestep_enabled;  
307 -  
308 - /* user data */  
309 - void *opaque;  
310 -} CPUX86State;  
311 -  
312 -#ifndef IN_OP_I386  
313 -void cpu_x86_outb(CPUX86State *env, int addr, int val);  
314 -void cpu_x86_outw(CPUX86State *env, int addr, int val);  
315 -void cpu_x86_outl(CPUX86State *env, int addr, int val);  
316 -int cpu_x86_inb(CPUX86State *env, int addr);  
317 -int cpu_x86_inw(CPUX86State *env, int addr);  
318 -int cpu_x86_inl(CPUX86State *env, int addr);  
319 -#endif  
320 -  
321 -CPUX86State *cpu_x86_init(void);  
322 -int cpu_x86_exec(CPUX86State *s);  
323 -void cpu_x86_close(CPUX86State *s);  
324 -int cpu_x86_get_pic_interrupt(CPUX86State *s);  
325 -  
326 -/* this function must always be used to load data in the segment  
327 - cache: it synchronizes the hflags with the segment cache values */  
328 -static inline void cpu_x86_load_seg_cache(CPUX86State *env,  
329 - int seg_reg, unsigned int selector,  
330 - uint8_t *base, unsigned int limit,  
331 - unsigned int flags)  
332 -{  
333 - SegmentCache *sc;  
334 - unsigned int new_hflags;  
335 -  
336 - sc = &env->segs[seg_reg];  
337 - sc->selector = selector;  
338 - sc->base = base;  
339 - sc->limit = limit;  
340 - sc->flags = flags;  
341 -  
342 - /* update the hidden flags */  
343 - new_hflags = (env->segs[R_CS].flags & DESC_B_MASK)  
344 - >> (DESC_B_SHIFT - HF_CS32_SHIFT);  
345 - new_hflags |= (env->segs[R_SS].flags & DESC_B_MASK)  
346 - >> (DESC_B_SHIFT - HF_SS32_SHIFT);  
347 - if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) {  
348 - /* XXX: try to avoid this test. The problem comes from the  
349 - fact that is real mode or vm86 mode we only modify the  
350 - 'base' and 'selector' fields of the segment cache to go  
351 - faster. A solution may be to force addseg to one in  
352 - translate-i386.c. */  
353 - new_hflags |= HF_ADDSEG_MASK;  
354 - } else {  
355 - new_hflags |= (((unsigned long)env->segs[R_DS].base |  
356 - (unsigned long)env->segs[R_ES].base |  
357 - (unsigned long)env->segs[R_SS].base) != 0) <<  
358 - HF_ADDSEG_SHIFT;  
359 - }  
360 - env->hflags = (env->hflags &  
361 - ~(HF_CS32_MASK | HF_SS32_MASK | HF_ADDSEG_MASK)) | new_hflags;  
362 -}  
363 -  
364 -/* wrapper, just in case memory mappings must be changed */  
365 -static inline void cpu_x86_set_cpl(CPUX86State *s, int cpl)  
366 -{  
367 -#if HF_CPL_MASK == 3  
368 - s->hflags = (s->hflags & ~HF_CPL_MASK) | cpl;  
369 -#else  
370 -#error HF_CPL_MASK is hardcoded  
371 -#endif  
372 -}  
373 -  
374 -/* the following helpers are only usable in user mode simulation as  
375 - they can trigger unexpected exceptions */  
376 -void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector);  
377 -void cpu_x86_fsave(CPUX86State *s, uint8_t *ptr, int data32);  
378 -void cpu_x86_frstor(CPUX86State *s, uint8_t *ptr, int data32);  
379 -  
380 -/* you can call this signal handler from your SIGBUS and SIGSEGV  
381 - signal handlers to inform the virtual CPU of exceptions. non zero  
382 - is returned if the signal was handled by the virtual CPU. */  
383 -struct siginfo;  
384 -int cpu_x86_signal_handler(int host_signum, struct siginfo *info,  
385 - void *puc);  
386 -  
387 -/* MMU defines */  
388 -void cpu_x86_init_mmu(CPUX86State *env);  
389 -extern int phys_ram_size;  
390 -extern int phys_ram_fd;  
391 -extern uint8_t *phys_ram_base;  
392 -  
393 -/* used to debug */  
394 -#define X86_DUMP_FPU 0x0001 /* dump FPU state too */  
395 -#define X86_DUMP_CCOP 0x0002 /* dump qemu flag cache */  
396 -void cpu_x86_dump_state(CPUX86State *env, FILE *f, int flags);  
397 -  
398 -#define TARGET_PAGE_BITS 12  
399 -#include "cpu-all.h"  
400 -  
401 -#endif /* CPU_I386_H */  
exec.h renamed to exec-all.h
exec-arm.h deleted 100644 → 0
1 -/*  
2 - * ARM execution defines  
3 - *  
4 - * Copyright (c) 2003 Fabrice Bellard  
5 - *  
6 - * This library is free software; you can redistribute it and/or  
7 - * modify it under the terms of the GNU Lesser General Public  
8 - * License as published by the Free Software Foundation; either  
9 - * version 2 of the License, or (at your option) any later version.  
10 - *  
11 - * This library is distributed in the hope that it will be useful,  
12 - * but WITHOUT ANY WARRANTY; without even the implied warranty of  
13 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  
14 - * Lesser General Public License for more details.  
15 - *  
16 - * You should have received a copy of the GNU Lesser General Public  
17 - * License along with this library; if not, write to the Free Software  
18 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA  
19 - */  
20 -#include "dyngen-exec.h"  
21 -  
22 -register struct CPUARMState *env asm(AREG0);  
23 -register uint32_t T0 asm(AREG1);  
24 -register uint32_t T1 asm(AREG2);  
25 -register uint32_t T2 asm(AREG3);  
26 -  
27 -#include "cpu-arm.h"  
28 -#include "exec.h"  
29 -  
30 -void cpu_lock(void);  
31 -void cpu_unlock(void);  
32 -void cpu_loop_exit(void);  
33 -  
34 -static inline int compute_cpsr(void)  
35 -{  
36 - int ZF;  
37 - ZF = (env->NZF == 0);  
38 - return env->cpsr | (env->NZF & 0x80000000) | (ZF << 30) |  
39 - (env->CF << 29) | ((env->VF & 0x80000000) >> 3);  
40 -}  
exec-i386.h deleted 100644 → 0
1 -/*  
2 - * i386 execution defines  
3 - *  
4 - * Copyright (c) 2003 Fabrice Bellard  
5 - *  
6 - * This library is free software; you can redistribute it and/or  
7 - * modify it under the terms of the GNU Lesser General Public  
8 - * License as published by the Free Software Foundation; either  
9 - * version 2 of the License, or (at your option) any later version.  
10 - *  
11 - * This library is distributed in the hope that it will be useful,  
12 - * but WITHOUT ANY WARRANTY; without even the implied warranty of  
13 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  
14 - * Lesser General Public License for more details.  
15 - *  
16 - * You should have received a copy of the GNU Lesser General Public  
17 - * License along with this library; if not, write to the Free Software  
18 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA  
19 - */  
20 -#include "dyngen-exec.h"  
21 -  
22 -/* at least 4 register variables are defines */  
23 -register struct CPUX86State *env asm(AREG0);  
24 -register uint32_t T0 asm(AREG1);  
25 -register uint32_t T1 asm(AREG2);  
26 -register uint32_t T2 asm(AREG3);  
27 -  
28 -#define A0 T2  
29 -  
30 -/* if more registers are available, we define some registers too */  
31 -#ifdef AREG4  
32 -register uint32_t EAX asm(AREG4);  
33 -#define reg_EAX  
34 -#endif  
35 -  
36 -#ifdef AREG5  
37 -register uint32_t ESP asm(AREG5);  
38 -#define reg_ESP  
39 -#endif  
40 -  
41 -#ifdef AREG6  
42 -register uint32_t EBP asm(AREG6);  
43 -#define reg_EBP  
44 -#endif  
45 -  
46 -#ifdef AREG7  
47 -register uint32_t ECX asm(AREG7);  
48 -#define reg_ECX  
49 -#endif  
50 -  
51 -#ifdef AREG8  
52 -register uint32_t EDX asm(AREG8);  
53 -#define reg_EDX  
54 -#endif  
55 -  
56 -#ifdef AREG9  
57 -register uint32_t EBX asm(AREG9);  
58 -#define reg_EBX  
59 -#endif  
60 -  
61 -#ifdef AREG10  
62 -register uint32_t ESI asm(AREG10);  
63 -#define reg_ESI  
64 -#endif  
65 -  
66 -#ifdef AREG11  
67 -register uint32_t EDI asm(AREG11);  
68 -#define reg_EDI  
69 -#endif  
70 -  
71 -extern FILE *logfile;  
72 -extern int loglevel;  
73 -  
74 -#ifndef reg_EAX  
75 -#define EAX (env->regs[R_EAX])  
76 -#endif  
77 -#ifndef reg_ECX  
78 -#define ECX (env->regs[R_ECX])  
79 -#endif  
80 -#ifndef reg_EDX  
81 -#define EDX (env->regs[R_EDX])  
82 -#endif  
83 -#ifndef reg_EBX  
84 -#define EBX (env->regs[R_EBX])  
85 -#endif  
86 -#ifndef reg_ESP  
87 -#define ESP (env->regs[R_ESP])  
88 -#endif  
89 -#ifndef reg_EBP  
90 -#define EBP (env->regs[R_EBP])  
91 -#endif  
92 -#ifndef reg_ESI  
93 -#define ESI (env->regs[R_ESI])  
94 -#endif  
95 -#ifndef reg_EDI  
96 -#define EDI (env->regs[R_EDI])  
97 -#endif  
98 -#define EIP (env->eip)  
99 -#define DF (env->df)  
100 -  
101 -#define CC_SRC (env->cc_src)  
102 -#define CC_DST (env->cc_dst)  
103 -#define CC_OP (env->cc_op)  
104 -  
105 -/* float macros */  
106 -#define FT0 (env->ft0)  
107 -#define ST0 (env->fpregs[env->fpstt])  
108 -#define ST(n) (env->fpregs[(env->fpstt + (n)) & 7])  
109 -#define ST1 ST(1)  
110 -  
111 -#ifdef USE_FP_CONVERT  
112 -#define FP_CONVERT (env->fp_convert)  
113 -#endif  
114 -  
115 -#include "cpu-i386.h"  
116 -#include "exec.h"  
117 -  
118 -typedef struct CCTable {  
119 - int (*compute_all)(void); /* return all the flags */  
120 - int (*compute_c)(void); /* return the C flag */  
121 -} CCTable;  
122 -  
123 -extern CCTable cc_table[];  
124 -  
125 -void load_seg(int seg_reg, int selector, unsigned cur_eip);  
126 -void helper_ljmp_protected_T0_T1(void);  
127 -void helper_lcall_real_T0_T1(int shift, int next_eip);  
128 -void helper_lcall_protected_T0_T1(int shift, int next_eip);  
129 -void helper_iret_real(int shift);  
130 -void helper_iret_protected(int shift);  
131 -void helper_lret_protected(int shift, int addend);  
132 -void helper_lldt_T0(void);  
133 -void helper_ltr_T0(void);  
134 -void helper_movl_crN_T0(int reg);  
135 -void helper_movl_drN_T0(int reg);  
136 -void helper_invlpg(unsigned int addr);  
137 -void cpu_x86_update_cr0(CPUX86State *env);  
138 -void cpu_x86_update_cr3(CPUX86State *env);  
139 -void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr);  
140 -int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write);  
141 -void tlb_fill(unsigned long addr, int is_write, void *retaddr);  
142 -void __hidden cpu_lock(void);  
143 -void __hidden cpu_unlock(void);  
144 -void do_interrupt(int intno, int is_int, int error_code,  
145 - unsigned int next_eip, int is_hw);  
146 -void do_interrupt_user(int intno, int is_int, int error_code,  
147 - unsigned int next_eip);  
148 -void raise_interrupt(int intno, int is_int, int error_code,  
149 - unsigned int next_eip);  
150 -void raise_exception_err(int exception_index, int error_code);  
151 -void raise_exception(int exception_index);  
152 -void __hidden cpu_loop_exit(void);  
153 -void helper_fsave(uint8_t *ptr, int data32);  
154 -void helper_frstor(uint8_t *ptr, int data32);  
155 -  
156 -void OPPROTO op_movl_eflags_T0(void);  
157 -void OPPROTO op_movl_T0_eflags(void);  
158 -void raise_interrupt(int intno, int is_int, int error_code,  
159 - unsigned int next_eip);  
160 -void raise_exception_err(int exception_index, int error_code);  
161 -void raise_exception(int exception_index);  
162 -void helper_divl_EAX_T0(uint32_t eip);  
163 -void helper_idivl_EAX_T0(uint32_t eip);  
164 -void helper_cmpxchg8b(void);  
165 -void helper_cpuid(void);  
166 -void helper_rdtsc(void);  
167 -void helper_rdmsr(void);  
168 -void helper_wrmsr(void);  
169 -void helper_lsl(void);  
170 -void helper_lar(void);  
171 -  
172 -#ifdef USE_X86LDOUBLE  
173 -/* use long double functions */  
174 -#define lrint lrintl  
175 -#define llrint llrintl  
176 -#define fabs fabsl  
177 -#define sin sinl  
178 -#define cos cosl  
179 -#define sqrt sqrtl  
180 -#define pow powl  
181 -#define log logl  
182 -#define tan tanl  
183 -#define atan2 atan2l  
184 -#define floor floorl  
185 -#define ceil ceill  
186 -#define rint rintl  
187 -#endif  
188 -  
189 -extern int lrint(CPU86_LDouble x);  
190 -extern int64_t llrint(CPU86_LDouble x);  
191 -extern CPU86_LDouble fabs(CPU86_LDouble x);  
192 -extern CPU86_LDouble sin(CPU86_LDouble x);  
193 -extern CPU86_LDouble cos(CPU86_LDouble x);  
194 -extern CPU86_LDouble sqrt(CPU86_LDouble x);  
195 -extern CPU86_LDouble pow(CPU86_LDouble, CPU86_LDouble);  
196 -extern CPU86_LDouble log(CPU86_LDouble x);  
197 -extern CPU86_LDouble tan(CPU86_LDouble x);  
198 -extern CPU86_LDouble atan2(CPU86_LDouble, CPU86_LDouble);  
199 -extern CPU86_LDouble floor(CPU86_LDouble x);  
200 -extern CPU86_LDouble ceil(CPU86_LDouble x);  
201 -extern CPU86_LDouble rint(CPU86_LDouble x);  
202 -  
203 -#define RC_MASK 0xc00  
204 -#define RC_NEAR 0x000  
205 -#define RC_DOWN 0x400  
206 -#define RC_UP 0x800  
207 -#define RC_CHOP 0xc00  
208 -  
209 -#define MAXTAN 9223372036854775808.0  
210 -  
211 -#ifdef __arm__  
212 -/* we have no way to do correct rounding - a FPU emulator is needed */  
213 -#define FE_DOWNWARD FE_TONEAREST  
214 -#define FE_UPWARD FE_TONEAREST  
215 -#define FE_TOWARDZERO FE_TONEAREST  
216 -#endif  
217 -  
218 -#ifdef USE_X86LDOUBLE  
219 -  
220 -/* only for x86 */  
221 -typedef union {  
222 - long double d;  
223 - struct {  
224 - unsigned long long lower;  
225 - unsigned short upper;  
226 - } l;  
227 -} CPU86_LDoubleU;  
228 -  
229 -/* the following deal with x86 long double-precision numbers */  
230 -#define MAXEXPD 0x7fff  
231 -#define EXPBIAS 16383  
232 -#define EXPD(fp) (fp.l.upper & 0x7fff)  
233 -#define SIGND(fp) ((fp.l.upper) & 0x8000)  
234 -#define MANTD(fp) (fp.l.lower)  
235 -#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7fff)) | EXPBIAS  
236 -  
237 -#else  
238 -  
239 -/* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */  
240 -typedef union {  
241 - double d;  
242 -#if !defined(WORDS_BIGENDIAN) && !defined(__arm__)  
243 - struct {  
244 - uint32_t lower;  
245 - int32_t upper;  
246 - } l;  
247 -#else  
248 - struct {  
249 - int32_t upper;  
250 - uint32_t lower;  
251 - } l;  
252 -#endif  
253 -#ifndef __arm__  
254 - int64_t ll;  
255 -#endif  
256 -} CPU86_LDoubleU;  
257 -  
258 -/* the following deal with IEEE double-precision numbers */  
259 -#define MAXEXPD 0x7ff  
260 -#define EXPBIAS 1023  
261 -#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF)  
262 -#define SIGND(fp) ((fp.l.upper) & 0x80000000)  
263 -#ifdef __arm__  
264 -#define MANTD(fp) (fp.l.lower | ((uint64_t)(fp.l.upper & ((1 << 20) - 1)) << 32))  
265 -#else  
266 -#define MANTD(fp) (fp.ll & ((1LL << 52) - 1))  
267 -#endif  
268 -#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7ff << 20)) | (EXPBIAS << 20)  
269 -#endif  
270 -  
271 -static inline void fpush(void)  
272 -{  
273 - env->fpstt = (env->fpstt - 1) & 7;  
274 - env->fptags[env->fpstt] = 0; /* validate stack entry */  
275 -}  
276 -  
277 -static inline void fpop(void)  
278 -{  
279 - env->fptags[env->fpstt] = 1; /* invvalidate stack entry */  
280 - env->fpstt = (env->fpstt + 1) & 7;  
281 -}  
282 -  
283 -#ifndef USE_X86LDOUBLE  
284 -static inline CPU86_LDouble helper_fldt(uint8_t *ptr)  
285 -{  
286 - CPU86_LDoubleU temp;  
287 - int upper, e;  
288 - uint64_t ll;  
289 -  
290 - /* mantissa */  
291 - upper = lduw(ptr + 8);  
292 - /* XXX: handle overflow ? */  
293 - e = (upper & 0x7fff) - 16383 + EXPBIAS; /* exponent */  
294 - e |= (upper >> 4) & 0x800; /* sign */  
295 - ll = (ldq(ptr) >> 11) & ((1LL << 52) - 1);  
296 -#ifdef __arm__  
297 - temp.l.upper = (e << 20) | (ll >> 32);  
298 - temp.l.lower = ll;  
299 -#else  
300 - temp.ll = ll | ((uint64_t)e << 52);  
301 -#endif  
302 - return temp.d;  
303 -}  
304 -  
305 -static inline void helper_fstt(CPU86_LDouble f, uint8_t *ptr)  
306 -{  
307 - CPU86_LDoubleU temp;  
308 - int e;  
309 -  
310 - temp.d = f;  
311 - /* mantissa */  
312 - stq(ptr, (MANTD(temp) << 11) | (1LL << 63));  
313 - /* exponent + sign */  
314 - e = EXPD(temp) - EXPBIAS + 16383;  
315 - e |= SIGND(temp) >> 16;  
316 - stw(ptr + 8, e);  
317 -}  
318 -#endif  
319 -  
320 -const CPU86_LDouble f15rk[7];  
321 -  
322 -void helper_fldt_ST0_A0(void);  
323 -void helper_fstt_ST0_A0(void);  
324 -void helper_fbld_ST0_A0(void);  
325 -void helper_fbst_ST0_A0(void);  
326 -void helper_f2xm1(void);  
327 -void helper_fyl2x(void);  
328 -void helper_fptan(void);  
329 -void helper_fpatan(void);  
330 -void helper_fxtract(void);  
331 -void helper_fprem1(void);  
332 -void helper_fprem(void);  
333 -void helper_fyl2xp1(void);  
334 -void helper_fsqrt(void);  
335 -void helper_fsincos(void);  
336 -void helper_frndint(void);  
337 -void helper_fscale(void);  
338 -void helper_fsin(void);  
339 -void helper_fcos(void);  
340 -void helper_fxam_ST0(void);  
341 -void helper_fstenv(uint8_t *ptr, int data32);  
342 -void helper_fldenv(uint8_t *ptr, int data32);  
343 -void helper_fsave(uint8_t *ptr, int data32);  
344 -void helper_frstor(uint8_t *ptr, int data32);  
345 -  
346 -const uint8_t parity_table[256];  
347 -const uint8_t rclw_table[32];  
348 -const uint8_t rclb_table[32];  
349 -  
350 -static inline uint32_t compute_eflags(void)  
351 -{  
352 - return env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);  
353 -}  
354 -  
355 -#define FL_UPDATE_MASK32 (TF_MASK | AC_MASK | ID_MASK)  
356 -  
357 -#define FL_UPDATE_CPL0_MASK (TF_MASK | IF_MASK | IOPL_MASK | NT_MASK | \  
358 - RF_MASK | AC_MASK | ID_MASK)  
359 -  
360 -/* NOTE: CC_OP must be modified manually to CC_OP_EFLAGS */  
361 -static inline void load_eflags(int eflags, int update_mask)  
362 -{  
363 - CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);  
364 - DF = 1 - (2 * ((eflags >> 10) & 1));  
365 - env->eflags = (env->eflags & ~update_mask) |  
366 - (eflags & update_mask);  
367 -}  
368 -  
369 -/* memory access macros */  
370 -  
371 -#define ldul ldl  
372 -#define lduq ldq  
373 -#define ldul_user ldl_user  
374 -#define ldul_kernel ldl_kernel  
375 -  
376 -#define ldub_raw ldub  
377 -#define ldsb_raw ldsb  
378 -#define lduw_raw lduw  
379 -#define ldsw_raw ldsw  
380 -#define ldl_raw ldl  
381 -#define ldq_raw ldq  
382 -  
383 -#define stb_raw stb  
384 -#define stw_raw stw  
385 -#define stl_raw stl  
386 -#define stq_raw stq  
387 -  
388 -#define MEMUSER 0  
389 -#define DATA_SIZE 1  
390 -#include "softmmu_header.h"  
391 -  
392 -#define DATA_SIZE 2  
393 -#include "softmmu_header.h"  
394 -  
395 -#define DATA_SIZE 4  
396 -#include "softmmu_header.h"  
397 -  
398 -#define DATA_SIZE 8  
399 -#include "softmmu_header.h"  
400 -  
401 -#undef MEMUSER  
402 -#define MEMUSER 1  
403 -#define DATA_SIZE 1  
404 -#include "softmmu_header.h"  
405 -  
406 -#define DATA_SIZE 2  
407 -#include "softmmu_header.h"  
408 -  
409 -#define DATA_SIZE 4  
410 -#include "softmmu_header.h"  
411 -  
412 -#define DATA_SIZE 8  
413 -#include "softmmu_header.h"  
414 -  
415 -#undef MEMUSER  
416 -  
helper-i386.c deleted 100644 → 0
1 -/*  
2 - * i386 helpers  
3 - *  
4 - * Copyright (c) 2003 Fabrice Bellard  
5 - *  
6 - * This library is free software; you can redistribute it and/or  
7 - * modify it under the terms of the GNU Lesser General Public  
8 - * License as published by the Free Software Foundation; either  
9 - * version 2 of the License, or (at your option) any later version.  
10 - *  
11 - * This library is distributed in the hope that it will be useful,  
12 - * but WITHOUT ANY WARRANTY; without even the implied warranty of  
13 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  
14 - * Lesser General Public License for more details.  
15 - *  
16 - * You should have received a copy of the GNU Lesser General Public  
17 - * License along with this library; if not, write to the Free Software  
18 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA  
19 - */  
20 -#include "exec-i386.h"  
21 -  
22 -const uint8_t parity_table[256] = {  
23 - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,  
24 - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,  
25 - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,  
26 - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,  
27 - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,  
28 - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,  
29 - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,  
30 - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,  
31 - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,  
32 - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,  
33 - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,  
34 - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,  
35 - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,  
36 - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,  
37 - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,  
38 - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,  
39 - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,  
40 - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,  
41 - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,  
42 - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,  
43 - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,  
44 - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,  
45 - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,  
46 - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,  
47 - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,  
48 - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,  
49 - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,  
50 - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,  
51 - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,  
52 - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,  
53 - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,  
54 - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,  
55 -};  
56 -  
57 -/* modulo 17 table */  
58 -const uint8_t rclw_table[32] = {  
59 - 0, 1, 2, 3, 4, 5, 6, 7,  
60 - 8, 9,10,11,12,13,14,15,  
61 - 16, 0, 1, 2, 3, 4, 5, 6,  
62 - 7, 8, 9,10,11,12,13,14,  
63 -};  
64 -  
65 -/* modulo 9 table */  
66 -const uint8_t rclb_table[32] = {  
67 - 0, 1, 2, 3, 4, 5, 6, 7,  
68 - 8, 0, 1, 2, 3, 4, 5, 6,  
69 - 7, 8, 0, 1, 2, 3, 4, 5,  
70 - 6, 7, 8, 0, 1, 2, 3, 4,  
71 -};  
72 -  
73 -const CPU86_LDouble f15rk[7] =  
74 -{  
75 - 0.00000000000000000000L,  
76 - 1.00000000000000000000L,  
77 - 3.14159265358979323851L, /*pi*/  
78 - 0.30102999566398119523L, /*lg2*/  
79 - 0.69314718055994530943L, /*ln2*/  
80 - 1.44269504088896340739L, /*l2e*/  
81 - 3.32192809488736234781L, /*l2t*/  
82 -};  
83 -  
84 -/* thread support */  
85 -  
86 -spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED;  
87 -  
88 -void cpu_lock(void)  
89 -{  
90 - spin_lock(&global_cpu_lock);  
91 -}  
92 -  
93 -void cpu_unlock(void)  
94 -{  
95 - spin_unlock(&global_cpu_lock);  
96 -}  
97 -  
98 -void cpu_loop_exit(void)  
99 -{  
100 - /* NOTE: the register at this point must be saved by hand because  
101 - longjmp restore them */  
102 -#ifdef reg_EAX  
103 - env->regs[R_EAX] = EAX;  
104 -#endif  
105 -#ifdef reg_ECX  
106 - env->regs[R_ECX] = ECX;  
107 -#endif  
108 -#ifdef reg_EDX  
109 - env->regs[R_EDX] = EDX;  
110 -#endif  
111 -#ifdef reg_EBX  
112 - env->regs[R_EBX] = EBX;  
113 -#endif  
114 -#ifdef reg_ESP  
115 - env->regs[R_ESP] = ESP;  
116 -#endif  
117 -#ifdef reg_EBP  
118 - env->regs[R_EBP] = EBP;  
119 -#endif  
120 -#ifdef reg_ESI  
121 - env->regs[R_ESI] = ESI;  
122 -#endif  
123 -#ifdef reg_EDI  
124 - env->regs[R_EDI] = EDI;  
125 -#endif  
126 - longjmp(env->jmp_env, 1);  
127 -}  
128 -  
129 -static inline void get_ss_esp_from_tss(uint32_t *ss_ptr,  
130 - uint32_t *esp_ptr, int dpl)  
131 -{  
132 - int type, index, shift;  
133 -  
134 -#if 0  
135 - {  
136 - int i;  
137 - printf("TR: base=%p limit=%x\n", env->tr.base, env->tr.limit);  
138 - for(i=0;i<env->tr.limit;i++) {  
139 - printf("%02x ", env->tr.base[i]);  
140 - if ((i & 7) == 7) printf("\n");  
141 - }  
142 - printf("\n");  
143 - }  
144 -#endif  
145 -  
146 - if (!(env->tr.flags & DESC_P_MASK))  
147 - cpu_abort(env, "invalid tss");  
148 - type = (env->tr.flags >> DESC_TYPE_SHIFT) & 0xf;  
149 - if ((type & 7) != 1)  
150 - cpu_abort(env, "invalid tss type");  
151 - shift = type >> 3;  
152 - index = (dpl * 4 + 2) << shift;  
153 - if (index + (4 << shift) - 1 > env->tr.limit)  
154 - raise_exception_err(EXCP0A_TSS, env->tr.selector & 0xfffc);  
155 - if (shift == 0) {  
156 - *esp_ptr = lduw(env->tr.base + index);  
157 - *ss_ptr = lduw(env->tr.base + index + 2);  
158 - } else {  
159 - *esp_ptr = ldl(env->tr.base + index);  
160 - *ss_ptr = lduw(env->tr.base + index + 4);  
161 - }  
162 -}  
163 -  
164 -/* return non zero if error */  
165 -static inline int load_segment(uint32_t *e1_ptr, uint32_t *e2_ptr,  
166 - int selector)  
167 -{  
168 - SegmentCache *dt;  
169 - int index;  
170 - uint8_t *ptr;  
171 -  
172 - if (selector & 0x4)  
173 - dt = &env->ldt;  
174 - else  
175 - dt = &env->gdt;  
176 - index = selector & ~7;  
177 - if ((index + 7) > dt->limit)  
178 - return -1;  
179 - ptr = dt->base + index;  
180 - *e1_ptr = ldl(ptr);  
181 - *e2_ptr = ldl(ptr + 4);  
182 - return 0;  
183 -}  
184 -  
185 -static inline unsigned int get_seg_limit(uint32_t e1, uint32_t e2)  
186 -{  
187 - unsigned int limit;  
188 - limit = (e1 & 0xffff) | (e2 & 0x000f0000);  
189 - if (e2 & DESC_G_MASK)  
190 - limit = (limit << 12) | 0xfff;  
191 - return limit;  
192 -}  
193 -  
194 -static inline uint8_t *get_seg_base(uint32_t e1, uint32_t e2)  
195 -{  
196 - return (uint8_t *)((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));  
197 -}  
198 -  
199 -static inline void load_seg_cache_raw_dt(SegmentCache *sc, uint32_t e1, uint32_t e2)  
200 -{  
201 - sc->base = get_seg_base(e1, e2);  
202 - sc->limit = get_seg_limit(e1, e2);  
203 - sc->flags = e2;  
204 -}  
205 -  
206 -/* init the segment cache in vm86 mode. */  
207 -static inline void load_seg_vm(int seg, int selector)  
208 -{  
209 - selector &= 0xffff;  
210 - cpu_x86_load_seg_cache(env, seg, selector,  
211 - (uint8_t *)(selector << 4), 0xffff, 0);  
212 -}  
213 -  
214 -/* protected mode interrupt */  
215 -static void do_interrupt_protected(int intno, int is_int, int error_code,  
216 - unsigned int next_eip, int is_hw)  
217 -{  
218 - SegmentCache *dt;  
219 - uint8_t *ptr, *ssp;  
220 - int type, dpl, selector, ss_dpl, cpl;  
221 - int has_error_code, new_stack, shift;  
222 - uint32_t e1, e2, offset, ss, esp, ss_e1, ss_e2, push_size;  
223 - uint32_t old_cs, old_ss, old_esp, old_eip;  
224 -  
225 - dt = &env->idt;  
226 - if (intno * 8 + 7 > dt->limit)  
227 - raise_exception_err(EXCP0D_GPF, intno * 8 + 2);  
228 - ptr = dt->base + intno * 8;  
229 - e1 = ldl(ptr);  
230 - e2 = ldl(ptr + 4);  
231 - /* check gate type */  
232 - type = (e2 >> DESC_TYPE_SHIFT) & 0x1f;  
233 - switch(type) {  
234 - case 5: /* task gate */  
235 - cpu_abort(env, "task gate not supported");  
236 - break;  
237 - case 6: /* 286 interrupt gate */  
238 - case 7: /* 286 trap gate */  
239 - case 14: /* 386 interrupt gate */  
240 - case 15: /* 386 trap gate */  
241 - break;  
242 - default:  
243 - raise_exception_err(EXCP0D_GPF, intno * 8 + 2);  
244 - break;  
245 - }  
246 - dpl = (e2 >> DESC_DPL_SHIFT) & 3;  
247 - cpl = env->hflags & HF_CPL_MASK;  
248 - /* check privledge if software int */  
249 - if (is_int && dpl < cpl)  
250 - raise_exception_err(EXCP0D_GPF, intno * 8 + 2);  
251 - /* check valid bit */  
252 - if (!(e2 & DESC_P_MASK))  
253 - raise_exception_err(EXCP0B_NOSEG, intno * 8 + 2);  
254 - selector = e1 >> 16;  
255 - offset = (e2 & 0xffff0000) | (e1 & 0x0000ffff);  
256 - if ((selector & 0xfffc) == 0)  
257 - raise_exception_err(EXCP0D_GPF, 0);  
258 -  
259 - if (load_segment(&e1, &e2, selector) != 0)  
260 - raise_exception_err(EXCP0D_GPF, selector & 0xfffc);  
261 - if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK)))  
262 - raise_exception_err(EXCP0D_GPF, selector & 0xfffc);  
263 - dpl = (e2 >> DESC_DPL_SHIFT) & 3;  
264 - if (dpl > cpl)  
265 - raise_exception_err(EXCP0D_GPF, selector & 0xfffc);  
266 - if (!(e2 & DESC_P_MASK))  
267 - raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);  
268 - if (!(e2 & DESC_C_MASK) && dpl < cpl) {  
269 - /* to inner priviledge */  
270 - get_ss_esp_from_tss(&ss, &esp, dpl);  
271 - if ((ss & 0xfffc) == 0)  
272 - raise_exception_err(EXCP0A_TSS, ss & 0xfffc);  
273 - if ((ss & 3) != dpl)  
274 - raise_exception_err(EXCP0A_TSS, ss & 0xfffc);  
275 - if (load_segment(&ss_e1, &ss_e2, ss) != 0)  
276 - raise_exception_err(EXCP0A_TSS, ss & 0xfffc);  
277 - ss_dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3;  
278 - if (ss_dpl != dpl)  
279 - raise_exception_err(EXCP0A_TSS, ss & 0xfffc);  
280 - if (!(ss_e2 & DESC_S_MASK) ||  
281 - (ss_e2 & DESC_CS_MASK) ||  
282 - !(ss_e2 & DESC_W_MASK))  
283 - raise_exception_err(EXCP0A_TSS, ss & 0xfffc);  
284 - if (!(ss_e2 & DESC_P_MASK))  
285 - raise_exception_err(EXCP0A_TSS, ss & 0xfffc);  
286 - new_stack = 1;  
287 - } else if ((e2 & DESC_C_MASK) || dpl == cpl) {  
288 - /* to same priviledge */  
289 - new_stack = 0;  
290 - } else {  
291 - raise_exception_err(EXCP0D_GPF, selector & 0xfffc);  
292 - new_stack = 0; /* avoid warning */  
293 - }  
294 -  
295 - shift = type >> 3;  
296 - has_error_code = 0;  
297 - if (!is_int && !is_hw) {  
298 - switch(intno) {  
299 - case 8:  
300 - case 10:  
301 - case 11:  
302 - case 12:  
303 - case 13:  
304 - case 14:  
305 - case 17:  
306 - has_error_code = 1;  
307 - break;  
308 - }  
309 - }  
310 - push_size = 6 + (new_stack << 2) + (has_error_code << 1);  
311 - if (env->eflags & VM_MASK)  
312 - push_size += 8;  
313 - push_size <<= shift;  
314 -  
315 - /* XXX: check that enough room is available */  
316 - if (new_stack) {  
317 - old_esp = ESP;  
318 - old_ss = env->segs[R_SS].selector;  
319 - ss = (ss & ~3) | dpl;  
320 - cpu_x86_load_seg_cache(env, R_SS, ss,  
321 - get_seg_base(ss_e1, ss_e2),  
322 - get_seg_limit(ss_e1, ss_e2),  
323 - ss_e2);  
324 - } else {  
325 - old_esp = 0;  
326 - old_ss = 0;  
327 - esp = ESP;  
328 - }  
329 - if (is_int)  
330 - old_eip = next_eip;  
331 - else  
332 - old_eip = env->eip;  
333 - old_cs = env->segs[R_CS].selector;  
334 - selector = (selector & ~3) | dpl;  
335 - cpu_x86_load_seg_cache(env, R_CS, selector,  
336 - get_seg_base(e1, e2),  
337 - get_seg_limit(e1, e2),  
338 - e2);  
339 - cpu_x86_set_cpl(env, dpl);  
340 - env->eip = offset;  
341 - ESP = esp - push_size;  
342 - ssp = env->segs[R_SS].base + esp;  
343 - if (shift == 1) {  
344 - int old_eflags;  
345 - if (env->eflags & VM_MASK) {  
346 - ssp -= 4;  
347 - stl(ssp, env->segs[R_GS].selector);  
348 - ssp -= 4;  
349 - stl(ssp, env->segs[R_FS].selector);  
350 - ssp -= 4;  
351 - stl(ssp, env->segs[R_DS].selector);  
352 - ssp -= 4;  
353 - stl(ssp, env->segs[R_ES].selector);  
354 - }  
355 - if (new_stack) {  
356 - ssp -= 4;  
357 - stl(ssp, old_ss);  
358 - ssp -= 4;  
359 - stl(ssp, old_esp);  
360 - }  
361 - ssp -= 4;  
362 - old_eflags = compute_eflags();  
363 - stl(ssp, old_eflags);  
364 - ssp -= 4;  
365 - stl(ssp, old_cs);  
366 - ssp -= 4;  
367 - stl(ssp, old_eip);  
368 - if (has_error_code) {  
369 - ssp -= 4;  
370 - stl(ssp, error_code);  
371 - }  
372 - } else {  
373 - if (new_stack) {  
374 - ssp -= 2;  
375 - stw(ssp, old_ss);  
376 - ssp -= 2;  
377 - stw(ssp, old_esp);  
378 - }  
379 - ssp -= 2;  
380 - stw(ssp, compute_eflags());  
381 - ssp -= 2;  
382 - stw(ssp, old_cs);  
383 - ssp -= 2;  
384 - stw(ssp, old_eip);  
385 - if (has_error_code) {  
386 - ssp -= 2;  
387 - stw(ssp, error_code);  
388 - }  
389 - }  
390 -  
391 - /* interrupt gate clear IF mask */  
392 - if ((type & 1) == 0) {  
393 - env->eflags &= ~IF_MASK;  
394 - }  
395 - env->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK);  
396 -}  
397 -  
398 -/* real mode interrupt */  
399 -static void do_interrupt_real(int intno, int is_int, int error_code,  
400 - unsigned int next_eip)  
401 -{  
402 - SegmentCache *dt;  
403 - uint8_t *ptr, *ssp;  
404 - int selector;  
405 - uint32_t offset, esp;  
406 - uint32_t old_cs, old_eip;  
407 -  
408 - /* real mode (simpler !) */  
409 - dt = &env->idt;  
410 - if (intno * 4 + 3 > dt->limit)  
411 - raise_exception_err(EXCP0D_GPF, intno * 8 + 2);  
412 - ptr = dt->base + intno * 4;  
413 - offset = lduw(ptr);  
414 - selector = lduw(ptr + 2);  
415 - esp = ESP;  
416 - ssp = env->segs[R_SS].base;  
417 - if (is_int)  
418 - old_eip = next_eip;  
419 - else  
420 - old_eip = env->eip;  
421 - old_cs = env->segs[R_CS].selector;  
422 - esp -= 2;  
423 - stw(ssp + (esp & 0xffff), compute_eflags());  
424 - esp -= 2;  
425 - stw(ssp + (esp & 0xffff), old_cs);  
426 - esp -= 2;  
427 - stw(ssp + (esp & 0xffff), old_eip);  
428 -  
429 - /* update processor state */  
430 - ESP = (ESP & ~0xffff) | (esp & 0xffff);  
431 - env->eip = offset;  
432 - env->segs[R_CS].selector = selector;  
433 - env->segs[R_CS].base = (uint8_t *)(selector << 4);  
434 - env->eflags &= ~(IF_MASK | TF_MASK | AC_MASK | RF_MASK);  
435 -}  
436 -  
437 -/* fake user mode interrupt */  
438 -void do_interrupt_user(int intno, int is_int, int error_code,  
439 - unsigned int next_eip)  
440 -{  
441 - SegmentCache *dt;  
442 - uint8_t *ptr;  
443 - int dpl, cpl;  
444 - uint32_t e2;  
445 -  
446 - dt = &env->idt;  
447 - ptr = dt->base + (intno * 8);  
448 - e2 = ldl(ptr + 4);  
449 -  
450 - dpl = (e2 >> DESC_DPL_SHIFT) & 3;  
451 - cpl = env->hflags & HF_CPL_MASK;  
452 - /* check privledge if software int */  
453 - if (is_int && dpl < cpl)  
454 - raise_exception_err(EXCP0D_GPF, intno * 8 + 2);  
455 -  
456 - /* Since we emulate only user space, we cannot do more than  
457 - exiting the emulation with the suitable exception and error  
458 - code */  
459 - if (is_int)  
460 - EIP = next_eip;  
461 -}  
462 -  
463 -/*  
464 - * Begin excution of an interruption. is_int is TRUE if coming from  
465 - * the int instruction. next_eip is the EIP value AFTER the interrupt  
466 - * instruction. It is only relevant if is_int is TRUE.  
467 - */  
468 -void do_interrupt(int intno, int is_int, int error_code,  
469 - unsigned int next_eip, int is_hw)  
470 -{  
471 - if (env->cr[0] & CR0_PE_MASK) {  
472 - do_interrupt_protected(intno, is_int, error_code, next_eip, is_hw);  
473 - } else {  
474 - do_interrupt_real(intno, is_int, error_code, next_eip);  
475 - }  
476 -}  
477 -  
478 -/*  
479 - * Signal an interruption. It is executed in the main CPU loop.  
480 - * is_int is TRUE if coming from the int instruction. next_eip is the  
481 - * EIP value AFTER the interrupt instruction. It is only relevant if  
482 - * is_int is TRUE.  
483 - */  
484 -void raise_interrupt(int intno, int is_int, int error_code,  
485 - unsigned int next_eip)  
486 -{  
487 - env->exception_index = intno;  
488 - env->error_code = error_code;  
489 - env->exception_is_int = is_int;  
490 - env->exception_next_eip = next_eip;  
491 - cpu_loop_exit();  
492 -}  
493 -  
494 -/* shortcuts to generate exceptions */  
495 -void raise_exception_err(int exception_index, int error_code)  
496 -{  
497 - raise_interrupt(exception_index, 0, error_code, 0);  
498 -}  
499 -  
500 -void raise_exception(int exception_index)  
501 -{  
502 - raise_interrupt(exception_index, 0, 0, 0);  
503 -}  
504 -  
505 -#ifdef BUGGY_GCC_DIV64  
506 -/* gcc 2.95.4 on PowerPC does not seem to like using __udivdi3, so we  
507 - call it from another function */  
508 -uint32_t div64(uint32_t *q_ptr, uint64_t num, uint32_t den)  
509 -{  
510 - *q_ptr = num / den;  
511 - return num % den;  
512 -}  
513 -  
514 -int32_t idiv64(int32_t *q_ptr, int64_t num, int32_t den)  
515 -{  
516 - *q_ptr = num / den;  
517 - return num % den;  
518 -}  
519 -#endif  
520 -  
521 -void helper_divl_EAX_T0(uint32_t eip)  
522 -{  
523 - unsigned int den, q, r;  
524 - uint64_t num;  
525 -  
526 - num = EAX | ((uint64_t)EDX << 32);  
527 - den = T0;  
528 - if (den == 0) {  
529 - EIP = eip;  
530 - raise_exception(EXCP00_DIVZ);  
531 - }  
532 -#ifdef BUGGY_GCC_DIV64  
533 - r = div64(&q, num, den);  
534 -#else  
535 - q = (num / den);  
536 - r = (num % den);  
537 -#endif  
538 - EAX = q;  
539 - EDX = r;  
540 -}  
541 -  
542 -void helper_idivl_EAX_T0(uint32_t eip)  
543 -{  
544 - int den, q, r;  
545 - int64_t num;  
546 -  
547 - num = EAX | ((uint64_t)EDX << 32);  
548 - den = T0;  
549 - if (den == 0) {  
550 - EIP = eip;  
551 - raise_exception(EXCP00_DIVZ);  
552 - }  
553 -#ifdef BUGGY_GCC_DIV64  
554 - r = idiv64(&q, num, den);  
555 -#else  
556 - q = (num / den);  
557 - r = (num % den);  
558 -#endif  
559 - EAX = q;  
560 - EDX = r;  
561 -}  
562 -  
563 -void helper_cmpxchg8b(void)  
564 -{  
565 - uint64_t d;  
566 - int eflags;  
567 -  
568 - eflags = cc_table[CC_OP].compute_all();  
569 - d = ldq((uint8_t *)A0);  
570 - if (d == (((uint64_t)EDX << 32) | EAX)) {  
571 - stq((uint8_t *)A0, ((uint64_t)ECX << 32) | EBX);  
572 - eflags |= CC_Z;  
573 - } else {  
574 - EDX = d >> 32;  
575 - EAX = d;  
576 - eflags &= ~CC_Z;  
577 - }  
578 - CC_SRC = eflags;  
579 -}  
580 -  
581 -/* We simulate a pre-MMX pentium as in valgrind */  
582 -#define CPUID_FP87 (1 << 0)  
583 -#define CPUID_VME (1 << 1)  
584 -#define CPUID_DE (1 << 2)  
585 -#define CPUID_PSE (1 << 3)  
586 -#define CPUID_TSC (1 << 4)  
587 -#define CPUID_MSR (1 << 5)  
588 -#define CPUID_PAE (1 << 6)  
589 -#define CPUID_MCE (1 << 7)  
590 -#define CPUID_CX8 (1 << 8)  
591 -#define CPUID_APIC (1 << 9)  
592 -#define CPUID_SEP (1 << 11) /* sysenter/sysexit */  
593 -#define CPUID_MTRR (1 << 12)  
594 -#define CPUID_PGE (1 << 13)  
595 -#define CPUID_MCA (1 << 14)  
596 -#define CPUID_CMOV (1 << 15)  
597 -/* ... */  
598 -#define CPUID_MMX (1 << 23)  
599 -#define CPUID_FXSR (1 << 24)  
600 -#define CPUID_SSE (1 << 25)  
601 -#define CPUID_SSE2 (1 << 26)  
602 -  
603 -void helper_cpuid(void)  
604 -{  
605 - if (EAX == 0) {  
606 - EAX = 1; /* max EAX index supported */  
607 - EBX = 0x756e6547;  
608 - ECX = 0x6c65746e;  
609 - EDX = 0x49656e69;  
610 - } else if (EAX == 1) {  
611 - int family, model, stepping;  
612 - /* EAX = 1 info */  
613 -#if 0  
614 - /* pentium 75-200 */  
615 - family = 5;  
616 - model = 2;  
617 - stepping = 11;  
618 -#else  
619 - /* pentium pro */  
620 - family = 6;  
621 - model = 1;  
622 - stepping = 3;  
623 -#endif  
624 - EAX = (family << 8) | (model << 4) | stepping;  
625 - EBX = 0;  
626 - ECX = 0;  
627 - EDX = CPUID_FP87 | CPUID_DE | CPUID_PSE |  
628 - CPUID_TSC | CPUID_MSR | CPUID_MCE |  
629 - CPUID_CX8 | CPUID_PGE | CPUID_CMOV;  
630 - }  
631 -}  
632 -  
633 -void helper_lldt_T0(void)  
634 -{  
635 - int selector;  
636 - SegmentCache *dt;  
637 - uint32_t e1, e2;  
638 - int index;  
639 - uint8_t *ptr;  
640 -  
641 - selector = T0 & 0xffff;  
642 - if ((selector & 0xfffc) == 0) {  
643 - /* XXX: NULL selector case: invalid LDT */  
644 - env->ldt.base = NULL;  
645 - env->ldt.limit = 0;  
646 - } else {  
647 - if (selector & 0x4)  
648 - raise_exception_err(EXCP0D_GPF, selector & 0xfffc);  
649 - dt = &env->gdt;  
650 - index = selector & ~7;  
651 - if ((index + 7) > dt->limit)  
652 - raise_exception_err(EXCP0D_GPF, selector & 0xfffc);  
653 - ptr = dt->base + index;  
654 - e1 = ldl(ptr);  
655 - e2 = ldl(ptr + 4);  
656 - if ((e2 & DESC_S_MASK) || ((e2 >> DESC_TYPE_SHIFT) & 0xf) != 2)  
657 - raise_exception_err(EXCP0D_GPF, selector & 0xfffc);  
658 - if (!(e2 & DESC_P_MASK))  
659 - raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);  
660 - load_seg_cache_raw_dt(&env->ldt, e1, e2);  
661 - }  
662 - env->ldt.selector = selector;  
663 -}  
664 -  
665 -void helper_ltr_T0(void)  
666 -{  
667 - int selector;  
668 - SegmentCache *dt;  
669 - uint32_t e1, e2;  
670 - int index, type;  
671 - uint8_t *ptr;  
672 -  
673 - selector = T0 & 0xffff;  
674 - if ((selector & 0xfffc) == 0) {  
675 - /* NULL selector case: invalid LDT */  
676 - env->tr.base = NULL;  
677 - env->tr.limit = 0;  
678 - env->tr.flags = 0;  
679 - } else {  
680 - if (selector & 0x4)  
681 - raise_exception_err(EXCP0D_GPF, selector & 0xfffc);  
682 - dt = &env->gdt;  
683 - index = selector & ~7;  
684 - if ((index + 7) > dt->limit)  
685 - raise_exception_err(EXCP0D_GPF, selector & 0xfffc);  
686 - ptr = dt->base + index;  
687 - e1 = ldl(ptr);  
688 - e2 = ldl(ptr + 4);  
689 - type = (e2 >> DESC_TYPE_SHIFT) & 0xf;  
690 - if ((e2 & DESC_S_MASK) ||  
691 - (type != 2 && type != 9))  
692 - raise_exception_err(EXCP0D_GPF, selector & 0xfffc);  
693 - if (!(e2 & DESC_P_MASK))  
694 - raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);  
695 - load_seg_cache_raw_dt(&env->tr, e1, e2);  
696 - e2 |= 0x00000200; /* set the busy bit */  
697 - stl(ptr + 4, e2);  
698 - }  
699 - env->tr.selector = selector;  
700 -}  
701 -  
702 -/* only works if protected mode and not VM86. Calling load_seg with  
703 - seg_reg == R_CS is discouraged */  
704 -void load_seg(int seg_reg, int selector, unsigned int cur_eip)  
705 -{  
706 - uint32_t e1, e2;  
707 -  
708 - if ((selector & 0xfffc) == 0) {  
709 - /* null selector case */  
710 - if (seg_reg == R_SS) {  
711 - EIP = cur_eip;  
712 - raise_exception_err(EXCP0D_GPF, 0);  
713 - } else {  
714 - cpu_x86_load_seg_cache(env, seg_reg, selector, NULL, 0, 0);  
715 - }  
716 - } else {  
717 - if (load_segment(&e1, &e2, selector) != 0) {  
718 - EIP = cur_eip;  
719 - raise_exception_err(EXCP0D_GPF, selector & 0xfffc);  
720 - }  
721 - if (!(e2 & DESC_S_MASK) ||  
722 - (e2 & (DESC_CS_MASK | DESC_R_MASK)) == DESC_CS_MASK) {  
723 - EIP = cur_eip;  
724 - raise_exception_err(EXCP0D_GPF, selector & 0xfffc);  
725 - }  
726 -  
727 - if (seg_reg == R_SS) {  
728 - if ((e2 & (DESC_CS_MASK | DESC_W_MASK)) == 0) {  
729 - EIP = cur_eip;  
730 - raise_exception_err(EXCP0D_GPF, selector & 0xfffc);  
731 - }  
732 - } else {  
733 - if ((e2 & (DESC_CS_MASK | DESC_R_MASK)) == DESC_CS_MASK) {  
734 - EIP = cur_eip;  
735 - raise_exception_err(EXCP0D_GPF, selector & 0xfffc);  
736 - }  
737 - }  
738 -  
739 - if (!(e2 & DESC_P_MASK)) {  
740 - EIP = cur_eip;  
741 - if (seg_reg == R_SS)  
742 - raise_exception_err(EXCP0C_STACK, selector & 0xfffc);  
743 - else  
744 - raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);  
745 - }  
746 - cpu_x86_load_seg_cache(env, seg_reg, selector,  
747 - get_seg_base(e1, e2),  
748 - get_seg_limit(e1, e2),  
749 - e2);  
750 -#if 0  
751 - fprintf(logfile, "load_seg: sel=0x%04x base=0x%08lx limit=0x%08lx flags=%08x\n",  
752 - selector, (unsigned long)sc->base, sc->limit, sc->flags);  
753 -#endif  
754 - }  
755 -}  
756 -  
757 -/* protected mode jump */  
758 -void helper_ljmp_protected_T0_T1(void)  
759 -{  
760 - int new_cs, new_eip;  
761 - uint32_t e1, e2, cpl, dpl, rpl, limit;  
762 -  
763 - new_cs = T0;  
764 - new_eip = T1;  
765 - if ((new_cs & 0xfffc) == 0)  
766 - raise_exception_err(EXCP0D_GPF, 0);  
767 - if (load_segment(&e1, &e2, new_cs) != 0)  
768 - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);  
769 - cpl = env->hflags & HF_CPL_MASK;  
770 - if (e2 & DESC_S_MASK) {  
771 - if (!(e2 & DESC_CS_MASK))  
772 - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);  
773 - dpl = (e2 >> DESC_DPL_SHIFT) & 3;  
774 - if (e2 & DESC_CS_MASK) {  
775 - /* conforming code segment */  
776 - if (dpl > cpl)  
777 - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);  
778 - } else {  
779 - /* non conforming code segment */  
780 - rpl = new_cs & 3;  
781 - if (rpl > cpl)  
782 - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);  
783 - if (dpl != cpl)  
784 - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);  
785 - }  
786 - if (!(e2 & DESC_P_MASK))  
787 - raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc);  
788 - limit = get_seg_limit(e1, e2);  
789 - if (new_eip > limit)  
790 - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);  
791 - cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl,  
792 - get_seg_base(e1, e2), limit, e2);  
793 - EIP = new_eip;  
794 - } else {  
795 - cpu_abort(env, "jmp to call/task gate not supported 0x%04x:0x%08x",  
796 - new_cs, new_eip);  
797 - }  
798 -}  
799 -  
800 -/* real mode call */  
801 -void helper_lcall_real_T0_T1(int shift, int next_eip)  
802 -{  
803 - int new_cs, new_eip;  
804 - uint32_t esp, esp_mask;  
805 - uint8_t *ssp;  
806 -  
807 - new_cs = T0;  
808 - new_eip = T1;  
809 - esp = ESP;  
810 - esp_mask = 0xffffffff;  
811 - if (!(env->segs[R_SS].flags & DESC_B_MASK))  
812 - esp_mask = 0xffff;  
813 - ssp = env->segs[R_SS].base;  
814 - if (shift) {  
815 - esp -= 4;  
816 - stl(ssp + (esp & esp_mask), env->segs[R_CS].selector);  
817 - esp -= 4;  
818 - stl(ssp + (esp & esp_mask), next_eip);  
819 - } else {  
820 - esp -= 2;  
821 - stw(ssp + (esp & esp_mask), env->segs[R_CS].selector);  
822 - esp -= 2;  
823 - stw(ssp + (esp & esp_mask), next_eip);  
824 - }  
825 -  
826 - if (!(env->segs[R_SS].flags & DESC_B_MASK))  
827 - ESP = (ESP & ~0xffff) | (esp & 0xffff);  
828 - else  
829 - ESP = esp;  
830 - env->eip = new_eip;  
831 - env->segs[R_CS].selector = new_cs;  
832 - env->segs[R_CS].base = (uint8_t *)(new_cs << 4);  
833 -}  
834 -  
835 -/* protected mode call */  
836 -void helper_lcall_protected_T0_T1(int shift, int next_eip)  
837 -{  
838 - int new_cs, new_eip;  
839 - uint32_t e1, e2, cpl, dpl, rpl, selector, offset, param_count;  
840 - uint32_t ss, ss_e1, ss_e2, push_size, sp, type, ss_dpl;  
841 - uint32_t old_ss, old_esp, val, i, limit;  
842 - uint8_t *ssp, *old_ssp;  
843 -  
844 - new_cs = T0;  
845 - new_eip = T1;  
846 - if ((new_cs & 0xfffc) == 0)  
847 - raise_exception_err(EXCP0D_GPF, 0);  
848 - if (load_segment(&e1, &e2, new_cs) != 0)  
849 - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);  
850 - cpl = env->hflags & HF_CPL_MASK;  
851 - if (e2 & DESC_S_MASK) {  
852 - if (!(e2 & DESC_CS_MASK))  
853 - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);  
854 - dpl = (e2 >> DESC_DPL_SHIFT) & 3;  
855 - if (e2 & DESC_CS_MASK) {  
856 - /* conforming code segment */  
857 - if (dpl > cpl)  
858 - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);  
859 - } else {  
860 - /* non conforming code segment */  
861 - rpl = new_cs & 3;  
862 - if (rpl > cpl)  
863 - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);  
864 - if (dpl != cpl)  
865 - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);  
866 - }  
867 - if (!(e2 & DESC_P_MASK))  
868 - raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc);  
869 -  
870 - sp = ESP;  
871 - if (!(env->segs[R_SS].flags & DESC_B_MASK))  
872 - sp &= 0xffff;  
873 - ssp = env->segs[R_SS].base + sp;  
874 - if (shift) {  
875 - ssp -= 4;  
876 - stl(ssp, env->segs[R_CS].selector);  
877 - ssp -= 4;  
878 - stl(ssp, next_eip);  
879 - } else {  
880 - ssp -= 2;  
881 - stw(ssp, env->segs[R_CS].selector);  
882 - ssp -= 2;  
883 - stw(ssp, next_eip);  
884 - }  
885 - sp -= (4 << shift);  
886 -  
887 - limit = get_seg_limit(e1, e2);  
888 - if (new_eip > limit)  
889 - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);  
890 - /* from this point, not restartable */  
891 - if (!(env->segs[R_SS].flags & DESC_B_MASK))  
892 - ESP = (ESP & 0xffff0000) | (sp & 0xffff);  
893 - else  
894 - ESP = sp;  
895 - cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl,  
896 - get_seg_base(e1, e2), limit, e2);  
897 - EIP = new_eip;  
898 - } else {  
899 - /* check gate type */  
900 - type = (e2 >> DESC_TYPE_SHIFT) & 0x1f;  
901 - switch(type) {  
902 - case 1: /* available 286 TSS */  
903 - case 9: /* available 386 TSS */  
904 - case 5: /* task gate */  
905 - cpu_abort(env, "task gate not supported");  
906 - break;  
907 - case 4: /* 286 call gate */  
908 - case 12: /* 386 call gate */  
909 - break;  
910 - default:  
911 - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);  
912 - break;  
913 - }  
914 - shift = type >> 3;  
915 -  
916 - dpl = (e2 >> DESC_DPL_SHIFT) & 3;  
917 - rpl = new_cs & 3;  
918 - if (dpl < cpl || dpl < rpl)  
919 - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);  
920 - /* check valid bit */  
921 - if (!(e2 & DESC_P_MASK))  
922 - raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc);  
923 - selector = e1 >> 16;  
924 - offset = (e2 & 0xffff0000) | (e1 & 0x0000ffff);  
925 - if ((selector & 0xfffc) == 0)  
926 - raise_exception_err(EXCP0D_GPF, 0);  
927 -  
928 - if (load_segment(&e1, &e2, selector) != 0)  
929 - raise_exception_err(EXCP0D_GPF, selector & 0xfffc);  
930 - if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK)))  
931 - raise_exception_err(EXCP0D_GPF, selector & 0xfffc);  
932 - dpl = (e2 >> DESC_DPL_SHIFT) & 3;  
933 - if (dpl > cpl)  
934 - raise_exception_err(EXCP0D_GPF, selector & 0xfffc);  
935 - if (!(e2 & DESC_P_MASK))  
936 - raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);  
937 -  
938 - if (!(e2 & DESC_C_MASK) && dpl < cpl) {  
939 - /* to inner priviledge */  
940 - get_ss_esp_from_tss(&ss, &sp, dpl);  
941 - if ((ss & 0xfffc) == 0)  
942 - raise_exception_err(EXCP0A_TSS, ss & 0xfffc);  
943 - if ((ss & 3) != dpl)  
944 - raise_exception_err(EXCP0A_TSS, ss & 0xfffc);  
945 - if (load_segment(&ss_e1, &ss_e2, ss) != 0)  
946 - raise_exception_err(EXCP0A_TSS, ss & 0xfffc);  
947 - ss_dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3;  
948 - if (ss_dpl != dpl)  
949 - raise_exception_err(EXCP0A_TSS, ss & 0xfffc);  
950 - if (!(ss_e2 & DESC_S_MASK) ||  
951 - (ss_e2 & DESC_CS_MASK) ||  
952 - !(ss_e2 & DESC_W_MASK))  
953 - raise_exception_err(EXCP0A_TSS, ss & 0xfffc);  
954 - if (!(ss_e2 & DESC_P_MASK))  
955 - raise_exception_err(EXCP0A_TSS, ss & 0xfffc);  
956 -  
957 - param_count = e2 & 0x1f;  
958 - push_size = ((param_count * 2) + 8) << shift;  
959 -  
960 - old_esp = ESP;  
961 - old_ss = env->segs[R_SS].selector;  
962 - if (!(env->segs[R_SS].flags & DESC_B_MASK))  
963 - old_esp &= 0xffff;  
964 - old_ssp = env->segs[R_SS].base + old_esp;  
965 -  
966 - /* XXX: from this point not restartable */  
967 - ss = (ss & ~3) | dpl;  
968 - cpu_x86_load_seg_cache(env, R_SS, ss,  
969 - get_seg_base(ss_e1, ss_e2),  
970 - get_seg_limit(ss_e1, ss_e2),  
971 - ss_e2);  
972 -  
973 - if (!(env->segs[R_SS].flags & DESC_B_MASK))  
974 - sp &= 0xffff;  
975 - ssp = env->segs[R_SS].base + sp;  
976 - if (shift) {  
977 - ssp -= 4;  
978 - stl(ssp, old_ss);  
979 - ssp -= 4;  
980 - stl(ssp, old_esp);  
981 - ssp -= 4 * param_count;  
982 - for(i = 0; i < param_count; i++) {  
983 - val = ldl(old_ssp + i * 4);  
984 - stl(ssp + i * 4, val);  
985 - }  
986 - } else {  
987 - ssp -= 2;  
988 - stw(ssp, old_ss);  
989 - ssp -= 2;  
990 - stw(ssp, old_esp);  
991 - ssp -= 2 * param_count;  
992 - for(i = 0; i < param_count; i++) {  
993 - val = lduw(old_ssp + i * 2);  
994 - stw(ssp + i * 2, val);  
995 - }  
996 - }  
997 - } else {  
998 - /* to same priviledge */  
999 - if (!(env->segs[R_SS].flags & DESC_B_MASK))  
1000 - sp &= 0xffff;  
1001 - ssp = env->segs[R_SS].base + sp;  
1002 - push_size = (4 << shift);  
1003 - }  
1004 -  
1005 - if (shift) {  
1006 - ssp -= 4;  
1007 - stl(ssp, env->segs[R_CS].selector);  
1008 - ssp -= 4;  
1009 - stl(ssp, next_eip);  
1010 - } else {  
1011 - ssp -= 2;  
1012 - stw(ssp, env->segs[R_CS].selector);  
1013 - ssp -= 2;  
1014 - stw(ssp, next_eip);  
1015 - }  
1016 -  
1017 - sp -= push_size;  
1018 - selector = (selector & ~3) | dpl;  
1019 - cpu_x86_load_seg_cache(env, R_CS, selector,  
1020 - get_seg_base(e1, e2),  
1021 - get_seg_limit(e1, e2),  
1022 - e2);  
1023 - cpu_x86_set_cpl(env, dpl);  
1024 -  
1025 - /* from this point, not restartable if same priviledge */  
1026 - if (!(env->segs[R_SS].flags & DESC_B_MASK))  
1027 - ESP = (ESP & 0xffff0000) | (sp & 0xffff);  
1028 - else  
1029 - ESP = sp;  
1030 - EIP = offset;  
1031 - }  
1032 -}  
1033 -  
1034 -/* real mode iret */  
1035 -void helper_iret_real(int shift)  
1036 -{  
1037 - uint32_t sp, new_cs, new_eip, new_eflags, new_esp;  
1038 - uint8_t *ssp;  
1039 - int eflags_mask;  
1040 -  
1041 - sp = ESP & 0xffff;  
1042 - ssp = env->segs[R_SS].base + sp;  
1043 - if (shift == 1) {  
1044 - /* 32 bits */  
1045 - new_eflags = ldl(ssp + 8);  
1046 - new_cs = ldl(ssp + 4) & 0xffff;  
1047 - new_eip = ldl(ssp) & 0xffff;  
1048 - } else {  
1049 - /* 16 bits */  
1050 - new_eflags = lduw(ssp + 4);  
1051 - new_cs = lduw(ssp + 2);  
1052 - new_eip = lduw(ssp);  
1053 - }  
1054 - new_esp = sp + (6 << shift);  
1055 - ESP = (ESP & 0xffff0000) |  
1056 - (new_esp & 0xffff);  
1057 - load_seg_vm(R_CS, new_cs);  
1058 - env->eip = new_eip;  
1059 - eflags_mask = FL_UPDATE_CPL0_MASK;  
1060 - if (shift == 0)  
1061 - eflags_mask &= 0xffff;  
1062 - load_eflags(new_eflags, eflags_mask);  
1063 -}  
1064 -  
1065 -/* protected mode iret */  
1066 -static inline void helper_ret_protected(int shift, int is_iret, int addend)  
1067 -{  
1068 - uint32_t sp, new_cs, new_eip, new_eflags, new_esp, new_ss;  
1069 - uint32_t new_es, new_ds, new_fs, new_gs;  
1070 - uint32_t e1, e2, ss_e1, ss_e2;  
1071 - int cpl, dpl, rpl, eflags_mask;  
1072 - uint8_t *ssp;  
1073 -  
1074 - sp = ESP;  
1075 - if (!(env->segs[R_SS].flags & DESC_B_MASK))  
1076 - sp &= 0xffff;  
1077 - ssp = env->segs[R_SS].base + sp;  
1078 - if (shift == 1) {  
1079 - /* 32 bits */  
1080 - if (is_iret)  
1081 - new_eflags = ldl(ssp + 8);  
1082 - new_cs = ldl(ssp + 4) & 0xffff;  
1083 - new_eip = ldl(ssp);  
1084 - if (is_iret && (new_eflags & VM_MASK))  
1085 - goto return_to_vm86;  
1086 - } else {  
1087 - /* 16 bits */  
1088 - if (is_iret)  
1089 - new_eflags = lduw(ssp + 4);  
1090 - new_cs = lduw(ssp + 2);  
1091 - new_eip = lduw(ssp);  
1092 - }  
1093 - if ((new_cs & 0xfffc) == 0)  
1094 - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);  
1095 - if (load_segment(&e1, &e2, new_cs) != 0)  
1096 - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);  
1097 - if (!(e2 & DESC_S_MASK) ||  
1098 - !(e2 & DESC_CS_MASK))  
1099 - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);  
1100 - cpl = env->hflags & HF_CPL_MASK;  
1101 - rpl = new_cs & 3;  
1102 - if (rpl < cpl)  
1103 - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);  
1104 - dpl = (e2 >> DESC_DPL_SHIFT) & 3;  
1105 - if (e2 & DESC_CS_MASK) {  
1106 - if (dpl > rpl)  
1107 - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);  
1108 - } else {  
1109 - if (dpl != rpl)  
1110 - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);  
1111 - }  
1112 - if (!(e2 & DESC_P_MASK))  
1113 - raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc);  
1114 -  
1115 - if (rpl == cpl) {  
1116 - /* return to same priledge level */  
1117 - cpu_x86_load_seg_cache(env, R_CS, new_cs,  
1118 - get_seg_base(e1, e2),  
1119 - get_seg_limit(e1, e2),  
1120 - e2);  
1121 - new_esp = sp + (4 << shift) + ((2 * is_iret) << shift) + addend;  
1122 - } else {  
1123 - /* return to different priviledge level */  
1124 - ssp += (4 << shift) + ((2 * is_iret) << shift) + addend;  
1125 - if (shift == 1) {  
1126 - /* 32 bits */  
1127 - new_esp = ldl(ssp);  
1128 - new_ss = ldl(ssp + 4) & 0xffff;  
1129 - } else {  
1130 - /* 16 bits */  
1131 - new_esp = lduw(ssp);  
1132 - new_ss = lduw(ssp + 2);  
1133 - }  
1134 -  
1135 - if ((new_ss & 3) != rpl)  
1136 - raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);  
1137 - if (load_segment(&ss_e1, &ss_e2, new_ss) != 0)  
1138 - raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);  
1139 - if (!(ss_e2 & DESC_S_MASK) ||  
1140 - (ss_e2 & DESC_CS_MASK) ||  
1141 - !(ss_e2 & DESC_W_MASK))  
1142 - raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);  
1143 - dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3;  
1144 - if (dpl != rpl)  
1145 - raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);  
1146 - if (!(ss_e2 & DESC_P_MASK))  
1147 - raise_exception_err(EXCP0B_NOSEG, new_ss & 0xfffc);  
1148 -  
1149 - cpu_x86_load_seg_cache(env, R_CS, new_cs,  
1150 - get_seg_base(e1, e2),  
1151 - get_seg_limit(e1, e2),  
1152 - e2);  
1153 - cpu_x86_load_seg_cache(env, R_SS, new_ss,  
1154 - get_seg_base(ss_e1, ss_e2),  
1155 - get_seg_limit(ss_e1, ss_e2),  
1156 - ss_e2);  
1157 - cpu_x86_set_cpl(env, rpl);  
1158 - }  
1159 - if (env->segs[R_SS].flags & DESC_B_MASK)  
1160 - ESP = new_esp;  
1161 - else  
1162 - ESP = (ESP & 0xffff0000) |  
1163 - (new_esp & 0xffff);  
1164 - env->eip = new_eip;  
1165 - if (is_iret) {  
1166 - /* NOTE: 'cpl' can be different from the current CPL */  
1167 - if (cpl == 0)  
1168 - eflags_mask = FL_UPDATE_CPL0_MASK;  
1169 - else  
1170 - eflags_mask = FL_UPDATE_MASK32;  
1171 - if (shift == 0)  
1172 - eflags_mask &= 0xffff;  
1173 - load_eflags(new_eflags, eflags_mask);  
1174 - }  
1175 - return;  
1176 -  
1177 - return_to_vm86:  
1178 - new_esp = ldl(ssp + 12);  
1179 - new_ss = ldl(ssp + 16);  
1180 - new_es = ldl(ssp + 20);  
1181 - new_ds = ldl(ssp + 24);  
1182 - new_fs = ldl(ssp + 28);  
1183 - new_gs = ldl(ssp + 32);  
1184 -  
1185 - /* modify processor state */  
1186 - load_eflags(new_eflags, FL_UPDATE_CPL0_MASK | VM_MASK | VIF_MASK | VIP_MASK);  
1187 - load_seg_vm(R_CS, new_cs);  
1188 - cpu_x86_set_cpl(env, 3);  
1189 - load_seg_vm(R_SS, new_ss);  
1190 - load_seg_vm(R_ES, new_es);  
1191 - load_seg_vm(R_DS, new_ds);  
1192 - load_seg_vm(R_FS, new_fs);  
1193 - load_seg_vm(R_GS, new_gs);  
1194 -  
1195 - env->eip = new_eip;  
1196 - ESP = new_esp;  
1197 -}  
1198 -  
1199 -void helper_iret_protected(int shift)  
1200 -{  
1201 - helper_ret_protected(shift, 1, 0);  
1202 -}  
1203 -  
1204 -void helper_lret_protected(int shift, int addend)  
1205 -{  
1206 - helper_ret_protected(shift, 0, addend);  
1207 -}  
1208 -  
1209 -void helper_movl_crN_T0(int reg)  
1210 -{  
1211 - env->cr[reg] = T0;  
1212 - switch(reg) {  
1213 - case 0:  
1214 - cpu_x86_update_cr0(env);  
1215 - break;  
1216 - case 3:  
1217 - cpu_x86_update_cr3(env);  
1218 - break;  
1219 - }  
1220 -}  
1221 -  
1222 -/* XXX: do more */  
1223 -void helper_movl_drN_T0(int reg)  
1224 -{  
1225 - env->dr[reg] = T0;  
1226 -}  
1227 -  
1228 -void helper_invlpg(unsigned int addr)  
1229 -{  
1230 - cpu_x86_flush_tlb(env, addr);  
1231 -}  
1232 -  
1233 -/* rdtsc */  
1234 -#ifndef __i386__  
1235 -uint64_t emu_time;  
1236 -#endif  
1237 -  
1238 -void helper_rdtsc(void)  
1239 -{  
1240 - uint64_t val;  
1241 -#ifdef __i386__  
1242 - asm("rdtsc" : "=A" (val));  
1243 -#else  
1244 - /* better than nothing: the time increases */  
1245 - val = emu_time++;  
1246 -#endif  
1247 - EAX = val;  
1248 - EDX = val >> 32;  
1249 -}  
1250 -  
1251 -void helper_wrmsr(void)  
1252 -{  
1253 - switch(ECX) {  
1254 - case MSR_IA32_SYSENTER_CS:  
1255 - env->sysenter_cs = EAX & 0xffff;  
1256 - break;  
1257 - case MSR_IA32_SYSENTER_ESP:  
1258 - env->sysenter_esp = EAX;  
1259 - break;  
1260 - case MSR_IA32_SYSENTER_EIP:  
1261 - env->sysenter_eip = EAX;  
1262 - break;  
1263 - default:  
1264 - /* XXX: exception ? */  
1265 - break;  
1266 - }  
1267 -}  
1268 -  
1269 -void helper_rdmsr(void)  
1270 -{  
1271 - switch(ECX) {  
1272 - case MSR_IA32_SYSENTER_CS:  
1273 - EAX = env->sysenter_cs;  
1274 - EDX = 0;  
1275 - break;  
1276 - case MSR_IA32_SYSENTER_ESP:  
1277 - EAX = env->sysenter_esp;  
1278 - EDX = 0;  
1279 - break;  
1280 - case MSR_IA32_SYSENTER_EIP:  
1281 - EAX = env->sysenter_eip;  
1282 - EDX = 0;  
1283 - break;  
1284 - default:  
1285 - /* XXX: exception ? */  
1286 - break;  
1287 - }  
1288 -}  
1289 -  
1290 -void helper_lsl(void)  
1291 -{  
1292 - unsigned int selector, limit;  
1293 - uint32_t e1, e2;  
1294 -  
1295 - CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z;  
1296 - selector = T0 & 0xffff;  
1297 - if (load_segment(&e1, &e2, selector) != 0)  
1298 - return;  
1299 - limit = (e1 & 0xffff) | (e2 & 0x000f0000);  
1300 - if (e2 & (1 << 23))  
1301 - limit = (limit << 12) | 0xfff;  
1302 - T1 = limit;  
1303 - CC_SRC |= CC_Z;  
1304 -}  
1305 -  
1306 -void helper_lar(void)  
1307 -{  
1308 - unsigned int selector;  
1309 - uint32_t e1, e2;  
1310 -  
1311 - CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z;  
1312 - selector = T0 & 0xffff;  
1313 - if (load_segment(&e1, &e2, selector) != 0)  
1314 - return;  
1315 - T1 = e2 & 0x00f0ff00;  
1316 - CC_SRC |= CC_Z;  
1317 -}  
1318 -  
1319 -/* FPU helpers */  
1320 -  
1321 -#ifndef USE_X86LDOUBLE  
1322 -void helper_fldt_ST0_A0(void)  
1323 -{  
1324 - int new_fpstt;  
1325 - new_fpstt = (env->fpstt - 1) & 7;  
1326 - env->fpregs[new_fpstt] = helper_fldt((uint8_t *)A0);  
1327 - env->fpstt = new_fpstt;  
1328 - env->fptags[new_fpstt] = 0; /* validate stack entry */  
1329 -}  
1330 -  
1331 -void helper_fstt_ST0_A0(void)  
1332 -{  
1333 - helper_fstt(ST0, (uint8_t *)A0);  
1334 -}  
1335 -#endif  
1336 -  
1337 -/* BCD ops */  
1338 -  
1339 -#define MUL10(iv) ( iv + iv + (iv << 3) )  
1340 -  
1341 -void helper_fbld_ST0_A0(void)  
1342 -{  
1343 - CPU86_LDouble tmp;  
1344 - uint64_t val;  
1345 - unsigned int v;  
1346 - int i;  
1347 -  
1348 - val = 0;  
1349 - for(i = 8; i >= 0; i--) {  
1350 - v = ldub((uint8_t *)A0 + i);  
1351 - val = (val * 100) + ((v >> 4) * 10) + (v & 0xf);  
1352 - }  
1353 - tmp = val;  
1354 - if (ldub((uint8_t *)A0 + 9) & 0x80)  
1355 - tmp = -tmp;  
1356 - fpush();  
1357 - ST0 = tmp;  
1358 -}  
1359 -  
1360 -void helper_fbst_ST0_A0(void)  
1361 -{  
1362 - CPU86_LDouble tmp;  
1363 - int v;  
1364 - uint8_t *mem_ref, *mem_end;  
1365 - int64_t val;  
1366 -  
1367 - tmp = rint(ST0);  
1368 - val = (int64_t)tmp;  
1369 - mem_ref = (uint8_t *)A0;  
1370 - mem_end = mem_ref + 9;  
1371 - if (val < 0) {  
1372 - stb(mem_end, 0x80);  
1373 - val = -val;  
1374 - } else {  
1375 - stb(mem_end, 0x00);  
1376 - }  
1377 - while (mem_ref < mem_end) {  
1378 - if (val == 0)  
1379 - break;  
1380 - v = val % 100;  
1381 - val = val / 100;  
1382 - v = ((v / 10) << 4) | (v % 10);  
1383 - stb(mem_ref++, v);  
1384 - }  
1385 - while (mem_ref < mem_end) {  
1386 - stb(mem_ref++, 0);  
1387 - }  
1388 -}  
1389 -  
1390 -void helper_f2xm1(void)  
1391 -{  
1392 - ST0 = pow(2.0,ST0) - 1.0;  
1393 -}  
1394 -  
1395 -void helper_fyl2x(void)  
1396 -{  
1397 - CPU86_LDouble fptemp;  
1398 -  
1399 - fptemp = ST0;  
1400 - if (fptemp>0.0){  
1401 - fptemp = log(fptemp)/log(2.0); /* log2(ST) */  
1402 - ST1 *= fptemp;  
1403 - fpop();  
1404 - } else {  
1405 - env->fpus &= (~0x4700);  
1406 - env->fpus |= 0x400;  
1407 - }  
1408 -}  
1409 -  
1410 -void helper_fptan(void)  
1411 -{  
1412 - CPU86_LDouble fptemp;  
1413 -  
1414 - fptemp = ST0;  
1415 - if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {  
1416 - env->fpus |= 0x400;  
1417 - } else {  
1418 - ST0 = tan(fptemp);  
1419 - fpush();  
1420 - ST0 = 1.0;  
1421 - env->fpus &= (~0x400); /* C2 <-- 0 */  
1422 - /* the above code is for |arg| < 2**52 only */  
1423 - }  
1424 -}  
1425 -  
1426 -void helper_fpatan(void)  
1427 -{  
1428 - CPU86_LDouble fptemp, fpsrcop;  
1429 -  
1430 - fpsrcop = ST1;  
1431 - fptemp = ST0;  
1432 - ST1 = atan2(fpsrcop,fptemp);  
1433 - fpop();  
1434 -}  
1435 -  
1436 -void helper_fxtract(void)  
1437 -{  
1438 - CPU86_LDoubleU temp;  
1439 - unsigned int expdif;  
1440 -  
1441 - temp.d = ST0;  
1442 - expdif = EXPD(temp) - EXPBIAS;  
1443 - /*DP exponent bias*/  
1444 - ST0 = expdif;  
1445 - fpush();  
1446 - BIASEXPONENT(temp);  
1447 - ST0 = temp.d;  
1448 -}  
1449 -  
1450 -void helper_fprem1(void)  
1451 -{  
1452 - CPU86_LDouble dblq, fpsrcop, fptemp;  
1453 - CPU86_LDoubleU fpsrcop1, fptemp1;  
1454 - int expdif;  
1455 - int q;  
1456 -  
1457 - fpsrcop = ST0;  
1458 - fptemp = ST1;  
1459 - fpsrcop1.d = fpsrcop;  
1460 - fptemp1.d = fptemp;  
1461 - expdif = EXPD(fpsrcop1) - EXPD(fptemp1);  
1462 - if (expdif < 53) {  
1463 - dblq = fpsrcop / fptemp;  
1464 - dblq = (dblq < 0.0)? ceil(dblq): floor(dblq);  
1465 - ST0 = fpsrcop - fptemp*dblq;  
1466 - q = (int)dblq; /* cutting off top bits is assumed here */  
1467 - env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */  
1468 - /* (C0,C1,C3) <-- (q2,q1,q0) */  
1469 - env->fpus |= (q&0x4) << 6; /* (C0) <-- q2 */  
1470 - env->fpus |= (q&0x2) << 8; /* (C1) <-- q1 */  
1471 - env->fpus |= (q&0x1) << 14; /* (C3) <-- q0 */  
1472 - } else {  
1473 - env->fpus |= 0x400; /* C2 <-- 1 */  
1474 - fptemp = pow(2.0, expdif-50);  
1475 - fpsrcop = (ST0 / ST1) / fptemp;  
1476 - /* fpsrcop = integer obtained by rounding to the nearest */  
1477 - fpsrcop = (fpsrcop-floor(fpsrcop) < ceil(fpsrcop)-fpsrcop)?  
1478 - floor(fpsrcop): ceil(fpsrcop);  
1479 - ST0 -= (ST1 * fpsrcop * fptemp);  
1480 - }  
1481 -}  
1482 -  
1483 -void helper_fprem(void)  
1484 -{  
1485 - CPU86_LDouble dblq, fpsrcop, fptemp;  
1486 - CPU86_LDoubleU fpsrcop1, fptemp1;  
1487 - int expdif;  
1488 - int q;  
1489 -  
1490 - fpsrcop = ST0;  
1491 - fptemp = ST1;  
1492 - fpsrcop1.d = fpsrcop;  
1493 - fptemp1.d = fptemp;  
1494 - expdif = EXPD(fpsrcop1) - EXPD(fptemp1);  
1495 - if ( expdif < 53 ) {  
1496 - dblq = fpsrcop / fptemp;  
1497 - dblq = (dblq < 0.0)? ceil(dblq): floor(dblq);  
1498 - ST0 = fpsrcop - fptemp*dblq;  
1499 - q = (int)dblq; /* cutting off top bits is assumed here */  
1500 - env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */  
1501 - /* (C0,C1,C3) <-- (q2,q1,q0) */  
1502 - env->fpus |= (q&0x4) << 6; /* (C0) <-- q2 */  
1503 - env->fpus |= (q&0x2) << 8; /* (C1) <-- q1 */  
1504 - env->fpus |= (q&0x1) << 14; /* (C3) <-- q0 */  
1505 - } else {  
1506 - env->fpus |= 0x400; /* C2 <-- 1 */  
1507 - fptemp = pow(2.0, expdif-50);  
1508 - fpsrcop = (ST0 / ST1) / fptemp;  
1509 - /* fpsrcop = integer obtained by chopping */  
1510 - fpsrcop = (fpsrcop < 0.0)?  
1511 - -(floor(fabs(fpsrcop))): floor(fpsrcop);  
1512 - ST0 -= (ST1 * fpsrcop * fptemp);  
1513 - }  
1514 -}  
1515 -  
1516 -void helper_fyl2xp1(void)  
1517 -{  
1518 - CPU86_LDouble fptemp;  
1519 -  
1520 - fptemp = ST0;  
1521 - if ((fptemp+1.0)>0.0) {  
1522 - fptemp = log(fptemp+1.0) / log(2.0); /* log2(ST+1.0) */  
1523 - ST1 *= fptemp;  
1524 - fpop();  
1525 - } else {  
1526 - env->fpus &= (~0x4700);  
1527 - env->fpus |= 0x400;  
1528 - }  
1529 -}  
1530 -  
1531 -void helper_fsqrt(void)  
1532 -{  
1533 - CPU86_LDouble fptemp;  
1534 -  
1535 - fptemp = ST0;  
1536 - if (fptemp<0.0) {  
1537 - env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */  
1538 - env->fpus |= 0x400;  
1539 - }  
1540 - ST0 = sqrt(fptemp);  
1541 -}  
1542 -  
1543 -void helper_fsincos(void)  
1544 -{  
1545 - CPU86_LDouble fptemp;  
1546 -  
1547 - fptemp = ST0;  
1548 - if ((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {  
1549 - env->fpus |= 0x400;  
1550 - } else {  
1551 - ST0 = sin(fptemp);  
1552 - fpush();  
1553 - ST0 = cos(fptemp);  
1554 - env->fpus &= (~0x400); /* C2 <-- 0 */  
1555 - /* the above code is for |arg| < 2**63 only */  
1556 - }  
1557 -}  
1558 -  
1559 -void helper_frndint(void)  
1560 -{  
1561 - CPU86_LDouble a;  
1562 -  
1563 - a = ST0;  
1564 -#ifdef __arm__  
1565 - switch(env->fpuc & RC_MASK) {  
1566 - default:  
1567 - case RC_NEAR:  
1568 - asm("rndd %0, %1" : "=f" (a) : "f"(a));  
1569 - break;  
1570 - case RC_DOWN:  
1571 - asm("rnddm %0, %1" : "=f" (a) : "f"(a));  
1572 - break;  
1573 - case RC_UP:  
1574 - asm("rnddp %0, %1" : "=f" (a) : "f"(a));  
1575 - break;  
1576 - case RC_CHOP:  
1577 - asm("rnddz %0, %1" : "=f" (a) : "f"(a));  
1578 - break;  
1579 - }  
1580 -#else  
1581 - a = rint(a);  
1582 -#endif  
1583 - ST0 = a;  
1584 -}  
1585 -  
1586 -void helper_fscale(void)  
1587 -{  
1588 - CPU86_LDouble fpsrcop, fptemp;  
1589 -  
1590 - fpsrcop = 2.0;  
1591 - fptemp = pow(fpsrcop,ST1);  
1592 - ST0 *= fptemp;  
1593 -}  
1594 -  
1595 -void helper_fsin(void)  
1596 -{  
1597 - CPU86_LDouble fptemp;  
1598 -  
1599 - fptemp = ST0;  
1600 - if ((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {  
1601 - env->fpus |= 0x400;  
1602 - } else {  
1603 - ST0 = sin(fptemp);  
1604 - env->fpus &= (~0x400); /* C2 <-- 0 */  
1605 - /* the above code is for |arg| < 2**53 only */  
1606 - }  
1607 -}  
1608 -  
1609 -void helper_fcos(void)  
1610 -{  
1611 - CPU86_LDouble fptemp;  
1612 -  
1613 - fptemp = ST0;  
1614 - if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {  
1615 - env->fpus |= 0x400;  
1616 - } else {  
1617 - ST0 = cos(fptemp);  
1618 - env->fpus &= (~0x400); /* C2 <-- 0 */  
1619 - /* the above code is for |arg5 < 2**63 only */  
1620 - }  
1621 -}  
1622 -  
1623 -void helper_fxam_ST0(void)  
1624 -{  
1625 - CPU86_LDoubleU temp;  
1626 - int expdif;  
1627 -  
1628 - temp.d = ST0;  
1629 -  
1630 - env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */  
1631 - if (SIGND(temp))  
1632 - env->fpus |= 0x200; /* C1 <-- 1 */  
1633 -  
1634 - expdif = EXPD(temp);  
1635 - if (expdif == MAXEXPD) {  
1636 - if (MANTD(temp) == 0)  
1637 - env->fpus |= 0x500 /*Infinity*/;  
1638 - else  
1639 - env->fpus |= 0x100 /*NaN*/;  
1640 - } else if (expdif == 0) {  
1641 - if (MANTD(temp) == 0)  
1642 - env->fpus |= 0x4000 /*Zero*/;  
1643 - else  
1644 - env->fpus |= 0x4400 /*Denormal*/;  
1645 - } else {  
1646 - env->fpus |= 0x400;  
1647 - }  
1648 -}  
1649 -  
1650 -void helper_fstenv(uint8_t *ptr, int data32)  
1651 -{  
1652 - int fpus, fptag, exp, i;  
1653 - uint64_t mant;  
1654 - CPU86_LDoubleU tmp;  
1655 -  
1656 - fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;  
1657 - fptag = 0;  
1658 - for (i=7; i>=0; i--) {  
1659 - fptag <<= 2;  
1660 - if (env->fptags[i]) {  
1661 - fptag |= 3;  
1662 - } else {  
1663 - tmp.d = env->fpregs[i];  
1664 - exp = EXPD(tmp);  
1665 - mant = MANTD(tmp);  
1666 - if (exp == 0 && mant == 0) {  
1667 - /* zero */  
1668 - fptag |= 1;  
1669 - } else if (exp == 0 || exp == MAXEXPD  
1670 -#ifdef USE_X86LDOUBLE  
1671 - || (mant & (1LL << 63)) == 0  
1672 -#endif  
1673 - ) {  
1674 - /* NaNs, infinity, denormal */  
1675 - fptag |= 2;  
1676 - }  
1677 - }  
1678 - }  
1679 - if (data32) {  
1680 - /* 32 bit */  
1681 - stl(ptr, env->fpuc);  
1682 - stl(ptr + 4, fpus);  
1683 - stl(ptr + 8, fptag);  
1684 - stl(ptr + 12, 0);  
1685 - stl(ptr + 16, 0);  
1686 - stl(ptr + 20, 0);  
1687 - stl(ptr + 24, 0);  
1688 - } else {  
1689 - /* 16 bit */  
1690 - stw(ptr, env->fpuc);  
1691 - stw(ptr + 2, fpus);  
1692 - stw(ptr + 4, fptag);  
1693 - stw(ptr + 6, 0);  
1694 - stw(ptr + 8, 0);  
1695 - stw(ptr + 10, 0);  
1696 - stw(ptr + 12, 0);  
1697 - }  
1698 -}  
1699 -  
1700 -void helper_fldenv(uint8_t *ptr, int data32)  
1701 -{  
1702 - int i, fpus, fptag;  
1703 -  
1704 - if (data32) {  
1705 - env->fpuc = lduw(ptr);  
1706 - fpus = lduw(ptr + 4);  
1707 - fptag = lduw(ptr + 8);  
1708 - }  
1709 - else {  
1710 - env->fpuc = lduw(ptr);  
1711 - fpus = lduw(ptr + 2);  
1712 - fptag = lduw(ptr + 4);  
1713 - }  
1714 - env->fpstt = (fpus >> 11) & 7;  
1715 - env->fpus = fpus & ~0x3800;  
1716 - for(i = 0;i < 7; i++) {  
1717 - env->fptags[i] = ((fptag & 3) == 3);  
1718 - fptag >>= 2;  
1719 - }  
1720 -}  
1721 -  
1722 -void helper_fsave(uint8_t *ptr, int data32)  
1723 -{  
1724 - CPU86_LDouble tmp;  
1725 - int i;  
1726 -  
1727 - helper_fstenv(ptr, data32);  
1728 -  
1729 - ptr += (14 << data32);  
1730 - for(i = 0;i < 8; i++) {  
1731 - tmp = ST(i);  
1732 -#ifdef USE_X86LDOUBLE  
1733 - *(long double *)ptr = tmp;  
1734 -#else  
1735 - helper_fstt(tmp, ptr);  
1736 -#endif  
1737 - ptr += 10;  
1738 - }  
1739 -  
1740 - /* fninit */  
1741 - env->fpus = 0;  
1742 - env->fpstt = 0;  
1743 - env->fpuc = 0x37f;  
1744 - env->fptags[0] = 1;  
1745 - env->fptags[1] = 1;  
1746 - env->fptags[2] = 1;  
1747 - env->fptags[3] = 1;  
1748 - env->fptags[4] = 1;  
1749 - env->fptags[5] = 1;  
1750 - env->fptags[6] = 1;  
1751 - env->fptags[7] = 1;  
1752 -}  
1753 -  
1754 -void helper_frstor(uint8_t *ptr, int data32)  
1755 -{  
1756 - CPU86_LDouble tmp;  
1757 - int i;  
1758 -  
1759 - helper_fldenv(ptr, data32);  
1760 - ptr += (14 << data32);  
1761 -  
1762 - for(i = 0;i < 8; i++) {  
1763 -#ifdef USE_X86LDOUBLE  
1764 - tmp = *(long double *)ptr;  
1765 -#else  
1766 - tmp = helper_fldt(ptr);  
1767 -#endif  
1768 - ST(i) = tmp;  
1769 - ptr += 10;  
1770 - }  
1771 -}  
1772 -  
1773 -#define SHIFT 0  
1774 -#include "softmmu_template.h"  
1775 -  
1776 -#define SHIFT 1  
1777 -#include "softmmu_template.h"  
1778 -  
1779 -#define SHIFT 2  
1780 -#include "softmmu_template.h"  
1781 -  
1782 -#define SHIFT 3  
1783 -#include "softmmu_template.h"  
1784 -  
1785 -/* try to fill the TLB and return an exception if error */  
1786 -void tlb_fill(unsigned long addr, int is_write, void *retaddr)  
1787 -{  
1788 - TranslationBlock *tb;  
1789 - int ret;  
1790 - unsigned long pc;  
1791 - ret = cpu_x86_handle_mmu_fault(env, addr, is_write);  
1792 - if (ret) {  
1793 - /* now we have a real cpu fault */  
1794 - pc = (unsigned long)retaddr;  
1795 - tb = tb_find_pc(pc);  
1796 - if (tb) {  
1797 - /* the PC is inside the translated code. It means that we have  
1798 - a virtual CPU fault */  
1799 - cpu_restore_state(tb, env, pc);  
1800 - }  
1801 - raise_exception_err(EXCP0E_PAGE, env->error_code);  
1802 - }  
1803 -}  
helper2-i386.c deleted 100644 → 0
1 -/*  
2 - * i386 helpers (without register variable usage)  
3 - *  
4 - * Copyright (c) 2003 Fabrice Bellard  
5 - *  
6 - * This library is free software; you can redistribute it and/or  
7 - * modify it under the terms of the GNU Lesser General Public  
8 - * License as published by the Free Software Foundation; either  
9 - * version 2 of the License, or (at your option) any later version.  
10 - *  
11 - * This library is distributed in the hope that it will be useful,  
12 - * but WITHOUT ANY WARRANTY; without even the implied warranty of  
13 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  
14 - * Lesser General Public License for more details.  
15 - *  
16 - * You should have received a copy of the GNU Lesser General Public  
17 - * License along with this library; if not, write to the Free Software  
18 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA  
19 - */  
20 -#include <stdarg.h>  
21 -#include <stdlib.h>  
22 -#include <stdio.h>  
23 -#include <string.h>  
24 -#include <inttypes.h>  
25 -#include <signal.h>  
26 -#include <assert.h>  
27 -#include <sys/mman.h>  
28 -  
29 -#include "cpu-i386.h"  
30 -#include "exec.h"  
31 -  
32 -//#define DEBUG_MMU  
33 -  
34 -CPUX86State *cpu_x86_init(void)  
35 -{  
36 - CPUX86State *env;  
37 - int i;  
38 - static int inited;  
39 -  
40 - cpu_exec_init();  
41 -  
42 - env = malloc(sizeof(CPUX86State));  
43 - if (!env)  
44 - return NULL;  
45 - memset(env, 0, sizeof(CPUX86State));  
46 - /* basic FPU init */  
47 - for(i = 0;i < 8; i++)  
48 - env->fptags[i] = 1;  
49 - env->fpuc = 0x37f;  
50 - /* flags setup : we activate the IRQs by default as in user mode */  
51 - env->eflags = 0x2 | IF_MASK;  
52 -  
53 - tlb_flush(env);  
54 -#ifdef CONFIG_SOFTMMU  
55 - env->hflags |= HF_SOFTMMU_MASK;  
56 -#endif  
57 - /* init various static tables */  
58 - if (!inited) {  
59 - inited = 1;  
60 - optimize_flags_init();  
61 - }  
62 - return env;  
63 -}  
64 -  
65 -void cpu_x86_close(CPUX86State *env)  
66 -{  
67 - free(env);  
68 -}  
69 -  
70 -/***********************************************************/  
71 -/* x86 debug */  
72 -  
73 -static const char *cc_op_str[] = {  
74 - "DYNAMIC",  
75 - "EFLAGS",  
76 - "MUL",  
77 - "ADDB",  
78 - "ADDW",  
79 - "ADDL",  
80 - "ADCB",  
81 - "ADCW",  
82 - "ADCL",  
83 - "SUBB",  
84 - "SUBW",  
85 - "SUBL",  
86 - "SBBB",  
87 - "SBBW",  
88 - "SBBL",  
89 - "LOGICB",  
90 - "LOGICW",  
91 - "LOGICL",  
92 - "INCB",  
93 - "INCW",  
94 - "INCL",  
95 - "DECB",  
96 - "DECW",  
97 - "DECL",  
98 - "SHLB",  
99 - "SHLW",  
100 - "SHLL",  
101 - "SARB",  
102 - "SARW",  
103 - "SARL",  
104 -};  
105 -  
106 -void cpu_x86_dump_state(CPUX86State *env, FILE *f, int flags)  
107 -{  
108 - int eflags;  
109 - char cc_op_name[32];  
110 -  
111 - eflags = env->eflags;  
112 - fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"  
113 - "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"  
114 - "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c]\n",  
115 - env->regs[R_EAX], env->regs[R_EBX], env->regs[R_ECX], env->regs[R_EDX],  
116 - env->regs[R_ESI], env->regs[R_EDI], env->regs[R_EBP], env->regs[R_ESP],  
117 - env->eip, eflags,  
118 - eflags & DF_MASK ? 'D' : '-',  
119 - eflags & CC_O ? 'O' : '-',  
120 - eflags & CC_S ? 'S' : '-',  
121 - eflags & CC_Z ? 'Z' : '-',  
122 - eflags & CC_A ? 'A' : '-',  
123 - eflags & CC_P ? 'P' : '-',  
124 - eflags & CC_C ? 'C' : '-');  
125 - fprintf(f, "CS=%04x SS=%04x DS=%04x ES=%04x FS=%04x GS=%04x\n",  
126 - env->segs[R_CS].selector,  
127 - env->segs[R_SS].selector,  
128 - env->segs[R_DS].selector,  
129 - env->segs[R_ES].selector,  
130 - env->segs[R_FS].selector,  
131 - env->segs[R_GS].selector);  
132 - if (flags & X86_DUMP_CCOP) {  
133 - if ((unsigned)env->cc_op < CC_OP_NB)  
134 - strcpy(cc_op_name, cc_op_str[env->cc_op]);  
135 - else  
136 - snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);  
137 - fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",  
138 - env->cc_src, env->cc_dst, cc_op_name);  
139 - }  
140 - if (flags & X86_DUMP_FPU) {  
141 - fprintf(f, "ST0=%f ST1=%f ST2=%f ST3=%f\n",  
142 - (double)env->fpregs[0],  
143 - (double)env->fpregs[1],  
144 - (double)env->fpregs[2],  
145 - (double)env->fpregs[3]);  
146 - fprintf(f, "ST4=%f ST5=%f ST6=%f ST7=%f\n",  
147 - (double)env->fpregs[4],  
148 - (double)env->fpregs[5],  
149 - (double)env->fpregs[7],  
150 - (double)env->fpregs[8]);  
151 - }  
152 -}  
153 -  
154 -/***********************************************************/  
155 -/* x86 mmu */  
156 -/* XXX: add PGE support */  
157 -  
158 -/* called when cr3 or PG bit are modified */  
159 -static int last_pg_state = -1;  
160 -static int last_pe_state = 0;  
161 -int phys_ram_size;  
162 -int phys_ram_fd;  
163 -uint8_t *phys_ram_base;  
164 -  
165 -void cpu_x86_update_cr0(CPUX86State *env)  
166 -{  
167 - int pg_state, pe_state;  
168 -  
169 -#ifdef DEBUG_MMU  
170 - printf("CR0 update: CR0=0x%08x\n", env->cr[0]);  
171 -#endif  
172 - pg_state = env->cr[0] & CR0_PG_MASK;  
173 - if (pg_state != last_pg_state) {  
174 - page_unmap();  
175 - tlb_flush(env);  
176 - last_pg_state = pg_state;  
177 - }  
178 - pe_state = env->cr[0] & CR0_PE_MASK;  
179 - if (last_pe_state != pe_state) {  
180 - tb_flush();  
181 - last_pe_state = pe_state;  
182 - }  
183 -}  
184 -  
185 -void cpu_x86_update_cr3(CPUX86State *env)  
186 -{  
187 - if (env->cr[0] & CR0_PG_MASK) {  
188 -#if defined(DEBUG_MMU)  
189 - printf("CR3 update: CR3=%08x\n", env->cr[3]);  
190 -#endif  
191 - page_unmap();  
192 - tlb_flush(env);  
193 - }  
194 -}  
195 -  
196 -void cpu_x86_init_mmu(CPUX86State *env)  
197 -{  
198 - last_pg_state = -1;  
199 - cpu_x86_update_cr0(env);  
200 -}  
201 -  
202 -/* XXX: also flush 4MB pages */  
203 -void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr)  
204 -{  
205 - int flags;  
206 - unsigned long virt_addr;  
207 -  
208 - tlb_flush_page(env, addr);  
209 -  
210 - flags = page_get_flags(addr);  
211 - if (flags & PAGE_VALID) {  
212 - virt_addr = addr & ~0xfff;  
213 - munmap((void *)virt_addr, 4096);  
214 - page_set_flags(virt_addr, virt_addr + 4096, 0);  
215 - }  
216 -}  
217 -  
218 -/* return value:  
219 - -1 = cannot handle fault  
220 - 0 = nothing more to do  
221 - 1 = generate PF fault  
222 - 2 = soft MMU activation required for this block  
223 -*/  
224 -int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write)  
225 -{  
226 - uint8_t *pde_ptr, *pte_ptr;  
227 - uint32_t pde, pte, virt_addr;  
228 - int cpl, error_code, is_dirty, is_user, prot, page_size, ret;  
229 - unsigned long pd;  
230 -  
231 - cpl = env->hflags & HF_CPL_MASK;  
232 - is_user = (cpl == 3);  
233 -  
234 -#ifdef DEBUG_MMU  
235 - printf("MMU fault: addr=0x%08x w=%d u=%d eip=%08x\n",  
236 - addr, is_write, is_user, env->eip);  
237 -#endif  
238 -  
239 - if (env->user_mode_only) {  
240 - /* user mode only emulation */  
241 - error_code = 0;  
242 - goto do_fault;  
243 - }  
244 -  
245 - if (!(env->cr[0] & CR0_PG_MASK)) {  
246 - pte = addr;  
247 - virt_addr = addr & ~0xfff;  
248 - prot = PROT_READ | PROT_WRITE;  
249 - page_size = 4096;  
250 - goto do_mapping;  
251 - }  
252 -  
253 - /* page directory entry */  
254 - pde_ptr = phys_ram_base + ((env->cr[3] & ~0xfff) + ((addr >> 20) & ~3));  
255 - pde = ldl(pde_ptr);  
256 - if (!(pde & PG_PRESENT_MASK)) {  
257 - error_code = 0;  
258 - goto do_fault;  
259 - }  
260 - if (is_user) {  
261 - if (!(pde & PG_USER_MASK))  
262 - goto do_fault_protect;  
263 - if (is_write && !(pde & PG_RW_MASK))  
264 - goto do_fault_protect;  
265 - } else {  
266 - if ((env->cr[0] & CR0_WP_MASK) && (pde & PG_USER_MASK) &&  
267 - is_write && !(pde & PG_RW_MASK))  
268 - goto do_fault_protect;  
269 - }  
270 - /* if PSE bit is set, then we use a 4MB page */  
271 - if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {  
272 - is_dirty = is_write && !(pde & PG_DIRTY_MASK);  
273 - if (!(pde & PG_ACCESSED_MASK)) {  
274 - pde |= PG_ACCESSED_MASK;  
275 - if (is_dirty)  
276 - pde |= PG_DIRTY_MASK;  
277 - stl(pde_ptr, pde);  
278 - }  
279 -  
280 - pte = pde & ~0x003ff000; /* align to 4MB */  
281 - page_size = 4096 * 1024;  
282 - virt_addr = addr & ~0x003fffff;  
283 - } else {  
284 - if (!(pde & PG_ACCESSED_MASK)) {  
285 - pde |= PG_ACCESSED_MASK;  
286 - stl(pde_ptr, pde);  
287 - }  
288 -  
289 - /* page directory entry */  
290 - pte_ptr = phys_ram_base + ((pde & ~0xfff) + ((addr >> 10) & 0xffc));  
291 - pte = ldl(pte_ptr);  
292 - if (!(pte & PG_PRESENT_MASK)) {  
293 - error_code = 0;  
294 - goto do_fault;  
295 - }  
296 - if (is_user) {  
297 - if (!(pte & PG_USER_MASK))  
298 - goto do_fault_protect;  
299 - if (is_write && !(pte & PG_RW_MASK))  
300 - goto do_fault_protect;  
301 - } else {  
302 - if ((env->cr[0] & CR0_WP_MASK) && (pte & PG_USER_MASK) &&  
303 - is_write && !(pte & PG_RW_MASK))  
304 - goto do_fault_protect;  
305 - }  
306 - is_dirty = is_write && !(pte & PG_DIRTY_MASK);  
307 - if (!(pte & PG_ACCESSED_MASK) || is_dirty) {  
308 - pte |= PG_ACCESSED_MASK;  
309 - if (is_dirty)  
310 - pte |= PG_DIRTY_MASK;  
311 - stl(pte_ptr, pte);  
312 - }  
313 - page_size = 4096;  
314 - virt_addr = addr & ~0xfff;  
315 - }  
316 - /* the page can be put in the TLB */  
317 - prot = PROT_READ;  
318 - if (is_user) {  
319 - if (pte & PG_RW_MASK)  
320 - prot |= PROT_WRITE;  
321 - } else {  
322 - if (!(env->cr[0] & CR0_WP_MASK) || !(pte & PG_USER_MASK) ||  
323 - (pte & PG_RW_MASK))  
324 - prot |= PROT_WRITE;  
325 - }  
326 -  
327 - do_mapping:  
328 - if (env->hflags & HF_SOFTMMU_MASK) {  
329 - unsigned long paddr, vaddr, address, addend, page_offset;  
330 - int index;  
331 -  
332 - /* software MMU case. Even if 4MB pages, we map only one 4KB  
333 - page in the cache to avoid filling it too fast */  
334 - page_offset = (addr & ~0xfff) & (page_size - 1);  
335 - paddr = (pte & ~0xfff) + page_offset;  
336 - vaddr = virt_addr + page_offset;  
337 - index = (addr >> 12) & (CPU_TLB_SIZE - 1);  
338 - pd = physpage_find(paddr);  
339 - if (pd & 0xfff) {  
340 - /* IO memory case */  
341 - address = vaddr | pd;  
342 - addend = paddr;  
343 - } else {  
344 - /* standard memory */  
345 - address = vaddr;  
346 - addend = (unsigned long)phys_ram_base + pd;  
347 - }  
348 - addend -= vaddr;  
349 - env->tlb_read[is_user][index].address = address;  
350 - env->tlb_read[is_user][index].addend = addend;  
351 - if (prot & PROT_WRITE) {  
352 - env->tlb_write[is_user][index].address = address;  
353 - env->tlb_write[is_user][index].addend = addend;  
354 - }  
355 - }  
356 - ret = 0;  
357 - /* XXX: incorrect for 4MB pages */  
358 - pd = physpage_find(pte & ~0xfff);  
359 - if ((pd & 0xfff) != 0) {  
360 - /* IO access: no mapping is done as it will be handled by the  
361 - soft MMU */  
362 - if (!(env->hflags & HF_SOFTMMU_MASK))  
363 - ret = 2;  
364 - } else {  
365 - void *map_addr;  
366 - map_addr = mmap((void *)virt_addr, page_size, prot,  
367 - MAP_SHARED | MAP_FIXED, phys_ram_fd, pd);  
368 - if (map_addr == MAP_FAILED) {  
369 - fprintf(stderr,  
370 - "mmap failed when mapped physical address 0x%08x to virtual address 0x%08x\n",  
371 - pte & ~0xfff, virt_addr);  
372 - exit(1);  
373 - }  
374 -#ifdef DEBUG_MMU  
375 - printf("mmaping 0x%08x to virt 0x%08x pse=%d\n",  
376 - pte & ~0xfff, virt_addr, (page_size != 4096));  
377 -#endif  
378 - page_set_flags(virt_addr, virt_addr + page_size,  
379 - PAGE_VALID | PAGE_EXEC | prot);  
380 - }  
381 - return ret;  
382 - do_fault_protect:  
383 - error_code = PG_ERROR_P_MASK;  
384 - do_fault:  
385 - env->cr[2] = addr;  
386 - env->error_code = (is_write << PG_ERROR_W_BIT) | error_code;  
387 - if (is_user)  
388 - env->error_code |= PG_ERROR_U_MASK;  
389 - return 1;  
390 -}  
op-arm-template.h deleted 100644 → 0
1 -/*  
2 - * ARM micro operations (templates for various register related  
3 - * operations)  
4 - *  
5 - * Copyright (c) 2003 Fabrice Bellard  
6 - *  
7 - * This library is free software; you can redistribute it and/or  
8 - * modify it under the terms of the GNU Lesser General Public  
9 - * License as published by the Free Software Foundation; either  
10 - * version 2 of the License, or (at your option) any later version.  
11 - *  
12 - * This library is distributed in the hope that it will be useful,  
13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of  
14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  
15 - * Lesser General Public License for more details.  
16 - *  
17 - * You should have received a copy of the GNU Lesser General Public  
18 - * License along with this library; if not, write to the Free Software  
19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA  
20 - */  
21 -  
22 -void OPPROTO glue(op_movl_T0_, REGNAME)(void)  
23 -{  
24 - T0 = REG;  
25 -}  
26 -  
27 -void OPPROTO glue(op_movl_T1_, REGNAME)(void)  
28 -{  
29 - T1 = REG;  
30 -}  
31 -  
32 -void OPPROTO glue(op_movl_T2_, REGNAME)(void)  
33 -{  
34 - T2 = REG;  
35 -}  
36 -  
37 -void OPPROTO glue(glue(op_movl_, REGNAME), _T0)(void)  
38 -{  
39 - REG = T0;  
40 -}  
41 -  
42 -void OPPROTO glue(glue(op_movl_, REGNAME), _T1)(void)  
43 -{  
44 - REG = T1;  
45 -}  
46 -  
47 -#undef REG  
48 -#undef REGNAME  
op-arm.c deleted 100644 → 0
1 -/*  
2 - * ARM micro operations  
3 - *  
4 - * Copyright (c) 2003 Fabrice Bellard  
5 - *  
6 - * This library is free software; you can redistribute it and/or  
7 - * modify it under the terms of the GNU Lesser General Public  
8 - * License as published by the Free Software Foundation; either  
9 - * version 2 of the License, or (at your option) any later version.  
10 - *  
11 - * This library is distributed in the hope that it will be useful,  
12 - * but WITHOUT ANY WARRANTY; without even the implied warranty of  
13 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  
14 - * Lesser General Public License for more details.  
15 - *  
16 - * You should have received a copy of the GNU Lesser General Public  
17 - * License along with this library; if not, write to the Free Software  
18 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA  
19 - */  
20 -#include "exec-arm.h"  
21 -  
22 -#define REGNAME r0  
23 -#define REG (env->regs[0])  
24 -#include "op-arm-template.h"  
25 -  
26 -#define REGNAME r1  
27 -#define REG (env->regs[1])  
28 -#include "op-arm-template.h"  
29 -  
30 -#define REGNAME r2  
31 -#define REG (env->regs[2])  
32 -#include "op-arm-template.h"  
33 -  
34 -#define REGNAME r3  
35 -#define REG (env->regs[3])  
36 -#include "op-arm-template.h"  
37 -  
38 -#define REGNAME r4  
39 -#define REG (env->regs[4])  
40 -#include "op-arm-template.h"  
41 -  
42 -#define REGNAME r5  
43 -#define REG (env->regs[5])  
44 -#include "op-arm-template.h"  
45 -  
46 -#define REGNAME r6  
47 -#define REG (env->regs[6])  
48 -#include "op-arm-template.h"  
49 -  
50 -#define REGNAME r7  
51 -#define REG (env->regs[7])  
52 -#include "op-arm-template.h"  
53 -  
54 -#define REGNAME r8  
55 -#define REG (env->regs[8])  
56 -#include "op-arm-template.h"  
57 -  
58 -#define REGNAME r9  
59 -#define REG (env->regs[9])  
60 -#include "op-arm-template.h"  
61 -  
62 -#define REGNAME r10  
63 -#define REG (env->regs[10])  
64 -#include "op-arm-template.h"  
65 -  
66 -#define REGNAME r11  
67 -#define REG (env->regs[11])  
68 -#include "op-arm-template.h"  
69 -  
70 -#define REGNAME r12  
71 -#define REG (env->regs[12])  
72 -#include "op-arm-template.h"  
73 -  
74 -#define REGNAME r13  
75 -#define REG (env->regs[13])  
76 -#include "op-arm-template.h"  
77 -  
78 -#define REGNAME r14  
79 -#define REG (env->regs[14])  
80 -#include "op-arm-template.h"  
81 -  
82 -#define REGNAME r15  
83 -#define REG (env->regs[15])  
84 -#include "op-arm-template.h"  
85 -  
86 -void OPPROTO op_movl_T0_0(void)  
87 -{  
88 - T0 = 0;  
89 -}  
90 -  
91 -void OPPROTO op_movl_T0_im(void)  
92 -{  
93 - T0 = PARAM1;  
94 -}  
95 -  
96 -void OPPROTO op_movl_T1_im(void)  
97 -{  
98 - T1 = PARAM1;  
99 -}  
100 -  
101 -void OPPROTO op_movl_T2_im(void)  
102 -{  
103 - T2 = PARAM1;  
104 -}  
105 -  
106 -void OPPROTO op_addl_T1_im(void)  
107 -{  
108 - T1 += PARAM1;  
109 -}  
110 -  
111 -void OPPROTO op_addl_T1_T2(void)  
112 -{  
113 - T1 += T2;  
114 -}  
115 -  
116 -void OPPROTO op_subl_T1_T2(void)  
117 -{  
118 - T1 -= T2;  
119 -}  
120 -  
121 -void OPPROTO op_addl_T0_T1(void)  
122 -{  
123 - T0 += T1;  
124 -}  
125 -  
126 -void OPPROTO op_addl_T0_T1_cc(void)  
127 -{  
128 - unsigned int src1;  
129 - src1 = T0;  
130 - T0 += T1;  
131 - env->NZF = T0;  
132 - env->CF = T0 < src1;  
133 - env->VF = (src1 ^ T1 ^ -1) & (src1 ^ T0);  
134 -}  
135 -  
136 -void OPPROTO op_adcl_T0_T1(void)  
137 -{  
138 - T0 += T1 + env->CF;  
139 -}  
140 -  
141 -void OPPROTO op_adcl_T0_T1_cc(void)  
142 -{  
143 - unsigned int src1;  
144 - src1 = T0;  
145 - if (!env->CF) {  
146 - T0 += T1;  
147 - env->CF = T0 < src1;  
148 - } else {  
149 - T0 += T1 + 1;  
150 - env->CF = T0 <= src1;  
151 - }  
152 - env->VF = (src1 ^ T1 ^ -1) & (src1 ^ T0);  
153 - env->NZF = T0;  
154 - FORCE_RET();  
155 -}  
156 -  
157 -#define OPSUB(sub, sbc, res, T0, T1) \  
158 - \  
159 -void OPPROTO op_ ## sub ## l_T0_T1(void) \  
160 -{ \  
161 - res = T0 - T1; \  
162 -} \  
163 - \  
164 -void OPPROTO op_ ## sub ## l_T0_T1_cc(void) \  
165 -{ \  
166 - unsigned int src1; \  
167 - src1 = T0; \  
168 - T0 -= T1; \  
169 - env->NZF = T0; \  
170 - env->CF = src1 >= T1; \  
171 - env->VF = (src1 ^ T1) & (src1 ^ T0); \  
172 - res = T0; \  
173 -} \  
174 - \  
175 -void OPPROTO op_ ## sbc ## l_T0_T1(void) \  
176 -{ \  
177 - res = T0 - T1 + env->CF - 1; \  
178 -} \  
179 - \  
180 -void OPPROTO op_ ## sbc ## l_T0_T1_cc(void) \  
181 -{ \  
182 - unsigned int src1; \  
183 - src1 = T0; \  
184 - if (!env->CF) { \  
185 - T0 = T0 - T1 - 1; \  
186 - env->CF = src1 >= T1; \  
187 - } else { \  
188 - T0 = T0 - T1; \  
189 - env->CF = src1 > T1; \  
190 - } \  
191 - env->VF = (src1 ^ T1) & (src1 ^ T0); \  
192 - env->NZF = T0; \  
193 - res = T0; \  
194 - FORCE_RET(); \  
195 -}  
196 -  
197 -OPSUB(sub, sbc, T0, T0, T1)  
198 -  
199 -OPSUB(rsb, rsc, T0, T1, T0)  
200 -  
201 -void OPPROTO op_andl_T0_T1(void)  
202 -{  
203 - T0 &= T1;  
204 -}  
205 -  
206 -void OPPROTO op_xorl_T0_T1(void)  
207 -{  
208 - T0 ^= T1;  
209 -}  
210 -  
211 -void OPPROTO op_orl_T0_T1(void)  
212 -{  
213 - T0 |= T1;  
214 -}  
215 -  
216 -void OPPROTO op_bicl_T0_T1(void)  
217 -{  
218 - T0 &= ~T1;  
219 -}  
220 -  
221 -void OPPROTO op_notl_T1(void)  
222 -{  
223 - T1 = ~T1;  
224 -}  
225 -  
226 -void OPPROTO op_logic_T0_cc(void)  
227 -{  
228 - env->NZF = T0;  
229 -}  
230 -  
231 -void OPPROTO op_logic_T1_cc(void)  
232 -{  
233 - env->NZF = T1;  
234 -}  
235 -  
236 -#define EIP (env->regs[15])  
237 -  
238 -void OPPROTO op_test_eq(void)  
239 -{  
240 - if (env->NZF == 0)  
241 - JUMP_TB(op_test_eq, PARAM1, 0, PARAM2);  
242 - FORCE_RET();  
243 -}  
244 -  
245 -void OPPROTO op_test_ne(void)  
246 -{  
247 - if (env->NZF != 0)  
248 - JUMP_TB(op_test_ne, PARAM1, 0, PARAM2);  
249 - FORCE_RET();  
250 -}  
251 -  
252 -void OPPROTO op_test_cs(void)  
253 -{  
254 - if (env->CF != 0)  
255 - JUMP_TB(op_test_cs, PARAM1, 0, PARAM2);  
256 - FORCE_RET();  
257 -}  
258 -  
259 -void OPPROTO op_test_cc(void)  
260 -{  
261 - if (env->CF == 0)  
262 - JUMP_TB(op_test_cc, PARAM1, 0, PARAM2);  
263 - FORCE_RET();  
264 -}  
265 -  
266 -void OPPROTO op_test_mi(void)  
267 -{  
268 - if ((env->NZF & 0x80000000) != 0)  
269 - JUMP_TB(op_test_mi, PARAM1, 0, PARAM2);  
270 - FORCE_RET();  
271 -}  
272 -  
273 -void OPPROTO op_test_pl(void)  
274 -{  
275 - if ((env->NZF & 0x80000000) == 0)  
276 - JUMP_TB(op_test_pl, PARAM1, 0, PARAM2);  
277 - FORCE_RET();  
278 -}  
279 -  
280 -void OPPROTO op_test_vs(void)  
281 -{  
282 - if ((env->VF & 0x80000000) != 0)  
283 - JUMP_TB(op_test_vs, PARAM1, 0, PARAM2);  
284 - FORCE_RET();  
285 -}  
286 -  
287 -void OPPROTO op_test_vc(void)  
288 -{  
289 - if ((env->VF & 0x80000000) == 0)  
290 - JUMP_TB(op_test_vc, PARAM1, 0, PARAM2);  
291 - FORCE_RET();  
292 -}  
293 -  
294 -void OPPROTO op_test_hi(void)  
295 -{  
296 - if (env->CF != 0 && env->NZF != 0)  
297 - JUMP_TB(op_test_hi, PARAM1, 0, PARAM2);  
298 - FORCE_RET();  
299 -}  
300 -  
301 -void OPPROTO op_test_ls(void)  
302 -{  
303 - if (env->CF == 0 || env->NZF == 0)  
304 - JUMP_TB(op_test_ls, PARAM1, 0, PARAM2);  
305 - FORCE_RET();  
306 -}  
307 -  
308 -void OPPROTO op_test_ge(void)  
309 -{  
310 - if (((env->VF ^ env->NZF) & 0x80000000) == 0)  
311 - JUMP_TB(op_test_ge, PARAM1, 0, PARAM2);  
312 - FORCE_RET();  
313 -}  
314 -  
315 -void OPPROTO op_test_lt(void)  
316 -{  
317 - if (((env->VF ^ env->NZF) & 0x80000000) != 0)  
318 - JUMP_TB(op_test_lt, PARAM1, 0, PARAM2);  
319 - FORCE_RET();  
320 -}  
321 -  
322 -void OPPROTO op_test_gt(void)  
323 -{  
324 - if (env->NZF != 0 && ((env->VF ^ env->NZF) & 0x80000000) == 0)  
325 - JUMP_TB(op_test_gt, PARAM1, 0, PARAM2);  
326 - FORCE_RET();  
327 -}  
328 -  
329 -void OPPROTO op_test_le(void)  
330 -{  
331 - if (env->NZF == 0 || ((env->VF ^ env->NZF) & 0x80000000) != 0)  
332 - JUMP_TB(op_test_le, PARAM1, 0, PARAM2);  
333 - FORCE_RET();  
334 -}  
335 -  
336 -void OPPROTO op_jmp(void)  
337 -{  
338 - JUMP_TB(op_jmp, PARAM1, 1, PARAM2);  
339 -}  
340 -  
341 -void OPPROTO op_exit_tb(void)  
342 -{  
343 - EXIT_TB();  
344 -}  
345 -  
346 -void OPPROTO op_movl_T0_psr(void)  
347 -{  
348 - T0 = compute_cpsr();  
349 -}  
350 -  
351 -/* NOTE: N = 1 and Z = 1 cannot be stored currently */  
352 -void OPPROTO op_movl_psr_T0(void)  
353 -{  
354 - unsigned int psr;  
355 - psr = T0;  
356 - env->CF = (psr >> 29) & 1;  
357 - env->NZF = (psr & 0xc0000000) ^ 0x40000000;  
358 - env->VF = (psr << 3) & 0x80000000;  
359 - /* for user mode we do not update other state info */  
360 -}  
361 -  
362 -void OPPROTO op_mul_T0_T1(void)  
363 -{  
364 - T0 = T0 * T1;  
365 -}  
366 -  
367 -/* 64 bit unsigned mul */  
368 -void OPPROTO op_mull_T0_T1(void)  
369 -{  
370 - uint64_t res;  
371 - res = T0 * T1;  
372 - T1 = res >> 32;  
373 - T0 = res;  
374 -}  
375 -  
376 -/* 64 bit signed mul */  
377 -void OPPROTO op_imull_T0_T1(void)  
378 -{  
379 - uint64_t res;  
380 - res = (int32_t)T0 * (int32_t)T1;  
381 - T1 = res >> 32;  
382 - T0 = res;  
383 -}  
384 -  
385 -void OPPROTO op_addq_T0_T1(void)  
386 -{  
387 - uint64_t res;  
388 - res = ((uint64_t)T1 << 32) | T0;  
389 - res += ((uint64_t)(env->regs[PARAM2]) << 32) | (env->regs[PARAM1]);  
390 - T1 = res >> 32;  
391 - T0 = res;  
392 -}  
393 -  
394 -void OPPROTO op_logicq_cc(void)  
395 -{  
396 - env->NZF = (T1 & 0x80000000) | ((T0 | T1) != 0);  
397 -}  
398 -  
399 -/* memory access */  
400 -  
401 -void OPPROTO op_ldub_T0_T1(void)  
402 -{  
403 - T0 = ldub((void *)T1);  
404 -}  
405 -  
406 -void OPPROTO op_ldsb_T0_T1(void)  
407 -{  
408 - T0 = ldsb((void *)T1);  
409 -}  
410 -  
411 -void OPPROTO op_lduw_T0_T1(void)  
412 -{  
413 - T0 = lduw((void *)T1);  
414 -}  
415 -  
416 -void OPPROTO op_ldsw_T0_T1(void)  
417 -{  
418 - T0 = ldsw((void *)T1);  
419 -}  
420 -  
421 -void OPPROTO op_ldl_T0_T1(void)  
422 -{  
423 - T0 = ldl((void *)T1);  
424 -}  
425 -  
426 -void OPPROTO op_stb_T0_T1(void)  
427 -{  
428 - stb((void *)T1, T0);  
429 -}  
430 -  
431 -void OPPROTO op_stw_T0_T1(void)  
432 -{  
433 - stw((void *)T1, T0);  
434 -}  
435 -  
436 -void OPPROTO op_stl_T0_T1(void)  
437 -{  
438 - stl((void *)T1, T0);  
439 -}  
440 -  
441 -void OPPROTO op_swpb_T0_T1(void)  
442 -{  
443 - int tmp;  
444 -  
445 - cpu_lock();  
446 - tmp = ldub((void *)T1);  
447 - stb((void *)T1, T0);  
448 - T0 = tmp;  
449 - cpu_unlock();  
450 -}  
451 -  
452 -void OPPROTO op_swpl_T0_T1(void)  
453 -{  
454 - int tmp;  
455 -  
456 - cpu_lock();  
457 - tmp = ldl((void *)T1);  
458 - stl((void *)T1, T0);  
459 - T0 = tmp;  
460 - cpu_unlock();  
461 -}  
462 -  
463 -/* shifts */  
464 -  
465 -/* T1 based */  
466 -void OPPROTO op_shll_T1_im(void)  
467 -{  
468 - T1 = T1 << PARAM1;  
469 -}  
470 -  
471 -void OPPROTO op_shrl_T1_im(void)  
472 -{  
473 - T1 = (uint32_t)T1 >> PARAM1;  
474 -}  
475 -  
476 -void OPPROTO op_sarl_T1_im(void)  
477 -{  
478 - T1 = (int32_t)T1 >> PARAM1;  
479 -}  
480 -  
481 -void OPPROTO op_rorl_T1_im(void)  
482 -{  
483 - int shift;  
484 - shift = PARAM1;  
485 - T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));  
486 -}  
487 -  
488 -/* T1 based, set C flag */  
489 -void OPPROTO op_shll_T1_im_cc(void)  
490 -{  
491 - env->CF = (T1 >> (32 - PARAM1)) & 1;  
492 - T1 = T1 << PARAM1;  
493 -}  
494 -  
495 -void OPPROTO op_shrl_T1_im_cc(void)  
496 -{  
497 - env->CF = (T1 >> (PARAM1 - 1)) & 1;  
498 - T1 = (uint32_t)T1 >> PARAM1;  
499 -}  
500 -  
501 -void OPPROTO op_sarl_T1_im_cc(void)  
502 -{  
503 - env->CF = (T1 >> (PARAM1 - 1)) & 1;  
504 - T1 = (int32_t)T1 >> PARAM1;  
505 -}  
506 -  
507 -void OPPROTO op_rorl_T1_im_cc(void)  
508 -{  
509 - int shift;  
510 - shift = PARAM1;  
511 - env->CF = (T1 >> (shift - 1)) & 1;  
512 - T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));  
513 -}  
514 -  
515 -/* T2 based */  
516 -void OPPROTO op_shll_T2_im(void)  
517 -{  
518 - T2 = T2 << PARAM1;  
519 -}  
520 -  
521 -void OPPROTO op_shrl_T2_im(void)  
522 -{  
523 - T2 = (uint32_t)T2 >> PARAM1;  
524 -}  
525 -  
526 -void OPPROTO op_sarl_T2_im(void)  
527 -{  
528 - T2 = (int32_t)T2 >> PARAM1;  
529 -}  
530 -  
531 -void OPPROTO op_rorl_T2_im(void)  
532 -{  
533 - int shift;  
534 - shift = PARAM1;  
535 - T2 = ((uint32_t)T2 >> shift) | (T2 << (32 - shift));  
536 -}  
537 -  
538 -/* T1 based, use T0 as shift count */  
539 -  
540 -void OPPROTO op_shll_T1_T0(void)  
541 -{  
542 - int shift;  
543 - shift = T0 & 0xff;  
544 - if (shift >= 32)  
545 - T1 = 0;  
546 - else  
547 - T1 = T1 << shift;  
548 - FORCE_RET();  
549 -}  
550 -  
551 -void OPPROTO op_shrl_T1_T0(void)  
552 -{  
553 - int shift;  
554 - shift = T0 & 0xff;  
555 - if (shift >= 32)  
556 - T1 = 0;  
557 - else  
558 - T1 = (uint32_t)T1 >> shift;  
559 - FORCE_RET();  
560 -}  
561 -  
562 -void OPPROTO op_sarl_T1_T0(void)  
563 -{  
564 - int shift;  
565 - shift = T0 & 0xff;  
566 - if (shift >= 32)  
567 - shift = 31;  
568 - T1 = (int32_t)T1 >> shift;  
569 -}  
570 -  
571 -void OPPROTO op_rorl_T1_T0(void)  
572 -{  
573 - int shift;  
574 - shift = T0 & 0x1f;  
575 - if (shift) {  
576 - T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));  
577 - }  
578 - FORCE_RET();  
579 -}  
580 -  
581 -/* T1 based, use T0 as shift count and compute CF */  
582 -  
583 -void OPPROTO op_shll_T1_T0_cc(void)  
584 -{  
585 - int shift;  
586 - shift = T0 & 0xff;  
587 - if (shift >= 32) {  
588 - if (shift == 32)  
589 - env->CF = T1 & 1;  
590 - else  
591 - env->CF = 0;  
592 - T1 = 0;  
593 - } else if (shift != 0) {  
594 - env->CF = (T1 >> (32 - shift)) & 1;  
595 - T1 = T1 << shift;  
596 - }  
597 - FORCE_RET();  
598 -}  
599 -  
600 -void OPPROTO op_shrl_T1_T0_cc(void)  
601 -{  
602 - int shift;  
603 - shift = T0 & 0xff;  
604 - if (shift >= 32) {  
605 - if (shift == 32)  
606 - env->CF = (T1 >> 31) & 1;  
607 - else  
608 - env->CF = 0;  
609 - T1 = 0;  
610 - } else if (shift != 0) {  
611 - env->CF = (T1 >> (shift - 1)) & 1;  
612 - T1 = (uint32_t)T1 >> shift;  
613 - }  
614 - FORCE_RET();  
615 -}  
616 -  
617 -void OPPROTO op_sarl_T1_T0_cc(void)  
618 -{  
619 - int shift;  
620 - shift = T0 & 0xff;  
621 - if (shift >= 32) {  
622 - env->CF = (T1 >> 31) & 1;  
623 - T1 = (int32_t)T1 >> 31;  
624 - } else {  
625 - env->CF = (T1 >> (shift - 1)) & 1;  
626 - T1 = (int32_t)T1 >> shift;  
627 - }  
628 - FORCE_RET();  
629 -}  
630 -  
631 -void OPPROTO op_rorl_T1_T0_cc(void)  
632 -{  
633 - int shift1, shift;  
634 - shift1 = T0 & 0xff;  
635 - shift = shift1 & 0x1f;  
636 - if (shift == 0) {  
637 - if (shift1 != 0)  
638 - env->CF = (T1 >> 31) & 1;  
639 - } else {  
640 - env->CF = (T1 >> (shift - 1)) & 1;  
641 - T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));  
642 - }  
643 - FORCE_RET();  
644 -}  
645 -  
646 -/* exceptions */  
647 -  
648 -void OPPROTO op_swi(void)  
649 -{  
650 - env->exception_index = EXCP_SWI;  
651 - cpu_loop_exit();  
652 -}  
653 -  
654 -void OPPROTO op_undef_insn(void)  
655 -{  
656 - env->exception_index = EXCP_UDEF;  
657 - cpu_loop_exit();  
658 -}  
659 -  
660 -/* thread support */  
661 -  
662 -spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED;  
663 -  
664 -void cpu_lock(void)  
665 -{  
666 - spin_lock(&global_cpu_lock);  
667 -}  
668 -  
669 -void cpu_unlock(void)  
670 -{  
671 - spin_unlock(&global_cpu_lock);  
672 -}  
673 -