Revision 7d13299d op-i386.c

b/op-i386.c
1
#define DEBUG_EXEC
2

  
3
typedef unsigned char uint8_t;
4
typedef unsigned short uint16_t;
5
typedef unsigned int uint32_t;
6
typedef unsigned long long uint64_t;
7

  
8
typedef signed char int8_t;
9
typedef signed short int16_t;
10
typedef signed int int32_t;
11
typedef signed long long int64_t;
12

  
13
#define bswap32(x) \
14
({ \
15
	uint32_t __x = (x); \
16
	((uint32_t)( \
17
		(((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
18
		(((uint32_t)(__x) & (uint32_t)0x0000ff00UL) <<  8) | \
19
		(((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >>  8) | \
20
		(((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) )); \
21
})
22

  
23
#define NULL 0
24
#include <fenv.h>
25

  
26
typedef struct FILE FILE;
27
extern FILE *logfile;
28
extern int loglevel;
29
extern int fprintf(FILE *, const char *, ...);
30

  
31
#ifdef __i386__
32
register unsigned int T0 asm("ebx");
33
register unsigned int T1 asm("esi");
34
register unsigned int A0 asm("edi");
35
register struct CPUX86State *env asm("ebp");
36
#endif
37
#ifdef __powerpc__
38
register unsigned int T0 asm("r24");
39
register unsigned int T1 asm("r25");
40
register unsigned int A0 asm("r26");
41
register struct CPUX86State *env asm("r27");
42
#endif
43
#ifdef __arm__
44
register unsigned int T0 asm("r4");
45
register unsigned int T1 asm("r5");
46
register unsigned int A0 asm("r6");
47
register struct CPUX86State *env asm("r7");
48
#endif
49
#ifdef __mips__
50
register unsigned int T0 asm("s0");
51
register unsigned int T1 asm("s1");
52
register unsigned int A0 asm("s2");
53
register struct CPUX86State *env asm("s3");
54
#endif
55
#ifdef __sparc__
56
register unsigned int T0 asm("l0");
57
register unsigned int T1 asm("l1");
58
register unsigned int A0 asm("l2");
59
register struct CPUX86State *env asm("l3");
60
#endif
61

  
62
/* force GCC to generate only one epilog at the end of the function */
63
#define FORCE_RET() asm volatile ("");
64

  
65
#ifndef OPPROTO
66
#define OPPROTO
67
#endif
68

  
69
#define xglue(x, y) x ## y
70
#define glue(x, y) xglue(x, y)
71

  
72
#define EAX (env->regs[R_EAX])
73
#define ECX (env->regs[R_ECX])
74
#define EDX (env->regs[R_EDX])
75
#define EBX (env->regs[R_EBX])
76
#define ESP (env->regs[R_ESP])
77
#define EBP (env->regs[R_EBP])
78
#define ESI (env->regs[R_ESI])
79
#define EDI (env->regs[R_EDI])
80
#define PC  (env->pc)
81
#define DF  (env->df)
82

  
83
#define CC_SRC (env->cc_src)
84
#define CC_DST (env->cc_dst)
85
#define CC_OP  (env->cc_op)
86

  
87
/* float macros */
88
#define FT0    (env->ft0)
89
#define ST0    (env->fpregs[env->fpstt])
90
#define ST(n)  (env->fpregs[(env->fpstt + (n)) & 7])
91
#define ST1    ST(1)
92

  
93
extern int __op_param1, __op_param2, __op_param3;
94
#define PARAM1 ((long)(&__op_param1))
95
#define PARAM2 ((long)(&__op_param2))
96
#define PARAM3 ((long)(&__op_param3))
97

  
98
#include "cpu-i386.h"
99

  
100
typedef struct CCTable {
101
    int (*compute_all)(void); /* return all the flags */
102
    int (*compute_c)(void);  /* return the C flag */
103
} CCTable;
1
/*
2
 *  i386 micro operations
3
 * 
4
 *  Copyright (c) 2003 Fabrice Bellard
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
#include "exec-i386.h"
104 21

  
105 22
/* NOTE: data are not static to force relocation generation by GCC */
106
extern CCTable cc_table[];
107 23

  
108 24
uint8_t parity_table[256] = {
109 25
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
......
1878 1794
    fesetround(rnd_type);
1879 1795
}
1880 1796

  
1881
/* main execution loop */
1882
uint8_t code_gen_buffer[65536];
1883

  
1884
#ifdef DEBUG_EXEC
1885
static const char *cc_op_str[] = {
1886
    "DYNAMIC",
1887
    "EFLAGS",
1888
    "MUL",
1889
    "ADDB",
1890
    "ADDW",
1891
    "ADDL",
1892
    "ADCB",
1893
    "ADCW",
1894
    "ADCL",
1895
    "SUBB",
1896
    "SUBW",
1897
    "SUBL",
1898
    "SBBB",
1899
    "SBBW",
1900
    "SBBL",
1901
    "LOGICB",
1902
    "LOGICW",
1903
    "LOGICL",
1904
    "INCB",
1905
    "INCW",
1906
    "INCL",
1907
    "DECB",
1908
    "DECW",
1909
    "DECL",
1910
    "SHLB",
1911
    "SHLW",
1912
    "SHLL",
1913
    "SARB",
1914
    "SARW",
1915
    "SARL",
1916
};
1917
#endif
1918

  
1919
int cpu_x86_exec(CPUX86State *env1)
1920
{
1921
    int saved_T0, saved_T1, saved_A0;
1922
    CPUX86State *saved_env;
1923
    int code_gen_size, ret;
1924
    void (*gen_func)(void);
1925

  
1926
    /* first we save global registers */
1927
    saved_T0 = T0;
1928
    saved_T1 = T1;
1929
    saved_A0 = A0;
1930
    saved_env = env;
1931
    env = env1;
1932
    
1933
    /* prepare setjmp context for exception handling */
1934
    if (setjmp(env->jmp_env) == 0) {
1935
        for(;;) {
1936
#ifdef DEBUG_EXEC
1937
            if (loglevel) {
1938
                int eflags;
1939
                eflags = cc_table[CC_OP].compute_all();
1940
                eflags |= (DF & DIRECTION_FLAG);
1941
                fprintf(logfile, 
1942
                        "EAX=%08x EBX=%08X ECX=%08x EDX=%08x\n"
1943
                        "ESI=%08x EDI=%08X EBP=%08x ESP=%08x\n"
1944
                        "CCS=%08x CCD=%08x CCO=%-8s EFL=%c%c%c%c%c%c%c\n",
1945
                        env->regs[R_EAX], env->regs[R_EBX], env->regs[R_ECX], env->regs[R_EDX], 
1946
                        env->regs[R_ESI], env->regs[R_EDI], env->regs[R_EBP], env->regs[R_ESP], 
1947
                        env->cc_src, env->cc_dst, cc_op_str[env->cc_op],
1948
                        eflags & DIRECTION_FLAG ? 'D' : '-',
1949
                        eflags & CC_O ? 'O' : '-',
1950
                        eflags & CC_S ? 'S' : '-',
1951
                        eflags & CC_Z ? 'Z' : '-',
1952
                        eflags & CC_A ? 'A' : '-',
1953
                        eflags & CC_P ? 'P' : '-',
1954
                        eflags & CC_C ? 'C' : '-'
1955
                        );
1956
#if 1
1957
                fprintf(logfile, "ST0=%f ST1=%f ST2=%f ST3=%f\n", 
1958
                        (double)ST0, (double)ST1, (double)ST(2), (double)ST(3));
1959
#endif
1960
            }
1961
#endif
1962
            cpu_x86_gen_code(code_gen_buffer, sizeof(code_gen_buffer), 
1963
                             &code_gen_size, (uint8_t *)env->pc);
1964
            /* execute the generated code */
1965
            gen_func = (void *)code_gen_buffer;
1966
            gen_func();
1967
        }
1968
    }
1969
    ret = env->exception_index;
1970

  
1971
    /* restore global registers */
1972
    T0 = saved_T0;
1973
    T1 = saved_T1;
1974
    A0 = saved_A0;
1975
    env = saved_env;
1976
    return ret;
1977
}

Also available in: Unified diff