///////////////////////////////////////////////////////////////////////// // $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