scsi-disk: support toggling the write cache
[qemu/opensuse.git] / target-i386 / cc_helper.c
blobff654bc5edab7d5a7819ea4f1dde09ca5ca0edbd
1 /*
2 * x86 condition code helpers
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 "cpu.h"
21 #include "dyngen-exec.h"
22 #include "helper.h"
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,
59 #define SHIFT 0
60 #include "cc_helper_template.h"
61 #undef SHIFT
63 #define SHIFT 1
64 #include "cc_helper_template.h"
65 #undef SHIFT
67 #define SHIFT 2
68 #include "cc_helper_template.h"
69 #undef SHIFT
71 #ifdef TARGET_X86_64
73 #define SHIFT 3
74 #include "cc_helper_template.h"
75 #undef SHIFT
77 #endif
79 static int compute_all_eflags(void)
81 return CC_SRC;
84 static int compute_c_eflags(void)
86 return CC_SRC & CC_C;
89 uint32_t helper_cc_compute_all(int op)
91 switch (op) {
92 default: /* should never happen */
93 return 0;
95 case CC_OP_EFLAGS:
96 return compute_all_eflags();
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();
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();
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();
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();
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();
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();
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();
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();
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();
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();
168 #ifdef TARGET_X86_64
169 case CC_OP_MULQ:
170 return compute_all_mulq();
172 case CC_OP_ADDQ:
173 return compute_all_addq();
175 case CC_OP_ADCQ:
176 return compute_all_adcq();
178 case CC_OP_SUBQ:
179 return compute_all_subq();
181 case CC_OP_SBBQ:
182 return compute_all_sbbq();
184 case CC_OP_LOGICQ:
185 return compute_all_logicq();
187 case CC_OP_INCQ:
188 return compute_all_incq();
190 case CC_OP_DECQ:
191 return compute_all_decq();
193 case CC_OP_SHLQ:
194 return compute_all_shlq();
196 case CC_OP_SARQ:
197 return compute_all_sarq();
198 #endif
202 uint32_t cpu_cc_compute_all(CPUX86State *env1, int op)
204 CPUX86State *saved_env;
205 uint32_t ret;
207 saved_env = env;
208 env = env1;
209 ret = helper_cc_compute_all(op);
210 env = saved_env;
211 return ret;
214 uint32_t helper_cc_compute_c(int op)
216 switch (op) {
217 default: /* should never happen */
218 return 0;
220 case CC_OP_EFLAGS:
221 return compute_c_eflags();
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();
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();
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();
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();
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();
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();
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();
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();
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();
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();
293 #ifdef TARGET_X86_64
294 case CC_OP_MULQ:
295 return compute_c_mull();
297 case CC_OP_ADDQ:
298 return compute_c_addq();
300 case CC_OP_ADCQ:
301 return compute_c_adcq();
303 case CC_OP_SUBQ:
304 return compute_c_subq();
306 case CC_OP_SBBQ:
307 return compute_c_sbbq();
309 case CC_OP_LOGICQ:
310 return compute_c_logicq();
312 case CC_OP_INCQ:
313 return compute_c_incl();
315 case CC_OP_DECQ:
316 return compute_c_incl();
318 case CC_OP_SHLQ:
319 return compute_c_shlq();
321 case CC_OP_SARQ:
322 return compute_c_sarl();
323 #endif
327 void helper_write_eflags(target_ulong t0, uint32_t update_mask)
329 cpu_load_eflags(env, t0, update_mask);
332 target_ulong helper_read_eflags(void)
334 uint32_t eflags;
336 eflags = helper_cc_compute_all(CC_OP);
337 eflags |= (DF & DF_MASK);
338 eflags |= env->eflags & ~(VM_MASK | RF_MASK);
339 return eflags;
342 void helper_clts(void)
344 env->cr[0] &= ~CR0_TS_MASK;
345 env->hflags &= ~HF_TS_MASK;
348 void helper_reset_rf(void)
350 env->eflags &= ~RF_MASK;
353 void helper_cli(void)
355 env->eflags &= ~IF_MASK;
358 void helper_sti(void)
360 env->eflags |= IF_MASK;
363 #if 0
364 /* vm86plus instructions */
365 void helper_cli_vm(void)
367 env->eflags &= ~VIF_MASK;
370 void helper_sti_vm(void)
372 env->eflags |= VIF_MASK;
373 if (env->eflags & VIP_MASK) {
374 raise_exception(env, EXCP0D_GPF);
377 #endif
379 void helper_set_inhibit_irq(void)
381 env->hflags |= HF_INHIBIT_IRQ_MASK;
384 void helper_reset_inhibit_irq(void)
386 env->hflags &= ~HF_INHIBIT_IRQ_MASK;