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