IEMAllAImpl.asm revision 58b7ab82f43487a8a838dbeb96387c0d27b527f1
ea7d33962ceb90ea90e67e427d60b5788f34268avboxsync; IEM - Instruction Implementation in Assembly.
65b0f0cd3c38007138720b7eaa43c963a9ee1244vboxsync; Copyright (C) 2011 Oracle Corporation
65b0f0cd3c38007138720b7eaa43c963a9ee1244vboxsync; This file is part of VirtualBox Open Source Edition (OSE), as
65b0f0cd3c38007138720b7eaa43c963a9ee1244vboxsync; available from http://www.virtualbox.org. This file is free software;
65b0f0cd3c38007138720b7eaa43c963a9ee1244vboxsync; you can redistribute it and/or modify it under the terms of the GNU
65b0f0cd3c38007138720b7eaa43c963a9ee1244vboxsync; General Public License (GPL) as published by the Free Software
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync; Foundation, in version 2 as it comes in the "COPYING" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync; Header Files ;
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
65b0f0cd3c38007138720b7eaa43c963a9ee1244vboxsync;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
cf57145d4697dceca3f0542b370c20f7a2c5c6e8vboxsync; Defined Constants And Macros ;
cf57145d4697dceca3f0542b370c20f7a2c5c6e8vboxsync;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
65b0f0cd3c38007138720b7eaa43c963a9ee1244vboxsync; RET XX / RET wrapper for fastcall.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync%macro RET_FASTCALL 1
c0cb47bd8aa02fca08ff72a37ba5c65894241cbfvboxsync%ifdef RT_ARCH_X86
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync %ifdef RT_OS_WINDOWS
e52b0dfe3d9ead70e24f2ce4ed3faa6c79c00618vboxsync; NAME for fastcall functions.
e52b0dfe3d9ead70e24f2ce4ed3faa6c79c00618vboxsync;; @todo 'global @fastcall@12' is still broken in yasm and requires dollar
e52b0dfe3d9ead70e24f2ce4ed3faa6c79c00618vboxsync; escaping (or whatever the dollar is good for here). Thus the ugly
e52b0dfe3d9ead70e24f2ce4ed3faa6c79c00618vboxsync; prefix argument.
e52b0dfe3d9ead70e24f2ce4ed3faa6c79c00618vboxsync%define NAME_FASTCALL(a_Name, a_cbArgs, a_Dollar) NAME(a_Name)
c320aee99660824809e157bbad368db3542a9e90vboxsync%ifdef RT_ARCH_X86
c0cb47bd8aa02fca08ff72a37ba5c65894241cbfvboxsync %ifdef RT_OS_WINDOWS
c320aee99660824809e157bbad368db3542a9e90vboxsync %undef NAME_FASTCALL
c0cb47bd8aa02fca08ff72a37ba5c65894241cbfvboxsync %define NAME_FASTCALL(a_Name, a_cbArgs, a_Prefix) a_Prefix %+ a_Name %+ @ %+ a_cbArgs
ea7d33962ceb90ea90e67e427d60b5788f34268avboxsync; BEGINPROC for fastcall functions.
f9f72da3edbd8434dc722c26ee038e2808d691favboxsync; @param 1 The function name (C).
c0cb47bd8aa02fca08ff72a37ba5c65894241cbfvboxsync; @param 2 The argument size on x86.
c0cb47bd8aa02fca08ff72a37ba5c65894241cbfvboxsync%macro BEGINPROC_FASTCALL 2
881b5ff6bc55e1fb0f4ef42f9782ccec79c0a138vboxsync %ifdef ASM_FORMAT_PE
c0cb47bd8aa02fca08ff72a37ba5c65894241cbfvboxsync export %1=NAME_FASTCALL(%1,%2,$@)
c0cb47bd8aa02fca08ff72a37ba5c65894241cbfvboxsync %ifdef __NASM__
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync %ifdef ASM_FORMAT_OMF
c0cb47bd8aa02fca08ff72a37ba5c65894241cbfvboxsync export NAME(%1) NAME_FASTCALL(%1,%2,$@)
f2af1be3e27a2fefe95332260d360f4b26cffbcfvboxsync %ifndef ASM_FORMAT_BIN
f2af1be3e27a2fefe95332260d360f4b26cffbcfvboxsync global NAME_FASTCALL(%1,%2,$@)
c0cb47bd8aa02fca08ff72a37ba5c65894241cbfvboxsyncNAME_FASTCALL(%1,%2,@):
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync; We employ some macro assembly here to hid the calling convention differences.
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync%ifdef RT_ARCH_AMD64
c0cb47bd8aa02fca08ff72a37ba5c65894241cbfvboxsync %macro PROLOGUE_1_ARGS 0
c0cb47bd8aa02fca08ff72a37ba5c65894241cbfvboxsync %macro EPILOGUE_1_ARGS 1
f1c8438d14b7420eb2b916ef5981ac09faa4f6c4vboxsync %macro PROLOGUE_2_ARGS 0
c0cb47bd8aa02fca08ff72a37ba5c65894241cbfvboxsync %macro EPILOGUE_2_ARGS 1
c0cb47bd8aa02fca08ff72a37ba5c65894241cbfvboxsync %macro PROLOGUE_3_ARGS 0
c0cb47bd8aa02fca08ff72a37ba5c65894241cbfvboxsync %macro EPILOGUE_3_ARGS 1
46f5824f3e233b92bad1626932d5ce9522886f54vboxsync %macro PROLOGUE_4_ARGS 0
46f5824f3e233b92bad1626932d5ce9522886f54vboxsync %macro EPILOGUE_4_ARGS 1
c0cb47bd8aa02fca08ff72a37ba5c65894241cbfvboxsync %ifdef ASM_CALL64_GCC
881b5ff6bc55e1fb0f4ef42f9782ccec79c0a138vboxsync %define A0 rdi
c0cb47bd8aa02fca08ff72a37ba5c65894241cbfvboxsync %define A0_32 edi
881b5ff6bc55e1fb0f4ef42f9782ccec79c0a138vboxsync %define A0_16 di
c0cb47bd8aa02fca08ff72a37ba5c65894241cbfvboxsync %define A0_8 dil
63e576f3c901db19ac9a11f2353025b66a6798eevboxsync %define A1 rsi
881b5ff6bc55e1fb0f4ef42f9782ccec79c0a138vboxsync %define A1_32 esi
c0cb47bd8aa02fca08ff72a37ba5c65894241cbfvboxsync %define A1_16 si
881b5ff6bc55e1fb0f4ef42f9782ccec79c0a138vboxsync %define A1_8 sil
881b5ff6bc55e1fb0f4ef42f9782ccec79c0a138vboxsync %define A2 rdx
c0cb47bd8aa02fca08ff72a37ba5c65894241cbfvboxsync %define A2_32 edx
881b5ff6bc55e1fb0f4ef42f9782ccec79c0a138vboxsync %define A2_16 dx
c0cb47bd8aa02fca08ff72a37ba5c65894241cbfvboxsync %define A2_8 dl
c0cb47bd8aa02fca08ff72a37ba5c65894241cbfvboxsync %define A3 rcx
0b4890533cbae4f30a0241d0780d4ff9daa304f4vboxsync %define A3_32 ecx
c0cb47bd8aa02fca08ff72a37ba5c65894241cbfvboxsync %define A3_16 cx
7e33622becf3d7cf9a2401ac0c53d315877f6e34vboxsync %ifdef ASM_CALL64_MSC
c0cb47bd8aa02fca08ff72a37ba5c65894241cbfvboxsync %define A0 rcx
7e33622becf3d7cf9a2401ac0c53d315877f6e34vboxsync %define A0_32 ecx
c0cb47bd8aa02fca08ff72a37ba5c65894241cbfvboxsync %define A0_16 cx
a1e9b93d4f2b32d7a2aac1fb6ee958e1d147197cvboxsync %define A0_8 cl
a1e9b93d4f2b32d7a2aac1fb6ee958e1d147197cvboxsync %define A1 rdx
a1e9b93d4f2b32d7a2aac1fb6ee958e1d147197cvboxsync %define A1_32 edx
881b5ff6bc55e1fb0f4ef42f9782ccec79c0a138vboxsync %define A1_16 dx
c0cb47bd8aa02fca08ff72a37ba5c65894241cbfvboxsync %define A1_8 dl
c0cb47bd8aa02fca08ff72a37ba5c65894241cbfvboxsync %define A2 r8
20593760b116c90f3e439552763eef632a3bbb17vboxsync %define A2_32 r8d
c0cb47bd8aa02fca08ff72a37ba5c65894241cbfvboxsync %define A2_16 r8w
881b5ff6bc55e1fb0f4ef42f9782ccec79c0a138vboxsync %define A2_8 r8b
8c3ab623787ffed571ef7a1fa8c1a98e22d28021vboxsync %define A3 r9
96d5bb6dc5895c648c1f60b3d4faef7b93404756vboxsync %define A3_32 r9d
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync %define A3_16 r9w
c0cb47bd8aa02fca08ff72a37ba5c65894241cbfvboxsync %define T0 rax
881b5ff6bc55e1fb0f4ef42f9782ccec79c0a138vboxsync %define T0_32 eax
c0cb47bd8aa02fca08ff72a37ba5c65894241cbfvboxsync %define T0_16 ax
65b0f0cd3c38007138720b7eaa43c963a9ee1244vboxsync %define T0_8 al
d1ae44110ca869b6cb4a708dc6d676e10f4167bavboxsync %define T1 r11
c0cb47bd8aa02fca08ff72a37ba5c65894241cbfvboxsync %define T1_32 r11d
2cf084f1df635fcf1e1e40547a96c33f723471cbvboxsync %define T1_16 r11w
c0cb47bd8aa02fca08ff72a37ba5c65894241cbfvboxsync %define T1_8 r11b
0028894c239c48232c9e516e73ba2205d8438a6avboxsync %macro PROLOGUE_1_ARGS 0
0028894c239c48232c9e516e73ba2205d8438a6avboxsync %macro EPILOGUE_1_ARGS 1
ac6ede0b256f7583f8673aef5347770437c003davboxsync %macro PROLOGUE_2_ARGS 0
ac6ede0b256f7583f8673aef5347770437c003davboxsync %macro EPILOGUE_2_ARGS 1
ac6ede0b256f7583f8673aef5347770437c003davboxsync %macro PROLOGUE_3_ARGS 0
ac6ede0b256f7583f8673aef5347770437c003davboxsync mov ebx, [esp + 4 + 4]
ac6ede0b256f7583f8673aef5347770437c003davboxsync %macro EPILOGUE_3_ARGS 1
ac6ede0b256f7583f8673aef5347770437c003davboxsync %macro PROLOGUE_4_ARGS 0
ac6ede0b256f7583f8673aef5347770437c003davboxsync mov ebx, [esp + 12 + 4 + 0]
ac6ede0b256f7583f8673aef5347770437c003davboxsync mov esi, [esp + 12 + 4 + 4]
ac6ede0b256f7583f8673aef5347770437c003davboxsync %macro EPILOGUE_4_ARGS 1
; @param 1 The parameter (A0..A3) pointing to the eflags.
IEMIMPL_BIN_OP add, 1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
IEMIMPL_BIN_OP adc, 1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
IEMIMPL_BIN_OP sub, 1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
IEMIMPL_BIN_OP sbb, 1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
IEMIMPL_BIN_OP xor, 1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), X86_EFL_AF,
IEMIMPL_BIN_OP and, 1, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), X86_EFL_AF,
IEMIMPL_BIN_OP cmp, 0, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
IEMIMPL_BIN_OP test, 0, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), X86_EFL_AF,
IEMIMPL_BIT_OP bt, 0, (X86_EFL_CF), (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
IEMIMPL_BIT_OP btc, 1, (X86_EFL_CF), (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
IEMIMPL_BIT_OP bts, 1, (X86_EFL_CF), (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
IEMIMPL_BIT_OP btr, 1, (X86_EFL_CF), (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_CF), (X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_CF), (X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_CF), (X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF)
; memory/register, then the pointer to the register, and finally a pointer to
IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
IEM_MAYBE_LOAD_FLAGS A2, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
IEMIMPL_UNARY_OP neg, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF), 0
IEMIMPL_SHIFT_OP shl, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), (X86_EFL_AF)
IEMIMPL_SHIFT_OP shr, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), (X86_EFL_AF)
IEMIMPL_SHIFT_OP sar, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), (X86_EFL_AF)
; A1, the shift count in A2 and a pointer to the eflags variable/register in A3.
IEMIMPL_SHIFT_DBL_OP shld, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), (X86_EFL_AF)
IEMIMPL_SHIFT_DBL_OP shrd, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF | X86_EFL_CF), (X86_EFL_AF)
; The functions all return 0 so the caller can be used for div/idiv as well as
; for the mul/imul implementation.
IEMIMPL_DIV_OP div, 0, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF)
IEMIMPL_DIV_OP idiv, 0, (X86_EFL_OF | X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF)
; (input/output). They all return void.
; @todo move to x86.mac.
movzx T0, word [%1 + X86FXSTATE.FCW]
fnstsw word [A1 + IEMFPURESULT.FSW]
fstp tword [A1 + IEMFPURESULT.r80Result]
fnstsw word [A1 + IEMFPURESULT.FSW]
fstp tword [A1 + IEMFPURESULT.r80Result]