VirtualBox

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

Last change on this file since 18808 was 11982, checked in by vboxsync, 16 years ago

All: license header changes for 2.0 (OSE headers, add Sun GPL/LGPL disclaimer)

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