]> git.proxmox.com Git - qemu.git/blame - target-i386/cc_helper.c
x86: avoid AREG0 for FPU helpers
[qemu.git] / target-i386 / cc_helper.c
CommitLineData
5918fffb
BS
1/*
2 * x86 condition code 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, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "cpu.h"
21#include "dyngen-exec.h"
22#include "helper.h"
23
24const uint8_t parity_table[256] = {
25 CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
26 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
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 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
30 CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
31 CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
32 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
33 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
34 CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
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 CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
38 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
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 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
42 CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
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 CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
46 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
47 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
48 CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
49 CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
50 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
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 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
54 CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
55 CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
56 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
57};
58
59#define SHIFT 0
60#include "cc_helper_template.h"
61#undef SHIFT
62
63#define SHIFT 1
64#include "cc_helper_template.h"
65#undef SHIFT
66
67#define SHIFT 2
68#include "cc_helper_template.h"
69#undef SHIFT
70
71#ifdef TARGET_X86_64
72
73#define SHIFT 3
74#include "cc_helper_template.h"
75#undef SHIFT
76
77#endif
78
79static int compute_all_eflags(void)
80{
81 return CC_SRC;
82}
83
84static int compute_c_eflags(void)
85{
86 return CC_SRC & CC_C;
87}
88
89uint32_t helper_cc_compute_all(int op)
90{
91 switch (op) {
92 default: /* should never happen */
93 return 0;
94
95 case CC_OP_EFLAGS:
96 return compute_all_eflags();
97
98 case CC_OP_MULB:
99 return compute_all_mulb();
100 case CC_OP_MULW:
101 return compute_all_mulw();
102 case CC_OP_MULL:
103 return compute_all_mull();
104
105 case CC_OP_ADDB:
106 return compute_all_addb();
107 case CC_OP_ADDW:
108 return compute_all_addw();
109 case CC_OP_ADDL:
110 return compute_all_addl();
111
112 case CC_OP_ADCB:
113 return compute_all_adcb();
114 case CC_OP_ADCW:
115 return compute_all_adcw();
116 case CC_OP_ADCL:
117 return compute_all_adcl();
118
119 case CC_OP_SUBB:
120 return compute_all_subb();
121 case CC_OP_SUBW:
122 return compute_all_subw();
123 case CC_OP_SUBL:
124 return compute_all_subl();
125
126 case CC_OP_SBBB:
127 return compute_all_sbbb();
128 case CC_OP_SBBW:
129 return compute_all_sbbw();
130 case CC_OP_SBBL:
131 return compute_all_sbbl();
132
133 case CC_OP_LOGICB:
134 return compute_all_logicb();
135 case CC_OP_LOGICW:
136 return compute_all_logicw();
137 case CC_OP_LOGICL:
138 return compute_all_logicl();
139
140 case CC_OP_INCB:
141 return compute_all_incb();
142 case CC_OP_INCW:
143 return compute_all_incw();
144 case CC_OP_INCL:
145 return compute_all_incl();
146
147 case CC_OP_DECB:
148 return compute_all_decb();
149 case CC_OP_DECW:
150 return compute_all_decw();
151 case CC_OP_DECL:
152 return compute_all_decl();
153
154 case CC_OP_SHLB:
155 return compute_all_shlb();
156 case CC_OP_SHLW:
157 return compute_all_shlw();
158 case CC_OP_SHLL:
159 return compute_all_shll();
160
161 case CC_OP_SARB:
162 return compute_all_sarb();
163 case CC_OP_SARW:
164 return compute_all_sarw();
165 case CC_OP_SARL:
166 return compute_all_sarl();
167
168#ifdef TARGET_X86_64
169 case CC_OP_MULQ:
170 return compute_all_mulq();
171
172 case CC_OP_ADDQ:
173 return compute_all_addq();
174
175 case CC_OP_ADCQ:
176 return compute_all_adcq();
177
178 case CC_OP_SUBQ:
179 return compute_all_subq();
180
181 case CC_OP_SBBQ:
182 return compute_all_sbbq();
183
184 case CC_OP_LOGICQ:
185 return compute_all_logicq();
186
187 case CC_OP_INCQ:
188 return compute_all_incq();
189
190 case CC_OP_DECQ:
191 return compute_all_decq();
192
193 case CC_OP_SHLQ:
194 return compute_all_shlq();
195
196 case CC_OP_SARQ:
197 return compute_all_sarq();
198#endif
199 }
200}
201
202uint32_t cpu_cc_compute_all(CPUX86State *env1, int op)
203{
204 CPUX86State *saved_env;
205 uint32_t ret;
206
207 saved_env = env;
208 env = env1;
209 ret = helper_cc_compute_all(op);
210 env = saved_env;
211 return ret;
212}
213
214uint32_t helper_cc_compute_c(int op)
215{
216 switch (op) {
217 default: /* should never happen */
218 return 0;
219
220 case CC_OP_EFLAGS:
221 return compute_c_eflags();
222
223 case CC_OP_MULB:
224 return compute_c_mull();
225 case CC_OP_MULW:
226 return compute_c_mull();
227 case CC_OP_MULL:
228 return compute_c_mull();
229
230 case CC_OP_ADDB:
231 return compute_c_addb();
232 case CC_OP_ADDW:
233 return compute_c_addw();
234 case CC_OP_ADDL:
235 return compute_c_addl();
236
237 case CC_OP_ADCB:
238 return compute_c_adcb();
239 case CC_OP_ADCW:
240 return compute_c_adcw();
241 case CC_OP_ADCL:
242 return compute_c_adcl();
243
244 case CC_OP_SUBB:
245 return compute_c_subb();
246 case CC_OP_SUBW:
247 return compute_c_subw();
248 case CC_OP_SUBL:
249 return compute_c_subl();
250
251 case CC_OP_SBBB:
252 return compute_c_sbbb();
253 case CC_OP_SBBW:
254 return compute_c_sbbw();
255 case CC_OP_SBBL:
256 return compute_c_sbbl();
257
258 case CC_OP_LOGICB:
259 return compute_c_logicb();
260 case CC_OP_LOGICW:
261 return compute_c_logicw();
262 case CC_OP_LOGICL:
263 return compute_c_logicl();
264
265 case CC_OP_INCB:
266 return compute_c_incl();
267 case CC_OP_INCW:
268 return compute_c_incl();
269 case CC_OP_INCL:
270 return compute_c_incl();
271
272 case CC_OP_DECB:
273 return compute_c_incl();
274 case CC_OP_DECW:
275 return compute_c_incl();
276 case CC_OP_DECL:
277 return compute_c_incl();
278
279 case CC_OP_SHLB:
280 return compute_c_shlb();
281 case CC_OP_SHLW:
282 return compute_c_shlw();
283 case CC_OP_SHLL:
284 return compute_c_shll();
285
286 case CC_OP_SARB:
287 return compute_c_sarl();
288 case CC_OP_SARW:
289 return compute_c_sarl();
290 case CC_OP_SARL:
291 return compute_c_sarl();
292
293#ifdef TARGET_X86_64
294 case CC_OP_MULQ:
295 return compute_c_mull();
296
297 case CC_OP_ADDQ:
298 return compute_c_addq();
299
300 case CC_OP_ADCQ:
301 return compute_c_adcq();
302
303 case CC_OP_SUBQ:
304 return compute_c_subq();
305
306 case CC_OP_SBBQ:
307 return compute_c_sbbq();
308
309 case CC_OP_LOGICQ:
310 return compute_c_logicq();
311
312 case CC_OP_INCQ:
313 return compute_c_incl();
314
315 case CC_OP_DECQ:
316 return compute_c_incl();
317
318 case CC_OP_SHLQ:
319 return compute_c_shlq();
320
321 case CC_OP_SARQ:
322 return compute_c_sarl();
323#endif
324 }
325}
326
327void helper_write_eflags(target_ulong t0, uint32_t update_mask)
328{
329 cpu_load_eflags(env, t0, update_mask);
330}
331
332target_ulong helper_read_eflags(void)
333{
334 uint32_t eflags;
335
336 eflags = helper_cc_compute_all(CC_OP);
337 eflags |= (DF & DF_MASK);
338 eflags |= env->eflags & ~(VM_MASK | RF_MASK);
339 return eflags;
340}
341
342void helper_clts(void)
343{
344 env->cr[0] &= ~CR0_TS_MASK;
345 env->hflags &= ~HF_TS_MASK;
346}
347
348void helper_reset_rf(void)
349{
350 env->eflags &= ~RF_MASK;
351}
352
353void helper_cli(void)
354{
355 env->eflags &= ~IF_MASK;
356}
357
358void helper_sti(void)
359{
360 env->eflags |= IF_MASK;
361}
362
363#if 0
364/* vm86plus instructions */
365void helper_cli_vm(void)
366{
367 env->eflags &= ~VIF_MASK;
368}
369
370void helper_sti_vm(void)
371{
372 env->eflags |= VIF_MASK;
373 if (env->eflags & VIP_MASK) {
374 raise_exception(env, EXCP0D_GPF);
375 }
376}
377#endif
378
379void helper_set_inhibit_irq(void)
380{
381 env->hflags |= HF_INHIBIT_IRQ_MASK;
382}
383
384void helper_reset_inhibit_irq(void)
385{
386 env->hflags &= ~HF_INHIBIT_IRQ_MASK;
387}