VirtualBox

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

Last change on this file since 36140 was 36140, checked in by vboxsync, 14 years ago

rem: Re-synced to svn://svn.savannah.nongnu.org/qemu/trunk@5495 (repo UUID c046a42c-6fe2-441c-8c8c-71466251a162).

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