EMAllA.asm revision 614471bd520e0597d0a771bf25d0021ecadfc0ca
10139N/A; $Id$
10139N/A;; @file
17583N/A; EM Assembly Routines.
15941N/A;
15941N/A
17583N/A;
17583N/A; Copyright (C) 2006-2007 Sun Microsystems, Inc.
10139N/A;
10139N/A; This file is part of VirtualBox Open Source Edition (OSE), as
10139N/A; available from http://www.virtualbox.org. This file is free software;
10139N/A; you can redistribute it and/or modify it under the terms of the GNU
10139N/A; General Public License (GPL) as published by the Free Software
17583N/A; Foundation, in version 2 as it comes in the "COPYING" file of the
10139N/A; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
10139N/A; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
10139N/A;
10139N/A; Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
17583N/A; Clara, CA 95054 USA or visit http://www.sun.com if you need
17583N/A; additional information or have any questions.
10139N/A;
10139N/A
10139N/A;*******************************************************************************
10139N/A;* Header Files *
17583N/A;*******************************************************************************
17583N/A%include "VBox/asmdefs.mac"
17583N/A%include "VBox/err.mac"
17583N/A%include "VBox/x86.mac"
17583N/A
17583N/A;; @def MY_PTR_REG
17583N/A; The register we use for value pointers (And,Or,Dec,Inc).
17583N/A%ifdef RT_ARCH_AMD64
17583N/A%define MY_PTR_REG rcx
17583N/A%else
10139N/A%define MY_PTR_REG ecx
17583N/A%endif
17583N/A
17583N/A;; @def MY_RET_REG
17583N/A; The register we return the result in.
17583N/A%ifdef RT_ARCH_AMD64
17583N/A%define MY_RET_REG rax
10139N/A%else
17583N/A%define MY_RET_REG eax
10139N/A%endif
10139N/A
17583N/ABEGINCODE
17583N/A
17583N/A
17583N/A;;
17583N/A; Emulate CMP instruction, CDECL calling conv.
17583N/A; EMDECL(uint32_t) EMEmulateCmp(uint32_t u32Param1, uint32_t u32Param2, size_t cb);
17583N/A;
17583N/A; @returns EFLAGS after the operation, only arithmetic flags is valid.
17583N/A; @param [esp + 04h] rdi rcx Param 1 - First parameter (Dst).
17583N/A; @param [esp + 08h] rsi edx Param 2 - Second parameter (Src).
17583N/A; @param [esp + 0ch] rdx r8 Param 3 - Size of parameters, only 1/2/4 is valid.
17583N/A;
17583N/Aalign 16
17583N/ABEGINPROC EMEmulateCmp
17583N/A%ifdef RT_ARCH_AMD64
17583N/A%ifdef RT_OS_WINDOWS
17583N/A mov rax, r8 ; eax = size of parameters
17583N/A%else ; !RT_OS_WINDOWS
17583N/A mov rax, rdx ; rax = size of parameters
17583N/A mov rcx, rdi ; rcx = first parameter
17583N/A mov rdx, rsi ; rdx = second parameter
17583N/A%endif ; !RT_OS_WINDOWS
17583N/A%else ; !RT_ARCH_AMD64
17583N/A mov eax, [esp + 0ch] ; eax = size of parameters
17583N/A mov ecx, [esp + 04h] ; ecx = first parameter
17583N/A mov edx, [esp + 08h] ; edx = second parameter
17583N/A%endif
17583N/A
17583N/A ; switch on size
17583N/A%ifdef RT_ARCH_AMD64
17583N/A cmp al, 8
17583N/A je short .do_qword ; 8 bytes variant
17583N/A%endif
17583N/A cmp al, 4
17583N/A je short .do_dword ; 4 bytes variant
17583N/A cmp al, 2
17583N/A je short .do_word ; 2 byte variant
17583N/A cmp al, 1
17583N/A je short .do_byte ; 1 bytes variant
17583N/A int3
17583N/A
17583N/A ; workers
17583N/A%ifdef RT_ARCH_AMD64
17583N/A.do_qword:
17583N/A cmp rcx, rdx ; do 8 bytes CMP
17583N/A jmp short .done
17583N/A%endif
17583N/A
17583N/A.do_dword:
17583N/A cmp ecx, edx ; do 4 bytes CMP
17583N/A jmp short .done
17583N/A
17583N/A.do_word:
17583N/A cmp cx, dx ; do 2 bytes CMP
17583N/A jmp short .done
17583N/A
17583N/A.do_byte:
17583N/A cmp cl, dl ; do 1 byte CMP
17583N/A
17583N/A ; collect flags and return.
17583N/A.done:
17583N/A pushf
17583N/A pop MY_RET_REG
17583N/A retn
17583N/AENDPROC EMEmulateCmp
17583N/A
17583N/A
17583N/A;;
17583N/A; Emulate AND instruction, CDECL calling conv.
17583N/A; EMDECL(uint32_t) EMEmulateAnd(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb);
17583N/A;
17583N/A; @returns EFLAGS after the operation, only arithmetic flags is valid.
17583N/A; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
17583N/A; @param [esp + 08h] Param 2 - Second parameter.
17583N/A; @param [esp + 0ch] Param 3 - Size of parameters, only 1/2/4 is valid.
17583N/A; @uses eax, ecx, edx
17583N/A;
17583N/Aalign 16
17583N/ABEGINPROC EMEmulateAnd
17583N/A%ifdef RT_ARCH_AMD64
17583N/A%ifdef RT_OS_WINDOWS
17583N/A mov rax, r8 ; eax = size of parameters
17583N/A%else ; !RT_OS_WINDOWS
17583N/A mov rax, rdx ; rax = size of parameters
17583N/A mov rcx, rdi ; rcx = first parameter
17583N/A mov rdx, rsi ; rdx = second parameter
17583N/A%endif ; !RT_OS_WINDOWS
17583N/A%else ; !RT_ARCH_AMD64
17583N/A mov eax, [esp + 0ch] ; eax = size of parameters
17583N/A mov ecx, [esp + 04h] ; ecx = first parameter
17583N/A mov edx, [esp + 08h] ; edx = second parameter
17583N/A%endif
17583N/A
17583N/A ; switch on size
17583N/A%ifdef RT_ARCH_AMD64
17583N/A cmp al, 8
17583N/A je short .do_qword ; 8 bytes variant
17583N/A%endif
17583N/A cmp al, 4
17583N/A je short .do_dword ; 4 bytes variant
17583N/A cmp al, 2
17583N/A je short .do_word ; 2 byte variant
17583N/A cmp al, 1
17583N/A je short .do_byte ; 1 bytes variant
17583N/A int3
17583N/A
17583N/A ; workers
17583N/A%ifdef RT_ARCH_AMD64
17583N/A.do_qword:
17583N/A and [MY_PTR_REG], rdx ; do 8 bytes AND
17583N/A jmp short .done
17583N/A%endif
17583N/A
17583N/A.do_dword:
17583N/A and [MY_PTR_REG], edx ; do 4 bytes AND
17583N/A jmp short .done
17583N/A
17583N/A.do_word:
17583N/A and [MY_PTR_REG], dx ; do 2 bytes AND
17583N/A jmp short .done
17583N/A
17583N/A.do_byte:
17583N/A and [MY_PTR_REG], dl ; do 1 byte AND
17583N/A
17583N/A ; collect flags and return.
17583N/A.done:
17583N/A pushf
17583N/A pop MY_RET_REG
17583N/A retn
17583N/AENDPROC EMEmulateAnd
17583N/A
17583N/A
17583N/A;;
17583N/A; Emulate OR instruction, CDECL calling conv.
17583N/A; EMDECL(uint32_t) EMEmulateOr(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb);
17583N/A;
17583N/A; @returns EFLAGS after the operation, only arithmetic flags is valid.
17583N/A; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
17583N/A; @param [esp + 08h] Param 2 - Second parameter.
17583N/A; @param [esp + 0ch] Param 3 - Size of parameters, only 1/2/4 is valid.
17583N/A; @uses eax, ecx, edx
17583N/A;
17583N/Aalign 16
17583N/ABEGINPROC EMEmulateOr
17583N/A%ifdef RT_ARCH_AMD64
17583N/A%ifdef RT_OS_WINDOWS
17583N/A mov rax, r8 ; eax = size of parameters
17583N/A%else ; !RT_OS_WINDOWS
17583N/A mov rax, rdx ; rax = size of parameters
17583N/A mov rcx, rdi ; rcx = first parameter
17583N/A mov rdx, rsi ; rdx = second parameter
17583N/A%endif ; !RT_OS_WINDOWS
17583N/A%else ; !RT_ARCH_AMD64
17583N/A mov eax, [esp + 0ch] ; eax = size of parameters
17583N/A mov ecx, [esp + 04h] ; ecx = first parameter
17583N/A mov edx, [esp + 08h] ; edx = second parameter
17583N/A%endif
17583N/A
17583N/A ; switch on size
17583N/A%ifdef RT_ARCH_AMD64
17583N/A cmp al, 8
17583N/A je short .do_qword ; 8 bytes variant
17583N/A%endif
17583N/A cmp al, 4
17583N/A je short .do_dword ; 4 bytes variant
17583N/A cmp al, 2
17583N/A je short .do_word ; 2 byte variant
17583N/A cmp al, 1
17583N/A je short .do_byte ; 1 bytes variant
17583N/A int3
17583N/A
17583N/A ; workers
17583N/A%ifdef RT_ARCH_AMD64
17583N/A.do_qword:
17583N/A or [MY_PTR_REG], rdx ; do 8 bytes OR
17583N/A jmp short .done
17583N/A%endif
17583N/A
17583N/A.do_dword:
17583N/A or [MY_PTR_REG], edx ; do 4 bytes OR
17583N/A jmp short .done
17583N/A
17583N/A.do_word:
17583N/A or [MY_PTR_REG], dx ; do 2 bytes OR
17583N/A jmp short .done
17583N/A
17583N/A.do_byte:
17583N/A or [MY_PTR_REG], dl ; do 1 byte OR
17583N/A
17583N/A ; collect flags and return.
17583N/A.done:
17583N/A pushf
17583N/A pop MY_RET_REG
17583N/A retn
17583N/AENDPROC EMEmulateOr
17583N/A
17583N/A;;
17583N/A; Emulate LOCK OR instruction.
17583N/A; EMDECL(int) EMEmulateLockOr(RTGCPTR GCPtrParam1, RTGCUINTREG Param2, size_t cbSize, RTGCUINTREG *pf);
17583N/A;
17583N/A; @returns VINF_SUCCESS on success, VERR_ACCESS_DENIED on \#PF (GC only).
17583N/A; @param [esp + 04h] gcc:rdi msc:rcx Param 1 - First parameter - pointer to data item (the real stuff).
17583N/A; @param [esp + 08h] gcc:rsi msc:rdx Param 2 - Second parameter- the immediate / register value.
17583N/A; @param [esp + 0ch] gcc:rdx msc:r8 Param 3 - Size of the operation - 1, 2, 4 or 8 bytes.
17583N/A; @param [esp + 10h] gcc:rcx msc:r9 Param 4 - Where to store the eflags on success.
17583N/A; only arithmetic flags are valid.
17583N/Aalign 16
17583N/ABEGINPROC EMEmulateLockOr
17583N/A%ifdef RT_ARCH_AMD64
17583N/A%ifdef RT_OS_WINDOWS
17583N/A mov rax, r8 ; eax = size of parameters
17583N/A%else ; !RT_OS_WINDOWS
17583N/A mov rax, rdx ; rax = size of parameters
17583N/A mov rcx, rdi ; rcx = first parameter
17583N/A mov rdx, rsi ; rdx = second parameter
17583N/A%endif ; !RT_OS_WINDOWS
17583N/A%else ; !RT_ARCH_AMD64
17583N/A mov eax, [esp + 0ch] ; eax = size of parameters
17583N/A mov ecx, [esp + 04h] ; ecx = first parameter (MY_PTR_REG)
17583N/A mov edx, [esp + 08h] ; edx = second parameter
17583N/A%endif
17583N/A
17583N/A ; switch on size
17583N/A%ifdef RT_ARCH_AMD64
17583N/A cmp al, 8
17583N/A je short .do_qword ; 8 bytes variant
17583N/A%endif
17583N/A cmp al, 4
17583N/A je short .do_dword ; 4 bytes variant
17583N/A cmp al, 2
17583N/A je short .do_word ; 2 byte variant
17583N/A cmp al, 1
17583N/A je short .do_byte ; 1 bytes variant
17583N/A int3
17583N/A
17583N/A ; workers
17583N/A%ifdef RT_ARCH_AMD64
17583N/A.do_qword:
17583N/A lock or [MY_PTR_REG], rdx ; do 8 bytes OR
17583N/A jmp short .done
17583N/A%endif
17583N/A
17583N/A.do_dword:
17583N/A lock or [MY_PTR_REG], edx ; do 4 bytes OR
17583N/A jmp short .done
17583N/A
17583N/A.do_word:
17583N/A lock or [MY_PTR_REG], dx ; do 2 bytes OR
17583N/A jmp short .done
17583N/A
17583N/A.do_byte:
17583N/A lock or [MY_PTR_REG], dl ; do 1 byte OR
17583N/A
17583N/A ; collect flags and return.
17583N/A.done:
17583N/A pushf
17583N/A%ifdef RT_ARCH_AMD64
17583N/A pop rax
17583N/A %ifdef RT_OS_WINDOWS
17583N/A mov [r9], eax
17583N/A %else ; !RT_OS_WINDOWS
17583N/A mov [rcx], eax
17583N/A %endif ; !RT_OS_WINDOWS
17583N/A%else ; !RT_ARCH_AMD64
17583N/A mov eax, [esp + 10h + 4]
17583N/A pop dword [eax]
17583N/A%endif
17583N/A mov eax, VINF_SUCCESS
17583N/A retn
17583N/A
17583N/A%ifdef IN_GC
17583N/A; #PF resume point.
17583N/AGLOBALNAME EMEmulateLockOr_Error
17583N/A mov eax, VERR_ACCESS_DENIED
17583N/A ret
17583N/A%endif
17583N/A
17583N/AENDPROC EMEmulateLockOr
17583N/A
17583N/A;;
17583N/A; Emulate XOR instruction, CDECL calling conv.
17583N/A; EMDECL(uint32_t) EMEmulateXor(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb);
17583N/A;
17583N/A; @returns EFLAGS after the operation, only arithmetic flags is valid.
17583N/A; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
17583N/A; @param [esp + 08h] Param 2 - Second parameter.
17583N/A; @param [esp + 0ch] Param 3 - Size of parameters, only 1/2/4 is valid.
17583N/A; @uses eax, ecx, edx
17583N/A;
17583N/Aalign 16
17583N/ABEGINPROC EMEmulateXor
17583N/A%ifdef RT_ARCH_AMD64
17583N/A%ifdef RT_OS_WINDOWS
17583N/A mov rax, r8 ; eax = size of parameters
17583N/A%else ; !RT_OS_WINDOWS
17583N/A mov rax, rdx ; rax = size of parameters
17583N/A mov rcx, rdi ; rcx = first parameter
17583N/A mov rdx, rsi ; rdx = second parameter
17583N/A%endif ; !RT_OS_WINDOWS
17583N/A%else ; !RT_ARCH_AMD64
17583N/A mov eax, [esp + 0ch] ; eax = size of parameters
17583N/A mov ecx, [esp + 04h] ; ecx = first parameter
17583N/A mov edx, [esp + 08h] ; edx = second parameter
17583N/A%endif
17583N/A
17583N/A ; switch on size
17583N/A%ifdef RT_ARCH_AMD64
17583N/A cmp al, 8
17583N/A je short .do_qword ; 8 bytes variant
17583N/A%endif
17583N/A cmp al, 4
17583N/A je short .do_dword ; 4 bytes variant
17583N/A cmp al, 2
17583N/A je short .do_word ; 2 byte variant
17583N/A cmp al, 1
10139N/A je short .do_byte ; 1 bytes variant
17583N/A int3
17583N/A
17583N/A ; workers
17583N/A%ifdef RT_ARCH_AMD64
17583N/A.do_qword:
17583N/A xor [MY_PTR_REG], rdx ; do 8 bytes XOR
17583N/A jmp short .done
17583N/A%endif
17583N/A
17583N/A.do_dword:
17583N/A xor [MY_PTR_REG], edx ; do 4 bytes XOR
17583N/A jmp short .done
17583N/A
17583N/A.do_word:
17583N/A xor [MY_PTR_REG], dx ; do 2 bytes XOR
17583N/A jmp short .done
17583N/A
17583N/A.do_byte:
17583N/A xor [MY_PTR_REG], dl ; do 1 byte XOR
17583N/A
17583N/A ; collect flags and return.
17583N/A.done:
17583N/A pushf
17583N/A pop MY_RET_REG
17583N/A retn
17583N/AENDPROC EMEmulateXor
17583N/A
17583N/A;;
17583N/A; Emulate INC instruction, CDECL calling conv.
17583N/A; EMDECL(uint32_t) EMEmulateInc(uint32_t *pu32Param1, size_t cb);
17583N/A;
17583N/A; @returns EFLAGS after the operation, only arithmetic flags are valid.
17583N/A; @param [esp + 04h] rdi rcx Param 1 - First parameter - pointer to data item.
17583N/A; @param [esp + 08h] rsi rdx Param 2 - Size of parameters, only 1/2/4 is valid.
17583N/A; @uses eax, ecx, edx
17583N/A;
17583N/Aalign 16
17583N/ABEGINPROC EMEmulateInc
17583N/A%ifdef RT_ARCH_AMD64
17583N/A%ifdef RT_OS_WINDOWS
17583N/A mov rax, rdx ; eax = size of parameters
17583N/A%else ; !RT_OS_WINDOWS
17583N/A mov rax, rsi ; eax = size of parameters
17583N/A mov rcx, rdi ; rcx = first parameter
17583N/A%endif ; !RT_OS_WINDOWS
17583N/A%else ; !RT_ARCH_AMD64
17583N/A mov eax, [esp + 08h] ; eax = size of parameters
17583N/A mov ecx, [esp + 04h] ; ecx = first parameter
17583N/A%endif
17583N/A
17583N/A ; switch on size
17583N/A%ifdef RT_ARCH_AMD64
17583N/A cmp al, 8
17583N/A je short .do_qword ; 8 bytes variant
17583N/A%endif
17583N/A cmp al, 4
17583N/A je short .do_dword ; 4 bytes variant
17583N/A cmp al, 2
17583N/A je short .do_word ; 2 byte variant
17583N/A cmp al, 1
17583N/A je short .do_byte ; 1 bytes variant
17583N/A int3
17583N/A
17583N/A ; workers
17583N/A%ifdef RT_ARCH_AMD64
17583N/A.do_qword:
17583N/A inc qword [MY_PTR_REG] ; do 8 bytes INC
17583N/A jmp short .done
17583N/A%endif
17583N/A
17583N/A.do_dword:
17583N/A inc dword [MY_PTR_REG] ; do 4 bytes INC
17583N/A jmp short .done
17583N/A
17583N/A.do_word:
17583N/A inc word [MY_PTR_REG] ; do 2 bytes INC
17583N/A jmp short .done
17583N/A
17583N/A.do_byte:
17583N/A inc byte [MY_PTR_REG] ; do 1 byte INC
17583N/A jmp short .done
17583N/A
17583N/A ; collect flags and return.
17583N/A.done:
17583N/A pushf
17583N/A pop MY_RET_REG
17583N/A retn
17583N/AENDPROC EMEmulateInc
17583N/A
17583N/A
17583N/A;;
17583N/A; Emulate DEC instruction, CDECL calling conv.
17583N/A; EMDECL(uint32_t) EMEmulateDec(uint32_t *pu32Param1, size_t cb);
17583N/A;
17583N/A; @returns EFLAGS after the operation, only arithmetic flags are valid.
17583N/A; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
17583N/A; @param [esp + 08h] Param 2 - Size of parameters, only 1/2/4 is valid.
17583N/A; @uses eax, ecx, edx
17583N/A;
17583N/Aalign 16
17583N/ABEGINPROC EMEmulateDec
17583N/A%ifdef RT_ARCH_AMD64
17583N/A%ifdef RT_OS_WINDOWS
17583N/A mov rax, rdx ; eax = size of parameters
17583N/A%else ; !RT_OS_WINDOWS
17583N/A mov rax, rsi ; eax = size of parameters
17583N/A mov rcx, rdi ; rcx = first parameter
17583N/A%endif ; !RT_OS_WINDOWS
17583N/A%else ; !RT_ARCH_AMD64
17583N/A mov eax, [esp + 08h] ; eax = size of parameters
17583N/A mov ecx, [esp + 04h] ; ecx = first parameter
17583N/A%endif
17583N/A
17583N/A ; switch on size
17583N/A%ifdef RT_ARCH_AMD64
17583N/A cmp al, 8
17583N/A je short .do_qword ; 8 bytes variant
17583N/A%endif
17583N/A cmp al, 4
17583N/A je short .do_dword ; 4 bytes variant
17583N/A cmp al, 2
17583N/A je short .do_word ; 2 byte variant
17583N/A cmp al, 1
17583N/A je short .do_byte ; 1 bytes variant
17583N/A int3
17583N/A
17583N/A ; workers
17583N/A%ifdef RT_ARCH_AMD64
17583N/A.do_qword:
17583N/A dec qword [MY_PTR_REG] ; do 8 bytes DEC
17583N/A jmp short .done
17583N/A%endif
17583N/A
17583N/A.do_dword:
17583N/A dec dword [MY_PTR_REG] ; do 4 bytes DEC
17583N/A jmp short .done
17583N/A
17583N/A.do_word:
17583N/A dec word [MY_PTR_REG] ; do 2 bytes DEC
17583N/A jmp short .done
17583N/A
17583N/A.do_byte:
17583N/A dec byte [MY_PTR_REG] ; do 1 byte DEC
17583N/A jmp short .done
17583N/A
17583N/A ; collect flags and return.
17583N/A.done:
17583N/A pushf
17583N/A pop MY_RET_REG
17583N/A retn
17583N/AENDPROC EMEmulateDec
17583N/A
17583N/A;;
17583N/A; Emulate ADD instruction, CDECL calling conv.
17583N/A; EMDECL(uint32_t) EMEmulateAdd(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb);
17583N/A;
17583N/A; @returns EFLAGS after the operation, only arithmetic flags is valid.
17583N/A; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
17583N/A; @param [esp + 08h] Param 2 - Second parameter.
17583N/A; @param [esp + 0ch] Param 3 - Size of parameters, only 1/2/4 is valid.
17583N/A; @uses eax, ecx, edx
17583N/A;
17583N/Aalign 16
17583N/ABEGINPROC EMEmulateAdd
17583N/A%ifdef RT_ARCH_AMD64
17583N/A%ifdef RT_OS_WINDOWS
17583N/A mov rax, r8 ; eax = size of parameters
17583N/A%else ; !RT_OS_WINDOWS
17583N/A mov rax, rdx ; rax = size of parameters
17583N/A mov rcx, rdi ; rcx = first parameter
17583N/A mov rdx, rsi ; rdx = second parameter
17583N/A%endif ; !RT_OS_WINDOWS
17583N/A%else ; !RT_ARCH_AMD64
17583N/A mov eax, [esp + 0ch] ; eax = size of parameters
17583N/A mov ecx, [esp + 04h] ; ecx = first parameter
17583N/A mov edx, [esp + 08h] ; edx = second parameter
17583N/A%endif
17583N/A
17583N/A ; switch on size
17583N/A%ifdef RT_ARCH_AMD64
17583N/A cmp al, 8
17583N/A je short .do_qword ; 8 bytes variant
17583N/A%endif
17583N/A cmp al, 4
17583N/A je short .do_dword ; 4 bytes variant
17583N/A cmp al, 2
17583N/A je short .do_word ; 2 byte variant
17583N/A cmp al, 1
17583N/A je short .do_byte ; 1 bytes variant
17583N/A int3
17583N/A
17583N/A ; workers
17583N/A%ifdef RT_ARCH_AMD64
17583N/A.do_qword:
17583N/A add [MY_PTR_REG], rdx ; do 8 bytes ADD
17583N/A jmp short .done
17583N/A%endif
17583N/A
17583N/A.do_dword:
17583N/A add [MY_PTR_REG], edx ; do 4 bytes ADD
17583N/A jmp short .done
17583N/A
17583N/A.do_word:
17583N/A add [MY_PTR_REG], dx ; do 2 bytes ADD
17583N/A jmp short .done
17583N/A
17583N/A.do_byte:
17583N/A add [MY_PTR_REG], dl ; do 1 byte ADD
17583N/A
17583N/A ; collect flags and return.
17583N/A.done:
17583N/A pushf
17583N/A pop MY_RET_REG
17583N/A retn
17583N/AENDPROC EMEmulateAdd
17583N/A
17583N/A;;
17583N/A; Emulate ADC instruction, CDECL calling conv.
17583N/A; EMDECL(uint32_t) EMEmulateAdcWithCarrySet(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb);
17583N/A;
17583N/A; @returns EFLAGS after the operation, only arithmetic flags is valid.
17583N/A; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
17583N/A; @param [esp + 08h] Param 2 - Second parameter.
17583N/A; @param [esp + 0ch] Param 3 - Size of parameters, only 1/2/4 is valid.
17583N/A; @uses eax, ecx, edx
17583N/A;
17583N/Aalign 16
17583N/ABEGINPROC EMEmulateAdcWithCarrySet
17583N/A%ifdef RT_ARCH_AMD64
17583N/A%ifdef RT_OS_WINDOWS
17583N/A mov rax, r8 ; eax = size of parameters
17583N/A%else ; !RT_OS_WINDOWS
17583N/A mov rax, rdx ; rax = size of parameters
17583N/A mov rcx, rdi ; rcx = first parameter
17583N/A mov rdx, rsi ; rdx = second parameter
17583N/A%endif ; !RT_OS_WINDOWS
17583N/A%else ; !RT_ARCH_AMD64
17583N/A mov eax, [esp + 0ch] ; eax = size of parameters
17583N/A mov ecx, [esp + 04h] ; ecx = first parameter
17583N/A mov edx, [esp + 08h] ; edx = second parameter
17583N/A%endif
17583N/A
17583N/A ; switch on size
17583N/A%ifdef RT_ARCH_AMD64
17583N/A cmp al, 8
17583N/A je short .do_qword ; 8 bytes variant
17583N/A%endif
17583N/A cmp al, 4
17583N/A je short .do_dword ; 4 bytes variant
17583N/A cmp al, 2
17583N/A je short .do_word ; 2 byte variant
17583N/A cmp al, 1
17583N/A je short .do_byte ; 1 bytes variant
17583N/A int3
17583N/A
17583N/A ; workers
17583N/A%ifdef RT_ARCH_AMD64
17583N/A.do_qword:
17583N/A stc ; set carry flag
17583N/A adc [MY_PTR_REG], rdx ; do 8 bytes ADC
17583N/A jmp short .done
17583N/A%endif
17583N/A
17583N/A.do_dword:
17583N/A stc ; set carry flag
17583N/A adc [MY_PTR_REG], edx ; do 4 bytes ADC
17583N/A jmp short .done
17583N/A
17583N/A.do_word:
17583N/A stc ; set carry flag
17583N/A adc [MY_PTR_REG], dx ; do 2 bytes ADC
17583N/A jmp short .done
17583N/A
17583N/A.do_byte:
17583N/A stc ; set carry flag
17583N/A adc [MY_PTR_REG], dl ; do 1 byte ADC
17583N/A
17583N/A ; collect flags and return.
17583N/A.done:
17583N/A pushf
17583N/A pop MY_RET_REG
17583N/A retn
17583N/AENDPROC EMEmulateAdcWithCarrySet
17583N/A
17583N/A;;
17583N/A; Emulate SUB instruction, CDECL calling conv.
17583N/A; EMDECL(uint32_t) EMEmulateSub(uint32_t *pu32Param1, uint32_t u32Param2, size_t cb);
17583N/A;
17583N/A; @returns EFLAGS after the operation, only arithmetic flags is valid.
17583N/A; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
17583N/A; @param [esp + 08h] Param 2 - Second parameter.
17583N/A; @param [esp + 0ch] Param 3 - Size of parameters, only 1/2/4 is valid.
17583N/A; @uses eax, ecx, edx
17583N/A;
17583N/Aalign 16
17583N/ABEGINPROC EMEmulateSub
17583N/A%ifdef RT_ARCH_AMD64
17583N/A%ifdef RT_OS_WINDOWS
17583N/A mov rax, r8 ; eax = size of parameters
17583N/A%else ; !RT_OS_WINDOWS
17583N/A mov rax, rdx ; rax = size of parameters
17583N/A mov rcx, rdi ; rcx = first parameter
17583N/A mov rdx, rsi ; rdx = second parameter
17583N/A%endif ; !RT_OS_WINDOWS
17583N/A%else ; !RT_ARCH_AMD64
17583N/A mov eax, [esp + 0ch] ; eax = size of parameters
17583N/A mov ecx, [esp + 04h] ; ecx = first parameter
17583N/A mov edx, [esp + 08h] ; edx = second parameter
17583N/A%endif
17583N/A
17583N/A ; switch on size
17583N/A%ifdef RT_ARCH_AMD64
17583N/A cmp al, 8
17583N/A je short .do_qword ; 8 bytes variant
17583N/A%endif
17583N/A cmp al, 4
17583N/A je short .do_dword ; 4 bytes variant
17583N/A cmp al, 2
17583N/A je short .do_word ; 2 byte variant
17583N/A cmp al, 1
17583N/A je short .do_byte ; 1 bytes variant
17583N/A int3
17583N/A
17583N/A ; workers
17583N/A%ifdef RT_ARCH_AMD64
17583N/A.do_qword:
17583N/A sub [MY_PTR_REG], rdx ; do 8 bytes SUB
17583N/A jmp short .done
17583N/A%endif
17583N/A
17583N/A.do_dword:
17583N/A sub [MY_PTR_REG], edx ; do 4 bytes SUB
17583N/A jmp short .done
17583N/A
17583N/A.do_word:
17583N/A sub [MY_PTR_REG], dx ; do 2 bytes SUB
10139N/A jmp short .done
17583N/A
17583N/A.do_byte:
10139N/A sub [MY_PTR_REG], dl ; do 1 byte SUB
17583N/A
17583N/A ; collect flags and return.
17583N/A.done:
17583N/A pushf
17583N/A pop MY_RET_REG
17583N/A retn
17583N/AENDPROC EMEmulateSub
17583N/A
17583N/A
17583N/A;;
17583N/A; Emulate BTR instruction, CDECL calling conv.
17583N/A; EMDECL(uint32_t) EMEmulateBtr(uint32_t *pu32Param1, uint32_t u32Param2);
17583N/A;
10139N/A; @returns EFLAGS after the operation, only arithmetic flags is valid.
10139N/A; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
10139N/A; @param [esp + 08h] Param 2 - Second parameter.
17583N/A; @uses eax, ecx, edx
17583N/A;
17583N/Aalign 16
17583N/ABEGINPROC EMEmulateBtr
17583N/A%ifdef RT_ARCH_AMD64
17583N/A%ifndef RT_OS_WINDOWS
10139N/A mov rcx, rdi ; rcx = first parameter
17583N/A mov rdx, rsi ; rdx = second parameter
17583N/A%endif ; !RT_OS_WINDOWS
17583N/A%else ; !RT_ARCH_AMD64
17583N/A mov ecx, [esp + 04h] ; ecx = first parameter
17583N/A mov edx, [esp + 08h] ; edx = second parameter
17583N/A%endif
17583N/A
17583N/A and edx, 7
17583N/A btr [MY_PTR_REG], edx
17583N/A
17583N/A ; collect flags and return.
10139N/A pushf
10139N/A pop MY_RET_REG
17583N/A retn
17583N/AENDPROC EMEmulateBtr
10139N/A
10139N/A;;
17583N/A; Emulate LOCK BTR instruction.
17583N/A; EMDECL(int) EMEmulateLockBtr(RTGCPTR GCPtrParam1, RTGCUINTREG Param2, uint32_t *pf);
17583N/A;
17583N/A; @returns VINF_SUCCESS on success, VERR_ACCESS_DENIED on \#PF (GC only).
17583N/A; @param [esp + 04h] gcc:rdi msc:rcx Param 1 - First parameter - pointer to data item (the real stuff).
10139N/A; @param [esp + 08h] gcc:rsi msc:rdx Param 2 - Second parameter- the immediate / register value. (really an 8 byte value)
17583N/A; @param [esp + 0ch] gcc:rdx msc:r8 Param 3 - Where to store the eflags on success.
17583N/A;
17583N/Aalign 16
17583N/ABEGINPROC EMEmulateLockBtr
17583N/A%ifdef RT_ARCH_AMD64
17583N/A %ifdef RT_OS_WINDOWS
17583N/A mov rax, r8 ; rax = third parameter
17583N/A %else ; !RT_OS_WINDOWS
17583N/A mov rcx, rdi ; rcx = first parameter
17583N/A mov rax, rdx ; rax = third parameter
17583N/A mov rdx, rsi ; rdx = second parameter
17583N/A %endif ; !RT_OS_WINDOWS
17583N/A%else ; !RT_ARCH_AMD64
10139N/A mov ecx, [esp + 04h] ; ecx = first parameter
15996N/A mov edx, [esp + 08h] ; edx = second parameter
17583N/A mov eax, [esp + 0ch] ; eax = third parameter
17583N/A%endif
15996N/A
15996N/A lock btr [MY_PTR_REG], edx
10139N/A
17583N/A ; collect flags and return.
15996N/A pushf
15996N/A pop xDX
10139N/A mov [xAX], edx
17583N/A mov eax, VINF_SUCCESS
17583N/A retn
17583N/A
17583N/A%ifdef IN_GC
17583N/A; #PF resume point.
17583N/AGLOBALNAME EMEmulateLockBtr_Error
17583N/A mov eax, VERR_ACCESS_DENIED
17583N/A ret
17583N/A%endif
17583N/A
17583N/AENDPROC EMEmulateLockBtr
17583N/A
17583N/A;;
17583N/A; Emulate BTC instruction, CDECL calling conv.
17583N/A; EMDECL(uint32_t) EMEmulateBtc(uint32_t *pu32Param1, uint32_t u32Param2);
17583N/A;
17583N/A; @returns EFLAGS after the operation, only arithmetic flags is valid.
17583N/A; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
17583N/A; @param [esp + 08h] Param 2 - Second parameter.
17583N/A; @uses eax, ecx, edx
17583N/A;
17583N/Aalign 16
17583N/ABEGINPROC EMEmulateBtc
17583N/A%ifdef RT_ARCH_AMD64
17583N/A%ifndef RT_OS_WINDOWS
17583N/A mov rcx, rdi ; rcx = first parameter
17583N/A mov rdx, rsi ; rdx = second parameter
17583N/A%endif ; !RT_OS_WINDOWS
17583N/A%else ; !RT_ARCH_AMD64
17583N/A mov ecx, [esp + 04h] ; ecx = first parameter
17583N/A mov edx, [esp + 08h] ; edx = second parameter
17583N/A%endif
17583N/A
17583N/A and edx, 7
17583N/A btc [MY_PTR_REG], edx
17583N/A
17583N/A ; collect flags and return.
17583N/A pushf
17583N/A pop MY_RET_REG
17583N/A retn
17583N/AENDPROC EMEmulateBtc
17583N/A
17583N/A;;
17583N/A; Emulate BTS instruction, CDECL calling conv.
17583N/A; EMDECL(uint32_t) EMEmulateBts(uint32_t *pu32Param1, uint32_t u32Param2);
17583N/A;
17583N/A; @returns EFLAGS after the operation, only arithmetic flags are valid.
17583N/A; @param [esp + 04h] Param 1 - First parameter - pointer to data item.
17583N/A; @param [esp + 08h] Param 2 - Second parameter.
17583N/A; @uses eax, ecx, edx
17583N/A;
17583N/Aalign 16
17583N/ABEGINPROC EMEmulateBts
17583N/A%ifdef RT_ARCH_AMD64
17583N/A%ifndef RT_OS_WINDOWS
17583N/A mov rcx, rdi ; rcx = first parameter
17583N/A mov rdx, rsi ; rdx = second parameter
17583N/A%endif ; !RT_OS_WINDOWS
17583N/A%else ; !RT_ARCH_AMD64
17583N/A mov ecx, [esp + 04h] ; ecx = first parameter
17583N/A mov edx, [esp + 08h] ; edx = second parameter
17583N/A%endif
17583N/A
17583N/A and edx, 7
17583N/A bts [MY_PTR_REG], edx
17583N/A
17583N/A ; collect flags and return.
17583N/A pushf
17583N/A pop MY_RET_REG
17583N/A retn
17583N/AENDPROC EMEmulateBts
17583N/A
17583N/A
17583N/A%if 0
17583N/A;; untested code!!
17583N/A
17583N/A;;
17583N/A; Emulate LOCK CMPXCHG instruction, CDECL calling conv.
17583N/A; EMDECL(uint32_t) EMEmulateLockCmpXchg32(RTHCPTR pu32Param1, uint32_t *pu32Param2, uint32_t u32Param3, size_t cbSize);
17583N/A;
17583N/A; @returns EFLAGS after the operation, only arithmetic flags is valid.
17583N/A; @param [esp + 04h] gcc:rdi msc:rcx Param 1 - First parameter - pointer to first parameter
17583N/A; @param [esp + 08h] gcc:rsi msc:rdx Param 2 - pointer to second parameter (eax)
17583N/A; @param [esp + 0ch] gcc:rdx msc:r8 Param 3 - third parameter
17583N/A; @param [esp + 10h] gcc:rcx msc:r9 Param 4 - Size of parameters, only 1/2/4 is valid
17583N/A; @uses eax, ecx, edx
17583N/A;
17583N/Aalign 16
17583N/ABEGINPROC EMEmulateLockCmpXchg32
17583N/A push ebx
17583N/A mov ecx, [esp + 04h + 4] ; ecx = first parameter
17583N/A mov ebx, [esp + 08h + 4] ; ebx = 2nd parameter (eax)
17583N/A mov edx, [esp + 0ch + 4] ; edx = third parameter
17583N/A mov eax, [esp + 10h + 4] ; eax = size of parameters
17583N/A
17583N/A cmp al, 4
17583N/A je short .do_dword ; 4 bytes variant
17583N/A cmp al, 2
17583N/A je short .do_word ; 2 byte variant
17583N/A cmp al, 1
17583N/A je short .do_byte ; 1 bytes variant
17583N/A int3
17583N/A
17583N/A.do_dword:
17583N/A ; load 2nd parameter's value
17583N/A mov eax, dword [ebx]
17583N/A
17583N/A lock cmpxchg dword [ecx], edx ; do 4 bytes CMPXCHG
17583N/A mov dword [ebx], eax
17583N/A jmp short .done
17583N/A
17583N/A.do_word:
17583N/A ; load 2nd parameter's value
17583N/A mov eax, dword [ebx]
17583N/A
17583N/A lock cmpxchg word [ecx], dx ; do 2 bytes CMPXCHG
17583N/A mov word [ebx], ax
17583N/A jmp short .done
17583N/A
17583N/A.do_byte:
17583N/A ; load 2nd parameter's value
10139N/A mov eax, dword [ebx]
10139N/A
17583N/A lock cmpxchg byte [ecx], dl ; do 1 bytes CMPXCHG
10139N/A mov byte [ebx], al
10139N/A
17583N/A.done:
10139N/A ; collect flags and return.
17583N/A pushf
17583N/A pop eax
17583N/A
17583N/A pop ebx
17583N/A retn
17583N/A
17583N/AENDPROC EMEmulateLockCmpXchg32
17583N/A
17583N/A;;
17583N/A; Emulate CMPXCHG instruction, CDECL calling conv.
17583N/A; EMDECL(uint32_t) EMEmulateCmpXchg32(RTHCPTR pu32Param1, uint32_t *pu32Param2, uint32_t u32Param3, size_t cbSize);
17583N/A;
17583N/A; @returns EFLAGS after the operation, only arithmetic flags is valid.
17583N/A; @param [esp + 04h] gcc:rdi msc:rcx Param 1 - First parameter - pointer to first parameter
10139N/A; @param [esp + 08h] gcc:rsi msc:rdx Param 2 - pointer to second parameter (eax)
10139N/A; @param [esp + 0ch] gcc:rdx msc:r8 Param 3 - third parameter
17583N/A; @param [esp + 10h] gcc:rcx msc:r9 Param 4 - Size of parameters, only 1/2/4 is valid.
17583N/A; @uses eax, ecx, edx
17583N/A;
17583N/Aalign 16
17583N/ABEGINPROC EMEmulateCmpXchg32
17583N/A push ebx
17583N/A mov ecx, [esp + 04h + 4] ; ecx = first parameter
17583N/A mov ebx, [esp + 08h + 4] ; ebx = 2nd parameter (eax)
17583N/A mov edx, [esp + 0ch + 4] ; edx = third parameter
10139N/A mov eax, [esp + 10h + 4] ; eax = size of parameters
17583N/A
17583N/A cmp al, 4
17583N/A je short .do_dword ; 4 bytes variant
17583N/A cmp al, 2
17583N/A je short .do_word ; 2 byte variant
10139N/A cmp al, 1
17583N/A je short .do_byte ; 1 bytes variant
17583N/A int3
17583N/A
17583N/A.do_dword:
17583N/A ; load 2nd parameter's value
17583N/A mov eax, dword [ebx]
17583N/A
17583N/A cmpxchg dword [ecx], edx ; do 4 bytes CMPXCHG
17583N/A mov dword [ebx], eax
17583N/A jmp short .done
17583N/A
17583N/A.do_word:
17583N/A ; load 2nd parameter's value
17583N/A mov eax, dword [ebx]
10139N/A
10139N/A cmpxchg word [ecx], dx ; do 2 bytes CMPXCHG
10139N/A mov word [ebx], ax
17583N/A jmp short .done
10139N/A
17583N/A.do_byte:
17583N/A ; load 2nd parameter's value
17583N/A mov eax, dword [ebx]
17583N/A
17583N/A cmpxchg byte [ecx], dl ; do 1 bytes CMPXCHG
17583N/A mov byte [ebx], al
17583N/A
17583N/A.done:
17583N/A ; collect flags and return.
17583N/A pushf
17583N/A pop eax
17583N/A
17583N/A pop ebx
17583N/A retn
17583N/A
17583N/AENDPROC EMEmulateCmpXchg32
17583N/A
17583N/A;;
17583N/A; Emulate LOCK CMPXCHG8B instruction, CDECL calling conv.
17583N/A; EMDECL(uint32_t) EMEmulateLockCmpXchg8b(RTHCPTR pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX);
17583N/A;
17583N/A; @returns EFLAGS after the operation, only arithmetic flags is valid.
17583N/A; @param [esp + 04h] Param 1 - First parameter - pointer to first parameter
17583N/A; @param [esp + 08h] Param 2 - Address of the eax register
17583N/A; @param [esp + 0ch] Param 3 - Address of the edx register
17583N/A; @param [esp + 10h] Param 4 - EBX
17583N/A; @param [esp + 14h] Param 5 - ECX
17583N/A; @uses eax, ecx, edx
17583N/A;
17583N/Aalign 16
17583N/ABEGINPROC EMEmulateLockCmpXchg8b32
17583N/A push ebp
17583N/A push ebx
10139N/A mov ebp, [esp + 04h + 8] ; ebp = first parameter
10139N/A mov eax, [esp + 08h + 8] ; &EAX
17583N/A mov eax, dword [eax]
17583N/A mov edx, [esp + 0ch + 8] ; &EDX
17583N/A mov edx, dword [edx]
17583N/A mov ebx, [esp + 10h + 8] ; EBX
17583N/A mov ecx, [esp + 14h + 8] ; ECX
17583N/A
17583N/A lock cmpxchg8b qword [ebp] ; do CMPXCHG8B
17583N/A mov ebx, dword [esp + 08h + 8]
17583N/A mov dword [ebx], eax
17583N/A mov ebx, dword [esp + 0ch + 8]
17583N/A mov dword [ebx], edx
17583N/A
17583N/A ; collect flags and return.
17583N/A pushf
17583N/A pop eax
17583N/A
17583N/A pop ebx
10139N/A pop ebp
17583N/A retn
17583N/A
17583N/AENDPROC EMEmulateLockCmpXchg8b32
17583N/A
17583N/A;;
10139N/A; Emulate CMPXCHG8B instruction, CDECL calling conv.
17583N/A; EMDECL(uint32_t) EMEmulateCmpXchg8b32(RTHCPTR pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX);
17583N/A;
17583N/A; @returns EFLAGS after the operation, only arithmetic flags is valid.
17583N/A; @param [esp + 04h] Param 1 - First parameter - pointer to first parameter
17583N/A; @param [esp + 08h] Param 2 - Address of the eax register
17583N/A; @param [esp + 0ch] Param 3 - Address of the edx register
17583N/A; @param [esp + 10h] Param 4 - EBX
17583N/A; @param [esp + 14h] Param 5 - ECX
17583N/A; @uses eax, ecx, edx
17583N/A;
17583N/Aalign 16
10139N/ABEGINPROC EMEmulateCmpXchg8b32
17583N/A push ebp
17583N/A push ebx
17583N/A mov ebp, [esp + 04h + 8] ; ebp = first parameter
10139N/A mov eax, [esp + 08h + 8] ; &EAX
17583N/A mov eax, dword [eax]
17583N/A mov edx, [esp + 0ch + 8] ; &EDX
17583N/A mov edx, dword [edx]
17583N/A mov ebx, [esp + 10h + 8] ; EBX
17583N/A mov ecx, [esp + 14h + 8] ; ECX
17583N/A
17583N/A cmpxchg8b qword [ebp] ; do CMPXCHG8B
10139N/A mov ebx, dword [esp + 08h + 8]
10139N/A mov dword [ebx], eax
10139N/A mov ebx, dword [esp + 0ch + 8]
10139N/A mov dword [ebx], edx
17583N/A
17583N/A ; collect flags and return.
17583N/A pushf
17583N/A pop eax
10139N/A
10139N/A pop ebx
17583N/A pop ebp
17583N/A retn
17583N/AENDPROC EMEmulateCmpXchg8b32
17583N/A
17583N/A%endif
17583N/A