root / op-i386.c @ 367e86e8
History | View | Annotate | Download (16.1 kB)
1 | 7bfdb6d1 | bellard | typedef unsigned char uint8_t; |
---|---|---|---|
2 | 7bfdb6d1 | bellard | typedef unsigned short uint16_t; |
3 | 7bfdb6d1 | bellard | typedef unsigned int uint32_t; |
4 | 7bfdb6d1 | bellard | typedef unsigned long long uint64_t; |
5 | 7bfdb6d1 | bellard | |
6 | 7bfdb6d1 | bellard | typedef signed char int8_t; |
7 | 7bfdb6d1 | bellard | typedef signed short int16_t; |
8 | 7bfdb6d1 | bellard | typedef signed int int32_t; |
9 | 7bfdb6d1 | bellard | typedef signed long long int64_t; |
10 | 7bfdb6d1 | bellard | |
11 | 367e86e8 | bellard | #define NULL 0 |
12 | 367e86e8 | bellard | |
13 | 7bfdb6d1 | bellard | #ifdef __i386__
|
14 | 7bfdb6d1 | bellard | register int T0 asm("esi"); |
15 | 7bfdb6d1 | bellard | register int T1 asm("ebx"); |
16 | 7bfdb6d1 | bellard | register int A0 asm("edi"); |
17 | 7bfdb6d1 | bellard | register struct CPU86State *env asm("ebp"); |
18 | 7bfdb6d1 | bellard | #define FORCE_RET() asm volatile ("ret"); |
19 | 7bfdb6d1 | bellard | #endif
|
20 | 7bfdb6d1 | bellard | #ifdef __powerpc__
|
21 | 7bfdb6d1 | bellard | register int T0 asm("r24"); |
22 | 7bfdb6d1 | bellard | register int T1 asm("r25"); |
23 | 7bfdb6d1 | bellard | register int A0 asm("r26"); |
24 | 7bfdb6d1 | bellard | register struct CPU86State *env asm("r27"); |
25 | 7bfdb6d1 | bellard | #define FORCE_RET() asm volatile ("blr"); |
26 | 7bfdb6d1 | bellard | #endif
|
27 | 7bfdb6d1 | bellard | #ifdef __arm__
|
28 | 7bfdb6d1 | bellard | register int T0 asm("r4"); |
29 | 7bfdb6d1 | bellard | register int T1 asm("r5"); |
30 | 7bfdb6d1 | bellard | register int A0 asm("r6"); |
31 | 7bfdb6d1 | bellard | register struct CPU86State *env asm("r7"); |
32 | 7bfdb6d1 | bellard | #define FORCE_RET() asm volatile ("mov pc, lr"); |
33 | 7bfdb6d1 | bellard | #endif
|
34 | 7bfdb6d1 | bellard | #ifdef __mips__
|
35 | 7bfdb6d1 | bellard | register int T0 asm("s0"); |
36 | 7bfdb6d1 | bellard | register int T1 asm("s1"); |
37 | 7bfdb6d1 | bellard | register int A0 asm("s2"); |
38 | 7bfdb6d1 | bellard | register struct CPU86State *env asm("s3"); |
39 | 7bfdb6d1 | bellard | #define FORCE_RET() asm volatile ("jr $31"); |
40 | 7bfdb6d1 | bellard | #endif
|
41 | 7bfdb6d1 | bellard | #ifdef __sparc__
|
42 | 7bfdb6d1 | bellard | register int T0 asm("l0"); |
43 | 7bfdb6d1 | bellard | register int T1 asm("l1"); |
44 | 7bfdb6d1 | bellard | register int A0 asm("l2"); |
45 | 7bfdb6d1 | bellard | register struct CPU86State *env asm("l3"); |
46 | 7bfdb6d1 | bellard | #define FORCE_RET() asm volatile ("retl ; nop"); |
47 | 7bfdb6d1 | bellard | #endif
|
48 | 7bfdb6d1 | bellard | |
49 | 7bfdb6d1 | bellard | #ifndef OPPROTO
|
50 | 7bfdb6d1 | bellard | #define OPPROTO
|
51 | 7bfdb6d1 | bellard | #endif
|
52 | 7bfdb6d1 | bellard | |
53 | 7bfdb6d1 | bellard | #define xglue(x, y) x ## y |
54 | 7bfdb6d1 | bellard | #define glue(x, y) xglue(x, y)
|
55 | 7bfdb6d1 | bellard | |
56 | 7bfdb6d1 | bellard | #define EAX (env->regs[R_EAX])
|
57 | 7bfdb6d1 | bellard | #define ECX (env->regs[R_ECX])
|
58 | 7bfdb6d1 | bellard | #define EDX (env->regs[R_EDX])
|
59 | 7bfdb6d1 | bellard | #define EBX (env->regs[R_EBX])
|
60 | 7bfdb6d1 | bellard | #define ESP (env->regs[R_ESP])
|
61 | 7bfdb6d1 | bellard | #define EBP (env->regs[R_EBP])
|
62 | 7bfdb6d1 | bellard | #define ESI (env->regs[R_ESI])
|
63 | 7bfdb6d1 | bellard | #define EDI (env->regs[R_EDI])
|
64 | 7bfdb6d1 | bellard | #define PC (env->pc)
|
65 | 7bfdb6d1 | bellard | #define DF (env->df)
|
66 | 7bfdb6d1 | bellard | |
67 | 7bfdb6d1 | bellard | #define CC_SRC (env->cc_src)
|
68 | 7bfdb6d1 | bellard | #define CC_DST (env->cc_dst)
|
69 | 7bfdb6d1 | bellard | #define CC_OP (env->cc_op)
|
70 | 7bfdb6d1 | bellard | |
71 | 7bfdb6d1 | bellard | extern int __op_param1, __op_param2, __op_param3; |
72 | 7bfdb6d1 | bellard | #define PARAM1 ((long)(&__op_param1)) |
73 | 7bfdb6d1 | bellard | #define PARAM2 ((long)(&__op_param2)) |
74 | 7bfdb6d1 | bellard | #define PARAM3 ((long)(&__op_param3)) |
75 | 7bfdb6d1 | bellard | |
76 | 7bfdb6d1 | bellard | #include "cpu-i386.h" |
77 | 7bfdb6d1 | bellard | |
78 | 7bfdb6d1 | bellard | typedef struct CCTable { |
79 | 7bfdb6d1 | bellard | int (*compute_all)(void); /* return all the flags */ |
80 | 367e86e8 | bellard | int (*compute_c)(void); /* return the C flag */ |
81 | 7bfdb6d1 | bellard | } CCTable; |
82 | 7bfdb6d1 | bellard | |
83 | 367e86e8 | bellard | extern CCTable cc_table[];
|
84 | 367e86e8 | bellard | |
85 | 7bfdb6d1 | bellard | uint8_t parity_table[256] = {
|
86 | 7bfdb6d1 | bellard | CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, |
87 | 7bfdb6d1 | bellard | 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, |
88 | 7bfdb6d1 | bellard | 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, |
89 | 7bfdb6d1 | bellard | CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, |
90 | 7bfdb6d1 | bellard | 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, |
91 | 7bfdb6d1 | bellard | CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, |
92 | 7bfdb6d1 | bellard | CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, |
93 | 7bfdb6d1 | bellard | 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, |
94 | 7bfdb6d1 | bellard | 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, |
95 | 7bfdb6d1 | bellard | CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, |
96 | 7bfdb6d1 | bellard | CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, |
97 | 7bfdb6d1 | bellard | 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, |
98 | 7bfdb6d1 | bellard | CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, |
99 | 7bfdb6d1 | bellard | 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, |
100 | 7bfdb6d1 | bellard | 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, |
101 | 7bfdb6d1 | bellard | CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, |
102 | 7bfdb6d1 | bellard | 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, |
103 | 7bfdb6d1 | bellard | CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, |
104 | 7bfdb6d1 | bellard | CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, |
105 | 7bfdb6d1 | bellard | 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, |
106 | 7bfdb6d1 | bellard | CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, |
107 | 7bfdb6d1 | bellard | 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, |
108 | 7bfdb6d1 | bellard | 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, |
109 | 7bfdb6d1 | bellard | CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, |
110 | 7bfdb6d1 | bellard | CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, |
111 | 7bfdb6d1 | bellard | 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, |
112 | 7bfdb6d1 | bellard | 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, |
113 | 7bfdb6d1 | bellard | CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, |
114 | 7bfdb6d1 | bellard | 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, |
115 | 7bfdb6d1 | bellard | CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, |
116 | 7bfdb6d1 | bellard | CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, |
117 | 7bfdb6d1 | bellard | 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, |
118 | 7bfdb6d1 | bellard | }; |
119 | 7bfdb6d1 | bellard | |
120 | 367e86e8 | bellard | /* modulo 17 table */
|
121 | 367e86e8 | bellard | const uint8_t rclw_table[32] = { |
122 | 367e86e8 | bellard | 0, 1, 2, 3, 4, 5, 6, 7, |
123 | 367e86e8 | bellard | 8, 9,10,11,12,13,14,15, |
124 | 367e86e8 | bellard | 16, 0, 1, 2, 3, 4, 5, 6, |
125 | 367e86e8 | bellard | 7, 8, 9,10,11,12,13,14, |
126 | 367e86e8 | bellard | }; |
127 | 7bfdb6d1 | bellard | |
128 | 367e86e8 | bellard | /* modulo 9 table */
|
129 | 367e86e8 | bellard | const uint8_t rclb_table[32] = { |
130 | 367e86e8 | bellard | 0, 1, 2, 3, 4, 5, 6, 7, |
131 | 367e86e8 | bellard | 8, 0, 1, 2, 3, 4, 5, 6, |
132 | 367e86e8 | bellard | 7, 8, 0, 1, 2, 3, 4, 5, |
133 | 367e86e8 | bellard | 6, 7, 8, 0, 1, 2, 3, 4, |
134 | 367e86e8 | bellard | }; |
135 | 7bfdb6d1 | bellard | |
136 | 367e86e8 | bellard | /* n must be a constant to be efficient */
|
137 | 367e86e8 | bellard | static inline int lshift(int x, int n) |
138 | 7bfdb6d1 | bellard | { |
139 | 367e86e8 | bellard | if (n >= 0) |
140 | 367e86e8 | bellard | return x << n;
|
141 | 367e86e8 | bellard | else
|
142 | 367e86e8 | bellard | return x >> (-n);
|
143 | 7bfdb6d1 | bellard | } |
144 | 7bfdb6d1 | bellard | |
145 | 7bfdb6d1 | bellard | /* we define the various pieces of code used by the JIT */
|
146 | 7bfdb6d1 | bellard | |
147 | 7bfdb6d1 | bellard | #define REG EAX
|
148 | 7bfdb6d1 | bellard | #define REGNAME _EAX
|
149 | 7bfdb6d1 | bellard | #include "opreg_template.h" |
150 | 7bfdb6d1 | bellard | #undef REG
|
151 | 7bfdb6d1 | bellard | #undef REGNAME
|
152 | 7bfdb6d1 | bellard | |
153 | 7bfdb6d1 | bellard | #define REG ECX
|
154 | 7bfdb6d1 | bellard | #define REGNAME _ECX
|
155 | 7bfdb6d1 | bellard | #include "opreg_template.h" |
156 | 7bfdb6d1 | bellard | #undef REG
|
157 | 7bfdb6d1 | bellard | #undef REGNAME
|
158 | 7bfdb6d1 | bellard | |
159 | 7bfdb6d1 | bellard | #define REG EDX
|
160 | 7bfdb6d1 | bellard | #define REGNAME _EDX
|
161 | 7bfdb6d1 | bellard | #include "opreg_template.h" |
162 | 7bfdb6d1 | bellard | #undef REG
|
163 | 7bfdb6d1 | bellard | #undef REGNAME
|
164 | 7bfdb6d1 | bellard | |
165 | 7bfdb6d1 | bellard | #define REG EBX
|
166 | 7bfdb6d1 | bellard | #define REGNAME _EBX
|
167 | 7bfdb6d1 | bellard | #include "opreg_template.h" |
168 | 7bfdb6d1 | bellard | #undef REG
|
169 | 7bfdb6d1 | bellard | #undef REGNAME
|
170 | 7bfdb6d1 | bellard | |
171 | 7bfdb6d1 | bellard | #define REG ESP
|
172 | 7bfdb6d1 | bellard | #define REGNAME _ESP
|
173 | 7bfdb6d1 | bellard | #include "opreg_template.h" |
174 | 7bfdb6d1 | bellard | #undef REG
|
175 | 7bfdb6d1 | bellard | #undef REGNAME
|
176 | 7bfdb6d1 | bellard | |
177 | 7bfdb6d1 | bellard | #define REG EBP
|
178 | 7bfdb6d1 | bellard | #define REGNAME _EBP
|
179 | 7bfdb6d1 | bellard | #include "opreg_template.h" |
180 | 7bfdb6d1 | bellard | #undef REG
|
181 | 7bfdb6d1 | bellard | #undef REGNAME
|
182 | 7bfdb6d1 | bellard | |
183 | 7bfdb6d1 | bellard | #define REG ESI
|
184 | 7bfdb6d1 | bellard | #define REGNAME _ESI
|
185 | 7bfdb6d1 | bellard | #include "opreg_template.h" |
186 | 7bfdb6d1 | bellard | #undef REG
|
187 | 7bfdb6d1 | bellard | #undef REGNAME
|
188 | 7bfdb6d1 | bellard | |
189 | 7bfdb6d1 | bellard | #define REG EDI
|
190 | 7bfdb6d1 | bellard | #define REGNAME _EDI
|
191 | 7bfdb6d1 | bellard | #include "opreg_template.h" |
192 | 7bfdb6d1 | bellard | #undef REG
|
193 | 7bfdb6d1 | bellard | #undef REGNAME
|
194 | 7bfdb6d1 | bellard | |
195 | 7bfdb6d1 | bellard | /* operations */
|
196 | 7bfdb6d1 | bellard | |
197 | 7bfdb6d1 | bellard | void OPPROTO op_addl_T0_T1_cc(void) |
198 | 7bfdb6d1 | bellard | { |
199 | 7bfdb6d1 | bellard | CC_SRC = T0; |
200 | 7bfdb6d1 | bellard | T0 += T1; |
201 | 7bfdb6d1 | bellard | CC_DST = T0; |
202 | 7bfdb6d1 | bellard | } |
203 | 7bfdb6d1 | bellard | |
204 | 7bfdb6d1 | bellard | void OPPROTO op_orl_T0_T1_cc(void) |
205 | 7bfdb6d1 | bellard | { |
206 | 7bfdb6d1 | bellard | T0 |= T1; |
207 | 7bfdb6d1 | bellard | CC_DST = T0; |
208 | 7bfdb6d1 | bellard | } |
209 | 7bfdb6d1 | bellard | |
210 | 7bfdb6d1 | bellard | void OPPROTO op_adcl_T0_T1_cc(void) |
211 | 7bfdb6d1 | bellard | { |
212 | 7bfdb6d1 | bellard | CC_SRC = T0; |
213 | 7bfdb6d1 | bellard | T0 = T0 + T1 + cc_table[CC_OP].compute_c(); |
214 | 7bfdb6d1 | bellard | CC_DST = T0; |
215 | 7bfdb6d1 | bellard | } |
216 | 7bfdb6d1 | bellard | |
217 | 7bfdb6d1 | bellard | void OPPROTO op_sbbl_T0_T1_cc(void) |
218 | 7bfdb6d1 | bellard | { |
219 | 7bfdb6d1 | bellard | CC_SRC = T0; |
220 | 7bfdb6d1 | bellard | T0 = T0 - T1 - cc_table[CC_OP].compute_c(); |
221 | 7bfdb6d1 | bellard | CC_DST = T0; |
222 | 7bfdb6d1 | bellard | } |
223 | 7bfdb6d1 | bellard | |
224 | 7bfdb6d1 | bellard | void OPPROTO op_andl_T0_T1_cc(void) |
225 | 7bfdb6d1 | bellard | { |
226 | 7bfdb6d1 | bellard | T0 &= T1; |
227 | 7bfdb6d1 | bellard | CC_DST = T0; |
228 | 7bfdb6d1 | bellard | } |
229 | 7bfdb6d1 | bellard | |
230 | 7bfdb6d1 | bellard | void OPPROTO op_subl_T0_T1_cc(void) |
231 | 7bfdb6d1 | bellard | { |
232 | 7bfdb6d1 | bellard | CC_SRC = T0; |
233 | 7bfdb6d1 | bellard | T0 -= T1; |
234 | 7bfdb6d1 | bellard | CC_DST = T0; |
235 | 7bfdb6d1 | bellard | } |
236 | 7bfdb6d1 | bellard | |
237 | 7bfdb6d1 | bellard | void OPPROTO op_xorl_T0_T1_cc(void) |
238 | 7bfdb6d1 | bellard | { |
239 | 7bfdb6d1 | bellard | T0 ^= T1; |
240 | 7bfdb6d1 | bellard | CC_DST = T0; |
241 | 7bfdb6d1 | bellard | } |
242 | 7bfdb6d1 | bellard | |
243 | 7bfdb6d1 | bellard | void OPPROTO op_cmpl_T0_T1_cc(void) |
244 | 7bfdb6d1 | bellard | { |
245 | 7bfdb6d1 | bellard | CC_SRC = T0; |
246 | 7bfdb6d1 | bellard | CC_DST = T0 - T1; |
247 | 7bfdb6d1 | bellard | } |
248 | 7bfdb6d1 | bellard | |
249 | 7bfdb6d1 | bellard | void OPPROTO op_notl_T0(void) |
250 | 7bfdb6d1 | bellard | { |
251 | 7bfdb6d1 | bellard | T0 = ~T0; |
252 | 7bfdb6d1 | bellard | } |
253 | 7bfdb6d1 | bellard | |
254 | 7bfdb6d1 | bellard | void OPPROTO op_negl_T0_cc(void) |
255 | 7bfdb6d1 | bellard | { |
256 | 7bfdb6d1 | bellard | CC_SRC = 0;
|
257 | 7bfdb6d1 | bellard | T0 = -T0; |
258 | 7bfdb6d1 | bellard | CC_DST = T0; |
259 | 7bfdb6d1 | bellard | } |
260 | 7bfdb6d1 | bellard | |
261 | 7bfdb6d1 | bellard | void OPPROTO op_incl_T0_cc(void) |
262 | 7bfdb6d1 | bellard | { |
263 | 7bfdb6d1 | bellard | T0++; |
264 | 7bfdb6d1 | bellard | CC_DST = T0; |
265 | 7bfdb6d1 | bellard | } |
266 | 7bfdb6d1 | bellard | |
267 | 7bfdb6d1 | bellard | void OPPROTO op_decl_T0_cc(void) |
268 | 7bfdb6d1 | bellard | { |
269 | 7bfdb6d1 | bellard | T0--; |
270 | 7bfdb6d1 | bellard | CC_DST = T0; |
271 | 7bfdb6d1 | bellard | } |
272 | 7bfdb6d1 | bellard | |
273 | 7bfdb6d1 | bellard | void OPPROTO op_testl_T0_T1_cc(void) |
274 | 7bfdb6d1 | bellard | { |
275 | 7bfdb6d1 | bellard | CC_SRC = T0; |
276 | 7bfdb6d1 | bellard | CC_DST = T0 & T1; |
277 | 7bfdb6d1 | bellard | } |
278 | 7bfdb6d1 | bellard | |
279 | 7bfdb6d1 | bellard | /* multiply/divide */
|
280 | 7bfdb6d1 | bellard | void OPPROTO op_mulb_AL_T0(void) |
281 | 7bfdb6d1 | bellard | { |
282 | 7bfdb6d1 | bellard | unsigned int res; |
283 | 7bfdb6d1 | bellard | res = (uint8_t)EAX * (uint8_t)T0; |
284 | 7bfdb6d1 | bellard | EAX = (EAX & 0xffff0000) | res;
|
285 | 7bfdb6d1 | bellard | CC_SRC = (res & 0xff00);
|
286 | 7bfdb6d1 | bellard | } |
287 | 7bfdb6d1 | bellard | |
288 | 7bfdb6d1 | bellard | void OPPROTO op_imulb_AL_T0(void) |
289 | 7bfdb6d1 | bellard | { |
290 | 7bfdb6d1 | bellard | int res;
|
291 | 7bfdb6d1 | bellard | res = (int8_t)EAX * (int8_t)T0; |
292 | 7bfdb6d1 | bellard | EAX = (EAX & 0xffff0000) | (res & 0xffff); |
293 | 7bfdb6d1 | bellard | CC_SRC = (res != (int8_t)res); |
294 | 7bfdb6d1 | bellard | } |
295 | 7bfdb6d1 | bellard | |
296 | 7bfdb6d1 | bellard | void OPPROTO op_mulw_AX_T0(void) |
297 | 7bfdb6d1 | bellard | { |
298 | 7bfdb6d1 | bellard | unsigned int res; |
299 | 7bfdb6d1 | bellard | res = (uint16_t)EAX * (uint16_t)T0; |
300 | 7bfdb6d1 | bellard | EAX = (EAX & 0xffff0000) | (res & 0xffff); |
301 | 7bfdb6d1 | bellard | EDX = (EDX & 0xffff0000) | ((res >> 16) & 0xffff); |
302 | 7bfdb6d1 | bellard | CC_SRC = res >> 16;
|
303 | 7bfdb6d1 | bellard | } |
304 | 7bfdb6d1 | bellard | |
305 | 7bfdb6d1 | bellard | void OPPROTO op_imulw_AX_T0(void) |
306 | 7bfdb6d1 | bellard | { |
307 | 7bfdb6d1 | bellard | int res;
|
308 | 7bfdb6d1 | bellard | res = (int16_t)EAX * (int16_t)T0; |
309 | 7bfdb6d1 | bellard | EAX = (EAX & 0xffff0000) | (res & 0xffff); |
310 | 7bfdb6d1 | bellard | EDX = (EDX & 0xffff0000) | ((res >> 16) & 0xffff); |
311 | 7bfdb6d1 | bellard | CC_SRC = (res != (int16_t)res); |
312 | 7bfdb6d1 | bellard | } |
313 | 7bfdb6d1 | bellard | |
314 | 7bfdb6d1 | bellard | void OPPROTO op_mull_EAX_T0(void) |
315 | 7bfdb6d1 | bellard | { |
316 | 7bfdb6d1 | bellard | uint64_t res; |
317 | 7bfdb6d1 | bellard | res = (uint64_t)((uint32_t)EAX) * (uint64_t)((uint32_t)T0); |
318 | 7bfdb6d1 | bellard | EAX = res; |
319 | 7bfdb6d1 | bellard | EDX = res >> 32;
|
320 | 7bfdb6d1 | bellard | CC_SRC = res >> 32;
|
321 | 7bfdb6d1 | bellard | } |
322 | 7bfdb6d1 | bellard | |
323 | 7bfdb6d1 | bellard | void OPPROTO op_imull_EAX_T0(void) |
324 | 7bfdb6d1 | bellard | { |
325 | 7bfdb6d1 | bellard | int64_t res; |
326 | 7bfdb6d1 | bellard | res = (int64_t)((int32_t)EAX) * (int64_t)((int32_t)T0); |
327 | 7bfdb6d1 | bellard | EAX = res; |
328 | 7bfdb6d1 | bellard | EDX = res >> 32;
|
329 | 7bfdb6d1 | bellard | CC_SRC = (res != (int32_t)res); |
330 | 7bfdb6d1 | bellard | } |
331 | 7bfdb6d1 | bellard | |
332 | 7bfdb6d1 | bellard | void OPPROTO op_imulw_T0_T1(void) |
333 | 7bfdb6d1 | bellard | { |
334 | 7bfdb6d1 | bellard | int res;
|
335 | 7bfdb6d1 | bellard | res = (int16_t)T0 * (int16_t)T1; |
336 | 7bfdb6d1 | bellard | T0 = res; |
337 | 7bfdb6d1 | bellard | CC_SRC = (res != (int16_t)res); |
338 | 7bfdb6d1 | bellard | } |
339 | 7bfdb6d1 | bellard | |
340 | 7bfdb6d1 | bellard | void OPPROTO op_imull_T0_T1(void) |
341 | 7bfdb6d1 | bellard | { |
342 | 7bfdb6d1 | bellard | int64_t res; |
343 | 7bfdb6d1 | bellard | res = (int64_t)((int32_t)EAX) * (int64_t)((int32_t)T1); |
344 | 7bfdb6d1 | bellard | T0 = res; |
345 | 7bfdb6d1 | bellard | CC_SRC = (res != (int32_t)res); |
346 | 7bfdb6d1 | bellard | } |
347 | 7bfdb6d1 | bellard | |
348 | 7bfdb6d1 | bellard | /* division, flags are undefined */
|
349 | 7bfdb6d1 | bellard | /* XXX: add exceptions for overflow & div by zero */
|
350 | 7bfdb6d1 | bellard | void OPPROTO op_divb_AL_T0(void) |
351 | 7bfdb6d1 | bellard | { |
352 | 7bfdb6d1 | bellard | unsigned int num, den, q, r; |
353 | 7bfdb6d1 | bellard | |
354 | 7bfdb6d1 | bellard | num = (EAX & 0xffff);
|
355 | 7bfdb6d1 | bellard | den = (T0 & 0xff);
|
356 | 7bfdb6d1 | bellard | q = (num / den) & 0xff;
|
357 | 7bfdb6d1 | bellard | r = (num % den) & 0xff;
|
358 | 7bfdb6d1 | bellard | EAX = (EAX & 0xffff0000) | (r << 8) | q; |
359 | 7bfdb6d1 | bellard | } |
360 | 7bfdb6d1 | bellard | |
361 | 7bfdb6d1 | bellard | void OPPROTO op_idivb_AL_T0(void) |
362 | 7bfdb6d1 | bellard | { |
363 | 7bfdb6d1 | bellard | int num, den, q, r;
|
364 | 7bfdb6d1 | bellard | |
365 | 7bfdb6d1 | bellard | num = (int16_t)EAX; |
366 | 7bfdb6d1 | bellard | den = (int8_t)T0; |
367 | 7bfdb6d1 | bellard | q = (num / den) & 0xff;
|
368 | 7bfdb6d1 | bellard | r = (num % den) & 0xff;
|
369 | 7bfdb6d1 | bellard | EAX = (EAX & 0xffff0000) | (r << 8) | q; |
370 | 7bfdb6d1 | bellard | } |
371 | 7bfdb6d1 | bellard | |
372 | 7bfdb6d1 | bellard | void OPPROTO op_divw_AX_T0(void) |
373 | 7bfdb6d1 | bellard | { |
374 | 7bfdb6d1 | bellard | unsigned int num, den, q, r; |
375 | 7bfdb6d1 | bellard | |
376 | 7bfdb6d1 | bellard | num = (EAX & 0xffff) | ((EDX & 0xffff) << 16); |
377 | 7bfdb6d1 | bellard | den = (T0 & 0xffff);
|
378 | 7bfdb6d1 | bellard | q = (num / den) & 0xffff;
|
379 | 7bfdb6d1 | bellard | r = (num % den) & 0xffff;
|
380 | 7bfdb6d1 | bellard | EAX = (EAX & 0xffff0000) | q;
|
381 | 7bfdb6d1 | bellard | EDX = (EDX & 0xffff0000) | r;
|
382 | 7bfdb6d1 | bellard | } |
383 | 7bfdb6d1 | bellard | |
384 | 7bfdb6d1 | bellard | void OPPROTO op_idivw_AX_T0(void) |
385 | 7bfdb6d1 | bellard | { |
386 | 7bfdb6d1 | bellard | int num, den, q, r;
|
387 | 7bfdb6d1 | bellard | |
388 | 7bfdb6d1 | bellard | num = (EAX & 0xffff) | ((EDX & 0xffff) << 16); |
389 | 7bfdb6d1 | bellard | den = (int16_t)T0; |
390 | 7bfdb6d1 | bellard | q = (num / den) & 0xffff;
|
391 | 7bfdb6d1 | bellard | r = (num % den) & 0xffff;
|
392 | 7bfdb6d1 | bellard | EAX = (EAX & 0xffff0000) | q;
|
393 | 7bfdb6d1 | bellard | EDX = (EDX & 0xffff0000) | r;
|
394 | 7bfdb6d1 | bellard | } |
395 | 7bfdb6d1 | bellard | |
396 | 7bfdb6d1 | bellard | void OPPROTO op_divl_EAX_T0(void) |
397 | 7bfdb6d1 | bellard | { |
398 | 7bfdb6d1 | bellard | unsigned int den, q, r; |
399 | 7bfdb6d1 | bellard | uint64_t num; |
400 | 7bfdb6d1 | bellard | |
401 | 7bfdb6d1 | bellard | num = EAX | ((uint64_t)EDX << 32);
|
402 | 7bfdb6d1 | bellard | den = T0; |
403 | 7bfdb6d1 | bellard | q = (num / den); |
404 | 7bfdb6d1 | bellard | r = (num % den); |
405 | 7bfdb6d1 | bellard | EAX = q; |
406 | 7bfdb6d1 | bellard | EDX = r; |
407 | 7bfdb6d1 | bellard | } |
408 | 7bfdb6d1 | bellard | |
409 | 7bfdb6d1 | bellard | void OPPROTO op_idivl_EAX_T0(void) |
410 | 7bfdb6d1 | bellard | { |
411 | 7bfdb6d1 | bellard | int den, q, r;
|
412 | 7bfdb6d1 | bellard | int16_t num; |
413 | 7bfdb6d1 | bellard | |
414 | 7bfdb6d1 | bellard | num = EAX | ((uint64_t)EDX << 32);
|
415 | 7bfdb6d1 | bellard | den = (int16_t)T0; |
416 | 7bfdb6d1 | bellard | q = (num / den); |
417 | 7bfdb6d1 | bellard | r = (num % den); |
418 | 7bfdb6d1 | bellard | EAX = q; |
419 | 7bfdb6d1 | bellard | EDX = r; |
420 | 7bfdb6d1 | bellard | } |
421 | 7bfdb6d1 | bellard | |
422 | 7bfdb6d1 | bellard | /* constant load */
|
423 | 7bfdb6d1 | bellard | |
424 | 7bfdb6d1 | bellard | void OPPROTO op1_movl_T0_im(void) |
425 | 7bfdb6d1 | bellard | { |
426 | 7bfdb6d1 | bellard | T0 = PARAM1; |
427 | 7bfdb6d1 | bellard | } |
428 | 7bfdb6d1 | bellard | |
429 | 7bfdb6d1 | bellard | void OPPROTO op1_movl_T1_im(void) |
430 | 7bfdb6d1 | bellard | { |
431 | 7bfdb6d1 | bellard | T1 = PARAM1; |
432 | 7bfdb6d1 | bellard | } |
433 | 7bfdb6d1 | bellard | |
434 | 7bfdb6d1 | bellard | void OPPROTO op1_movl_A0_im(void) |
435 | 7bfdb6d1 | bellard | { |
436 | 7bfdb6d1 | bellard | A0 = PARAM1; |
437 | 7bfdb6d1 | bellard | } |
438 | 7bfdb6d1 | bellard | |
439 | 7bfdb6d1 | bellard | /* memory access */
|
440 | 7bfdb6d1 | bellard | |
441 | 7bfdb6d1 | bellard | void OPPROTO op_ldub_T0_A0(void) |
442 | 7bfdb6d1 | bellard | { |
443 | 7bfdb6d1 | bellard | T0 = ldub((uint8_t *)A0); |
444 | 7bfdb6d1 | bellard | } |
445 | 7bfdb6d1 | bellard | |
446 | 7bfdb6d1 | bellard | void OPPROTO op_ldsb_T0_A0(void) |
447 | 7bfdb6d1 | bellard | { |
448 | 7bfdb6d1 | bellard | T0 = ldsb((int8_t *)A0); |
449 | 7bfdb6d1 | bellard | } |
450 | 7bfdb6d1 | bellard | |
451 | 7bfdb6d1 | bellard | void OPPROTO op_lduw_T0_A0(void) |
452 | 7bfdb6d1 | bellard | { |
453 | 7bfdb6d1 | bellard | T0 = lduw((uint8_t *)A0); |
454 | 7bfdb6d1 | bellard | } |
455 | 7bfdb6d1 | bellard | |
456 | 7bfdb6d1 | bellard | void OPPROTO op_ldsw_T0_A0(void) |
457 | 7bfdb6d1 | bellard | { |
458 | 7bfdb6d1 | bellard | T0 = ldsw((int8_t *)A0); |
459 | 7bfdb6d1 | bellard | } |
460 | 7bfdb6d1 | bellard | |
461 | 7bfdb6d1 | bellard | void OPPROTO op_ldl_T0_A0(void) |
462 | 7bfdb6d1 | bellard | { |
463 | 7bfdb6d1 | bellard | T0 = ldl((uint8_t *)A0); |
464 | 7bfdb6d1 | bellard | } |
465 | 7bfdb6d1 | bellard | |
466 | 7bfdb6d1 | bellard | void OPPROTO op_ldub_T1_A0(void) |
467 | 7bfdb6d1 | bellard | { |
468 | 7bfdb6d1 | bellard | T1 = ldub((uint8_t *)A0); |
469 | 7bfdb6d1 | bellard | } |
470 | 7bfdb6d1 | bellard | |
471 | 7bfdb6d1 | bellard | void OPPROTO op_ldsb_T1_A0(void) |
472 | 7bfdb6d1 | bellard | { |
473 | 7bfdb6d1 | bellard | T1 = ldsb((int8_t *)A0); |
474 | 7bfdb6d1 | bellard | } |
475 | 7bfdb6d1 | bellard | |
476 | 7bfdb6d1 | bellard | void OPPROTO op_lduw_T1_A0(void) |
477 | 7bfdb6d1 | bellard | { |
478 | 7bfdb6d1 | bellard | T1 = lduw((uint8_t *)A0); |
479 | 7bfdb6d1 | bellard | } |
480 | 7bfdb6d1 | bellard | |
481 | 7bfdb6d1 | bellard | void OPPROTO op_ldsw_T1_A0(void) |
482 | 7bfdb6d1 | bellard | { |
483 | 7bfdb6d1 | bellard | T1 = ldsw((int8_t *)A0); |
484 | 7bfdb6d1 | bellard | } |
485 | 7bfdb6d1 | bellard | |
486 | 7bfdb6d1 | bellard | void OPPROTO op_ldl_T1_A0(void) |
487 | 7bfdb6d1 | bellard | { |
488 | 7bfdb6d1 | bellard | T1 = ldl((uint8_t *)A0); |
489 | 7bfdb6d1 | bellard | } |
490 | 7bfdb6d1 | bellard | |
491 | 7bfdb6d1 | bellard | void OPPROTO op_stb_T0_A0(void) |
492 | 7bfdb6d1 | bellard | { |
493 | 7bfdb6d1 | bellard | stb((uint8_t *)A0, T0); |
494 | 7bfdb6d1 | bellard | } |
495 | 7bfdb6d1 | bellard | |
496 | 7bfdb6d1 | bellard | void OPPROTO op_stw_T0_A0(void) |
497 | 7bfdb6d1 | bellard | { |
498 | 7bfdb6d1 | bellard | stw((uint8_t *)A0, T0); |
499 | 7bfdb6d1 | bellard | } |
500 | 7bfdb6d1 | bellard | |
501 | 7bfdb6d1 | bellard | void OPPROTO op_stl_T0_A0(void) |
502 | 7bfdb6d1 | bellard | { |
503 | 7bfdb6d1 | bellard | stl((uint8_t *)A0, T0); |
504 | 7bfdb6d1 | bellard | } |
505 | 7bfdb6d1 | bellard | |
506 | 7bfdb6d1 | bellard | /* jumps */
|
507 | 7bfdb6d1 | bellard | |
508 | 7bfdb6d1 | bellard | /* indirect jump */
|
509 | 7bfdb6d1 | bellard | void OPPROTO op_jmp_T0(void) |
510 | 7bfdb6d1 | bellard | { |
511 | 7bfdb6d1 | bellard | PC = T0; |
512 | 7bfdb6d1 | bellard | } |
513 | 7bfdb6d1 | bellard | |
514 | 7bfdb6d1 | bellard | void OPPROTO op_jmp_im(void) |
515 | 7bfdb6d1 | bellard | { |
516 | 7bfdb6d1 | bellard | PC = PARAM1; |
517 | 7bfdb6d1 | bellard | } |
518 | 7bfdb6d1 | bellard | |
519 | 7bfdb6d1 | bellard | /* string ops */
|
520 | 7bfdb6d1 | bellard | |
521 | 7bfdb6d1 | bellard | #define ldul ldl
|
522 | 7bfdb6d1 | bellard | |
523 | 7bfdb6d1 | bellard | #define SHIFT 0 |
524 | 367e86e8 | bellard | #include "ops_template.h" |
525 | 7bfdb6d1 | bellard | #undef SHIFT
|
526 | 7bfdb6d1 | bellard | |
527 | 7bfdb6d1 | bellard | #define SHIFT 1 |
528 | 367e86e8 | bellard | #include "ops_template.h" |
529 | 7bfdb6d1 | bellard | #undef SHIFT
|
530 | 7bfdb6d1 | bellard | |
531 | 7bfdb6d1 | bellard | #define SHIFT 2 |
532 | 367e86e8 | bellard | #include "ops_template.h" |
533 | 7bfdb6d1 | bellard | #undef SHIFT
|
534 | 7bfdb6d1 | bellard | |
535 | 7bfdb6d1 | bellard | /* sign extend */
|
536 | 7bfdb6d1 | bellard | |
537 | 7bfdb6d1 | bellard | void OPPROTO op_movsbl_T0_T0(void) |
538 | 7bfdb6d1 | bellard | { |
539 | 7bfdb6d1 | bellard | T0 = (int8_t)T0; |
540 | 7bfdb6d1 | bellard | } |
541 | 7bfdb6d1 | bellard | |
542 | 7bfdb6d1 | bellard | void OPPROTO op_movzbl_T0_T0(void) |
543 | 7bfdb6d1 | bellard | { |
544 | 7bfdb6d1 | bellard | T0 = (uint8_t)T0; |
545 | 7bfdb6d1 | bellard | } |
546 | 7bfdb6d1 | bellard | |
547 | 7bfdb6d1 | bellard | void OPPROTO op_movswl_T0_T0(void) |
548 | 7bfdb6d1 | bellard | { |
549 | 7bfdb6d1 | bellard | T0 = (int16_t)T0; |
550 | 7bfdb6d1 | bellard | } |
551 | 7bfdb6d1 | bellard | |
552 | 7bfdb6d1 | bellard | void OPPROTO op_movzwl_T0_T0(void) |
553 | 7bfdb6d1 | bellard | { |
554 | 7bfdb6d1 | bellard | T0 = (uint16_t)T0; |
555 | 7bfdb6d1 | bellard | } |
556 | 7bfdb6d1 | bellard | |
557 | 7bfdb6d1 | bellard | void OPPROTO op_movswl_EAX_AX(void) |
558 | 7bfdb6d1 | bellard | { |
559 | 7bfdb6d1 | bellard | EAX = (int16_t)EAX; |
560 | 7bfdb6d1 | bellard | } |
561 | 7bfdb6d1 | bellard | |
562 | 7bfdb6d1 | bellard | void OPPROTO op_movsbw_AX_AL(void) |
563 | 7bfdb6d1 | bellard | { |
564 | 7bfdb6d1 | bellard | EAX = (EAX & 0xffff0000) | ((int8_t)EAX & 0xffff); |
565 | 7bfdb6d1 | bellard | } |
566 | 7bfdb6d1 | bellard | |
567 | 7bfdb6d1 | bellard | void OPPROTO op_movslq_EDX_EAX(void) |
568 | 7bfdb6d1 | bellard | { |
569 | 7bfdb6d1 | bellard | EDX = (int32_t)EAX >> 31;
|
570 | 7bfdb6d1 | bellard | } |
571 | 7bfdb6d1 | bellard | |
572 | 7bfdb6d1 | bellard | void OPPROTO op_movswl_DX_AX(void) |
573 | 7bfdb6d1 | bellard | { |
574 | 7bfdb6d1 | bellard | EDX = (EDX & 0xffff0000) | (((int16_t)EAX >> 15) & 0xffff); |
575 | 7bfdb6d1 | bellard | } |
576 | 7bfdb6d1 | bellard | |
577 | 7bfdb6d1 | bellard | /* push/pop */
|
578 | 7bfdb6d1 | bellard | /* XXX: add 16 bit operand/16 bit seg variants */
|
579 | 7bfdb6d1 | bellard | |
580 | 7bfdb6d1 | bellard | void op_pushl_T0(void) |
581 | 7bfdb6d1 | bellard | { |
582 | 7bfdb6d1 | bellard | uint32_t offset; |
583 | 7bfdb6d1 | bellard | offset = ESP - 4;
|
584 | 7bfdb6d1 | bellard | stl((void *)offset, T0);
|
585 | 7bfdb6d1 | bellard | /* modify ESP after to handle exceptions correctly */
|
586 | 7bfdb6d1 | bellard | ESP = offset; |
587 | 7bfdb6d1 | bellard | } |
588 | 7bfdb6d1 | bellard | |
589 | 7bfdb6d1 | bellard | void op_pushl_T1(void) |
590 | 7bfdb6d1 | bellard | { |
591 | 7bfdb6d1 | bellard | uint32_t offset; |
592 | 7bfdb6d1 | bellard | offset = ESP - 4;
|
593 | 7bfdb6d1 | bellard | stl((void *)offset, T1);
|
594 | 7bfdb6d1 | bellard | /* modify ESP after to handle exceptions correctly */
|
595 | 7bfdb6d1 | bellard | ESP = offset; |
596 | 7bfdb6d1 | bellard | } |
597 | 7bfdb6d1 | bellard | |
598 | 7bfdb6d1 | bellard | void op_popl_T0(void) |
599 | 7bfdb6d1 | bellard | { |
600 | 7bfdb6d1 | bellard | T0 = ldl((void *)ESP);
|
601 | 7bfdb6d1 | bellard | ESP += 4;
|
602 | 7bfdb6d1 | bellard | } |
603 | 7bfdb6d1 | bellard | |
604 | 7bfdb6d1 | bellard | void op_addl_ESP_im(void) |
605 | 7bfdb6d1 | bellard | { |
606 | 7bfdb6d1 | bellard | ESP += PARAM1; |
607 | 7bfdb6d1 | bellard | } |
608 | 367e86e8 | bellard | |
609 | 367e86e8 | bellard | /* flags handling */
|
610 | 367e86e8 | bellard | |
611 | 367e86e8 | bellard | /* slow jumps cases (compute x86 flags) */
|
612 | 367e86e8 | bellard | void OPPROTO op_jo_cc(void) |
613 | 367e86e8 | bellard | { |
614 | 367e86e8 | bellard | int eflags;
|
615 | 367e86e8 | bellard | eflags = cc_table[CC_OP].compute_all(); |
616 | 367e86e8 | bellard | if (eflags & CC_O)
|
617 | 367e86e8 | bellard | PC += PARAM1; |
618 | 367e86e8 | bellard | else
|
619 | 367e86e8 | bellard | PC += PARAM2; |
620 | 367e86e8 | bellard | } |
621 | 367e86e8 | bellard | |
622 | 367e86e8 | bellard | void OPPROTO op_jb_cc(void) |
623 | 367e86e8 | bellard | { |
624 | 367e86e8 | bellard | if (cc_table[CC_OP].compute_c())
|
625 | 367e86e8 | bellard | PC += PARAM1; |
626 | 367e86e8 | bellard | else
|
627 | 367e86e8 | bellard | PC += PARAM2; |
628 | 367e86e8 | bellard | } |
629 | 367e86e8 | bellard | |
630 | 367e86e8 | bellard | void OPPROTO op_jz_cc(void) |
631 | 367e86e8 | bellard | { |
632 | 367e86e8 | bellard | int eflags;
|
633 | 367e86e8 | bellard | eflags = cc_table[CC_OP].compute_all(); |
634 | 367e86e8 | bellard | if (eflags & CC_Z)
|
635 | 367e86e8 | bellard | PC += PARAM1; |
636 | 367e86e8 | bellard | else
|
637 | 367e86e8 | bellard | PC += PARAM2; |
638 | 367e86e8 | bellard | } |
639 | 367e86e8 | bellard | |
640 | 367e86e8 | bellard | void OPPROTO op_jbe_cc(void) |
641 | 367e86e8 | bellard | { |
642 | 367e86e8 | bellard | int eflags;
|
643 | 367e86e8 | bellard | eflags = cc_table[CC_OP].compute_all(); |
644 | 367e86e8 | bellard | if (eflags & (CC_Z | CC_C))
|
645 | 367e86e8 | bellard | PC += PARAM1; |
646 | 367e86e8 | bellard | else
|
647 | 367e86e8 | bellard | PC += PARAM2; |
648 | 367e86e8 | bellard | } |
649 | 367e86e8 | bellard | |
650 | 367e86e8 | bellard | void OPPROTO op_js_cc(void) |
651 | 367e86e8 | bellard | { |
652 | 367e86e8 | bellard | int eflags;
|
653 | 367e86e8 | bellard | eflags = cc_table[CC_OP].compute_all(); |
654 | 367e86e8 | bellard | if (eflags & CC_S)
|
655 | 367e86e8 | bellard | PC += PARAM1; |
656 | 367e86e8 | bellard | else
|
657 | 367e86e8 | bellard | PC += PARAM2; |
658 | 367e86e8 | bellard | } |
659 | 367e86e8 | bellard | |
660 | 367e86e8 | bellard | void OPPROTO op_jp_cc(void) |
661 | 367e86e8 | bellard | { |
662 | 367e86e8 | bellard | int eflags;
|
663 | 367e86e8 | bellard | eflags = cc_table[CC_OP].compute_all(); |
664 | 367e86e8 | bellard | if (eflags & CC_P)
|
665 | 367e86e8 | bellard | PC += PARAM1; |
666 | 367e86e8 | bellard | else
|
667 | 367e86e8 | bellard | PC += PARAM2; |
668 | 367e86e8 | bellard | } |
669 | 367e86e8 | bellard | |
670 | 367e86e8 | bellard | void OPPROTO op_jl_cc(void) |
671 | 367e86e8 | bellard | { |
672 | 367e86e8 | bellard | int eflags;
|
673 | 367e86e8 | bellard | eflags = cc_table[CC_OP].compute_all(); |
674 | 367e86e8 | bellard | if ((eflags ^ (eflags >> 4)) & 0x80) |
675 | 367e86e8 | bellard | PC += PARAM1; |
676 | 367e86e8 | bellard | else
|
677 | 367e86e8 | bellard | PC += PARAM2; |
678 | 367e86e8 | bellard | } |
679 | 367e86e8 | bellard | |
680 | 367e86e8 | bellard | void OPPROTO op_jle_cc(void) |
681 | 367e86e8 | bellard | { |
682 | 367e86e8 | bellard | int eflags;
|
683 | 367e86e8 | bellard | eflags = cc_table[CC_OP].compute_all(); |
684 | 367e86e8 | bellard | if (((eflags ^ (eflags >> 4)) & 0x80) || (eflags & CC_Z)) |
685 | 367e86e8 | bellard | PC += PARAM1; |
686 | 367e86e8 | bellard | else
|
687 | 367e86e8 | bellard | PC += PARAM2; |
688 | 367e86e8 | bellard | } |
689 | 367e86e8 | bellard | |
690 | 367e86e8 | bellard | /* slow set cases (compute x86 flags) */
|
691 | 367e86e8 | bellard | void OPPROTO op_seto_T0_cc(void) |
692 | 367e86e8 | bellard | { |
693 | 367e86e8 | bellard | int eflags;
|
694 | 367e86e8 | bellard | eflags = cc_table[CC_OP].compute_all(); |
695 | 367e86e8 | bellard | T0 = (eflags >> 11) & 1; |
696 | 367e86e8 | bellard | } |
697 | 367e86e8 | bellard | |
698 | 367e86e8 | bellard | void OPPROTO op_setb_T0_cc(void) |
699 | 367e86e8 | bellard | { |
700 | 367e86e8 | bellard | T0 = cc_table[CC_OP].compute_c(); |
701 | 367e86e8 | bellard | } |
702 | 367e86e8 | bellard | |
703 | 367e86e8 | bellard | void OPPROTO op_setz_T0_cc(void) |
704 | 367e86e8 | bellard | { |
705 | 367e86e8 | bellard | int eflags;
|
706 | 367e86e8 | bellard | eflags = cc_table[CC_OP].compute_all(); |
707 | 367e86e8 | bellard | T0 = (eflags >> 6) & 1; |
708 | 367e86e8 | bellard | } |
709 | 367e86e8 | bellard | |
710 | 367e86e8 | bellard | void OPPROTO op_setbe_T0_cc(void) |
711 | 367e86e8 | bellard | { |
712 | 367e86e8 | bellard | int eflags;
|
713 | 367e86e8 | bellard | eflags = cc_table[CC_OP].compute_all(); |
714 | 367e86e8 | bellard | T0 = (eflags & (CC_Z | CC_C)) != 0;
|
715 | 367e86e8 | bellard | } |
716 | 367e86e8 | bellard | |
717 | 367e86e8 | bellard | void OPPROTO op_sets_T0_cc(void) |
718 | 367e86e8 | bellard | { |
719 | 367e86e8 | bellard | int eflags;
|
720 | 367e86e8 | bellard | eflags = cc_table[CC_OP].compute_all(); |
721 | 367e86e8 | bellard | T0 = (eflags >> 7) & 1; |
722 | 367e86e8 | bellard | } |
723 | 367e86e8 | bellard | |
724 | 367e86e8 | bellard | void OPPROTO op_setp_T0_cc(void) |
725 | 367e86e8 | bellard | { |
726 | 367e86e8 | bellard | int eflags;
|
727 | 367e86e8 | bellard | eflags = cc_table[CC_OP].compute_all(); |
728 | 367e86e8 | bellard | T0 = (eflags >> 2) & 1; |
729 | 367e86e8 | bellard | } |
730 | 367e86e8 | bellard | |
731 | 367e86e8 | bellard | void OPPROTO op_setl_T0_cc(void) |
732 | 367e86e8 | bellard | { |
733 | 367e86e8 | bellard | int eflags;
|
734 | 367e86e8 | bellard | eflags = cc_table[CC_OP].compute_all(); |
735 | 367e86e8 | bellard | T0 = ((eflags ^ (eflags >> 4)) >> 7) & 1; |
736 | 367e86e8 | bellard | } |
737 | 367e86e8 | bellard | |
738 | 367e86e8 | bellard | void OPPROTO op_setle_T0_cc(void) |
739 | 367e86e8 | bellard | { |
740 | 367e86e8 | bellard | int eflags;
|
741 | 367e86e8 | bellard | eflags = cc_table[CC_OP].compute_all(); |
742 | 367e86e8 | bellard | T0 = (((eflags ^ (eflags >> 4)) & 0x80) || (eflags & CC_Z)) != 0; |
743 | 367e86e8 | bellard | } |
744 | 367e86e8 | bellard | |
745 | 367e86e8 | bellard | void OPPROTO op_xor_T0_1(void) |
746 | 367e86e8 | bellard | { |
747 | 367e86e8 | bellard | T0 ^= 1;
|
748 | 367e86e8 | bellard | } |
749 | 367e86e8 | bellard | |
750 | 367e86e8 | bellard | void OPPROTO op_set_cc_op(void) |
751 | 367e86e8 | bellard | { |
752 | 367e86e8 | bellard | CC_OP = PARAM1; |
753 | 367e86e8 | bellard | } |
754 | 367e86e8 | bellard | |
755 | 367e86e8 | bellard | void OPPROTO op_movl_eflags_T0(void) |
756 | 367e86e8 | bellard | { |
757 | 367e86e8 | bellard | CC_SRC = T0; |
758 | 367e86e8 | bellard | DF = 1 - (2 * ((T0 >> 10) & 1)); |
759 | 367e86e8 | bellard | } |
760 | 367e86e8 | bellard | |
761 | 367e86e8 | bellard | /* XXX: compute only O flag */
|
762 | 367e86e8 | bellard | void OPPROTO op_movb_eflags_T0(void) |
763 | 367e86e8 | bellard | { |
764 | 367e86e8 | bellard | int of;
|
765 | 367e86e8 | bellard | of = cc_table[CC_OP].compute_all() & CC_O; |
766 | 367e86e8 | bellard | CC_SRC = T0 | of; |
767 | 367e86e8 | bellard | } |
768 | 367e86e8 | bellard | |
769 | 367e86e8 | bellard | void OPPROTO op_movl_T0_eflags(void) |
770 | 367e86e8 | bellard | { |
771 | 367e86e8 | bellard | T0 = cc_table[CC_OP].compute_all(); |
772 | 367e86e8 | bellard | T0 |= (DF & DIRECTION_FLAG); |
773 | 367e86e8 | bellard | } |
774 | 367e86e8 | bellard | |
775 | 367e86e8 | bellard | void OPPROTO op_cld(void) |
776 | 367e86e8 | bellard | { |
777 | 367e86e8 | bellard | DF = 1;
|
778 | 367e86e8 | bellard | } |
779 | 367e86e8 | bellard | |
780 | 367e86e8 | bellard | void OPPROTO op_std(void) |
781 | 367e86e8 | bellard | { |
782 | 367e86e8 | bellard | DF = -1;
|
783 | 367e86e8 | bellard | } |
784 | 367e86e8 | bellard | |
785 | 367e86e8 | bellard | void OPPROTO op_clc(void) |
786 | 367e86e8 | bellard | { |
787 | 367e86e8 | bellard | int eflags;
|
788 | 367e86e8 | bellard | eflags = cc_table[CC_OP].compute_all(); |
789 | 367e86e8 | bellard | eflags &= ~CC_C; |
790 | 367e86e8 | bellard | CC_SRC = eflags; |
791 | 367e86e8 | bellard | } |
792 | 367e86e8 | bellard | |
793 | 367e86e8 | bellard | void OPPROTO op_stc(void) |
794 | 367e86e8 | bellard | { |
795 | 367e86e8 | bellard | int eflags;
|
796 | 367e86e8 | bellard | eflags = cc_table[CC_OP].compute_all(); |
797 | 367e86e8 | bellard | eflags |= CC_C; |
798 | 367e86e8 | bellard | CC_SRC = eflags; |
799 | 367e86e8 | bellard | } |
800 | 367e86e8 | bellard | |
801 | 367e86e8 | bellard | void OPPROTO op_cmc(void) |
802 | 367e86e8 | bellard | { |
803 | 367e86e8 | bellard | int eflags;
|
804 | 367e86e8 | bellard | eflags = cc_table[CC_OP].compute_all(); |
805 | 367e86e8 | bellard | eflags ^= CC_C; |
806 | 367e86e8 | bellard | CC_SRC = eflags; |
807 | 367e86e8 | bellard | } |
808 | 367e86e8 | bellard | |
809 | 367e86e8 | bellard | static int compute_all_eflags(void) |
810 | 367e86e8 | bellard | { |
811 | 367e86e8 | bellard | return CC_SRC;
|
812 | 367e86e8 | bellard | } |
813 | 367e86e8 | bellard | |
814 | 367e86e8 | bellard | static int compute_c_eflags(void) |
815 | 367e86e8 | bellard | { |
816 | 367e86e8 | bellard | return CC_SRC & CC_C;
|
817 | 367e86e8 | bellard | } |
818 | 367e86e8 | bellard | |
819 | 367e86e8 | bellard | static int compute_c_mul(void) |
820 | 367e86e8 | bellard | { |
821 | 367e86e8 | bellard | int cf;
|
822 | 367e86e8 | bellard | cf = (CC_SRC != 0);
|
823 | 367e86e8 | bellard | return cf;
|
824 | 367e86e8 | bellard | } |
825 | 367e86e8 | bellard | |
826 | 367e86e8 | bellard | static int compute_all_mul(void) |
827 | 367e86e8 | bellard | { |
828 | 367e86e8 | bellard | int cf, pf, af, zf, sf, of;
|
829 | 367e86e8 | bellard | cf = (CC_SRC != 0);
|
830 | 367e86e8 | bellard | pf = 0; /* undefined */ |
831 | 367e86e8 | bellard | af = 0; /* undefined */ |
832 | 367e86e8 | bellard | zf = 0; /* undefined */ |
833 | 367e86e8 | bellard | sf = 0; /* undefined */ |
834 | 367e86e8 | bellard | of = cf << 11;
|
835 | 367e86e8 | bellard | return cf | pf | af | zf | sf | of;
|
836 | 367e86e8 | bellard | } |
837 | 367e86e8 | bellard | |
838 | 367e86e8 | bellard | CCTable cc_table[CC_OP_NB] = { |
839 | 367e86e8 | bellard | [CC_OP_DYNAMIC] = { /* should never happen */ },
|
840 | 367e86e8 | bellard | |
841 | 367e86e8 | bellard | [CC_OP_EFLAGS] = { compute_all_eflags, compute_c_eflags }, |
842 | 367e86e8 | bellard | |
843 | 367e86e8 | bellard | [CC_OP_MUL] = { compute_all_mul, compute_c_mul }, |
844 | 367e86e8 | bellard | |
845 | 367e86e8 | bellard | [CC_OP_ADDB] = { compute_all_addb, compute_c_addb }, |
846 | 367e86e8 | bellard | [CC_OP_ADDW] = { compute_all_addw, compute_c_addw }, |
847 | 367e86e8 | bellard | [CC_OP_ADDL] = { compute_all_addl, compute_c_addl }, |
848 | 367e86e8 | bellard | |
849 | 367e86e8 | bellard | [CC_OP_SUBB] = { compute_all_subb, compute_c_subb }, |
850 | 367e86e8 | bellard | [CC_OP_SUBW] = { compute_all_subw, compute_c_subw }, |
851 | 367e86e8 | bellard | [CC_OP_SUBL] = { compute_all_subl, compute_c_subl }, |
852 | 367e86e8 | bellard | |
853 | 367e86e8 | bellard | [CC_OP_LOGICB] = { compute_all_logicb, compute_c_logicb }, |
854 | 367e86e8 | bellard | [CC_OP_LOGICW] = { compute_all_logicw, compute_c_logicw }, |
855 | 367e86e8 | bellard | [CC_OP_LOGICL] = { compute_all_logicl, compute_c_logicl }, |
856 | 367e86e8 | bellard | |
857 | 367e86e8 | bellard | [CC_OP_INCB] = { compute_all_incb, compute_c_incb }, |
858 | 367e86e8 | bellard | [CC_OP_INCW] = { compute_all_incw, compute_c_incw }, |
859 | 367e86e8 | bellard | [CC_OP_INCL] = { compute_all_incl, compute_c_incl }, |
860 | 367e86e8 | bellard | |
861 | 367e86e8 | bellard | [CC_OP_DECB] = { compute_all_decb, compute_c_incb }, |
862 | 367e86e8 | bellard | [CC_OP_DECW] = { compute_all_decw, compute_c_incw }, |
863 | 367e86e8 | bellard | [CC_OP_DECL] = { compute_all_decl, compute_c_incl }, |
864 | 367e86e8 | bellard | |
865 | 367e86e8 | bellard | [CC_OP_SHLB] = { compute_all_shlb, compute_c_shlb }, |
866 | 367e86e8 | bellard | [CC_OP_SHLW] = { compute_all_shlw, compute_c_shlw }, |
867 | 367e86e8 | bellard | [CC_OP_SHLL] = { compute_all_shll, compute_c_shll }, |
868 | 367e86e8 | bellard | }; |