Commit ba1c6e37fc5efc0f3d1e50d0760f9f4a1061187b
1 parent
927f621e
test infrastructure
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@16 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
194 additions
and
43 deletions
cpu-i386.h
... | ... | @@ -85,7 +85,7 @@ typedef long double CPU86_LDouble; |
85 | 85 | typedef double CPU86_LDouble; |
86 | 86 | #endif |
87 | 87 | |
88 | -typedef struct CPU86State { | |
88 | +typedef struct CPUX86State { | |
89 | 89 | /* standard registers */ |
90 | 90 | uint32_t regs[8]; |
91 | 91 | uint32_t pc; /* cs_case + eip value */ |
... | ... | @@ -109,11 +109,8 @@ typedef struct CPU86State { |
109 | 109 | unsigned int fpuc; |
110 | 110 | |
111 | 111 | /* emulator internal variables */ |
112 | - uint32_t t0; /* temporary t0 storage */ | |
113 | - uint32_t t1; /* temporary t1 storage */ | |
114 | - uint32_t a0; /* temporary a0 storage (address) */ | |
115 | 112 | CPU86_LDouble ft0; |
116 | -} CPU86State; | |
113 | +} CPUX86State; | |
117 | 114 | |
118 | 115 | static inline int ldub(void *ptr) |
119 | 116 | { |
... | ... | @@ -188,12 +185,20 @@ static inline void stfq(void *ptr, double v) |
188 | 185 | } |
189 | 186 | |
190 | 187 | #ifndef IN_OP_I386 |
191 | -void port_outb(int addr, int val); | |
192 | -void port_outw(int addr, int val); | |
193 | -void port_outl(int addr, int val); | |
194 | -int port_inb(int addr); | |
195 | -int port_inw(int addr); | |
196 | -int port_inl(int addr); | |
188 | +void cpu_x86_outb(int addr, int val); | |
189 | +void cpu_x86_outw(int addr, int val); | |
190 | +void cpu_x86_outl(int addr, int val); | |
191 | +int cpu_x86_inb(int addr); | |
192 | +int cpu_x86_inw(int addr); | |
193 | +int cpu_x86_inl(int addr); | |
197 | 194 | #endif |
198 | 195 | |
196 | +CPUX86State *cpu_x86_init(void); | |
197 | +int cpu_x86_exec(CPUX86State *s); | |
198 | +void cpu_x86_close(CPUX86State *s); | |
199 | + | |
200 | +/* internal functions */ | |
201 | +int cpu_x86_gen_code(uint8_t *gen_code_buf, int *gen_code_size_ptr, | |
202 | + uint8_t *pc_start); | |
203 | + | |
199 | 204 | #endif /* CPU_I386_H */ | ... | ... |
linux-user/main.c
... | ... | @@ -193,34 +193,34 @@ void INT_handler(int num, void *env) |
193 | 193 | /***********************************************************/ |
194 | 194 | /* new CPU core */ |
195 | 195 | |
196 | -void port_outb(int addr, int val) | |
196 | +void cpu_x86_outb(int addr, int val) | |
197 | 197 | { |
198 | 198 | fprintf(stderr, "outb: port=0x%04x, data=%02x\n", addr, val); |
199 | 199 | } |
200 | 200 | |
201 | -void port_outw(int addr, int val) | |
201 | +void cpu_x86_outw(int addr, int val) | |
202 | 202 | { |
203 | 203 | fprintf(stderr, "outw: port=0x%04x, data=%04x\n", addr, val); |
204 | 204 | } |
205 | 205 | |
206 | -void port_outl(int addr, int val) | |
206 | +void cpu_x86_outl(int addr, int val) | |
207 | 207 | { |
208 | 208 | fprintf(stderr, "outl: port=0x%04x, data=%08x\n", addr, val); |
209 | 209 | } |
210 | 210 | |
211 | -int port_inb(int addr) | |
211 | +int cpu_x86_inb(int addr) | |
212 | 212 | { |
213 | 213 | fprintf(stderr, "inb: port=0x%04x\n", addr); |
214 | 214 | return 0; |
215 | 215 | } |
216 | 216 | |
217 | -int port_inw(int addr) | |
217 | +int cpu_x86_inw(int addr) | |
218 | 218 | { |
219 | 219 | fprintf(stderr, "inw: port=0x%04x\n", addr); |
220 | 220 | return 0; |
221 | 221 | } |
222 | 222 | |
223 | -int port_inl(int addr) | |
223 | +int cpu_x86_inl(int addr) | |
224 | 224 | { |
225 | 225 | fprintf(stderr, "inl: port=0x%04x\n", addr); |
226 | 226 | return 0; | ... | ... |
op-i386.c
... | ... | @@ -10,39 +10,44 @@ typedef signed long long int64_t; |
10 | 10 | |
11 | 11 | #define NULL 0 |
12 | 12 | |
13 | +typedef struct FILE FILE; | |
14 | + | |
15 | +extern FILE *stderr; | |
16 | +extern int fprintf(FILE *, const char *, ...); | |
17 | + | |
13 | 18 | #ifdef __i386__ |
14 | 19 | register int T0 asm("esi"); |
15 | 20 | register int T1 asm("ebx"); |
16 | 21 | register int A0 asm("edi"); |
17 | -register struct CPU86State *env asm("ebp"); | |
22 | +register struct CPUX86State *env asm("ebp"); | |
18 | 23 | #define FORCE_RET() asm volatile ("ret"); |
19 | 24 | #endif |
20 | 25 | #ifdef __powerpc__ |
21 | 26 | register int T0 asm("r24"); |
22 | 27 | register int T1 asm("r25"); |
23 | 28 | register int A0 asm("r26"); |
24 | -register struct CPU86State *env asm("r27"); | |
29 | +register struct CPUX86State *env asm("r27"); | |
25 | 30 | #define FORCE_RET() asm volatile ("blr"); |
26 | 31 | #endif |
27 | 32 | #ifdef __arm__ |
28 | 33 | register int T0 asm("r4"); |
29 | 34 | register int T1 asm("r5"); |
30 | 35 | register int A0 asm("r6"); |
31 | -register struct CPU86State *env asm("r7"); | |
36 | +register struct CPUX86State *env asm("r7"); | |
32 | 37 | #define FORCE_RET() asm volatile ("mov pc, lr"); |
33 | 38 | #endif |
34 | 39 | #ifdef __mips__ |
35 | 40 | register int T0 asm("s0"); |
36 | 41 | register int T1 asm("s1"); |
37 | 42 | register int A0 asm("s2"); |
38 | -register struct CPU86State *env asm("s3"); | |
43 | +register struct CPUX86State *env asm("s3"); | |
39 | 44 | #define FORCE_RET() asm volatile ("jr $31"); |
40 | 45 | #endif |
41 | 46 | #ifdef __sparc__ |
42 | 47 | register int T0 asm("l0"); |
43 | 48 | register int T1 asm("l1"); |
44 | 49 | register int A0 asm("l2"); |
45 | -register struct CPU86State *env asm("l3"); | |
50 | +register struct CPUX86State *env asm("l3"); | |
46 | 51 | #define FORCE_RET() asm volatile ("retl ; nop"); |
47 | 52 | #endif |
48 | 53 | |
... | ... | @@ -465,17 +470,17 @@ void OPPROTO op_idivl_EAX_T0(void) |
465 | 470 | |
466 | 471 | /* constant load */ |
467 | 472 | |
468 | -void OPPROTO op1_movl_T0_im(void) | |
473 | +void OPPROTO op_movl_T0_im(void) | |
469 | 474 | { |
470 | 475 | T0 = PARAM1; |
471 | 476 | } |
472 | 477 | |
473 | -void OPPROTO op1_movl_T1_im(void) | |
478 | +void OPPROTO op_movl_T1_im(void) | |
474 | 479 | { |
475 | 480 | T1 = PARAM1; |
476 | 481 | } |
477 | 482 | |
478 | -void OPPROTO op1_movl_A0_im(void) | |
483 | +void OPPROTO op_movl_A0_im(void) | |
479 | 484 | { |
480 | 485 | A0 = PARAM1; |
481 | 486 | } |
... | ... | @@ -1592,3 +1597,35 @@ void OPPROTO op_fcos(void) |
1592 | 1597 | helper_fcos(); |
1593 | 1598 | } |
1594 | 1599 | |
1600 | +/* main execution loop */ | |
1601 | +uint8_t code_gen_buffer[65536]; | |
1602 | + | |
1603 | + | |
1604 | +int cpu_x86_exec(CPUX86State *env1) | |
1605 | +{ | |
1606 | + int saved_T0, saved_T1, saved_A0; | |
1607 | + CPUX86State *saved_env; | |
1608 | + int code_gen_size; | |
1609 | + void (*gen_func)(void); | |
1610 | + | |
1611 | + /* first we save global registers */ | |
1612 | + saved_T0 = T0; | |
1613 | + saved_T1 = T1; | |
1614 | + saved_A0 = A0; | |
1615 | + saved_env = env; | |
1616 | + env = env1; | |
1617 | + | |
1618 | + for(;;) { | |
1619 | + cpu_x86_gen_code(code_gen_buffer, &code_gen_size, (uint8_t *)env->pc); | |
1620 | + /* execute the generated code */ | |
1621 | + gen_func = (void *)code_gen_buffer; | |
1622 | + gen_func(); | |
1623 | + } | |
1624 | + | |
1625 | + /* restore global registers */ | |
1626 | + T0 = saved_T0; | |
1627 | + T1 = saved_T1; | |
1628 | + A0 = saved_A0; | |
1629 | + env = saved_env; | |
1630 | + return 0; | |
1631 | +} | ... | ... |
ops_template.h
... | ... | @@ -575,12 +575,14 @@ void OPPROTO glue(op_repnz_cmps, SUFFIX)(void) |
575 | 575 | } |
576 | 576 | } |
577 | 577 | |
578 | +/* port I/O */ | |
579 | + | |
578 | 580 | void OPPROTO glue(op_outs, SUFFIX)(void) |
579 | 581 | { |
580 | 582 | int v, dx; |
581 | 583 | dx = EDX & 0xffff; |
582 | 584 | v = glue(ldu, SUFFIX)((void *)ESI); |
583 | - glue(port_out, SUFFIX)(dx, v); | |
585 | + glue(cpu_x86_out, SUFFIX)(dx, v); | |
584 | 586 | ESI += (DF << SHIFT); |
585 | 587 | } |
586 | 588 | |
... | ... | @@ -591,7 +593,7 @@ void OPPROTO glue(op_rep_outs, SUFFIX)(void) |
591 | 593 | dx = EDX & 0xffff; |
592 | 594 | while (ECX != 0) { |
593 | 595 | v = glue(ldu, SUFFIX)((void *)ESI); |
594 | - glue(port_out, SUFFIX)(dx, v); | |
596 | + glue(cpu_x86_out, SUFFIX)(dx, v); | |
595 | 597 | ESI += inc; |
596 | 598 | ECX--; |
597 | 599 | } |
... | ... | @@ -601,7 +603,7 @@ void OPPROTO glue(op_ins, SUFFIX)(void) |
601 | 603 | { |
602 | 604 | int v, dx; |
603 | 605 | dx = EDX & 0xffff; |
604 | - v = glue(port_in, SUFFIX)(dx); | |
606 | + v = glue(cpu_x86_in, SUFFIX)(dx); | |
605 | 607 | glue(st, SUFFIX)((void *)EDI, v); |
606 | 608 | EDI += (DF << SHIFT); |
607 | 609 | } |
... | ... | @@ -612,13 +614,23 @@ void OPPROTO glue(op_rep_ins, SUFFIX)(void) |
612 | 614 | inc = (DF << SHIFT); |
613 | 615 | dx = EDX & 0xffff; |
614 | 616 | while (ECX != 0) { |
615 | - v = glue(port_in, SUFFIX)(dx); | |
617 | + v = glue(cpu_x86_in, SUFFIX)(dx); | |
616 | 618 | glue(st, SUFFIX)((void *)EDI, v); |
617 | 619 | EDI += (DF << SHIFT); |
618 | 620 | ECX--; |
619 | 621 | } |
620 | 622 | } |
621 | 623 | |
624 | +void OPPROTO glue(glue(op_out, SUFFIX), _T0_T1)(void) | |
625 | +{ | |
626 | + glue(cpu_x86_out, SUFFIX)(T0 & 0xffff, T1 & DATA_MASK); | |
627 | +} | |
628 | + | |
629 | +void OPPROTO glue(glue(op_in, SUFFIX), _T0_T1)(void) | |
630 | +{ | |
631 | + T1 = glue(cpu_x86_in, SUFFIX)(T0 & 0xffff); | |
632 | +} | |
633 | + | |
622 | 634 | #undef DATA_BITS |
623 | 635 | #undef SHIFT_MASK |
624 | 636 | #undef SIGN_MASK | ... | ... |
translate-i386.c
... | ... | @@ -495,6 +495,18 @@ static GenOpFunc *gen_op_outs[6] = { |
495 | 495 | gen_op_rep_outsl, |
496 | 496 | }; |
497 | 497 | |
498 | +static GenOpFunc *gen_op_in[3] = { | |
499 | + gen_op_inb_T0_T1, | |
500 | + gen_op_inw_T0_T1, | |
501 | + gen_op_inl_T0_T1, | |
502 | +}; | |
503 | + | |
504 | +static GenOpFunc *gen_op_out[3] = { | |
505 | + gen_op_outb_T0_T1, | |
506 | + gen_op_outw_T0_T1, | |
507 | + gen_op_outl_T0_T1, | |
508 | +}; | |
509 | + | |
498 | 510 | enum { |
499 | 511 | JCC_O, |
500 | 512 | JCC_B, |
... | ... | @@ -632,7 +644,7 @@ static void gen_op(DisasContext *s1, int op, int ot, int d, int s) |
632 | 644 | |
633 | 645 | static void gen_opi(DisasContext *s1, int op, int ot, int d, int c) |
634 | 646 | { |
635 | - gen_op1_movl_T1_im(c); | |
647 | + gen_op_movl_T1_im(c); | |
636 | 648 | gen_op(s1, op, ot, d, OR_TMP0); |
637 | 649 | } |
638 | 650 | |
... | ... | @@ -678,7 +690,7 @@ static void gen_shift(DisasContext *s1, int op, int ot, int d, int s) |
678 | 690 | static void gen_shifti(DisasContext *s1, int op, int ot, int d, int c) |
679 | 691 | { |
680 | 692 | /* currently not optimized */ |
681 | - gen_op1_movl_T1_im(c); | |
693 | + gen_op_movl_T1_im(c); | |
682 | 694 | gen_shift(s1, op, ot, d, OR_TMP1); |
683 | 695 | } |
684 | 696 | |
... | ... | @@ -746,7 +758,7 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ |
746 | 758 | if (reg2 == OR_ZERO) { |
747 | 759 | /* op: disp + (reg1 << scale) */ |
748 | 760 | if (reg1 == OR_ZERO) { |
749 | - gen_op1_movl_A0_im(disp); | |
761 | + gen_op_movl_A0_im(disp); | |
750 | 762 | } else if (scale == 0 && disp == 0) { |
751 | 763 | gen_op_movl_A0_reg[reg1](); |
752 | 764 | } else { |
... | ... | @@ -755,7 +767,7 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ |
755 | 767 | } else { |
756 | 768 | /* op: disp + reg1 + (reg2 << scale) */ |
757 | 769 | if (disp != 0) { |
758 | - gen_op1_movl_A0_im(disp); | |
770 | + gen_op_movl_A0_im(disp); | |
759 | 771 | gen_op_addl_A0_reg_sN[0][reg1](); |
760 | 772 | } else { |
761 | 773 | gen_op_movl_A0_reg[reg1](); |
... | ... | @@ -1149,7 +1161,7 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) |
1149 | 1161 | switch(op) { |
1150 | 1162 | case 0: /* test */ |
1151 | 1163 | val = insn_get(s, ot); |
1152 | - gen_op1_movl_T1_im(val); | |
1164 | + gen_op_movl_T1_im(val); | |
1153 | 1165 | gen_op_testl_T0_T1_cc(); |
1154 | 1166 | s->cc_op = CC_OP_LOGICB + ot; |
1155 | 1167 | break; |
... | ... | @@ -1266,7 +1278,7 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) |
1266 | 1278 | gen_op_st_T0_A0[ot](); |
1267 | 1279 | break; |
1268 | 1280 | case 2: /* call Ev */ |
1269 | - gen_op1_movl_T1_im((long)s->pc); | |
1281 | + gen_op_movl_T1_im((long)s->pc); | |
1270 | 1282 | gen_op_pushl_T1(); |
1271 | 1283 | gen_op_jmp_T0(); |
1272 | 1284 | break; |
... | ... | @@ -1309,7 +1321,7 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) |
1309 | 1321 | val = insn_get(s, ot); |
1310 | 1322 | |
1311 | 1323 | gen_op_mov_TN_reg[ot][0][OR_EAX](); |
1312 | - gen_op1_movl_T1_im(val); | |
1324 | + gen_op_movl_T1_im(val); | |
1313 | 1325 | gen_op_testl_T0_T1_cc(); |
1314 | 1326 | s->cc_op = CC_OP_LOGICB + ot; |
1315 | 1327 | break; |
... | ... | @@ -1336,10 +1348,10 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) |
1336 | 1348 | gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0); |
1337 | 1349 | if (b == 0x69) { |
1338 | 1350 | val = insn_get(s, ot); |
1339 | - gen_op1_movl_T1_im(val); | |
1351 | + gen_op_movl_T1_im(val); | |
1340 | 1352 | } else if (b == 0x6b) { |
1341 | 1353 | val = insn_get(s, OT_BYTE); |
1342 | - gen_op1_movl_T1_im(val); | |
1354 | + gen_op_movl_T1_im(val); | |
1343 | 1355 | } else { |
1344 | 1356 | gen_op_mov_TN_reg[ot][1][reg](); |
1345 | 1357 | } |
... | ... | @@ -1369,7 +1381,7 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) |
1369 | 1381 | val = insn_get(s, ot); |
1370 | 1382 | else |
1371 | 1383 | val = (int8_t)insn_get(s, OT_BYTE); |
1372 | - gen_op1_movl_T0_im(val); | |
1384 | + gen_op_movl_T0_im(val); | |
1373 | 1385 | gen_op_pushl_T0(); |
1374 | 1386 | break; |
1375 | 1387 | case 0x8f: /* pop Ev */ |
... | ... | @@ -1408,7 +1420,7 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) |
1408 | 1420 | mod = (modrm >> 6) & 3; |
1409 | 1421 | |
1410 | 1422 | val = insn_get(s, ot); |
1411 | - gen_op1_movl_T0_im(val); | |
1423 | + gen_op_movl_T0_im(val); | |
1412 | 1424 | gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1); |
1413 | 1425 | break; |
1414 | 1426 | case 0x8a: |
... | ... | @@ -1502,14 +1514,14 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) |
1502 | 1514 | |
1503 | 1515 | case 0xb0 ... 0xb7: /* mov R, Ib */ |
1504 | 1516 | val = insn_get(s, OT_BYTE); |
1505 | - gen_op1_movl_T0_im(val); | |
1517 | + gen_op_movl_T0_im(val); | |
1506 | 1518 | gen_op_mov_reg_T0[OT_BYTE][b & 7](); |
1507 | 1519 | break; |
1508 | 1520 | case 0xb8 ... 0xbf: /* mov R, Iv */ |
1509 | 1521 | ot = dflag ? OT_LONG : OT_WORD; |
1510 | 1522 | val = insn_get(s, ot); |
1511 | 1523 | reg = OR_EAX + (b & 7); |
1512 | - gen_op1_movl_T0_im(val); | |
1524 | + gen_op_movl_T0_im(val); | |
1513 | 1525 | gen_op_mov_reg_T0[ot][reg](); |
1514 | 1526 | break; |
1515 | 1527 | |
... | ... | @@ -1978,6 +1990,8 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) |
1978 | 1990 | } |
1979 | 1991 | break; |
1980 | 1992 | |
1993 | + /************************/ | |
1994 | + /* port I/O */ | |
1981 | 1995 | case 0x6c: /* insS */ |
1982 | 1996 | case 0x6d: |
1983 | 1997 | if ((b & 1) == 0) |
... | ... | @@ -2002,6 +2016,48 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) |
2002 | 2016 | gen_op_outs[ot](); |
2003 | 2017 | } |
2004 | 2018 | break; |
2019 | + case 0xe4: | |
2020 | + case 0xe5: | |
2021 | + if ((b & 1) == 0) | |
2022 | + ot = OT_BYTE; | |
2023 | + else | |
2024 | + ot = dflag ? OT_LONG : OT_WORD; | |
2025 | + val = ldub(s->pc++); | |
2026 | + gen_op_movl_T0_im(val); | |
2027 | + gen_op_in[ot](); | |
2028 | + gen_op_mov_reg_T1[ot][R_EAX](); | |
2029 | + break; | |
2030 | + case 0xe6: | |
2031 | + case 0xe7: | |
2032 | + if ((b & 1) == 0) | |
2033 | + ot = OT_BYTE; | |
2034 | + else | |
2035 | + ot = dflag ? OT_LONG : OT_WORD; | |
2036 | + val = ldub(s->pc++); | |
2037 | + gen_op_movl_T0_im(val); | |
2038 | + gen_op_mov_TN_reg[ot][1][R_EAX](); | |
2039 | + gen_op_out[ot](); | |
2040 | + break; | |
2041 | + case 0xec: | |
2042 | + case 0xed: | |
2043 | + if ((b & 1) == 0) | |
2044 | + ot = OT_BYTE; | |
2045 | + else | |
2046 | + ot = dflag ? OT_LONG : OT_WORD; | |
2047 | + gen_op_mov_TN_reg[OT_WORD][0][R_EDX](); | |
2048 | + gen_op_in[ot](); | |
2049 | + gen_op_mov_reg_T1[ot][R_EAX](); | |
2050 | + break; | |
2051 | + case 0xee: | |
2052 | + case 0xef: | |
2053 | + if ((b & 1) == 0) | |
2054 | + ot = OT_BYTE; | |
2055 | + else | |
2056 | + ot = dflag ? OT_LONG : OT_WORD; | |
2057 | + gen_op_mov_TN_reg[OT_WORD][0][R_EDX](); | |
2058 | + gen_op_mov_TN_reg[ot][1][R_EAX](); | |
2059 | + gen_op_out[ot](); | |
2060 | + break; | |
2005 | 2061 | |
2006 | 2062 | /************************/ |
2007 | 2063 | /* control */ |
... | ... | @@ -2020,7 +2076,7 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) |
2020 | 2076 | case 0xe8: /* call */ |
2021 | 2077 | val = insn_get(s, OT_LONG); |
2022 | 2078 | val += (long)s->pc; |
2023 | - gen_op1_movl_T1_im((long)s->pc); | |
2079 | + gen_op_movl_T1_im((long)s->pc); | |
2024 | 2080 | gen_op_pushl_T1(); |
2025 | 2081 | gen_op_jmp_im(val); |
2026 | 2082 | break; |
... | ... | @@ -2121,3 +2177,44 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) |
2121 | 2177 | return (long)s->pc; |
2122 | 2178 | } |
2123 | 2179 | |
2180 | +/* return the next pc */ | |
2181 | +int cpu_x86_gen_code(uint8_t *gen_code_buf, int *gen_code_size_ptr, | |
2182 | + uint8_t *pc_start) | |
2183 | +{ | |
2184 | + DisasContext dc1, *dc = &dc1; | |
2185 | + long ret; | |
2186 | + dc->cc_op = CC_OP_DYNAMIC; | |
2187 | + gen_code_ptr = gen_code_buf; | |
2188 | + gen_start(); | |
2189 | + ret = disas_insn(dc, pc_start); | |
2190 | + if (ret == -1) | |
2191 | + error("unknown instruction at PC=0x%x", pc_start); | |
2192 | + gen_end(); | |
2193 | + *gen_code_size_ptr = gen_code_ptr - gen_code_buf; | |
2194 | + printf("0x%08lx: code_size = %d\n", (long)pc_start, *gen_code_size_ptr); | |
2195 | + return 0; | |
2196 | +} | |
2197 | + | |
2198 | +CPUX86State *cpu_x86_init(void) | |
2199 | +{ | |
2200 | + CPUX86State *env; | |
2201 | + int i; | |
2202 | + | |
2203 | + env = malloc(sizeof(CPUX86State)); | |
2204 | + if (!env) | |
2205 | + return NULL; | |
2206 | + memset(env, 0, sizeof(CPUX86State)); | |
2207 | + /* basic FPU init */ | |
2208 | + for(i = 0;i < 8; i++) | |
2209 | + env->fptags[i] = 1; | |
2210 | + env->fpuc = 0x37f; | |
2211 | + /* flags setup */ | |
2212 | + env->cc_op = CC_OP_EFLAGS; | |
2213 | + env->df = 1; | |
2214 | + return env; | |
2215 | +} | |
2216 | + | |
2217 | +void cpu_x86_close(CPUX86State *env) | |
2218 | +{ | |
2219 | + free(env); | |
2220 | +} | ... | ... |