1 /* OpenCP Module Player
2  * copyright (c) '04-'10 Stian Skjelstad <stian@nixia.no>
3  *
4  * Emulation of x86 (ia32) instructions
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program 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
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */
20 #ifndef ASM_X86_H
21 #define ASM_X86_H 1
22 
23 #include <math.h>
24 #include <string.h>
25 #include <stdio.h>
26 
27 #define ASM_X86_INTERNAL_H
28 
29 /* #define X86_AF */
30 /* #define X86_PF */
31 /* #define X86_FPU_EXCEPTIONS */
32 
33 /* TODO */
34 #define FPU_TYPE long double
35 #define FPU_TYPE_FORMAT "%Lf"
36 #define FPU_REGS 8
37 
38 struct reg32_t
39 {
40 	union
41 	{
42 		uint8_t values8[4];
43 		uint16_t values16[2];
44 		uint32_t values32[1];
45 	};
46 };
47 
48 #define STACK_LENGTH 1024
49 
50 typedef void (*writecallback_t)(uint_fast16_t selector, uint_fast32_t addr, int size, uint_fast32_t data);
51 typedef uint_fast32_t (*readcallback_t)(uint_fast16_t selector, uint_fast32_t addr, int size);
52 
53 struct  __attribute__((packed)) assembler_state_t
54 {
55 	struct reg32_t _eax;
56 	struct reg32_t _ebx;
57 	struct reg32_t _ecx;
ext2fs_warn_bitmap2(ext2fs_generic_bitmap gen_bitmap,int code,unsigned long arg)58 	struct reg32_t _edx;
59 
60 	struct reg32_t _ebp;
61 	struct reg32_t _esp;
62 
63 	struct reg32_t _esi;
64 	struct reg32_t _edi;
65 /*
66 	struct reg32_t eip; */
67 
68 	struct reg32_t _eflags;
69 
70 	uint16_t cs;
71 	uint16_t ds;
check_magic(ext2fs_generic_bitmap bitmap)72 	uint16_t es;
73 	uint16_t fs;
74 	uint16_t gs;
75 	uint16_t ss;
76 	unsigned char stackmemory[STACK_LENGTH];
77 
78 	uint16_t FPUControlWord;
79 	uint16_t FPUStatusWord;
80 	uint16_t FPUTagWord;
ext2fs_make_generic_bitmap(errcode_t magic,ext2_filsys fs,__u32 start,__u32 end,__u32 real_end,const char * descr,char * init_map,ext2fs_generic_bitmap * ret)81 #ifdef X86_FPU_EXCEPTIONS
82 	uint32_t FPUDataPointerOffset;
83 	uint16_t FPUDataPointerSelector;
84 	uint32_t FPUInstructionPointerOffset;
85 	uint16_t FPUInstructionPointerSelector;
86 	uint16_t FPULastInstructionOpcode;
87 #endif
88 	FPU_TYPE FPUStack[FPU_REGS];
89 
90 	writecallback_t write;
91 	readcallback_t read;
92 };
93 
94 static inline void x86_write_memory(struct assembler_state_t *state, uint_fast16_t selector, uint_fast32_t addr, int size, uint_fast32_t data)
95 {
96 	if (selector < 4)
97 	{
98 		fprintf(stderr, "#GP exception occured (zero-selector written to)\n");
99 		return;
100 	}
101 	if (selector == 4)
102 	{
103 		if ((addr+size) > STACK_LENGTH)
104 		{
105 			fprintf(stderr, "#SS exception occured\n");
106 			return;
107 		}
108 		if (size==4)
109 		{
110 			state->stackmemory[addr] = data;
111 			state->stackmemory[addr+1] = data >> 8;
112 			state->stackmemory[addr+2] = data >> 16;
113 			state->stackmemory[addr+3] = data >> 24;
114 		}
115 		else if (size==2)
116 		{
117 			state->stackmemory[addr] = data;
118 			state->stackmemory[addr+1] = data >> 8;
119 		}
120 		else if (size==1)
121 		{
122 			state->stackmemory[addr] = data;
123 		}
124 	}
125 	state->write(selector, addr, size, data);
126 }
127 
128 static inline uint_fast32_t x86_read_memory(struct assembler_state_t *state, uint_fast16_t selector, uint_fast32_t addr, int size)
129 {
130 	if (selector < 4)
131 	{
132 		fprintf(stderr, "#GP exception occured (zero-selector red from)\n");
133 		return 0;
134 	}
135 	if (selector == 4)
136 	{
137 		if ((addr+size) > STACK_LENGTH)
ext2fs_allocate_generic_bitmap(__u32 start,__u32 end,__u32 real_end,const char * descr,ext2fs_generic_bitmap * ret)138 		{
139 			fprintf(stderr, "#SS exception occured\n");
140 			return state->stackmemory[addr];
141 		}
142 		if (size==4)
143 			return state->stackmemory[addr] | (state->stackmemory[addr+1]<<8) | (state->stackmemory[addr+2]<<16) | (state->stackmemory[addr+3]<<24);
144 		else if (size==2)
145 			return state->stackmemory[addr] | (state->stackmemory[addr+1]<<8);
146 		else if (size==1)
147 			return state->stackmemory[addr];
ext2fs_copy_generic_bitmap(ext2fs_generic_bitmap gen_src,ext2fs_generic_bitmap * dest)148 	}
149 	return state->read(selector, addr, size);
150 }
151 
152 #ifdef WORDS_BIGENDIAN
153 #define offset_0 1
154 #define offset_1 0
155 #else
156 #define offset_0 0
157 #define offset_1 1
158 #endif
159 
ext2fs_free_generic_bitmap(ext2fs_inode_bitmap gen_bitmap)160 #define eax _eax.values32[0]
161 #define  ax _eax.values16[offset_0]
162 #define  al _eax.values8[offset_0]
163 #define  ah _eax.values8[offset_1]
164 
165 #define ebx _ebx.values32[0]
166 #define  bx _ebx.values16[offset_0]
167 #define  bl _ebx.values8[offset_0]
168 #define  bh _ebx.values8[offset_1]
169 
170 #define ecx _ecx.values32[0]
171 #define  cx _ecx.values16[offset_0]
172 #define  cl _ecx.values8[offset_0]
173 #define  ch _ecx.values8[offset_1]
174 
175 #define edx _edx.values32[0]
176 #define  dx _edx.values16[offset_0]
177 #define  dl _edx.values8[offset_0]
178 #define  dh _edx.values8[offset_1]
179 
180 #define ebp _ebp.values32[0]
181 #define  bp _ebp.values16[offset_0]
182 
183 #define esp _esp.values32[0]
184 #define  sp _esp.values16[offset_0]
185 
186 #define edi _edi.values32[0]
187 #define  di _edi.values16[offset_0]
188 
189 #define esi _esi.values32[0]
190 #define  si _esi.values16[offset_0]
191 
192 #define eflags _eflags.values32[0]
193 /* CARRY FLAG */
194 #define read_cf(flags) (!!(flags & 0x00000001))
195 #define write_cf(flags, state) flags = (flags & ~0x00000001) | ((state)?0x00000001:0)
196 #ifdef X86_PF
197 /* PARITY FLAG */
198 #define read_pf(flags) (!!(flags & 0x00000004))
199 #define write_pf(flags, state) flags = (flags & ~0x00000004) | ((state)?0x00000004:0)
200 #endif
201 #ifdef X86_AF
202 /* ADJUST FLAG */
203 #define read_af(flags) (!!(flags & 0x00000010))
204 #define write_af(flags, state) flags = (flags & ~0x00000010) | ((state)?0x00000010:0)
205 #endif
206 /* ZERO FLAG */
207 #define read_zf(flags) (!!(flags & 0x00000040))
208 #define write_zf(flags, state) flags = (flags & ~0x00000040) | ((state)?0x00000040:0)
209 /* SIGN FLAG */
210 #define read_sf(flags) (!!(flags & 0x00000080))
211 #define write_sf(flags, state) flags = (flags & ~0x00000080) | ((state)?0x00000080:0)
212 /* DIRECTION FLAG */
213 #define read_df(flags) (!!(flags & 0x00000200))
214 #define write_df(flags, state) flags = (flags & ~0x00000200) | ((state)?0x00000200:0)
215 /* OVERFLOW FLAG */
216 #define read_of(flags) (!!(flags & 0x00000400))
217 #define write_of(flags, state) flags = (flags & ~0x00000400) | ((state)?0x00000400:0)
218 #ifdef X86_PF
219 static inline void asm_update_pf(uint32_t *_eflags, const uint32_t reg)
220 {
221 	write_pf(*_eflags,
222 		(!!(ref&0x80))^
223 		(!!(reg&0x40))^
224 		(!!(reg&0x20))^
225 		(!!(reg&0x10))^
226 		(!!(reg&0x08))^
227 		(!!(reg&0x04))^
228 		(!!(reg&0x02))^
229 		(reg&0x01)^0x01);
230 }
231 #endif
232 #ifdef X86_AF
233 static inline void asm_update_af(uint32_t *_eflags, const uint32_t newreg, const uint32_t oldreg)
234 {
235 
236 	write_af(*_eflags, (oldreg&0x10)&&((oldref&0xfffffff0)!=(newreg&0xfffffff0)));
237 }
238 #endif
239 /* B */
240 #define read_fpu_status_busy(status) (!!(status & 0x8000))
241 #define write_fpu_status_busy(status, state) status = (status & ~ 0x8000) | ((state)?0x8000:0)
242 /* C3 */
243 #define read_fpu_status_conditioncode3(status) (!!(status & 0x4000))
244 #define write_fpu_status_conditioncode3(status, state) status = (status & ~ 0x4000) | ((state)?0x4000:0)
245 /* C2 */
246 #define read_fpu_status_conditioncode2(status) (!!(status & 0x0400))
247 #define write_fpu_status_conditioncode2(status, state) status = (status & ~ 0x0400) | ((state)?0x0400:0)
248 /* C1 */
249 #define read_fpu_status_conditioncode1(status) (!!(status & 0x0200))
250 #define write_fpu_status_conditioncode1(status, state) status = (status & ~ 0x0200) | ((state)?0x0200:0)
ext2fs_get_generic_bitmap_start(ext2fs_generic_bitmap bitmap)251 /* C0 */
252 #define read_fpu_status_conditioncode0(status) (!!(status & 0x0100))
253 #define write_fpu_status_conditioncode0(status, state) status = (status & ~ 0x0100) | ((state)?0x0100:0)
254 /* TOP */
255 #define read_fpu_status_top(status) ((status & 0x3800)>>11)
256 #define write_fpu_status_top(status, state) status = (status & ~ 0x3800) | ((state<<11)&0x3800)
257 /* ES */
258 #define read_fpu_status_error_summary(status) (!!(status & 0x0040))
259 #define write_fpu_status_error_summary(status, state) status = (status & ~ 0x0040) | ((state)?0x0040:0)
260 /* SF */
261 #define read_fpu_status_stack_fault(status) (!!(status & 0x0040))
262 #define write_fpu_status_stack_fault(status, state) status = (status & ~ 0x0040) | ((state)?0x0040:0)
263 /* PE */
264 #define read_fpu_status_exception_precision(status) (!!(status & 0x0020))
265 #define write_fpu_status_exception_precision(status, state) status = (status & ~ 0x0020) | ((state)?0x0020:0)
266 /* UE */
267 #define read_fpu_status_exception_underflow(status) (!!(status & 0x0010))
268 #define write_fpu_status_exception_underflow(status, state) status = (status & ~ 0x0010) | ((state)?0x0010:0)
269 /* OE */
270 #define read_fpu_status_exception_overflow(status) (!!(status & 0x0008))
271 #define write_fpu_status_exception_overflow(status, state) status = (status & ~ 0x0008) | ((state)?0x0008:0)
272 /* ZE */
273 #define read_fpu_status_exception_zero_divide(status) (!!(status & 0x0004))
274 #define write_fpu_status_exception_zero_divide(status, state) status = (status & ~ 0x0004) | ((state)?0x0004:0)
275 /* DE */
276 #define read_fpu_status_exception_denormalized_operand(status) (!!(status & 0x0002))
277 #define write_fpu_status_exception_denormalized_operand(status, state) status = (status & ~ 0x0002) | ((state)?0x0002:0)
278 /* IE */
279 #define read_fpu_status_exception_invalid_operand(status) (!!(status & 0x0001))
280 #define write_fpu_status_exception_invalid_operand(status, state) status = (status & ~ 0x0001) | ((state)?0x0001:0)
281 
282 /* X, this is actually a NC bit */
283 #define read_fpu_control_infinty(status) (!!(status & 0x1000))
284 #define write_fpu_control_infinty(status,state) status = (status & ~0x1000) | ((state)?0x1000:0)
285 /* RC */
286 #define read_fpu_control_rounding(status) ((status&0x0c00)>>10)
287 #define write_fpu_control_roudning(status,state) status = (status & ~0x0c000) | ((state & 0x0003)<<10)
288 #define RC_ROUND_TO_NEAREST 0x00
289 #define RC_ROUND_DOWN       0x01
290 #define RC_ROUND_UP         0x02
291 #define RC_ROUND_ZERO       0x03
292 /* PC */
293 #define read_fpu_control_precision(status) ((status&0x0300)>>8)
294 #define write_fpu_control_precision(status) status = (status & ~0x0300) | ((state & 0x0003)<<8)
295 #define PC_SINGLE_PRECISION          0x00
296 #define PC_RESERVED                  0x01
297 #define PC_DOUBLE_PRECISION          0x02
298 #define PC_DOUBLE_EXTENDED_PRECISION 0x03
299 /* PM */
300 #define read_fpu_control_exception_mask_precision(status) (!!(status&0x0020))
301 #define write_fpu_control_exception_mask_precision(status,state) status = (status & ~0x0020) | ((state)?0x0020:0)
302 /* UM */
303 #define read_fpu_control_exception_mask_underflow(status) (!!(status&0x0010))
304 #define write_fpu_control_exception_mask_underflow(status,state) status = (status & ~0x0010) | ((state)?0x0010:0)
305 /* OM */
306 #define read_fpu_control_exception_mask_overflow(status) (!!(status&0x0008))
307 #define write_fpu_control_exception_mask_overflow(status,state) status = (status & ~0x0008) | ((state)?0x0008:0)
308 /* ZM */
309 #define read_fpu_control_exception_mask_zero_divide(status) (!!(status&0x0004))
310 #define write_fpu_control_exception_mask_zero_divide(status,state) status = (status & ~0x0004) | ((state)?0x0004:0)
311 /* DM */
312 #define read_fpu_control_exception_mask_denormal_operand(status) (!!(status&0x0002))
313 #define write_fpu_control_exception_mask_denormal_operand(status,state) status = (status & ~0x0002) | ((state)?0x0002:0)
314 /* IM */
315 #define read_fpu_control_exception_mask_invalid_operation(status) (!!(status&0x0001))
316 #define write_fpu_control_exception_mask_invalid_operation(status,state) status = (status & ~0x0001) | ((state)?0x0001:0)
317 
318 #define FPU_TAG_VALID   0x00
319 #define FPU_TAG_ZERO    0x01
320 #define FPU_TAG_SPECIAL 0x02
321 #define FPU_TAG_EMPTY   0x03
322 static inline int read_fpu_sub_tag(uint16_t status, int tag)
323 {
324 	if ((tag<0)||(tag>7))
325 	{
326 		fprintf(stderr, "read_fpu_sub_tag: invalid tag index\n");
327 		return 0;
328 	}
329 	return ((status>>tag)>>tag)&3;
330 }
331 static inline void write_fpu_sub_tag(uint16_t *status, int tag, int value)
332 {
333 	if ((tag<0)||(tag>7))
334 	{
335 		fprintf(stderr, "write_fpu_sub_tag: invalid tag index\n");
336 		return;
337 	}
338 	*status &= ~((3<<tag)<<tag);
339 	value &= 3;
340 	*status |= ((value<<tag)<<tag);
341 }
342 static inline int pop_fpu_sub_tag(uint16_t *status)
343 {
344 	if ((*status & 0x0003) == FPU_TAG_EMPTY)
345 	{
346 		fprintf(stderr, "pop_fpu_sub_tag: underflow exception occured\n");
347 		return 0x0010;
348 	}
349 	*status = (*status)>>2;
350 	*status &= 0x3fff;
351 	*status |= (FPU_TAG_EMPTY<<14);
352 	return 0;
353 }
354 static inline int push_fpu_sub_tag(uint16_t *status, int value)
355 {
356 	if ((*status & 0xc000) != (FPU_TAG_EMPTY<<14))
357 	{
358 		fprintf(stderr, "push_fpu_sub_tag: overflow exception occured\n");
359 		return 0x0010;
360 	}
361 	if ((value < 0) || (value > 2)) /* this should never happen */
362 	{
363 		fprintf(stderr, "push_fpu_sub_tag: invalid operation occured\n");
364 		return 0x0001;
365 	}
366 	*status = (*status)<<2;
367 	*status |= (uint16_t)value;
368 	return 0;
ext2fs_compare_generic_bitmap(errcode_t magic,errcode_t neq,ext2fs_generic_bitmap gen_bm1,ext2fs_generic_bitmap gen_bm2)369 }
370 
371 static inline FPU_TYPE read_fpu_st(struct assembler_state_t *state, int index)
372 {
373 	int offset = (read_fpu_status_top(state->FPUStatusWord)+index) & 7;
374 	return state->FPUStack[offset];
375 }
376 static inline void write_fpu_st(struct assembler_state_t *state, int index, FPU_TYPE data)
377 {
378 	int offset = (read_fpu_status_top(state->FPUStatusWord)+index) & 7;
379 	state->FPUStack[offset] = data;
380 }
381 static inline FPU_TYPE read_fpu_r(struct assembler_state_t *state, int index)
382 {
383 	return state->FPUStack[index&7];
384 }
385 static inline void write_fpu_r(struct assembler_state_t *state, int index, FPU_TYPE data)
386 {
387 	state->FPUStack[index&7] = data;
388 }
389 
390 static inline void asm_finit(struct assembler_state_t *state);
391 static inline void init_assembler_state(struct assembler_state_t *state, writecallback_t write, readcallback_t read)
392 {
393 	memset(state, 0, sizeof(*state));
394 
395 	state->cs = state->ds = state->es = state->fs = state->gs = 8;
ext2fs_set_generic_bitmap_padding(ext2fs_generic_bitmap gen_map)396 	state->ss = 4;
397 	state->esp=STACK_LENGTH;
398 	state->ebp=STACK_LENGTH;
399 
400 	state->write = write;
401 	state->read = read;
402 
403 	asm_finit(state);
404 }
405 
406 static inline void asm_movl(struct assembler_state_t *state, uint32_t src, uint32_t *dst) {*dst = src;};
407 static inline void asm_movw(struct assembler_state_t *state, uint16_t src, uint16_t *dst) {*dst = src;};
ext2fs_get_generic_bitmap_range(ext2fs_generic_bitmap gen_bmap,errcode_t magic,__u32 start,__u32 num,void * out)408 static inline void asm_movb(struct assembler_state_t *state, uint8_t src, uint8_t *dst) {*dst = src;};
409 
410 static inline void asm_leal(struct assembler_state_t *state, uint32_t src, uint32_t *dst) {*dst = src;};
411 static inline void asm_leaw(struct assembler_state_t *state, uint16_t src, uint16_t *dst) {*dst = src;};
412 static inline void asm_leab(struct assembler_state_t *state, uint8_t src, uint8_t *dst) {*dst = src;};
413 
414 
415 
416 #include "asm_emu/x86_add.h"
417 #include "asm_emu/x86_adc.h"
418 #include "asm_emu/x86_and.h"
419 #include "asm_emu/x86_cmp.h"
420 #include "asm_emu/x86_dec.h"
421 #include "asm_emu/x86_div.h"
422 #include "asm_emu/x86_fadd.h"
423 #include "asm_emu/x86_faddp.h"
424 #include "asm_emu/x86_fcom.h"
ext2fs_set_generic_bitmap_range(ext2fs_generic_bitmap gen_bmap,errcode_t magic,__u32 start,__u32 num,void * in)425 #include "asm_emu/x86_fcomp.h"
426 #include "asm_emu/x86_fcompp.h"
427 #include "asm_emu/x86_fdiv.h"
428 #include "asm_emu/x86_fdivp.h"
429 #include "asm_emu/x86_fiadd.h"
430 #include "asm_emu/x86_fidiv.h"
431 #include "asm_emu/x86_fimul.h"
432 #include "asm_emu/x86_finit.h"
433 #include "asm_emu/x86_fisub.h"
434 #include "asm_emu/x86_fisubr.h"
435 #include "asm_emu/x86_fistp.h"
436 #include "asm_emu/x86_fld.h"
437 #include "asm_emu/x86_fldz.h"
438 #include "asm_emu/x86_fmul.h"
439 #include "asm_emu/x86_fmulp.h"
440 #include "asm_emu/x86_fst.h"
441 #include "asm_emu/x86_fstp.h"
442 #include "asm_emu/x86_fstsw.h"
443 #include "asm_emu/x86_fsub.h"
444 #include "asm_emu/x86_fsubp.h"
445 #include "asm_emu/x86_fsubr.h"
446 #include "asm_emu/x86_fsubrp.h"
447 #include "asm_emu/x86_fxch.h"
448 #include "asm_emu/x86_imul.h"
449 #include "asm_emu/x86_inc.h"
450 #include "asm_emu/x86_neg.h"
451 #include "asm_emu/x86_sar.h"
452 #include "asm_emu/x86_sahf.h"
453 #include "asm_emu/x86_shl.h"
454 #include "asm_emu/x86_shld.h"
455 #include "asm_emu/x86_shr.h"
456 #include "asm_emu/x86_sbb.h"
457 #include "asm_emu/x86_stos.h"
458 #include "asm_emu/x86_sub.h"
459 #include "asm_emu/x86_test.h"
460 #include "asm_emu/x86_or.h"
461 #include "asm_emu/x86_pop.h"
462 #include "asm_emu/x86_push.h"
463 #include "asm_emu/x86_xor.h"
464 
465 #define asm_jmp(state,label)                                                                                          goto label /* Jump */
466 #define asm_ja(state,label)   if ((!read_cf((state)->eflags)&&(!read_zf((state)->eflags))))                          goto label /* Jump if above (CF=0 and ZF=0) */
467 #define asm_jae(state,label)  if (!read_cf((state)->eflags))                                                         goto label /* Jump if above or equal (CF=0) */
468 #define asm_jb(state,label)   if (read_cf((state)->eflags))                                                          goto label /* Jump if below (CF=1) */
469 #define asm_jbe(state,label)  if (read_cf((state)->eflags)||read_zf((state)->eflags))                                goto label /* Jump if below or equal (CF=1 or ZF=1) */
470 #define asm_jc(state,label)   if (read_cf((state)->eflags))                                                          goto label /* Jump if carry (CF=1) */
471 /*#define asm_jcxz(regs,label) TODO Jump if CX=0, 0x66 prefix dependen */
472 /*#define asm_jecxz(regs,label) TODO Jump if ECX=0, 0x66 prefix dependent */
473 #define asm_je(state,label)   if (read_zf((state)->eflags))                                                          goto label /* Jump if equal (ZF=1) */
474 #define asm_jg(state,label)   if ((!read_zf((state)->eflags))&&(read_of((state)->eflags)==read_sf((state)->eflags))) goto label /* Jump if greater (ZF=0 and SF=OF) */
475 #define asm_jge(state,label)  if (read_of((state)->eflags)==read_sf((state)->eflags))                                goto label /* Jump if greater or equal (SF=OF) */
476 #define asm_jl(state,label)   if (read_of((state)->eflags)!=read_sf((state)->eflags))                                goto label /* Jump if less (SF!=OF) */
477 #define asm_jle(state,label)  if (read_zf((state)->eflags)||(read_of((state)->eflags)!=read_sf((state)->eflags)))    goto label /* Jump if less or equal (ZF=1 or SF!=OF) */
478 #define asm_jna(state,label)  if (read_cf((state)->eflags)||read_zf((state)->eflags))                                goto label /* Jump if not above (CF=1 or ZF=1) */
479 #define asm_jnae(state,label) if (read_cf((state)->eflags))                                                          goto label /* Jump if not above or equal (CF=1) */
480 #define asm_jnb(state,label)  if (!read_cf((state)->eflags))                                                         goto label /* Jump if not below (CF=0) */
481 #define asm_jnbe(state,label) if ((!read_cf((state)->eflags)&&(!read_zf((state)->eflags))))                          goto label /* Jump if not below or equal (CF=0 and ZF=0) */
482 #define asm_jnc(state,label)  if (!read_cf((state)->eflags))                                                         goto label /* Jump if not carry (CF=0) */
483 #define asm_jne(state,label)  if (!read_zf((state)->eflags))                                                         goto label /* Jump if not equal (ZF=0) */
484 #define asm_jng(state,label)  if (read_zf((state)->elfags)||(read_of((state)->eflags)!=read_sf((state)->eflags)))    goto label /* Jump if not greater (ZF=1 or SF!=OF) */
485 #define asm_jnge(state,label) if (read_of((state)->eflags)!=read_sf((state)->eflags))                                goto label /* Jump if not greater of equal (SF!=OF) */
486 #define asm_jnl(state,label)  if (read_of((state)->eflags)==read_sf((state)->eflags))                                goto label /* Jump if not less (SF=OF) */
487 #define asm_jnle(state,label) if ((!read_zf((state)->eflags))&&read_of((state)->eflags)==read_sf((state)->eflags))   goto label /* Jump if not less or equal (ZF=0 and SF==OF) */
488 #define asm_jno(state,label)  if (!read_of((state)->eflags))                                                         goto label /* Jump if not overflow (OF=0) */
489 #ifdef X86_PF
490 #define asm_jnp(state,label)  if (!read_pf((state)->eflags))                                                         goto label /* Jump if not parity (PF=0) */
491 #endif
492 #define asm_jns(state,label)  if (!read_sf((state)->eflags))                                                         goto label /* Jump if not sign (SF=0) */
493 #define asm_jnz(state,label)  if (!read_zf((state)->eflags))                                                         goto label /* Jump if not zero (ZF=0) */
494 #define asm_jo(state,label)   if (read_of((state)->eflags))                                                          goto label /* Jump if overflow (OF=1) */
495 #ifdef X86_PF
496 #define asm_jp(state,label)   if (read_pf((state)->eflags))                                                          goto label /* Jump if parity (PF=1) */
497 #define asm_jpe(state,label)  if (read_pf((state)->eflags))                                                          goto label /* Jump if parity even (PF=1) */
498 #define asm_jpo(state,label)  if (!read_pf((state)->eflags))                                                         goto label /* Jump if parity odd (PF=0) */
499 #endif
500 #define asm_js(state,label)   if (read_sf((state)->eflags))                                                          goto label /* Jump if signed (SF=1) */
501 #define asm_jz(state,label)   if (read_zf((state)->eflags))                                                          goto label /* Jump if zero (ZF=1) */
502 
503 #undef ASM_X86_INTERNAL_H
504 
505 #endif
506