VirtualBox

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

Last change on this file since 9026 was 8225, checked in by vboxsync, 17 years ago

Added some assembly support routines (inactive; todo)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 31.7 KB
Line 
1; $Id: EMAllA.asm 8225 2008-04-21 13:35:52Z 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
45BEGINCODE
46
47
48;;
49; Emulate CMP instruction, CDECL calling conv.
50; EMDECL(uint32_t) EMEmulateCmp(uint32_t u32Param1, uint32_t u32Param2, size_t cb);
51;
52; @returns EFLAGS after the operation, only arithmetic flags is valid.
53; @param [esp + 04h] rdi rcx Param 1 - First parameter (Dst).
54; @param [esp + 08h] rsi edx Param 2 - Second parameter (Src).
55; @param [esp + 0ch] rdx r8 Param 3 - Size of parameters, only 1/2/4 is valid.
56;
57align 16
58BEGINPROC EMEmulateCmp
59%ifdef RT_ARCH_AMD64
60%ifdef RT_OS_WINDOWS
61 mov rax, r8 ; eax = size of parameters
62%else ; !RT_OS_WINDOWS
63 mov rax, rdx ; rax = size of parameters
64 mov rcx, rdi ; rcx = first parameter
65 mov rdx, rsi ; rdx = second parameter
66%endif ; !RT_OS_WINDOWS
67%else ; !RT_ARCH_AMD64
68 mov eax, [esp + 0ch] ; eax = size of parameters
69 mov ecx, [esp + 04h] ; ecx = first parameter
70 mov edx, [esp + 08h] ; edx = second parameter
71%endif
72
73 ; switch on size
74%ifdef RT_ARCH_AMD64
75 cmp al, 8
76 je short .do_qword ; 8 bytes variant
77%endif
78 cmp al, 4
79 je short .do_dword ; 4 bytes variant
80 cmp al, 2
81 je short .do_word ; 2 byte variant
82 cmp al, 1
83 je short .do_byte ; 1 bytes variant
84 int3
85
86 ; workers
87%ifdef RT_ARCH_AMD64
88.do_qword:
89 cmp rcx, rdx ; do 8 bytes CMP
90 jmp short .done
91%endif
92
93.do_dword:
94 cmp ecx, edx ; do 4 bytes CMP
95 jmp short .done
96
97.do_word:
98 cmp cx, dx ; do 2 bytes CMP
99 jmp short .done
100
101.do_byte:
102 cmp cl, dl ; do 1 byte CMP
103
104 ; collect flags and return.
105.done:
106 pushf
107 pop MY_RET_REG
108 retn
109ENDPROC EMEmulateCmp
110
111
112;;
113; Emulate AND instruction, CDECL calling conv.
114; EMDECL(uint32_t) EMEmulateAnd(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb);
115;
116; @returns EFLAGS after the operation, only arithmetic flags is valid.
117; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
118; @param [esp + 08h] Param 2 - Second parameter.
119; @param [esp + 0ch] Param 3 - Size of parameters, only 1/2/4 is valid.
120; @uses eax, ecx, edx
121;
122align 16
123BEGINPROC EMEmulateAnd
124%ifdef RT_ARCH_AMD64
125%ifdef RT_OS_WINDOWS
126 mov rax, r8 ; eax = size of parameters
127%else ; !RT_OS_WINDOWS
128 mov rax, rdx ; rax = size of parameters
129 mov rcx, rdi ; rcx = first parameter
130 mov rdx, rsi ; rdx = second parameter
131%endif ; !RT_OS_WINDOWS
132%else ; !RT_ARCH_AMD64
133 mov eax, [esp + 0ch] ; eax = size of parameters
134 mov ecx, [esp + 04h] ; ecx = first parameter
135 mov edx, [esp + 08h] ; edx = second parameter
136%endif
137
138 ; switch on size
139%ifdef RT_ARCH_AMD64
140 cmp al, 8
141 je short .do_qword ; 8 bytes variant
142%endif
143 cmp al, 4
144 je short .do_dword ; 4 bytes variant
145 cmp al, 2
146 je short .do_word ; 2 byte variant
147 cmp al, 1
148 je short .do_byte ; 1 bytes variant
149 int3
150
151 ; workers
152%ifdef RT_ARCH_AMD64
153.do_qword:
154 and [MY_PTR_REG], rdx ; do 8 bytes AND
155 jmp short .done
156%endif
157
158.do_dword:
159 and [MY_PTR_REG], edx ; do 4 bytes AND
160 jmp short .done
161
162.do_word:
163 and [MY_PTR_REG], dx ; do 2 bytes AND
164 jmp short .done
165
166.do_byte:
167 and [MY_PTR_REG], dl ; do 1 byte AND
168
169 ; collect flags and return.
170.done:
171 pushf
172 pop MY_RET_REG
173 retn
174ENDPROC EMEmulateAnd
175
176
177;;
178; Emulate OR instruction, CDECL calling conv.
179; EMDECL(uint32_t) EMEmulateOr(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb);
180;
181; @returns EFLAGS after the operation, only arithmetic flags is valid.
182; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
183; @param [esp + 08h] Param 2 - Second parameter.
184; @param [esp + 0ch] Param 3 - Size of parameters, only 1/2/4 is valid.
185; @uses eax, ecx, edx
186;
187align 16
188BEGINPROC EMEmulateOr
189%ifdef RT_ARCH_AMD64
190%ifdef RT_OS_WINDOWS
191 mov rax, r8 ; eax = size of parameters
192%else ; !RT_OS_WINDOWS
193 mov rax, rdx ; rax = size of parameters
194 mov rcx, rdi ; rcx = first parameter
195 mov rdx, rsi ; rdx = second parameter
196%endif ; !RT_OS_WINDOWS
197%else ; !RT_ARCH_AMD64
198 mov eax, [esp + 0ch] ; eax = size of parameters
199 mov ecx, [esp + 04h] ; ecx = first parameter
200 mov edx, [esp + 08h] ; edx = second parameter
201%endif
202
203 ; switch on size
204%ifdef RT_ARCH_AMD64
205 cmp al, 8
206 je short .do_qword ; 8 bytes variant
207%endif
208 cmp al, 4
209 je short .do_dword ; 4 bytes variant
210 cmp al, 2
211 je short .do_word ; 2 byte variant
212 cmp al, 1
213 je short .do_byte ; 1 bytes variant
214 int3
215
216 ; workers
217%ifdef RT_ARCH_AMD64
218.do_qword:
219 or [MY_PTR_REG], rdx ; do 8 bytes OR
220 jmp short .done
221%endif
222
223.do_dword:
224 or [MY_PTR_REG], edx ; do 4 bytes OR
225 jmp short .done
226
227.do_word:
228 or [MY_PTR_REG], dx ; do 2 bytes OR
229 jmp short .done
230
231.do_byte:
232 or [MY_PTR_REG], dl ; do 1 byte OR
233
234 ; collect flags and return.
235.done:
236 pushf
237 pop MY_RET_REG
238 retn
239ENDPROC EMEmulateOr
240
241;;
242; Emulate LOCK OR instruction.
243; EMDECL(int) EMEmulateLockOr(RTGCPTR GCPtrParam1, RTGCUINTREG Param2, size_t cbSize, RTGCUINTREG *pf);
244;
245; @returns VINF_SUCCESS on success, VERR_ACCESS_DENIED on \#PF (GC only).
246; @param [esp + 04h] gcc:rdi msc:rcx Param 1 - First parameter - pointer to data item (the real stuff).
247; @param [esp + 08h] gcc:rsi msc:rdx Param 2 - Second parameter- the immediate / register value.
248; @param [esp + 0ch] gcc:rdx msc:r8 Param 3 - Size of the operation - 1, 2, 4 or 8 bytes.
249; @param [esp + 10h] gcc:rcx msc:r9 Param 4 - Where to store the eflags on success.
250; only arithmetic flags are valid.
251align 16
252BEGINPROC EMEmulateLockOr
253%ifdef RT_ARCH_AMD64
254%ifdef RT_OS_WINDOWS
255 mov rax, r8 ; eax = size of parameters
256%else ; !RT_OS_WINDOWS
257 mov rax, rdx ; rax = size of parameters
258 mov rcx, rdi ; rcx = first parameter
259 mov rdx, rsi ; rdx = second parameter
260%endif ; !RT_OS_WINDOWS
261%else ; !RT_ARCH_AMD64
262 mov eax, [esp + 0ch] ; eax = size of parameters
263 mov ecx, [esp + 04h] ; ecx = first parameter (MY_PTR_REG)
264 mov edx, [esp + 08h] ; edx = second parameter
265%endif
266
267 ; switch on size
268%ifdef RT_ARCH_AMD64
269 cmp al, 8
270 je short .do_qword ; 8 bytes variant
271%endif
272 cmp al, 4
273 je short .do_dword ; 4 bytes variant
274 cmp al, 2
275 je short .do_word ; 2 byte variant
276 cmp al, 1
277 je short .do_byte ; 1 bytes variant
278 int3
279
280 ; workers
281%ifdef RT_ARCH_AMD64
282.do_qword:
283 lock or [MY_PTR_REG], rdx ; do 8 bytes OR
284 jmp short .done
285%endif
286
287.do_dword:
288 lock or [MY_PTR_REG], edx ; do 4 bytes OR
289 jmp short .done
290
291.do_word:
292 lock or [MY_PTR_REG], dx ; do 2 bytes OR
293 jmp short .done
294
295.do_byte:
296 lock or [MY_PTR_REG], dl ; do 1 byte OR
297
298 ; collect flags and return.
299.done:
300 pushf
301%ifdef RT_ARCH_AMD64
302 pop rax
303 %ifdef RT_OS_WINDOWS
304 mov [r9], eax
305 %else ; !RT_OS_WINDOWS
306 mov [rcx], eax
307 %endif ; !RT_OS_WINDOWS
308%else ; !RT_ARCH_AMD64
309 mov eax, [esp + 10h + 4]
310 pop dword [eax]
311%endif
312 mov eax, VINF_SUCCESS
313 retn
314
315%ifdef IN_GC
316; #PF resume point.
317GLOBALNAME EMEmulateLockOr_Error
318 mov eax, VERR_ACCESS_DENIED
319 ret
320%endif
321
322ENDPROC EMEmulateLockOr
323
324;;
325; Emulate XOR instruction, CDECL calling conv.
326; EMDECL(uint32_t) EMEmulateXor(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb);
327;
328; @returns EFLAGS after the operation, only arithmetic flags is valid.
329; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
330; @param [esp + 08h] Param 2 - Second parameter.
331; @param [esp + 0ch] Param 3 - Size of parameters, only 1/2/4 is valid.
332; @uses eax, ecx, edx
333;
334align 16
335BEGINPROC EMEmulateXor
336%ifdef RT_ARCH_AMD64
337%ifdef RT_OS_WINDOWS
338 mov rax, r8 ; eax = size of parameters
339%else ; !RT_OS_WINDOWS
340 mov rax, rdx ; rax = size of parameters
341 mov rcx, rdi ; rcx = first parameter
342 mov rdx, rsi ; rdx = second parameter
343%endif ; !RT_OS_WINDOWS
344%else ; !RT_ARCH_AMD64
345 mov eax, [esp + 0ch] ; eax = size of parameters
346 mov ecx, [esp + 04h] ; ecx = first parameter
347 mov edx, [esp + 08h] ; edx = second parameter
348%endif
349
350 ; switch on size
351%ifdef RT_ARCH_AMD64
352 cmp al, 8
353 je short .do_qword ; 8 bytes variant
354%endif
355 cmp al, 4
356 je short .do_dword ; 4 bytes variant
357 cmp al, 2
358 je short .do_word ; 2 byte variant
359 cmp al, 1
360 je short .do_byte ; 1 bytes variant
361 int3
362
363 ; workers
364%ifdef RT_ARCH_AMD64
365.do_qword:
366 xor [MY_PTR_REG], rdx ; do 8 bytes XOR
367 jmp short .done
368%endif
369
370.do_dword:
371 xor [MY_PTR_REG], edx ; do 4 bytes XOR
372 jmp short .done
373
374.do_word:
375 xor [MY_PTR_REG], dx ; do 2 bytes XOR
376 jmp short .done
377
378.do_byte:
379 xor [MY_PTR_REG], dl ; do 1 byte XOR
380
381 ; collect flags and return.
382.done:
383 pushf
384 pop MY_RET_REG
385 retn
386ENDPROC EMEmulateXor
387
388;;
389; Emulate INC instruction, CDECL calling conv.
390; EMDECL(uint32_t) EMEmulateInc(uint32_t *pu32Param1, size_t cb);
391;
392; @returns EFLAGS after the operation, only arithmetic flags are valid.
393; @param [esp + 04h] rdi rcx Param 1 - First parameter - pointer to data item.
394; @param [esp + 08h] rsi rdx Param 2 - Size of parameters, only 1/2/4 is valid.
395; @uses eax, ecx, edx
396;
397align 16
398BEGINPROC EMEmulateInc
399%ifdef RT_ARCH_AMD64
400%ifdef RT_OS_WINDOWS
401 mov rax, rdx ; eax = size of parameters
402%else ; !RT_OS_WINDOWS
403 mov rax, rsi ; eax = size of parameters
404 mov rcx, rdi ; rcx = first parameter
405%endif ; !RT_OS_WINDOWS
406%else ; !RT_ARCH_AMD64
407 mov eax, [esp + 08h] ; eax = size of parameters
408 mov ecx, [esp + 04h] ; ecx = first parameter
409%endif
410
411 ; switch on size
412%ifdef RT_ARCH_AMD64
413 cmp al, 8
414 je short .do_qword ; 8 bytes variant
415%endif
416 cmp al, 4
417 je short .do_dword ; 4 bytes variant
418 cmp al, 2
419 je short .do_word ; 2 byte variant
420 cmp al, 1
421 je short .do_byte ; 1 bytes variant
422 int3
423
424 ; workers
425%ifdef RT_ARCH_AMD64
426.do_qword:
427 inc qword [MY_PTR_REG] ; do 8 bytes INC
428 jmp short .done
429%endif
430
431.do_dword:
432 inc dword [MY_PTR_REG] ; do 4 bytes INC
433 jmp short .done
434
435.do_word:
436 inc word [MY_PTR_REG] ; do 2 bytes INC
437 jmp short .done
438
439.do_byte:
440 inc byte [MY_PTR_REG] ; do 1 byte INC
441 jmp short .done
442
443 ; collect flags and return.
444.done:
445 pushf
446 pop MY_RET_REG
447 retn
448ENDPROC EMEmulateInc
449
450
451;;
452; Emulate DEC instruction, CDECL calling conv.
453; EMDECL(uint32_t) EMEmulateDec(uint32_t *pu32Param1, size_t cb);
454;
455; @returns EFLAGS after the operation, only arithmetic flags are valid.
456; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
457; @param [esp + 08h] Param 2 - Size of parameters, only 1/2/4 is valid.
458; @uses eax, ecx, edx
459;
460align 16
461BEGINPROC EMEmulateDec
462%ifdef RT_ARCH_AMD64
463%ifdef RT_OS_WINDOWS
464 mov rax, rdx ; eax = size of parameters
465%else ; !RT_OS_WINDOWS
466 mov rax, rsi ; eax = size of parameters
467 mov rcx, rdi ; rcx = first parameter
468%endif ; !RT_OS_WINDOWS
469%else ; !RT_ARCH_AMD64
470 mov eax, [esp + 08h] ; eax = size of parameters
471 mov ecx, [esp + 04h] ; ecx = first parameter
472%endif
473
474 ; switch on size
475%ifdef RT_ARCH_AMD64
476 cmp al, 8
477 je short .do_qword ; 8 bytes variant
478%endif
479 cmp al, 4
480 je short .do_dword ; 4 bytes variant
481 cmp al, 2
482 je short .do_word ; 2 byte variant
483 cmp al, 1
484 je short .do_byte ; 1 bytes variant
485 int3
486
487 ; workers
488%ifdef RT_ARCH_AMD64
489.do_qword:
490 dec qword [MY_PTR_REG] ; do 8 bytes DEC
491 jmp short .done
492%endif
493
494.do_dword:
495 dec dword [MY_PTR_REG] ; do 4 bytes DEC
496 jmp short .done
497
498.do_word:
499 dec word [MY_PTR_REG] ; do 2 bytes DEC
500 jmp short .done
501
502.do_byte:
503 dec byte [MY_PTR_REG] ; do 1 byte DEC
504 jmp short .done
505
506 ; collect flags and return.
507.done:
508 pushf
509 pop MY_RET_REG
510 retn
511ENDPROC EMEmulateDec
512
513;;
514; Emulate ADD instruction, CDECL calling conv.
515; EMDECL(uint32_t) EMEmulateAdd(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb);
516;
517; @returns EFLAGS after the operation, only arithmetic flags is valid.
518; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
519; @param [esp + 08h] Param 2 - Second parameter.
520; @param [esp + 0ch] Param 3 - Size of parameters, only 1/2/4 is valid.
521; @uses eax, ecx, edx
522;
523align 16
524BEGINPROC EMEmulateAdd
525%ifdef RT_ARCH_AMD64
526%ifdef RT_OS_WINDOWS
527 mov rax, r8 ; eax = size of parameters
528%else ; !RT_OS_WINDOWS
529 mov rax, rdx ; rax = size of parameters
530 mov rcx, rdi ; rcx = first parameter
531 mov rdx, rsi ; rdx = second parameter
532%endif ; !RT_OS_WINDOWS
533%else ; !RT_ARCH_AMD64
534 mov eax, [esp + 0ch] ; eax = size of parameters
535 mov ecx, [esp + 04h] ; ecx = first parameter
536 mov edx, [esp + 08h] ; edx = second parameter
537%endif
538
539 ; switch on size
540%ifdef RT_ARCH_AMD64
541 cmp al, 8
542 je short .do_qword ; 8 bytes variant
543%endif
544 cmp al, 4
545 je short .do_dword ; 4 bytes variant
546 cmp al, 2
547 je short .do_word ; 2 byte variant
548 cmp al, 1
549 je short .do_byte ; 1 bytes variant
550 int3
551
552 ; workers
553%ifdef RT_ARCH_AMD64
554.do_qword:
555 add [MY_PTR_REG], rdx ; do 8 bytes ADD
556 jmp short .done
557%endif
558
559.do_dword:
560 add [MY_PTR_REG], edx ; do 4 bytes ADD
561 jmp short .done
562
563.do_word:
564 add [MY_PTR_REG], dx ; do 2 bytes ADD
565 jmp short .done
566
567.do_byte:
568 add [MY_PTR_REG], dl ; do 1 byte ADD
569
570 ; collect flags and return.
571.done:
572 pushf
573 pop MY_RET_REG
574 retn
575ENDPROC EMEmulateAdd
576
577;;
578; Emulate ADC instruction, CDECL calling conv.
579; EMDECL(uint32_t) EMEmulateAdcWithCarrySet(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb);
580;
581; @returns EFLAGS after the operation, only arithmetic flags is valid.
582; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
583; @param [esp + 08h] Param 2 - Second parameter.
584; @param [esp + 0ch] Param 3 - Size of parameters, only 1/2/4 is valid.
585; @uses eax, ecx, edx
586;
587align 16
588BEGINPROC EMEmulateAdcWithCarrySet
589%ifdef RT_ARCH_AMD64
590%ifdef RT_OS_WINDOWS
591 mov rax, r8 ; eax = size of parameters
592%else ; !RT_OS_WINDOWS
593 mov rax, rdx ; rax = size of parameters
594 mov rcx, rdi ; rcx = first parameter
595 mov rdx, rsi ; rdx = second parameter
596%endif ; !RT_OS_WINDOWS
597%else ; !RT_ARCH_AMD64
598 mov eax, [esp + 0ch] ; eax = size of parameters
599 mov ecx, [esp + 04h] ; ecx = first parameter
600 mov edx, [esp + 08h] ; edx = second parameter
601%endif
602
603 ; switch on size
604%ifdef RT_ARCH_AMD64
605 cmp al, 8
606 je short .do_qword ; 8 bytes variant
607%endif
608 cmp al, 4
609 je short .do_dword ; 4 bytes variant
610 cmp al, 2
611 je short .do_word ; 2 byte variant
612 cmp al, 1
613 je short .do_byte ; 1 bytes variant
614 int3
615
616 ; workers
617%ifdef RT_ARCH_AMD64
618.do_qword:
619 stc ; set carry flag
620 adc [MY_PTR_REG], rdx ; do 8 bytes ADC
621 jmp short .done
622%endif
623
624.do_dword:
625 stc ; set carry flag
626 adc [MY_PTR_REG], edx ; do 4 bytes ADC
627 jmp short .done
628
629.do_word:
630 stc ; set carry flag
631 adc [MY_PTR_REG], dx ; do 2 bytes ADC
632 jmp short .done
633
634.do_byte:
635 stc ; set carry flag
636 adc [MY_PTR_REG], dl ; do 1 byte ADC
637
638 ; collect flags and return.
639.done:
640 pushf
641 pop MY_RET_REG
642 retn
643ENDPROC EMEmulateAdcWithCarrySet
644
645;;
646; Emulate SUB instruction, CDECL calling conv.
647; EMDECL(uint32_t) EMEmulateSub(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb);
648;
649; @returns EFLAGS after the operation, only arithmetic flags is valid.
650; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
651; @param [esp + 08h] Param 2 - Second parameter.
652; @param [esp + 0ch] Param 3 - Size of parameters, only 1/2/4 is valid.
653; @uses eax, ecx, edx
654;
655align 16
656BEGINPROC EMEmulateSub
657%ifdef RT_ARCH_AMD64
658%ifdef RT_OS_WINDOWS
659 mov rax, r8 ; eax = size of parameters
660%else ; !RT_OS_WINDOWS
661 mov rax, rdx ; rax = size of parameters
662 mov rcx, rdi ; rcx = first parameter
663 mov rdx, rsi ; rdx = second parameter
664%endif ; !RT_OS_WINDOWS
665%else ; !RT_ARCH_AMD64
666 mov eax, [esp + 0ch] ; eax = size of parameters
667 mov ecx, [esp + 04h] ; ecx = first parameter
668 mov edx, [esp + 08h] ; edx = second parameter
669%endif
670
671 ; switch on size
672%ifdef RT_ARCH_AMD64
673 cmp al, 8
674 je short .do_qword ; 8 bytes variant
675%endif
676 cmp al, 4
677 je short .do_dword ; 4 bytes variant
678 cmp al, 2
679 je short .do_word ; 2 byte variant
680 cmp al, 1
681 je short .do_byte ; 1 bytes variant
682 int3
683
684 ; workers
685%ifdef RT_ARCH_AMD64
686.do_qword:
687 sub [MY_PTR_REG], rdx ; do 8 bytes SUB
688 jmp short .done
689%endif
690
691.do_dword:
692 sub [MY_PTR_REG], edx ; do 4 bytes SUB
693 jmp short .done
694
695.do_word:
696 sub [MY_PTR_REG], dx ; do 2 bytes SUB
697 jmp short .done
698
699.do_byte:
700 sub [MY_PTR_REG], dl ; do 1 byte SUB
701
702 ; collect flags and return.
703.done:
704 pushf
705 pop MY_RET_REG
706 retn
707ENDPROC EMEmulateSub
708
709
710;;
711; Emulate BTR instruction, CDECL calling conv.
712; EMDECL(uint32_t) EMEmulateBtr(uint32_t *pu32Param1, uint32_t u32Param2);
713;
714; @returns EFLAGS after the operation, only arithmetic flags is valid.
715; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
716; @param [esp + 08h] Param 2 - Second parameter.
717; @uses eax, ecx, edx
718;
719align 16
720BEGINPROC EMEmulateBtr
721%ifdef RT_ARCH_AMD64
722%ifndef RT_OS_WINDOWS
723 mov rcx, rdi ; rcx = first parameter
724 mov rdx, rsi ; rdx = second parameter
725%endif ; !RT_OS_WINDOWS
726%else ; !RT_ARCH_AMD64
727 mov ecx, [esp + 04h] ; ecx = first parameter
728 mov edx, [esp + 08h] ; edx = second parameter
729%endif
730
731 and edx, 7
732 btr [MY_PTR_REG], edx
733
734 ; collect flags and return.
735 pushf
736 pop MY_RET_REG
737 retn
738ENDPROC EMEmulateBtr
739
740;;
741; Emulate LOCK BTR instruction.
742; EMDECL(int) EMEmulateLockBtr(RTGCPTR GCPtrParam1, RTGCUINTREG Param2, uint32_t *pf);
743;
744; @returns VINF_SUCCESS on success, VERR_ACCESS_DENIED on \#PF (GC only).
745; @param [esp + 04h] gcc:rdi msc:rcx Param 1 - First parameter - pointer to data item (the real stuff).
746; @param [esp + 08h] gcc:rsi msc:rdx Param 2 - Second parameter- the immediate / register value. (really an 8 byte value)
747; @param [esp + 0ch] gcc:rdx msc:r8 Param 3 - Where to store the eflags on success.
748;
749align 16
750BEGINPROC EMEmulateLockBtr
751%ifdef RT_ARCH_AMD64
752 %ifdef RT_OS_WINDOWS
753 mov rax, r8 ; rax = third parameter
754 %else ; !RT_OS_WINDOWS
755 mov rcx, rdi ; rcx = first parameter
756 mov rax, rdx ; rax = third parameter
757 mov rdx, rsi ; rdx = second parameter
758 %endif ; !RT_OS_WINDOWS
759%else ; !RT_ARCH_AMD64
760 mov ecx, [esp + 04h] ; ecx = first parameter
761 mov edx, [esp + 08h] ; edx = second parameter
762 mov eax, [esp + 0ch] ; eax = third parameter
763%endif
764
765 lock btr [MY_PTR_REG], edx
766
767 ; collect flags and return.
768 pushf
769 pop xDX
770 mov [xAX], edx
771 mov eax, VINF_SUCCESS
772 retn
773
774%ifdef IN_GC
775; #PF resume point.
776GLOBALNAME EMEmulateLockBtr_Error
777 mov eax, VERR_ACCESS_DENIED
778 ret
779%endif
780
781ENDPROC EMEmulateLockBtr
782
783;;
784; Emulate BTC instruction, CDECL calling conv.
785; EMDECL(uint32_t) EMEmulateBtc(uint32_t *pu32Param1, uint32_t u32Param2);
786;
787; @returns EFLAGS after the operation, only arithmetic flags is valid.
788; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
789; @param [esp + 08h] Param 2 - Second parameter.
790; @uses eax, ecx, edx
791;
792align 16
793BEGINPROC EMEmulateBtc
794%ifdef RT_ARCH_AMD64
795%ifndef RT_OS_WINDOWS
796 mov rcx, rdi ; rcx = first parameter
797 mov rdx, rsi ; rdx = second parameter
798%endif ; !RT_OS_WINDOWS
799%else ; !RT_ARCH_AMD64
800 mov ecx, [esp + 04h] ; ecx = first parameter
801 mov edx, [esp + 08h] ; edx = second parameter
802%endif
803
804 and edx, 7
805 btc [MY_PTR_REG], edx
806
807 ; collect flags and return.
808 pushf
809 pop MY_RET_REG
810 retn
811ENDPROC EMEmulateBtc
812
813;;
814; Emulate BTS instruction, CDECL calling conv.
815; EMDECL(uint32_t) EMEmulateBts(uint32_t *pu32Param1, uint32_t u32Param2);
816;
817; @returns EFLAGS after the operation, only arithmetic flags are valid.
818; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
819; @param [esp + 08h] Param 2 - Second parameter.
820; @uses eax, ecx, edx
821;
822align 16
823BEGINPROC EMEmulateBts
824%ifdef RT_ARCH_AMD64
825%ifndef RT_OS_WINDOWS
826 mov rcx, rdi ; rcx = first parameter
827 mov rdx, rsi ; rdx = second parameter
828%endif ; !RT_OS_WINDOWS
829%else ; !RT_ARCH_AMD64
830 mov ecx, [esp + 04h] ; ecx = first parameter
831 mov edx, [esp + 08h] ; edx = second parameter
832%endif
833
834 and edx, 7
835 bts [MY_PTR_REG], edx
836
837 ; collect flags and return.
838 pushf
839 pop MY_RET_REG
840 retn
841ENDPROC EMEmulateBts
842
843
844%if 0
845;;
846; Emulate LOCK CMPXCHG instruction, CDECL calling conv.
847; EMDECL(uint32_t) EMEmulateLockCmpXchg32(RTHCPTR pu32Param1, uint32_t *pu32Param2, uint32_t u32Param3, size_t cbSize);
848;
849; @returns EFLAGS after the operation, only arithmetic flags is valid.
850; @param [esp + 04h] gcc:rdi msc:rcx Param 1 - First parameter - pointer to first parameter
851; @param [esp + 08h] gcc:rsi msc:rdx Param 2 - pointer to second parameter (eax)
852; @param [esp + 0ch] gcc:rdx msc:r8 Param 3 - third parameter
853; @param [esp + 10h] gcc:rcx msc:r9 Param 4 - Size of parameters, only 1/2/4 is valid
854; @uses eax, ecx, edx
855;
856align 16
857BEGINPROC EMEmulateLockCmpXchg32
858 push ebx
859 mov ecx, [esp + 04h + 4] ; ecx = first parameter
860 mov ebx, [esp + 08h + 4] ; ebx = 2nd parameter (eax)
861 mov edx, [esp + 0ch + 4] ; edx = third parameter
862 mov eax, [esp + 10h + 4] ; eax = size of parameters
863
864 cmp al, 4
865 je short .do_dword ; 4 bytes variant
866 cmp al, 2
867 je short .do_word ; 2 byte variant
868 cmp al, 1
869 je short .do_byte ; 1 bytes variant
870 int3
871
872.do_dword:
873 ; load 2nd parameter's value
874 mov eax, dword [ebx]
875
876 lock cmpxchg dword [ecx], edx ; do 4 bytes CMPXCHG
877 mov dword [ebx], eax
878 jmp short .done
879
880.do_word:
881 ; load 2nd parameter's value
882 mov eax, dword [ebx]
883
884 lock cmpxchg word [ecx], dx ; do 2 bytes CMPXCHG
885 mov word [ebx], ax
886 jmp short .done
887
888.do_byte:
889 ; load 2nd parameter's value
890 mov eax, dword [ebx]
891
892 lock cmpxchg byte [ecx], dl ; do 1 bytes CMPXCHG
893 mov byte [ebx], al
894
895.done:
896 ; collect flags and return.
897 pushf
898 pop eax
899
900 mov edx, [esp + 14h + 4] ; eflags pointer
901 mov dword [edx], eax
902
903 pop ebx
904 mov eax, VINF_SUCCESS
905 retn
906
907; Read error - we will be here after our page fault handler.
908GLOBALNAME EMEmulateLockCmpXchg32_Error
909 pop ebx
910 mov eax, VERR_ACCESS_DENIED
911 ret
912
913ENDPROC EMEmulateLockCmpXchg32
914
915;;
916; Emulate CMPXCHG instruction, CDECL calling conv.
917; EMDECL(uint32_t) EMEmulateCmpXchg32(RTHCPTR pu32Param1, uint32_t *pu32Param2, uint32_t u32Param3, size_t cbSize);
918;
919; @returns EFLAGS after the operation, only arithmetic flags is valid.
920; @param [esp + 04h] gcc:rdi msc:rcx Param 1 - First parameter - pointer to first parameter
921; @param [esp + 08h] gcc:rsi msc:rdx Param 2 - pointer to second parameter (eax)
922; @param [esp + 0ch] gcc:rdx msc:r8 Param 3 - third parameter
923; @param [esp + 10h] gcc:rcx msc:r9 Param 4 - Size of parameters, only 1/2/4 is valid.
924; @uses eax, ecx, edx
925;
926align 16
927BEGINPROC EMEmulateCmpXchg32
928 push ebx
929 mov ecx, [esp + 04h + 4] ; ecx = first parameter
930 mov ebx, [esp + 08h + 4] ; ebx = 2nd parameter (eax)
931 mov edx, [esp + 0ch + 4] ; edx = third parameter
932 mov eax, [esp + 10h + 4] ; eax = size of parameters
933
934 cmp al, 4
935 je short .do_dword ; 4 bytes variant
936 cmp al, 2
937 je short .do_word ; 2 byte variant
938 cmp al, 1
939 je short .do_byte ; 1 bytes variant
940 int3
941
942.do_dword:
943 ; load 2nd parameter's value
944 mov eax, dword [ebx]
945
946 cmpxchg dword [ecx], edx ; do 4 bytes CMPXCHG
947 mov dword [ebx], eax
948 jmp short .done
949
950.do_word:
951 ; load 2nd parameter's value
952 mov eax, dword [ebx]
953
954 cmpxchg word [ecx], dx ; do 2 bytes CMPXCHG
955 mov word [ebx], ax
956 jmp short .done
957
958.do_byte:
959 ; load 2nd parameter's value
960 mov eax, dword [ebx]
961
962 cmpxchg byte [ecx], dl ; do 1 bytes CMPXCHG
963 mov byte [ebx], al
964
965.done:
966 ; collect flags and return.
967 pushf
968 pop eax
969
970 mov edx, [esp + 14h + 4] ; eflags pointer
971 mov dword [edx], eax
972
973 pop ebx
974 mov eax, VINF_SUCCESS
975 retn
976
977; Read error - we will be here after our page fault handler.
978GLOBALNAME EMEmulateCmpXchg32_Error
979 pop ebx
980 mov eax, VERR_ACCESS_DENIED
981 ret
982ENDPROC EMEmulateCmpXchg32
983
984;;
985; Emulate LOCK CMPXCHG8B instruction, CDECL calling conv.
986; EMDECL(uint32_t) EMEmulateLockCmpXchg8b(RTHCPTR pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX);
987;
988; @returns EFLAGS after the operation, only arithmetic flags is valid.
989; @param [esp + 04h] Param 1 - First parameter - pointer to first parameter
990; @param [esp + 08h] Param 2 - Address of the eax register
991; @param [esp + 0ch] Param 3 - Address of the edx register
992; @param [esp + 10h] Param 4 - EBX
993; @param [esp + 14h] Param 5 - ECX
994; @uses eax, ecx, edx
995;
996align 16
997BEGINPROC EMEmulateLockCmpXchg8b32
998 push ebp
999 push ebx
1000 mov ebp, [esp + 04h + 8] ; ebp = first parameter
1001 mov eax, [esp + 08h + 8] ; &EAX
1002 mov eax, dword [eax]
1003 mov edx, [esp + 0ch + 8] ; &EDX
1004 mov edx, dword [edx]
1005 mov ebx, [esp + 10h + 8] ; EBX
1006 mov ecx, [esp + 14h + 8] ; ECX
1007
1008 lock cmpxchg8b qword [ebp] ; do CMPXCHG8B
1009 mov dword [esp + 08h + 8], eax
1010 mov dword [esp + 0ch + 8], edx
1011
1012 ; collect flags and return.
1013 pushf
1014 pop eax
1015
1016 mov edx, [esp + 18h + 8] ; eflags pointer
1017 mov dword [edx], eax
1018
1019 pop ebx
1020 pop ebp
1021 mov eax, VINF_SUCCESS
1022 retn
1023
1024; Read error - we will be here after our page fault handler.
1025GLOBALNAME EMEmulateLockCmpXchg8b32_Error
1026 pop ebx
1027 pop ebp
1028 mov eax, VERR_ACCESS_DENIED
1029 ret
1030
1031ENDPROC EMEmulateLockCmpXchg8b32
1032
1033;;
1034; Emulate CMPXCHG8B instruction, CDECL calling conv.
1035; EMDECL(uint32_t) EMEmulateCmpXchg8b32(RTHCPTR pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX);
1036;
1037; @returns EFLAGS after the operation, only arithmetic flags is valid.
1038; @param [esp + 04h] Param 1 - First parameter - pointer to first parameter
1039; @param [esp + 08h] Param 2 - Address of the eax register
1040; @param [esp + 0ch] Param 3 - Address of the edx register
1041; @param [esp + 10h] Param 4 - EBX
1042; @param [esp + 14h] Param 5 - ECX
1043; @uses eax, ecx, edx
1044;
1045align 16
1046BEGINPROC EMEmulateCmpXchg8b32
1047 push ebp
1048 push ebx
1049 mov ebp, [esp + 04h + 8] ; ebp = first parameter
1050 mov eax, [esp + 08h + 8] ; &EAX
1051 mov eax, dword [eax]
1052 mov edx, [esp + 0ch + 8] ; &EDX
1053 mov edx, dword [edx]
1054 mov ebx, [esp + 10h + 8] ; EBX
1055 mov ecx, [esp + 14h + 8] ; ECX
1056
1057 cmpxchg8b qword [ebp] ; do CMPXCHG8B
1058 mov dword [esp + 08h + 8], eax
1059 mov dword [esp + 0ch + 8], edx
1060
1061 ; collect flags and return.
1062 pushf
1063 pop eax
1064
1065 mov edx, [esp + 18h + 8] ; eflags pointer
1066 mov dword [edx], eax
1067
1068 pop ebx
1069 pop ebp
1070 mov eax, VINF_SUCCESS
1071 retn
1072
1073; Read error - we will be here after our page fault handler.
1074GLOBALNAME EMEmulateCmpXchg8b32_Error
1075 pop ebx
1076 pop ebp
1077 mov eax, VERR_ACCESS_DENIED
1078 ret
1079ENDPROC EMEmulateCmpXchg8b32
1080
1081%endif
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