2009-07-28 21:32:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Copyright (C) 2003 Dolphin Project.
  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 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, version 2.0.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 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 2.0 for more details.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// A copy of the GPL 2.0 should have been included with the program.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// If not, see http://www.gnu.org/licenses/
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Official SVN repository and contact information can be found at
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// http://code.google.com/p/dolphin-emu/
  
						 
					
						
							
								
									
										
										
										
											2008-12-19 21:24:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "Common.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "x64Emitter.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "ABI.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "CPUDetect.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								namespace  Gen  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-19 21:24:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// TODO(ector): Add EAX special casing, for ever so slightly smaller code.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  NormalOpDef  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									u8  toRm8 ,  toRm32 ,  fromRm8 ,  fromRm32 ,  imm8 ,  imm32 ,  simm8 ,  ext ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  const  NormalOpDef  nops [ 11 ]  =   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 0x00 ,  0x01 ,  0x02 ,  0x03 ,  0x80 ,  0x81 ,  0x83 ,  0 } ,  //ADD
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 0x10 ,  0x11 ,  0x12 ,  0x13 ,  0x80 ,  0x81 ,  0x83 ,  2 } ,  //ADC
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 0x28 ,  0x29 ,  0x2A ,  0x2B ,  0x80 ,  0x81 ,  0x83 ,  5 } ,  //SUB
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 0x18 ,  0x19 ,  0x1A ,  0x1B ,  0x80 ,  0x81 ,  0x83 ,  3 } ,  //SBB
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 0x20 ,  0x21 ,  0x22 ,  0x23 ,  0x80 ,  0x81 ,  0x83 ,  4 } ,  //AND
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 0x08 ,  0x09 ,  0x0A ,  0x0B ,  0x80 ,  0x81 ,  0x83 ,  1 } ,  //OR
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 0x30 ,  0x31 ,  0x32 ,  0x33 ,  0x80 ,  0x81 ,  0x83 ,  6 } ,  //XOR
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 0x88 ,  0x89 ,  0x8A ,  0x8B ,  0xC6 ,  0xC7 ,  0xCC ,  0 } ,  //MOV
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 0x84 ,  0x85 ,  0x84 ,  0x85 ,  0xF6 ,  0xF7 ,  0xCC ,  0 } ,  //TEST (to == from)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 0x38 ,  0x39 ,  0x3A ,  0x3B ,  0x80 ,  0x81 ,  0x83 ,  7 } ,  //CMP
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 0x86 ,  0x87 ,  0x86 ,  0x87 ,  0xCC ,  0xCC ,  0xCC ,  7 } ,  //XCHG
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								enum  NormalSSEOps  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sseCMP  =          0xC2 ,  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sseADD  =          0x58 ,  //ADD
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sseSUB  = 		 0x5C ,  //SUB
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sseAND  = 		 0x54 ,  //AND
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sseANDN  = 		 0x55 ,  //ANDN
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sseOR   =          0x56 ,  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sseXOR   =         0x57 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sseMUL  = 		 0x59 ,  //MUL,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sseDIV  = 		 0x5E ,  //DIV
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sseMIN  = 		 0x5D ,  //MIN
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sseMAX  = 		 0x5F ,  //MAX
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sseCOMIS  = 		 0x2F ,  //COMIS
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sseUCOMIS  = 		 0x2E ,  //UCOMIS
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sseSQRT  = 		 0x51 ,  //SQRT
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sseRSQRT  = 		 0x52 ,  //RSQRT (NO DOUBLE PRECISION!!!)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sseMOVAPfromRM  =  0x28 ,  //MOVAP from RM
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sseMOVAPtoRM  = 	 0x29 ,  //MOVAP to RM
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sseMOVUPfromRM  =  0x10 ,  //MOVUP from RM
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sseMOVUPtoRM  = 	 0x11 ,  //MOVUP to RM
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sseMASKMOVDQU  =   0xF7 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sseLDDQU       =   0xF0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sseSHUF        =   0xC6 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sseMOVNTDQ      =  0xE7 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sseMOVNTP       =  0x2B , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : SetCodePtr ( u8  * ptr )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									code  =  ptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  u8  * XEmitter : : GetCodePtr ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  code ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								u8  * XEmitter : : GetWritableCodePtr ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  code ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : ReserveCodeSpace ( int  bytes )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( int  i  =  0 ;  i  <  bytes ;  i + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* code + +  =  0xCC ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  u8  * XEmitter : : AlignCode4 ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  c  =  int ( ( u64 ) code  &  3 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( c ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ReserveCodeSpace ( 4 - c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  code ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  u8  * XEmitter : : AlignCode16 ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  c  =  int ( ( u64 ) code  &  15 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( c ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ReserveCodeSpace ( 16 - c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  code ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  u8  * XEmitter : : AlignCodePage ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  c  =  int ( ( u64 ) code  &  4095 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( c ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ReserveCodeSpace ( 4096 - c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  code ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : WriteModRM ( int  mod ,  int  rm ,  int  reg )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( ( u8 ) ( ( mod  < <  6 )  |  ( ( rm  &  7 )  < <  3 )  |  ( reg  &  7 ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : WriteSIB ( int  scale ,  int  index ,  int  base )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( ( u8 ) ( ( scale  < <  6 )  |  ( ( index  &  7 )  < <  3 )  |  ( base  &  7 ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  OpArg : : WriteRex ( XEmitter  * emit ,  bool  op64 ,  int  customOp )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef _M_X64 
  
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									u8  op  =  0x40 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( customOp  = =  - 1 )        customOp  =  operandReg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( op64 )                  op  | =  8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( customOp  > >  3 )         op  | =  4 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( indexReg  > >  3 )         op  | =  2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( offsetOrBaseReg  > >  3 )  op  | =  1 ;  //TODO investigate if this is dangerous
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( op  ! =  0x40 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										emit - > Write8 ( op ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# else 
  
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_dbg_assert_ ( DYNA_REC ,  ( operandReg  > >  3 )  = =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									_dbg_assert_ ( DYNA_REC ,  ( indexReg  > >  3 )  = =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									_dbg_assert_ ( DYNA_REC ,  ( offsetOrBaseReg  > >  3 )  = =  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  OpArg : : WriteRest ( XEmitter  * emit ,  int  extraBytes ,  X64Reg  _operandReg )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( _operandReg  = =  0xff ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_operandReg  =  ( X64Reg ) this - > operandReg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  mod  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  ireg  =  indexReg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bool  SIB  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  _offsetOrBaseReg  =  this - > offsetOrBaseReg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( scale  = =  SCALE_RIP )  //Also, on 32-bit, just an immediate address
 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Oh, RIP addressing. 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_offsetOrBaseReg  =  5 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										emit - > WriteModRM ( 0 ,  _operandReg & 7 ,  5 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										//TODO : add some checks
 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef _M_X64 
  
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										u64  ripAddr  =  ( u64 ) emit - > GetCodePtr ( )  +  4  +  extraBytes ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-26 19:37:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										s64  distance  =  ( s64 ) offset  -  ( s64 ) ripAddr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( distance  > =  0x0000000080000000LL 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    | |  distance  <   - 0x0000000080000000LL )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-05 15:59:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    PanicAlert ( " WriteRest: op out of range (0x%llx uses 0x%llx) " ,  ripAddr ,  offset ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-26 19:37:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s32  offs  =  ( s32 ) distance ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										emit - > Write32 ( ( u32 ) offs ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# else 
  
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										emit - > Write32 ( ( u32 ) offset ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( scale  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Oh, no memory, Just a reg.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mod  =  3 ;  //11
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else  if  ( scale  > =  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										//Ah good, no scaling.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( scale  = =  SCALE_ATREG  & &  ! ( ( _offsetOrBaseReg  &  7 )  = =  4  | |  ( _offsetOrBaseReg  &  7 )  = =  5 ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											//Okay, we're good. No SIB necessary.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											int  ioff  =  ( int ) offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ioff  = =  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												mod  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											else  if  ( ioff < - 128  | |  ioff > 127 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												mod  =  2 ;  //32-bit displacement
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											else 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												mod  =  1 ;  //8-bit displacement
 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										else  //if (scale != SCALE_ATREG)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ( _offsetOrBaseReg  &  7 )  = =  4 )  //this would occupy the SIB encoding :(
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												//So we have to fake it with SIB encoding :(
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												SIB  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( scale  > =  SCALE_1  & &  scale  <  SCALE_ATREG ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												SIB  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( scale  = =  SCALE_ATREG  & &  ( ( _offsetOrBaseReg  &  7 )  = =  4 ) )  
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												SIB  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ireg  =  _offsetOrBaseReg ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											//Okay, we're fine. Just disp encoding.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											//We need displacement. Which size?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											int  ioff  =  ( int ) ( s64 ) offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ioff  <  - 128  | |  ioff  >  127 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												mod  =  2 ;  //32-bit displacement
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												mod  =  1 ;  //8-bit displacement
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Okay. Time to do the actual writing
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// ModRM byte:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  oreg  =  _offsetOrBaseReg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( SIB ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										oreg  =  4 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// TODO(ector): WTF is this if about? I don't remember writing it :-)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//if (RIP)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//    oreg = 5;
 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									emit - > WriteModRM ( mod ,  _operandReg & 7 ,  oreg & 7 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( SIB ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										//SIB byte
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  ss ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( scale ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  0 :  _offsetOrBaseReg  =  4 ;  ss  =  0 ;  break ;  //RSP 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  1 :  ss  =  0 ;  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  2 :  ss  =  1 ;  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  4 :  ss  =  2 ;  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  8 :  ss  =  3 ;  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  SCALE_ATREG :  ss  =  0 ;  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default :  _assert_msg_ ( DYNA_REC ,  0 ,  " Invalid scale for SIB byte " ) ;  ss  =  0 ;  break ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										emit - > Write8 ( ( u8 ) ( ( ss  < <  6 )  |  ( ( ireg & 7 ) < < 3 )  |  ( _offsetOrBaseReg & 7 ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( mod  = =  1 )  //8-bit disp
 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										emit - > Write8 ( ( u8 ) ( s8 ) ( s32 ) offset ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else  if  ( mod  = =  2 )  //32-bit disp
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										emit - > Write32 ( ( u32 ) offset ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// W = operand extended width (1 if 64-bit)
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// R = register# upper bit
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// X = scale amnt upper bit
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// B = base register# upper bit
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : Rex ( int  w ,  int  r ,  int  x ,  int  b )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									w  =  w  ?  1  :  0 ; 		
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									r  =  r  ?  1  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									x  =  x  ?  1  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									b  =  b  ?  1  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									u8  rx  =  ( u8 ) ( 0x40  |  ( w  < <  3 )  |  ( r  < <  2 )  |  ( x  < <  1 )  |  ( b ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rx  ! =  0x40 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write8 ( rx ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : JMP ( const  u8  * addr ,  bool  force5Bytes )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									u64  fn  =  ( u64 ) addr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! force5Bytes ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-16 22:38:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										s64  distance  =  ( s64 ) ( fn  -  ( ( u64 ) code  +  2 ) ) ;  //TODO - sanity check
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_assert_msg_ ( DYNA_REC ,  distance  > =  - 0x80  & &  distance  <  0x80 ,  " Jump target too far away, needs force5Bytes = true " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										//8 bits will do
 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Write8 ( 0xEB ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Write8 ( ( u8 ) ( s8 ) distance ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-16 22:38:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										s64  distance  =  ( s64 ) ( fn  -  ( ( u64 ) code  +  5 ) ) ;  //TODO - sanity check
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_assert_msg_ ( DYNA_REC ,  distance  > =  - 0x80000000LL  & &  distance  <  0x80000000LL ,  " Jump target too far away, needs indirect register " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Write8 ( 0xE9 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write32 ( ( u32 ) ( s32 ) distance ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : JMPptr ( const  OpArg  & arg2 )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									OpArg  arg  =  arg2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( arg . IsImm ( ) )  _assert_msg_ ( DYNA_REC ,  0 ,  " JMPptr - Imm argument " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									arg . operandReg  =  4 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									arg . WriteRex ( this ,  false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0xFF ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									arg . WriteRest ( this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//Can be used to trap other processors, before overwriting their code
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// not used in dolphin
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : JMPself ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0xEB ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0xFE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : CALLptr ( OpArg  arg )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( arg . IsImm ( ) )  _assert_msg_ ( DYNA_REC ,  0 ,  " CALLptr - Imm argument " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									arg . operandReg  =  2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									arg . WriteRex ( this ,  false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0xFF ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									arg . WriteRest ( this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : CALL ( const  void  * fnptr )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									u64  distance  =  u64 ( fnptr )  -  ( u64 ( code )  +  5 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( distance  > =  0x0000000080000000ULL 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 & &  distance  <   0xFFFFFFFF80000000ULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										PanicAlert ( " CALL out of range (%p calls %p) " ,  code ,  fnptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Write8 ( 0xE8 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write32 ( u32 ( distance ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								FixupBranch  XEmitter : : J ( bool  force5bytes )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									FixupBranch  branch ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									branch . type  =  force5bytes  ?  1  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									branch . ptr  =  code  +  ( force5bytes  ?  5  :  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! force5bytes ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										//8 bits will do
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write8 ( 0xEB ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write8 ( 0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Write8 ( 0xE9 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write32 ( 0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  branch ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								FixupBranch  XEmitter : : J_CC ( CCFlags  conditionCode ,  bool  force5bytes )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									FixupBranch  branch ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									branch . type  =  force5bytes  ?  1  :  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-11 12:27:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									branch . ptr  =  code  +  ( force5bytes  ?  6  :  2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! force5bytes ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										//8 bits will do
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write8 ( 0x70  +  conditionCode ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write8 ( 0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write8 ( 0x0F ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write8 ( 0x80  +  conditionCode ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write32 ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  branch ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : J_CC ( CCFlags  conditionCode ,  const  u8  *  addr ,  bool  force5Bytes )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									u64  fn  =  ( u64 ) addr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! force5Bytes ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-16 22:38:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										s64  distance  =  ( s64 ) ( fn  -  ( ( u64 ) code  +  2 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_assert_msg_ ( DYNA_REC ,  distance  > =  - 0x80  & &  distance  <  0x80 ,  " Jump target too far away, needs force5Bytes = true " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										//8 bits will do
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write8 ( 0x70  +  conditionCode ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write8 ( ( u8 ) ( s8 ) distance ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-16 22:38:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										s64  distance  =  ( s64 ) ( fn  -  ( ( u64 ) code  +  6 ) ) ;  //TODO - sanity check
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_assert_msg_ ( DYNA_REC ,  distance  > =  - 0x80000000LL  & &  distance  <  0x80000000LL ,  " Jump target too far away, needs indirect register " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Write8 ( 0x0F ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write8 ( 0x80  +  conditionCode ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write32 ( ( u32 ) ( s32 ) distance ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : SetJumpTarget ( const  FixupBranch  & branch )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( branch . type  = =  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-16 22:38:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										s64  distance  =  ( s64 ) ( code  -  branch . ptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_assert_msg_ ( DYNA_REC ,  distance  > =  - 0x80  & &  distance  <  0x80 ,  " Jump target too far away, needs force5Bytes = true " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-30 16:17:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										branch . ptr [ - 1 ]  =  ( u8 ) ( s8 ) distance ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									else  if  ( branch . type  = =  1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-16 22:38:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										s64  distance  =  ( s64 ) ( code  -  branch . ptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_assert_msg_ ( DYNA_REC ,  distance  > =  - 0x80000000LL  & &  distance  <  0x80000000LL ,  " Jump target too far away, needs indirect register " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										( ( s32 * ) branch . ptr ) [ - 1 ]  =  ( s32 ) distance ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// INC/DEC considered harmful on newer CPUs due to partial flag set.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Use ADD, SUB instead.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : INC ( int  bits ,  OpArg  arg )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( arg . IsImm ( ) )  _assert_msg_ ( DYNA_REC ,  0 ,  " INC - Imm argument " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									arg . operandReg  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bits  = =  16 )  { Write8 ( 0x66 ) ; } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									arg . WriteRex ( this ,  bits  = =  64 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( bits  = =  8  ?  0xFE  :  0xFF ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									arg . WriteRest ( this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : DEC ( int  bits ,  OpArg  arg )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( arg . IsImm ( ) )  _assert_msg_ ( DYNA_REC ,  0 ,  " DEC - Imm argument " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									arg . operandReg  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bits  = =  16 )  { Write8 ( 0x66 ) ; } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									arg . WriteRex ( this ,  bits  = =  64 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( bits  = =  8  ?  0xFE  :  0xFF ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									arg . WriteRest ( this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//Single byte opcodes
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//There is no PUSHAD/POPAD in 64-bit mode.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : INT3 ( )  { Write8 ( 0xCC ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : RET ( )   { Write8 ( 0xC3 ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : RET_FAST ( )   { Write8 ( 0xF3 ) ;  Write8 ( 0xC3 ) ; }  //two-byte return (rep ret) - recommended by AMD optimization manual for the case of jumping to a ret
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : NOP ( int  count )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// TODO: look up the fastest nop sleds for various sizes
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( count )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write8 ( 0x90 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  2 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write8 ( 0x66 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write8 ( 0x90 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  ( i  =  0 ;  i  <  count ;  i + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Write8 ( 0x90 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PAUSE ( )  { Write8 ( 0xF3 ) ;  NOP ( ) ; }  //use in tight spinloops for energy saving on some cpu
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : CLC ( )   { Write8 ( 0xF8 ) ; }  //clear carry
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : CMC ( )   { Write8 ( 0xF5 ) ; }  //flip carry
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : STC ( )   { Write8 ( 0xF9 ) ; }  //set carry
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//TODO: xchg ah, al ???
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : XCHG_AHAL ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0x86 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0xe0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// alt. 86 c4
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//These two can not be executed on early Intel 64-bit CPU:s, only on AMD!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : LAHF ( )  { Write8 ( 0x9F ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : SAHF ( )  { Write8 ( 0x9E ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PUSHF ( )  { Write8 ( 0x9C ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : POPF ( )   { Write8 ( 0x9D ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : LFENCE ( )  { Write8 ( 0x0F ) ;  Write8 ( 0xAE ) ;  Write8 ( 0xE8 ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MFENCE ( )  { Write8 ( 0x0F ) ;  Write8 ( 0xAE ) ;  Write8 ( 0xF0 ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : SFENCE ( )  { Write8 ( 0x0F ) ;  Write8 ( 0xAE ) ;  Write8 ( 0xF8 ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : WriteSimple1Byte ( int  bits ,  u8  byte ,  X64Reg  reg )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bits  = =  16 )  { Write8 ( 0x66 ) ; } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Rex ( bits  = =  64 ,  0 ,  0 ,  ( int ) reg  > >  3 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( byte  +  ( ( int ) reg  &  7 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : WriteSimple2Byte ( int  bits ,  u8  byte1 ,  u8  byte2 ,  X64Reg  reg )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bits  = =  16 )  { Write8 ( 0x66 ) ; } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Rex ( bits = = 64 ,  0 ,  0 ,  ( int ) reg  > >  3 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( byte1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( byte2  +  ( ( int ) reg  &  7 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : CWD ( int  bits )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bits  = =  16 )  { Write8 ( 0x66 ) ; } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Rex ( bits  = =  64 ,  0 ,  0 ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0x99 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : CBW ( int  bits )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bits  = =  8 )  { Write8 ( 0x66 ) ; } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Rex ( bits  = =  32 ,  0 ,  0 ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0x98 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//Simple opcodes
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//push/pop do not need wide to be 64-bit
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PUSH ( X64Reg  reg )  { WriteSimple1Byte ( 32 ,  0x50 ,  reg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : POP ( X64Reg  reg )   { WriteSimple1Byte ( 32 ,  0x58 ,  reg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PUSH ( int  bits ,  const  OpArg  & reg )   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( reg . IsSimpleReg ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										PUSH ( reg . GetSimpleReg ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else  if  ( reg . IsImm ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( reg . GetImmBits ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  8 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Write8 ( 0x6A ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Write8 ( ( u8 ) ( s8 ) reg . offset ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  16 : 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Write8 ( 0x66 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Write8 ( 0x68 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Write16 ( ( u16 ) ( s16 ) ( s32 ) reg . offset ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  32 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Write8 ( 0x68 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Write32 ( ( u32 ) reg . offset ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											_assert_msg_ ( DYNA_REC ,  0 ,  " PUSH - Bad imm bits " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( bits  = =  16 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Write8 ( 0x66 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										reg . WriteRex ( this ,  bits  = =  64 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write8 ( 0xFF ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										reg . WriteRest ( this ,  0 ,  ( X64Reg ) 6 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : POP ( int  /*bits*/ ,  const  OpArg  & reg )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( reg . IsSimpleReg ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										POP ( reg . GetSimpleReg ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										INT3 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : BSWAP ( int  bits ,  X64Reg  reg )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bits  > =  32 ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										WriteSimple2Byte ( bits ,  0x0F ,  0xC8 ,  reg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									else  if  ( bits  = =  16 ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ROL ( 16 ,  R ( reg ) ,  Imm8 ( 8 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									else  if  ( bits  = =  8 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Do nothing - can't bswap a single byte...
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_assert_msg_ ( DYNA_REC ,  0 ,  " BSWAP - Wrong number of bits " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Undefined opcode - reserved
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// If we ever need a way to always cause a non-breakpoint hard exception...
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : UD2 ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0x0F ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0x0B ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PREFETCH ( PrefetchLevel  level ,  OpArg  arg )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( arg . IsImm ( ) )  _assert_msg_ ( DYNA_REC ,  0 ,  " PREFETCH - Imm argument " ) ; ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									arg . operandReg  =  ( u8 ) level ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									arg . WriteRex ( this ,  false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0x0F ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0x18 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									arg . WriteRest ( this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : SETcc ( CCFlags  flag ,  OpArg  dest )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( dest . IsImm ( ) )  _assert_msg_ ( DYNA_REC ,  0 ,  " SETcc - Imm argument " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dest . operandReg  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dest . WriteRex ( this ,  false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0x0F ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0x90  +  ( u8 ) flag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dest . WriteRest ( this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : CMOVcc ( int  bits ,  X64Reg  dest ,  OpArg  src ,  CCFlags  flag )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( src . IsImm ( ) )  _assert_msg_ ( DYNA_REC ,  0 ,  " CMOVcc - Imm argument " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									src . operandReg  =  dest ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									src . WriteRex ( this ,  bits  = =  64 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0x0F ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0x40  +  ( u8 ) flag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									src . WriteRest ( this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : WriteMulDivType ( int  bits ,  OpArg  src ,  int  ext )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( src . IsImm ( ) )  _assert_msg_ ( DYNA_REC ,  0 ,  " WriteMulDivType - Imm argument " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									src . operandReg  =  ext ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bits  = =  16 )  Write8 ( 0x66 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									src . WriteRex ( this ,  bits  = =  64 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bits  = =  8 ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Write8 ( 0xF6 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									else  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write8 ( 0xF7 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									src . WriteRest ( this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : MUL ( int  bits ,  OpArg  src )   { WriteMulDivType ( bits ,  src ,  4 ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : DIV ( int  bits ,  OpArg  src )   { WriteMulDivType ( bits ,  src ,  6 ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : IMUL ( int  bits ,  OpArg  src )  { WriteMulDivType ( bits ,  src ,  5 ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : IDIV ( int  bits ,  OpArg  src )  { WriteMulDivType ( bits ,  src ,  7 ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : NEG ( int  bits ,  OpArg  src )   { WriteMulDivType ( bits ,  src ,  3 ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : NOT ( int  bits ,  OpArg  src )   { WriteMulDivType ( bits ,  src ,  2 ) ; }  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : WriteBitSearchType ( int  bits ,  X64Reg  dest ,  OpArg  src ,  u8  byte2 )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( src . IsImm ( ) )  _assert_msg_ ( DYNA_REC ,  0 ,  " WriteBitSearchType - Imm argument " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									src . operandReg  =  ( u8 ) dest ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bits  = =  16 )  Write8 ( 0x66 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									src . WriteRex ( this ,  bits  = =  64 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0x0F ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( byte2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									src . WriteRest ( this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MOVNTI ( int  bits ,  OpArg  dest ,  X64Reg  src )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bits  < =  16 )  _assert_msg_ ( DYNA_REC ,  0 ,  " MOVNTI - bits<=16 " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									WriteBitSearchType ( bits ,  src ,  dest ,  0xC3 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : BSF ( int  bits ,  X64Reg  dest ,  OpArg  src )  { WriteBitSearchType ( bits , dest , src , 0xBC ) ; }  //bottom bit to top bit
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : BSR ( int  bits ,  X64Reg  dest ,  OpArg  src )  { WriteBitSearchType ( bits , dest , src , 0xBD ) ; }  //top bit to bottom bit
  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : MOVSX ( int  dbits ,  int  sbits ,  X64Reg  dest ,  OpArg  src )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( src . IsImm ( ) )  _assert_msg_ ( DYNA_REC ,  0 ,  " MOVSX - Imm argument " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( dbits  = =  sbits )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										MOV ( dbits ,  R ( dest ) ,  src ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									src . operandReg  =  ( u8 ) dest ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( dbits  = =  16 )  Write8 ( 0x66 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									src . WriteRex ( this ,  dbits  = =  64 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( sbits  = =  8 ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Write8 ( 0x0F ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write8 ( 0xBE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									else  if  ( sbits  = =  16 ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write8 ( 0x0F ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Write8 ( 0xBF ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									else  if  ( sbits  = =  32  & &  dbits  = =  64 ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Write8 ( 0x63 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Crash ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									src . WriteRest ( this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : MOVZX ( int  dbits ,  int  sbits ,  X64Reg  dest ,  OpArg  src )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( src . IsImm ( ) )  _assert_msg_ ( DYNA_REC ,  0 ,  " MOVZX - Imm argument " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( dbits  = =  sbits )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										MOV ( dbits ,  R ( dest ) ,  src ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									src . operandReg  =  ( u8 ) dest ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( dbits  = =  16 )  Write8 ( 0x66 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									src . WriteRex ( this ,  dbits  = =  64 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( sbits  = =  8 ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write8 ( 0x0F ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Write8 ( 0xB6 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									else  if  ( sbits  = =  16 ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write8 ( 0x0F ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Write8 ( 0xB7 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Crash ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									src . WriteRest ( this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : LEA ( int  bits ,  X64Reg  dest ,  OpArg  src )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( src . IsImm ( ) )  _assert_msg_ ( DYNA_REC ,  0 ,  " LEA - Imm argument " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									src . operandReg  =  ( u8 ) dest ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bits  = =  16 )  Write8 ( 0x66 ) ;  //TODO: performance warning
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									src . WriteRex ( this ,  bits  = =  64 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0x8D ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									src . WriteRest ( this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//shift can be either imm8 or cl
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : WriteShift ( int  bits ,  OpArg  dest ,  OpArg  & shift ,  int  ext )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bool  writeImm  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( dest . IsImm ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_assert_msg_ ( DYNA_REC ,  0 ,  " WriteShift - can't shift imms " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ( shift . IsSimpleReg ( )  & &  shift . GetSimpleReg ( )  ! =  ECX )  | |  ( shift . IsImm ( )  & &  shift . GetImmBits ( )  ! =  8 ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_assert_msg_ ( DYNA_REC ,  0 ,  " WriteShift - illegal argument " ) ;  
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dest . operandReg  =  ext ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bits  = =  16 )  Write8 ( 0x66 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dest . WriteRex ( this ,  bits  = =  64 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( shift . GetImmBits ( )  = =  8 ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										//ok an imm
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										u8  imm  =  ( u8 ) shift . offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( imm  = =  1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Write8 ( bits  = =  8  ?  0xD0  :  0xD1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											writeImm  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Write8 ( bits  = =  8  ?  0xC0  :  0xC1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Write8 ( bits  = =  8  ?  0xD2  :  0xD3 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dest . WriteRest ( this ,  writeImm  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( writeImm ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write8 ( ( u8 ) shift . offset ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// large rotates and shift are slower on intel than amd
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// intel likes to rotate by 1, and the op is smaller too
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : ROL ( int  bits ,  OpArg  dest ,  OpArg  shift )  { WriteShift ( bits ,  dest ,  shift ,  0 ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : ROR ( int  bits ,  OpArg  dest ,  OpArg  shift )  { WriteShift ( bits ,  dest ,  shift ,  1 ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : RCL ( int  bits ,  OpArg  dest ,  OpArg  shift )  { WriteShift ( bits ,  dest ,  shift ,  2 ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : RCR ( int  bits ,  OpArg  dest ,  OpArg  shift )  { WriteShift ( bits ,  dest ,  shift ,  3 ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : SHL ( int  bits ,  OpArg  dest ,  OpArg  shift )  { WriteShift ( bits ,  dest ,  shift ,  4 ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : SHR ( int  bits ,  OpArg  dest ,  OpArg  shift )  { WriteShift ( bits ,  dest ,  shift ,  5 ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : SAR ( int  bits ,  OpArg  dest ,  OpArg  shift )  { WriteShift ( bits ,  dest ,  shift ,  7 ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  OpArg : : WriteSingleByteOp ( XEmitter  * emit ,  u8  op ,  X64Reg  _operandReg ,  int  bits )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bits  = =  16 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										emit - > Write8 ( 0x66 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									this - > operandReg  =  ( u8 ) _operandReg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									WriteRex ( emit ,  bits  = =  64 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									emit - > Write8 ( op ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									WriteRest ( emit ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//operand can either be immediate or register
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  OpArg : : WriteNormalOp ( XEmitter  * emit ,  bool  toRM ,  NormalOp  op ,  const  OpArg  & operand ,  int  bits )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									X64Reg  _operandReg  =  ( X64Reg ) this - > operandReg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( IsImm ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_assert_msg_ ( DYNA_REC ,  0 ,  " WriteNormalOp - Imm argument, wrong order " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bits  = =  16 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										emit - > Write8 ( 0x66 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  immToWrite  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( operand . IsImm ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_operandReg  =  ( X64Reg ) 0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										WriteRex ( emit ,  bits  = =  64 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! toRM ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											_assert_msg_ ( DYNA_REC ,  0 ,  " WriteNormalOp - Writing to Imm (!toRM) " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( operand . scale  = =  SCALE_IMM8  & &  bits  = =  8 )  
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											emit - > Write8 ( nops [ op ] . imm8 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											immToWrite  =  8 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										else  if  ( ( operand . scale  = =  SCALE_IMM16  & &  bits  = =  16 )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                             ( operand . scale  = =  SCALE_IMM32  & &  bits  = =  32 )  | |  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                             ( operand . scale  = =  SCALE_IMM32  & &  bits  = =  64 ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											emit - > Write8 ( nops [ op ] . imm32 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											immToWrite  =  bits  = =  16  ?  16  :  32 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										else  if  ( ( operand . scale  = =  SCALE_IMM8  & &  bits  = =  16 )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                             ( operand . scale  = =  SCALE_IMM8  & &  bits  = =  32 )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                             ( operand . scale  = =  SCALE_IMM8  & &  bits  = =  64 ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											emit - > Write8 ( nops [ op ] . simm8 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											immToWrite  =  8 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										else  if  ( operand . scale  = =  SCALE_IMM64  & &  bits  = =  64 ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( op  = =  nrmMOV ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												emit - > Write8 ( 0xB8  +  ( offsetOrBaseReg  &  7 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												emit - > Write64 ( ( u64 ) operand . offset ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											_assert_msg_ ( DYNA_REC ,  0 ,  " WriteNormalOp - Only MOV can take 64-bit imm " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											_assert_msg_ ( DYNA_REC ,  0 ,  " WriteNormalOp - Unhandled case " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_operandReg  =  ( X64Reg ) nops [ op ] . ext ;  //pass extension in REG of ModRM
 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_operandReg  =  ( X64Reg ) operand . offsetOrBaseReg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										WriteRex ( emit ,  bits  = =  64 ,  _operandReg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// mem/reg or reg/reg op
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( toRM ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											emit - > Write8 ( bits  = =  8  ?  nops [ op ] . toRm8  :  nops [ op ] . toRm32 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// _assert_msg_(DYNA_REC, code[-1] != 0xCC, "ARGH4");
 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											emit - > Write8 ( bits  = =  8  ?  nops [ op ] . fromRm8  :  nops [ op ] . fromRm32 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// _assert_msg_(DYNA_REC, code[-1] != 0xCC, "ARGH5");
 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									WriteRest ( emit ,  immToWrite > > 3 ,  _operandReg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( immToWrite ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  0 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  8 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										emit - > Write8 ( ( u8 ) operand . offset ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  16 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										emit - > Write16 ( ( u16 ) operand . offset ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  32 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										emit - > Write32 ( ( u32 ) operand . offset ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_assert_msg_ ( DYNA_REC ,  0 ,  " WriteNormalOp - Unhandled case " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : WriteNormalOp ( XEmitter  * emit ,  int  bits ,  NormalOp  op ,  const  OpArg  & a1 ,  const  OpArg  & a2 )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( a1 . IsImm ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										//Booh! Can't write to an imm
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_assert_msg_ ( DYNA_REC ,  0 ,  " WriteNormalOp - a1 cannot be imm " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( a2 . IsImm ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										a1 . WriteNormalOp ( emit ,  true ,  op ,  a2 ,  bits ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( a1 . IsSimpleReg ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											a2 . WriteNormalOp ( emit ,  false ,  op ,  a1 ,  bits ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										else 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											a1 . WriteNormalOp ( emit ,  true ,  op ,  a2 ,  bits ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : ADD  ( int  bits ,  const  OpArg  & a1 ,  const  OpArg  & a2 )  { WriteNormalOp ( this ,  bits ,  nrmADD ,  a1 ,  a2 ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : ADC  ( int  bits ,  const  OpArg  & a1 ,  const  OpArg  & a2 )  { WriteNormalOp ( this ,  bits ,  nrmADC ,  a1 ,  a2 ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : SUB  ( int  bits ,  const  OpArg  & a1 ,  const  OpArg  & a2 )  { WriteNormalOp ( this ,  bits ,  nrmSUB ,  a1 ,  a2 ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : SBB  ( int  bits ,  const  OpArg  & a1 ,  const  OpArg  & a2 )  { WriteNormalOp ( this ,  bits ,  nrmSBB ,  a1 ,  a2 ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : AND  ( int  bits ,  const  OpArg  & a1 ,  const  OpArg  & a2 )  { WriteNormalOp ( this ,  bits ,  nrmAND ,  a1 ,  a2 ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : OR   ( int  bits ,  const  OpArg  & a1 ,  const  OpArg  & a2 )  { WriteNormalOp ( this ,  bits ,  nrmOR  ,  a1 ,  a2 ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : XOR  ( int  bits ,  const  OpArg  & a1 ,  const  OpArg  & a2 )  { WriteNormalOp ( this ,  bits ,  nrmXOR ,  a1 ,  a2 ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MOV  ( int  bits ,  const  OpArg  & a1 ,  const  OpArg  & a2 )   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2010-01-17 21:28:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef _DEBUG 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									_assert_msg_ ( DYNA_REC ,  ! a1 . IsSimpleReg ( )  | |  ! a2 . IsSimpleReg ( )  | |  a1 . GetSimpleReg ( )  ! =  a2 . GetSimpleReg ( ) ,  " Redundant MOV @ %p - bug in JIT? " ,  
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												 code ) ;  
							 
						 
					
						
							
								
									
										
										
										
											2010-01-17 21:28:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									WriteNormalOp ( this ,  bits ,  nrmMOV ,  a1 ,  a2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : TEST ( int  bits ,  const  OpArg  & a1 ,  const  OpArg  & a2 )  { WriteNormalOp ( this ,  bits ,  nrmTEST ,  a1 ,  a2 ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : CMP  ( int  bits ,  const  OpArg  & a1 ,  const  OpArg  & a2 )  { WriteNormalOp ( this ,  bits ,  nrmCMP ,  a1 ,  a2 ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : XCHG ( int  bits ,  const  OpArg  & a1 ,  const  OpArg  & a2 )  { WriteNormalOp ( this ,  bits ,  nrmXCHG ,  a1 ,  a2 ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : IMUL ( int  bits ,  X64Reg  regOp ,  OpArg  a1 ,  OpArg  a2 )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bits  = =  8 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_assert_msg_ ( DYNA_REC ,  0 ,  " IMUL - illegal bit size! " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( a1 . IsImm ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_assert_msg_ ( DYNA_REC ,  0 ,  " IMUL - second arg cannot be imm! " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! a2 . IsImm ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_assert_msg_ ( DYNA_REC ,  0 ,  " IMUL - third arg must be imm! " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bits  = =  16 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write8 ( 0x66 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a1 . WriteRex ( this ,  bits  = =  64 ,  regOp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( a2 . GetImmBits ( )  = =  8 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write8 ( 0x6B ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										a1 . WriteRest ( this ,  1 ,  regOp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write8 ( ( u8 ) a2 . offset ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write8 ( 0x69 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( a2 . GetImmBits ( )  = =  16  & &  bits  = =  16 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											a1 . WriteRest ( this ,  2 ,  regOp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Write16 ( ( u16 ) a2 . offset ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( a2 . GetImmBits ( )  = =  32  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											( bits  = =  32  | |  bits  = =  64 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												a1 . WriteRest ( this ,  4 ,  regOp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Write32 ( ( u32 ) a2 . offset ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											_assert_msg_ ( DYNA_REC ,  0 ,  " IMUL - unhandled case! " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : IMUL ( int  bits ,  X64Reg  regOp ,  OpArg  a )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bits  = =  8 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_assert_msg_ ( DYNA_REC ,  0 ,  " IMUL - illegal bit size! " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( a . IsImm ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										IMUL ( bits ,  regOp ,  R ( regOp ) ,  a )  ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-09 19:18:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bits  = =  16 ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Write8 ( 0x66 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									a . WriteRex ( this ,  bits  = =  64 ,  regOp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0x0F ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0xAF ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a . WriteRest ( this ,  0 ,  regOp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-18 06:46:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : WriteSSEOp ( int  size ,  u8  sseOp ,  bool  packed ,  X64Reg  regOp ,  OpArg  arg ,  int  extrabytes )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( size  = =  64  & &  packed ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write8 ( 0x66 ) ;  //this time, override goes upwards
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! packed ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write8 ( size  = =  64  ?  0xF2  :  0xF3 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									arg . operandReg  =  regOp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									arg . WriteRex ( this ,  false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0x0F ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( sseOp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									arg . WriteRest ( this ,  extrabytes ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MOVD_xmm ( X64Reg  dest ,  const  OpArg  & arg )  { WriteSSEOp ( 64 ,  0x6E ,  true ,  dest ,  arg ,  0 ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MOVD_xmm ( const  OpArg  & arg ,  X64Reg  src )  { WriteSSEOp ( 64 ,  0x7E ,  true ,  src ,  arg ,  0 ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MOVQ_xmm ( X64Reg  dest ,  OpArg  arg )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef _M_X64 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Alternate encoding
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// This does not display correctly in MSVC's debugger, it thinks it's a MOVD
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										arg . operandReg  =  dest ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Write8 ( 0x66 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										arg . WriteRex ( this ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Write8 ( 0x0f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Write8 ( 0x6E ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										arg . WriteRest ( this ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# else 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										arg . operandReg  =  dest ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write8 ( 0xF3 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write8 ( 0x0f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write8 ( 0x7E ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										arg . WriteRest ( this ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : MOVQ_xmm ( OpArg  arg ,  X64Reg  src )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( arg . IsSimpleReg ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										PanicAlert ( " Emitter: MOVQ_xmm doesn't support single registers as destination " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( src  >  7 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Alternate encoding
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// This does not display correctly in MSVC's debugger, it thinks it's a MOVD
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										arg . operandReg  =  src ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Write8 ( 0x66 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										arg . WriteRex ( this ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write8 ( 0x0f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Write8 ( 0x7E ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										arg . WriteRest ( this ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										arg . operandReg  =  src ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-19 21:24:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										arg . WriteRex ( this ,  false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Write8 ( 0x66 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Write8 ( 0x0f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Write8 ( 0xD6 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-19 21:24:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										arg . WriteRest ( this ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : WriteMXCSR ( OpArg  arg ,  int  ext )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( arg . IsImm ( )  | |  arg . IsSimpleReg ( ) )  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_assert_msg_ ( DYNA_REC ,  0 ,  " MXCSR - invalid operand " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									arg . operandReg  =  ext ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									arg . WriteRex ( this ,  false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0x0F ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0xAE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									arg . WriteRest ( this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : STMXCSR ( OpArg  memloc )  { WriteMXCSR ( memloc ,  3 ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : LDMXCSR ( OpArg  memloc )  { WriteMXCSR ( memloc ,  2 ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MOVNTDQ ( OpArg  arg ,  X64Reg  regOp )    { WriteSSEOp ( 64 ,  sseMOVNTDQ ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MOVNTPS ( OpArg  arg ,  X64Reg  regOp )    { WriteSSEOp ( 32 ,  sseMOVNTP ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MOVNTPD ( OpArg  arg ,  X64Reg  regOp )    { WriteSSEOp ( 64 ,  sseMOVNTP ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : ADDSS ( X64Reg  regOp ,  OpArg  arg )    { WriteSSEOp ( 32 ,  sseADD ,  false ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : ADDSD ( X64Reg  regOp ,  OpArg  arg )    { WriteSSEOp ( 64 ,  sseADD ,  false ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : SUBSS ( X64Reg  regOp ,  OpArg  arg )    { WriteSSEOp ( 32 ,  sseSUB ,  false ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : SUBSD ( X64Reg  regOp ,  OpArg  arg )    { WriteSSEOp ( 64 ,  sseSUB ,  false ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : CMPSS ( X64Reg  regOp ,  OpArg  arg ,  u8  compare )    { WriteSSEOp ( 32 ,  sseCMP ,  false ,  regOp ,  arg , 1 ) ;  Write8 ( compare ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : CMPSD ( X64Reg  regOp ,  OpArg  arg ,  u8  compare )    { WriteSSEOp ( 64 ,  sseCMP ,  false ,  regOp ,  arg , 1 ) ;  Write8 ( compare ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MULSS ( X64Reg  regOp ,  OpArg  arg )    { WriteSSEOp ( 32 ,  sseMUL ,  false ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MULSD ( X64Reg  regOp ,  OpArg  arg )    { WriteSSEOp ( 64 ,  sseMUL ,  false ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : DIVSS ( X64Reg  regOp ,  OpArg  arg )    { WriteSSEOp ( 32 ,  sseDIV ,  false ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : DIVSD ( X64Reg  regOp ,  OpArg  arg )    { WriteSSEOp ( 64 ,  sseDIV ,  false ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MINSS ( X64Reg  regOp ,  OpArg  arg )    { WriteSSEOp ( 32 ,  sseMIN ,  false ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MINSD ( X64Reg  regOp ,  OpArg  arg )    { WriteSSEOp ( 64 ,  sseMIN ,  false ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MAXSS ( X64Reg  regOp ,  OpArg  arg )    { WriteSSEOp ( 32 ,  sseMAX ,  false ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MAXSD ( X64Reg  regOp ,  OpArg  arg )    { WriteSSEOp ( 64 ,  sseMAX ,  false ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : SQRTSS ( X64Reg  regOp ,  OpArg  arg )   { WriteSSEOp ( 32 ,  sseSQRT ,  false ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : SQRTSD ( X64Reg  regOp ,  OpArg  arg )   { WriteSSEOp ( 64 ,  sseSQRT ,  false ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : RSQRTSS ( X64Reg  regOp ,  OpArg  arg )  { WriteSSEOp ( 32 ,  sseRSQRT ,  false ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : ADDPS ( X64Reg  regOp ,  OpArg  arg )    { WriteSSEOp ( 32 ,  sseADD ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : ADDPD ( X64Reg  regOp ,  OpArg  arg )    { WriteSSEOp ( 64 ,  sseADD ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : SUBPS ( X64Reg  regOp ,  OpArg  arg )    { WriteSSEOp ( 32 ,  sseSUB ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : SUBPD ( X64Reg  regOp ,  OpArg  arg )    { WriteSSEOp ( 64 ,  sseSUB ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : CMPPS ( X64Reg  regOp ,  OpArg  arg ,  u8  compare )    { WriteSSEOp ( 32 ,  sseCMP ,  true ,  regOp ,  arg , 1 ) ;  Write8 ( compare ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : CMPPD ( X64Reg  regOp ,  OpArg  arg ,  u8  compare )    { WriteSSEOp ( 64 ,  sseCMP ,  true ,  regOp ,  arg , 1 ) ;  Write8 ( compare ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : ANDPS ( X64Reg  regOp ,  OpArg  arg )    { WriteSSEOp ( 32 ,  sseAND ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : ANDPD ( X64Reg  regOp ,  OpArg  arg )    { WriteSSEOp ( 64 ,  sseAND ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : ANDNPS ( X64Reg  regOp ,  OpArg  arg )   { WriteSSEOp ( 32 ,  sseANDN ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : ANDNPD ( X64Reg  regOp ,  OpArg  arg )   { WriteSSEOp ( 64 ,  sseANDN ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : ORPS ( X64Reg  regOp ,  OpArg  arg )     { WriteSSEOp ( 32 ,  sseOR ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : ORPD ( X64Reg  regOp ,  OpArg  arg )     { WriteSSEOp ( 64 ,  sseOR ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : XORPS ( X64Reg  regOp ,  OpArg  arg )    { WriteSSEOp ( 32 ,  sseXOR ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : XORPD ( X64Reg  regOp ,  OpArg  arg )    { WriteSSEOp ( 64 ,  sseXOR ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MULPS ( X64Reg  regOp ,  OpArg  arg )    { WriteSSEOp ( 32 ,  sseMUL ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MULPD ( X64Reg  regOp ,  OpArg  arg )    { WriteSSEOp ( 64 ,  sseMUL ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : DIVPS ( X64Reg  regOp ,  OpArg  arg )    { WriteSSEOp ( 32 ,  sseDIV ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : DIVPD ( X64Reg  regOp ,  OpArg  arg )    { WriteSSEOp ( 64 ,  sseDIV ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MINPS ( X64Reg  regOp ,  OpArg  arg )    { WriteSSEOp ( 32 ,  sseMIN ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MINPD ( X64Reg  regOp ,  OpArg  arg )    { WriteSSEOp ( 64 ,  sseMIN ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MAXPS ( X64Reg  regOp ,  OpArg  arg )    { WriteSSEOp ( 32 ,  sseMAX ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MAXPD ( X64Reg  regOp ,  OpArg  arg )    { WriteSSEOp ( 64 ,  sseMAX ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : SQRTPS ( X64Reg  regOp ,  OpArg  arg )   { WriteSSEOp ( 32 ,  sseSQRT ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : SQRTPD ( X64Reg  regOp ,  OpArg  arg )   { WriteSSEOp ( 64 ,  sseSQRT ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : RSQRTPS ( X64Reg  regOp ,  OpArg  arg )  { WriteSSEOp ( 32 ,  sseRSQRT ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : SHUFPS ( X64Reg  regOp ,  OpArg  arg ,  u8  shuffle )  { WriteSSEOp ( 32 ,  sseSHUF ,  true ,  regOp ,  arg , 1 ) ;  Write8 ( shuffle ) ; }   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : SHUFPD ( X64Reg  regOp ,  OpArg  arg ,  u8  shuffle )  { WriteSSEOp ( 64 ,  sseSHUF ,  true ,  regOp ,  arg , 1 ) ;  Write8 ( shuffle ) ; }   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : COMISS ( X64Reg  regOp ,  OpArg  arg )   { WriteSSEOp ( 32 ,  sseCOMIS ,  true ,  regOp ,  arg ) ; }  //weird that these should be packed
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : COMISD ( X64Reg  regOp ,  OpArg  arg )   { WriteSSEOp ( 64 ,  sseCOMIS ,  true ,  regOp ,  arg ) ; }  //ordered
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : UCOMISS ( X64Reg  regOp ,  OpArg  arg )  { WriteSSEOp ( 32 ,  sseUCOMIS ,  true ,  regOp ,  arg ) ; }  //unordered
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : UCOMISD ( X64Reg  regOp ,  OpArg  arg )  { WriteSSEOp ( 64 ,  sseUCOMIS ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MOVAPS ( X64Reg  regOp ,  OpArg  arg )   { WriteSSEOp ( 32 ,  sseMOVAPfromRM ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MOVAPD ( X64Reg  regOp ,  OpArg  arg )   { WriteSSEOp ( 64 ,  sseMOVAPfromRM ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MOVAPS ( OpArg  arg ,  X64Reg  regOp )   { WriteSSEOp ( 32 ,  sseMOVAPtoRM ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MOVAPD ( OpArg  arg ,  X64Reg  regOp )   { WriteSSEOp ( 64 ,  sseMOVAPtoRM ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MOVUPS ( X64Reg  regOp ,  OpArg  arg )   { WriteSSEOp ( 32 ,  sseMOVUPfromRM ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MOVUPD ( X64Reg  regOp ,  OpArg  arg )   { WriteSSEOp ( 64 ,  sseMOVUPfromRM ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MOVUPS ( OpArg  arg ,  X64Reg  regOp )   { WriteSSEOp ( 32 ,  sseMOVUPtoRM ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MOVUPD ( OpArg  arg ,  X64Reg  regOp )   { WriteSSEOp ( 64 ,  sseMOVUPtoRM ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MOVSS ( X64Reg  regOp ,  OpArg  arg )    { WriteSSEOp ( 32 ,  sseMOVUPfromRM ,  false ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MOVSD ( X64Reg  regOp ,  OpArg  arg )    { WriteSSEOp ( 64 ,  sseMOVUPfromRM ,  false ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MOVSS ( OpArg  arg ,  X64Reg  regOp )    { WriteSSEOp ( 32 ,  sseMOVUPtoRM ,  false ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MOVSD ( OpArg  arg ,  X64Reg  regOp )    { WriteSSEOp ( 64 ,  sseMOVUPtoRM ,  false ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : CVTPS2PD ( X64Reg  regOp ,  OpArg  arg )  { WriteSSEOp ( 32 ,  0x5A ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : CVTPD2PS ( X64Reg  regOp ,  OpArg  arg )  { WriteSSEOp ( 64 ,  0x5A ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : CVTSD2SS ( X64Reg  regOp ,  OpArg  arg )  { WriteSSEOp ( 64 ,  0x5A ,  false ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : CVTSS2SD ( X64Reg  regOp ,  OpArg  arg )  { WriteSSEOp ( 32 ,  0x5A ,  false ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : CVTSD2SI ( X64Reg  regOp ,  OpArg  arg )  { WriteSSEOp ( 32 ,  0xF2 ,  false ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : CVTDQ2PD ( X64Reg  regOp ,  OpArg  arg )  { WriteSSEOp ( 32 ,  0xE6 ,  false ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : CVTDQ2PS ( X64Reg  regOp ,  OpArg  arg )  { WriteSSEOp ( 32 ,  0x5B ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : CVTPD2DQ ( X64Reg  regOp ,  OpArg  arg )  { WriteSSEOp ( 64 ,  0xE6 ,  false ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : CVTPS2DQ ( X64Reg  regOp ,  OpArg  arg )  { WriteSSEOp ( 64 ,  0x5B ,  true ,  regOp ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 22:44:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : CVTTSS2SI ( X64Reg  xregdest ,  OpArg  arg )  { WriteSSEOp ( 32 ,  0x2C ,  false ,  xregdest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : CVTTPS2DQ ( X64Reg  xregdest ,  OpArg  arg )  { WriteSSEOp ( 32 ,  0x5B ,  false ,  xregdest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : MASKMOVDQU ( X64Reg  dest ,  X64Reg  src )   { WriteSSEOp ( 64 ,  sseMASKMOVDQU ,  true ,  dest ,  R ( src ) ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MOVMSKPS ( X64Reg  dest ,  OpArg  arg )  { WriteSSEOp ( 32 ,  0x50 ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MOVMSKPD ( X64Reg  dest ,  OpArg  arg )  { WriteSSEOp ( 64 ,  0x50 ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : LDDQU ( X64Reg  dest ,  OpArg  arg )     { WriteSSEOp ( 64 ,  sseLDDQU ,  false ,  dest ,  arg ) ; }  // For integer data only
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// THESE TWO ARE UNTESTED.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : UNPCKLPS ( X64Reg  dest ,  OpArg  arg )  { WriteSSEOp ( 32 ,  0x14 ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : UNPCKHPS ( X64Reg  dest ,  OpArg  arg )  { WriteSSEOp ( 32 ,  0x15 ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : UNPCKLPD ( X64Reg  dest ,  OpArg  arg )  { WriteSSEOp ( 64 ,  0x14 ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : UNPCKHPD ( X64Reg  dest ,  OpArg  arg )  { WriteSSEOp ( 64 ,  0x15 ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : MOVDDUP ( X64Reg  regOp ,  OpArg  arg )   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( cpu_info . bSSE3 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										WriteSSEOp ( 64 ,  0x12 ,  false ,  regOp ,  arg ) ;  //SSE3 movddup
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Simulate this instruction with SSE2 instructions
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! arg . IsSimpleReg ( regOp ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											MOVQ_xmm ( regOp ,  arg ) ;    // MOVSD better?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										UNPCKLPD ( regOp ,  R ( regOp ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//There are a few more left
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Also some integer instrucitons are missing
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PACKSSDW ( X64Reg  dest ,  OpArg  arg )  { WriteSSEOp ( 64 ,  0x6B ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PACKSSWB ( X64Reg  dest ,  OpArg  arg )  { WriteSSEOp ( 64 ,  0x63 ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//void PACKUSDW(X64Reg dest, OpArg arg) {WriteSSEOp(64, 0x66, true, dest, arg);} // WRONG
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PACKUSWB ( X64Reg  dest ,  OpArg  arg )  { WriteSSEOp ( 64 ,  0x67 ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PUNPCKLBW ( X64Reg  dest ,  const  OpArg  & arg )  { WriteSSEOp ( 64 ,  0x60 ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PUNPCKLWD ( X64Reg  dest ,  const  OpArg  & arg )  { WriteSSEOp ( 64 ,  0x61 ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PUNPCKLDQ ( X64Reg  dest ,  const  OpArg  & arg )  { WriteSSEOp ( 64 ,  0x62 ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//void PUNPCKLQDQ(X64Reg dest, OpArg arg) {WriteSSEOp(64, 0x60, true, dest, arg);}
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-09-06 03:03:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : PSRLW ( X64Reg  reg ,  int  shift )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									WriteSSEOp ( 64 ,  0x71 ,  true ,  ( X64Reg ) 2 ,  R ( reg ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Write8 ( shift ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-09-06 03:03:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : PSRLD ( X64Reg  reg ,  int  shift )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									WriteSSEOp ( 64 ,  0x72 ,  true ,  ( X64Reg ) 2 ,  R ( reg ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( shift ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PSRLQ ( X64Reg  reg ,  int  shift )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									WriteSSEOp ( 64 ,  0x73 ,  true ,  ( X64Reg ) 2 ,  R ( reg ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Write8 ( shift ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PSLLW ( X64Reg  reg ,  int  shift )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									WriteSSEOp ( 64 ,  0x71 ,  true ,  ( X64Reg ) 6 ,  R ( reg ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( shift ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-09-06 03:03:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : PSLLD ( X64Reg  reg ,  int  shift )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									WriteSSEOp ( 64 ,  0x72 ,  true ,  ( X64Reg ) 6 ,  R ( reg ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( shift ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PSLLQ ( X64Reg  reg ,  int  shift )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									WriteSSEOp ( 64 ,  0x73 ,  true ,  ( X64Reg ) 6 ,  R ( reg ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( shift ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// WARNING not REX compatible
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PSRAW ( X64Reg  reg ,  int  shift )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( reg  >  7 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										PanicAlert ( " The PSRAW-emitter does not support regs above 7 " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0x66 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0x0f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0x71 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0xE0  |  reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( shift ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// WARNING not REX compatible
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PSRAD ( X64Reg  reg ,  int  shift )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( reg  >  7 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										PanicAlert ( " The PSRAD-emitter does not support regs above 7 " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0x66 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0x0f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0x72 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0xE0  |  reg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( shift ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PSHUFB ( X64Reg  dest ,  OpArg  arg )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! cpu_info . bSSSE3 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										PanicAlert ( " Trying to use PSHUFB on a system that doesn't support it. Bad programmer. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0x66 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									arg . operandReg  =  dest ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									arg . WriteRex ( this ,  false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0x0f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0x38 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0x00 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									arg . WriteRest ( this ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : PAND ( X64Reg  dest ,  OpArg  arg )      { WriteSSEOp ( 64 ,  0xDB ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PANDN ( X64Reg  dest ,  OpArg  arg )     { WriteSSEOp ( 64 ,  0xDF ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PXOR ( X64Reg  dest ,  OpArg  arg )      { WriteSSEOp ( 64 ,  0xEF ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : POR ( X64Reg  dest ,  OpArg  arg )       { WriteSSEOp ( 64 ,  0xEB ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : PADDB ( X64Reg  dest ,  OpArg  arg )     { WriteSSEOp ( 64 ,  0xFC ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PADDW ( X64Reg  dest ,  OpArg  arg )     { WriteSSEOp ( 64 ,  0xFD ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PADDD ( X64Reg  dest ,  OpArg  arg )     { WriteSSEOp ( 64 ,  0xFE ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PADDQ ( X64Reg  dest ,  OpArg  arg )     { WriteSSEOp ( 64 ,  0xD4 ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : PADDSB ( X64Reg  dest ,  OpArg  arg )    { WriteSSEOp ( 64 ,  0xEC ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PADDSW ( X64Reg  dest ,  OpArg  arg )    { WriteSSEOp ( 64 ,  0xED ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PADDUSB ( X64Reg  dest ,  OpArg  arg )   { WriteSSEOp ( 64 ,  0xDC ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PADDUSW ( X64Reg  dest ,  OpArg  arg )   { WriteSSEOp ( 64 ,  0xDD ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : PSUBB ( X64Reg  dest ,  OpArg  arg )     { WriteSSEOp ( 64 ,  0xF8 ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PSUBW ( X64Reg  dest ,  OpArg  arg )     { WriteSSEOp ( 64 ,  0xF9 ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PSUBD ( X64Reg  dest ,  OpArg  arg )     { WriteSSEOp ( 64 ,  0xFA ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PSUBQ ( X64Reg  dest ,  OpArg  arg )     { WriteSSEOp ( 64 ,  0xDB ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : PSUBSB ( X64Reg  dest ,  OpArg  arg )    { WriteSSEOp ( 64 ,  0xE8 ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PSUBSW ( X64Reg  dest ,  OpArg  arg )    { WriteSSEOp ( 64 ,  0xE9 ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PSUBUSB ( X64Reg  dest ,  OpArg  arg )   { WriteSSEOp ( 64 ,  0xD8 ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PSUBUSW ( X64Reg  dest ,  OpArg  arg )   { WriteSSEOp ( 64 ,  0xD9 ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : PAVGB ( X64Reg  dest ,  OpArg  arg )     { WriteSSEOp ( 64 ,  0xE0 ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PAVGW ( X64Reg  dest ,  OpArg  arg )     { WriteSSEOp ( 64 ,  0xE3 ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : PCMPEQB ( X64Reg  dest ,  OpArg  arg )   { WriteSSEOp ( 64 ,  0x74 ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PCMPEQW ( X64Reg  dest ,  OpArg  arg )   { WriteSSEOp ( 64 ,  0x75 ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PCMPEQD ( X64Reg  dest ,  OpArg  arg )   { WriteSSEOp ( 64 ,  0x76 ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : PCMPGTB ( X64Reg  dest ,  OpArg  arg )   { WriteSSEOp ( 64 ,  0x64 ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PCMPGTW ( X64Reg  dest ,  OpArg  arg )   { WriteSSEOp ( 64 ,  0x65 ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PCMPGTD ( X64Reg  dest ,  OpArg  arg )   { WriteSSEOp ( 64 ,  0x66 ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : PEXTRW ( X64Reg  dest ,  OpArg  arg ,  u8  subreg )     { WriteSSEOp ( 64 ,  0x64 ,  true ,  dest ,  arg ) ;  Write8 ( subreg ) ; }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PINSRW ( X64Reg  dest ,  OpArg  arg ,  u8  subreg )     { WriteSSEOp ( 64 ,  0x64 ,  true ,  dest ,  arg ) ;  Write8 ( subreg ) ; }  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : PMADDWD ( X64Reg  dest ,  OpArg  arg )   { WriteSSEOp ( 64 ,  0xF5 ,  true ,  dest ,  arg ) ;  }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PSADBW ( X64Reg  dest ,  OpArg  arg )    { WriteSSEOp ( 64 ,  0xF6 ,  true ,  dest ,  arg ) ; }  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : PMAXSW ( X64Reg  dest ,  OpArg  arg )    { WriteSSEOp ( 64 ,  0xEE ,  true ,  dest ,  arg ) ;  }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PMAXUB ( X64Reg  dest ,  OpArg  arg )    { WriteSSEOp ( 64 ,  0xDE ,  true ,  dest ,  arg ) ;  }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PMINSW ( X64Reg  dest ,  OpArg  arg )    { WriteSSEOp ( 64 ,  0xEA ,  true ,  dest ,  arg ) ;  }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : PMINUB ( X64Reg  dest ,  OpArg  arg )    { WriteSSEOp ( 64 ,  0xDA ,  true ,  dest ,  arg ) ;  }  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : PMOVMSKB ( X64Reg  dest ,  OpArg  arg )     { WriteSSEOp ( 64 ,  0xD7 ,  true ,  dest ,  arg ) ;  }  
						 
					
						
							
								
									
										
										
										
											2008-12-18 06:46:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : PSHUFLW ( X64Reg  regOp ,  OpArg  arg ,  u8  shuffle )    { WriteSSEOp ( 64 ,  0x70 ,  false ,  regOp ,  arg ,  1 ) ;  Write8 ( shuffle ) ; }  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Prefixes
  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : LOCK ( )   {  Write8 ( 0xF0 ) ;  }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : REP ( )    {  Write8 ( 0xF3 ) ;  }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : REPNE ( )  {  Write8 ( 0xF2 ) ;  }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  XEmitter : : FWAIT ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Write8 ( 0x9B ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-16 19:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : RTDSC ( )  {  Write8 ( 0x0F ) ;  Write8 ( 0x31 ) ;  }  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// helper routines for setting pointers
  
						 
					
						
							
								
									
										
										
										
											2008-12-19 21:24:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : CallCdeclFunction3 ( void *  fnptr ,  u32  arg0 ,  u32  arg1 ,  u32  arg2 )  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    using  namespace  Gen ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef _M_X64 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef _MSC_VER 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( RCX ) ,  Imm32 ( arg0 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( RDX ) ,  Imm32 ( arg1 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( R8 ) ,   Imm32 ( arg2 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    CALL ( fnptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# else 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( RDI ) ,  Imm32 ( arg0 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( RSI ) ,  Imm32 ( arg1 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( RDX ) ,  Imm32 ( arg2 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    CALL ( fnptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# else 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ABI_AlignStack ( 3  *  4 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PUSH ( 32 ,  Imm32 ( arg2 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PUSH ( 32 ,  Imm32 ( arg1 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PUSH ( 32 ,  Imm32 ( arg0 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    CALL ( fnptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef _WIN32 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // don't inc stack
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# else 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ABI_RestoreStack ( 3  *  4 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-19 21:24:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : CallCdeclFunction4 ( void *  fnptr ,  u32  arg0 ,  u32  arg1 ,  u32  arg2 ,  u32  arg3 )  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    using  namespace  Gen ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef _M_X64 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef _MSC_VER 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( RCX ) ,  Imm32 ( arg0 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( RDX ) ,  Imm32 ( arg1 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( R8 ) ,  Imm32 ( arg2 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( R9 ) ,  Imm32 ( arg3 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    CALL ( fnptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# else 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( RDI ) ,  Imm32 ( arg0 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( RSI ) ,  Imm32 ( arg1 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( RDX ) ,  Imm32 ( arg2 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( RCX ) ,  Imm32 ( arg3 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    CALL ( fnptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# else 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ABI_AlignStack ( 4  *  4 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PUSH ( 32 ,  Imm32 ( arg3 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PUSH ( 32 ,  Imm32 ( arg2 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PUSH ( 32 ,  Imm32 ( arg1 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PUSH ( 32 ,  Imm32 ( arg0 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    CALL ( fnptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef _WIN32 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // don't inc stack
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# else 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ABI_RestoreStack ( 4  *  4 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-19 21:24:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : CallCdeclFunction5 ( void *  fnptr ,  u32  arg0 ,  u32  arg1 ,  u32  arg2 ,  u32  arg3 ,  u32  arg4 )  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    using  namespace  Gen ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef _M_X64 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef _MSC_VER 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( RCX ) ,  Imm32 ( arg0 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( RDX ) ,  Imm32 ( arg1 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( R8 ) ,   Imm32 ( arg2 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( R9 ) ,   Imm32 ( arg3 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									MOV ( 32 ,  MDisp ( RSP ,  0x20 ) ,  Imm32 ( arg4 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    CALL ( fnptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# else 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( RDI ) ,  Imm32 ( arg0 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( RSI ) ,  Imm32 ( arg1 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( RDX ) ,  Imm32 ( arg2 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( RCX ) ,  Imm32 ( arg3 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( R8 ) ,   Imm32 ( arg4 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    CALL ( fnptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# else 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ABI_AlignStack ( 5  *  4 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PUSH ( 32 ,  Imm32 ( arg4 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PUSH ( 32 ,  Imm32 ( arg3 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PUSH ( 32 ,  Imm32 ( arg2 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PUSH ( 32 ,  Imm32 ( arg1 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PUSH ( 32 ,  Imm32 ( arg0 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    CALL ( fnptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef _WIN32 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // don't inc stack
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# else 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ABI_RestoreStack ( 5  *  4 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-19 21:24:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : CallCdeclFunction6 ( void *  fnptr ,  u32  arg0 ,  u32  arg1 ,  u32  arg2 ,  u32  arg3 ,  u32  arg4 ,  u32  arg5 )  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    using  namespace  Gen ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef _M_X64 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef _MSC_VER 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( RCX ) ,  Imm32 ( arg0 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( RDX ) ,  Imm32 ( arg1 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( R8 ) ,  Imm32 ( arg2 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( R9 ) ,  Imm32 ( arg3 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									MOV ( 32 ,  MDisp ( RSP ,  0x20 ) ,  Imm32 ( arg4 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									MOV ( 32 ,  MDisp ( RSP ,  0x28 ) ,  Imm32 ( arg5 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    CALL ( fnptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# else 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( RDI ) ,  Imm32 ( arg0 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( RSI ) ,  Imm32 ( arg1 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( RDX ) ,  Imm32 ( arg2 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( RCX ) ,  Imm32 ( arg3 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( R8 ) ,  Imm32 ( arg4 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( R9 ) ,  Imm32 ( arg5 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    CALL ( fnptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# else 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ABI_AlignStack ( 6  *  4 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PUSH ( 32 ,  Imm32 ( arg5 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PUSH ( 32 ,  Imm32 ( arg4 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PUSH ( 32 ,  Imm32 ( arg3 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PUSH ( 32 ,  Imm32 ( arg2 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PUSH ( 32 ,  Imm32 ( arg1 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PUSH ( 32 ,  Imm32 ( arg0 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    CALL ( fnptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef _WIN32 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // don't inc stack
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# else 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ABI_RestoreStack ( 6  *  4 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef _M_X64 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// See header
  
						 
					
						
							
								
									
										
										
										
											2008-12-19 21:24:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : ___CallCdeclImport3 ( void *  impptr ,  u32  arg0 ,  u32  arg1 ,  u32  arg2 )  {  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( RCX ) ,  Imm32 ( arg0 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( RDX ) ,  Imm32 ( arg1 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( R8 ) ,  Imm32 ( arg2 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									CALLptr ( M ( impptr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-19 21:24:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : ___CallCdeclImport4 ( void *  impptr ,  u32  arg0 ,  u32  arg1 ,  u32  arg2 ,  u32  arg3 )  {  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( RCX ) ,  Imm32 ( arg0 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( RDX ) ,  Imm32 ( arg1 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( R8 ) ,  Imm32 ( arg2 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( R9 ) ,  Imm32 ( arg3 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									CALLptr ( M ( impptr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-19 21:24:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : ___CallCdeclImport5 ( void *  impptr ,  u32  arg0 ,  u32  arg1 ,  u32  arg2 ,  u32  arg3 ,  u32  arg4 )  {  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( RCX ) ,  Imm32 ( arg0 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( RDX ) ,  Imm32 ( arg1 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( R8 ) ,  Imm32 ( arg2 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( R9 ) ,  Imm32 ( arg3 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									MOV ( 32 ,  MDisp ( RSP ,  0x20 ) ,  Imm32 ( arg4 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									CALLptr ( M ( impptr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-19 21:24:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  XEmitter : : ___CallCdeclImport6 ( void *  impptr ,  u32  arg0 ,  u32  arg1 ,  u32  arg2 ,  u32  arg3 ,  u32  arg4 ,  u32  arg5 )  {  
						 
					
						
							
								
									
										
										
										
											2008-12-08 05:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( RCX ) ,  Imm32 ( arg0 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( RDX ) ,  Imm32 ( arg1 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( R8 ) ,  Imm32 ( arg2 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOV ( 32 ,  R ( R9 ) ,  Imm32 ( arg3 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									MOV ( 32 ,  MDisp ( RSP ,  0x20 ) ,  Imm32 ( arg4 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									MOV ( 32 ,  MDisp ( RSP ,  0x28 ) ,  Imm32 ( arg5 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									CALLptr ( M ( impptr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}