]> Git Repo - qemu.git/blob - target-i386/cc_helper.c
x86: split off condition code helpers
[qemu.git] / target-i386 / cc_helper.c
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
24 const 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
79 static int compute_all_eflags(void)
80 {
81     return CC_SRC;
82 }
83
84 static int compute_c_eflags(void)
85 {
86     return CC_SRC & CC_C;
87 }
88
89 uint32_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
202 uint32_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
214 uint32_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
327 void helper_write_eflags(target_ulong t0, uint32_t update_mask)
328 {
329     cpu_load_eflags(env, t0, update_mask);
330 }
331
332 target_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
342 void helper_clts(void)
343 {
344     env->cr[0] &= ~CR0_TS_MASK;
345     env->hflags &= ~HF_TS_MASK;
346 }
347
348 void helper_reset_rf(void)
349 {
350     env->eflags &= ~RF_MASK;
351 }
352
353 void helper_cli(void)
354 {
355     env->eflags &= ~IF_MASK;
356 }
357
358 void helper_sti(void)
359 {
360     env->eflags |= IF_MASK;
361 }
362
363 #if 0
364 /* vm86plus instructions */
365 void helper_cli_vm(void)
366 {
367     env->eflags &= ~VIF_MASK;
368 }
369
370 void 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
379 void helper_set_inhibit_irq(void)
380 {
381     env->hflags |= HF_INHIBIT_IRQ_MASK;
382 }
383
384 void helper_reset_inhibit_irq(void)
385 {
386     env->hflags &= ~HF_INHIBIT_IRQ_MASK;
387 }
This page took 0.042006 seconds and 4 git commands to generate.