VirtualBox

source: vbox/trunk/src/recompiler/target-i386/ops_template_mem.h@ 4672

Last change on this file since 4672 was 2422, checked in by vboxsync, 18 years ago

Removed the old recompiler code.

  • Property svn:eol-style set to native
File size: 10.6 KB
Line 
1/*
2 * i386 micro operations (included several times to generate
3 * different operand sizes)
4 *
5 * Copyright (c) 2003 Fabrice Bellard
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21#ifdef MEM_WRITE
22
23#if MEM_WRITE == 0
24
25#if DATA_BITS == 8
26#define MEM_SUFFIX b_raw
27#elif DATA_BITS == 16
28#define MEM_SUFFIX w_raw
29#elif DATA_BITS == 32
30#define MEM_SUFFIX l_raw
31#elif DATA_BITS == 64
32#define MEM_SUFFIX q_raw
33#endif
34
35#elif MEM_WRITE == 1
36
37#if DATA_BITS == 8
38#define MEM_SUFFIX b_kernel
39#elif DATA_BITS == 16
40#define MEM_SUFFIX w_kernel
41#elif DATA_BITS == 32
42#define MEM_SUFFIX l_kernel
43#elif DATA_BITS == 64
44#define MEM_SUFFIX q_kernel
45#endif
46
47#elif MEM_WRITE == 2
48
49#if DATA_BITS == 8
50#define MEM_SUFFIX b_user
51#elif DATA_BITS == 16
52#define MEM_SUFFIX w_user
53#elif DATA_BITS == 32
54#define MEM_SUFFIX l_user
55#elif DATA_BITS == 64
56#define MEM_SUFFIX q_user
57#endif
58
59#else
60
61#error invalid MEM_WRITE
62
63#endif
64
65#else
66
67#define MEM_SUFFIX SUFFIX
68
69#endif
70
71void OPPROTO glue(glue(op_rol, MEM_SUFFIX), _T0_T1_cc)(void)
72{
73 int count;
74 target_long src;
75
76 if (T1 & SHIFT1_MASK) {
77 count = T1 & SHIFT_MASK;
78 src = T0;
79 T0 &= DATA_MASK;
80 T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
81#ifdef MEM_WRITE
82 glue(st, MEM_SUFFIX)(A0, T0);
83#else
84 /* gcc 3.2 workaround. This is really a bug in gcc. */
85 asm volatile("" : : "r" (T0));
86#endif
87 CC_SRC = (cc_table[CC_OP].compute_all() & ~(CC_O | CC_C)) |
88 (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
89 (T0 & CC_C);
90 CC_OP = CC_OP_EFLAGS;
91 }
92 FORCE_RET();
93}
94
95void OPPROTO glue(glue(op_ror, MEM_SUFFIX), _T0_T1_cc)(void)
96{
97 int count;
98 target_long src;
99
100 if (T1 & SHIFT1_MASK) {
101 count = T1 & SHIFT_MASK;
102 src = T0;
103 T0 &= DATA_MASK;
104 T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
105#ifdef MEM_WRITE
106 glue(st, MEM_SUFFIX)(A0, T0);
107#else
108 /* gcc 3.2 workaround. This is really a bug in gcc. */
109 asm volatile("" : : "r" (T0));
110#endif
111 CC_SRC = (cc_table[CC_OP].compute_all() & ~(CC_O | CC_C)) |
112 (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
113 ((T0 >> (DATA_BITS - 1)) & CC_C);
114 CC_OP = CC_OP_EFLAGS;
115 }
116 FORCE_RET();
117}
118
119void OPPROTO glue(glue(op_rol, MEM_SUFFIX), _T0_T1)(void)
120{
121 int count;
122 count = T1 & SHIFT_MASK;
123 if (count) {
124 T0 &= DATA_MASK;
125 T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
126#ifdef MEM_WRITE
127 glue(st, MEM_SUFFIX)(A0, T0);
128#endif
129 }
130 FORCE_RET();
131}
132
133void OPPROTO glue(glue(op_ror, MEM_SUFFIX), _T0_T1)(void)
134{
135 int count;
136 count = T1 & SHIFT_MASK;
137 if (count) {
138 T0 &= DATA_MASK;
139 T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
140#ifdef MEM_WRITE
141 glue(st, MEM_SUFFIX)(A0, T0);
142#endif
143 }
144 FORCE_RET();
145}
146
147void OPPROTO glue(glue(op_rcl, MEM_SUFFIX), _T0_T1_cc)(void)
148{
149 int count, eflags;
150 target_ulong src;
151 target_long res;
152
153 count = T1 & SHIFT1_MASK;
154#if DATA_BITS == 16
155 count = rclw_table[count];
156#elif DATA_BITS == 8
157 count = rclb_table[count];
158#endif
159 if (count) {
160 eflags = cc_table[CC_OP].compute_all();
161 T0 &= DATA_MASK;
162 src = T0;
163 res = (T0 << count) | ((target_ulong)(eflags & CC_C) << (count - 1));
164 if (count > 1)
165 res |= T0 >> (DATA_BITS + 1 - count);
166 T0 = res;
167#ifdef MEM_WRITE
168 glue(st, MEM_SUFFIX)(A0, T0);
169#endif
170 CC_SRC = (eflags & ~(CC_C | CC_O)) |
171 (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
172 ((src >> (DATA_BITS - count)) & CC_C);
173 CC_OP = CC_OP_EFLAGS;
174 }
175 FORCE_RET();
176}
177
178void OPPROTO glue(glue(op_rcr, MEM_SUFFIX), _T0_T1_cc)(void)
179{
180 int count, eflags;
181 target_ulong src;
182 target_long res;
183
184 count = T1 & SHIFT1_MASK;
185#if DATA_BITS == 16
186 count = rclw_table[count];
187#elif DATA_BITS == 8
188 count = rclb_table[count];
189#endif
190 if (count) {
191 eflags = cc_table[CC_OP].compute_all();
192 T0 &= DATA_MASK;
193 src = T0;
194 res = (T0 >> count) | ((target_ulong)(eflags & CC_C) << (DATA_BITS - count));
195 if (count > 1)
196 res |= T0 << (DATA_BITS + 1 - count);
197 T0 = res;
198#ifdef MEM_WRITE
199 glue(st, MEM_SUFFIX)(A0, T0);
200#endif
201 CC_SRC = (eflags & ~(CC_C | CC_O)) |
202 (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
203 ((src >> (count - 1)) & CC_C);
204 CC_OP = CC_OP_EFLAGS;
205 }
206 FORCE_RET();
207}
208
209void OPPROTO glue(glue(op_shl, MEM_SUFFIX), _T0_T1_cc)(void)
210{
211 int count;
212 target_long src;
213
214 count = T1 & SHIFT1_MASK;
215 if (count) {
216 src = (DATA_TYPE)T0 << (count - 1);
217 T0 = T0 << count;
218#ifdef MEM_WRITE
219 glue(st, MEM_SUFFIX)(A0, T0);
220#endif
221 CC_SRC = src;
222 CC_DST = T0;
223 CC_OP = CC_OP_SHLB + SHIFT;
224 }
225 FORCE_RET();
226}
227
228void OPPROTO glue(glue(op_shr, MEM_SUFFIX), _T0_T1_cc)(void)
229{
230 int count;
231 target_long src;
232
233 count = T1 & SHIFT1_MASK;
234 if (count) {
235 T0 &= DATA_MASK;
236 src = T0 >> (count - 1);
237 T0 = T0 >> count;
238#ifdef MEM_WRITE
239 glue(st, MEM_SUFFIX)(A0, T0);
240#endif
241 CC_SRC = src;
242 CC_DST = T0;
243 CC_OP = CC_OP_SARB + SHIFT;
244 }
245 FORCE_RET();
246}
247
248void OPPROTO glue(glue(op_sar, MEM_SUFFIX), _T0_T1_cc)(void)
249{
250 int count;
251 target_long src;
252
253 count = T1 & SHIFT1_MASK;
254 if (count) {
255 src = (DATA_STYPE)T0;
256 T0 = src >> count;
257 src = src >> (count - 1);
258#ifdef MEM_WRITE
259 glue(st, MEM_SUFFIX)(A0, T0);
260#endif
261 CC_SRC = src;
262 CC_DST = T0;
263 CC_OP = CC_OP_SARB + SHIFT;
264 }
265 FORCE_RET();
266}
267
268#if DATA_BITS == 16
269/* XXX: overflow flag might be incorrect in some cases in shldw */
270void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_im_cc)(void)
271{
272 int count;
273 unsigned int res, tmp;
274 count = PARAM1;
275 T1 &= 0xffff;
276 res = T1 | (T0 << 16);
277 tmp = res >> (32 - count);
278 res <<= count;
279 if (count > 16)
280 res |= T1 << (count - 16);
281 T0 = res >> 16;
282#ifdef MEM_WRITE
283 glue(st, MEM_SUFFIX)(A0, T0);
284#endif
285 CC_SRC = tmp;
286 CC_DST = T0;
287}
288
289void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
290{
291 int count;
292 unsigned int res, tmp;
293 count = ECX & 0x1f;
294 if (count) {
295 T1 &= 0xffff;
296 res = T1 | (T0 << 16);
297 tmp = res >> (32 - count);
298 res <<= count;
299 if (count > 16)
300 res |= T1 << (count - 16);
301 T0 = res >> 16;
302#ifdef MEM_WRITE
303 glue(st, MEM_SUFFIX)(A0, T0);
304#endif
305 CC_SRC = tmp;
306 CC_DST = T0;
307 CC_OP = CC_OP_SARB + SHIFT;
308 }
309 FORCE_RET();
310}
311
312void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_im_cc)(void)
313{
314 int count;
315 unsigned int res, tmp;
316
317 count = PARAM1;
318 res = (T0 & 0xffff) | (T1 << 16);
319 tmp = res >> (count - 1);
320 res >>= count;
321 if (count > 16)
322 res |= T1 << (32 - count);
323 T0 = res;
324#ifdef MEM_WRITE
325 glue(st, MEM_SUFFIX)(A0, T0);
326#endif
327 CC_SRC = tmp;
328 CC_DST = T0;
329}
330
331
332void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
333{
334 int count;
335 unsigned int res, tmp;
336
337 count = ECX & 0x1f;
338 if (count) {
339 res = (T0 & 0xffff) | (T1 << 16);
340 tmp = res >> (count - 1);
341 res >>= count;
342 if (count > 16)
343 res |= T1 << (32 - count);
344 T0 = res;
345#ifdef MEM_WRITE
346 glue(st, MEM_SUFFIX)(A0, T0);
347#endif
348 CC_SRC = tmp;
349 CC_DST = T0;
350 CC_OP = CC_OP_SARB + SHIFT;
351 }
352 FORCE_RET();
353}
354#endif
355
356#if DATA_BITS >= 32
357void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_im_cc)(void)
358{
359 int count;
360 target_long tmp;
361
362 count = PARAM1;
363 T0 &= DATA_MASK;
364 T1 &= DATA_MASK;
365 tmp = T0 << (count - 1);
366 T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
367#ifdef MEM_WRITE
368 glue(st, MEM_SUFFIX)(A0, T0);
369#endif
370 CC_SRC = tmp;
371 CC_DST = T0;
372}
373
374void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
375{
376 int count;
377 target_long tmp;
378
379 count = ECX & SHIFT1_MASK;
380 if (count) {
381 T0 &= DATA_MASK;
382 T1 &= DATA_MASK;
383 tmp = T0 << (count - 1);
384 T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
385#ifdef MEM_WRITE
386 glue(st, MEM_SUFFIX)(A0, T0);
387#endif
388 CC_SRC = tmp;
389 CC_DST = T0;
390 CC_OP = CC_OP_SHLB + SHIFT;
391 }
392 FORCE_RET();
393}
394
395void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_im_cc)(void)
396{
397 int count;
398 target_long tmp;
399
400 count = PARAM1;
401 T0 &= DATA_MASK;
402 T1 &= DATA_MASK;
403 tmp = T0 >> (count - 1);
404 T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
405#ifdef MEM_WRITE
406 glue(st, MEM_SUFFIX)(A0, T0);
407#endif
408 CC_SRC = tmp;
409 CC_DST = T0;
410}
411
412
413void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
414{
415 int count;
416 target_long tmp;
417
418 count = ECX & SHIFT1_MASK;
419 if (count) {
420 T0 &= DATA_MASK;
421 T1 &= DATA_MASK;
422 tmp = T0 >> (count - 1);
423 T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
424#ifdef MEM_WRITE
425 glue(st, MEM_SUFFIX)(A0, T0);
426#endif
427 CC_SRC = tmp;
428 CC_DST = T0;
429 CC_OP = CC_OP_SARB + SHIFT;
430 }
431 FORCE_RET();
432}
433#endif
434
435/* carry add/sub (we only need to set CC_OP differently) */
436
437void OPPROTO glue(glue(op_adc, MEM_SUFFIX), _T0_T1_cc)(void)
438{
439 int cf;
440 cf = cc_table[CC_OP].compute_c();
441 T0 = T0 + T1 + cf;
442#ifdef MEM_WRITE
443 glue(st, MEM_SUFFIX)(A0, T0);
444#endif
445 CC_SRC = T1;
446 CC_DST = T0;
447 CC_OP = CC_OP_ADDB + SHIFT + cf * 4;
448}
449
450void OPPROTO glue(glue(op_sbb, MEM_SUFFIX), _T0_T1_cc)(void)
451{
452 int cf;
453 cf = cc_table[CC_OP].compute_c();
454 T0 = T0 - T1 - cf;
455#ifdef MEM_WRITE
456 glue(st, MEM_SUFFIX)(A0, T0);
457#endif
458 CC_SRC = T1;
459 CC_DST = T0;
460 CC_OP = CC_OP_SUBB + SHIFT + cf * 4;
461}
462
463void OPPROTO glue(glue(op_cmpxchg, MEM_SUFFIX), _T0_T1_EAX_cc)(void)
464{
465 target_ulong src, dst;
466
467 src = T0;
468 dst = EAX - T0;
469 if ((DATA_TYPE)dst == 0) {
470 T0 = T1;
471#ifdef MEM_WRITE
472 glue(st, MEM_SUFFIX)(A0, T0);
473#endif
474 } else {
475 EAX = (EAX & ~DATA_MASK) | (T0 & DATA_MASK);
476 }
477 CC_SRC = src;
478 CC_DST = dst;
479 FORCE_RET();
480}
481
482#undef MEM_SUFFIX
483#undef MEM_WRITE
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette