Index: trunk/src/VBox/VMM/VMMAll/EMAllA.asm
===================================================================
--- trunk/src/VBox/VMM/VMMAll/EMAllA.asm	(revision 11507)
+++ trunk/src/VBox/VMM/VMMAll/EMAllA.asm	(revision 11508)
@@ -50,5 +50,5 @@
 ; EMDECL(uint32_t) EMEmulateCmp(uint32_t u32Param1, uint64_t u64Param2, size_t cb);
 ;
-; @returns EFLAGS after the operation, only arithmetic flags is valid.
+; @returns EFLAGS after the operation, only arithmetic flags are valid.
 ; @param    [esp + 04h]  rdi  rcx       Param 1 - First parameter (Dst).
 ; @param    [esp + 08h]  rsi  edx       Param 2 - Second parameter (Src).
@@ -114,5 +114,5 @@
 ; EMDECL(uint32_t) EMEmulateAnd(void *pvParam1, uint64_t u64Param2, size_t cb);
 ;
-; @returns EFLAGS after the operation, only arithmetic flags is valid.
+; @returns EFLAGS after the operation, only arithmetic flags are valid.
 ; @param    [esp + 04h]    Param 1 - First parameter - pointer to data item.
 ; @param    [esp + 08h]    Param 2 - Second parameter.
@@ -179,5 +179,5 @@
 ; EMDECL(uint32_t) EMEmulateOr(void *pvParam1, uint64_t u64Param2, size_t cb);
 ;
-; @returns EFLAGS after the operation, only arithmetic flags is valid.
+; @returns EFLAGS after the operation, only arithmetic flags are valid.
 ; @param    [esp + 04h]    Param 1 - First parameter - pointer to data item.
 ; @param    [esp + 08h]    Param 2 - Second parameter.
@@ -326,5 +326,5 @@
 ; EMDECL(uint32_t) EMEmulateXor(void *pvParam1, uint64_t u64Param2, size_t cb);
 ;
-; @returns EFLAGS after the operation, only arithmetic flags is valid.
+; @returns EFLAGS after the operation, only arithmetic flags are valid.
 ; @param    [esp + 04h]    Param 1 - First parameter - pointer to data item.
 ; @param    [esp + 08h]    Param 2 - Second parameter.
@@ -515,5 +515,5 @@
 ; EMDECL(uint32_t) EMEmulateAdd(void *pvParam1, uint64_t u64Param2, size_t cb);
 ;
-; @returns EFLAGS after the operation, only arithmetic flags is valid.
+; @returns EFLAGS after the operation, only arithmetic flags are valid.
 ; @param    [esp + 04h]    Param 1 - First parameter - pointer to data item.
 ; @param    [esp + 08h]    Param 2 - Second parameter.
@@ -579,5 +579,5 @@
 ; EMDECL(uint32_t) EMEmulateAdcWithCarrySet(void *pvParam1, uint64_t u64Param2, size_t cb);
 ;
-; @returns EFLAGS after the operation, only arithmetic flags is valid.
+; @returns EFLAGS after the operation, only arithmetic flags are valid.
 ; @param    [esp + 04h]    Param 1 - First parameter - pointer to data item.
 ; @param    [esp + 08h]    Param 2 - Second parameter.
@@ -647,5 +647,5 @@
 ; EMDECL(uint32_t) EMEmulateSub(void *pvParam1, uint64_t u64Param2, size_t cb);
 ;
-; @returns EFLAGS after the operation, only arithmetic flags is valid.
+; @returns EFLAGS after the operation, only arithmetic flags are valid.
 ; @param    [esp + 04h]    Param 1 - First parameter - pointer to data item.
 ; @param    [esp + 08h]    Param 2 - Second parameter.
@@ -712,5 +712,5 @@
 ; EMDECL(uint32_t) EMEmulateBtr(void *pvParam1, uint64_t u64Param2);
 ;
-; @returns EFLAGS after the operation, only arithmetic flags is valid.
+; @returns EFLAGS after the operation, only arithmetic flags are valid.
 ; @param    [esp + 04h]    Param 1 - First parameter - pointer to data item.
 ; @param    [esp + 08h]    Param 2 - Second parameter.
