Revision ba1c6e37

b/cpu-i386.h
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 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 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 */
b/linux-user/main.c
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;
b/op-i386.c
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 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 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
}
b/ops_template.h
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 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 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 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
b/translate-i386.c
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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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
}

Also available in: Unified diff