VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMAll/EMAllA.asm@ 15419

Last change on this file since 15419 was 15418, checked in by vboxsync, 16 years ago

EMAll: AND, OR and XOR on darwin/R0 - the first two are for vista64.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 38.3 KB
Line 
1; $Id: EMAllA.asm 15418 2008-12-13 06:39:03Z vboxsync $
2;; @file
3; EM Assembly Routines.
4;
5
6;
7; Copyright (C) 2006-2007 Sun Microsystems, Inc.
8;
9; This file is part of VirtualBox Open Source Edition (OSE), as
10; available from http://www.virtualbox.org. This file is free software;
11; you can redistribute it and/or modify it under the terms of the GNU
12; General Public License (GPL) as published by the Free Software
13; Foundation, in version 2 as it comes in the "COPYING" file of the
14; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16;
17; Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18; Clara, CA 95054 USA or visit http://www.sun.com if you need
19; additional information or have any questions.
20;
21
22;*******************************************************************************
23;* Header Files *
24;*******************************************************************************
25%include "VBox/asmdefs.mac"
26%include "VBox/err.mac"
27%include "VBox/x86.mac"
28
29;; @def MY_PTR_REG
30; The register we use for value pointers (And,Or,Dec,Inc).
31%ifdef RT_ARCH_AMD64
32 %define MY_PTR_REG rcx
33%else
34 %define MY_PTR_REG ecx
35%endif
36
37;; @def MY_RET_REG
38; The register we return the result in.
39%ifdef RT_ARCH_AMD64
40 %define MY_RET_REG rax
41%else
42 %define MY_RET_REG eax
43%endif
44
45;; @def RT_ARCH_AMD64
46; Indicator for whether we can deal with 8 byte operatands. (Darwin fun again.)
47%ifdef RT_ARCH_AMD64
48 %define CAN_DO_8_BYTE_OP 1
49%endif
50%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
51 %define CAN_DO_8_BYTE_OP 1
52 %define MY_PTR_REG64 rcx
53%endif
54
55
56;*******************************************************************************
57;* External Symbols *
58;*******************************************************************************
59%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
60extern NAME(SUPR0Abs64bitKernelCS)
61extern NAME(SUPR0AbsKernelCS)
62%endif
63
64
65BEGINCODE
66
67
68;;
69; Emulate CMP instruction, CDECL calling conv.
70; VMMDECL(uint32_t) EMEmulateCmp(uint32_t u32Param1, uint64_t u64Param2, size_t cb);
71;
72; @returns EFLAGS after the operation, only arithmetic flags are valid.
73; @param [esp + 04h] rdi rcx Param 1 - First parameter (Dst).
74; @param [esp + 08h] rsi edx Param 2 - Second parameter (Src).
75; @param [esp + 10h] Param 3 - Size of parameters, only 1/2/4/8 (64 bits host only) is valid.
76;
77align 16
78BEGINPROC EMEmulateCmp
79%ifdef RT_ARCH_AMD64
80%ifdef RT_OS_WINDOWS
81 mov rax, r8 ; eax = size of parameters
82%else ; !RT_OS_WINDOWS
83 mov rax, rdx ; rax = size of parameters
84 mov rcx, rdi ; rcx = first parameter
85 mov rdx, rsi ; rdx = second parameter
86%endif ; !RT_OS_WINDOWS
87%else ; !RT_ARCH_AMD64
88 mov eax, [esp + 10h] ; eax = size of parameters
89 mov ecx, [esp + 04h] ; ecx = first parameter
90 mov edx, [esp + 08h] ; edx = second parameter
91%endif
92
93 ; switch on size
94%ifdef RT_ARCH_AMD64
95 cmp al, 8
96 je short .do_qword ; 8 bytes variant
97%endif
98 cmp al, 4
99 je short .do_dword ; 4 bytes variant
100 cmp al, 2
101 je short .do_word ; 2 byte variant
102 cmp al, 1
103 je short .do_byte ; 1 bytes variant
104 int3
105
106 ; workers
107%ifdef RT_ARCH_AMD64
108.do_qword:
109 cmp rcx, rdx ; do 8 bytes CMP
110 jmp short .done
111%endif
112
113.do_dword:
114 cmp ecx, edx ; do 4 bytes CMP
115 jmp short .done
116
117.do_word:
118 cmp cx, dx ; do 2 bytes CMP
119 jmp short .done
120
121.do_byte:
122 cmp cl, dl ; do 1 byte CMP
123
124 ; collect flags and return.
125.done:
126 pushf
127 pop MY_RET_REG
128 retn
129ENDPROC EMEmulateCmp
130
131
132;;
133; Emulate AND instruction, CDECL calling conv.
134; VMMDECL(uint32_t) EMEmulateAnd(void *pvParam1, uint64_t u64Param2, size_t cb);
135;
136; @returns EFLAGS after the operation, only arithmetic flags are valid.
137; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
138; @param [esp + 08h] Param 2 - Second parameter.
139; @param [esp + 10h] Param 3 - Size of parameters, only 1/2/4/8 (64 bits host only) is valid.
140; @uses eax, ecx, edx
141;
142align 16
143BEGINPROC EMEmulateAnd
144%ifdef RT_ARCH_AMD64
145%ifdef RT_OS_WINDOWS
146 mov rax, r8 ; eax = size of parameters
147%else ; !RT_OS_WINDOWS
148 mov rax, rdx ; rax = size of parameters
149 mov rcx, rdi ; rcx = first parameter
150 mov rdx, rsi ; rdx = second parameter
151%endif ; !RT_OS_WINDOWS
152%else ; !RT_ARCH_AMD64
153 mov eax, [esp + 10h] ; eax = size of parameters
154 mov ecx, [esp + 04h] ; ecx = first parameter
155 mov edx, [esp + 08h] ; edx = second parameter
156%endif
157
158 ; switch on size
159%ifdef CAN_DO_8_BYTE_OP
160 cmp al, 8
161 je short .do_qword ; 8 bytes variant
162%endif
163 cmp al, 4
164 je short .do_dword ; 4 bytes variant
165 cmp al, 2
166 je short .do_word ; 2 byte variant
167 cmp al, 1
168 je short .do_byte ; 1 bytes variant
169 int3
170
171 ; workers
172%ifdef RT_ARCH_AMD64
173.do_qword:
174 and [MY_PTR_REG], rdx ; do 8 bytes AND
175 jmp short .done
176%endif
177
178.do_dword:
179 and [MY_PTR_REG], edx ; do 4 bytes AND
180 jmp short .done
181
182.do_word:
183 and [MY_PTR_REG], dx ; do 2 bytes AND
184 jmp short .done
185
186.do_byte:
187 and [MY_PTR_REG], dl ; do 1 byte AND
188
189 ; collect flags and return.
190.done:
191 pushf
192 pop MY_RET_REG
193 retn
194
195%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
196.do_qword:
197 db 0xea ; jmp far .sixtyfourbit_mode
198 dd .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
199BITS 64
200.sixtyfourbit_mode:
201 and esp, 0ffffffffh
202 and MY_PTR_REG, 0ffffffffh
203 mov rdx, qword [rsp + 08h] ; rdx = second parameter
204 and [MY_PTR_REG64], rdx ; do 8 bytes AND
205 jmp far [.fpret wrt rip]
206.fpret: ; 16:32 Pointer to .done.
207 dd .done, NAME(SUPR0AbsKernelCS)
208BITS 32
209%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
210ENDPROC EMEmulateAnd
211
212
213;;
214; Emulate OR instruction, CDECL calling conv.
215; VMMDECL(uint32_t) EMEmulateOr(void *pvParam1, uint64_t u64Param2, size_t cb);
216;
217; @returns EFLAGS after the operation, only arithmetic flags are valid.
218; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
219; @param [esp + 08h] Param 2 - Second parameter.
220; @param [esp + 10h] Param 3 - Size of parameters, only 1/2/4/8 (64 bits host only) is valid.
221; @uses eax, ecx, edx
222;
223align 16
224BEGINPROC EMEmulateOr
225%ifdef RT_ARCH_AMD64
226%ifdef RT_OS_WINDOWS
227 mov rax, r8 ; eax = size of parameters
228%else ; !RT_OS_WINDOWS
229 mov rax, rdx ; rax = size of parameters
230 mov rcx, rdi ; rcx = first parameter
231 mov rdx, rsi ; rdx = second parameter
232%endif ; !RT_OS_WINDOWS
233%else ; !RT_ARCH_AMD64
234 mov eax, [esp + 10h] ; eax = size of parameters
235 mov ecx, [esp + 04h] ; ecx = first parameter
236 mov edx, [esp + 08h] ; edx = second parameter
237%endif
238
239 ; switch on size
240%ifdef CAN_DO_8_BYTE_OP
241 cmp al, 8
242 je short .do_qword ; 8 bytes variant
243%endif
244 cmp al, 4
245 je short .do_dword ; 4 bytes variant
246 cmp al, 2
247 je short .do_word ; 2 byte variant
248 cmp al, 1
249 je short .do_byte ; 1 bytes variant
250 int3
251
252 ; workers
253%ifdef RT_ARCH_AMD64
254.do_qword:
255 or [MY_PTR_REG], rdx ; do 8 bytes OR
256 jmp short .done
257%endif
258
259.do_dword:
260 or [MY_PTR_REG], edx ; do 4 bytes OR
261 jmp short .done
262
263.do_word:
264 or [MY_PTR_REG], dx ; do 2 bytes OR
265 jmp short .done
266
267.do_byte:
268 or [MY_PTR_REG], dl ; do 1 byte OR
269
270 ; collect flags and return.
271.done:
272 pushf
273 pop MY_RET_REG
274 retn
275
276%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
277.do_qword:
278 db 0xea ; jmp far .sixtyfourbit_mode
279 dd .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
280BITS 64
281.sixtyfourbit_mode:
282 and esp, 0ffffffffh
283 and MY_PTR_REG, 0ffffffffh
284 mov rdx, qword [rsp + 08h] ; rdx = second parameter
285 or [MY_PTR_REG64], rdx ; do 8 bytes OR
286 jmp far [.fpret wrt rip]
287.fpret: ; 16:32 Pointer to .done.
288 dd .done, NAME(SUPR0AbsKernelCS)
289BITS 32
290%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
291ENDPROC EMEmulateOr
292
293
294;;
295; Emulate LOCK OR instruction.
296; VMMDECL(int) EMEmulateLockOr(void *pvParam1, uint64_t u64Param2, size_t cbSize, RTGCUINTREG32 *pf);
297;
298; @returns VINF_SUCCESS on success, VERR_ACCESS_DENIED on \#PF (GC only).
299; @param [esp + 04h] gcc:rdi msc:rcx Param 1 - First parameter - pointer to data item (the real stuff).
300; @param [esp + 08h] gcc:rsi msc:rdx Param 2 - Second parameter- the immediate / register value.
301; @param [esp + 10h] gcc:rdx msc:r8 Param 3 - Size of the operation - 1, 2, 4 or 8 bytes.
302; @param [esp + 14h] gcc:rcx msc:r9 Param 4 - Where to store the eflags on success.
303; only arithmetic flags are valid.
304align 16
305BEGINPROC EMEmulateLockOr
306%ifdef RT_ARCH_AMD64
307%ifdef RT_OS_WINDOWS
308 mov rax, r8 ; eax = size of parameters
309%else ; !RT_OS_WINDOWS
310 mov rax, rdx ; rax = size of parameters
311 mov rcx, rdi ; rcx = first parameter
312 mov rdx, rsi ; rdx = second parameter
313%endif ; !RT_OS_WINDOWS
314%else ; !RT_ARCH_AMD64
315 mov eax, [esp + 10h] ; eax = size of parameters
316 mov ecx, [esp + 04h] ; ecx = first parameter (MY_PTR_REG)
317 mov edx, [esp + 08h] ; edx = second parameter
318%endif
319
320 ; switch on size
321%ifdef CAN_DO_8_BYTE_OP
322 cmp al, 8
323 je short .do_qword ; 8 bytes variant
324%endif
325 cmp al, 4
326 je short .do_dword ; 4 bytes variant
327 cmp al, 2
328 je short .do_word ; 2 byte variant
329 cmp al, 1
330 je short .do_byte ; 1 bytes variant
331 int3
332
333 ; workers
334%ifdef RT_ARCH_AMD64
335.do_qword:
336 lock or [MY_PTR_REG], rdx ; do 8 bytes OR
337 jmp short .done
338%endif
339
340.do_dword:
341 lock or [MY_PTR_REG], edx ; do 4 bytes OR
342 jmp short .done
343
344.do_word:
345 lock or [MY_PTR_REG], dx ; do 2 bytes OR
346 jmp short .done
347
348.do_byte:
349 lock or [MY_PTR_REG], dl ; do 1 byte OR
350
351 ; collect flags and return.
352.done:
353 pushf
354%ifdef RT_ARCH_AMD64
355 pop rax
356 %ifdef RT_OS_WINDOWS
357 mov [r9], eax
358 %else ; !RT_OS_WINDOWS
359 mov [rcx], eax
360 %endif ; !RT_OS_WINDOWS
361%else ; !RT_ARCH_AMD64
362 mov eax, [esp + 14h + 4]
363 pop dword [eax]
364%endif
365 mov eax, VINF_SUCCESS
366 retn
367
368%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
369.do_qword:
370 db 0xea ; jmp far .sixtyfourbit_mode
371 dd .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
372BITS 64
373.sixtyfourbit_mode:
374 and esp, 0ffffffffh
375 and MY_PTR_REG, 0ffffffffh
376 mov rdx, qword [rsp + 08h] ; rdx = second parameter
377 lock or [MY_PTR_REG64], rdx ; do 8 bytes OR
378 jmp far [.fpret wrt rip]
379.fpret: ; 16:32 Pointer to .done.
380 dd .done, NAME(SUPR0AbsKernelCS)
381BITS 32
382%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
383
384
385%ifdef IN_RC
386; #PF resume point.
387GLOBALNAME EMEmulateLockOr_Error
388 mov eax, VERR_ACCESS_DENIED
389 ret
390%endif
391
392ENDPROC EMEmulateLockOr
393
394
395;;
396; Emulate XOR instruction, CDECL calling conv.
397; VMMDECL(uint32_t) EMEmulateXor(void *pvParam1, uint64_t u64Param2, size_t cb);
398;
399; @returns EFLAGS after the operation, only arithmetic flags are valid.
400; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
401; @param [esp + 08h] Param 2 - Second parameter.
402; @param [esp + 10h] Param 3 - Size of parameters, only 1/2/4/8 (64 bits host only) is valid.
403; @uses eax, ecx, edx
404;
405align 16
406BEGINPROC EMEmulateXor
407%ifdef RT_ARCH_AMD64
408%ifdef RT_OS_WINDOWS
409 mov rax, r8 ; eax = size of parameters
410%else ; !RT_OS_WINDOWS
411 mov rax, rdx ; rax = size of parameters
412 mov rcx, rdi ; rcx = first parameter
413 mov rdx, rsi ; rdx = second parameter
414%endif ; !RT_OS_WINDOWS
415%else ; !RT_ARCH_AMD64
416 mov eax, [esp + 10h] ; eax = size of parameters
417 mov ecx, [esp + 04h] ; ecx = first parameter
418 mov edx, [esp + 08h] ; edx = second parameter
419%endif
420
421 ; switch on size
422%ifdef CAN_DO_8_BYTE_OP
423 cmp al, 8
424 je short .do_qword ; 8 bytes variant
425%endif
426 cmp al, 4
427 je short .do_dword ; 4 bytes variant
428 cmp al, 2
429 je short .do_word ; 2 byte variant
430 cmp al, 1
431 je short .do_byte ; 1 bytes variant
432 int3
433
434 ; workers
435%ifdef RT_ARCH_AMD64
436.do_qword:
437 xor [MY_PTR_REG], rdx ; do 8 bytes XOR
438 jmp short .done
439%endif
440
441.do_dword:
442 xor [MY_PTR_REG], edx ; do 4 bytes XOR
443 jmp short .done
444
445.do_word:
446 xor [MY_PTR_REG], dx ; do 2 bytes XOR
447 jmp short .done
448
449.do_byte:
450 xor [MY_PTR_REG], dl ; do 1 byte XOR
451
452 ; collect flags and return.
453.done:
454 pushf
455 pop MY_RET_REG
456 retn
457
458%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
459.do_qword:
460 db 0xea ; jmp far .sixtyfourbit_mode
461 dd .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
462BITS 64
463.sixtyfourbit_mode:
464 and esp, 0ffffffffh
465 and MY_PTR_REG, 0ffffffffh
466 mov rdx, qword [rsp + 08h] ; rdx = second parameter
467 xor [MY_PTR_REG64], rdx ; do 8 bytes XOR
468 jmp far [.fpret wrt rip]
469.fpret: ; 16:32 Pointer to .done.
470 dd .done, NAME(SUPR0AbsKernelCS)
471BITS 32
472%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
473ENDPROC EMEmulateXor
474
475
476;;
477; Emulate INC instruction, CDECL calling conv.
478; VMMDECL(uint32_t) EMEmulateInc(void *pvParam1, size_t cb);
479;
480; @returns EFLAGS after the operation, only arithmetic flags are valid.
481; @param [esp + 04h] rdi rcx Param 1 - First parameter - pointer to data item.
482; @param [esp + 08h] rsi rdx Param 2 - Size of parameters, only 1/2/4 is valid.
483; @uses eax, ecx, edx
484;
485align 16
486BEGINPROC EMEmulateInc
487%ifdef RT_ARCH_AMD64
488%ifdef RT_OS_WINDOWS
489 mov rax, rdx ; eax = size of parameters
490%else ; !RT_OS_WINDOWS
491 mov rax, rsi ; eax = size of parameters
492 mov rcx, rdi ; rcx = first parameter
493%endif ; !RT_OS_WINDOWS
494%else ; !RT_ARCH_AMD64
495 mov eax, [esp + 08h] ; eax = size of parameters
496 mov ecx, [esp + 04h] ; ecx = first parameter
497%endif
498
499 ; switch on size
500%ifdef RT_ARCH_AMD64
501 cmp al, 8
502 je short .do_qword ; 8 bytes variant
503%endif
504 cmp al, 4
505 je short .do_dword ; 4 bytes variant
506 cmp al, 2
507 je short .do_word ; 2 byte variant
508 cmp al, 1
509 je short .do_byte ; 1 bytes variant
510 int3
511
512 ; workers
513%ifdef RT_ARCH_AMD64
514.do_qword:
515 inc qword [MY_PTR_REG] ; do 8 bytes INC
516 jmp short .done
517%endif
518
519.do_dword:
520 inc dword [MY_PTR_REG] ; do 4 bytes INC
521 jmp short .done
522
523.do_word:
524 inc word [MY_PTR_REG] ; do 2 bytes INC
525 jmp short .done
526
527.do_byte:
528 inc byte [MY_PTR_REG] ; do 1 byte INC
529 jmp short .done
530
531 ; collect flags and return.
532.done:
533 pushf
534 pop MY_RET_REG
535 retn
536ENDPROC EMEmulateInc
537
538
539;;
540; Emulate DEC instruction, CDECL calling conv.
541; VMMDECL(uint32_t) EMEmulateDec(void *pvParam1, size_t cb);
542;
543; @returns EFLAGS after the operation, only arithmetic flags are valid.
544; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
545; @param [esp + 08h] Param 2 - Size of parameters, only 1/2/4 is valid.
546; @uses eax, ecx, edx
547;
548align 16
549BEGINPROC EMEmulateDec
550%ifdef RT_ARCH_AMD64
551%ifdef RT_OS_WINDOWS
552 mov rax, rdx ; eax = size of parameters
553%else ; !RT_OS_WINDOWS
554 mov rax, rsi ; eax = size of parameters
555 mov rcx, rdi ; rcx = first parameter
556%endif ; !RT_OS_WINDOWS
557%else ; !RT_ARCH_AMD64
558 mov eax, [esp + 08h] ; eax = size of parameters
559 mov ecx, [esp + 04h] ; ecx = first parameter
560%endif
561
562 ; switch on size
563%ifdef RT_ARCH_AMD64
564 cmp al, 8
565 je short .do_qword ; 8 bytes variant
566%endif
567 cmp al, 4
568 je short .do_dword ; 4 bytes variant
569 cmp al, 2
570 je short .do_word ; 2 byte variant
571 cmp al, 1
572 je short .do_byte ; 1 bytes variant
573 int3
574
575 ; workers
576%ifdef RT_ARCH_AMD64
577.do_qword:
578 dec qword [MY_PTR_REG] ; do 8 bytes DEC
579 jmp short .done
580%endif
581
582.do_dword:
583 dec dword [MY_PTR_REG] ; do 4 bytes DEC
584 jmp short .done
585
586.do_word:
587 dec word [MY_PTR_REG] ; do 2 bytes DEC
588 jmp short .done
589
590.do_byte:
591 dec byte [MY_PTR_REG] ; do 1 byte DEC
592 jmp short .done
593
594 ; collect flags and return.
595.done:
596 pushf
597 pop MY_RET_REG
598 retn
599ENDPROC EMEmulateDec
600
601
602;;
603; Emulate ADD instruction, CDECL calling conv.
604; VMMDECL(uint32_t) EMEmulateAdd(void *pvParam1, uint64_t u64Param2, size_t cb);
605;
606; @returns EFLAGS after the operation, only arithmetic flags are valid.
607; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
608; @param [esp + 08h] Param 2 - Second parameter.
609; @param [esp + 10h] Param 3 - Size of parameters, only 1/2/4/8 (64 bits host only) is valid.
610; @uses eax, ecx, edx
611;
612align 16
613BEGINPROC EMEmulateAdd
614%ifdef RT_ARCH_AMD64
615%ifdef RT_OS_WINDOWS
616 mov rax, r8 ; eax = size of parameters
617%else ; !RT_OS_WINDOWS
618 mov rax, rdx ; rax = size of parameters
619 mov rcx, rdi ; rcx = first parameter
620 mov rdx, rsi ; rdx = second parameter
621%endif ; !RT_OS_WINDOWS
622%else ; !RT_ARCH_AMD64
623 mov eax, [esp + 10h] ; eax = size of parameters
624 mov ecx, [esp + 04h] ; ecx = first parameter
625 mov edx, [esp + 08h] ; edx = second parameter
626%endif
627
628 ; switch on size
629%ifdef RT_ARCH_AMD64
630 cmp al, 8
631 je short .do_qword ; 8 bytes variant
632%endif
633 cmp al, 4
634 je short .do_dword ; 4 bytes variant
635 cmp al, 2
636 je short .do_word ; 2 byte variant
637 cmp al, 1
638 je short .do_byte ; 1 bytes variant
639 int3
640
641 ; workers
642%ifdef RT_ARCH_AMD64
643.do_qword:
644 add [MY_PTR_REG], rdx ; do 8 bytes ADD
645 jmp short .done
646%endif
647
648.do_dword:
649 add [MY_PTR_REG], edx ; do 4 bytes ADD
650 jmp short .done
651
652.do_word:
653 add [MY_PTR_REG], dx ; do 2 bytes ADD
654 jmp short .done
655
656.do_byte:
657 add [MY_PTR_REG], dl ; do 1 byte ADD
658
659 ; collect flags and return.
660.done:
661 pushf
662 pop MY_RET_REG
663 retn
664ENDPROC EMEmulateAdd
665
666
667;;
668; Emulate ADC instruction, CDECL calling conv.
669; VMMDECL(uint32_t) EMEmulateAdcWithCarrySet(void *pvParam1, uint64_t u64Param2, size_t cb);
670;
671; @returns EFLAGS after the operation, only arithmetic flags are valid.
672; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
673; @param [esp + 08h] Param 2 - Second parameter.
674; @param [esp + 10h] Param 3 - Size of parameters, only 1/2/4/8 (64 bits host only) is valid.
675; @uses eax, ecx, edx
676;
677align 16
678BEGINPROC EMEmulateAdcWithCarrySet
679%ifdef RT_ARCH_AMD64
680%ifdef RT_OS_WINDOWS
681 mov rax, r8 ; eax = size of parameters
682%else ; !RT_OS_WINDOWS
683 mov rax, rdx ; rax = size of parameters
684 mov rcx, rdi ; rcx = first parameter
685 mov rdx, rsi ; rdx = second parameter
686%endif ; !RT_OS_WINDOWS
687%else ; !RT_ARCH_AMD64
688 mov eax, [esp + 10h] ; eax = size of parameters
689 mov ecx, [esp + 04h] ; ecx = first parameter
690 mov edx, [esp + 08h] ; edx = second parameter
691%endif
692
693 ; switch on size
694%ifdef RT_ARCH_AMD64
695 cmp al, 8
696 je short .do_qword ; 8 bytes variant
697%endif
698 cmp al, 4
699 je short .do_dword ; 4 bytes variant
700 cmp al, 2
701 je short .do_word ; 2 byte variant
702 cmp al, 1
703 je short .do_byte ; 1 bytes variant
704 int3
705
706 ; workers
707%ifdef RT_ARCH_AMD64
708.do_qword:
709 stc ; set carry flag
710 adc [MY_PTR_REG], rdx ; do 8 bytes ADC
711 jmp short .done
712%endif
713
714.do_dword:
715 stc ; set carry flag
716 adc [MY_PTR_REG], edx ; do 4 bytes ADC
717 jmp short .done
718
719.do_word:
720 stc ; set carry flag
721 adc [MY_PTR_REG], dx ; do 2 bytes ADC
722 jmp short .done
723
724.do_byte:
725 stc ; set carry flag
726 adc [MY_PTR_REG], dl ; do 1 byte ADC
727
728 ; collect flags and return.
729.done:
730 pushf
731 pop MY_RET_REG
732 retn
733ENDPROC EMEmulateAdcWithCarrySet
734
735
736;;
737; Emulate SUB instruction, CDECL calling conv.
738; VMMDECL(uint32_t) EMEmulateSub(void *pvParam1, uint64_t u64Param2, size_t cb);
739;
740; @returns EFLAGS after the operation, only arithmetic flags are valid.
741; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
742; @param [esp + 08h] Param 2 - Second parameter.
743; @param [esp + 10h] Param 3 - Size of parameters, only 1/2/4/8 (64 bits host only) is valid.
744; @uses eax, ecx, edx
745;
746align 16
747BEGINPROC EMEmulateSub
748%ifdef RT_ARCH_AMD64
749%ifdef RT_OS_WINDOWS
750 mov rax, r8 ; eax = size of parameters
751%else ; !RT_OS_WINDOWS
752 mov rax, rdx ; rax = size of parameters
753 mov rcx, rdi ; rcx = first parameter
754 mov rdx, rsi ; rdx = second parameter
755%endif ; !RT_OS_WINDOWS
756%else ; !RT_ARCH_AMD64
757 mov eax, [esp + 10h] ; eax = size of parameters
758 mov ecx, [esp + 04h] ; ecx = first parameter
759 mov edx, [esp + 08h] ; edx = second parameter
760%endif
761
762 ; switch on size
763%ifdef RT_ARCH_AMD64
764 cmp al, 8
765 je short .do_qword ; 8 bytes variant
766%endif
767 cmp al, 4
768 je short .do_dword ; 4 bytes variant
769 cmp al, 2
770 je short .do_word ; 2 byte variant
771 cmp al, 1
772 je short .do_byte ; 1 bytes variant
773 int3
774
775 ; workers
776%ifdef RT_ARCH_AMD64
777.do_qword:
778 sub [MY_PTR_REG], rdx ; do 8 bytes SUB
779 jmp short .done
780%endif
781
782.do_dword:
783 sub [MY_PTR_REG], edx ; do 4 bytes SUB
784 jmp short .done
785
786.do_word:
787 sub [MY_PTR_REG], dx ; do 2 bytes SUB
788 jmp short .done
789
790.do_byte:
791 sub [MY_PTR_REG], dl ; do 1 byte SUB
792
793 ; collect flags and return.
794.done:
795 pushf
796 pop MY_RET_REG
797 retn
798ENDPROC EMEmulateSub
799
800
801;;
802; Emulate BTR instruction, CDECL calling conv.
803; VMMDECL(uint32_t) EMEmulateBtr(void *pvParam1, uint64_t u64Param2);
804;
805; @returns EFLAGS after the operation, only arithmetic flags are valid.
806; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
807; @param [esp + 08h] Param 2 - Second parameter.
808; @uses eax, ecx, edx
809;
810align 16
811BEGINPROC EMEmulateBtr
812%ifdef RT_ARCH_AMD64
813%ifndef RT_OS_WINDOWS
814 mov rcx, rdi ; rcx = first parameter
815 mov rdx, rsi ; rdx = second parameter
816%endif ; !RT_OS_WINDOWS
817%else ; !RT_ARCH_AMD64
818 mov ecx, [esp + 04h] ; ecx = first parameter
819 mov edx, [esp + 08h] ; edx = second parameter
820%endif
821
822 and edx, 7
823 btr [MY_PTR_REG], edx
824
825 ; collect flags and return.
826 pushf
827 pop MY_RET_REG
828 retn
829ENDPROC EMEmulateBtr
830
831;;
832; Emulate LOCK BTR instruction.
833; VMMDECL(int) EMEmulateLockBtr(void *pvParam1, uint64_t u64Param2, RTGCUINTREG32 *pf);
834;
835; @returns VINF_SUCCESS on success, VERR_ACCESS_DENIED on \#PF (GC only).
836; @param [esp + 04h] gcc:rdi msc:rcx Param 1 - First parameter - pointer to data item (the real stuff).
837; @param [esp + 08h] gcc:rsi msc:rdx Param 2 - Second parameter- the immediate / register value. (really an 8 byte value)
838; @param [esp + 10h] gcc:rdx msc:r8 Param 3 - Where to store the eflags on success.
839;
840align 16
841BEGINPROC EMEmulateLockBtr
842%ifdef RT_ARCH_AMD64
843 %ifdef RT_OS_WINDOWS
844 mov rax, r8 ; rax = third parameter
845 %else ; !RT_OS_WINDOWS
846 mov rcx, rdi ; rcx = first parameter
847 mov rax, rdx ; rax = third parameter
848 mov rdx, rsi ; rdx = second parameter
849 %endif ; !RT_OS_WINDOWS
850%else ; !RT_ARCH_AMD64
851 mov ecx, [esp + 04h] ; ecx = first parameter
852 mov edx, [esp + 08h] ; edx = second parameter
853 mov eax, [esp + 10h] ; eax = third parameter
854%endif
855
856 lock btr [MY_PTR_REG], edx
857
858 ; collect flags and return.
859 pushf
860 pop xDX
861 mov [xAX], edx
862 mov eax, VINF_SUCCESS
863 retn
864
865%ifdef IN_RC
866; #PF resume point.
867GLOBALNAME EMEmulateLockBtr_Error
868 mov eax, VERR_ACCESS_DENIED
869 ret
870%endif
871
872ENDPROC EMEmulateLockBtr
873
874
875;;
876; Emulate BTC instruction, CDECL calling conv.
877; VMMDECL(uint32_t) EMEmulateBtc(void *pvParam1, uint64_t u64Param2);
878;
879; @returns EFLAGS after the operation, only arithmetic flags are valid.
880; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
881; @param [esp + 08h] Param 2 - Second parameter.
882; @uses eax, ecx, edx
883;
884align 16
885BEGINPROC EMEmulateBtc
886%ifdef RT_ARCH_AMD64
887%ifndef RT_OS_WINDOWS
888 mov rcx, rdi ; rcx = first parameter
889 mov rdx, rsi ; rdx = second parameter
890%endif ; !RT_OS_WINDOWS
891%else ; !RT_ARCH_AMD64
892 mov ecx, [esp + 04h] ; ecx = first parameter
893 mov edx, [esp + 08h] ; edx = second parameter
894%endif
895
896 and edx, 7
897 btc [MY_PTR_REG], edx
898
899 ; collect flags and return.
900 pushf
901 pop MY_RET_REG
902 retn
903ENDPROC EMEmulateBtc
904
905
906;;
907; Emulate BTS instruction, CDECL calling conv.
908; VMMDECL(uint32_t) EMEmulateBts(void *pvParam1, uint64_t u64Param2);
909;
910; @returns EFLAGS after the operation, only arithmetic flags are valid.
911; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
912; @param [esp + 08h] Param 2 - Second parameter.
913; @uses eax, ecx, edx
914;
915align 16
916BEGINPROC EMEmulateBts
917%ifdef RT_ARCH_AMD64
918%ifndef RT_OS_WINDOWS
919 mov rcx, rdi ; rcx = first parameter
920 mov rdx, rsi ; rdx = second parameter
921%endif ; !RT_OS_WINDOWS
922%else ; !RT_ARCH_AMD64
923 mov ecx, [esp + 04h] ; ecx = first parameter
924 mov edx, [esp + 08h] ; edx = second parameter
925%endif
926
927 and edx, 7
928 bts [MY_PTR_REG], edx
929
930 ; collect flags and return.
931 pushf
932 pop MY_RET_REG
933 retn
934ENDPROC EMEmulateBts
935
936
937;;
938; Emulate LOCK CMPXCHG instruction, CDECL calling conv.
939; VMMDECL(uint32_t) EMEmulateLockCmpXchg(void *pvParam1, uint64_t *pu64Param2, uint64_t u64Param3, size_t cbSize);
940;
941; @returns EFLAGS after the operation, only arithmetic flags are valid.
942; @param [esp + 04h] gcc:rdi msc:rcx Param 1 - First parameter - pointer to first parameter
943; @param [esp + 08h] gcc:rsi msc:rdx Param 2 - pointer to second parameter (eax)
944; @param [esp + 0ch] gcc:rdx msc:r8 Param 3 - third parameter
945; @param [esp + 14h] gcc:rcx msc:r9 Param 4 - Size of parameters, only 1/2/4/8 is valid
946; @uses eax, ecx, edx
947;
948align 16
949BEGINPROC EMEmulateLockCmpXchg
950 push xBX
951%ifdef RT_ARCH_AMD64
952%ifdef RT_OS_WINDOWS
953 ; rcx contains the first parameter already
954 mov rbx, rdx ; rdx = 2nd parameter
955 mov rdx, r8 ; r8 = 3rd parameter
956 mov rax, r9 ; r9 = size of parameters
957%else
958 mov rax, rcx ; rcx = size of parameters (4th)
959 mov rcx, rdi ; rdi = 1st parameter
960 mov rbx, rsi ; rsi = second parameter
961 ;rdx contains the 3rd parameter already
962%endif ; !RT_OS_WINDOWS
963%else ; !RT_ARCH_AMD64
964 mov ecx, [esp + 04h + 4] ; ecx = first parameter
965 mov ebx, [esp + 08h + 4] ; ebx = 2nd parameter (eax)
966 mov edx, [esp + 0ch + 4] ; edx = third parameter
967 mov eax, [esp + 14h + 4] ; eax = size of parameters
968%endif
969
970%ifdef CAN_DO_8_BYTE_OP
971 cmp al, 8
972 je short .do_qword ; 8 bytes variant
973%endif
974 cmp al, 4
975 je short .do_dword ; 4 bytes variant
976 cmp al, 2
977 je short .do_word ; 2 byte variant
978 cmp al, 1
979 je short .do_byte ; 1 bytes variant
980 int3
981
982%ifdef RT_ARCH_AMD64
983.do_qword:
984 ; load 2nd parameter's value
985 mov rax, qword [rbx]
986
987 lock cmpxchg qword [rcx], rdx ; do 8 bytes CMPXCHG
988 mov qword [rbx], rax
989 jmp short .done
990%endif
991
992.do_dword:
993 ; load 2nd parameter's value
994 mov eax, dword [xBX]
995
996 lock cmpxchg dword [xCX], edx ; do 4 bytes CMPXCHG
997 mov dword [xBX], eax
998 jmp short .done
999
1000.do_word:
1001 ; load 2nd parameter's value
1002 mov eax, dword [xBX]
1003
1004 lock cmpxchg word [xCX], dx ; do 2 bytes CMPXCHG
1005 mov word [xBX], ax
1006 jmp short .done
1007
1008.do_byte:
1009 ; load 2nd parameter's value
1010 mov eax, dword [xBX]
1011
1012 lock cmpxchg byte [xCX], dl ; do 1 byte CMPXCHG
1013 mov byte [xBX], al
1014
1015.done:
1016 ; collect flags and return.
1017 pushf
1018 pop MY_RET_REG
1019
1020 pop xBX
1021 retn
1022
1023%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
1024.do_qword:
1025 db 0xea ; jmp far .sixtyfourbit_mode
1026 dd .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
1027BITS 64
1028.sixtyfourbit_mode:
1029 and ebx, 0ffffffffh
1030 and esp, 0ffffffffh
1031 and ecx, 0ffffffffh
1032 mov rax, qword [rbx] ; load 2nd parameter's value
1033 mov rdx, qword [rsp + 0ch + 4] ; rdx = third parameter
1034
1035 lock cmpxchg qword [rcx], rdx ; do 8 byte CMPXCHG
1036 mov qword [rbx], rax
1037 jmp far [.fpret wrt rip]
1038.fpret: ; 16:32 Pointer to .done.
1039 dd .done, NAME(SUPR0AbsKernelCS)
1040BITS 32
1041%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
1042ENDPROC EMEmulateLockCmpXchg
1043
1044
1045;;
1046; Emulate CMPXCHG instruction, CDECL calling conv.
1047; VMMDECL(uint32_t) EMEmulateCmpXchg(void *pvParam1, uint64_t *pu32Param2, uint64_t u32Param3, size_t cbSize);
1048;
1049; @returns EFLAGS after the operation, only arithmetic flags are valid.
1050; @param [esp + 04h] gcc:rdi msc:rcx Param 1 - First parameter - pointer to first parameter
1051; @param [esp + 08h] gcc:rsi msc:rdx Param 2 - pointer to second parameter (eax)
1052; @param [esp + 0ch] gcc:rdx msc:r8 Param 3 - third parameter
1053; @param [esp + 14h] gcc:rcx msc:r9 Param 4 - Size of parameters, only 1/2/4 is valid.
1054; @uses eax, ecx, edx
1055;
1056align 16
1057BEGINPROC EMEmulateCmpXchg
1058 push xBX
1059%ifdef RT_ARCH_AMD64
1060%ifdef RT_OS_WINDOWS
1061 ; rcx contains the first parameter already
1062 mov rbx, rdx ; rdx = 2nd parameter
1063 mov rdx, r8 ; r8 = 3rd parameter
1064 mov rax, r9 ; r9 = size of parameters
1065%else
1066 mov rax, rcx ; rcx = size of parameters (4th)
1067 mov rcx, rdi ; rdi = 1st parameter
1068 mov rbx, rsi ; rsi = second parameter
1069 ;rdx contains the 3rd parameter already
1070%endif ; !RT_OS_WINDOWS
1071%else ; !RT_ARCH_AMD64
1072 mov ecx, [esp + 04h + 4] ; ecx = first parameter
1073 mov ebx, [esp + 08h + 4] ; ebx = 2nd parameter (eax)
1074 mov edx, [esp + 0ch + 4] ; edx = third parameter
1075 mov eax, [esp + 14h + 4] ; eax = size of parameters
1076%endif
1077
1078%ifdef CAN_DO_8_BYTE_OP
1079 cmp al, 8
1080 je short .do_qword ; 8 bytes variant
1081%endif
1082 cmp al, 4
1083 je short .do_dword ; 4 bytes variant
1084 cmp al, 2
1085 je short .do_word ; 2 byte variant
1086 cmp al, 1
1087 je short .do_byte ; 1 bytes variant
1088 int3
1089
1090%ifdef RT_ARCH_AMD64
1091.do_qword:
1092 ; load 2nd parameter's value
1093 mov rax, qword [rbx]
1094
1095 cmpxchg qword [rcx], rdx ; do 8 bytes CMPXCHG
1096 mov qword [rbx], rax
1097 jmp short .done
1098%endif
1099
1100.do_dword:
1101 ; load 2nd parameter's value
1102 mov eax, dword [xBX]
1103
1104 cmpxchg dword [xCX], edx ; do 4 bytes CMPXCHG
1105 mov dword [xBX], eax
1106 jmp short .done
1107
1108.do_word:
1109 ; load 2nd parameter's value
1110 mov eax, dword [xBX]
1111
1112 cmpxchg word [xCX], dx ; do 2 bytes CMPXCHG
1113 mov word [xBX], ax
1114 jmp short .done
1115
1116.do_byte:
1117 ; load 2nd parameter's value
1118 mov eax, dword [xBX]
1119
1120 cmpxchg byte [xCX], dl ; do 1 byte CMPXCHG
1121 mov byte [xBX], al
1122
1123.done:
1124 ; collect flags and return.
1125 pushf
1126 pop MY_RET_REG
1127
1128 pop xBX
1129 retn
1130
1131%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
1132.do_qword:
1133 db 0xea ; jmp far .sixtyfourbit_mode
1134 dd .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
1135BITS 64
1136.sixtyfourbit_mode:
1137 and ebx, 0ffffffffh
1138 and esp, 0ffffffffh
1139 and ecx, 0ffffffffh
1140 mov rax, qword [rbx] ; load 2nd parameter's value
1141 mov rdx, qword [rsp + 0ch + 4] ; rdx = third parameter
1142
1143 cmpxchg qword [rcx], rdx ; do 8 byte CMPXCHG
1144 mov qword [rbx], rax
1145 jmp far [.fpret wrt rip]
1146.fpret: ; 16:32 Pointer to .done.
1147 dd .done, NAME(SUPR0AbsKernelCS)
1148BITS 32
1149%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
1150ENDPROC EMEmulateCmpXchg
1151
1152
1153;;
1154; Emulate LOCK CMPXCHG8B instruction, CDECL calling conv.
1155; VMMDECL(uint32_t) EMEmulateLockCmpXchg8b(void *pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX);
1156;
1157; @returns EFLAGS after the operation, only the ZF flag is valid.
1158; @param [esp + 04h] gcc:rdi msc:rcx Param 1 - First parameter - pointer to first parameter
1159; @param [esp + 08h] gcc:rsi msc:rdx Param 2 - Address of the eax register
1160; @param [esp + 0ch] gcc:rdx msc:r8 Param 3 - Address of the edx register
1161; @param [esp + 10h] gcc:rcx msc:r9 Param 4 - EBX
1162; @param [esp + 14h] gcc:r8 msc:[rsp + 8] Param 5 - ECX
1163; @uses eax, ecx, edx
1164;
1165align 16
1166BEGINPROC EMEmulateLockCmpXchg8b
1167 push xBP
1168 push xBX
1169%ifdef RT_ARCH_AMD64
1170 %ifdef RT_OS_WINDOWS
1171 mov rbp, rcx
1172 mov r10, rdx
1173 mov eax, dword [rdx]
1174 mov edx, dword [r8]
1175 mov rbx, r9
1176 mov ecx, [rsp + 28h + 16]
1177 %else
1178 mov rbp, rdi
1179 mov r10, rdx
1180 mov eax, dword [rsi]
1181 mov edx, dword [rdx]
1182 mov rbx, rcx
1183 mov rcx, r8
1184 %endif
1185%else
1186 mov ebp, [esp + 04h + 8] ; ebp = first parameter
1187 mov eax, [esp + 08h + 8] ; &EAX
1188 mov eax, dword [eax]
1189 mov edx, [esp + 0ch + 8] ; &EDX
1190 mov edx, dword [edx]
1191 mov ebx, [esp + 10h + 8] ; EBX
1192 mov ecx, [esp + 14h + 8] ; ECX
1193%endif
1194
1195%ifdef RT_OS_OS2
1196 lock cmpxchg8b [xBP] ; do CMPXCHG8B
1197%else
1198 lock cmpxchg8b qword [xBP] ; do CMPXCHG8B
1199%endif
1200
1201%ifdef RT_ARCH_AMD64
1202 %ifdef RT_OS_WINDOWS
1203 mov dword [r10], eax
1204 mov dword [r8], edx
1205 %else
1206 mov dword [rsi], eax
1207 mov dword [r10], edx
1208 %endif
1209%else
1210 mov ebx, dword [esp + 08h + 8]
1211 mov dword [ebx], eax
1212 mov ebx, dword [esp + 0ch + 8]
1213 mov dword [ebx], edx
1214%endif
1215 ; collect flags and return.
1216 pushf
1217 pop MY_RET_REG
1218
1219 pop xBX
1220 pop xBP
1221 retn
1222ENDPROC EMEmulateLockCmpXchg8b
1223
1224;;
1225; Emulate CMPXCHG8B instruction, CDECL calling conv.
1226; VMMDECL(uint32_t) EMEmulateCmpXchg8b(void *pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX);
1227;
1228; @returns EFLAGS after the operation, only arithmetic flags are valid.
1229; @param [esp + 04h] gcc:rdi msc:rcx Param 1 - First parameter - pointer to first parameter
1230; @param [esp + 08h] gcc:rsi msc:rdx Param 2 - Address of the eax register
1231; @param [esp + 0ch] gcc:rdx msc:r8 Param 3 - Address of the edx register
1232; @param [esp + 10h] gcc:rcx msc:r9 Param 4 - EBX
1233; @param [esp + 14h] gcc:r8 msc:[rsp + 8] Param 5 - ECX
1234; @uses eax, ecx, edx
1235;
1236align 16
1237BEGINPROC EMEmulateCmpXchg8b
1238 push xBP
1239 push xBX
1240%ifdef RT_ARCH_AMD64
1241 %ifdef RT_OS_WINDOWS
1242 mov rbp, rcx
1243 mov r10, rdx
1244 mov eax, dword [rdx]
1245 mov edx, dword [r8]
1246 mov rbx, r9
1247 mov ecx, [rsp + 28h + 16]
1248 %else
1249 mov rbp, rdi
1250 mov r10, rdx
1251 mov eax, dword [rsi]
1252 mov edx, dword [rdx]
1253 mov rbx, rcx
1254 mov rcx, r8
1255 %endif
1256%else
1257 mov ebp, [esp + 04h + 8] ; ebp = first parameter
1258 mov eax, [esp + 08h + 8] ; &EAX
1259 mov eax, dword [eax]
1260 mov edx, [esp + 0ch + 8] ; &EDX
1261 mov edx, dword [edx]
1262 mov ebx, [esp + 10h + 8] ; EBX
1263 mov ecx, [esp + 14h + 8] ; ECX
1264%endif
1265
1266%ifdef RT_OS_OS2
1267 cmpxchg8b [xBP] ; do CMPXCHG8B
1268%else
1269 cmpxchg8b qword [xBP] ; do CMPXCHG8B
1270%endif
1271
1272%ifdef RT_ARCH_AMD64
1273 %ifdef RT_OS_WINDOWS
1274 mov dword [r10], eax
1275 mov dword [r8], edx
1276 %else
1277 mov dword [rsi], eax
1278 mov dword [r10], edx
1279 %endif
1280%else
1281 mov ebx, dword [esp + 08h + 8]
1282 mov dword [ebx], eax
1283 mov ebx, dword [esp + 0ch + 8]
1284 mov dword [ebx], edx
1285%endif
1286
1287 ; collect flags and return.
1288 pushf
1289 pop MY_RET_REG
1290
1291 pop xBX
1292 pop xBP
1293 retn
1294ENDPROC EMEmulateCmpXchg8b
1295
Note: See TracBrowser for help on using the repository browser.

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