Bochs/bochs/cpu/hostasm.h

665 lines
15 KiB
C
Raw Normal View History

/////////////////////////////////////////////////////////////////////////
// $Id: hostasm.h,v 1.1 2004-02-15 17:57:44 cbothamy Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
//
// MandrakeSoft S.A.
// 43, rue d'Aboukir
// 75002 Paris - France
// http://www.linux-mandrake.com/
// http://www.mandrakesoft.com/
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#ifndef BX_HOSTASM_H
# define BX_HOSTASM_H 1
// This file defines some convience inline functions which do the
// dirty work of asm() statements for arithmetic instructions on x86 hosts.
// Essentially these speed up eflags processing since the value of the
// eflags register can be read directly on x86 hosts, after the
// arithmetic operations.
// gcc on i386
#if (defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
#define BX_HostAsm_Add16
static inline void
asmAdd16(Bit16u &sum_16, Bit16u op1_16, Bit16u op2_16, Bit32u &flags32)
{
asm (
"addw %3, %1 \n\t"
"pushfl \n\t"
"popl %0"
: "=g" (flags32), "=r" (sum_16)
: "1" (op1_16), "g" (op2_16)
: "cc"
);
}
#define BX_HostAsm_Add32
static inline void
asmAdd32(Bit32u &sum_32, Bit32u op1_32, Bit32u op2_32, Bit32u &flags32)
{
asm (
"addl %3, %1 \n\t"
"pushfl \n\t"
"popl %0"
: "=g" (flags32), "=r" (sum_32)
: "1" (op1_32), "g" (op2_32)
: "cc"
);
}
#define BX_HostAsm_Sub16
static inline void
asmSub16(Bit16u &diff_16, Bit16u op1_16, Bit16u op2_16, Bit32u &flags32)
{
asm (
"subw %3, %1\n\t"
"pushfl \n\t"
"popl %0"
: "=g" (flags32), "=r" (diff_16)
: "1" (op1_16), "g" (op2_16)
: "cc"
);
}
#define BX_HostAsm_Sub32
static inline void
asmSub32(Bit32u &diff_32, Bit32u op1_32, Bit32u op2_32, Bit32u &flags32)
{
asm (
"subl %3, %1\n\t"
"pushfl \n\t"
"popl %0"
: "=g" (flags32), "=r" (diff_32)
: "1" (op1_32), "g" (op2_32)
: "cc"
);
}
#define BX_HostAsm_Cmp8
static inline void
asmCmp8(Bit8u op1_8, Bit8u op2_8, Bit32u &flags32)
{
asm (
"cmpb %2, %1\n\t"
"pushfl \n\t"
"popl %0"
: "=g" (flags32)
: "q" (op1_8), "mq" (op2_8)
: "cc"
);
}
#define BX_HostAsm_Cmp16
static inline void
asmCmp16(Bit16u op1_16, Bit16u op2_16, Bit32u &flags32)
{
asm (
"cmpw %2, %1\n\t"
"pushfl \n\t"
"popl %0"
: "=g" (flags32)
: "r" (op1_16), "g" (op2_16)
: "cc"
);
}
#define BX_HostAsm_Cmp32
static inline void
asmCmp32(Bit32u op1_32, Bit32u op2_32, Bit32u &flags32)
{
asm (
"cmpl %2, %1\n\t"
"pushfl \n\t"
"popl %0"
: "=g" (flags32)
: "r" (op1_32), "g" (op2_32)
: "cc"
);
}
#define BX_HostAsm_Inc16
static inline void
asmInc16(Bit16u &op1_16, Bit32u &flags32)
{
asm (
"incw %1 \n\t"
"pushfl \n\t"
"popl %0"
: "=g" (flags32), "=g" (op1_16)
: "1" (op1_16)
: "cc"
);
}
#define BX_HostAsm_Inc32
static inline void
asmInc32(Bit32u &op1_32, Bit32u &flags32)
{
asm (
"incl %1 \n\t"
"pushfl \n\t"
"popl %0"
: "=g" (flags32), "=g" (op1_32)
: "1" (op1_32)
: "cc"
);
}
#define BX_HostAsm_Dec16
static inline void
asmDec16(Bit16u &op1_16, Bit32u &flags32)
{
asm (
"decw %1 \n\t"
"pushfl \n\t"
"popl %0"
: "=g" (flags32), "=g" (op1_16)
: "1" (op1_16)
: "cc"
);
}
#define BX_HostAsm_Dec32
static inline void
asmDec32(Bit32u &op1_32, Bit32u &flags32)
{
asm (
"decl %1 \n\t"
"pushfl \n\t"
"popl %0"
: "=g" (flags32), "=g" (op1_32)
: "1" (op1_32)
: "cc"
);
}
#define BX_HostAsm_Xor16
static inline void
asmXor16(Bit16u &result_16, Bit16u op1_16, Bit16u op2_16, Bit32u &flags32)
{
asm (
"xorw %3, %1 \n\t"
"pushfl \n\t"
"popl %0"
: "=g" (flags32), "=r" (result_16)
: "1" (op1_16), "g" (op2_16)
: "cc"
);
}
#define BX_HostAsm_Xor32
static inline void
asmXor32(Bit32u &result_32, Bit32u op1_32, Bit32u op2_32, Bit32u &flags32)
{
asm (
"xorl %3, %1 \n\t"
"pushfl \n\t"
"popl %0"
: "=g" (flags32), "=r" (result_32)
: "1" (op1_32), "g" (op2_32)
: "cc"
);
}
#define BX_HostAsm_Or8
static inline void
asmOr8(Bit8u &result_8, Bit8u op1_8, Bit8u op2_8, Bit32u &flags32)
{
asm (
"orb %3, %1 \n\t"
"pushfl \n\t"
"popl %0"
: "=g" (flags32), "=q" (result_8)
: "1" (op1_8), "mq" (op2_8)
: "cc"
);
}
#define BX_HostAsm_Or16
static inline void
asmOr16(Bit16u &result_16, Bit16u op1_16, Bit16u op2_16, Bit32u &flags32)
{
asm (
"orw %3, %1 \n\t"
"pushfl \n\t"
"popl %0"
: "=g" (flags32), "=r" (result_16)
: "1" (op1_16), "g" (op2_16)
: "cc"
);
}
#define BX_HostAsm_Or32
static inline void
asmOr32(Bit32u &result_32, Bit32u op1_32, Bit32u op2_32, Bit32u &flags32)
{
asm (
"orl %3, %1 \n\t"
"pushfl \n\t"
"popl %0"
: "=g" (flags32), "=r" (result_32)
: "1" (op1_32), "g" (op2_32)
: "cc"
);
}
#define BX_HostAsm_And8
static inline void
asmAnd8(Bit8u &result_8, Bit8u op1_8, Bit8u op2_8, Bit32u &flags32)
{
asm (
"andb %3, %1\n\t"
"pushfl \n\t"
"popl %0"
: "=g" (flags32), "=q" (result_8)
: "1" (op1_8), "mq" (op2_8)
: "cc"
);
}
#define BX_HostAsm_And16
static inline void
asmAnd16(Bit16u &result_16, Bit16u op1_16, Bit16u op2_16, Bit32u &flags32)
{
asm (
"andw %3, %1 \n\t"
"pushfl \n\t"
"popl %0"
: "=g" (flags32), "=r" (result_16)
: "1" (op1_16), "g" (op2_16)
: "cc"
);
}
#define BX_HostAsm_And32
static inline void
asmAnd32(Bit32u &result_32, Bit32u op1_32, Bit32u op2_32, Bit32u &flags32)
{
asm (
"andl %3, %1 \n\t"
"pushfl \n\t"
"popl %0"
: "=g" (flags32), "=r" (result_32)
: "1" (op1_32), "g" (op2_32)
: "cc"
);
}
#define BX_HostAsm_Test8
static inline void
asmTest8(Bit8u op1_8, Bit8u op2_8, Bit32u &flags32)
{
asm (
"testb %2, %1\n\t"
"pushfl \n\t"
"popl %0"
: "=g" (flags32)
: "q" (op1_8), "mq" (op2_8)
: "cc"
);
}
#define BX_HostAsm_Test16
static inline void
asmTest16(Bit16u op1_16, Bit16u op2_16, Bit32u &flags32)
{
asm (
"testw %2, %1\n\t"
"pushfl \n\t"
"popl %0"
: "=g" (flags32)
: "r" (op1_16), "g" (op2_16)
: "cc"
);
}
#define BX_HostAsm_Test32
static inline void
asmTest32(Bit32u op1_32, Bit32u op2_32, Bit32u &flags32)
{
asm (
"testl %2, %1\n\t"
"pushfl \n\t"
"popl %0"
: "=g" (flags32)
: "r" (op1_32), "g" (op2_32)
: "cc"
);
}
#define BX_HostAsm_Shr16
static inline void
asmShr16(Bit16u &result_16, Bit16u op1_16, unsigned count, Bit32u &flags32)
{
asm (
"shrw %%cl, %1\n\t"
"pushfl \n\t"
"popl %0"
: "=g" (flags32), "=g" (result_16)
: "1" (op1_16), "c" (count)
: "cc"
);
}
#define BX_HostAsm_Shr32
static inline void
asmShr32(Bit32u &result_32, Bit32u op1_32, unsigned count, Bit32u &flags32)
{
asm (
"shrl %%cl, %1\n\t"
"pushfl \n\t"
"popl %0"
: "=g" (flags32), "=g" (result_32)
: "1" (op1_32), "c" (count)
: "cc"
);
}
#endif // (defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
// msvc++ on i386
#if (defined(_M_IX86) && defined(_MSC_VER) && BX_SupportHostAsms)
#define BX_HostAsm_Add16
// asmAdd16(Bit16u &sum_16, Bit16u op1_16, Bit16u op2_16, Bit32u &flags32)
#define asmAdd16(sum_16,op1_16,op2_16,flags32) \
__asm { \
__asm mov ax,op1_16 \
__asm add ax,op2_16 \
__asm pushfd \
__asm pop edx \
__asm mov sum_16,ax \
__asm mov flags32,edx \
}
#define BX_HostAsm_Add32
// asmAdd32(Bit32u &sum_32, Bit32u op1_32, Bit32u op2_32, Bit32u &flags32)
#define asmAdd32(sum_32,op1_32,op2_32,flags32) \
__asm { \
__asm mov eax,op1_32 \
__asm add eax,op2_32 \
__asm pushfd \
__asm pop edx \
__asm mov sum_32,eax \
__asm mov flags32,edx \
}
#define BX_HostAsm_Sub16
// asmSub16(Bit16u &diff_16, Bit16u op1_16, Bit16u op2_16, Bit32u &flags32)
#define asmSub16(diff_16,op1_16,op2_16,flags32) \
__asm { \
__asm mov ax,op1_16 \
__asm sub ax,op2_16 \
__asm pushfd \
__asm pop edx \
__asm mov diff_16,ax \
__asm mov flags32,edx \
}
#define BX_HostAsm_Sub32
// asmSub32(Bit32u &diff_32, Bit32u op1_32, Bit32u op2_32, Bit32u &flags32)
#define asmSub32(diff_32,op1_32,op2_32,flags32) \
__asm { \
__asm mov eax,op1_32 \
__asm sub eax,op2_32 \
__asm pushfd \
__asm pop edx \
__asm mov diff_32,eax \
__asm mov flags32,edx \
}
#define BX_HostAsm_Cmp8
// asmCmp8(Bit8u op1_8, Bit8u op2_8, Bit32u &flags32)
#define asmCmp8(op1_8,op2_8,flags32) \
__asm { \
__asm mov al,op1_8 \
__asm cmp al,op2_8 \
__asm pushfd \
__asm pop edx \
__asm mov flags32,edx \
}
#define BX_HostAsm_Cmp16
// asmCmp16(Bit16u op1_16, Bit16u op2_16, Bit32u &flags32)
#define asmCmp16(op1_16,op2_16,flags32) \
__asm { \
__asm mov ax,op1_16 \
__asm cmp ax,op2_16 \
__asm pushfd \
__asm pop edx \
__asm mov flags32,edx \
}
#define BX_HostAsm_Cmp32
// asmCmp32(Bit32u op1_32, Bit32u op2_32, Bit32u &flags32)
#define asmCmp32(op1_32,op2_32,flags32) \
__asm { \
__asm mov eax,op1_32 \
__asm cmp eax,op2_32 \
__asm pushfd \
__asm pop edx \
__asm mov flags32,edx \
}
// FIXME: cannot compile arith16.cc because of 'union'.
//#define BX_HostAsm_Inc16
// asmInc16(Bit16u &op1_16, Bit32u &flags32)
#define asmInc16(op1_16,flags32) \
__asm { \
__asm inc word ptr op1_16 \
__asm pushfd \
__asm pop edx \
__asm mov flags32,edx \
}
// FIXME: cannot compile arith32.cc because of 'union'.
//#define BX_HostAsm_Inc32
// asmInc32(Bit32u &op1_32, Bit32u &flags32)
#define asmInc32(op1_32,flags32) \
__asm { \
__asm inc dword ptr op1_32 \
__asm pushfd \
__asm pop edx \
__asm mov flags32,edx \
}
// FIXME: cannot compile arith16.cc because of 'union'.
//#define BX_HostAsm_Dec16
// asmDec16(Bit16u &op1_16, Bit32u &flags32)
#define asmDec16(op1_16,flags32) \
__asm { \
__asm dec word ptr op1_16 \
__asm pushfd \
__asm pop edx \
__asm mov flags32,edx \
}
// FIXME: cannot compile arith32.cc because of 'union'.
//#define BX_HostAsm_Dec32
// asmDec32(Bit32u &op1_32, Bit32u &flags32)
#define asmDec32(op1_32,flags32) \
__asm { \
__asm dec dword ptr op1_32 \
__asm pushfd \
__asm pop edx \
__asm mov flags32,edx \
}
#define BX_HostAsm_Xor16
// asmXor16(Bit16u &result_16, Bit16u op1_16, Bit16u op2_16, Bit32u &flags32)
#define asmXor16(result_16,op1_16,op2_16,flags32) \
__asm { \
__asm mov ax,op1_16 \
__asm xor ax,op2_16 \
__asm pushfd \
__asm pop edx \
__asm mov result_16,ax \
__asm mov flags32,edx \
}
#define BX_HostAsm_Xor32
// asmXor32(Bit32u &result_32, Bit32u op1_32, Bit32u op2_32, Bit32u &flags32)
#define asmXor32(result_32,op1_32,op2_32,flags32) \
__asm { \
__asm mov eax,op1_32 \
__asm xor eax,op2_32 \
__asm pushfd \
__asm pop edx \
__asm mov result_32,eax \
__asm mov flags32,edx \
}
#define BX_HostAsm_Or8
// asmOr8(Bit8u &result_8, Bit8u op1_8, Bit8u op2_8, Bit32u &flags32)
#define asmOr8(result_8,op1_8,op2_8,flags32) \
__asm { \
__asm mov al,op1_8 \
__asm or al,op2_8 \
__asm pushfd \
__asm pop edx \
__asm mov result_8,al \
__asm mov flags32,edx \
}
#define BX_HostAsm_Or16
// asmOr16(Bit16u &result_16, Bit16u op1_16, Bit16u op2_16, Bit32u &flags32)
#define asmOr16(result_16,op1_16,op2_16,flags32) \
__asm { \
__asm mov ax,op1_16 \
__asm or ax,op2_16 \
__asm pushfd \
__asm pop edx \
__asm mov result_16,ax \
__asm mov flags32,edx \
}
#define BX_HostAsm_Or32
// asmOr32(Bit32u &result_32, Bit32u op1_32, Bit32u op2_32, Bit32u &flags32)
#define asmOr32(result_32,op1_32,op2_32,flags32) \
__asm { \
__asm mov eax,op1_32 \
__asm or eax,op2_32 \
__asm pushfd \
__asm pop edx \
__asm mov result_32,eax \
__asm mov flags32,edx \
}
#define BX_HostAsm_And8
// asmAnd8(Bit8u &result_8, Bit8u op1_8, Bit8u op2_8, Bit32u &flags32)
#define asmAnd8(result_8,op1_8,op2_8,flags32) \
__asm { \
__asm mov al,op1_8 \
__asm and al,op2_8 \
__asm pushfd \
__asm pop edx \
__asm mov result_8,al \
__asm mov flags32,edx \
}
#define BX_HostAsm_And16
// asmAnd16(Bit16u &result_16, Bit16u op1_16, Bit16u op2_16, Bit32u &flags32)
#define asmAnd16(result_16,op1_16,op2_16,flags32) \
__asm { \
__asm mov ax,op1_16 \
__asm and ax,op2_16 \
__asm pushfd \
__asm pop edx \
__asm mov result_16,ax \
__asm mov flags32,edx \
}
#define BX_HostAsm_And32
// asmAnd32(Bit32u &result_32, Bit32u op1_32, Bit32u op2_32, Bit32u &flags32)
#define asmAnd32(result_32,op1_32,op2_32,flags32) \
__asm { \
__asm mov eax,op1_32 \
__asm and eax,op2_32 \
__asm pushfd \
__asm pop edx \
__asm mov result_32,eax \
__asm mov flags32,edx \
}
#define BX_HostAsm_Test8
// asmTest8(Bit8u op1_8, Bit8u op2_8, Bit32u &flags32)
#define asmTest8(op1_8,op2_8,flags32) \
__asm { \
__asm mov al,op1_8 \
__asm test al,op2_8 \
__asm pushfd \
__asm pop edx \
__asm mov flags32,edx \
}
#define BX_HostAsm_Test16
// asmTest16(Bit16u op1_16, Bit16u op2_16, Bit32u &flags32)
#define asmTest16(op1_16,op2_16,flags32) \
__asm { \
__asm mov ax,op1_16 \
__asm test ax,op2_16 \
__asm pushfd \
__asm pop edx \
__asm mov flags32,edx \
}
#define BX_HostAsm_Test32
// asmTest32(Bit32u op1_32, Bit32u op2_32, Bit32u &flags32)
#define asmTest32(op1_32,op2_32,flags32) \
__asm { \
__asm mov eax,op1_32 \
__asm test eax,op2_32 \
__asm pushfd \
__asm pop edx \
__asm mov flags32,edx \
}
#define BX_HostAsm_Shr16
// asmShr16(Bit16u &result_16, Bit16u op1_16, unsigned count, Bit32u &flags32)
#define asmShr16(result_16,op1_16,count,flags32) \
__asm { \
__asm mov ax,op1_16 \
__asm mov cl,byte ptr count \
__asm shr ax,cl \
__asm pushfd \
__asm pop edx \
__asm mov result_16,ax \
__asm mov flags32,edx \
}
#define BX_HostAsm_Shr32
// asmShr32(Bit32u &result_32, Bit32u op1_32, unsigned count, Bit32u &flags32)
#define asmShr32(result_32,op1_32,count,flags32) \
__asm { \
__asm mov eax,op1_32 \
__asm mov cl,byte ptr count \
__asm shr eax,cl \
__asm pushfd \
__asm pop edx \
__asm mov result_32,eax \
__asm mov flags32,edx \
}
#endif // (defined(_M_IX86) && defined(_MSC_VER) && BX_SupportHostAsms)
#endif // BX_HOSTASM_H