1 /////////////////////////////////////////////////////////////////////////
2 // $Id: lazy_flags.cc,v 1.34 2007/03/18 19:29:17 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
5 // Copyright (C) 2001 MandrakeSoft S.A.
9 // 75002 Paris - France
10 // http://www.linux-mandrake.com/
11 // http://www.mandrakesoft.com/
13 // This library is free software; you can redistribute it and/or
14 // modify it under the terms of the GNU Lesser General Public
15 // License as published by the Free Software Foundation; either
16 // version 2 of the License, or (at your option) any later version.
18 // This library is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 // Lesser General Public License for more details.
23 // You should have received a copy of the GNU Lesser General Public
24 // License along with this library; if not, write to the Free Software
25 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 /////////////////////////////////////////////////////////////////////////
29 #define NEED_CPU_REG_SHORTCUTS 1
32 #define LOG_THIS BX_CPU_THIS_PTR
35 // This array defines a look-up table for the even parity-ness
36 // of an 8bit quantity, for optimal assignment of the parity bit
37 // in the EFLAGS register
38 const bx_bool bx_parity_lookup
[256] = {
39 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
40 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
41 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
42 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
43 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
44 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
45 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
46 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
47 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
48 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
49 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
50 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
51 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
52 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
53 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
54 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
57 bx_bool
BX_CPU_C::get_CFLazy(void)
61 BX_ASSERT((BX_CPU_THIS_PTR lf_flags_status
& 0x00000f) == BX_LF_INDEX_OSZAPC
);
63 switch (BX_CPU_THIS_PTR oszapc
.instr
) {
65 cf
= (BX_CPU_THIS_PTR oszapc
.result_8
<
66 BX_CPU_THIS_PTR oszapc
.op1_8
);
69 cf
= (BX_CPU_THIS_PTR oszapc
.result_16
<
70 BX_CPU_THIS_PTR oszapc
.op1_16
);
73 cf
= (BX_CPU_THIS_PTR oszapc
.result_32
<
74 BX_CPU_THIS_PTR oszapc
.op1_32
);
78 cf
= (BX_CPU_THIS_PTR oszapc
.result_64
<
79 BX_CPU_THIS_PTR oszapc
.op1_64
);
82 // used only if CF = 1 when executing ADC instruction
84 cf
= (BX_CPU_THIS_PTR oszapc
.result_8
<=
85 BX_CPU_THIS_PTR oszapc
.op1_8
);
87 // used only if CF = 1 when executing ADC instruction
89 cf
= (BX_CPU_THIS_PTR oszapc
.result_16
<=
90 BX_CPU_THIS_PTR oszapc
.op1_16
);
92 // used only if CF = 1 when executing ADC instruction
94 cf
= (BX_CPU_THIS_PTR oszapc
.result_32
<=
95 BX_CPU_THIS_PTR oszapc
.op1_32
);
98 // used only if CF = 1 when executing ADC instruction
100 cf
= (BX_CPU_THIS_PTR oszapc
.result_64
<=
101 BX_CPU_THIS_PTR oszapc
.op1_64
);
105 cf
= (BX_CPU_THIS_PTR oszapc
.op1_8
<
106 BX_CPU_THIS_PTR oszapc
.op2_8
);
109 cf
= (BX_CPU_THIS_PTR oszapc
.op1_16
<
110 BX_CPU_THIS_PTR oszapc
.op2_16
);
113 cf
= (BX_CPU_THIS_PTR oszapc
.op1_32
<
114 BX_CPU_THIS_PTR oszapc
.op2_32
);
116 #if BX_SUPPORT_X86_64
118 cf
= (BX_CPU_THIS_PTR oszapc
.op1_64
<
119 BX_CPU_THIS_PTR oszapc
.op2_64
);
122 // used only if CF = 1 when executing SBB instruction
124 cf
= (BX_CPU_THIS_PTR oszapc
.op1_8
< BX_CPU_THIS_PTR oszapc
.result_8
) ||
125 (BX_CPU_THIS_PTR oszapc
.op2_8
==0xff);
127 // used only if CF = 1 when executing SBB instruction
129 cf
= (BX_CPU_THIS_PTR oszapc
.op1_16
< BX_CPU_THIS_PTR oszapc
.result_16
) ||
130 (BX_CPU_THIS_PTR oszapc
.op2_16
==0xffff);
132 // used only if CF = 1 when executing SBB instruction
134 cf
= (BX_CPU_THIS_PTR oszapc
.op1_32
< BX_CPU_THIS_PTR oszapc
.result_32
) ||
135 (BX_CPU_THIS_PTR oszapc
.op2_32
==0xffffffff);
137 #if BX_SUPPORT_X86_64
138 // used only if CF = 1 when executing SBB instruction
140 cf
= (BX_CPU_THIS_PTR oszapc
.op1_64
< BX_CPU_THIS_PTR oszapc
.result_64
) ||
141 (BX_CPU_THIS_PTR oszapc
.op2_64
==BX_CONST64(0xffffffffffffffff));
145 cf
= (BX_CPU_THIS_PTR oszapc
.result_8
!= 0);
148 cf
= (BX_CPU_THIS_PTR oszapc
.result_16
!= 0);
151 cf
= (BX_CPU_THIS_PTR oszapc
.result_32
!= 0);
153 #if BX_SUPPORT_X86_64
155 cf
= (BX_CPU_THIS_PTR oszapc
.result_64
!= 0);
158 case BX_INSTR_LOGIC8
:
159 case BX_INSTR_LOGIC16
:
160 case BX_INSTR_LOGIC32
:
161 case BX_INSTR_BITSCAN16
:
162 case BX_INSTR_BITSCAN32
:
163 #if BX_SUPPORT_X86_64
164 case BX_INSTR_LOGIC64
:
165 case BX_INSTR_BITSCAN64
:
170 if (BX_CPU_THIS_PTR oszapc
.op2_8
< 8) {
171 cf
= (BX_CPU_THIS_PTR oszapc
.op1_8
>>
172 (BX_CPU_THIS_PTR oszapc
.op2_8
- 1)) & 0x01;
175 cf
= (BX_CPU_THIS_PTR oszapc
.op1_8
& 0x80) > 0;
179 cf
= (BX_CPU_THIS_PTR oszapc
.op1_8
>>
180 (BX_CPU_THIS_PTR oszapc
.op2_8
- 1)) & 0x01;
183 if (BX_CPU_THIS_PTR oszapc
.op2_16
< 16) {
184 cf
= (BX_CPU_THIS_PTR oszapc
.op1_16
>>
185 (BX_CPU_THIS_PTR oszapc
.op2_16
- 1)) & 0x01;
188 cf
= (BX_CPU_THIS_PTR oszapc
.op1_16
& 0x8000) > 0;
192 case BX_INSTR_SHRD16
:
193 cf
= (BX_CPU_THIS_PTR oszapc
.op1_16
>>
194 (BX_CPU_THIS_PTR oszapc
.op2_16
- 1)) & 0x01;
198 case BX_INSTR_SHRD32
:
199 cf
= (BX_CPU_THIS_PTR oszapc
.op1_32
>>
200 (BX_CPU_THIS_PTR oszapc
.op2_32
- 1)) & 0x01;
202 #if BX_SUPPORT_X86_64
205 case BX_INSTR_SHRD64
:
206 cf
= (BX_CPU_THIS_PTR oszapc
.op1_64
>>
207 (BX_CPU_THIS_PTR oszapc
.op2_64
- 1)) & 0x01;
211 if (BX_CPU_THIS_PTR oszapc
.op2_8
<= 8) {
212 cf
= (BX_CPU_THIS_PTR oszapc
.op1_8
>>
213 (8 - BX_CPU_THIS_PTR oszapc
.op2_8
)) & 0x01;
220 if (BX_CPU_THIS_PTR oszapc
.op2_16
<= 16) {
221 cf
= (BX_CPU_THIS_PTR oszapc
.op1_16
>>
222 (16 - BX_CPU_THIS_PTR oszapc
.op2_16
)) & 0x01;
229 cf
= (BX_CPU_THIS_PTR oszapc
.op1_32
>>
230 (32 - BX_CPU_THIS_PTR oszapc
.op2_32
)) & 0x01;
232 #if BX_SUPPORT_X86_64
234 cf
= (BX_CPU_THIS_PTR oszapc
.op1_64
>>
235 (64 - BX_CPU_THIS_PTR oszapc
.op2_64
)) & 0x01;
239 cf
= ! ((BX_CPU_THIS_PTR oszapc
.op1_8
< 0x80 &&
240 BX_CPU_THIS_PTR oszapc
.op2_8
== 0) ||
241 ((BX_CPU_THIS_PTR oszapc
.op1_8
& 0x80) &&
242 BX_CPU_THIS_PTR oszapc
.op2_8
== 0xff));
244 case BX_INSTR_IMUL16
:
245 cf
= ! ((BX_CPU_THIS_PTR oszapc
.op1_16
< 0x8000 &&
246 BX_CPU_THIS_PTR oszapc
.op2_16
== 0) ||
247 ((BX_CPU_THIS_PTR oszapc
.op1_16
& 0x8000) &&
248 BX_CPU_THIS_PTR oszapc
.op2_16
== 0xffff));
250 case BX_INSTR_IMUL32
:
251 cf
= ! ((BX_CPU_THIS_PTR oszapc
.op1_32
< 0x80000000 &&
252 BX_CPU_THIS_PTR oszapc
.op2_32
== 0) ||
253 ((BX_CPU_THIS_PTR oszapc
.op1_32
& 0x80000000) &&
254 BX_CPU_THIS_PTR oszapc
.op2_32
== 0xffffffff));
256 #if BX_SUPPORT_X86_64
257 case BX_INSTR_IMUL64
:
258 cf
= ! ((BX_CPU_THIS_PTR oszapc
.op1_64
< BX_CONST64(0x8000000000000000) &&
259 BX_CPU_THIS_PTR oszapc
.op2_64
== 0) ||
260 ((BX_CPU_THIS_PTR oszapc
.op1_64
& BX_CONST64(0x8000000000000000)) &&
261 BX_CPU_THIS_PTR oszapc
.op2_64
== BX_CONST64(0xffffffffffffffff)));
265 cf
= (BX_CPU_THIS_PTR oszapc
.op2_8
!= 0);
268 cf
= (BX_CPU_THIS_PTR oszapc
.op2_16
!= 0);
271 cf
= (BX_CPU_THIS_PTR oszapc
.op2_32
!= 0);
273 #if BX_SUPPORT_X86_64
275 cf
= (BX_CPU_THIS_PTR oszapc
.op2_64
!= 0);
279 cf
= 0; // Keep compiler quiet.
280 BX_PANIC(("get_CF: OSZAPC: unknown instr %u",
281 (unsigned) BX_CPU_THIS_PTR oszapc
.instr
));
284 BX_CPU_THIS_PTR lf_flags_status
&= 0xfffff0;
285 BX_CPU_THIS_PTR eflags
.val32
&= ~(1<<0);
286 BX_CPU_THIS_PTR eflags
.val32
|= (!!cf
)<<0;
290 bx_bool
BX_CPU_C::get_AFLazy(void)
294 switch ((BX_CPU_THIS_PTR lf_flags_status
>>8) & 0x00000f) {
295 case BX_LF_INDEX_OSZAPC
:
296 switch (BX_CPU_THIS_PTR oszapc
.instr
) {
302 ((BX_CPU_THIS_PTR oszapc
.op1_8
^
303 BX_CPU_THIS_PTR oszapc
.op2_8
) ^
304 BX_CPU_THIS_PTR oszapc
.result_8
) & 0x10;
311 ((BX_CPU_THIS_PTR oszapc
.op1_16
^
312 BX_CPU_THIS_PTR oszapc
.op2_16
) ^
313 BX_CPU_THIS_PTR oszapc
.result_16
) & 0x10;
320 ((BX_CPU_THIS_PTR oszapc
.op1_32
^
321 BX_CPU_THIS_PTR oszapc
.op2_32
) ^
322 BX_CPU_THIS_PTR oszapc
.result_32
) & 0x10;
324 #if BX_SUPPORT_X86_64
330 ((BX_CPU_THIS_PTR oszapc
.op1_64
^
331 BX_CPU_THIS_PTR oszapc
.op2_64
) ^
332 BX_CPU_THIS_PTR oszapc
.result_64
) & 0x10;
336 af
= (BX_CPU_THIS_PTR oszapc
.result_8
& 0x0f) != 0;
339 af
= (BX_CPU_THIS_PTR oszapc
.result_16
& 0x0f) != 0;
342 af
= (BX_CPU_THIS_PTR oszapc
.result_32
& 0x0f) != 0;
344 #if BX_SUPPORT_X86_64
346 af
= (BX_CPU_THIS_PTR oszapc
.result_64
& 0x0f) != 0;
349 case BX_INSTR_LOGIC8
:
350 case BX_INSTR_LOGIC16
:
351 case BX_INSTR_LOGIC32
:
352 case BX_INSTR_BITSCAN16
:
353 case BX_INSTR_BITSCAN32
:
354 #if BX_SUPPORT_X86_64
355 case BX_INSTR_LOGIC64
:
356 case BX_INSTR_BITSCAN64
:
359 case BX_INSTR_SHRD64
:
361 case BX_INSTR_IMUL64
:
370 case BX_INSTR_SHRD16
:
371 case BX_INSTR_SHRD32
:
376 case BX_INSTR_IMUL16
:
377 case BX_INSTR_IMUL32
:
384 af
= 0; // Keep compiler quiet.
385 BX_PANIC(("get_AF: OSZAPC: unknown instr %u",
386 (unsigned) BX_CPU_THIS_PTR oszapc
.instr
));
388 BX_CPU_THIS_PTR lf_flags_status
&= 0xfff0ff;
389 BX_CPU_THIS_PTR eflags
.val32
&= ~(1<<4);
390 BX_CPU_THIS_PTR eflags
.val32
|= (!!af
)<<4;
393 case BX_LF_INDEX_OSZAP
:
394 switch (BX_CPU_THIS_PTR oszap
.instr
) {
396 af
= (BX_CPU_THIS_PTR oszap
.result_8
& 0x0f) == 0;
399 af
= (BX_CPU_THIS_PTR oszap
.result_16
& 0x0f) == 0;
402 af
= (BX_CPU_THIS_PTR oszap
.result_32
& 0x0f) == 0;
404 #if BX_SUPPORT_X86_64
406 af
= (BX_CPU_THIS_PTR oszap
.result_64
& 0x0f) == 0;
410 af
= (BX_CPU_THIS_PTR oszap
.result_8
& 0x0f) == 0x0f;
413 af
= (BX_CPU_THIS_PTR oszap
.result_16
& 0x0f) == 0x0f;
416 af
= (BX_CPU_THIS_PTR oszap
.result_32
& 0x0f) == 0x0f;
418 #if BX_SUPPORT_X86_64
420 af
= (BX_CPU_THIS_PTR oszap
.result_64
& 0x0f) == 0x0f;
424 af
= 0; // Keep compiler quiet.
425 BX_PANIC(("get_AF: OSZAP: unknown instr %u",
426 (unsigned) BX_CPU_THIS_PTR oszap
.instr
));
428 BX_CPU_THIS_PTR lf_flags_status
&= 0xfff0ff;
429 BX_CPU_THIS_PTR eflags
.val32
&= ~(1<<4);
430 BX_CPU_THIS_PTR eflags
.val32
|= (!!af
)<<4;
434 BX_PANIC(("get_AF: unknown case"));
439 bx_bool
BX_CPU_C::get_ZFLazy(void)
443 switch ((BX_CPU_THIS_PTR lf_flags_status
>>12) & 0x00000f) {
444 case BX_LF_INDEX_OSZAPC
:
445 switch (BX_CPU_THIS_PTR oszapc
.instr
) {
446 case BX_INSTR_LOGIC8
:
455 zf
= (BX_CPU_THIS_PTR oszapc
.result_8
== 0);
457 case BX_INSTR_LOGIC16
:
465 case BX_INSTR_SHRD16
:
467 zf
= (BX_CPU_THIS_PTR oszapc
.result_16
== 0);
469 case BX_INSTR_LOGIC32
:
477 case BX_INSTR_SHRD32
:
479 zf
= (BX_CPU_THIS_PTR oszapc
.result_32
== 0);
481 #if BX_SUPPORT_X86_64
482 case BX_INSTR_LOGIC64
:
490 case BX_INSTR_SHRD64
:
492 zf
= (BX_CPU_THIS_PTR oszapc
.result_64
== 0);
497 zf
= (BX_CPU_THIS_PTR oszapc
.op1_8
== 0);
499 case BX_INSTR_IMUL16
:
501 zf
= (BX_CPU_THIS_PTR oszapc
.op1_16
== 0);
503 case BX_INSTR_IMUL32
:
505 zf
= (BX_CPU_THIS_PTR oszapc
.op1_32
== 0);
507 #if BX_SUPPORT_X86_64
508 case BX_INSTR_IMUL64
:
510 zf
= (BX_CPU_THIS_PTR oszapc
.op1_64
== 0);
513 case BX_INSTR_BITSCAN16
:
514 case BX_INSTR_BITSCAN32
:
515 #if BX_SUPPORT_X86_64
516 case BX_INSTR_BITSCAN64
:
522 BX_PANIC(("get_ZF: OSZAPC: unknown instr"));
524 BX_CPU_THIS_PTR lf_flags_status
&= 0xff0fff;
525 BX_CPU_THIS_PTR eflags
.val32
&= ~(1<<6);
526 BX_CPU_THIS_PTR eflags
.val32
|= zf
<<6; // zf always exactly 0 or 1.
529 case BX_LF_INDEX_OSZAP
:
530 switch (BX_CPU_THIS_PTR oszap
.instr
) {
533 zf
= (BX_CPU_THIS_PTR oszap
.result_8
== 0);
537 zf
= (BX_CPU_THIS_PTR oszap
.result_16
== 0);
541 zf
= (BX_CPU_THIS_PTR oszap
.result_32
== 0);
543 #if BX_SUPPORT_X86_64
546 zf
= (BX_CPU_THIS_PTR oszap
.result_64
== 0);
551 BX_PANIC(("get_ZF: OSZAP: unknown instr"));
553 BX_CPU_THIS_PTR lf_flags_status
&= 0xff0fff;
554 BX_CPU_THIS_PTR eflags
.val32
&= ~(1<<6);
555 BX_CPU_THIS_PTR eflags
.val32
|= zf
<<6; // zf always exactly 0 or 1.
559 BX_PANIC(("get_ZF: unknown case"));
564 bx_bool
BX_CPU_C::get_SFLazy(void)
568 switch ((BX_CPU_THIS_PTR lf_flags_status
>>16) & 0x00000f) {
569 case BX_LF_INDEX_OSZAPC
:
570 switch (BX_CPU_THIS_PTR oszapc
.instr
) {
571 case BX_INSTR_LOGIC8
:
580 sf
= (BX_CPU_THIS_PTR oszapc
.result_8
>= 0x80);
582 case BX_INSTR_LOGIC16
:
590 case BX_INSTR_SHRD16
:
592 case BX_INSTR_BITSCAN16
:
593 sf
= (BX_CPU_THIS_PTR oszapc
.result_16
>= 0x8000);
595 case BX_INSTR_LOGIC32
:
603 case BX_INSTR_SHRD32
:
605 case BX_INSTR_BITSCAN32
:
606 sf
= (BX_CPU_THIS_PTR oszapc
.result_32
>= 0x80000000);
608 #if BX_SUPPORT_X86_64
609 case BX_INSTR_LOGIC64
:
617 case BX_INSTR_SHRD64
:
619 case BX_INSTR_BITSCAN64
:
620 sf
= (BX_CPU_THIS_PTR oszapc
.result_64
>= BX_CONST64(0x8000000000000000));
625 sf
= (BX_CPU_THIS_PTR oszapc
.op1_8
>= 0x80);
627 case BX_INSTR_IMUL16
:
629 sf
= (BX_CPU_THIS_PTR oszapc
.op1_16
>= 0x8000);
631 case BX_INSTR_IMUL32
:
633 sf
= (BX_CPU_THIS_PTR oszapc
.op1_32
>= 0x80000000);
635 #if BX_SUPPORT_X86_64
636 case BX_INSTR_IMUL64
:
638 sf
= (BX_CPU_THIS_PTR oszapc
.op1_64
>= BX_CONST64(0x8000000000000000));
642 sf
= 0; // Keep compiler quiet.
643 BX_PANIC(("get_SF: OSZAPC: unknown instr"));
645 BX_CPU_THIS_PTR lf_flags_status
&= 0xf0ffff;
646 BX_CPU_THIS_PTR eflags
.val32
&= ~(1<<7);
647 BX_CPU_THIS_PTR eflags
.val32
|= (!!sf
)<<7;
650 case BX_LF_INDEX_OSZAP
:
651 switch (BX_CPU_THIS_PTR oszap
.instr
) {
654 sf
= (BX_CPU_THIS_PTR oszap
.result_8
>= 0x80);
658 sf
= (BX_CPU_THIS_PTR oszap
.result_16
>= 0x8000);
662 sf
= (BX_CPU_THIS_PTR oszap
.result_32
>= 0x80000000);
664 #if BX_SUPPORT_X86_64
667 sf
= (BX_CPU_THIS_PTR oszap
.result_64
>= BX_CONST64(0x8000000000000000));
671 sf
= 0; // Keep compiler quiet.
672 BX_PANIC(("get_SF: OSZAP: unknown instr"));
674 BX_CPU_THIS_PTR lf_flags_status
&= 0xf0ffff;
675 BX_CPU_THIS_PTR eflags
.val32
&= ~(1<<7);
676 BX_CPU_THIS_PTR eflags
.val32
|= (!!sf
)<<7;
680 BX_PANIC(("get_SF: unknown case"));
685 #define GET_ADD_OVERFLOW(op1, op2, result, mask) \
686 (((~((op1) ^ (op2)) & ((op2) ^ (result))) & (mask)) != 0)
688 #define GET_SUB_OVERFLOW(op1, op2, result, mask) \
689 (((((op1) ^ (op2)) & ((op1) ^ (result))) & (mask)) != 0)
691 bx_bool
BX_CPU_C::get_OFLazy(void)
695 switch ((BX_CPU_THIS_PTR lf_flags_status
>>20) & 0x00000f) {
696 case BX_LF_INDEX_OSZAPC
:
697 switch (BX_CPU_THIS_PTR oszapc
.instr
) {
700 of
= GET_ADD_OVERFLOW(BX_CPU_THIS_PTR oszapc
.op1_8
, BX_CPU_THIS_PTR oszapc
.op2_8
,
701 BX_CPU_THIS_PTR oszapc
.result_8
, 0x80);
705 of
= GET_ADD_OVERFLOW(BX_CPU_THIS_PTR oszapc
.op1_16
, BX_CPU_THIS_PTR oszapc
.op2_16
,
706 BX_CPU_THIS_PTR oszapc
.result_16
, 0x8000);
710 of
= GET_ADD_OVERFLOW(BX_CPU_THIS_PTR oszapc
.op1_32
, BX_CPU_THIS_PTR oszapc
.op2_32
,
711 BX_CPU_THIS_PTR oszapc
.result_32
, 0x80000000);
713 #if BX_SUPPORT_X86_64
716 of
= GET_ADD_OVERFLOW(BX_CPU_THIS_PTR oszapc
.op1_64
, BX_CPU_THIS_PTR oszapc
.op2_64
,
717 BX_CPU_THIS_PTR oszapc
.result_64
, BX_CONST64(0x8000000000000000));
722 of
= GET_SUB_OVERFLOW(BX_CPU_THIS_PTR oszapc
.op1_8
, BX_CPU_THIS_PTR oszapc
.op2_8
,
723 BX_CPU_THIS_PTR oszapc
.result_8
, 0x80);
727 of
= GET_SUB_OVERFLOW(BX_CPU_THIS_PTR oszapc
.op1_16
, BX_CPU_THIS_PTR oszapc
.op2_16
,
728 BX_CPU_THIS_PTR oszapc
.result_16
, 0x8000);
732 of
= GET_SUB_OVERFLOW(BX_CPU_THIS_PTR oszapc
.op1_32
, BX_CPU_THIS_PTR oszapc
.op2_32
,
733 BX_CPU_THIS_PTR oszapc
.result_32
, 0x80000000);
735 #if BX_SUPPORT_X86_64
738 of
= GET_SUB_OVERFLOW(BX_CPU_THIS_PTR oszapc
.op1_64
, BX_CPU_THIS_PTR oszapc
.op2_64
,
739 BX_CPU_THIS_PTR oszapc
.result_64
, BX_CONST64(0x8000000000000000));
743 of
= (BX_CPU_THIS_PTR oszapc
.result_8
== 0x80);
746 of
= (BX_CPU_THIS_PTR oszapc
.result_16
== 0x8000);
749 of
= (BX_CPU_THIS_PTR oszapc
.result_32
== 0x80000000);
751 #if BX_SUPPORT_X86_64
753 of
= (BX_CPU_THIS_PTR oszapc
.result_64
== BX_CONST64(0x8000000000000000));
756 case BX_INSTR_LOGIC8
:
757 case BX_INSTR_LOGIC16
:
758 case BX_INSTR_LOGIC32
:
759 case BX_INSTR_BITSCAN16
:
760 case BX_INSTR_BITSCAN32
:
764 #if BX_SUPPORT_X86_64
765 case BX_INSTR_LOGIC64
:
766 case BX_INSTR_BITSCAN64
:
772 if (BX_CPU_THIS_PTR oszapc
.op2_8
== 1)
773 of
= (BX_CPU_THIS_PTR oszapc
.op1_8
>= 0x80);
775 of
= 0; /* undocumented, but hardware really does it */
778 if (BX_CPU_THIS_PTR oszapc
.op2_16
== 1)
779 of
= (BX_CPU_THIS_PTR oszapc
.op1_16
>= 0x8000);
781 of
= 0; /* undocumented, but hardware really does it */
784 if (BX_CPU_THIS_PTR oszapc
.op2_32
== 1)
785 of
= (BX_CPU_THIS_PTR oszapc
.op1_32
>= 0x80000000);
787 of
= 0; /* undocumented, but hardware really does it */
789 #if BX_SUPPORT_X86_64
791 if (BX_CPU_THIS_PTR oszapc
.op2_64
== 1)
792 of
= (BX_CPU_THIS_PTR oszapc
.op1_64
>= BX_CONST64(0x8000000000000000));
794 of
= 0; /* undocumented, but hardware really does it */
797 case BX_INSTR_SHRD16
:
798 /* undocumented, but this formula works right for any shift count */
799 of
= (((BX_CPU_THIS_PTR oszapc
.result_16
<< 1) ^
800 BX_CPU_THIS_PTR oszapc
.result_16
) & 0x8000) > 0;
802 case BX_INSTR_SHRD32
:
803 /* undocumented, but this formula works right for any shift count */
804 of
= (((BX_CPU_THIS_PTR oszapc
.result_32
<< 1) ^
805 BX_CPU_THIS_PTR oszapc
.result_32
) & 0x80000000) > 0;
807 #if BX_SUPPORT_X86_64
808 case BX_INSTR_SHRD64
:
809 /* undocumented, but this formula works right for any shift count */
810 of
= (((BX_CPU_THIS_PTR oszapc
.result_64
<< 1) ^
811 BX_CPU_THIS_PTR oszapc
.result_64
) & BX_CONST64(0x8000000000000000)) > 0;
815 if (BX_CPU_THIS_PTR oszapc
.op2_8
== 1)
816 of
= ((BX_CPU_THIS_PTR oszapc
.op1_8
^
817 BX_CPU_THIS_PTR oszapc
.result_8
) & 0x80) > 0;
819 of
= (((BX_CPU_THIS_PTR oszapc
.op1_8
<<
820 (BX_CPU_THIS_PTR oszapc
.op2_8
- 1)) ^
821 BX_CPU_THIS_PTR oszapc
.result_8
) & 0x80) > 0;
824 if (BX_CPU_THIS_PTR oszapc
.op2_16
== 1)
825 of
= ((BX_CPU_THIS_PTR oszapc
.op1_16
^
826 BX_CPU_THIS_PTR oszapc
.result_16
) & 0x8000) > 0;
828 of
= (((BX_CPU_THIS_PTR oszapc
.op1_16
<<
829 (BX_CPU_THIS_PTR oszapc
.op2_16
- 1)) ^
830 BX_CPU_THIS_PTR oszapc
.result_16
) & 0x8000) > 0;
833 if (BX_CPU_THIS_PTR oszapc
.op2_32
== 1)
834 of
= ((BX_CPU_THIS_PTR oszapc
.op1_32
^
835 BX_CPU_THIS_PTR oszapc
.result_32
) & 0x80000000) > 0;
837 of
= (((BX_CPU_THIS_PTR oszapc
.op1_32
<<
838 (BX_CPU_THIS_PTR oszapc
.op2_32
- 1)) ^
839 BX_CPU_THIS_PTR oszapc
.result_32
) & 0x80000000) > 0;
841 #if BX_SUPPORT_X86_64
843 if (BX_CPU_THIS_PTR oszapc
.op2_64
== 1)
844 of
= ((BX_CPU_THIS_PTR oszapc
.op1_64
^
845 BX_CPU_THIS_PTR oszapc
.result_64
) & BX_CONST64(0x8000000000000000)) > 0;
847 of
= (((BX_CPU_THIS_PTR oszapc
.op1_64
<<
848 (BX_CPU_THIS_PTR oszapc
.op2_64
- 1)) ^
849 BX_CPU_THIS_PTR oszapc
.result_64
) & BX_CONST64(0x8000000000000000)) > 0;
853 of
= ! ((BX_CPU_THIS_PTR oszapc
.op1_8
< 0x80 &&
854 BX_CPU_THIS_PTR oszapc
.op2_8
== 0) ||
855 ((BX_CPU_THIS_PTR oszapc
.op1_8
& 0x80) &&
856 BX_CPU_THIS_PTR oszapc
.op2_8
== 0xff));
858 case BX_INSTR_IMUL16
:
859 of
= ! ((BX_CPU_THIS_PTR oszapc
.op1_16
< 0x8000 &&
860 BX_CPU_THIS_PTR oszapc
.op2_16
== 0) ||
861 ((BX_CPU_THIS_PTR oszapc
.op1_16
& 0x8000) &&
862 BX_CPU_THIS_PTR oszapc
.op2_16
== 0xffff));
864 case BX_INSTR_IMUL32
:
865 of
= ! ((BX_CPU_THIS_PTR oszapc
.op1_32
< 0x80000000 &&
866 BX_CPU_THIS_PTR oszapc
.op2_32
== 0) ||
867 ((BX_CPU_THIS_PTR oszapc
.op1_32
& 0x80000000) &&
868 BX_CPU_THIS_PTR oszapc
.op2_32
== 0xffffffff));
870 #if BX_SUPPORT_X86_64
871 case BX_INSTR_IMUL64
:
872 of
= ! ((BX_CPU_THIS_PTR oszapc
.op1_64
< BX_CONST64(0x8000000000000000) &&
873 BX_CPU_THIS_PTR oszapc
.op2_64
== 0) ||
874 ((BX_CPU_THIS_PTR oszapc
.op1_64
& BX_CONST64(0x8000000000000000)) &&
875 BX_CPU_THIS_PTR oszapc
.op2_64
== BX_CONST64(0xffffffffffffffff)));
879 of
= (BX_CPU_THIS_PTR oszapc
.op2_8
!= 0);
882 of
= (BX_CPU_THIS_PTR oszapc
.op2_16
!= 0);
885 of
= (BX_CPU_THIS_PTR oszapc
.op2_32
!= 0);
887 #if BX_SUPPORT_X86_64
889 of
= (BX_CPU_THIS_PTR oszapc
.op2_64
!= 0);
893 of
= 0; // Keep compiler happy.
894 BX_PANIC(("get_OF: OSZAPC: unknown instr"));
896 BX_CPU_THIS_PTR lf_flags_status
&= 0x0fffff;
897 BX_CPU_THIS_PTR eflags
.val32
&= ~(1<<11);
898 BX_CPU_THIS_PTR eflags
.val32
|= (!!of
)<<11;
901 case BX_LF_INDEX_OSZAP
:
902 switch (BX_CPU_THIS_PTR oszap
.instr
) {
904 of
= (BX_CPU_THIS_PTR oszap
.result_8
== 0x80);
907 of
= (BX_CPU_THIS_PTR oszap
.result_16
== 0x8000);
910 of
= (BX_CPU_THIS_PTR oszap
.result_32
== 0x80000000);
912 #if BX_SUPPORT_X86_64
914 of
= (BX_CPU_THIS_PTR oszap
.result_64
== BX_CONST64(0x8000000000000000));
918 of
= (BX_CPU_THIS_PTR oszap
.result_8
== 0x7F);
921 of
= (BX_CPU_THIS_PTR oszap
.result_16
== 0x7FFF);
924 of
= (BX_CPU_THIS_PTR oszap
.result_32
== 0x7FFFFFFF);
926 #if BX_SUPPORT_X86_64
928 of
= (BX_CPU_THIS_PTR oszap
.result_64
== BX_CONST64(0x7FFFFFFFFFFFFFFF));
932 of
= 0; // Keep compiler happy.
933 BX_PANIC(("get_OF: OSZAP: unknown instr"));
935 BX_CPU_THIS_PTR lf_flags_status
&= 0x0fffff;
936 BX_CPU_THIS_PTR eflags
.val32
&= ~(1<<11);
937 BX_CPU_THIS_PTR eflags
.val32
|= (!!of
)<<11;
941 BX_PANIC(("get_OF: unknown case"));
946 bx_bool
BX_CPU_C::get_PFLazy(void)
950 switch ((BX_CPU_THIS_PTR lf_flags_status
>>4) & 0x00000f) {
951 case BX_LF_INDEX_OSZAPC
:
952 switch (BX_CPU_THIS_PTR oszapc
.instr
) {
953 case BX_INSTR_LOGIC8
:
962 pf
= bx_parity_lookup
[BX_CPU_THIS_PTR oszapc
.result_8
];
964 case BX_INSTR_LOGIC16
:
972 case BX_INSTR_SHRD16
:
974 case BX_INSTR_BITSCAN16
:
975 pf
= bx_parity_lookup
[(Bit8u
) BX_CPU_THIS_PTR oszapc
.result_16
];
977 case BX_INSTR_LOGIC32
:
985 case BX_INSTR_SHRD32
:
987 case BX_INSTR_BITSCAN32
:
988 pf
= bx_parity_lookup
[(Bit8u
) BX_CPU_THIS_PTR oszapc
.result_32
];
990 #if BX_SUPPORT_X86_64
991 case BX_INSTR_LOGIC64
:
999 case BX_INSTR_SHRD64
:
1000 case BX_INSTR_SHL64
:
1001 case BX_INSTR_BITSCAN64
:
1002 pf
= bx_parity_lookup
[(Bit8u
) BX_CPU_THIS_PTR oszapc
.result_64
];
1005 case BX_INSTR_IMUL8
:
1007 pf
= bx_parity_lookup
[BX_CPU_THIS_PTR oszapc
.op1_8
];
1009 case BX_INSTR_IMUL16
:
1010 case BX_INSTR_MUL16
:
1011 pf
= bx_parity_lookup
[(Bit8u
) BX_CPU_THIS_PTR oszapc
.op1_16
];
1013 case BX_INSTR_IMUL32
:
1014 case BX_INSTR_MUL32
:
1015 pf
= bx_parity_lookup
[(Bit8u
) BX_CPU_THIS_PTR oszapc
.op1_32
];
1017 #if BX_SUPPORT_X86_64
1018 case BX_INSTR_IMUL64
:
1019 case BX_INSTR_MUL64
:
1020 pf
= bx_parity_lookup
[(Bit8u
) BX_CPU_THIS_PTR oszapc
.op1_64
];
1024 pf
= 0; // Keep compiler quiet.
1025 BX_PANIC(("get_PF: OSZAPC: unknown instr"));
1027 BX_CPU_THIS_PTR lf_flags_status
&= 0xffff0f;
1028 BX_CPU_THIS_PTR eflags
.val32
&= ~(1<<2);
1029 BX_CPU_THIS_PTR eflags
.val32
|= (pf
)<<2; // pf is always 0 or 1 here
1032 case BX_LF_INDEX_OSZAP
:
1033 switch (BX_CPU_THIS_PTR oszap
.instr
) {
1036 pf
= bx_parity_lookup
[BX_CPU_THIS_PTR oszap
.result_8
];
1038 case BX_INSTR_INC16
:
1039 case BX_INSTR_DEC16
:
1040 pf
= bx_parity_lookup
[(Bit8u
) BX_CPU_THIS_PTR oszap
.result_16
];
1042 case BX_INSTR_INC32
:
1043 case BX_INSTR_DEC32
:
1044 pf
= bx_parity_lookup
[(Bit8u
) BX_CPU_THIS_PTR oszap
.result_32
];
1046 #if BX_SUPPORT_X86_64
1047 case BX_INSTR_INC64
:
1048 case BX_INSTR_DEC64
:
1049 pf
= bx_parity_lookup
[(Bit8u
) BX_CPU_THIS_PTR oszap
.result_64
];
1053 pf
= 0; // Keep compiler quiet.
1054 BX_PANIC(("get_PF: OSZAP: unknown instr"));
1056 BX_CPU_THIS_PTR lf_flags_status
&= 0xffff0f;
1057 BX_CPU_THIS_PTR eflags
.val32
&= ~(1<<2);
1058 BX_CPU_THIS_PTR eflags
.val32
|= (pf
)<<2; // pf is always 0 or 1 here
1062 BX_PANIC(("get_PF: unknown case"));