@@ -785,5 +785,5 @@
 ; EMDECL(uint32_t) EMEmulateBtc(void *pvParam1, uint64_t u64Param2);
 ;
-; @returns EFLAGS after the operation, only arithmetic flags is valid.
+; @returns EFLAGS after the operation, only arithmetic flags are valid.
 ; @param    [esp + 04h]    Param 1 - First parameter - pointer to data item.
 ; @param    [esp + 08h]    Param 2 - Second parameter.
@@ -842,26 +842,41 @@
 
 
-%if 0
-;; untested code!!
-
 ;;
 ; Emulate LOCK CMPXCHG instruction, CDECL calling conv.
-; EMDECL(uint32_t) EMEmulateLockCmpXchg32(RTHCPTR pu32Param1, uint32_t *pu32Param2, uint32_t u32Param3, size_t cbSize);
-;
-; @returns EFLAGS after the operation, only arithmetic flags is valid.
+; EMDECL(uint32_t) EMEmulateLockCmpXchg(void *pvParam1, uint64_t *pu64Param2, uint64_t u64Param3, size_t cbSize);
+;
+; @returns EFLAGS after the operation, only arithmetic flags are valid.
 ; @param    [esp + 04h]  gcc:rdi  msc:rcx   Param 1 - First parameter - pointer to first parameter
 ; @param    [esp + 08h]  gcc:rsi  msc:rdx   Param 2 - pointer to second parameter (eax)
 ; @param    [esp + 0ch]  gcc:rdx  msc:r8    Param 3 - third parameter
-; @param    [esp + 10h]  gcc:rcx  msc:r9    Param 4 - Size of parameters, only 1/2/4 is valid
-; @uses     eax, ecx, edx
-;
-align 16
-BEGINPROC   EMEmulateLockCmpXchg32
-    push    ebx
+; @param    [esp + 14h]  gcc:rcx  msc:r9    Param 4 - Size of parameters, only 1/2/4/8 is valid
+; @uses     eax, ecx, edx
+;
+align 16
+BEGINPROC   EMEmulateLockCmpXchg
+    push    xBX
+%ifdef RT_ARCH_AMD64
+%ifdef RT_OS_WINDOWS
+    ; rcx contains the first parameter already
+    mov     rbx, rdx                    ; rdx = 2nd parameter
+    mov     rdx, r8                     ; r8  = 3rd parameter
+    mov     rax, r9                     ; r9  = size of parameters
+%else
+    mov     rax, rcx                    ; rcx = size of parameters (4th)
+    mov     rcx, rdi                    ; rdi = 1st parameter
+    mov     rbx, rsi                    ; rsi = second parameter
+    ;rdx contains the 3rd parameter already
+%endif  ; !RT_OS_WINDOWS
+%else   ; !RT_ARCH_AMD64
     mov     ecx, [esp + 04h + 4]        ; ecx = first parameter
     mov     ebx, [esp + 08h + 4]        ; ebx = 2nd parameter (eax)
     mov     edx, [esp + 0ch + 4]        ; edx = third parameter
-    mov     eax, [esp + 10h + 4]        ; eax = size of parameters
-
+    mov     eax, [esp + 14h + 4]        ; eax = size of parameters
+%endif
+
+%ifdef RT_ARCH_AMD64
+    cmp     al, 8
+    je short .do_qword                  ; 4 bytes variant
+%endif
     cmp     al, 4
     je short .do_dword                  ; 4 bytes variant
@@ -872,56 +887,83 @@
     int3
 
+%ifdef RT_ARCH_AMD64
+.do_qword:
+    ; load 2nd parameter's value
+    mov     rax, qword [rbx]
+
+    lock cmpxchg qword [rcx], rdx            ; do 8 bytes CMPXCHG
+    mov     qword [rbx], rax
+    jmp     short .done
+%endif
+
 .do_dword:
     ; load 2nd parameter's value
