VirtualBox

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

Last change on this file since 1986 was 1986, checked in by vboxsync, 18 years ago

Btr emulation added. (possibly dangerous; not well tested)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 18.6 KB
Line 
1; $Id: EMAllA.asm 1986 2007-04-09 10:22:30Z vboxsync $
2;; @file
3; EM Assembly Routines.
4;
5
6;
7; Copyright (C) 2006 InnoTek Systemberatung 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 as published by the Free Software Foundation,
13; in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14; distribution. VirtualBox OSE is distributed in the hope that it will
15; be useful, but WITHOUT ANY WARRANTY of any kind.
16;
17; If you received this file as part of a commercial VirtualBox
18; distribution, then only the terms of your commercial VirtualBox
19; license agreement apply instead of the previous paragraph.
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 __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 __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 __AMD64__
60%ifdef __WIN64__
61 mov rax, r8 ; eax = size of parameters
62%else ; !__WIN64__
63 mov rax, rdx ; rax = size of parameters
64 mov rcx, rdi ; rcx = first parameter
65 mov rdx, rsi ; rdx = second parameter
66%endif ; !__WIN64__
67%else ; !__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 __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 __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 __AMD64__
125%ifdef __WIN64__
126 mov rax, r8 ; eax = size of parameters
127%else ; !__WIN64__
128 mov rax, rdx ; rax = size of parameters
129 mov rcx, rdi ; rcx = first parameter
130 mov rdx, rsi ; rdx = second parameter
131%endif ; !__WIN64__
132%else ; !__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 __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 __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 __AMD64__
190%ifdef __WIN64__
191 mov rax, r8 ; eax = size of parameters
192%else ; !__WIN64__
193 mov rax, rdx ; rax = size of parameters
194 mov rcx, rdi ; rcx = first parameter
195 mov rdx, rsi ; rdx = second parameter
196%endif ; !__WIN64__
197%else ; !__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 __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 __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 XOR instruction, CDECL calling conv.
243; EMDECL(uint32_t) EMEmulateXor(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb);
244;
245; @returns EFLAGS after the operation, only arithmetic flags is valid.
246; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
247; @param [esp + 08h] Param 2 - Second parameter.
248; @param [esp + 0ch] Param 3 - Size of parameters, only 1/2/4 is valid.
249; @uses eax, ecx, edx
250;
251align 16
252BEGINPROC EMEmulateXor
253%ifdef __AMD64__
254%ifdef __WIN64__
255 mov rax, r8 ; eax = size of parameters
256%else ; !__WIN64__
257 mov rax, rdx ; rax = size of parameters
258 mov rcx, rdi ; rcx = first parameter
259 mov rdx, rsi ; rdx = second parameter
260%endif ; !__WIN64__
261%else ; !__AMD64__
262 mov eax, [esp + 0ch] ; eax = size of parameters
263 mov ecx, [esp + 04h] ; ecx = first parameter
264 mov edx, [esp + 08h] ; edx = second parameter
265%endif
266
267 ; switch on size
268%ifdef __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 __AMD64__
282.do_qword:
283 xor [MY_PTR_REG], rdx ; do 8 bytes XOR
284 jmp short .done
285%endif
286
287.do_dword:
288 xor [MY_PTR_REG], edx ; do 4 bytes XOR
289 jmp short .done
290
291.do_word:
292 xor [MY_PTR_REG], dx ; do 2 bytes XOR
293 jmp short .done
294
295.do_byte:
296 xor [MY_PTR_REG], dl ; do 1 byte XOR
297
298 ; collect flags and return.
299.done:
300 pushf
301 pop MY_RET_REG
302 retn
303ENDPROC EMEmulateXor
304
305;;
306; Emulate INC instruction, CDECL calling conv.
307; EMDECL(uint32_t) EMEmulateInc(uint32_t *pu32Param1, size_t cb);
308;
309; @returns EFLAGS after the operation, only arithmetic flags are valid.
310; @param [esp + 04h] rdi rcx Param 1 - First parameter - pointer to data item.
311; @param [esp + 08h] rsi rdx Param 2 - Size of parameters, only 1/2/4 is valid.
312; @uses eax, ecx, edx
313;
314align 16
315BEGINPROC EMEmulateInc
316%ifdef __AMD64__
317%ifdef __WIN64__
318 mov rax, rdx ; eax = size of parameters
319%else ; !__WIN64__
320 mov rax, rsi ; eax = size of parameters
321 mov rcx, rdi ; rcx = first parameter
322%endif ; !__WIN64__
323%else ; !__AMD64__
324 mov eax, [esp + 08h] ; eax = size of parameters
325 mov ecx, [esp + 04h] ; ecx = first parameter
326%endif
327
328 ; switch on size
329%ifdef __AMD64__
330 cmp al, 8
331 je short .do_qword ; 8 bytes variant
332%endif
333 cmp al, 4
334 je short .do_dword ; 4 bytes variant
335 cmp al, 2
336 je short .do_word ; 2 byte variant
337 cmp al, 1
338 je short .do_byte ; 1 bytes variant
339 int3
340
341 ; workers
342%ifdef __AMD64__
343.do_qword:
344 inc qword [MY_PTR_REG] ; do 8 bytes INC
345 jmp short .done
346%endif
347
348.do_dword:
349 inc dword [MY_PTR_REG] ; do 4 bytes INC
350 jmp short .done
351
352.do_word:
353 inc word [MY_PTR_REG] ; do 2 bytes INC
354 jmp short .done
355
356.do_byte:
357 inc byte [MY_PTR_REG] ; do 1 byte INC
358 jmp short .done
359
360 ; collect flags and return.
361.done:
362 pushf
363 pop MY_RET_REG
364 retn
365ENDPROC EMEmulateInc
366
367
368;;
369; Emulate DEC instruction, CDECL calling conv.
370; EMDECL(uint32_t) EMEmulateDec(uint32_t *pu32Param1, size_t cb);
371;
372; @returns EFLAGS after the operation, only arithmetic flags are valid.
373; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
374; @param [esp + 08h] Param 2 - Size of parameters, only 1/2/4 is valid.
375; @uses eax, ecx, edx
376;
377align 16
378BEGINPROC EMEmulateDec
379%ifdef __AMD64__
380%ifdef __WIN64__
381 mov rax, rdx ; eax = size of parameters
382%else ; !__WIN64__
383 mov rax, rsi ; eax = size of parameters
384 mov rcx, rdi ; rcx = first parameter
385%endif ; !__WIN64__
386%else ; !__AMD64__
387 mov eax, [esp + 08h] ; eax = size of parameters
388 mov ecx, [esp + 04h] ; ecx = first parameter
389%endif
390
391 ; switch on size
392%ifdef __AMD64__
393 cmp al, 8
394 je short .do_qword ; 8 bytes variant
395%endif
396 cmp al, 4
397 je short .do_dword ; 4 bytes variant
398 cmp al, 2
399 je short .do_word ; 2 byte variant
400 cmp al, 1
401 je short .do_byte ; 1 bytes variant
402 int3
403
404 ; workers
405%ifdef __AMD64__
406.do_qword:
407 dec qword [MY_PTR_REG] ; do 8 bytes DEC
408 jmp short .done
409%endif
410
411.do_dword:
412 dec dword [MY_PTR_REG] ; do 4 bytes DEC
413 jmp short .done
414
415.do_word:
416 dec word [MY_PTR_REG] ; do 2 bytes DEC
417 jmp short .done
418
419.do_byte:
420 dec byte [MY_PTR_REG] ; do 1 byte DEC
421 jmp short .done
422
423 ; collect flags and return.
424.done:
425 pushf
426 pop MY_RET_REG
427 retn
428ENDPROC EMEmulateDec
429
430;;
431; Emulate ADD instruction, CDECL calling conv.
432; EMDECL(uint32_t) EMEmulateAdd(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb);
433;
434; @returns EFLAGS after the operation, only arithmetic flags is valid.
435; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
436; @param [esp + 08h] Param 2 - Second parameter.
437; @param [esp + 0ch] Param 3 - Size of parameters, only 1/2/4 is valid.
438; @uses eax, ecx, edx
439;
440align 16
441BEGINPROC EMEmulateAdd
442%ifdef __AMD64__
443%ifdef __WIN64__
444 mov rax, r8 ; eax = size of parameters
445%else ; !__WIN64__
446 mov rax, rdx ; rax = size of parameters
447 mov rcx, rdi ; rcx = first parameter
448 mov rdx, rsi ; rdx = second parameter
449%endif ; !__WIN64__
450%else ; !__AMD64__
451 mov eax, [esp + 0ch] ; eax = size of parameters
452 mov ecx, [esp + 04h] ; ecx = first parameter
453 mov edx, [esp + 08h] ; edx = second parameter
454%endif
455
456 ; switch on size
457%ifdef __AMD64__
458 cmp al, 8
459 je short .do_qword ; 8 bytes variant
460%endif
461 cmp al, 4
462 je short .do_dword ; 4 bytes variant
463 cmp al, 2
464 je short .do_word ; 2 byte variant
465 cmp al, 1
466 je short .do_byte ; 1 bytes variant
467 int3
468
469 ; workers
470%ifdef __AMD64__
471.do_qword:
472 add [MY_PTR_REG], rdx ; do 8 bytes ADD
473 jmp short .done
474%endif
475
476.do_dword:
477 add [MY_PTR_REG], edx ; do 4 bytes ADD
478 jmp short .done
479
480.do_word:
481 add [MY_PTR_REG], dx ; do 2 bytes ADD
482 jmp short .done
483
484.do_byte:
485 add [MY_PTR_REG], dl ; do 1 byte ADD
486
487 ; collect flags and return.
488.done:
489 pushf
490 pop MY_RET_REG
491 retn
492ENDPROC EMEmulateAdd
493
494;;
495; Emulate ADC instruction, CDECL calling conv.
496; EMDECL(uint32_t) EMEmulateAdcWithCarrySet(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb);
497;
498; @returns EFLAGS after the operation, only arithmetic flags is valid.
499; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
500; @param [esp + 08h] Param 2 - Second parameter.
501; @param [esp + 0ch] Param 3 - Size of parameters, only 1/2/4 is valid.
502; @uses eax, ecx, edx
503;
504align 16
505BEGINPROC EMEmulateAdcWithCarrySet
506%ifdef __AMD64__
507%ifdef __WIN64__
508 mov rax, r8 ; eax = size of parameters
509%else ; !__WIN64__
510 mov rax, rdx ; rax = size of parameters
511 mov rcx, rdi ; rcx = first parameter
512 mov rdx, rsi ; rdx = second parameter
513%endif ; !__WIN64__
514%else ; !__AMD64__
515 mov eax, [esp + 0ch] ; eax = size of parameters
516 mov ecx, [esp + 04h] ; ecx = first parameter
517 mov edx, [esp + 08h] ; edx = second parameter
518%endif
519
520 ; switch on size
521%ifdef __AMD64__
522 cmp al, 8
523 je short .do_qword ; 8 bytes variant
524%endif
525 cmp al, 4
526 je short .do_dword ; 4 bytes variant
527 cmp al, 2
528 je short .do_word ; 2 byte variant
529 cmp al, 1
530 je short .do_byte ; 1 bytes variant
531 int3
532
533 ; workers
534%ifdef __AMD64__
535.do_qword:
536 stc ; set carry flag
537 adc [MY_PTR_REG], rdx ; do 8 bytes ADC
538 jmp short .done
539%endif
540
541.do_dword:
542 stc ; set carry flag
543 adc [MY_PTR_REG], edx ; do 4 bytes ADC
544 jmp short .done
545
546.do_word:
547 stc ; set carry flag
548 adc [MY_PTR_REG], dx ; do 2 bytes ADC
549 jmp short .done
550
551.do_byte:
552 stc ; set carry flag
553 adc [MY_PTR_REG], dl ; do 1 byte ADC
554
555 ; collect flags and return.
556.done:
557 pushf
558 pop MY_RET_REG
559 retn
560ENDPROC EMEmulateAdcWithCarrySet
561
562;;
563; Emulate SUB instruction, CDECL calling conv.
564; EMDECL(uint32_t) EMEmulateSub(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb);
565;
566; @returns EFLAGS after the operation, only arithmetic flags is valid.
567; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
568; @param [esp + 08h] Param 2 - Second parameter.
569; @param [esp + 0ch] Param 3 - Size of parameters, only 1/2/4 is valid.
570; @uses eax, ecx, edx
571;
572align 16
573BEGINPROC EMEmulateSub
574%ifdef __AMD64__
575%ifdef __WIN64__
576 mov rax, r8 ; eax = size of parameters
577%else ; !__WIN64__
578 mov rax, rdx ; rax = size of parameters
579 mov rcx, rdi ; rcx = first parameter
580 mov rdx, rsi ; rdx = second parameter
581%endif ; !__WIN64__
582%else ; !__AMD64__
583 mov eax, [esp + 0ch] ; eax = size of parameters
584 mov ecx, [esp + 04h] ; ecx = first parameter
585 mov edx, [esp + 08h] ; edx = second parameter
586%endif
587
588 ; switch on size
589%ifdef __AMD64__
590 cmp al, 8
591 je short .do_qword ; 8 bytes variant
592%endif
593 cmp al, 4
594 je short .do_dword ; 4 bytes variant
595 cmp al, 2
596 je short .do_word ; 2 byte variant
597 cmp al, 1
598 je short .do_byte ; 1 bytes variant
599 int3
600
601 ; workers
602%ifdef __AMD64__
603.do_qword:
604 sub [MY_PTR_REG], rdx ; do 8 bytes SUB
605 jmp short .done
606%endif
607
608.do_dword:
609 sub [MY_PTR_REG], edx ; do 4 bytes SUB
610 jmp short .done
611
612.do_word:
613 sub [MY_PTR_REG], dx ; do 2 bytes SUB
614 jmp short .done
615
616.do_byte:
617 sub [MY_PTR_REG], dl ; do 1 byte SUB
618
619 ; collect flags and return.
620.done:
621 pushf
622 pop MY_RET_REG
623 retn
624ENDPROC EMEmulateSub
625
626
627;;
628; Emulate BTR instruction, CDECL calling conv.
629; EMDECL(uint32_t) EMEmulateBtr(uint32_t *pu32Param1, uint32_t u32Param2);
630;
631; @returns EFLAGS after the operation, only arithmetic flags is valid.
632; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
633; @param [esp + 08h] Param 2 - Second parameter.
634; @uses eax, ecx, edx
635;
636align 16
637BEGINPROC EMEmulateBtr
638%ifdef __AMD64__
639%ifndef __WIN64__
640 mov rcx, rdi ; rcx = first parameter
641 mov rdx, rsi ; rdx = second parameter
642%endif ; !__WIN64__
643%else ; !__AMD64__
644 mov ecx, [esp + 04h] ; ecx = first parameter
645 mov edx, [esp + 08h] ; edx = second parameter
646%endif
647
648 and edx, 7
649 btr [MY_PTR_REG], edx
650
651 ; collect flags and return.
652 pushf
653 pop MY_RET_REG
654 retn
655ENDPROC EMEmulateBtr
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