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 /* multiple size ops */
131 #include "ops_template.h"
135 #include "ops_template.h"
139 #include "ops_template.h"
145 #include "ops_template.h"
150 /* segment handling */
152 /* faster VM86 version */
153 void OPPROTO op_movl_seg_T0_vm(void)
158 selector = T0 & 0xffff;
159 /* env->segs[] access */
160 sc = (SegmentCache *)((char *)env + PARAM1);
161 sc->selector = selector;
162 sc->base = (selector << 4);
165 void OPPROTO op_movl_T0_seg(void)
167 T0 = env->segs[PARAM1].selector;
170 void OPPROTO op_arpl(void)
172 if ((T0 & 3) < (T1 & 3)) {
173 /* XXX: emulate bug or 0xff3f0000 oring as in bochs ? */
174 T0 = (T0 & ~3) | (T1 & 3);
182 void OPPROTO op_arpl_update(void)
185 eflags = cc_table[CC_OP].compute_all();
186 CC_SRC = (eflags & ~CC_Z) | T1;
189 void OPPROTO op_movl_T0_env(void)
191 T0 = *(uint32_t *)((char *)env + PARAM1);
194 void OPPROTO op_movl_env_T0(void)
196 *(uint32_t *)((char *)env + PARAM1) = T0;
199 void OPPROTO op_movl_env_T1(void)
201 *(uint32_t *)((char *)env + PARAM1) = T1;
204 void OPPROTO op_movtl_T0_env(void)
206 T0 = *(target_ulong *)((char *)env + PARAM1);
209 void OPPROTO op_movtl_env_T0(void)
211 *(target_ulong *)((char *)env + PARAM1) = T0;
214 void OPPROTO op_movtl_T1_env(void)
216 T1 = *(target_ulong *)((char *)env + PARAM1);
219 void OPPROTO op_movtl_env_T1(void)
221 *(target_ulong *)((char *)env + PARAM1) = T1;
226 void OPPROTO op_jmp_label(void)
231 void OPPROTO op_jnz_T0_label(void)
238 /* slow set cases (compute x86 flags) */
239 void OPPROTO op_seto_T0_cc(void)
242 eflags = cc_table[CC_OP].compute_all();
243 T0 = (eflags >> 11) & 1;
246 void OPPROTO op_setb_T0_cc(void)
248 T0 = cc_table[CC_OP].compute_c();
251 void OPPROTO op_setz_T0_cc(void)
254 eflags = cc_table[CC_OP].compute_all();
255 T0 = (eflags >> 6) & 1;
258 void OPPROTO op_setbe_T0_cc(void)
261 eflags = cc_table[CC_OP].compute_all();
262 T0 = (eflags & (CC_Z | CC_C)) != 0;
265 void OPPROTO op_sets_T0_cc(void)
268 eflags = cc_table[CC_OP].compute_all();
269 T0 = (eflags >> 7) & 1;
272 void OPPROTO op_setp_T0_cc(void)
275 eflags = cc_table[CC_OP].compute_all();
276 T0 = (eflags >> 2) & 1;
279 void OPPROTO op_setl_T0_cc(void)
282 eflags = cc_table[CC_OP].compute_all();
283 T0 = ((eflags ^ (eflags >> 4)) >> 7) & 1;
286 void OPPROTO op_setle_T0_cc(void)
289 eflags = cc_table[CC_OP].compute_all();
290 T0 = (((eflags ^ (eflags >> 4)) & 0x80) || (eflags & CC_Z)) != 0;
293 void OPPROTO op_xor_T0_1(void)
298 /* XXX: clear VIF/VIP in all ops ? */
300 void OPPROTO op_movl_eflags_T0(void)
302 load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK));
305 void OPPROTO op_movw_eflags_T0(void)
307 load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK) & 0xffff);
310 void OPPROTO op_movl_eflags_T0_io(void)
312 load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK));
315 void OPPROTO op_movw_eflags_T0_io(void)
317 load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK) & 0xffff);
320 void OPPROTO op_movl_eflags_T0_cpl0(void)
322 load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK));
325 void OPPROTO op_movw_eflags_T0_cpl0(void)
327 load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK) & 0xffff);
331 /* vm86plus version */
332 void OPPROTO op_movw_eflags_T0_vm(void)
336 CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
337 DF = 1 - (2 * ((eflags >> 10) & 1));
338 /* we also update some system flags as in user mode */
339 env->eflags = (env->eflags & ~(FL_UPDATE_MASK16 | VIF_MASK)) |
340 (eflags & FL_UPDATE_MASK16);
341 if (eflags & IF_MASK) {
342 env->eflags |= VIF_MASK;
343 if (env->eflags & VIP_MASK) {
345 raise_exception(EXCP0D_GPF);
351 void OPPROTO op_movl_eflags_T0_vm(void)
355 CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
356 DF = 1 - (2 * ((eflags >> 10) & 1));
357 /* we also update some system flags as in user mode */
358 env->eflags = (env->eflags & ~(FL_UPDATE_MASK32 | VIF_MASK)) |
359 (eflags & FL_UPDATE_MASK32);
360 if (eflags & IF_MASK) {
361 env->eflags |= VIF_MASK;
362 if (env->eflags & VIP_MASK) {
364 raise_exception(EXCP0D_GPF);
371 /* XXX: compute only O flag */
372 void OPPROTO op_movb_eflags_T0(void)
375 of = cc_table[CC_OP].compute_all() & CC_O;
376 CC_SRC = (T0 & (CC_S | CC_Z | CC_A | CC_P | CC_C)) | of;
379 void OPPROTO op_movl_T0_eflags(void)
382 eflags = cc_table[CC_OP].compute_all();
383 eflags |= (DF & DF_MASK);
384 eflags |= env->eflags & ~(VM_MASK | RF_MASK);
388 /* vm86plus version */
390 void OPPROTO op_movl_T0_eflags_vm(void)
393 eflags = cc_table[CC_OP].compute_all();
394 eflags |= (DF & DF_MASK);
395 eflags |= env->eflags & ~(VM_MASK | RF_MASK | IF_MASK);
396 if (env->eflags & VIF_MASK)
402 void OPPROTO op_clc(void)
405 eflags = cc_table[CC_OP].compute_all();
410 void OPPROTO op_stc(void)
413 eflags = cc_table[CC_OP].compute_all();
418 void OPPROTO op_cmc(void)
421 eflags = cc_table[CC_OP].compute_all();
426 void OPPROTO op_salc(void)
429 cf = cc_table[CC_OP].compute_c();
430 EAX = (EAX & ~0xff) | ((-cf) & 0xff);