VirtualBox

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

Last change on this file since 6537 was 5999, checked in by vboxsync, 17 years ago

The Giant CDDL Dual-License Header Change.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 24.3 KB
Line 
1; $Id: EMAllA.asm 5999 2007-12-07 15:05:06Z vboxsync $
2;; @file
3; EM Assembly Routines.
4;
5
6;
7; Copyright (C) 2006-2007 innotek GmbH
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
18;*******************************************************************************
19;* Header Files *
20;*******************************************************************************
21%include "VBox/asmdefs.mac"
22%include "VBox/err.mac"
23%include "VBox/x86.mac"
24
25;; @def MY_PTR_REG
26; The register we use for value pointers (And,Or,Dec,Inc).
27%ifdef RT_ARCH_AMD64
28%define MY_PTR_REG rcx
29%else
30%define MY_PTR_REG ecx
31%endif
32
33;; @def MY_RET_REG
34; The register we return the result in.
35%ifdef RT_ARCH_AMD64
36%define MY_RET_REG rax
37%else
38%define MY_RET_REG eax
39%endif
40
41BEGINCODE
42
43
44;;
45; Emulate CMP instruction, CDECL calling conv.
46; EMDECL(uint32_t) EMEmulateCmp(uint32_t u32Param1, uint32_t u32Param2, size_t cb);
47;
48; @returns EFLAGS after the operation, only arithmetic flags is valid.
49; @param [esp + 04h] rdi rcx Param 1 - First parameter (Dst).
50; @param [esp + 08h] rsi edx Param 2 - Second parameter (Src).
51; @param [esp + 0ch] rdx r8 Param 3 - Size of parameters, only 1/2/4 is valid.
52;
53align 16
54BEGINPROC EMEmulateCmp
55%ifdef RT_ARCH_AMD64
56%ifdef RT_OS_WINDOWS
57 mov rax, r8 ; eax = size of parameters
58%else ; !RT_OS_WINDOWS
59 mov rax, rdx ; rax = size of parameters
60 mov rcx, rdi ; rcx = first parameter
61 mov rdx, rsi ; rdx = second parameter
62%endif ; !RT_OS_WINDOWS
63%else ; !RT_ARCH_AMD64
64 mov eax, [esp + 0ch] ; eax = size of parameters
65 mov ecx, [esp + 04h] ; ecx = first parameter
66 mov edx, [esp + 08h] ; edx = second parameter
67%endif
68
69 ; switch on size
70%ifdef RT_ARCH_AMD64
71 cmp al, 8
72 je short .do_qword ; 8 bytes variant
73%endif
74 cmp al, 4
75 je short .do_dword ; 4 bytes variant
76 cmp al, 2
77 je short .do_word ; 2 byte variant
78 cmp al, 1
79 je short .do_byte ; 1 bytes variant
80 int3
81
82 ; workers
83%ifdef RT_ARCH_AMD64
84.do_qword:
85 cmp rcx, rdx ; do 8 bytes CMP
86 jmp short .done
87%endif
88
89.do_dword:
90 cmp ecx, edx ; do 4 bytes CMP
91 jmp short .done
92
93.do_word:
94 cmp cx, dx ; do 2 bytes CMP
95 jmp short .done
96
97.do_byte:
98 cmp cl, dl ; do 1 byte CMP
99
100 ; collect flags and return.
101.done:
102 pushf
103 pop MY_RET_REG
104 retn
105ENDPROC EMEmulateCmp
106
107
108;;
109; Emulate AND instruction, CDECL calling conv.
110; EMDECL(uint32_t) EMEmulateAnd(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb);
111;
112; @returns EFLAGS after the operation, only arithmetic flags is valid.
113; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
114; @param [esp + 08h] Param 2 - Second parameter.
115; @param [esp + 0ch] Param 3 - Size of parameters, only 1/2/4 is valid.
116; @uses eax, ecx, edx
117;
118align 16
119BEGINPROC EMEmulateAnd
120%ifdef RT_ARCH_AMD64
121%ifdef RT_OS_WINDOWS
122 mov rax, r8 ; eax = size of parameters
123%else ; !RT_OS_WINDOWS
124 mov rax, rdx ; rax = size of parameters
125 mov rcx, rdi ; rcx = first parameter
126 mov rdx, rsi ; rdx = second parameter
127%endif ; !RT_OS_WINDOWS
128%else ; !RT_ARCH_AMD64
129 mov eax, [esp + 0ch] ; eax = size of parameters
130 mov ecx, [esp + 04h] ; ecx = first parameter
131 mov edx, [esp + 08h] ; edx = second parameter
132%endif
133
134 ; switch on size
135%ifdef RT_ARCH_AMD64
136 cmp al, 8
137 je short .do_qword ; 8 bytes variant
138%endif
139 cmp al, 4
140 je short .do_dword ; 4 bytes variant
141 cmp al, 2
142 je short .do_word ; 2 byte variant
143 cmp al, 1
144 je short .do_byte ; 1 bytes variant
145 int3
146
147 ; workers
148%ifdef RT_ARCH_AMD64
149.do_qword:
150 and [MY_PTR_REG], rdx ; do 8 bytes AND
151 jmp short .done
152%endif
153
154.do_dword:
155 and [MY_PTR_REG], edx ; do 4 bytes AND
156 jmp short .done
157
158.do_word:
159 and [MY_PTR_REG], dx ; do 2 bytes AND
160 jmp short .done
161
162.do_byte:
163 and [MY_PTR_REG], dl ; do 1 byte AND
164
165 ; collect flags and return.
166.done:
167 pushf
168 pop MY_RET_REG
169 retn
170ENDPROC EMEmulateAnd
171
172
173;;
174; Emulate OR instruction, CDECL calling conv.
175; EMDECL(uint32_t) EMEmulateOr(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb);
176;
177; @returns EFLAGS after the operation, only arithmetic flags is valid.
178; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
179; @param [esp + 08h] Param 2 - Second parameter.
180; @param [esp + 0ch] Param 3 - Size of parameters, only 1/2/4 is valid.
181; @uses eax, ecx, edx
182;
183align 16
184BEGINPROC EMEmulateOr
185%ifdef RT_ARCH_AMD64
186%ifdef RT_OS_WINDOWS
187 mov rax, r8 ; eax = size of parameters
188%else ; !RT_OS_WINDOWS
189 mov rax, rdx ; rax = size of parameters
190 mov rcx, rdi ; rcx = first parameter
191 mov rdx, rsi ; rdx = second parameter
192%endif ; !RT_OS_WINDOWS
193%else ; !RT_ARCH_AMD64
194 mov eax, [esp + 0ch] ; eax = size of parameters
195 mov ecx, [esp + 04h] ; ecx = first parameter
196 mov edx, [esp + 08h] ; edx = second parameter
197%endif
198
199 ; switch on size
200%ifdef RT_ARCH_AMD64
201 cmp al, 8
202 je short .do_qword ; 8 bytes variant
203%endif
204 cmp al, 4
205 je short .do_dword ; 4 bytes variant
206 cmp al, 2
207 je short .do_word ; 2 byte variant
208 cmp al, 1
209 je short .do_byte ; 1 bytes variant
210 int3
211
212 ; workers
213%ifdef RT_ARCH_AMD64
214.do_qword:
215 or [MY_PTR_REG], rdx ; do 8 bytes OR
216 jmp short .done
217%endif
218
219.do_dword:
220 or [MY_PTR_REG], edx ; do 4 bytes OR
221 jmp short .done
222
223.do_word:
224 or [MY_PTR_REG], dx ; do 2 bytes OR
225 jmp short .done
226
227.do_byte:
228 or [MY_PTR_REG], dl ; do 1 byte OR
229
230 ; collect flags and return.
231.done:
232 pushf
233 pop MY_RET_REG
234 retn
235ENDPROC EMEmulateOr
236
237;;
238; Emulate LOCK OR instruction.
239; EMDECL(int) EMEmulateLockOr(RTGCPTR GCPtrParam1, RTGCUINTREG Param2, size_t cbSize, RTGCUINTREG *pf);
240;
241; @returns VINF_SUCCESS on success, VERR_ACCESS_DENIED on \#PF (GC only).
242; @param [esp + 04h] gcc:rdi msc:rcx Param 1 - First parameter - pointer to data item (the real stuff).
243; @param [esp + 08h] gcc:rsi msc:rdx Param 2 - Second parameter- the immediate / register value.
244; @param [esp + 0ch] gcc:rdx msc:r8 Param 3 - Size of the operation - 1, 2, 4 or 8 bytes.
245; @param [esp + 10h] gcc:rcx msc:r9 Param 4 - Where to store the eflags on success.
246; only arithmetic flags are valid.
247align 16
248BEGINPROC EMEmulateLockOr
249%ifdef RT_ARCH_AMD64
250%ifdef RT_OS_WINDOWS
251 mov rax, r8 ; eax = size of parameters
252%else ; !RT_OS_WINDOWS
253 mov rax, rdx ; rax = size of parameters
254 mov rcx, rdi ; rcx = first parameter
255 mov rdx, rsi ; rdx = second parameter
256%endif ; !RT_OS_WINDOWS
257%else ; !RT_ARCH_AMD64
258 mov eax, [esp + 0ch] ; eax = size of parameters
259 mov ecx, [esp + 04h] ; ecx = first parameter (MY_PTR_REG)
260 mov edx, [esp + 08h] ; edx = second parameter
261%endif
262
263 ; switch on size
264%ifdef RT_ARCH_AMD64
265 cmp al, 8
266 je short .do_qword ; 8 bytes variant
267%endif
268 cmp al, 4
269 je short .do_dword ; 4 bytes variant
270 cmp al, 2
271 je short .do_word ; 2 byte variant
272 cmp al, 1
273 je short .do_byte ; 1 bytes variant
274 int3
275
276 ; workers
277%ifdef RT_ARCH_AMD64
278.do_qword:
279 lock or [MY_PTR_REG], rdx ; do 8 bytes OR
280 jmp short .done
281%endif
282
283.do_dword:
284 lock or [MY_PTR_REG], edx ; do 4 bytes OR
285 jmp short .done
286
287.do_word:
288 lock or [MY_PTR_REG], dx ; do 2 bytes OR
289 jmp short .done
290
291.do_byte:
292 lock or [MY_PTR_REG], dl ; do 1 byte OR
293
294 ; collect flags and return.
295.done:
296 pushf
297%ifdef RT_ARCH_AMD64
298 pop rax
299 %ifdef RT_OS_WINDOWS
300 mov [r9], eax
301 %else ; !RT_OS_WINDOWS
302 mov [rcx], eax
303 %endif ; !RT_OS_WINDOWS
304%else ; !RT_ARCH_AMD64
305 mov eax, [esp + 10h + 4]
306 pop dword [eax]
307%endif
308 mov eax, VINF_SUCCESS
309 retn
310
311%ifdef IN_GC
312; #PF resume point.
313GLOBALNAME EMEmulateLockOr_Error
314 mov eax, VERR_ACCESS_DENIED
315 ret
316%endif
317
318ENDPROC EMEmulateLockOr
319
320;;
321; Emulate XOR instruction, CDECL calling conv.
322; EMDECL(uint32_t) EMEmulateXor(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb);
323;
324; @returns EFLAGS after the operation, only arithmetic flags is valid.
325; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
326; @param [esp + 08h] Param 2 - Second parameter.
327; @param [esp + 0ch] Param 3 - Size of parameters, only 1/2/4 is valid.
328; @uses eax, ecx, edx
329;
330align 16
331BEGINPROC EMEmulateXor
332%ifdef RT_ARCH_AMD64
333%ifdef RT_OS_WINDOWS
334 mov rax, r8 ; eax = size of parameters
335%else ; !RT_OS_WINDOWS
336 mov rax, rdx ; rax = size of parameters
337 mov rcx, rdi ; rcx = first parameter
338 mov rdx, rsi ; rdx = second parameter
339%endif ; !RT_OS_WINDOWS
340%else ; !RT_ARCH_AMD64
341 mov eax, [esp + 0ch] ; eax = size of parameters
342 mov ecx, [esp + 04h] ; ecx = first parameter
343 mov edx, [esp + 08h] ; edx = second parameter
344%endif
345
346 ; switch on size
347%ifdef RT_ARCH_AMD64
348 cmp al, 8
349 je short .do_qword ; 8 bytes variant
350%endif
351 cmp al, 4
352 je short .do_dword ; 4 bytes variant
353 cmp al, 2
354 je short .do_word ; 2 byte variant
355 cmp al, 1
356 je short .do_byte ; 1 bytes variant
357 int3
358
359 ; workers
360%ifdef RT_ARCH_AMD64
361.do_qword:
362 xor [MY_PTR_REG], rdx ; do 8 bytes XOR
363 jmp short .done
364%endif
365
366.do_dword:
367 xor [MY_PTR_REG], edx ; do 4 bytes XOR
368 jmp short .done
369
370.do_word:
371 xor [MY_PTR_REG], dx ; do 2 bytes XOR
372 jmp short .done
373
374.do_byte:
375 xor [MY_PTR_REG], dl ; do 1 byte XOR
376
377 ; collect flags and return.
378.done:
379 pushf
380 pop MY_RET_REG
381 retn
382ENDPROC EMEmulateXor
383
384;;
385; Emulate INC instruction, CDECL calling conv.
386; EMDECL(uint32_t) EMEmulateInc(uint32_t *pu32Param1, size_t cb);
387;
388; @returns EFLAGS after the operation, only arithmetic flags are valid.
389; @param [esp + 04h] rdi rcx Param 1 - First parameter - pointer to data item.
390; @param [esp + 08h] rsi rdx Param 2 - Size of parameters, only 1/2/4 is valid.
391; @uses eax, ecx, edx
392;
393align 16
394BEGINPROC EMEmulateInc
395%ifdef RT_ARCH_AMD64
396%ifdef RT_OS_WINDOWS
397 mov rax, rdx ; eax = size of parameters
398%else ; !RT_OS_WINDOWS
399 mov rax, rsi ; eax = size of parameters
400 mov rcx, rdi ; rcx = first parameter
401%endif ; !RT_OS_WINDOWS
402%else ; !RT_ARCH_AMD64
403 mov eax, [esp + 08h] ; eax = size of parameters
404 mov ecx, [esp + 04h] ; ecx = first parameter
405%endif
406
407 ; switch on size
408%ifdef RT_ARCH_AMD64
409 cmp al, 8
410 je short .do_qword ; 8 bytes variant
411%endif
412 cmp al, 4
413 je short .do_dword ; 4 bytes variant
414 cmp al, 2
415 je short .do_word ; 2 byte variant
416 cmp al, 1
417 je short .do_byte ; 1 bytes variant
418 int3
419
420 ; workers
421%ifdef RT_ARCH_AMD64
422.do_qword:
423 inc qword [MY_PTR_REG] ; do 8 bytes INC
424 jmp short .done
425%endif
426
427.do_dword:
428 inc dword [MY_PTR_REG] ; do 4 bytes INC
429 jmp short .done
430
431.do_word:
432 inc word [MY_PTR_REG] ; do 2 bytes INC
433 jmp short .done
434
435.do_byte:
436 inc byte [MY_PTR_REG] ; do 1 byte INC
437 jmp short .done
438
439 ; collect flags and return.
440.done:
441 pushf
442 pop MY_RET_REG
443 retn
444ENDPROC EMEmulateInc
445
446
447;;
448; Emulate DEC instruction, CDECL calling conv.
449; EMDECL(uint32_t) EMEmulateDec(uint32_t *pu32Param1, size_t cb);
450;
451; @returns EFLAGS after the operation, only arithmetic flags are valid.
452; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
453; @param [esp + 08h] Param 2 - Size of parameters, only 1/2/4 is valid.
454; @uses eax, ecx, edx
455;
456align 16
457BEGINPROC EMEmulateDec
458%ifdef RT_ARCH_AMD64
459%ifdef RT_OS_WINDOWS
460 mov rax, rdx ; eax = size of parameters
461%else ; !RT_OS_WINDOWS
462 mov rax, rsi ; eax = size of parameters
463 mov rcx, rdi ; rcx = first parameter
464%endif ; !RT_OS_WINDOWS
465%else ; !RT_ARCH_AMD64
466 mov eax, [esp + 08h] ; eax = size of parameters
467 mov ecx, [esp + 04h] ; ecx = first parameter
468%endif
469
470 ; switch on size
471%ifdef RT_ARCH_AMD64
472 cmp al, 8
473 je short .do_qword ; 8 bytes variant
474%endif
475 cmp al, 4
476 je short .do_dword ; 4 bytes variant
477 cmp al, 2
478 je short .do_word ; 2 byte variant
479 cmp al, 1
480 je short .do_byte ; 1 bytes variant
481 int3
482
483 ; workers
484%ifdef RT_ARCH_AMD64
485.do_qword:
486 dec qword [MY_PTR_REG] ; do 8 bytes DEC
487 jmp short .done
488%endif
489
490.do_dword:
491 dec dword [MY_PTR_REG] ; do 4 bytes DEC
492 jmp short .done
493
494.do_word:
495 dec word [MY_PTR_REG] ; do 2 bytes DEC
496 jmp short .done
497
498.do_byte:
499 dec byte [MY_PTR_REG] ; do 1 byte DEC
500 jmp short .done
501
502 ; collect flags and return.
503.done:
504 pushf
505 pop MY_RET_REG
506 retn
507ENDPROC EMEmulateDec
508
509;;
510; Emulate ADD instruction, CDECL calling conv.
511; EMDECL(uint32_t) EMEmulateAdd(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb);
512;
513; @returns EFLAGS after the operation, only arithmetic flags is valid.
514; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
515; @param [esp + 08h] Param 2 - Second parameter.
516; @param [esp + 0ch] Param 3 - Size of parameters, only 1/2/4 is valid.
517; @uses eax, ecx, edx
518;
519align 16
520BEGINPROC EMEmulateAdd
521%ifdef RT_ARCH_AMD64
522%ifdef RT_OS_WINDOWS
523 mov rax, r8 ; eax = size of parameters
524%else ; !RT_OS_WINDOWS
525 mov rax, rdx ; rax = size of parameters
526 mov rcx, rdi ; rcx = first parameter
527 mov rdx, rsi ; rdx = second parameter
528%endif ; !RT_OS_WINDOWS
529%else ; !RT_ARCH_AMD64
530 mov eax, [esp + 0ch] ; eax = size of parameters
531 mov ecx, [esp + 04h] ; ecx = first parameter
532 mov edx, [esp + 08h] ; edx = second parameter
533%endif
534
535 ; switch on size
536%ifdef RT_ARCH_AMD64
537 cmp al, 8
538 je short .do_qword ; 8 bytes variant
539%endif
540 cmp al, 4
541 je short .do_dword ; 4 bytes variant
542 cmp al, 2
543 je short .do_word ; 2 byte variant
544 cmp al, 1
545 je short .do_byte ; 1 bytes variant
546 int3
547
548 ; workers
549%ifdef RT_ARCH_AMD64
550.do_qword:
551 add [MY_PTR_REG], rdx ; do 8 bytes ADD
552 jmp short .done
553%endif
554
555.do_dword:
556 add [MY_PTR_REG], edx ; do 4 bytes ADD
557 jmp short .done
558
559.do_word:
560 add [MY_PTR_REG], dx ; do 2 bytes ADD
561 jmp short .done
562
563.do_byte:
564 add [MY_PTR_REG], dl ; do 1 byte ADD
565
566 ; collect flags and return.
567.done:
568 pushf
569 pop MY_RET_REG
570 retn
571ENDPROC EMEmulateAdd
572
573;;
574; Emulate ADC instruction, CDECL calling conv.
575; EMDECL(uint32_t) EMEmulateAdcWithCarrySet(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb);
576;
577; @returns EFLAGS after the operation, only arithmetic flags is valid.
578; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
579; @param [esp + 08h] Param 2 - Second parameter.
580; @param [esp + 0ch] Param 3 - Size of parameters, only 1/2/4 is valid.
581; @uses eax, ecx, edx
582;
583align 16
584BEGINPROC EMEmulateAdcWithCarrySet
585%ifdef RT_ARCH_AMD64
586%ifdef RT_OS_WINDOWS
587 mov rax, r8 ; eax = size of parameters
588%else ; !RT_OS_WINDOWS
589 mov rax, rdx ; rax = size of parameters
590 mov rcx, rdi ; rcx = first parameter
591 mov rdx, rsi ; rdx = second parameter
592%endif ; !RT_OS_WINDOWS
593%else ; !RT_ARCH_AMD64
594 mov eax, [esp + 0ch] ; eax = size of parameters
595 mov ecx, [esp + 04h] ; ecx = first parameter
596 mov edx, [esp + 08h] ; edx = second parameter
597%endif
598
599 ; switch on size
600%ifdef RT_ARCH_AMD64
601 cmp al, 8
602 je short .do_qword ; 8 bytes variant
603%endif
604 cmp al, 4
605 je short .do_dword ; 4 bytes variant
606 cmp al, 2
607 je short .do_word ; 2 byte variant
608 cmp al, 1
609 je short .do_byte ; 1 bytes variant
610 int3
611
612 ; workers
613%ifdef RT_ARCH_AMD64
614.do_qword:
615 stc ; set carry flag
616 adc [MY_PTR_REG], rdx ; do 8 bytes ADC
617 jmp short .done
618%endif
619
620.do_dword:
621 stc ; set carry flag
622 adc [MY_PTR_REG], edx ; do 4 bytes ADC
623 jmp short .done
624
625.do_word:
626 stc ; set carry flag
627 adc [MY_PTR_REG], dx ; do 2 bytes ADC
628 jmp short .done
629
630.do_byte:
631 stc ; set carry flag
632 adc [MY_PTR_REG], dl ; do 1 byte ADC
633
634 ; collect flags and return.
635.done:
636 pushf
637 pop MY_RET_REG
638 retn
639ENDPROC EMEmulateAdcWithCarrySet
640
641;;
642; Emulate SUB instruction, CDECL calling conv.
643; EMDECL(uint32_t) EMEmulateSub(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb);
644;
645; @returns EFLAGS after the operation, only arithmetic flags is valid.
646; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
647; @param [esp + 08h] Param 2 - Second parameter.
648; @param [esp + 0ch] Param 3 - Size of parameters, only 1/2/4 is valid.
649; @uses eax, ecx, edx
650;
651align 16
652BEGINPROC EMEmulateSub
653%ifdef RT_ARCH_AMD64
654%ifdef RT_OS_WINDOWS
655 mov rax, r8 ; eax = size of parameters
656%else ; !RT_OS_WINDOWS
657 mov rax, rdx ; rax = size of parameters
658 mov rcx, rdi ; rcx = first parameter
659 mov rdx, rsi ; rdx = second parameter
660%endif ; !RT_OS_WINDOWS
661%else ; !RT_ARCH_AMD64
662 mov eax, [esp + 0ch] ; eax = size of parameters
663 mov ecx, [esp + 04h] ; ecx = first parameter
664 mov edx, [esp + 08h] ; edx = second parameter
665%endif
666
667 ; switch on size
668%ifdef RT_ARCH_AMD64
669 cmp al, 8
670 je short .do_qword ; 8 bytes variant
671%endif
672 cmp al, 4
673 je short .do_dword ; 4 bytes variant
674 cmp al, 2
675 je short .do_word ; 2 byte variant
676 cmp al, 1
677 je short .do_byte ; 1 bytes variant
678 int3
679
680 ; workers
681%ifdef RT_ARCH_AMD64
682.do_qword:
683 sub [MY_PTR_REG], rdx ; do 8 bytes SUB
684 jmp short .done
685%endif
686
687.do_dword:
688 sub [MY_PTR_REG], edx ; do 4 bytes SUB
689 jmp short .done
690
691.do_word:
692 sub [MY_PTR_REG], dx ; do 2 bytes SUB
693 jmp short .done
694
695.do_byte:
696 sub [MY_PTR_REG], dl ; do 1 byte SUB
697
698 ; collect flags and return.
699.done:
700 pushf
701 pop MY_RET_REG
702 retn
703ENDPROC EMEmulateSub
704
705
706;;
707; Emulate BTR instruction, CDECL calling conv.
708; EMDECL(uint32_t) EMEmulateBtr(uint32_t *pu32Param1, uint32_t u32Param2);
709;
710; @returns EFLAGS after the operation, only arithmetic flags is valid.
711; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
712; @param [esp + 08h] Param 2 - Second parameter.
713; @uses eax, ecx, edx
714;
715align 16
716BEGINPROC EMEmulateBtr
717%ifdef RT_ARCH_AMD64
718%ifndef RT_OS_WINDOWS
719 mov rcx, rdi ; rcx = first parameter
720 mov rdx, rsi ; rdx = second parameter
721%endif ; !RT_OS_WINDOWS
722%else ; !RT_ARCH_AMD64
723 mov ecx, [esp + 04h] ; ecx = first parameter
724 mov edx, [esp + 08h] ; edx = second parameter
725%endif
726
727 and edx, 7
728 btr [MY_PTR_REG], edx
729
730 ; collect flags and return.
731 pushf
732 pop MY_RET_REG
733 retn
734ENDPROC EMEmulateBtr
735
736;;
737; Emulate LOCK BTR instruction.
738; EMDECL(int) EMEmulateLockBtr(RTGCPTR GCPtrParam1, RTGCUINTREG Param2, uint32_t *pf);
739;
740; @returns VINF_SUCCESS on success, VERR_ACCESS_DENIED on \#PF (GC only).
741; @param [esp + 04h] gcc:rdi msc:rcx Param 1 - First parameter - pointer to data item (the real stuff).
742; @param [esp + 08h] gcc:rsi msc:rdx Param 2 - Second parameter- the immediate / register value. (really an 8 byte value)
743; @param [esp + 0ch] gcc:rdx msc:r8 Param 3 - Where to store the eflags on success.
744;
745align 16
746BEGINPROC EMEmulateLockBtr
747%ifdef RT_ARCH_AMD64
748 %ifdef RT_OS_WINDOWS
749 mov rax, r8 ; rax = third parameter
750 %else ; !RT_OS_WINDOWS
751 mov rcx, rdi ; rcx = first parameter
752 mov rax, rdx ; rax = third parameter
753 mov rdx, rsi ; rdx = second parameter
754 %endif ; !RT_OS_WINDOWS
755%else ; !RT_ARCH_AMD64
756 mov ecx, [esp + 04h] ; ecx = first parameter
757 mov edx, [esp + 08h] ; edx = second parameter
758 mov eax, [esp + 0ch] ; eax = third parameter
759%endif
760
761 lock btr [MY_PTR_REG], edx
762
763 ; collect flags and return.
764 pushf
765 pop xDX
766 mov [xAX], edx
767 mov eax, VINF_SUCCESS
768 retn
769
770%ifdef IN_GC
771; #PF resume point.
772GLOBALNAME EMEmulateLockBtr_Error
773 mov eax, VERR_ACCESS_DENIED
774 ret
775%endif
776
777ENDPROC EMEmulateLockBtr
778
779;;
780; Emulate BTC instruction, CDECL calling conv.
781; EMDECL(uint32_t) EMEmulateBtc(uint32_t *pu32Param1, uint32_t u32Param2);
782;
783; @returns EFLAGS after the operation, only arithmetic flags is valid.
784; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
785; @param [esp + 08h] Param 2 - Second parameter.
786; @uses eax, ecx, edx
787;
788align 16
789BEGINPROC EMEmulateBtc
790%ifdef RT_ARCH_AMD64
791%ifndef RT_OS_WINDOWS
792 mov rcx, rdi ; rcx = first parameter
793 mov rdx, rsi ; rdx = second parameter
794%endif ; !RT_OS_WINDOWS
795%else ; !RT_ARCH_AMD64
796 mov ecx, [esp + 04h] ; ecx = first parameter
797 mov edx, [esp + 08h] ; edx = second parameter
798%endif
799
800 and edx, 7
801 btc [MY_PTR_REG], edx
802
803 ; collect flags and return.
804 pushf
805 pop MY_RET_REG
806 retn
807ENDPROC EMEmulateBtc
808
809;;
810; Emulate BTS instruction, CDECL calling conv.
811; EMDECL(uint32_t) EMEmulateBts(uint32_t *pu32Param1, uint32_t u32Param2);
812;
813; @returns EFLAGS after the operation, only arithmetic flags is valid.
814; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
815; @param [esp + 08h] Param 2 - Second parameter.
816; @uses eax, ecx, edx
817;
818align 16
819BEGINPROC EMEmulateBts
820%ifdef RT_ARCH_AMD64
821%ifndef RT_OS_WINDOWS
822 mov rcx, rdi ; rcx = first parameter
823 mov rdx, rsi ; rdx = second parameter
824%endif ; !RT_OS_WINDOWS
825%else ; !RT_ARCH_AMD64
826 mov ecx, [esp + 04h] ; ecx = first parameter
827 mov edx, [esp + 08h] ; edx = second parameter
828%endif
829
830 and edx, 7
831 bts [MY_PTR_REG], edx
832
833 ; collect flags and return.
834 pushf
835 pop MY_RET_REG
836 retn
837ENDPROC EMEmulateBts
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