2 * i386 micro operations
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, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 /* we define the various pieces of code used by the JIT */
28 #include "opreg_template.h"
34 #include "opreg_template.h"
40 #include "opreg_template.h"
46 #include "opreg_template.h"
52 #include "opreg_template.h"
58 #include "opreg_template.h"
64 #include "opreg_template.h"
70 #include "opreg_template.h"
76 #define REG (env->regs[8])
78 #include "opreg_template.h"
82 #define REG (env->regs[9])
84 #include "opreg_template.h"
88 #define REG (env->regs[10])
90 #include "opreg_template.h"
94 #define REG (env->regs[11])
96 #include "opreg_template.h"
100 #define REG (env->regs[12])
102 #include "opreg_template.h"
106 #define REG (env->regs[13])
108 #include "opreg_template.h"
112 #define REG (env->regs[14])
114 #include "opreg_template.h"
118 #define REG (env->regs[15])
120 #include "opreg_template.h"
126 /* constant load & misc op */
128 /* XXX: consistent names */
129 void OPPROTO op_into(void)
132 eflags = cc_table[CC_OP].compute_all();
134 raise_interrupt(EXCP04_INTO, 1, 0, PARAM1);
139 void OPPROTO op_cmpxchg8b(void)
141 helper_cmpxchg8b(A0);
144 /* multiple size ops */
149 #include "ops_template.h"
153 #include "ops_template.h"
157 #include "ops_template.h"
163 #include "ops_template.h"
170 void OPPROTO op_aam(void)
175 void OPPROTO op_aad(void)
180 void OPPROTO op_aaa(void)
185 void OPPROTO op_aas(void)
190 void OPPROTO op_daa(void)
195 void OPPROTO op_das(void)
200 /* segment handling */
202 /* faster VM86 version */
203 void OPPROTO op_movl_seg_T0_vm(void)
208 selector = T0 & 0xffff;
209 /* env->segs[] access */
210 sc = (SegmentCache *)((char *)env + PARAM1);
211 sc->selector = selector;
212 sc->base = (selector << 4);
215 void OPPROTO op_movl_T0_seg(void)
217 T0 = env->segs[PARAM1].selector;
220 void OPPROTO op_lsl(void)
223 val = helper_lsl(T0);
229 void OPPROTO op_lar(void)
232 val = helper_lar(T0);
238 void OPPROTO op_verr(void)
243 void OPPROTO op_verw(void)
248 void OPPROTO op_arpl(void)
250 if ((T0 & 3) < (T1 & 3)) {
251 /* XXX: emulate bug or 0xff3f0000 oring as in bochs ? */
252 T0 = (T0 & ~3) | (T1 & 3);
260 void OPPROTO op_arpl_update(void)
263 eflags = cc_table[CC_OP].compute_all();
264 CC_SRC = (eflags & ~CC_Z) | T1;
267 void OPPROTO op_movl_T0_env(void)
269 T0 = *(uint32_t *)((char *)env + PARAM1);
272 void OPPROTO op_movl_env_T0(void)
274 *(uint32_t *)((char *)env + PARAM1) = T0;
277 void OPPROTO op_movl_env_T1(void)
279 *(uint32_t *)((char *)env + PARAM1) = T1;
282 void OPPROTO op_movtl_T0_env(void)
284 T0 = *(target_ulong *)((char *)env + PARAM1);
287 void OPPROTO op_movtl_env_T0(void)
289 *(target_ulong *)((char *)env + PARAM1) = T0;
292 void OPPROTO op_movtl_T1_env(void)
294 T1 = *(target_ulong *)((char *)env + PARAM1);
297 void OPPROTO op_movtl_env_T1(void)
299 *(target_ulong *)((char *)env + PARAM1) = T1;
304 void OPPROTO op_jmp_label(void)
309 void OPPROTO op_jnz_T0_label(void)
316 /* slow set cases (compute x86 flags) */
317 void OPPROTO op_seto_T0_cc(void)
320 eflags = cc_table[CC_OP].compute_all();
321 T0 = (eflags >> 11) & 1;
324 void OPPROTO op_setb_T0_cc(void)
326 T0 = cc_table[CC_OP].compute_c();
329 void OPPROTO op_setz_T0_cc(void)
332 eflags = cc_table[CC_OP].compute_all();
333 T0 = (eflags >> 6) & 1;
336 void OPPROTO op_setbe_T0_cc(void)
339 eflags = cc_table[CC_OP].compute_all();
340 T0 = (eflags & (CC_Z | CC_C)) != 0;
343 void OPPROTO op_sets_T0_cc(void)
346 eflags = cc_table[CC_OP].compute_all();
347 T0 = (eflags >> 7) & 1;
350 void OPPROTO op_setp_T0_cc(void)
353 eflags = cc_table[CC_OP].compute_all();
354 T0 = (eflags >> 2) & 1;
357 void OPPROTO op_setl_T0_cc(void)
360 eflags = cc_table[CC_OP].compute_all();
361 T0 = ((eflags ^ (eflags >> 4)) >> 7) & 1;
364 void OPPROTO op_setle_T0_cc(void)
367 eflags = cc_table[CC_OP].compute_all();
368 T0 = (((eflags ^ (eflags >> 4)) & 0x80) || (eflags & CC_Z)) != 0;
371 void OPPROTO op_xor_T0_1(void)
376 /* XXX: clear VIF/VIP in all ops ? */
378 void OPPROTO op_movl_eflags_T0(void)
380 load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK));
383 void OPPROTO op_movw_eflags_T0(void)
385 load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK) & 0xffff);
388 void OPPROTO op_movl_eflags_T0_io(void)
390 load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK));
393 void OPPROTO op_movw_eflags_T0_io(void)
395 load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK) & 0xffff);
398 void OPPROTO op_movl_eflags_T0_cpl0(void)
400 load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK));
403 void OPPROTO op_movw_eflags_T0_cpl0(void)
405 load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK) & 0xffff);
409 /* vm86plus version */
410 void OPPROTO op_movw_eflags_T0_vm(void)
414 CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
415 DF = 1 - (2 * ((eflags >> 10) & 1));
416 /* we also update some system flags as in user mode */
417 env->eflags = (env->eflags & ~(FL_UPDATE_MASK16 | VIF_MASK)) |
418 (eflags & FL_UPDATE_MASK16);
419 if (eflags & IF_MASK) {
420 env->eflags |= VIF_MASK;
421 if (env->eflags & VIP_MASK) {
423 raise_exception(EXCP0D_GPF);
429 void OPPROTO op_movl_eflags_T0_vm(void)
433 CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
434 DF = 1 - (2 * ((eflags >> 10) & 1));
435 /* we also update some system flags as in user mode */
436 env->eflags = (env->eflags & ~(FL_UPDATE_MASK32 | VIF_MASK)) |
437 (eflags & FL_UPDATE_MASK32);
438 if (eflags & IF_MASK) {
439 env->eflags |= VIF_MASK;
440 if (env->eflags & VIP_MASK) {
442 raise_exception(EXCP0D_GPF);
449 /* XXX: compute only O flag */
450 void OPPROTO op_movb_eflags_T0(void)
453 of = cc_table[CC_OP].compute_all() & CC_O;
454 CC_SRC = (T0 & (CC_S | CC_Z | CC_A | CC_P | CC_C)) | of;
457 void OPPROTO op_movl_T0_eflags(void)
460 eflags = cc_table[CC_OP].compute_all();
461 eflags |= (DF & DF_MASK);
462 eflags |= env->eflags & ~(VM_MASK | RF_MASK);
466 /* vm86plus version */
468 void OPPROTO op_movl_T0_eflags_vm(void)
471 eflags = cc_table[CC_OP].compute_all();
472 eflags |= (DF & DF_MASK);
473 eflags |= env->eflags & ~(VM_MASK | RF_MASK | IF_MASK);
474 if (env->eflags & VIF_MASK)
480 void OPPROTO op_clc(void)
483 eflags = cc_table[CC_OP].compute_all();
488 void OPPROTO op_stc(void)
491 eflags = cc_table[CC_OP].compute_all();
496 void OPPROTO op_cmc(void)
499 eflags = cc_table[CC_OP].compute_all();
504 void OPPROTO op_salc(void)
507 cf = cc_table[CC_OP].compute_c();
508 EAX = (EAX & ~0xff) | ((-cf) & 0xff);
511 void OPPROTO op_fcomi_dummy(void)
517 void OPPROTO op_com_dummy(void)