1 /////////////////////////////////////////////////////////////////////////
2 // $Id: ctrl_xfer16.cc,v 1.64 2008/12/01 19:06:14 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 /////////////////////////////////////////////////////////////////////////
28 #define NEED_CPU_REG_SHORTCUTS 1
31 #define LOG_THIS BX_CPU_THIS_PTR
33 // Make code more tidy with a few macros.
34 #if BX_SUPPORT_X86_64==0
39 BX_CPP_INLINE
void BX_CPP_AttrRegparmN(1) BX_CPU_C::branch_near16(Bit16u new_IP
)
41 BX_ASSERT(BX_CPU_THIS_PTR cpu_mode
!= BX_MODE_LONG_64
);
43 // check always, not only in protected mode
44 if (new_IP
> BX_CPU_THIS_PTR sregs
[BX_SEG_REG_CS
].cache
.u
.segment
.limit_scaled
)
46 BX_ERROR(("branch_near16: offset outside of CS limits"));
47 exception(BX_GP_EXCEPTION
, 0, 0);
52 #if BX_SUPPORT_TRACE_CACHE && !defined(BX_TRACE_CACHE_NO_SPECULATIVE_TRACING)
53 // assert magic async_event to stop trace execution
54 BX_CPU_THIS_PTR async_event
|= BX_ASYNC_EVENT_STOP_TRACE
;
58 void BX_CPP_AttrRegparmN(1) BX_CPU_C::RETnear16_Iw(bxInstruction_c
*i
)
60 BX_ASSERT(BX_CPU_THIS_PTR cpu_mode
!= BX_MODE_LONG_64
);
63 BX_CPU_THIS_PTR show_flag
|= Flag_ret
;
66 BX_CPU_THIS_PTR speculative_rsp
= 1;
67 BX_CPU_THIS_PTR prev_rsp
= ESP
;
69 Bit16u return_IP
= pop_16();
71 if (return_IP
> BX_CPU_THIS_PTR sregs
[BX_SEG_REG_CS
].cache
.u
.segment
.limit_scaled
)
73 BX_ERROR(("RETnear16_Iw: IP > limit"));
74 exception(BX_GP_EXCEPTION
, 0, 0);
79 Bit16u imm16
= i
->Iw();
81 if (BX_CPU_THIS_PTR sregs
[BX_SEG_REG_SS
].cache
.u
.segment
.d_b
) /* 32bit stack */
86 BX_CPU_THIS_PTR speculative_rsp
= 0;
88 BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID
, BX_INSTR_IS_RET
, EIP
);
91 void BX_CPP_AttrRegparmN(1) BX_CPU_C::RETnear16(bxInstruction_c
*i
)
93 BX_ASSERT(BX_CPU_THIS_PTR cpu_mode
!= BX_MODE_LONG_64
);
96 BX_CPU_THIS_PTR show_flag
|= Flag_ret
;
99 BX_CPU_THIS_PTR speculative_rsp
= 1;
100 BX_CPU_THIS_PTR prev_rsp
= ESP
;
102 Bit16u return_IP
= pop_16();
104 if (return_IP
> BX_CPU_THIS_PTR sregs
[BX_SEG_REG_CS
].cache
.u
.segment
.limit_scaled
)
106 BX_ERROR(("RETnear16: IP > limit"));
107 exception(BX_GP_EXCEPTION
, 0, 0);
112 BX_CPU_THIS_PTR speculative_rsp
= 0;
114 BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID
, BX_INSTR_IS_RET
, EIP
);
117 void BX_CPP_AttrRegparmN(1) BX_CPU_C::RETfar16_Iw(bxInstruction_c
*i
)
121 invalidate_prefetch_q();
124 BX_CPU_THIS_PTR show_flag
|= Flag_ret
;
127 Bit16s imm16
= (Bit16s
) i
->Iw();
129 BX_CPU_THIS_PTR speculative_rsp
= 1;
130 BX_CPU_THIS_PTR prev_rsp
= RSP
;
132 if (protected_mode()) {
133 BX_CPU_THIS_PTR
return_protected(i
, imm16
);
140 // CS.LIMIT can't change when in real/v8086 mode
141 if (ip
> BX_CPU_THIS_PTR sregs
[BX_SEG_REG_CS
].cache
.u
.segment
.limit_scaled
) {
142 BX_ERROR(("RETfar16_Iw: instruction pointer not within code segment limits"));
143 exception(BX_GP_EXCEPTION
, 0, 0);
146 load_seg_reg(&BX_CPU_THIS_PTR sregs
[BX_SEG_REG_CS
], cs_raw
);
149 if (BX_CPU_THIS_PTR sregs
[BX_SEG_REG_SS
].cache
.u
.segment
.d_b
)
156 BX_CPU_THIS_PTR speculative_rsp
= 0;
158 BX_INSTR_FAR_BRANCH(BX_CPU_ID
, BX_INSTR_IS_RET
,
159 BX_CPU_THIS_PTR sregs
[BX_SEG_REG_CS
].selector
.value
, EIP
);
162 void BX_CPP_AttrRegparmN(1) BX_CPU_C::RETfar16(bxInstruction_c
*i
)
166 invalidate_prefetch_q();
169 BX_CPU_THIS_PTR show_flag
|= Flag_ret
;
172 BX_CPU_THIS_PTR speculative_rsp
= 1;
173 BX_CPU_THIS_PTR prev_rsp
= RSP
;
175 if (protected_mode()) {
176 BX_CPU_THIS_PTR
return_protected(i
, 0);
183 // CS.LIMIT can't change when in real/v8086 mode
184 if (ip
> BX_CPU_THIS_PTR sregs
[BX_SEG_REG_CS
].cache
.u
.segment
.limit_scaled
) {
185 BX_ERROR(("RETfar16: instruction pointer not within code segment limits"));
186 exception(BX_GP_EXCEPTION
, 0, 0);
189 load_seg_reg(&BX_CPU_THIS_PTR sregs
[BX_SEG_REG_CS
], cs_raw
);
194 BX_CPU_THIS_PTR speculative_rsp
= 0;
196 BX_INSTR_FAR_BRANCH(BX_CPU_ID
, BX_INSTR_IS_RET
,
197 BX_CPU_THIS_PTR sregs
[BX_SEG_REG_CS
].selector
.value
, EIP
);
200 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CALL_Jw(bxInstruction_c
*i
)
203 BX_CPU_THIS_PTR show_flag
|= Flag_call
;
206 BX_CPU_THIS_PTR speculative_rsp
= 1;
207 BX_CPU_THIS_PTR prev_rsp
= RSP
;
209 /* push 16 bit EA of next instruction */
212 Bit16u new_IP
= IP
+ i
->Iw();
213 branch_near16(new_IP
);
215 BX_CPU_THIS_PTR speculative_rsp
= 0;
217 BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID
, BX_INSTR_IS_CALL
, EIP
);
220 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CALL16_Ap(bxInstruction_c
*i
)
222 BX_ASSERT(BX_CPU_THIS_PTR cpu_mode
!= BX_MODE_LONG_64
);
224 invalidate_prefetch_q();
227 BX_CPU_THIS_PTR show_flag
|= Flag_call
;
230 Bit16u disp16
= i
->Iw();
231 Bit16u cs_raw
= i
->Iw2();
233 BX_CPU_THIS_PTR speculative_rsp
= 1;
234 BX_CPU_THIS_PTR prev_rsp
= ESP
;
236 if (protected_mode()) {
237 BX_CPU_THIS_PTR
call_protected(i
, cs_raw
, disp16
);
241 push_16(BX_CPU_THIS_PTR sregs
[BX_SEG_REG_CS
].selector
.value
);
244 // CS.LIMIT can't change when in real/v8086 mode
245 if (disp16
> BX_CPU_THIS_PTR sregs
[BX_SEG_REG_CS
].cache
.u
.segment
.limit_scaled
) {
246 BX_ERROR(("CALL16_Ap: instruction pointer not within code segment limits"));
247 exception(BX_GP_EXCEPTION
, 0, 0);
250 load_seg_reg(&BX_CPU_THIS_PTR sregs
[BX_SEG_REG_CS
], cs_raw
);
251 EIP
= (Bit32u
) disp16
;
255 BX_CPU_THIS_PTR speculative_rsp
= 0;
257 BX_INSTR_FAR_BRANCH(BX_CPU_ID
, BX_INSTR_IS_CALL
,
258 BX_CPU_THIS_PTR sregs
[BX_SEG_REG_CS
].selector
.value
, EIP
);
261 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CALL_EwR(bxInstruction_c
*i
)
263 Bit16u new_IP
= BX_READ_16BIT_REG(i
->rm());
266 BX_CPU_THIS_PTR show_flag
|= Flag_call
;
269 BX_CPU_THIS_PTR speculative_rsp
= 1;
270 BX_CPU_THIS_PTR prev_rsp
= ESP
;
272 /* push 16 bit EA of next instruction */
275 branch_near16(new_IP
);
277 BX_CPU_THIS_PTR speculative_rsp
= 0;
279 BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID
, BX_INSTR_IS_CALL
, EIP
);
282 void BX_CPP_AttrRegparmN(1) BX_CPU_C::CALL16_Ep(bxInstruction_c
*i
)
287 invalidate_prefetch_q();
290 BX_CPU_THIS_PTR show_flag
|= Flag_call
;
293 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
295 op1_16
= read_virtual_word(i
->seg(), eaddr
);
296 cs_raw
= read_virtual_word(i
->seg(), eaddr
+2);
298 BX_CPU_THIS_PTR speculative_rsp
= 1;
299 BX_CPU_THIS_PTR prev_rsp
= RSP
;
301 if (protected_mode()) {
302 BX_CPU_THIS_PTR
call_protected(i
, cs_raw
, op1_16
);
306 push_16(BX_CPU_THIS_PTR sregs
[BX_SEG_REG_CS
].selector
.value
);
309 // CS.LIMIT can't change when in real/v8086 mode
310 if (op1_16
> BX_CPU_THIS_PTR sregs
[BX_SEG_REG_CS
].cache
.u
.segment
.limit_scaled
) {
311 BX_ERROR(("CALL16_Ep: instruction pointer not within code segment limits"));
312 exception(BX_GP_EXCEPTION
, 0, 0);
315 load_seg_reg(&BX_CPU_THIS_PTR sregs
[BX_SEG_REG_CS
], cs_raw
);
320 BX_CPU_THIS_PTR speculative_rsp
= 0;
322 BX_INSTR_FAR_BRANCH(BX_CPU_ID
, BX_INSTR_IS_CALL
,
323 BX_CPU_THIS_PTR sregs
[BX_SEG_REG_CS
].selector
.value
, EIP
);
326 void BX_CPP_AttrRegparmN(1) BX_CPU_C::JMP_Jw(bxInstruction_c
*i
)
328 Bit16u new_IP
= IP
+ i
->Iw();
329 branch_near16(new_IP
);
330 BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID
, BX_INSTR_IS_JMP
, new_IP
);
333 void BX_CPP_AttrRegparmN(1) BX_CPU_C::JO_Jw(bxInstruction_c
*i
)
336 Bit16u new_IP
= IP
+ i
->Iw();
337 branch_near16(new_IP
);
338 BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID
, new_IP
);
340 #if BX_INSTRUMENTATION
342 BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID
);
347 void BX_CPP_AttrRegparmN(1) BX_CPU_C::JNO_Jw(bxInstruction_c
*i
)
350 Bit16u new_IP
= IP
+ i
->Iw();
351 branch_near16(new_IP
);
352 BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID
, new_IP
);
354 #if BX_INSTRUMENTATION
356 BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID
);
361 void BX_CPP_AttrRegparmN(1) BX_CPU_C::JB_Jw(bxInstruction_c
*i
)
364 Bit16u new_IP
= IP
+ i
->Iw();
365 branch_near16(new_IP
);
366 BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID
, new_IP
);
368 #if BX_INSTRUMENTATION
370 BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID
);
375 void BX_CPP_AttrRegparmN(1) BX_CPU_C::JNB_Jw(bxInstruction_c
*i
)
378 Bit16u new_IP
= IP
+ i
->Iw();
379 branch_near16(new_IP
);
380 BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID
, new_IP
);
382 #if BX_INSTRUMENTATION
384 BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID
);
389 void BX_CPP_AttrRegparmN(1) BX_CPU_C::JZ_Jw(bxInstruction_c
*i
)
392 Bit16u new_IP
= IP
+ i
->Iw();
393 branch_near16(new_IP
);
394 BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID
, new_IP
);
396 #if BX_INSTRUMENTATION
398 BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID
);
403 void BX_CPP_AttrRegparmN(1) BX_CPU_C::JNZ_Jw(bxInstruction_c
*i
)
406 Bit16u new_IP
= IP
+ i
->Iw();
407 branch_near16(new_IP
);
408 BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID
, new_IP
);
410 #if BX_INSTRUMENTATION
412 BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID
);
417 void BX_CPP_AttrRegparmN(1) BX_CPU_C::JBE_Jw(bxInstruction_c
*i
)
419 if (get_CF() || get_ZF()) {
420 Bit16u new_IP
= IP
+ i
->Iw();
421 branch_near16(new_IP
);
422 BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID
, new_IP
);
424 #if BX_INSTRUMENTATION
426 BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID
);
431 void BX_CPP_AttrRegparmN(1) BX_CPU_C::JNBE_Jw(bxInstruction_c
*i
)
433 if (! (get_CF() || get_ZF())) {
434 Bit16u new_IP
= IP
+ i
->Iw();
435 branch_near16(new_IP
);
436 BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID
, new_IP
);
438 #if BX_INSTRUMENTATION
440 BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID
);
445 void BX_CPP_AttrRegparmN(1) BX_CPU_C::JS_Jw(bxInstruction_c
*i
)
448 Bit16u new_IP
= IP
+ i
->Iw();
449 branch_near16(new_IP
);
450 BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID
, new_IP
);
452 #if BX_INSTRUMENTATION
454 BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID
);
459 void BX_CPP_AttrRegparmN(1) BX_CPU_C::JNS_Jw(bxInstruction_c
*i
)
462 Bit16u new_IP
= IP
+ i
->Iw();
463 branch_near16(new_IP
);
464 BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID
, new_IP
);
466 #if BX_INSTRUMENTATION
468 BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID
);
473 void BX_CPP_AttrRegparmN(1) BX_CPU_C::JP_Jw(bxInstruction_c
*i
)
476 Bit16u new_IP
= IP
+ i
->Iw();
477 branch_near16(new_IP
);
478 BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID
, new_IP
);
480 #if BX_INSTRUMENTATION
482 BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID
);
487 void BX_CPP_AttrRegparmN(1) BX_CPU_C::JNP_Jw(bxInstruction_c
*i
)
490 Bit16u new_IP
= IP
+ i
->Iw();
491 branch_near16(new_IP
);
492 BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID
, new_IP
);
494 #if BX_INSTRUMENTATION
496 BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID
);
501 void BX_CPP_AttrRegparmN(1) BX_CPU_C::JL_Jw(bxInstruction_c
*i
)
503 if (getB_SF() != getB_OF()) {
504 Bit16u new_IP
= IP
+ i
->Iw();
505 branch_near16(new_IP
);
506 BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID
, new_IP
);
508 #if BX_INSTRUMENTATION
510 BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID
);
515 void BX_CPP_AttrRegparmN(1) BX_CPU_C::JNL_Jw(bxInstruction_c
*i
)
517 if (getB_SF() == getB_OF()) {
518 Bit16u new_IP
= IP
+ i
->Iw();
519 branch_near16(new_IP
);
520 BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID
, new_IP
);
522 #if BX_INSTRUMENTATION
524 BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID
);
529 void BX_CPP_AttrRegparmN(1) BX_CPU_C::JLE_Jw(bxInstruction_c
*i
)
531 if (get_ZF() || (getB_SF() != getB_OF())) {
532 Bit16u new_IP
= IP
+ i
->Iw();
533 branch_near16(new_IP
);
534 BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID
, new_IP
);
536 #if BX_INSTRUMENTATION
538 BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID
);
543 void BX_CPP_AttrRegparmN(1) BX_CPU_C::JNLE_Jw(bxInstruction_c
*i
)
545 if (! get_ZF() && (getB_SF() == getB_OF())) {
546 Bit16u new_IP
= IP
+ i
->Iw();
547 branch_near16(new_IP
);
548 BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID
, new_IP
);
550 #if BX_INSTRUMENTATION
552 BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID
);
557 void BX_CPP_AttrRegparmN(1) BX_CPU_C::JMP_EwR(bxInstruction_c
*i
)
559 Bit16u new_IP
= BX_READ_16BIT_REG(i
->rm());
560 branch_near16(new_IP
);
561 BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID
, BX_INSTR_IS_JMP
, new_IP
);
564 /* Far indirect jump */
565 void BX_CPP_AttrRegparmN(1) BX_CPU_C::JMP16_Ep(bxInstruction_c
*i
)
570 invalidate_prefetch_q();
572 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
574 op1_16
= read_virtual_word(i
->seg(), eaddr
);
575 cs_raw
= read_virtual_word(i
->seg(), eaddr
+2);
577 // jump_protected doesn't affect RSP so it is RSP safe
578 if (protected_mode()) {
579 BX_CPU_THIS_PTR
jump_protected(i
, cs_raw
, op1_16
);
583 // CS.LIMIT can't change when in real/v8086 mode
584 if (op1_16
> BX_CPU_THIS_PTR sregs
[BX_SEG_REG_CS
].cache
.u
.segment
.limit_scaled
) {
585 BX_ERROR(("JMP16_Ep: instruction pointer not within code segment limits"));
586 exception(BX_GP_EXCEPTION
, 0, 0);
589 load_seg_reg(&BX_CPU_THIS_PTR sregs
[BX_SEG_REG_CS
], cs_raw
);
594 BX_INSTR_FAR_BRANCH(BX_CPU_ID
, BX_INSTR_IS_JMP
,
595 BX_CPU_THIS_PTR sregs
[BX_SEG_REG_CS
].selector
.value
, EIP
);
598 void BX_CPP_AttrRegparmN(1) BX_CPU_C::IRET16(bxInstruction_c
*i
)
600 Bit16u ip
, cs_raw
, flags
;
602 invalidate_prefetch_q();
605 BX_CPU_THIS_PTR show_flag
|= Flag_iret
;
608 BX_CPU_THIS_PTR disable_NMI
= 0;
610 BX_CPU_THIS_PTR speculative_rsp
= 1;
611 BX_CPU_THIS_PTR prev_rsp
= RSP
;
614 // IOPL check in stack_return_from_v86()
615 iret16_stack_return_from_v86(i
);
619 if (protected_mode()) {
625 cs_raw
= pop_16(); // #SS has higher priority
628 // CS.LIMIT can't change when in real/v8086 mode
629 if(ip
> BX_CPU_THIS_PTR sregs
[BX_SEG_REG_CS
].cache
.u
.segment
.limit_scaled
) {
630 BX_ERROR(("IRET16: instruction pointer not within code segment limits"));
631 exception(BX_GP_EXCEPTION
, 0, 0);
634 load_seg_reg(&BX_CPU_THIS_PTR sregs
[BX_SEG_REG_CS
], cs_raw
);
636 write_flags(flags
, /* change IOPL? */ 1, /* change IF? */ 1);
639 BX_CPU_THIS_PTR speculative_rsp
= 0;
641 BX_INSTR_FAR_BRANCH(BX_CPU_ID
, BX_INSTR_IS_IRET
,
642 BX_CPU_THIS_PTR sregs
[BX_SEG_REG_CS
].selector
.value
, EIP
);
645 void BX_CPP_AttrRegparmN(1) BX_CPU_C::JCXZ_Jb(bxInstruction_c
*i
)
647 // it is impossible to get this instruction in long mode
648 BX_ASSERT(i
->as64L() == 0);
658 Bit16u new_IP
= IP
+ i
->Iw();
659 branch_near16(new_IP
);
660 BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID
, new_IP
);
662 #if BX_INSTRUMENTATION
664 BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID
);
670 // There is some weirdness in LOOP instructions definition. If an exception
671 // was generated during the instruction execution (for example #GP fault
672 // because EIP was beyond CS segment limits) CPU state should restore the
673 // state prior to instruction execution.
675 // The final point that we are not allowed to decrement ECX register before
676 // it is known that no exceptions can happen.
679 void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOOPNE16_Jb(bxInstruction_c
*i
)
681 // it is impossible to get this instruction in long mode
682 BX_ASSERT(i
->as64L() == 0);
688 if (count
!= 0 && (get_ZF()==0)) {
689 Bit16u new_IP
= IP
+ i
->Iw();
690 branch_near16(new_IP
);
691 BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID
, new_IP
);
693 #if BX_INSTRUMENTATION
695 BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID
);
705 if (count
!= 0 && (get_ZF()==0)) {
706 Bit16u new_IP
= IP
+ i
->Iw();
707 branch_near16(new_IP
);
708 BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID
, new_IP
);
710 #if BX_INSTRUMENTATION
712 BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID
);
720 void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOOPE16_Jb(bxInstruction_c
*i
)
722 // it is impossible to get this instruction in long mode
723 BX_ASSERT(i
->as64L() == 0);
729 if (count
!= 0 && get_ZF()) {
730 Bit16u new_IP
= IP
+ i
->Iw();
731 branch_near16(new_IP
);
732 BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID
, new_IP
);
734 #if BX_INSTRUMENTATION
736 BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID
);
746 if (count
!= 0 && get_ZF()) {
747 Bit16u new_IP
= IP
+ i
->Iw();
748 branch_near16(new_IP
);
749 BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID
, new_IP
);
751 #if BX_INSTRUMENTATION
753 BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID
);
761 void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOOP16_Jb(bxInstruction_c
*i
)
763 // it is impossible to get this instruction in long mode
764 BX_ASSERT(i
->as64L() == 0);
771 Bit16u new_IP
= IP
+ i
->Iw();
772 branch_near16(new_IP
);
773 BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID
, new_IP
);
775 #if BX_INSTRUMENTATION
777 BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID
);
788 Bit16u new_IP
= IP
+ i
->Iw();
789 branch_near16(new_IP
);
790 BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID
, new_IP
);
792 #if BX_INSTRUMENTATION
794 BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID
);