VirtualBox

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

最後變更 在這個檔案從36140是 36140,由 vboxsync 提交於 14 年 前

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

  • 屬性 svn:eol-style 設為 native
檔案大小: 13.5 KB
 
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#define DATA_BITS (1 << (3 + SHIFT))
33#define SHIFT_MASK (DATA_BITS - 1)
34#define SIGN_MASK (((target_ulong)1) << (DATA_BITS - 1))
35#if DATA_BITS <= 32
36#define SHIFT1_MASK 0x1f
37#else
38#define SHIFT1_MASK 0x3f
39#endif
40
41#if DATA_BITS == 8
42#define SUFFIX b
43#define DATA_TYPE uint8_t
44#define DATA_STYPE int8_t
45#define DATA_MASK 0xff
46#elif DATA_BITS == 16
47#define SUFFIX w
48#define DATA_TYPE uint16_t
49#define DATA_STYPE int16_t
50#define DATA_MASK 0xffff
51#elif DATA_BITS == 32
52#define SUFFIX l
53#define DATA_TYPE uint32_t
54#define DATA_STYPE int32_t
55#define DATA_MASK 0xffffffff
56#elif DATA_BITS == 64
57#define SUFFIX q
58#define DATA_TYPE uint64_t
59#define DATA_STYPE int64_t
60#define DATA_MASK 0xffffffffffffffffULL
61#else
62#error unhandled operand size
63#endif
64
65/* dynamic flags computation */
66
67static int glue(compute_all_add, SUFFIX)(void)
68{
69 int cf, pf, af, zf, sf, of;
70 target_long src1, src2;
71 src1 = CC_SRC;
72 src2 = CC_DST - CC_SRC;
73 cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1;
74 pf = parity_table[(uint8_t)CC_DST];
75 af = (CC_DST ^ src1 ^ src2) & 0x10;
76 zf = ((DATA_TYPE)CC_DST == 0) << 6;
77 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
78 of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
79 return cf | pf | af | zf | sf | of;
80}
81
82static int glue(compute_c_add, SUFFIX)(void)
83{
84 int cf;
85 target_long src1;
86 src1 = CC_SRC;
87 cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1;
88 return cf;
89}
90
91static int glue(compute_all_adc, SUFFIX)(void)
92{
93 int cf, pf, af, zf, sf, of;
94 target_long src1, src2;
95 src1 = CC_SRC;
96 src2 = CC_DST - CC_SRC - 1;
97 cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
98 pf = parity_table[(uint8_t)CC_DST];
99 af = (CC_DST ^ src1 ^ src2) & 0x10;
100 zf = ((DATA_TYPE)CC_DST == 0) << 6;
101 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
102 of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
103 return cf | pf | af | zf | sf | of;
104}
105
106static int glue(compute_c_adc, SUFFIX)(void)
107{
108 int cf;
109 target_long src1;
110 src1 = CC_SRC;
111 cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
112 return cf;
113}
114
115static int glue(compute_all_sub, SUFFIX)(void)
116{
117 int cf, pf, af, zf, sf, of;
118 target_long src1, src2;
119 src1 = CC_DST + CC_SRC;
120 src2 = CC_SRC;
121 cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
122 pf = parity_table[(uint8_t)CC_DST];
123 af = (CC_DST ^ src1 ^ src2) & 0x10;
124 zf = ((DATA_TYPE)CC_DST == 0) << 6;
125 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
126 of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
127 return cf | pf | af | zf | sf | of;
128}
129
130static int glue(compute_c_sub, SUFFIX)(void)
131{
132 int cf;
133 target_long src1, src2;
134 src1 = CC_DST + CC_SRC;
135 src2 = CC_SRC;
136 cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
137 return cf;
138}
139
140static int glue(compute_all_sbb, SUFFIX)(void)
141{
142 int cf, pf, af, zf, sf, of;
143 target_long src1, src2;
144 src1 = CC_DST + CC_SRC + 1;
145 src2 = CC_SRC;
146 cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
147 pf = parity_table[(uint8_t)CC_DST];
148 af = (CC_DST ^ src1 ^ src2) & 0x10;
149 zf = ((DATA_TYPE)CC_DST == 0) << 6;
150 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
151 of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
152 return cf | pf | af | zf | sf | of;
153}
154
155static int glue(compute_c_sbb, SUFFIX)(void)
156{
157 int cf;
158 target_long src1, src2;
159 src1 = CC_DST + CC_SRC + 1;
160 src2 = CC_SRC;
161 cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
162 return cf;
163}
164
165static int glue(compute_all_logic, SUFFIX)(void)
166{
167 int cf, pf, af, zf, sf, of;
168 cf = 0;
169 pf = parity_table[(uint8_t)CC_DST];
170 af = 0;
171 zf = ((DATA_TYPE)CC_DST == 0) << 6;
172 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
173 of = 0;
174 return cf | pf | af | zf | sf | of;
175}
176
177static int glue(compute_c_logic, SUFFIX)(void)
178{
179 return 0;
180}
181
182static int glue(compute_all_inc, SUFFIX)(void)
183{
184 int cf, pf, af, zf, sf, of;
185 target_long src1, src2;
186 src1 = CC_DST - 1;
187 src2 = 1;
188 cf = CC_SRC;
189 pf = parity_table[(uint8_t)CC_DST];
190 af = (CC_DST ^ src1 ^ src2) & 0x10;
191 zf = ((DATA_TYPE)CC_DST == 0) << 6;
192 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
193 of = ((CC_DST & DATA_MASK) == SIGN_MASK) << 11;
194 return cf | pf | af | zf | sf | of;
195}
196
197#if DATA_BITS == 32
198static int glue(compute_c_inc, SUFFIX)(void)
199{
200 return CC_SRC;
201}
202#endif
203
204static int glue(compute_all_dec, SUFFIX)(void)
205{
206 int cf, pf, af, zf, sf, of;
207 target_long src1, src2;
208 src1 = CC_DST + 1;
209 src2 = 1;
210 cf = CC_SRC;
211 pf = parity_table[(uint8_t)CC_DST];
212 af = (CC_DST ^ src1 ^ src2) & 0x10;
213 zf = ((DATA_TYPE)CC_DST == 0) << 6;
214 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
215 of = ((CC_DST & DATA_MASK) == ((target_ulong)SIGN_MASK - 1)) << 11;
216 return cf | pf | af | zf | sf | of;
217}
218
219static int glue(compute_all_shl, SUFFIX)(void)
220{
221 int cf, pf, af, zf, sf, of;
222 cf = (CC_SRC >> (DATA_BITS - 1)) & CC_C;
223 pf = parity_table[(uint8_t)CC_DST];
224 af = 0; /* undefined */
225 zf = ((DATA_TYPE)CC_DST == 0) << 6;
226 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
227 /* of is defined if shift count == 1 */
228 of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O;
229 return cf | pf | af | zf | sf | of;
230}
231
232static int glue(compute_c_shl, SUFFIX)(void)
233{
234 return (CC_SRC >> (DATA_BITS - 1)) & CC_C;
235}
236
237#if DATA_BITS == 32
238static int glue(compute_c_sar, SUFFIX)(void)
239{
240 return CC_SRC & 1;
241}
242#endif
243
244static int glue(compute_all_sar, SUFFIX)(void)
245{
246 int cf, pf, af, zf, sf, of;
247 cf = CC_SRC & 1;
248 pf = parity_table[(uint8_t)CC_DST];
249 af = 0; /* undefined */
250 zf = ((DATA_TYPE)CC_DST == 0) << 6;
251 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
252 /* of is defined if shift count == 1 */
253 of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O;
254 return cf | pf | af | zf | sf | of;
255}
256
257#if DATA_BITS == 32
258static int glue(compute_c_mul, SUFFIX)(void)
259{
260 int cf;
261 cf = (CC_SRC != 0);
262 return cf;
263}
264#endif
265
266/* NOTE: we compute the flags like the P4. On olders CPUs, only OF and
267 CF are modified and it is slower to do that. */
268static int glue(compute_all_mul, SUFFIX)(void)
269{
270 int cf, pf, af, zf, sf, of;
271 cf = (CC_SRC != 0);
272 pf = parity_table[(uint8_t)CC_DST];
273 af = 0; /* undefined */
274 zf = ((DATA_TYPE)CC_DST == 0) << 6;
275 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
276 of = cf << 11;
277 return cf | pf | af | zf | sf | of;
278}
279
280/* various optimized jumps cases */
281
282void OPPROTO glue(op_jb_sub, SUFFIX)(void)
283{
284 target_long src1, src2;
285 src1 = CC_DST + CC_SRC;
286 src2 = CC_SRC;
287
288 if ((DATA_TYPE)src1 < (DATA_TYPE)src2)
289 GOTO_LABEL_PARAM(1);
290 FORCE_RET();
291}
292
293void OPPROTO glue(op_jz_sub, SUFFIX)(void)
294{
295 if ((DATA_TYPE)CC_DST == 0)
296 GOTO_LABEL_PARAM(1);
297 FORCE_RET();
298}
299
300void OPPROTO glue(op_jnz_sub, SUFFIX)(void)
301{
302 if ((DATA_TYPE)CC_DST != 0)
303 GOTO_LABEL_PARAM(1);
304 FORCE_RET();
305}
306
307void OPPROTO glue(op_jbe_sub, SUFFIX)(void)
308{
309 target_long src1, src2;
310 src1 = CC_DST + CC_SRC;
311 src2 = CC_SRC;
312
313 if ((DATA_TYPE)src1 <= (DATA_TYPE)src2)
314 GOTO_LABEL_PARAM(1);
315 FORCE_RET();
316}
317
318void OPPROTO glue(op_js_sub, SUFFIX)(void)
319{
320 if (CC_DST & SIGN_MASK)
321 GOTO_LABEL_PARAM(1);
322 FORCE_RET();
323}
324
325void OPPROTO glue(op_jl_sub, SUFFIX)(void)
326{
327 target_long src1, src2;
328 src1 = CC_DST + CC_SRC;
329 src2 = CC_SRC;
330
331 if ((DATA_STYPE)src1 < (DATA_STYPE)src2)
332 GOTO_LABEL_PARAM(1);
333 FORCE_RET();
334}
335
336void OPPROTO glue(op_jle_sub, SUFFIX)(void)
337{
338 target_long src1, src2;
339 src1 = CC_DST + CC_SRC;
340 src2 = CC_SRC;
341
342 if ((DATA_STYPE)src1 <= (DATA_STYPE)src2)
343 GOTO_LABEL_PARAM(1);
344 FORCE_RET();
345}
346
347/* oldies */
348
349#if DATA_BITS >= 16
350
351void OPPROTO glue(op_loopnz, SUFFIX)(void)
352{
353 if ((DATA_TYPE)ECX != 0 && !(T0 & CC_Z))
354 GOTO_LABEL_PARAM(1);
355 FORCE_RET();
356}
357
358void OPPROTO glue(op_loopz, SUFFIX)(void)
359{
360 if ((DATA_TYPE)ECX != 0 && (T0 & CC_Z))
361 GOTO_LABEL_PARAM(1);
362 FORCE_RET();
363}
364
365void OPPROTO glue(op_jz_ecx, SUFFIX)(void)
366{
367 if ((DATA_TYPE)ECX == 0)
368 GOTO_LABEL_PARAM(1);
369 FORCE_RET();
370}
371
372void OPPROTO glue(op_jnz_ecx, SUFFIX)(void)
373{
374 if ((DATA_TYPE)ECX != 0)
375 GOTO_LABEL_PARAM(1);
376 FORCE_RET();
377}
378
379#endif
380
381/* various optimized set cases */
382
383void OPPROTO glue(op_setb_T0_sub, SUFFIX)(void)
384{
385 target_long src1, src2;
386 src1 = CC_DST + CC_SRC;
387 src2 = CC_SRC;
388
389 T0 = ((DATA_TYPE)src1 < (DATA_TYPE)src2);
390}
391
392void OPPROTO glue(op_setz_T0_sub, SUFFIX)(void)
393{
394 T0 = ((DATA_TYPE)CC_DST == 0);
395}
396
397void OPPROTO glue(op_setbe_T0_sub, SUFFIX)(void)
398{
399 target_long src1, src2;
400 src1 = CC_DST + CC_SRC;
401 src2 = CC_SRC;
402
403 T0 = ((DATA_TYPE)src1 <= (DATA_TYPE)src2);
404}
405
406void OPPROTO glue(op_sets_T0_sub, SUFFIX)(void)
407{
408 T0 = lshift(CC_DST, -(DATA_BITS - 1)) & 1;
409}
410
411void OPPROTO glue(op_setl_T0_sub, SUFFIX)(void)
412{
413 target_long src1, src2;
414 src1 = CC_DST + CC_SRC;
415 src2 = CC_SRC;
416
417 T0 = ((DATA_STYPE)src1 < (DATA_STYPE)src2);
418}
419
420void OPPROTO glue(op_setle_T0_sub, SUFFIX)(void)
421{
422 target_long src1, src2;
423 src1 = CC_DST + CC_SRC;
424 src2 = CC_SRC;
425
426 T0 = ((DATA_STYPE)src1 <= (DATA_STYPE)src2);
427}
428
429/* shifts */
430
431void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1)(void)
432{
433 int count;
434 count = T1 & SHIFT1_MASK;
435 T0 = T0 << count;
436 FORCE_RET();
437}
438
439void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1)(void)
440{
441 int count;
442 count = T1 & SHIFT1_MASK;
443 T0 &= DATA_MASK;
444 T0 = T0 >> count;
445 FORCE_RET();
446}
447
448void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1)(void)
449{
450 int count;
451 target_long src;
452
453 count = T1 & SHIFT1_MASK;
454 src = (DATA_STYPE)T0;
455 T0 = src >> count;
456 FORCE_RET();
457}
458
459#undef MEM_WRITE
460#include "ops_template_mem.h"
461
462#define MEM_WRITE 0
463#include "ops_template_mem.h"
464
465#if !defined(CONFIG_USER_ONLY)
466#define MEM_WRITE 1
467#include "ops_template_mem.h"
468
469#define MEM_WRITE 2
470#include "ops_template_mem.h"
471#endif
472
473/* bit operations */
474#if DATA_BITS >= 16
475
476void OPPROTO glue(glue(op_bt, SUFFIX), _T0_T1_cc)(void)
477{
478 int count;
479 count = T1 & SHIFT_MASK;
480 CC_SRC = T0 >> count;
481}
482
483void OPPROTO glue(glue(op_bts, SUFFIX), _T0_T1_cc)(void)
484{
485 int count;
486 count = T1 & SHIFT_MASK;
487 T1 = T0 >> count;
488 T0 |= (((target_long)1) << count);
489}
490
491void OPPROTO glue(glue(op_btr, SUFFIX), _T0_T1_cc)(void)
492{
493 int count;
494 count = T1 & SHIFT_MASK;
495 T1 = T0 >> count;
496 T0 &= ~(((target_long)1) << count);
497}
498
499void OPPROTO glue(glue(op_btc, SUFFIX), _T0_T1_cc)(void)
500{
501 int count;
502 count = T1 & SHIFT_MASK;
503 T1 = T0 >> count;
504 T0 ^= (((target_long)1) << count);
505}
506
507void OPPROTO glue(glue(op_add_bit, SUFFIX), _A0_T1)(void)
508{
509 A0 += ((DATA_STYPE)T1 >> (3 + SHIFT)) << SHIFT;
510}
511
512void OPPROTO glue(glue(op_bsf, SUFFIX), _T0_cc)(void)
513{
514 int count;
515 target_long res;
516
517 res = T0 & DATA_MASK;
518 if (res != 0) {
519 count = 0;
520 while ((res & 1) == 0) {
521 count++;
522 res >>= 1;
523 }
524 T1 = count;
525 CC_DST = 1; /* ZF = 0 */
526 } else {
527 CC_DST = 0; /* ZF = 1 */
528 }
529 FORCE_RET();
530}
531
532void OPPROTO glue(glue(op_bsr, SUFFIX), _T0_cc)(void)
533{
534 int count;
535 target_long res;
536
537 res = T0 & DATA_MASK;
538 if (res != 0) {
539 count = DATA_BITS - 1;
540 while ((res & SIGN_MASK) == 0) {
541 count--;
542 res <<= 1;
543 }
544 T1 = count;
545 CC_DST = 1; /* ZF = 0 */
546 } else {
547 CC_DST = 0; /* ZF = 1 */
548 }
549 FORCE_RET();
550}
551
552#endif
553
554#if DATA_BITS == 32
555void OPPROTO op_update_bt_cc(void)
556{
557 CC_SRC = T1;
558}
559#endif
560
561/* string operations */
562
563void OPPROTO glue(op_movl_T0_Dshift, SUFFIX)(void)
564{
565 T0 = DF << SHIFT;
566}
567
568/* port I/O */
569#if DATA_BITS <= 32
570void OPPROTO glue(glue(op_out, SUFFIX), _T0_T1)(void)
571{
572 glue(cpu_out, SUFFIX)(env, T0, T1 & DATA_MASK);
573}
574
575void OPPROTO glue(glue(op_in, SUFFIX), _T0_T1)(void)
576{
577 T1 = glue(cpu_in, SUFFIX)(env, T0);
578}
579
580void OPPROTO glue(glue(op_in, SUFFIX), _DX_T0)(void)
581{
582 T0 = glue(cpu_in, SUFFIX)(env, EDX & 0xffff);
583}
584
585void OPPROTO glue(glue(op_out, SUFFIX), _DX_T0)(void)
586{
587 glue(cpu_out, SUFFIX)(env, EDX & 0xffff, T0);
588}
589
590void OPPROTO glue(glue(op_check_io, SUFFIX), _T0)(void)
591{
592 glue(glue(check_io, SUFFIX), _T0)();
593}
594
595void OPPROTO glue(glue(op_check_io, SUFFIX), _DX)(void)
596{
597 glue(glue(check_io, SUFFIX), _DX)();
598}
599#endif
600
601#undef DATA_BITS
602#undef SHIFT_MASK
603#undef SHIFT1_MASK
604#undef SIGN_MASK
605#undef DATA_TYPE
606#undef DATA_STYPE
607#undef DATA_MASK
608#undef SUFFIX
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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