-    mov     eax, dword [ebx]
-
-    lock cmpxchg dword [ecx], edx            ; do 4 bytes CMPXCHG
-    mov     dword [ebx], eax
+    mov     eax, dword [xBX]
+
+    lock cmpxchg dword [xCX], edx            ; do 4 bytes CMPXCHG
+    mov     dword [xBX], eax
     jmp     short .done
 
 .do_word:
     ; load 2nd parameter's value
-    mov     eax, dword [ebx]
-
-    lock cmpxchg word [ecx], dx              ; do 2 bytes CMPXCHG
-    mov     word [ebx], ax
+    mov     eax, dword [xBX]
+
+    lock cmpxchg word [xCX], dx              ; do 2 bytes CMPXCHG
+    mov     word [xBX], ax
     jmp     short .done
 
 .do_byte:
     ; load 2nd parameter's value
-    mov     eax, dword [ebx]
-
-    lock cmpxchg byte [ecx], dl              ; do 1 bytes CMPXCHG
-    mov     byte [ebx], al
+    mov     eax, dword [xBX]
+
+    lock cmpxchg byte [xCX], dl              ; do 1 byte CMPXCHG
+    mov     byte [xBX], al
 
 .done:
     ; collect flags and return.
     pushf
-    pop     eax
-
-    pop     ebx
-    retn
-
-ENDPROC     EMEmulateLockCmpXchg32
+    pop     MY_RET_REG
+
+    pop     xBX
+    retn
+ENDPROC     EMEmulateLockCmpXchg
 
 ;;
 ; Emulate CMPXCHG instruction, CDECL calling conv.
-; EMDECL(uint32_t) EMEmulateCmpXchg32(RTHCPTR pu32Param1, uint32_t *pu32Param2, uint32_t u32Param3, size_t cbSize);
-;
-; @returns EFLAGS after the operation, only arithmetic flags is valid.
+; EMDECL(uint32_t) EMEmulateCmpXchg(void *pvParam1, uint64_t *pu32Param2, uint64_t u32Param3, size_t cbSize);
+;
+; @returns EFLAGS after the operation, only arithmetic flags are valid.
 ; @param    [esp + 04h]  gcc:rdi  msc:rcx   Param 1 - First parameter - pointer to first parameter
 ; @param    [esp + 08h]  gcc:rsi  msc:rdx   Param 2 - pointer to second parameter (eax)
 ; @param    [esp + 0ch]  gcc:rdx  msc:r8    Param 3 - third parameter
-; @param    [esp + 10h]  gcc:rcx  msc:r9    Param 4 - Size of parameters, only 1/2/4 is valid.
-; @uses     eax, ecx, edx
-;
-align 16
-BEGINPROC   EMEmulateCmpXchg32
-    push    ebx
+; @param    [esp + 14h]  gcc:rcx  msc:r9    Param 4 - Size of parameters, only 1/2/4 is valid.
+; @uses     eax, ecx, edx
+;
+align 16
+BEGINPROC   EMEmulateCmpXchg
+    push    xBX
+%ifdef RT_ARCH_AMD64
+%ifdef RT_OS_WINDOWS
+    ; rcx contains the first parameter already
+    mov     rbx, rdx                    ; rdx = 2nd parameter
+    mov     rdx, r8                     ; r8  = 3rd parameter
+    mov     rax, r9                     ; r9  = size of parameters
+%else
+    mov     rax, rcx                    ; rcx = size of parameters (4th)
+    mov     rcx, rdi                    ; rdi = 1st parameter
+    mov     rbx, rsi                    ; rsi = second parameter
+    ;rdx contains the 3rd parameter already
+%endif  ; !RT_OS_WINDOWS
+%else   ; !RT_ARCH_AMD64
     mov     ecx, [esp + 04h + 4]        ; ecx = first parameter
     mov     ebx, [esp + 08h + 4]        ; ebx = 2nd parameter (eax)
     mov     edx, [esp + 0ch + 4]        ; edx = third parameter
-    mov     eax, [esp + 10h + 4]        ; eax = size of parameters
-
+    mov     eax, [esp + 14h + 4]        ; eax = size of parameters
+%endif
+
+%ifdef RT_ARCH_AMD64
+    cmp     al, 8
+    je short .do_qword                  ; 4 bytes variant
+%endif
     cmp     al, 4
     je short .do_dword                  ; 4 bytes variant
