VirtualBox

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

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

*: rebrand Sun (L)GPL disclaimers

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