VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMAll/IEMAllAImpl.asm@ 38018

Last change on this file since 38018 was 38018, checked in by vboxsync, 13 years ago

IEM: Made it link on 32-bit windows.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 36.1 KB
Line 
1; $Id: IEMAllAImpl.asm 38018 2011-07-18 13:43:36Z vboxsync $
2;; @file
3; IEM - Instruction Implementation in Assembly.
4;
5
6; Copyright (C) 2011 Oracle Corporation
7;
8; This file is part of VirtualBox Open Source Edition (OSE), as
9; available from http://www.virtualbox.org. This file is free software;
10; you can redistribute it and/or modify it under the terms of the GNU
11; General Public License (GPL) as published by the Free Software
12; Foundation, in version 2 as it comes in the "COPYING" file of the
13; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15;
16
17
18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19; Header Files ;
20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21%include "VBox/asmdefs.mac"
22%include "VBox/err.mac"
23%include "iprt/x86.mac"
24
25
26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
27; Defined Constants And Macros ;
28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
29
30;
31; We employ some macro assembly here to hid the calling convention differences.
32;
33%ifdef RT_ARCH_AMD64
34 %macro PROLOGUE_1_ARGS 0
35 %endmacro
36 %macro EPILOGUE_1_ARGS 0
37 %endmacro
38 %macro PROLOGUE_2_ARGS 0
39 %endmacro
40 %macro EPILOGUE_2_ARGS 0
41 %endmacro
42 %macro PROLOGUE_3_ARGS 0
43 %endmacro
44 %macro EPILOGUE_3_ARGS 0
45 %endmacro
46 %macro PROLOGUE_4_ARGS 0
47 %endmacro
48 %macro EPILOGUE_4_ARGS 0
49 %endmacro
50
51 %ifdef ASM_CALL64_GCC
52 %define A0 rdi
53 %define A0_32 edi
54 %define A0_16 di
55 %define A0_8 dil
56
57 %define A1 rsi
58 %define A1_32 esi
59 %define A1_16 si
60 %define A1_8 sil
61
62 %define A2 rdx
63 %define A2_32 edx
64 %define A2_16 dx
65 %define A2_8 dl
66
67 %define A3 rcx
68 %define A3_32 ecx
69 %define A3_16 cx
70 %endif
71
72 %ifdef ASM_CALL64_MSC
73 %define A0 rcx
74 %define A0_32 ecx
75 %define A0_16 cx
76 %define A0_8 cl
77
78 %define A1 rdx
79 %define A1_32 edx
80 %define A1_16 dx
81 %define A1_8 dl
82
83 %define A2 r8
84 %define A2_32 r8d
85 %define A2_16 r8w
86 %define A2_8 r8b
87
88 %define A3 r9
89 %define A3_32 r9d
90 %define A3_16 r9w
91 %endif
92
93 %define T0 rax
94 %define T0_32 eax
95 %define T0_16 ax
96 %define T0_8 al
97
98 %define T1 r11
99 %define T1_32 r11d
100 %define T1_16 r11w
101 %define T1_8 r11b
102
103%else
104 ; x86
105 %macro PROLOGUE_1_ARGS 0
106 push edi
107 %endmacro
108 %macro EPILOGUE_1_ARGS 0
109 pop edi
110 %endmacro
111
112 %macro PROLOGUE_2_ARGS 0
113 push edi
114 %endmacro
115 %macro EPILOGUE_2_ARGS 0
116 pop edi
117 %endmacro
118
119 %macro PROLOGUE_3_ARGS 0
120 push ebx
121 mov ebx, [esp + 4 + 4]
122 push edi
123 %endmacro
124 %macro EPILOGUE_3_ARGS 0
125 pop edi
126 pop ebx
127 %endmacro
128
129 %macro PROLOGUE_4_ARGS 0
130 push ebx
131 push edi
132 push esi
133 mov ebx, [esp + 12 + 4 + 0]
134 mov esi, [esp + 12 + 4 + 4]
135 %endmacro
136 %macro EPILOGUE_4_ARGS 0
137 pop esi
138 pop edi
139 pop ebx
140 %endmacro
141
142 %define A0 ecx
143 %define A0_32 ecx
144 %define A0_16 cx
145 %define A0_8 cl
146
147 %define A1 edx
148 %define A1_32 edx
149 %define A1_16 dx
150 %define A1_8 dl
151
152 %define A2 ebx
153 %define A2_32 ebx
154 %define A2_16 bx
155 %define A2_8 bl
156
157 %define A3 esi
158 %define A3_32 esi
159 %define A3_16 si
160
161 %define T0 eax
162 %define T0_32 eax
163 %define T0_16 ax
164 %define T0_8 al
165
166 %define T1 edi
167 %define T1_32 edi
168 %define T1_16 di
169%endif
170
171;;
172; NAME for fastcall functions.
173;
174;; @todo 'global @fastcall@12' is still broken in yasm and requires dollar
175; escaping (or whatever the dollar is good for here). Thus the ugly
176; prefix argument.
177;
178%define NAME_FASTCALL(a_Name, a_cbArgs, a_Dollar) NAME(a_aName)
179%ifdef RT_ARCH_X86
180 %ifdef RT_OS_WINDOWS
181 %undef NAME_FASTCALL
182 %define NAME_FASTCALL(a_Name, a_cbArgs, a_Prefix) a_Prefix %+ a_Name %+ @ %+ a_cbArgs
183 %endif
184%endif
185
186;;
187; BEGINPROC for fastcall functions.
188;
189; @param 1 The function name (C).
190; @param 2 The argument size on x86.
191;
192%macro BEGINPROC_FASTCALL 2
193 %ifdef ASM_FORMAT_PE
194 export %1=NAME_FASTCALL(%1,%2,$@)
195 %endif
196 %ifdef __NASM__
197 %ifdef ASM_FORMAT_OMF
198 export NAME(%1) NAME_FASTCALL(%1,%2,$@)
199 %endif
200 %endif
201 %ifndef ASM_FORMAT_BIN
202 global NAME_FASTCALL(%1,%2,$@)
203 %endif
204NAME_FASTCALL(%1,%2,@):
205%endmacro
206
207
208;;
209; Load the relevant flags from [%1] if there are undefined flags (%3).
210;
211; @remarks Clobbers T0, stack. Changes EFLAGS.
212; @param A2 The register pointing to the flags.
213; @param 1 The parameter (A0..A3) pointing to the eflags.
214; @param 2 The set of modified flags.
215; @param 3 The set of undefined flags.
216;
217%macro IEM_MAYBE_LOAD_FLAGS 3
218 ;%if (%3) != 0
219 pushf ; store current flags
220 mov T0_32, [%1] ; load the guest flags
221 and dword [xSP], ~(%2 | %3) ; mask out the modified and undefined flags
222 and T0_32, (%2 | %3) ; select the modified and undefined flags.
223 or [xSP], T0 ; merge guest flags with host flags.
224 popf ; load the mixed flags.
225 ;%endif
226%endmacro
227
228;;
229; Update the flag.
230;
231; @remarks Clobbers T0, T1, stack.
232; @param 1 The register pointing to the EFLAGS.
233; @param 2 The mask of modified flags to save.
234; @param 3 The mask of undefined flags to (maybe) save.
235;
236%macro IEM_SAVE_FLAGS 3
237 %if (%2 | %3) != 0
238 pushf
239 pop T1
240 mov T0_32, [%1] ; flags
241 and T0_32, ~(%2 | %3) ; clear the modified & undefined flags.
242 and T1_32, (%2 | %3) ; select the modified and undefined flags.
243 or T0_32, T1_32 ; combine the flags.
244 mov [%1], T0_32 ; save the flags.
245 %endif
246%endmacro
247
248
249;;
250; Macro for implementing a binary operator.
251;
252; This will generate code for the 8, 16, 32 and 64 bit accesses with locked
253; variants, except on 32-bit system where the 64-bit accesses requires hand
254; coding.
255;
256; All the functions takes a pointer to the destination memory operand in A0,
257; the source register operand in A1 and a pointer to eflags in A2.
258;
259; @param 1 The instruction mnemonic.
260; @param 2 Non-zero if there should be a locked version.
261; @param 3 The modified flags.
262; @param 4 The undefined flags.
263;
264%macro IEMIMPL_BIN_OP 4
265BEGINCODE
266BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u8, 12
267 PROLOGUE_3_ARGS
268 IEM_MAYBE_LOAD_FLAGS A2, %3, %4
269 %1 byte [A0], A1_8
270 IEM_SAVE_FLAGS A2, %3, %4
271 EPILOGUE_3_ARGS
272 ret
273ENDPROC iemAImpl_ %+ %1 %+ _u8
274
275BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16, 12
276 PROLOGUE_3_ARGS
277 IEM_MAYBE_LOAD_FLAGS A2, %3, %4
278 %1 word [A0], A1_16
279 IEM_SAVE_FLAGS A2, %3, %4
280 EPILOGUE_3_ARGS
281 ret
282ENDPROC iemAImpl_ %+ %1 %+ _u16
283
284BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32, 12
285 PROLOGUE_3_ARGS
286 IEM_MAYBE_LOAD_FLAGS A2, %3, %4
287 %1 dword [A0], A1_32
288 IEM_SAVE_FLAGS A2, %3, %4
289 EPILOGUE_3_ARGS
290 ret
291ENDPROC iemAImpl_ %+ %1 %+ _u32
292
293 %ifdef RT_ARCH_AMD64
294BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 16
295 PROLOGUE_3_ARGS
296 IEM_MAYBE_LOAD_FLAGS A2, %3, %4
297 %1 qword [A0], A1
298 IEM_SAVE_FLAGS A2, %3, %4
299 EPILOGUE_3_ARGS
300 ret
301ENDPROC iemAImpl_ %+ %1 %+ _u64
302 %else ; stub it for now - later, replace with hand coded stuff.
303BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 16
304 int3
305 ret
306ENDPROC iemAImpl_ %+ %1 %+ _u64
307 %endif ; !RT_ARCH_AMD64
308
309 %if %2 != 0 ; locked versions requested?
310
311BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u8_locked, 12
312 PROLOGUE_3_ARGS
313 IEM_MAYBE_LOAD_FLAGS A2, %3, %4
314 lock %1 byte [A0], A1_8
315 IEM_SAVE_FLAGS A2, %3, %4
316 EPILOGUE_3_ARGS
317 ret
318ENDPROC iemAImpl_ %+ %1 %+ _u8_locked
319
320BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16_locked, 12
321 PROLOGUE_3_ARGS
322 IEM_MAYBE_LOAD_FLAGS A2, %3, %4
323 lock %1 word [A0], A1_16
324 IEM_SAVE_FLAGS A2, %3, %4
325 EPILOGUE_3_ARGS
326 ret
327ENDPROC iemAImpl_ %+ %1 %+ _u16_locked
328
329BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32_locked, 12
330 PROLOGUE_3_ARGS
331 IEM_MAYBE_LOAD_FLAGS A2, %3, %4
332 lock %1 dword [A0], A1_32
333 IEM_SAVE_FLAGS A2, %3, %4
334 EPILOGUE_3_ARGS
335 ret
336ENDPROC iemAImpl_ %+ %1 %+ _u32_locked
337
338 %ifdef RT_ARCH_AMD64
339BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64_locked, 16
340 PROLOGUE_3_ARGS
341 IEM_MAYBE_LOAD_FLAGS A2, %3, %4
342 lock %1 qword [A0], A1
343 IEM_SAVE_FLAGS A2, %3, %4
344 EPILOGUE_3_ARGS
345 ret
346ENDPROC iemAImpl_ %+ %1 %+ _u64_locked
347 %else ; stub it for now - later, replace with hand coded stuff.
348BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64_locked, 16
349 int3
350 ret
351ENDPROC iemAImpl_ %+ %1 %+ _u64_locked
352 %endif ; !RT_ARCH_AMD64
353 %endif ; locked
354%endmacro
355
356; instr,lock,modified-flags.
357IEMIMPL_BIN_OP add, 1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
358IEMIMPL_BIN_OP adc, 1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
359IEMIMPL_BIN_OP sub, 1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
360IEMIMPL_BIN_OP sbb, 1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
361IEMIMPL_BIN_OP or, 1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), X86_EFL_AF,
362IEMIMPL_BIN_OP xor, 1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), X86_EFL_AF,
363IEMIMPL_BIN_OP and, 1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), X86_EFL_AF,
364IEMIMPL_BIN_OP cmp, 0, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
365IEMIMPL_BIN_OP test, 0, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), X86_EFL_AF,
366
367
368;;
369; Macro for implementing a bit operator.
370;
371; This will generate code for the 16, 32 and 64 bit accesses with locked
372; variants, except on 32-bit system where the 64-bit accesses requires hand
373; coding.
374;
375; All the functions takes a pointer to the destination memory operand in A0,
376; the source register operand in A1 and a pointer to eflags in A2.
377;
378; @param 1 The instruction mnemonic.
379; @param 2 Non-zero if there should be a locked version.
380; @param 3 The modified flags.
381; @param 4 The undefined flags.
382;
383%macro IEMIMPL_BIT_OP 4
384BEGINCODE
385BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16, 12
386 PROLOGUE_3_ARGS
387 IEM_MAYBE_LOAD_FLAGS A2, %3, %4
388 %1 word [A0], A1_16
389 IEM_SAVE_FLAGS A2, %3, %4
390 EPILOGUE_3_ARGS
391 ret
392ENDPROC iemAImpl_ %+ %1 %+ _u16
393
394BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32, 12
395 PROLOGUE_3_ARGS
396 IEM_MAYBE_LOAD_FLAGS A2, %3, %4
397 %1 dword [A0], A1_32
398 IEM_SAVE_FLAGS A2, %3, %4
399 EPILOGUE_3_ARGS
400 ret
401ENDPROC iemAImpl_ %+ %1 %+ _u32
402
403 %ifdef RT_ARCH_AMD64
404BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 16
405 PROLOGUE_3_ARGS
406 IEM_MAYBE_LOAD_FLAGS A2, %3, %4
407 %1 qword [A0], A1
408 IEM_SAVE_FLAGS A2, %3, %4
409 EPILOGUE_3_ARGS
410 ret
411ENDPROC iemAImpl_ %+ %1 %+ _u64
412 %else ; stub it for now - later, replace with hand coded stuff.
413BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 16
414 int3
415 ret
416ENDPROC iemAImpl_ %+ %1 %+ _u64
417 %endif ; !RT_ARCH_AMD64
418
419 %if %2 != 0 ; locked versions requested?
420
421BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16_locked, 12
422 PROLOGUE_3_ARGS
423 IEM_MAYBE_LOAD_FLAGS A2, %3, %4
424 lock %1 word [A0], A1_16
425 IEM_SAVE_FLAGS A2, %3, %4
426 EPILOGUE_3_ARGS
427 ret
428ENDPROC iemAImpl_ %+ %1 %+ _u16_locked
429
430BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32_locked, 12
431 PROLOGUE_3_ARGS
432 IEM_MAYBE_LOAD_FLAGS A2, %3, %4
433 lock %1 dword [A0], A1_32
434 IEM_SAVE_FLAGS A2, %3, %4
435 EPILOGUE_3_ARGS
436 ret
437ENDPROC iemAImpl_ %+ %1 %+ _u32_locked
438
439 %ifdef RT_ARCH_AMD64
440BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64_locked, 16
441 PROLOGUE_3_ARGS
442 IEM_MAYBE_LOAD_FLAGS A2, %3, %4
443 lock %1 qword [A0], A1
444 IEM_SAVE_FLAGS A2, %3, %4
445 EPILOGUE_3_ARGS
446 ret
447ENDPROC iemAImpl_ %+ %1 %+ _u64_locked
448 %else ; stub it for now - later, replace with hand coded stuff.
449BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64_locked, 16
450 int3
451 ret
452ENDPROC iemAImpl_ %+ %1 %+ _u64_locked
453 %endif ; !RT_ARCH_AMD64
454 %endif ; locked
455%endmacro
456IEMIMPL_BIT_OP bt, 0, (X86_EFL_CF), (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
457IEMIMPL_BIT_OP btc, 1, (X86_EFL_CF), (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
458IEMIMPL_BIT_OP bts, 1, (X86_EFL_CF), (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
459IEMIMPL_BIT_OP btr, 1, (X86_EFL_CF), (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
460
461;;
462; Macro for implementing a bit search operator.
463;
464; This will generate code for the 16, 32 and 64 bit accesses, except on 32-bit
465; system where the 64-bit accesses requires hand coding.
466;
467; All the functions takes a pointer to the destination memory operand in A0,
468; the source register operand in A1 and a pointer to eflags in A2.
469;
470; @param 1 The instruction mnemonic.
471; @param 2 The modified flags.
472; @param 3 The undefined flags.
473;
474%macro IEMIMPL_BIT_OP 3
475BEGINCODE
476BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16, 12
477 PROLOGUE_3_ARGS
478 IEM_MAYBE_LOAD_FLAGS A2, %2, %3
479 %1 T0_16, A1_16
480 mov [A0], T0_16
481 IEM_SAVE_FLAGS A2, %2, %3
482 EPILOGUE_3_ARGS
483 ret
484ENDPROC iemAImpl_ %+ %1 %+ _u16
485
486BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32, 12
487 PROLOGUE_3_ARGS
488 IEM_MAYBE_LOAD_FLAGS A2, %2, %3
489 %1 T0_32, A1_32
490 mov [A0], T0_32
491 IEM_SAVE_FLAGS A2, %2, %3
492 EPILOGUE_3_ARGS
493 ret
494ENDPROC iemAImpl_ %+ %1 %+ _u32
495
496 %ifdef RT_ARCH_AMD64
497BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 16
498 PROLOGUE_3_ARGS
499 IEM_MAYBE_LOAD_FLAGS A2, %2, %3
500 %1 T0, A1
501 mov [A0], T0
502 IEM_SAVE_FLAGS A2, %2, %3
503 EPILOGUE_3_ARGS
504 ret
505ENDPROC iemAImpl_ %+ %1 %+ _u64
506 %else ; stub it for now - later, replace with hand coded stuff.
507BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 16
508 int3
509 ret
510ENDPROC iemAImpl_ %+ %1 %+ _u64
511 %endif ; !RT_ARCH_AMD64
512%endmacro
513IEMIMPL_BIT_OP bsf, (X86_EFL_ZF), (X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF)
514IEMIMPL_BIT_OP bsr, (X86_EFL_ZF), (X86_EFL_OF | X86_EFL_SF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF)
515
516
517;
518; IMUL is also a similar but yet different case (no lock, no mem dst).
519; The rDX:rAX variant of imul is handled together with mul further down.
520;
521BEGINCODE
522BEGINPROC_FASTCALL iemAImpl_imul_two_u16, 12
523 PROLOGUE_3_ARGS
524 IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_CF), (X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
525 imul A1_16, word [A0]
526 mov [A0], A1_16
527 IEM_SAVE_FLAGS A2, (X86_EFL_OF | X86_EFL_CF), (X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
528 EPILOGUE_3_ARGS
529 ret
530ENDPROC iemAImpl_imul_two_u16
531
532BEGINPROC_FASTCALL iemAImpl_imul_two_u32, 12
533 PROLOGUE_3_ARGS
534 IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_CF), (X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
535 imul A1_32, dword [A0]
536 mov [A0], A1_32
537 IEM_SAVE_FLAGS A2, (X86_EFL_OF | X86_EFL_CF), (X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
538 EPILOGUE_3_ARGS
539 ret
540ENDPROC iemAImpl_imul_two_u32
541
542BEGINPROC_FASTCALL iemAImpl_imul_two_u64, 16
543 PROLOGUE_3_ARGS
544%ifdef RT_ARCH_AMD64
545 IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_CF), (X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
546 imul A1, qword [A0]
547 mov [A0], A1
548 IEM_SAVE_FLAGS A2, (X86_EFL_OF | X86_EFL_CF), (X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
549%else
550 int3 ;; @todo implement me
551%endif
552 EPILOGUE_3_ARGS
553 ret
554ENDPROC iemAImpl_imul_two_u64
555
556
557;
558; XCHG for memory operands. This implies locking. No flag changes.
559;
560; Each function takes two arguments, first the pointer to the memory,
561; then the pointer to the register. They all return void.
562;
563BEGINCODE
564BEGINPROC_FASTCALL iemAImpl_xchg_u8, 8
565 PROLOGUE_2_ARGS
566 mov T0_8, [A1]
567 xchg [A0], T0_8
568 mov [A1], T0_8
569 EPILOGUE_2_ARGS
570 ret
571ENDPROC iemAImpl_xchg_u8
572
573BEGINPROC_FASTCALL iemAImpl_xchg_u16, 8
574 PROLOGUE_2_ARGS
575 mov T0_16, [A1]
576 xchg [A0], T0_16
577 mov [A1], T0_16
578 EPILOGUE_2_ARGS
579 ret
580ENDPROC iemAImpl_xchg_u16
581
582BEGINPROC_FASTCALL iemAImpl_xchg_u32, 8
583 PROLOGUE_2_ARGS
584 mov T0_32, [A1]
585 xchg [A0], T0_32
586 mov [A1], T0_32
587 EPILOGUE_2_ARGS
588 ret
589ENDPROC iemAImpl_xchg_u32
590
591BEGINPROC_FASTCALL iemAImpl_xchg_u64, 8
592%ifdef RT_ARCH_AMD64
593 PROLOGUE_2_ARGS
594 mov T0, [A1]
595 xchg [A0], T0
596 mov [A1], T0
597 EPILOGUE_2_ARGS
598 ret
599%else
600 int3
601%endif
602ENDPROC iemAImpl_xchg_u64
603
604
605;
606; XADD for memory operands.
607;
608; Each function takes three arguments, first the pointer to the
609; memory/register, then the pointer to the register, and finally a pointer to
610; eflags. They all return void.
611;
612BEGINCODE
613BEGINPROC_FASTCALL iemAImpl_xadd_u8, 12
614 PROLOGUE_3_ARGS
615 IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
616 mov T0_8, [A1]
617 xadd [A0], T0_8
618 mov [A1], T0_8
619 IEM_SAVE_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
620 EPILOGUE_3_ARGS
621 ret
622ENDPROC iemAImpl_xadd_u8
623
624BEGINPROC_FASTCALL iemAImpl_xadd_u16, 12
625 PROLOGUE_3_ARGS
626 IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
627 mov T0_16, [A1]
628 xadd [A0], T0_16
629 mov [A1], T0_16
630 IEM_SAVE_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
631 EPILOGUE_3_ARGS
632 ret
633ENDPROC iemAImpl_xadd_u16
634
635BEGINPROC_FASTCALL iemAImpl_xadd_u32, 12
636 PROLOGUE_3_ARGS
637 IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
638 mov T0_32, [A1]
639 xadd [A0], T0_32
640 mov [A1], T0_32
641 IEM_SAVE_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
642 EPILOGUE_3_ARGS
643 ret
644ENDPROC iemAImpl_xadd_u32
645
646BEGINPROC_FASTCALL iemAImpl_xadd_u64, 12
647%ifdef RT_ARCH_AMD64
648 PROLOGUE_3_ARGS
649 IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
650 mov T0, [A1]
651 xadd [A0], T0
652 mov [A1], T0
653 IEM_SAVE_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
654 EPILOGUE_3_ARGS
655 ret
656%else
657 int3
658%endif
659ENDPROC iemAImpl_xadd_u64
660
661BEGINPROC_FASTCALL iemAImpl_xadd_u8_locked, 12
662 PROLOGUE_3_ARGS
663 IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
664 mov T0_8, [A1]
665 lock xadd [A0], T0_8
666 mov [A1], T0_8
667 IEM_SAVE_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
668 EPILOGUE_3_ARGS
669 ret
670ENDPROC iemAImpl_xadd_u8_locked
671
672BEGINPROC_FASTCALL iemAImpl_xadd_u16_locked, 12
673 PROLOGUE_3_ARGS
674 IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
675 mov T0_16, [A1]
676 lock xadd [A0], T0_16
677 mov [A1], T0_16
678 IEM_SAVE_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
679 EPILOGUE_3_ARGS
680 ret
681ENDPROC iemAImpl_xadd_u16_locked
682
683BEGINPROC_FASTCALL iemAImpl_xadd_u32_locked, 12
684 PROLOGUE_3_ARGS
685 IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
686 mov T0_32, [A1]
687 lock xadd [A0], T0_32
688 mov [A1], T0_32
689 IEM_SAVE_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
690 EPILOGUE_3_ARGS
691 ret
692ENDPROC iemAImpl_xadd_u32_locked
693
694BEGINPROC_FASTCALL iemAImpl_xadd_u64_locked, 12
695%ifdef RT_ARCH_AMD64
696 PROLOGUE_3_ARGS
697 IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
698 mov T0, [A1]
699 lock xadd [A0], T0
700 mov [A1], T0
701 IEM_SAVE_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
702 EPILOGUE_3_ARGS
703 ret
704%else
705 int3
706%endif
707ENDPROC iemAImpl_xadd_u64_locked
708
709
710;;
711; Macro for implementing a unary operator.
712;
713; This will generate code for the 8, 16, 32 and 64 bit accesses with locked
714; variants, except on 32-bit system where the 64-bit accesses requires hand
715; coding.
716;
717; All the functions takes a pointer to the destination memory operand in A0,
718; the source register operand in A1 and a pointer to eflags in A2.
719;
720; @param 1 The instruction mnemonic.
721; @param 2 The modified flags.
722; @param 3 The undefined flags.
723;
724%macro IEMIMPL_UNARY_OP 3
725BEGINCODE
726BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u8, 8
727 PROLOGUE_2_ARGS
728 IEM_MAYBE_LOAD_FLAGS A1, %2, %3
729 %1 byte [A0]
730 IEM_SAVE_FLAGS A1, %2, %3
731 EPILOGUE_2_ARGS
732 ret
733ENDPROC iemAImpl_ %+ %1 %+ _u8
734
735BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u8_locked, 8
736 PROLOGUE_2_ARGS
737 IEM_MAYBE_LOAD_FLAGS A1, %2, %3
738 lock %1 byte [A0]
739 IEM_SAVE_FLAGS A1, %2, %3
740 EPILOGUE_2_ARGS
741 ret
742ENDPROC iemAImpl_ %+ %1 %+ _u8_locked
743
744BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16, 8
745 PROLOGUE_2_ARGS
746 IEM_MAYBE_LOAD_FLAGS A1, %2, %3
747 %1 word [A0]
748 IEM_SAVE_FLAGS A1, %2, %3
749 EPILOGUE_2_ARGS
750 ret
751ENDPROC iemAImpl_ %+ %1 %+ _u16
752
753BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16_locked, 8
754 PROLOGUE_2_ARGS
755 IEM_MAYBE_LOAD_FLAGS A1, %2, %3
756 lock %1 word [A0]
757 IEM_SAVE_FLAGS A1, %2, %3
758 EPILOGUE_2_ARGS
759 ret
760ENDPROC iemAImpl_ %+ %1 %+ _u16_locked
761
762BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32, 8
763 PROLOGUE_2_ARGS
764 IEM_MAYBE_LOAD_FLAGS A1, %2, %3
765 %1 dword [A0]
766 IEM_SAVE_FLAGS A1, %2, %3
767 EPILOGUE_2_ARGS
768 ret
769ENDPROC iemAImpl_ %+ %1 %+ _u32
770
771BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32_locked, 8
772 PROLOGUE_2_ARGS
773 IEM_MAYBE_LOAD_FLAGS A1, %2, %3
774 lock %1 dword [A0]
775 IEM_SAVE_FLAGS A1, %2, %3
776 EPILOGUE_2_ARGS
777 ret
778ENDPROC iemAImpl_ %+ %1 %+ _u32_locked
779
780 %ifdef RT_ARCH_AMD64
781BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 8
782 PROLOGUE_2_ARGS
783 IEM_MAYBE_LOAD_FLAGS A1, %2, %3
784 %1 qword [A0]
785 IEM_SAVE_FLAGS A1, %2, %3
786 EPILOGUE_2_ARGS
787 ret
788ENDPROC iemAImpl_ %+ %1 %+ _u64
789
790BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64_locked, 8
791 PROLOGUE_2_ARGS
792 IEM_MAYBE_LOAD_FLAGS A1, %2, %3
793 lock %1 qword [A0]
794 IEM_SAVE_FLAGS A1, %2, %3
795 EPILOGUE_2_ARGS
796 ret
797ENDPROC iemAImpl_ %+ %1 %+ _u64_locked
798 %else
799 ; stub them for now.
800BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 8
801 int3
802 ret
803ENDPROC iemAImpl_ %+ %1 %+ _u64
804BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64_locked, 8
805 int3
806 ret
807ENDPROC iemAImpl_ %+ %1 %+ _u64_locked
808 %endif
809
810%endmacro
811
812IEMIMPL_UNARY_OP inc, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF), 0
813IEMIMPL_UNARY_OP dec, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF), 0
814IEMIMPL_UNARY_OP neg, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
815IEMIMPL_UNARY_OP not, 0, 0
816
817
818
819;;
820; Macro for implementing a shift operation.
821;
822; This will generate code for the 8, 16, 32 and 64 bit accesses, except on
823; 32-bit system where the 64-bit accesses requires hand coding.
824;
825; All the functions takes a pointer to the destination memory operand in A0,
826; the shift count in A1 and a pointer to eflags in A2.
827;
828; @param 1 The instruction mnemonic.
829; @param 2 The modified flags.
830; @param 3 The undefined flags.
831;
832; Makes ASSUMPTIONS about A0, A1 and A2 assignments.
833;
834%macro IEMIMPL_SHIFT_OP 3
835BEGINCODE
836BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u8, 12
837 PROLOGUE_3_ARGS
838 IEM_MAYBE_LOAD_FLAGS A2, %2, %3
839 %ifdef ASM_CALL64_GCC
840 mov cl, A1_8
841 %1 byte [A0], cl
842 %else
843 xchg A1, A0
844 %1 byte [A1], cl
845 %endif
846 IEM_SAVE_FLAGS A2, %2, %3
847 EPILOGUE_3_ARGS
848 ret
849ENDPROC iemAImpl_ %+ %1 %+ _u8
850
851BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16, 12
852 PROLOGUE_3_ARGS
853 IEM_MAYBE_LOAD_FLAGS A2, %2, %3
854 %ifdef ASM_CALL64_GCC
855 mov cl, A1_8
856 %1 word [A0], cl
857 %else
858 xchg A1, A0
859 %1 word [A1], cl
860 %endif
861 IEM_SAVE_FLAGS A2, %2, %3
862 EPILOGUE_3_ARGS
863 ret
864ENDPROC iemAImpl_ %+ %1 %+ _u16
865
866BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32, 12
867 PROLOGUE_3_ARGS
868 IEM_MAYBE_LOAD_FLAGS A2, %2, %3
869 %ifdef ASM_CALL64_GCC
870 mov cl, A1_8
871 %1 dword [A0], cl
872 %else
873 xchg A1, A0
874 %1 dword [A1], cl
875 %endif
876 IEM_SAVE_FLAGS A2, %2, %3
877 EPILOGUE_3_ARGS
878 ret
879ENDPROC iemAImpl_ %+ %1 %+ _u32
880
881 %ifdef RT_ARCH_AMD64
882BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 12
883 PROLOGUE_3_ARGS
884 IEM_MAYBE_LOAD_FLAGS A2, %2, %3
885 %ifdef ASM_CALL64_GCC
886 mov cl, A1_8
887 %1 qword [A0], cl
888 %else
889 xchg A1, A0
890 %1 qword [A1], cl
891 %endif
892 IEM_SAVE_FLAGS A2, %2, %3
893 EPILOGUE_3_ARGS
894 ret
895ENDPROC iemAImpl_ %+ %1 %+ _u64
896 %else ; stub it for now - later, replace with hand coded stuff.
897BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 12
898 int3
899 ret
900ENDPROC iemAImpl_ %+ %1 %+ _u64
901 %endif ; !RT_ARCH_AMD64
902
903%endmacro
904
905IEMIMPL_SHIFT_OP rol, (X86_EFL_OF | X86_EFL_CF), 0
906IEMIMPL_SHIFT_OP ror, (X86_EFL_OF | X86_EFL_CF), 0
907IEMIMPL_SHIFT_OP rcl, (X86_EFL_OF | X86_EFL_CF), 0
908IEMIMPL_SHIFT_OP rcr, (X86_EFL_OF | X86_EFL_CF), 0
909IEMIMPL_SHIFT_OP shl, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), (X86_EFL_AF)
910IEMIMPL_SHIFT_OP shr, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), (X86_EFL_AF)
911IEMIMPL_SHIFT_OP sar, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), (X86_EFL_AF)
912
913
914;;
915; Macro for implementing a double precision shift operation.
916;
917; This will generate code for the 16, 32 and 64 bit accesses, except on
918; 32-bit system where the 64-bit accesses requires hand coding.
919;
920; The functions takes the destination operand (r/m) in A0, the source (reg) in
921; A1, the shift count in A2 and a pointer to the eflags variable/register in A3.
922;
923; @param 1 The instruction mnemonic.
924; @param 2 The modified flags.
925; @param 3 The undefined flags.
926;
927; Makes ASSUMPTIONS about A0, A1, A2 and A3 assignments.
928;
929%macro IEMIMPL_SHIFT_DBL_OP 3
930BEGINCODE
931BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16, 16
932 PROLOGUE_4_ARGS
933 IEM_MAYBE_LOAD_FLAGS A3, %2, %3
934 %ifdef ASM_CALL64_GCC
935 xchg A3, A2
936 %1 [A0], A1_16, cl
937 xchg A3, A2
938 %else
939 xchg A0, A2
940 %1 [A2], A1_16, cl
941 %endif
942 IEM_SAVE_FLAGS A3, %2, %3
943 EPILOGUE_4_ARGS
944 ret
945ENDPROC iemAImpl_ %+ %1 %+ _u16
946
947BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32, 16
948 PROLOGUE_4_ARGS
949 IEM_MAYBE_LOAD_FLAGS A3, %2, %3
950 %ifdef ASM_CALL64_GCC
951 xchg A3, A2
952 %1 [A0], A1_32, cl
953 xchg A3, A2
954 %else
955 xchg A0, A2
956 %1 [A2], A1_32, cl
957 %endif
958 IEM_SAVE_FLAGS A3, %2, %3
959 EPILOGUE_4_ARGS
960 ret
961ENDPROC iemAImpl_ %+ %1 %+ _u32
962
963 %ifdef RT_ARCH_AMD64
964BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 20
965 PROLOGUE_4_ARGS
966 IEM_MAYBE_LOAD_FLAGS A3, %2, %3
967 %ifdef ASM_CALL64_GCC
968 xchg A3, A2
969 %1 [A0], A1, cl
970 xchg A3, A2
971 %else
972 xchg A0, A2
973 %1 [A2], A1, cl
974 %endif
975 IEM_SAVE_FLAGS A3, %2, %3
976 EPILOGUE_4_ARGS
977 ret
978ENDPROC iemAImpl_ %+ %1 %+ _u64
979 %else ; stub it for now - later, replace with hand coded stuff.
980BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 20
981 int3
982 ret
983ENDPROC iemAImpl_ %+ %1 %+ _u64
984 %endif ; !RT_ARCH_AMD64
985
986%endmacro
987
988IEMIMPL_SHIFT_DBL_OP shld, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), (X86_EFL_AF)
989IEMIMPL_SHIFT_DBL_OP shrd, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), (X86_EFL_AF)
990
991
992;;
993; Macro for implementing a multiplication operations.
994;
995; This will generate code for the 8, 16, 32 and 64 bit accesses, except on
996; 32-bit system where the 64-bit accesses requires hand coding.
997;
998; The 8-bit function only operates on AX, so it takes no DX pointer. The other
999; functions takes a pointer to rAX in A0, rDX in A1, the operand in A2 and a
1000; pointer to eflags in A3.
1001;
1002; The functions all return 0 so the caller can be used for div/idiv as well as
1003; for the mul/imul implementation.
1004;
1005; @param 1 The instruction mnemonic.
1006; @param 2 The modified flags.
1007; @param 3 The undefined flags.
1008;
1009; Makes ASSUMPTIONS about A0, A1, A2, A3, T0 and T1 assignments.
1010;
1011%macro IEMIMPL_MUL_OP 3
1012BEGINCODE
1013BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u8, 12
1014 PROLOGUE_3_ARGS
1015 IEM_MAYBE_LOAD_FLAGS A2, %2, %3
1016 mov al, [A0]
1017 %1 A1_8
1018 mov [A0], ax
1019 IEM_SAVE_FLAGS A2, %2, %3
1020 EPILOGUE_3_ARGS
1021 xor eax, eax
1022 ret
1023ENDPROC iemAImpl_ %+ %1 %+ _u8
1024
1025BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16, 16
1026 PROLOGUE_4_ARGS
1027 IEM_MAYBE_LOAD_FLAGS A3, %2, %3
1028 mov ax, [A0]
1029 %ifdef ASM_CALL64_GCC
1030 %1 A2_16
1031 mov [A0], ax
1032 mov [A1], dx
1033 %else
1034 mov T1, A1
1035 %1 A2_16
1036 mov [A0], ax
1037 mov [T1], dx
1038 %endif
1039 IEM_SAVE_FLAGS A3, %2, %3
1040 EPILOGUE_4_ARGS
1041 xor eax, eax
1042 ret
1043ENDPROC iemAImpl_ %+ %1 %+ _u16
1044
1045BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32, 16
1046 PROLOGUE_4_ARGS
1047 IEM_MAYBE_LOAD_FLAGS A3, %2, %3
1048 mov eax, [A0]
1049 %ifdef ASM_CALL64_GCC
1050 %1 A2_32
1051 mov [A0], eax
1052 mov [A1], edx
1053 %else
1054 mov T1, A1
1055 %1 A2_32
1056 mov [A0], eax
1057 mov [T1], edx
1058 %endif
1059 IEM_SAVE_FLAGS A3, %2, %3
1060 EPILOGUE_4_ARGS
1061 xor eax, eax
1062 ret
1063ENDPROC iemAImpl_ %+ %1 %+ _u32
1064
1065 %ifdef RT_ARCH_AMD64
1066BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 20
1067 PROLOGUE_4_ARGS
1068 IEM_MAYBE_LOAD_FLAGS A3, %2, %3
1069 mov rax, [A0]
1070 %ifdef ASM_CALL64_GCC
1071 %1 A2
1072 mov [A0], rax
1073 mov [A1], rdx
1074 %else
1075 mov T1, A1
1076 %1 A2
1077 mov [A0], rax
1078 mov [T1], rdx
1079 %endif
1080 IEM_SAVE_FLAGS A3, %2, %3
1081 EPILOGUE_4_ARGS
1082 xor eax, eax
1083 ret
1084ENDPROC iemAImpl_ %+ %1 %+ _u64
1085 %else ; stub it for now - later, replace with hand coded stuff.
1086BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 20
1087 int3
1088 ret
1089ENDPROC iemAImpl_ %+ %1 %+ _u64
1090 %endif ; !RT_ARCH_AMD64
1091
1092%endmacro
1093
1094IEMIMPL_MUL_OP mul, (X86_EFL_OF | X86_EFL_CF), (X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
1095IEMIMPL_MUL_OP imul, (X86_EFL_OF | X86_EFL_CF), (X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
1096
1097
1098;;
1099; Macro for implementing a division operations.
1100;
1101; This will generate code for the 8, 16, 32 and 64 bit accesses, except on
1102; 32-bit system where the 64-bit accesses requires hand coding.
1103;
1104; The 8-bit function only operates on AX, so it takes no DX pointer. The other
1105; functions takes a pointer to rAX in A0, rDX in A1, the operand in A2 and a
1106; pointer to eflags in A3.
1107;
1108; The functions all return 0 on success and -1 if a divide error should be
1109; raised by the caller.
1110;
1111; @param 1 The instruction mnemonic.
1112; @param 2 The modified flags.
1113; @param 3 The undefined flags.
1114;
1115; Makes ASSUMPTIONS about A0, A1, A2, A3, T0 and T1 assignments.
1116;
1117%macro IEMIMPL_DIV_OP 3
1118BEGINCODE
1119BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u8, 12
1120 PROLOGUE_3_ARGS
1121
1122 test A1_8, A1_8
1123 jz .div_zero
1124 ;; @todo test for overflow
1125
1126 IEM_MAYBE_LOAD_FLAGS A2, %2, %3
1127 mov ax, [A0]
1128 %1 A1_8
1129 mov [A0], ax
1130 IEM_SAVE_FLAGS A2, %2, %3
1131 xor eax, eax
1132
1133.return:
1134 EPILOGUE_3_ARGS
1135 ret
1136.div_zero:
1137 mov eax, -1
1138 jmp .return
1139ENDPROC iemAImpl_ %+ %1 %+ _u8
1140
1141BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u16, 16
1142 PROLOGUE_4_ARGS
1143
1144 test A1_16, A1_16
1145 jz .div_zero
1146 ;; @todo test for overflow
1147
1148 IEM_MAYBE_LOAD_FLAGS A3, %2, %3
1149 %ifdef ASM_CALL64_GCC
1150 mov T1, A2
1151 mov ax, [A0]
1152 mov dx, [A1]
1153 %1 T1_16
1154 mov [A0], ax
1155 mov [A1], dx
1156 %else
1157 mov T1, A1
1158 mov ax, [A0]
1159 mov dx, [T1]
1160 %1 A2_16
1161 mov [A0], ax
1162 mov [T1], dx
1163 %endif
1164 IEM_SAVE_FLAGS A3, %2, %3
1165 xor eax, eax
1166
1167.return:
1168 EPILOGUE_4_ARGS
1169 ret
1170.div_zero:
1171 mov eax, -1
1172 jmp .return
1173ENDPROC iemAImpl_ %+ %1 %+ _u16
1174
1175BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u32, 16
1176 PROLOGUE_4_ARGS
1177
1178 test A1_32, A1_32
1179 jz .div_zero
1180 ;; @todo test for overflow
1181
1182 IEM_MAYBE_LOAD_FLAGS A3, %2, %3
1183 mov eax, [A0]
1184 %ifdef ASM_CALL64_GCC
1185 mov T1, A2
1186 mov eax, [A0]
1187 mov edx, [A1]
1188 %1 T1_32
1189 mov [A0], eax
1190 mov [A1], edx
1191 %else
1192 mov T1, A1
1193 mov eax, [A0]
1194 mov edx, [T1]
1195 %1 A2_32
1196 mov [A0], eax
1197 mov [T1], edx
1198 %endif
1199 IEM_SAVE_FLAGS A3, %2, %3
1200 xor eax, eax
1201
1202.return:
1203 EPILOGUE_4_ARGS
1204 ret
1205.div_zero:
1206 mov eax, -1
1207 jmp .return
1208ENDPROC iemAImpl_ %+ %1 %+ _u32
1209
1210 %ifdef RT_ARCH_AMD64
1211BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 20
1212 PROLOGUE_4_ARGS
1213
1214 test A1, A1
1215 jz .div_zero
1216 ;; @todo test for overflow
1217
1218 IEM_MAYBE_LOAD_FLAGS A3, %2, %3
1219 mov rax, [A0]
1220 %ifdef ASM_CALL64_GCC
1221 mov T1, A2
1222 mov rax, [A0]
1223 mov rdx, [A1]
1224 %1 T1
1225 mov [A0], rax
1226 mov [A1], rdx
1227 %else
1228 mov T1, A1
1229 mov rax, [A0]
1230 mov rdx, [T1]
1231 %1 A2
1232 mov [A0], rax
1233 mov [T1], rdx
1234 %endif
1235 IEM_SAVE_FLAGS A3, %2, %3
1236 xor eax, eax
1237
1238.return:
1239 EPILOGUE_4_ARGS
1240 ret
1241.div_zero:
1242 mov eax, -1
1243 jmp .return
1244ENDPROC iemAImpl_ %+ %1 %+ _u64
1245 %else ; stub it for now - later, replace with hand coded stuff.
1246BEGINPROC_FASTCALL iemAImpl_ %+ %1 %+ _u64, 20
1247 int3
1248 ret
1249ENDPROC iemAImpl_ %+ %1 %+ _u64
1250 %endif ; !RT_ARCH_AMD64
1251
1252%endmacro
1253
1254IEMIMPL_DIV_OP div, 0, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF)
1255IEMIMPL_DIV_OP idiv, 0, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF)
1256
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