@@ -932,36 +974,48 @@
     int3
 
+%ifdef RT_ARCH_AMD64
+.do_qword:
+    ; load 2nd parameter's value
+    mov     rax, qword [rbx]
+
+    cmpxchg qword [rcx], rdx            ; do 8 bytes CMPXCHG
+    mov     qword [rbx], rax
+    jmp     short .done
+%endif
+
 .do_dword:
     ; load 2nd parameter's value
-    mov     eax, dword [ebx]
-
-    cmpxchg dword [ecx], edx            ; do 4 bytes CMPXCHG
-    mov     dword [ebx], eax
+    mov     eax, dword [xBX]
+
+    cmpxchg dword [xCX], edx            ; do 4 bytes CMPXCHG
+    mov     dword [xBX], eax
     jmp     short .done
 
 .do_word:
     ; load 2nd parameter's value
-    mov     eax, dword [ebx]
-
-    cmpxchg word [ecx], dx              ; do 2 bytes CMPXCHG
-    mov     word [ebx], ax
+    mov     eax, dword [xBX]
+
+    cmpxchg word [xCX], dx              ; do 2 bytes CMPXCHG
+    mov     word [xBX], ax
     jmp     short .done
 
 .do_byte:
     ; load 2nd parameter's value
-    mov     eax, dword [ebx]
-
-    cmpxchg byte [ecx], dl              ; do 1 bytes CMPXCHG
-    mov     byte [ebx], al
+    mov     eax, dword [xBX]
+
+    cmpxchg byte [xCX], dl              ; do 1 byte CMPXCHG
+    mov     byte [xBX], al
 
 .done:
     ; collect flags and return.
     pushf
-    pop     eax
-
-    pop     ebx
-    retn
-
-ENDPROC     EMEmulateCmpXchg32
+    pop     MY_RET_REG
+
+    pop     xBX
+    retn
+ENDPROC     EMEmulateCmpXchg
+
+%if 0
+;; not tested!!
 
 ;;
@@ -969,5 +1023,5 @@
 ; EMDECL(uint32_t) EMEmulateLockCmpXchg8b(RTHCPTR pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX);
 ;
-; @returns EFLAGS after the operation, only arithmetic flags is valid.
+; @returns EFLAGS after the operation, only arithmetic flags are valid.
 ; @param    [esp + 04h]    Param 1 - First parameter - pointer to first parameter
 ; @param    [esp + 08h]    Param 2 - Address of the eax register
@@ -978,5 +1032,5 @@
 ;
 align 16
-BEGINPROC   EMEmulateLockCmpXchg8b32
+BEGINPROC   EMEmulateLockCmpXchg8b
     push    ebp
     push    ebx
@@ -1003,11 +1057,11 @@
     retn
 
-ENDPROC     EMEmulateLockCmpXchg8b32
+ENDPROC     EMEmulateLockCmpXchg8b
 
 ;;
 ; Emulate CMPXCHG8B instruction, CDECL calling conv.
-; EMDECL(uint32_t) EMEmulateCmpXchg8b32(RTHCPTR pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX);
-;
-; @returns EFLAGS after the operation, only arithmetic flags is valid.
+; EMDECL(uint32_t) EMEmulateCmpXchg8b(RTHCPTR pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX);
+;
+; @returns EFLAGS after the operation, only arithmetic flags are valid.
 ; @param    [esp + 04h]    Param 1 - First parameter - pointer to first parameter
 ; @param    [esp + 08h]    Param 2 - Address of the eax register
@@ -1018,5 +1072,5 @@
 ;
 align 16
-BEGINPROC   EMEmulateCmpXchg8b32
+BEGINPROC   EMEmulateCmpXchg8b
     push    ebp
     push    ebx
@@ -1042,5 +1096,5 @@
     pop     ebp
     retn
-ENDPROC     EMEmulateCmpXchg8b32
-
-%endif
+ENDPROC     EMEmulateCmpXchg8b
+
+%endif
