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