2 * i386 TCG cpu class initialization
4 * Copyright (c) 2003 Fabrice Bellard
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.
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.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 #include "qemu/osdep.h"
22 #include "helper-tcg.h"
23 #include "qemu/accel.h"
24 #include "hw/core/accel-cpu.h"
28 /* Frob eflags into and out of the CPU temporary format. */
30 static void x86_cpu_exec_enter(CPUState
*cs
)
32 X86CPU
*cpu
= X86_CPU(cs
);
33 CPUX86State
*env
= &cpu
->env
;
35 CC_SRC
= env
->eflags
& (CC_O
| CC_S
| CC_Z
| CC_A
| CC_P
| CC_C
);
36 env
->df
= 1 - (2 * ((env
->eflags
>> 10) & 1));
38 env
->eflags
&= ~(DF_MASK
| CC_O
| CC_S
| CC_Z
| CC_A
| CC_P
| CC_C
);
41 static void x86_cpu_exec_exit(CPUState
*cs
)
43 X86CPU
*cpu
= X86_CPU(cs
);
44 CPUX86State
*env
= &cpu
->env
;
46 env
->eflags
= cpu_compute_eflags(env
);
49 static void x86_cpu_synchronize_from_tb(CPUState
*cs
,
50 const TranslationBlock
*tb
)
52 /* The instruction pointer is always up to date with CF_PCREL. */
53 if (!(tb_cflags(tb
) & CF_PCREL
)) {
54 CPUX86State
*env
= cs
->env_ptr
;
55 env
->eip
= tb
->pc
- tb
->cs_base
;
59 static void x86_restore_state_to_opc(CPUState
*cs
,
60 const TranslationBlock
*tb
,
63 X86CPU
*cpu
= X86_CPU(cs
);
64 CPUX86State
*env
= &cpu
->env
;
67 if (tb_cflags(tb
) & CF_PCREL
) {
68 env
->eip
= (env
->eip
& TARGET_PAGE_MASK
) | data
[0];
70 env
->eip
= data
[0] - tb
->cs_base
;
72 if (cc_op
!= CC_OP_DYNAMIC
) {
77 #ifndef CONFIG_USER_ONLY
78 static bool x86_debug_check_breakpoint(CPUState
*cs
)
80 X86CPU
*cpu
= X86_CPU(cs
);
81 CPUX86State
*env
= &cpu
->env
;
83 /* RF disables all architectural breakpoints. */
84 return !(env
->eflags
& RF_MASK
);
88 #include "hw/core/tcg-cpu-ops.h"
90 static const struct TCGCPUOps x86_tcg_ops
= {
91 .initialize
= tcg_x86_init
,
92 .synchronize_from_tb
= x86_cpu_synchronize_from_tb
,
93 .restore_state_to_opc
= x86_restore_state_to_opc
,
94 .cpu_exec_enter
= x86_cpu_exec_enter
,
95 .cpu_exec_exit
= x86_cpu_exec_exit
,
96 #ifdef CONFIG_USER_ONLY
97 .fake_user_interrupt
= x86_cpu_do_interrupt
,
98 .record_sigsegv
= x86_cpu_record_sigsegv
,
99 .record_sigbus
= x86_cpu_record_sigbus
,
101 .tlb_fill
= x86_cpu_tlb_fill
,
102 .do_interrupt
= x86_cpu_do_interrupt
,
103 .cpu_exec_interrupt
= x86_cpu_exec_interrupt
,
104 .do_unaligned_access
= x86_cpu_do_unaligned_access
,
105 .debug_excp_handler
= breakpoint_handler
,
106 .debug_check_breakpoint
= x86_debug_check_breakpoint
,
107 #endif /* !CONFIG_USER_ONLY */
110 static void tcg_cpu_init_ops(AccelCPUClass
*accel_cpu
, CPUClass
*cc
)
112 /* for x86, all cpus use the same set of operations */
113 cc
->tcg_ops
= &x86_tcg_ops
;
116 static void tcg_cpu_class_init(CPUClass
*cc
)
118 cc
->init_accel_cpu
= tcg_cpu_init_ops
;
121 static void tcg_cpu_xsave_init(void)
123 #define XO(bit, field) \
124 x86_ext_save_areas[bit].offset = offsetof(X86XSaveArea, field);
126 XO(XSTATE_FP_BIT
, legacy
);
127 XO(XSTATE_SSE_BIT
, legacy
);
128 XO(XSTATE_YMM_BIT
, avx_state
);
129 XO(XSTATE_BNDREGS_BIT
, bndreg_state
);
130 XO(XSTATE_BNDCSR_BIT
, bndcsr_state
);
131 XO(XSTATE_OPMASK_BIT
, opmask_state
);
132 XO(XSTATE_ZMM_Hi256_BIT
, zmm_hi256_state
);
133 XO(XSTATE_Hi16_ZMM_BIT
, hi16_zmm_state
);
134 XO(XSTATE_PKRU_BIT
, pkru_state
);
140 * TCG-specific defaults that override cpudef models when using TCG.
141 * Only for builtin_x86_defs models initialized with x86_register_cpudef_types.
143 static PropValue tcg_default_props
[] = {
148 static void tcg_cpu_instance_init(CPUState
*cs
)
150 X86CPU
*cpu
= X86_CPU(cs
);
151 X86CPUClass
*xcc
= X86_CPU_GET_CLASS(cpu
);
154 /* Special cases not set in the X86CPUDefinition structs: */
155 x86_cpu_apply_props(cpu
, tcg_default_props
);
158 tcg_cpu_xsave_init();
161 static void tcg_cpu_accel_class_init(ObjectClass
*oc
, void *data
)
163 AccelCPUClass
*acc
= ACCEL_CPU_CLASS(oc
);
165 #ifndef CONFIG_USER_ONLY
166 acc
->cpu_realizefn
= tcg_cpu_realizefn
;
167 #endif /* CONFIG_USER_ONLY */
169 acc
->cpu_class_init
= tcg_cpu_class_init
;
170 acc
->cpu_instance_init
= tcg_cpu_instance_init
;
172 static const TypeInfo tcg_cpu_accel_type_info
= {
173 .name
= ACCEL_CPU_NAME("tcg"),
175 .parent
= TYPE_ACCEL_CPU
,
176 .class_init
= tcg_cpu_accel_class_init
,
179 static void tcg_cpu_accel_register_types(void)
181 type_register_static(&tcg_cpu_accel_type_info
);
183 type_init(tcg_cpu_accel_register_types
);