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   -