From 986b4fdf939e9463ef08cb9b0c930de4622283ad Mon Sep 17 00:00:00 2001 From: "Jake.Stine" Date: Thu, 16 Apr 2009 01:39:38 +0000 Subject: [PATCH] Forgot to add a new file from the last commit... >_< [ix86_impl_dwshift.h] git-svn-id: http://pcsx2.googlecode.com/svn/trunk@987 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/x86/ix86/ix86_impl_dwshift.h | 124 +++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 pcsx2/x86/ix86/ix86_impl_dwshift.h diff --git a/pcsx2/x86/ix86/ix86_impl_dwshift.h b/pcsx2/x86/ix86/ix86_impl_dwshift.h new file mode 100644 index 0000000000..db7fe4ca3f --- /dev/null +++ b/pcsx2/x86/ix86/ix86_impl_dwshift.h @@ -0,0 +1,124 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#pragma once + +// Header: ix86_impl_dwshift.h -- covers SHLD and SHRD. +// Note: This header is meant to be included from within the x86Emitter::Internal namespace. + + +// ------------------------------------------------------------------- +// Optimization Note: Imm shifts by 0 are ignore (no code generated). This is a safe optimization +// because shifts by 0 do *not* affect flags status. + +template< typename ImmType, bool isShiftRight > +class DwordShiftImpl +{ +public: + static const uint OperandSize = sizeof(ImmType); + + DwordShiftImpl() {} // because GCC doesn't like static classes + +protected: + static bool Is8BitOperand() { return OperandSize == 1; } + static void prefix16() { if( OperandSize == 2 ) iWrite( 0x66 ); } + static void basesibform( bool isCL ) + { + prefix16(); + write8( 0x0f ); + write8( (isCL ? 0xa5 : 0xa4) | (isShiftRight ? 0x8 : 0) ); + } + +public: + static __emitinline void Emit( const iRegister& to, const iRegister& from ) + { + prefix16(); + write16( 0xa50f | (isShiftRight ? 0x800 : 0) ); + ModRM( 3, from.Id, to.Id ); + } + + static __emitinline void Emit( const iRegister& to, const iRegister& from, u8 imm ) + { + if( imm == 0 ) return; + prefix16(); + write16( 0xa40f | (isShiftRight ? 0x800 : 0) ); + ModRM( 3, from.Id, to.Id ); + write8( imm ); + } + + static __emitinline void Emit( const ModSibBase& sibdest, const iRegister& from, __unused const iRegisterCL& clreg ) + { + basesibform(); + EmitSibMagic( from.Id, sibdest ); + } + + static __emitinline void Emit( const ModSibBase& sibdest, const iRegister& from, u8 imm ) + { + basesibform(); + EmitSibMagic( from.Id, sibdest ); + write8( imm ); + } + + // dest data type is inferred from the 'from' register, so we can do void* resolution :) + static __emitinline void Emit( void* dest, const iRegister& from, __unused const iRegisterCL& clreg ) + { + basesibform(); + iWriteDisp( from.Id, dest ); + } + + // dest data type is inferred from the 'from' register, so we can do void* resolution :) + static __emitinline void Emit( void* dest, const iRegister& from, u8 imm ) + { + basesibform(); + iWriteDisp( from.Id, dest ); + write8( imm ); + } +}; + + +// ------------------------------------------------------------------- +// +template< bool isShiftRight > +class DwordShiftImplAll +{ +protected: + typedef DwordShiftImpl m_32; + typedef DwordShiftImpl m_16; + + // (Note: I'm not going to macro this since it would likely clobber intellisense parameter resolution) + +public: + // ---------- 32 Bit Interface ----------- + __forceinline void operator()( const iRegister32& to, const iRegister32& from, __unused const iRegisterCL& clreg ) const { m_32::Emit( to, from ); } + __forceinline void operator()( void* dest, const iRegister32& from, __unused const iRegisterCL& clreg ) const { m_32::Emit( dest, from ); } + __noinline void operator()( const ModSibBase& sibdest, const iRegister32& from, __unused const iRegisterCL& clreg ) const { m_32::Emit( sibdest, from ); } + __forceinline void operator()( const iRegister32& to, const iRegister32& from, u8 imm ) const { m_32::Emit( to, from, imm ); } + __forceinline void operator()( void* dest, const iRegister32& from, u8 imm ) const { m_32::Emit( dest, from, imm ); } + __noinline void operator()( const ModSibBase& sibdest, const iRegister32& from, u8 imm ) const { m_32::Emit( sibdest, from ); } + + // ---------- 16 Bit Interface ----------- + __forceinline void operator()( const iRegister16& to, const iRegister16& from, __unused const iRegisterCL& clreg ) const { m_16::Emit( to, from ); } + __forceinline void operator()( void* dest, const iRegister16& from, __unused const iRegisterCL& clreg ) const { m_16::Emit( dest, from ); } + __noinline void operator()( const ModSibBase& sibdest, const iRegister16& from, __unused const iRegisterCL& clreg ) const { m_16::Emit( sibdest, from ); } + __forceinline void operator()( const iRegister16& to, const iRegister16& from, u8 imm ) const { m_16::Emit( to, from, imm ); } + __forceinline void operator()( void* dest, const iRegister16& from, u8 imm ) const { m_16::Emit( dest, from, imm ); } + __noinline void operator()( const ModSibBase& sibdest, const iRegister16& from, u8 imm ) const { m_16::Emit( sibdest, from ); } + + DwordShiftImplAll() {} // Why does GCC need these? +}; +