1 /**
2  * @namespace   biew_plugins_II
3  * @file        plugins/disasm/ix86/ix86_fun.c
4  * @brief       This file contains implementation common function and utility
5  *              for Intel x86 disassembler.
6  * @version     -
7  * @remark      this source file is part of Binary vIEW project (BIEW).
8  *              The Binary vIEW (BIEW) is copyright (C) 1995 Nickols_K.
9  *              All rights reserved. This software is redistributable under the
10  *              licence given in the file "Licence.en" ("Licence.ru" in russian
11  *              translation) distributed in the BIEW archive.
12  * @note        Requires POSIX compatible development system
13  *
14  * @author      Nickols_K
15  * @since       1995
16  * @note        Development, fixes and improvements
17  * @author      Kostya Nosov <k-nosov@yandex.ru>
18  * @date        12.09.2000
19  * @note        Adding navigation for indirect jumps
20 **/
21 #include <string.h>
22 #include <limits.h>
23 #include <stdio.h>
24 
25 #include "plugins/disasm.h"
26 #include "plugins/disasm/ix86/ix86.h"
27 #include "biewutil.h"
28 #include "bmfile.h"
29 #include "codeguid.h"
30 #include "reg_form.h"
31 
32 #define MODRM_REG(X) (((X)&0x38)>>3)
33 #define MODRM_COP(X) MODRM_REG(X)
34 #define MODRM_MOD(X) (((X)&0xC0)>>6)
35 #define MODRM_RM(X)  ((X)&0x07)
36 
37 char *ix86_appstr;
38 char *ix86_dtile;
39 char *ix86_appbuffer;
40 char *ix86_apistr;
41 char *ix86_modrm_ret;
42 char *ix86_Katmai_buff;
43 
44 #define ix86_setModifier(str,modf) disSetModifier(str,modf)
45 #define getSREG(sreg) (ix86_SegRegs[(unsigned char)sreg])
46 
47 #define REX_reg(rex,reg) (reg|((rex&1)<<3))
48 
49 #define HAS_REX (DisP->pfx&PFX_REX)
50 #define K64_REX (DisP->REX)
51 
52 #define HAS_REX (DisP->pfx&PFX_REX)
53 #define USE_WIDE_DATA (DisP->mode&MOD_WIDE_DATA)
54 #define USE_WIDE_ADDR (DisP->mode&MOD_WIDE_ADDR)
55 #define HAS_67_IN64 ((x86_Bitness == DAB_USE64)&&(DisP->pfx&PFX_67))
56 
ix86_calcModifier(ix86Param * DisP,unsigned w)57 static inline unsigned ix86_calcModifier(ix86Param* DisP,unsigned w) {
58   unsigned sizptr;
59      if(!w) sizptr = BYTE_PTR;
60      else
61      if(x86_Bitness == DAB_USE64)
62 	sizptr = REX_w(DisP->REX)?QWORD_PTR:USE_WIDE_DATA?DWORD_PTR:WORD_PTR;
63      else
64 	sizptr = USE_WIDE_DATA ? DWORD_PTR : WORD_PTR;
65    return sizptr;
66 }
67 
k64_getREG(ix86Param * DisP,unsigned char reg,tBool w,tBool rex,tBool use_qregs)68 static const char * __FASTCALL__ k64_getREG(ix86Param*DisP,unsigned char reg,tBool w,tBool rex, tBool use_qregs)
69 {
70  if((DisP->mode&MOD_SSE)) {
71     const char **k64_xmm_regs;
72     unsigned ridx;
73     if((DisP->pfx&PFX_VEX) && (DisP->VEX_vlp&0x04))	k64_xmm_regs=k64_YMMXRegs; /* 256-bit vectors */
74     else						k64_xmm_regs=k64_XMMXRegs; /* 128-bit vectors */
75     ridx = x86_Bitness==DAB_USE64?REX_reg(rex,reg):(reg&0x07);
76     return  k64_xmm_regs[ridx];
77  }
78  else
79    if((DisP->mode&MOD_MMX))  return ix86_MMXRegs[reg];
80    else
81      if(!w) return (x86_Bitness==DAB_USE64&&HAS_REX)?k64_ByteRegs[REX_reg(rex,reg)]:i8086_ByteRegs[reg];
82      else
83       return use_qregs?k64_QWordRegs[REX_reg(rex,reg)]:USE_WIDE_DATA?k64_DWordRegs[REX_reg(rex,reg)]:k64_WordRegs[REX_reg(rex,reg)];
84 }
85 
get_VEX_reg(ix86Param * DisP)86 static const char *get_VEX_reg(ix86Param* DisP)
87 {
88     unsigned rg,brex,wrex;
89     const char *rval=NULL;
90     rg = (x86_Bitness == DAB_USE64)?((DisP->VEX_vlp>>3)&0x0F)^0x0F:((DisP->VEX_vlp>>3)&0x07)^0x07;
91     wrex = REX_W(K64_REX);
92     brex = (rg>>3)&0x01;
93     if(DisP->insn_flags&INSN_VEX_V) rval=k64_getREG(DisP,rg,1,brex,wrex);
94     return rval;
95 }
96 
GetDigitsApp(unsigned char loc_off,ix86Param * DisP,char codelen,int type)97 static char * __NEAR__ __FASTCALL__ GetDigitsApp(unsigned char loc_off,
98                                                  ix86Param *DisP,
99                                                  char codelen,int type)
100 {
101   ix86_appbuffer[0] = 0;
102   if(!((DisP->flags & __DISF_SIZEONLY) == __DISF_SIZEONLY))
103     disAppendDigits(ix86_appbuffer,DisP->CodeAddress + loc_off,
104                     APREF_USE_TYPE,codelen,&DisP->RealCmd[loc_off],type);
105   return ix86_appbuffer;
106 }
107 
108 #define Get2DigitApp(loc_off,DisP)   GetDigitsApp(loc_off,DisP,1,DISARG_BYTE)
109 #define Get2SignDigApp(loc_off,DisP) GetDigitsApp(loc_off,DisP,1,DISARG_CHAR)
110 #define Get4DigitApp(loc_off,DisP)   GetDigitsApp(loc_off,DisP,2,DISARG_WORD)
111 #define Get4SignDigApp(loc_off,DisP) GetDigitsApp(loc_off,DisP,2,DISARG_SHORT)
112 #define Get8DigitApp(loc_off,DisP)   GetDigitsApp(loc_off,DisP,4,DISARG_DWORD)
113 #define Get8SignDigApp(loc_off,DisP) GetDigitsApp(loc_off,DisP,4,DISARG_LONG)
114 #define Get16DigitApp(loc_off,DisP)   GetDigitsApp(loc_off,DisP,8,DISARG_QWORD)
115 #define Get16SignDigApp(loc_off,DisP) GetDigitsApp(loc_off,DisP,8,DISARG_LLONG)
Get2SquareDig(unsigned char loc_off,ix86Param * DisP,tBool as_sign)116 static char * __NEAR__ __FASTCALL__ Get2SquareDig(unsigned char loc_off,ix86Param *DisP,tBool as_sign)
117 {
118   char *ptr = ix86_apistr;
119   char *rets;
120   *ptr = 0;
121   if(!((DisP->flags & __DISF_SIZEONLY) == __DISF_SIZEONLY))
122   {
123     rets = GetDigitsApp(loc_off,DisP,1,as_sign ? DISARG_CHAR : DISARG_BYTE);
124     if(!(rets[0] == '+' || rets[0] == '-')) *ptr++ = '+';
125     strcpy(ptr,rets);
126   }
127   return ix86_apistr;
128 }
129 
Get4SquareDig(unsigned char loc_off,ix86Param * DisP,tBool as_sign,tBool is_disponly)130 static char * __NEAR__ __FASTCALL__ Get4SquareDig(unsigned char loc_off,ix86Param *DisP,tBool as_sign, tBool is_disponly)
131 {
132   char *ptr = ix86_apistr;
133   char *rets;
134   unsigned type;
135   *ptr = 0;
136   if(!((DisP->flags & __DISF_SIZEONLY) == __DISF_SIZEONLY))
137   {
138     type = as_sign ? DISARG_SHORT : DISARG_WORD;
139     type |= is_disponly ? DISARG_DISP : DISARG_IDXDISP;
140     rets = GetDigitsApp(loc_off,DisP,2,type);
141     if(!(rets[0] == '+' || rets[0] == '-')) *ptr++ = '+';
142     strcpy(ptr,rets);
143   }
144   return ix86_apistr;
145 }
146 
Get8SquareDig(unsigned char loc_off,ix86Param * DisP,tBool as_sign,tBool is_disponly,tBool as_rip)147 static char * __NEAR__ __FASTCALL__ Get8SquareDig(unsigned char loc_off,ix86Param *DisP,tBool as_sign,tBool is_disponly,tBool as_rip)
148 {
149   char *ptr = ix86_apistr;
150   char *rets;
151   unsigned type;
152   *ptr = 0;
153   if(!((DisP->flags & __DISF_SIZEONLY) == __DISF_SIZEONLY))
154   {
155     type = as_sign ? DISARG_LONG : DISARG_DWORD;
156     type |= is_disponly ? DISARG_DISP : DISARG_IDXDISP;
157     if(as_rip) type |= DISARG_RIP;
158     rets = GetDigitsApp(loc_off,DisP,4,type);
159     if(!(rets[0] == '+' || rets[0] == '-')) *ptr++ = '+';
160     strcpy(ptr,rets);
161   }
162   return ix86_apistr;
163 }
164 
Get16SquareDig(unsigned char loc_off,ix86Param * DisP,tBool as_sign,tBool is_disponly)165 static char * __NEAR__ __FASTCALL__ Get16SquareDig(unsigned char loc_off,ix86Param *DisP,tBool as_sign,tBool is_disponly)
166 {
167   char *ptr = ix86_apistr;
168   char *rets;
169   unsigned type;
170   *ptr = 0;
171   if(!((DisP->flags & __DISF_SIZEONLY) == __DISF_SIZEONLY))
172   {
173     type = as_sign ? DISARG_LLONG : DISARG_QWORD;
174     type |= is_disponly ? DISARG_DISP : DISARG_IDXDISP;
175     rets = GetDigitsApp(loc_off,DisP,8,type);
176     if(!(rets[0] == '+' || rets[0] == '-')) *ptr++ = '+';
177     strcpy(ptr,rets);
178   }
179   return ix86_apistr;
180 }
181 
ix86_ArgES(char * str,ix86Param * param)182 void __FASTCALL__ ix86_ArgES(char *str,ix86Param *param)
183 {
184   UNUSED(param);
185   strcat(str,"es");
186 }
187 
ix86_ArgDS(char * str,ix86Param * param)188 void __FASTCALL__ ix86_ArgDS(char *str,ix86Param *param)
189 {
190   UNUSED(param);
191   strcat(str,"ds");
192 }
193 
ix86_ArgSS(char * str,ix86Param * param)194 void __FASTCALL__ ix86_ArgSS(char *str,ix86Param *param)
195 {
196   UNUSED(param);
197   strcat(str,"ss");
198 }
199 
ix86_ArgCS(char * str,ix86Param * param)200 void __FASTCALL__ ix86_ArgCS(char *str,ix86Param *param)
201 {
202   UNUSED(param);
203   strcat(str,"cs");
204 }
205 
ix86_ArgFS(char * str,ix86Param * param)206 void __FASTCALL__ ix86_ArgFS(char *str,ix86Param *param)
207 {
208   UNUSED(param);
209   strcat(str,"fs");
210 }
211 
ix86_ArgGS(char * str,ix86Param * param)212 void __FASTCALL__ ix86_ArgGS(char *str,ix86Param *param)
213 {
214   UNUSED(param);
215   strcat(str,"gs");
216 }
217 
218 
ix86_GetDigitTile(ix86Param * DisP,char wrd,char sgn,unsigned char loc_off)219 static char * __FASTCALL__ ix86_GetDigitTile(ix86Param* DisP,char wrd,char sgn,unsigned char loc_off)
220 {
221   int cl,type;
222   int do_64;
223   do_64 = 0;
224   if(x86_Bitness == DAB_USE64 && wrd == -1) do_64 = 1; /* special case for */
225   cl = do_64 ? 8 : wrd ? ( USE_WIDE_DATA ? 4 : 2 ) : 1;
226   if(!((DisP->flags & __DISF_SIZEONLY) == __DISF_SIZEONLY))
227   {
228     if(do_64) type = sgn ? DISARG_LLONG : DISARG_QWORD;
229     else
230     type = sgn ? wrd ? ( USE_WIDE_DATA ? DISARG_LONG : DISARG_SHORT ) : DISARG_CHAR:
231                  wrd ? ( USE_WIDE_DATA ? DISARG_DWORD : DISARG_WORD ) : DISARG_BYTE;
232     type |= DISARG_IMM;
233     ix86_dtile[0] = 0;
234     disAppendDigits(ix86_dtile,
235                     DisP->CodeAddress + loc_off,
236                     APREF_USE_TYPE,cl,&DisP->RealCmd[loc_off],type);
237   }
238   DisP->codelen += cl;
239   return ix86_dtile;
240 }
241 
arg_segoff(char * str,ix86Param * DisP)242 void __FASTCALL__ arg_segoff(char * str,ix86Param *DisP)
243 {
244   unsigned long newpos = 0L;
245   long off = 0L;
246   unsigned short seg = 0;
247   if(!((DisP->flags & __DISF_SIZEONLY) == __DISF_SIZEONLY))
248   {
249     seg = USE_WIDE_DATA ? *((tInt16  *)(&DisP->RealCmd[5])) : *((tInt16  *)(&DisP->RealCmd[3]));
250     off = USE_WIDE_DATA ? *((tInt32  *)(&DisP->RealCmd[1])) : (tInt32)(*((tInt16  *)(&DisP->RealCmd[1])));
251     newpos = ((long)(seg) << 4) + off; /* It is computing of x86 real-mode address */
252   }
253   DisP->codelen += USE_WIDE_DATA ? 6 : 4;
254   if(!((DisP->flags & __DISF_SIZEONLY) == __DISF_SIZEONLY))
255     disAppendFAddr(str,DisP->CodeAddress + 1,off,newpos,
256                    USE_WIDE_DATA ? DISADR_FAR32 : DISADR_FAR16,seg,DisP->codelen-1);
257 }
258 
arg_offset(char * str,ix86Param * DisP)259 void __FASTCALL__ arg_offset(char * str,ix86Param *DisP)
260 {
261   long lshift = 0L;
262   unsigned long newpos;
263   unsigned modifier,off8;
264   off8 = (DisP->insn_flags&IMM_BYTE)?1:0;
265   if(!((DisP->flags & __DISF_SIZEONLY) == __DISF_SIZEONLY))
266     lshift =	off8 ? (long)(*((tInt8  *)(&DisP->RealCmd[1]))):
267 		USE_WIDE_DATA ?(long)(*((tInt32  *)(&DisP->RealCmd[1]))) :
268 					(long)(*((tInt16  *)(&DisP->RealCmd[1])));
269 #if 0
270 /*
271 In 64-bit mode, the operand size defaults to 64 bits. The processor sign-extends
272 the 8-bit or 32-bit displacement value to 64 bits before adding it to the RIP.
273 */
274   if(x86_Bitness == DAB_USE64) {
275     DisP->codelen += 8;
276     modifier=DISADR_NEAR64;
277   }
278   else
279 #endif
280   {
281     DisP->codelen += off8 ? 1 : USE_WIDE_DATA ? 4 : 2;
282     modifier = USE_WIDE_DATA ? off8 ? DISARG_SHORT : DISADR_NEAR32 : DISADR_NEAR16;
283   }
284   if(!((DisP->flags & __DISF_SIZEONLY) == __DISF_SIZEONLY))
285   {
286     newpos = DisP->CodeAddress + lshift + DisP->codelen;
287     disAppendFAddr(str,DisP->CodeAddress + 1,lshift,newpos,modifier,0,DisP->codelen);
288   }
289 }
290 
getSIBRegs(ix86Param * DisP,char * base,char * scale,char * _index,char * mod,char code)291 static void __NEAR__ __FASTCALL__ getSIBRegs(ix86Param*DisP,char * base,char * scale,char * _index,char *mod,char code)
292 {
293   char scl = (code & 0xC0) >> 6;
294   char bas = code & 0x07;
295   char ind = (code & 0x38) >> 3;
296   unsigned long mode = DisP->mode;
297   tBool brex, wrex;
298   DisP->mode|=MOD_WIDE_DATA;
299   DisP->mode&=~MOD_MMX;
300   DisP->mode&=~MOD_SSE;
301   brex = wrex = 0;
302   if(scl)
303   {
304     scale[0] = '*';
305     scale[1] = ( 1 << scl ) + 0x30;
306     scale[2] = 0;
307   }
308   else scale[0] = 0;
309   if(ind == 4)
310   {
311 	if(x86_Bitness == DAB_USE64 && REX_X(K64_REX))
312 	    /*	AMD 24594.pdf rev 3.02 aug 2002:
313 		REX adds fourth bit (X) which is decoded
314 		that allows to use R12 as index.
315 	     */
316 	     goto do_r12;
317 	else
318 	_index[0] = 0;
319   }
320   else
321   {
322      do_r12:
323      if(x86_Bitness == DAB_USE64)
324      {
325          wrex = HAS_67_IN64?0:1;
326          brex = REX_X(K64_REX);
327      }
328      strcpy(_index,k64_getREG(DisP,ind,True,brex,wrex));
329   }
330   if(bas == 5 && *mod == 0) { base[0] = 0; *mod = 2; }
331   else
332   {
333      if(x86_Bitness == DAB_USE64)
334      {
335          wrex = HAS_67_IN64?0:1;
336          brex = REX_B(K64_REX);
337      }
338     strcpy(base,k64_getREG(DisP,bas,True,brex,wrex));
339   }
340   DisP->mode = mode;
341 #if 0
342   return ind == 4 || ind == 5 || bas == 4 || bas == 5; /** return is_stack */
343 #endif
344 }
345 
ConstrSibMod(ix86Param * DisP,char * store,char * scale,char * _index,char * base,char code,char * mod)346 static char * __NEAR__ __FASTCALL__ ConstrSibMod(ix86Param*DisP,char * store,char * scale,char * _index,char * base,char code,char *mod)
347 {
348    getSIBRegs(DisP,base,scale,_index,mod,code);
349    store[0] = 0;
350    if(_index[0])
351    {
352      strcat(store,_index);
353      strcat(store,scale);
354    }
355    if(base[0])
356    {
357      if(_index[0]) strcat(store,"+");
358      strcat(store,base);
359    }
360    return store;
361 }
362 
363 
ix86_getModRM16(tBool w,unsigned char mod,unsigned char rm,ix86Param * DisP)364 char * __FASTCALL__ ix86_getModRM16(tBool w,unsigned char mod,unsigned char rm,ix86Param *DisP)
365 {
366  char square[50];
367  char new_mode = mod;
368  unsigned char clen;
369  tBool as_sign,is_disponly,as_rip;
370  if(!((DisP->flags & __DISF_SIZEONLY) == __DISF_SIZEONLY)) {
371     strcpy(square,ix86_A16[rm]);
372     mod = new_mode;
373     if(mod != 3)
374     {
375 	strcat(ix86_modrm_ret,ix86_segpref);
376 	ix86_segpref[0] = 0;
377     }
378     is_disponly = False;
379     as_sign = True;
380     as_rip=False;
381  }
382  clen = 2;
383  switch(mod) {
384     case 0:
385 	if(rm!=6)	clen=0;
386 	else		clen=2;
387 	break;
388     case 1:
389 	clen = 1;
390 	break;
391     case 2:
392 	clen=2;
393 	break;
394     default:
395 	clen=0;
396 	break;
397  }
398  if(!((DisP->flags & __DISF_SIZEONLY) == __DISF_SIZEONLY)) {
399     switch(mod) {
400 	case 0:
401 		if(rm != 6) /* i.e. combine address */
402 		    strcat(ix86_modrm_ret,square);
403 		else { /* i.e. displacement only. fake mod = 2 */
404 		    square[0] = 0;
405 		    is_disponly = True;
406 		    as_sign = False;
407 		    goto disp_long;
408 		}
409 		break;
410 	case 1:
411 		strcat(ix86_modrm_ret,ix86_segpref);
412 		ix86_segpref[0] = 0;
413 		strcat(ix86_modrm_ret,square);
414 		/* The "disp8" nomenclature denotes an 8-bit displacement
415 		   following the ModR/M or SIB byte, to be sign-extended
416 		   and added to the index. */
417 		strcat(ix86_modrm_ret,Get2SquareDig(2,DisP,True));
418 		break;
419 	case 2: {
420 		disp_long:
421 		strcat(ix86_modrm_ret,ix86_segpref);
422 		ix86_segpref[0] = 0;
423 		strcat(ix86_modrm_ret,square);
424 		strcat(ix86_modrm_ret,Get4SquareDig(2,DisP,as_sign,is_disponly));
425 		}
426 		break;
427 	default:
428 		strcat(ix86_modrm_ret,k64_getREG(DisP,rm,w,0,0));
429 		break;
430     }
431  }
432  if(mod != 3) DisP->codelen += clen;
433  return ix86_modrm_ret;
434 }
435 
ix86_getModRM32(tBool w,unsigned char mod,unsigned char rm,ix86Param * DisP)436 char * __FASTCALL__ ix86_getModRM32(tBool w,unsigned char mod,unsigned char rm,ix86Param *DisP)
437 {
438  const char *cptr;
439  char square[50];
440  char ret1[50];
441  char base[8];
442  char _index[8];
443  char scale[4];
444  char new_mode = mod;
445  unsigned char clen,tmp;
446  tBool as_sign,is_disponly,as_rip;
447  if(!((DisP->flags & __DISF_SIZEONLY) == __DISF_SIZEONLY)) {
448     if(rm == 4)	cptr = ConstrSibMod(DisP,ret1,base,_index,scale,DisP->RealCmd[2],&new_mode);
449     else	cptr = k64_DWordRegs[REX_reg(REX_b(K64_REX),rm)];
450     strcpy(square,cptr);
451     mod = new_mode;
452     if(mod != 3) {
453 	strcat(ix86_modrm_ret,ix86_segpref);
454 	ix86_segpref[0] = 0;
455     }
456     is_disponly = False;
457     as_sign = True;
458     as_rip=False;
459  }
460  clen = 2;
461  switch(mod) {
462     case 0:
463 	if(rm != 5) { /* i.e. combine address */
464 	    clen = 0;
465 	    if(rm == 4) clen = 1;
466 	}
467 	else goto __disp_long;
468 	break;
469     case 1:
470 	if(rm != 4)	clen = 1;
471 	else		clen = 2;
472 	break;
473     case 2: {
474 	    __disp_long:
475 	    if(rm != 4)	clen = 4;
476 	    else	clen = 5;
477 	}
478 	break;
479     default:
480 	clen=0;
481 	break;
482  }
483  if(!((DisP->flags & __DISF_SIZEONLY) == __DISF_SIZEONLY)) {
484     switch(mod) {
485 	case 0:
486 		if(rm != 5) /* i.e. combine address */
487 		    strcat(ix86_modrm_ret,square);
488 		else { /* i.e. displacement only. fake mod = 2 */
489 		    square[0] = 0;
490 		    is_disponly = True;
491 		    as_sign = False;
492 		    goto disp_long;
493 		}
494 		break;
495 	case 1:
496 		if(rm != 4)	tmp = 2;
497 		else		tmp = 3;
498 		strcat(ix86_modrm_ret,square);
499 		/* The "disp8" nomenclature denotes an 8-bit displacement
500 		   following the ModR/M or SIB byte, to be sign-extended
501 		   and added to the index. */
502 		strcat(ix86_modrm_ret,Get2SquareDig(tmp,DisP,True));
503 		break;
504 	case 2: {
505 		disp_long:
506 		    if(rm != 4)	tmp = 2;
507 		    else	tmp = 3;
508 		    strcat(ix86_modrm_ret,square);
509 		    strcat(ix86_modrm_ret,Get8SquareDig(tmp,DisP,as_sign,is_disponly,as_rip));
510 		}
511 		break;
512 	default:
513 		strcat(ix86_modrm_ret,k64_getREG(DisP,rm,w,0,0));
514 		break;
515     }
516  }
517  if(mod != 3) DisP->codelen += clen;
518  return ix86_modrm_ret;
519 }
520 
ix86_getModRM64(tBool w,unsigned char mod,unsigned char rm,ix86Param * DisP)521 char * __FASTCALL__ ix86_getModRM64(tBool w,unsigned char mod,unsigned char rm,ix86Param *DisP)
522 {
523  const char *cptr;
524  char square[50];
525  char ret1[50];
526  char base[8];
527  char _index[8];
528  char scale[4];
529  char new_mode = mod;
530  unsigned char clen,tmp;
531  tBool as_sign,is_disponly,as_rip;
532  if(!((DisP->flags & __DISF_SIZEONLY) == __DISF_SIZEONLY)) {
533     if(rm == 4)	cptr = ConstrSibMod(DisP,ret1,base,_index,scale,DisP->RealCmd[2],&new_mode);
534     else	cptr = k64_QWordRegs[REX_reg(REX_b(K64_REX),rm)];
535     strcpy(square,cptr);
536     mod = new_mode;
537     if(mod != 3) {
538 	strcat(ix86_modrm_ret,ix86_segpref);
539 	ix86_segpref[0] = 0;
540     }
541     is_disponly = False;
542     as_sign = True;
543     as_rip=False;
544  }
545  clen = 2;
546  switch(mod) {
547     case 0:
548 	if(rm != 5) { /* i.e. combine address */
549 	    clen = 0;
550 	    if(rm == 4) clen = 1;
551 	}
552 	else goto __disp_long;
553 	break;
554     case 1:
555 	if(rm != 4)	clen = 1;
556 	else		clen = 2;
557 	break;
558     case 2: {
559 	__disp_long:
560 	    if(rm != 4)	clen = 4;
561 	    else	clen = 5;
562 	}
563 	break;
564     default:
565 	clen=0;
566 	break;
567  }
568  if(!((DisP->flags & __DISF_SIZEONLY) == __DISF_SIZEONLY)) {
569     switch(mod) {
570 	case 0:
571 		if(rm != 5) /* i.e. combine address */
572 		    strcat(ix86_modrm_ret,square);
573 		else { /* i.e. displacement only. fake mod = 2 */
574 		    square[0] = 0;
575 		    is_disponly = True;
576 		    as_sign = False;
577 		    goto disp_long;
578 		}
579 		break;
580 	case 1:
581 		if(rm != 4)	tmp = 2;
582 		else		tmp = 3;
583 		strcat(ix86_modrm_ret,square);
584 		/* The "disp8" nomenclature denotes an 8-bit displacement
585 		   following the ModR/M or SIB byte, to be sign-extended
586 		   and added to the index. */
587 		strcat(ix86_modrm_ret,Get2SquareDig(tmp,DisP,True));
588 		break;
589 	case 2: {
590 		    disp_long:
591 		    if(is_disponly) {
592 			strcat(ix86_modrm_ret,"rip");
593 			as_sign = True;
594 			is_disponly = False;
595 			as_rip=True;
596 		    }
597 		    if(rm != 4)	tmp = 2;
598 		    else	tmp = 3;
599 		    strcat(ix86_modrm_ret,square);
600 		    strcat(ix86_modrm_ret,Get8SquareDig(tmp,DisP,as_sign,is_disponly,as_rip));
601 		}
602 		break;
603 	default: {
604 		    tBool brex, use64;
605 		    brex = REX_B(K64_REX);
606 		    use64 = REX_W(K64_REX);
607 		    strcat(ix86_modrm_ret,k64_getREG(DisP,rm,w,brex,use64));
608 		}
609 		break;
610     }
611  }
612  if(mod != 3) DisP->codelen += clen;
613  return ix86_modrm_ret;
614 }
615 
ix86_getModRM(tBool w,unsigned char mod,unsigned char rm,ix86Param * DisP)616 char * __FASTCALL__ ix86_getModRM(tBool w,unsigned char mod,unsigned char rm,ix86Param *DisP)
617 {
618     char *rval;
619     if(!((DisP->flags & __DISF_SIZEONLY) == __DISF_SIZEONLY)) {
620 	if(mod!=3)	strcpy(ix86_modrm_ret,"[");
621 	else		ix86_modrm_ret[0]=0;
622     }
623     if((x86_Bitness == DAB_USE16 || x86_Bitness == DAB_USE32) && !USE_WIDE_ADDR) rval = ix86_getModRM16(w,mod,rm,DisP);
624     else
625     if(x86_Bitness == DAB_USE64 && USE_WIDE_ADDR) rval = ix86_getModRM64(w,mod,rm,DisP);
626     else rval = ix86_getModRM32(w,mod,rm,DisP);
627     if(!((DisP->flags & __DISF_SIZEONLY) == __DISF_SIZEONLY)) {
628 	if(mod!=3)	strcat(ix86_modrm_ret,"]");
629     }
630     return rval;
631 }
632 
ix86_CStile(ix86Param * DisP,char * str,const char * arg2)633 char * __FASTCALL__ ix86_CStile(ix86Param *DisP,char *str,const char *arg2)
634 {
635   if(!((DisP->flags & __DISF_SIZEONLY) == __DISF_SIZEONLY)) {
636     strcat(str,",");
637     strcat(str,arg2);
638   }
639   return str;
640 }
641 
__buildModRegRm(ix86Param * DisP,tBool w,tBool d)642 static char * __NEAR__ __FASTCALL__ __buildModRegRm(ix86Param *DisP,tBool w,tBool d)
643 {
644  char reg = MODRM_REG(DisP->RealCmd[1]);
645  char mod = MODRM_MOD(DisP->RealCmd[1]);
646  char rm  = MODRM_RM(DisP->RealCmd[1]);
647  const char *regs,* modrm, *ends, *vxx=NULL;
648  tBool brex, wrex, vex_d;
649  brex = REX_R(K64_REX);
650  wrex = REX_W(K64_REX);
651  regs = k64_getREG(DisP,reg,w,brex,wrex);
652  brex = REX_B(K64_REX);
653  if(mod == 3) modrm = k64_getREG(DisP,rm,w,brex,wrex);
654  else         modrm = ix86_getModRM(w,mod,rm,DisP);
655  ix86_dtile[0] = 0;
656  vex_d = 0;
657  if(DisP->insn_flags&INSN_VEXW_AS_SWAP && DisP->pfx&PFX_VEX) vex_d = REX_W(K64_REX);
658  strcat(ix86_dtile,d ? regs : modrm);
659  /* add VEX.vvvv field as first source operand */
660  ends = d ? modrm : regs;
661  if((DisP->pfx&PFX_VEX) && (DisP->insn_flags&INSN_VEX_V)) vxx = get_VEX_reg(DisP);
662  if(vxx) {
663     ix86_CStile(DisP,ix86_dtile,vex_d ? ends : vxx);
664     ix86_CStile(DisP,ix86_dtile,vex_d ? vxx : ends);
665  }
666  else     ix86_CStile(DisP,ix86_dtile,ends);
667  return ix86_dtile;
668 }
669 
__buildModRegRmReg(ix86Param * DisP,tBool d,unsigned char wrex)670 static char * __NEAR__ __FASTCALL__ __buildModRegRmReg(ix86Param *DisP,tBool d,unsigned char wrex)
671 {
672  char reg = MODRM_REG(DisP->RealCmd[1]);
673  char mod = MODRM_MOD(DisP->RealCmd[1]);
674  char rm  = MODRM_RM(DisP->RealCmd[1]);
675  const char *dest,*src1,*src2;
676  unsigned char is4,brex,reg2;
677  brex = REX_R(K64_REX);
678  dest = k64_getREG(DisP,reg,1,brex,wrex);
679  brex = REX_B(K64_REX);
680  DisP->codelen++;
681  if(mod == 3) src1 = k64_getREG(DisP,rm,1,brex,wrex);
682  else         src1 = ix86_getModRM(1,mod,rm,DisP);
683  is4=DisP->RealCmd[DisP->codelen];
684  reg2 = ((is4>>4)&0x0F);
685  src2 = k64_getREG(DisP,reg2&0x07,1,(reg2>>3)&1,wrex);
686  ix86_dtile[0] = 0;
687  strcat(ix86_dtile,dest);
688  /* add VEX.vvvv field as first source operand */
689  if((DisP->pfx&PFX_VEX) && (DisP->insn_flags&INSN_VEX_V)) ix86_CStile(DisP,ix86_dtile,get_VEX_reg(DisP));
690  ix86_CStile(DisP,ix86_dtile,d ? src2 : src1);
691  ix86_CStile(DisP,ix86_dtile,d ? src1 : src2);
692  DisP->codelen++;
693  return ix86_dtile;
694 }
695 
arg_cpu_modregrm(char * str,ix86Param * DisP)696 void __FASTCALL__ arg_cpu_modregrm(char * str,ix86Param *DisP)
697 {
698  DisP->codelen++;
699  strcat(str,__buildModRegRm(DisP,(DisP->insn_flags&INSN_OP_BYTE)?False:True,(DisP->insn_flags&INSN_STORE)?False:True));
700 }
701 
arg_cpu_modREGrm(char * str,ix86Param * DisP)702 void __FASTCALL__ arg_cpu_modREGrm(char * str,ix86Param *DisP)
703 {
704   tBool brex,wrex;
705   char reg = MODRM_REG(DisP->RealCmd[1]);
706   char mod = MODRM_MOD(DisP->RealCmd[1]);
707   char rm = MODRM_RM(DisP->RealCmd[1]);
708   unsigned long mode = DisP->mode;
709   brex = REX_B(K64_REX);
710   wrex = REX_W(K64_REX);
711   if(x86_Bitness>DAB_USE16) DisP->mode|=MOD_WIDE_DATA;
712   strcat(str,k64_getREG(DisP,reg,True,brex,wrex));
713   DisP->mode=mode;
714   DisP->codelen++;
715   ix86_CStile(DisP,str,ix86_getModRM((DisP->insn_flags&INSN_OP_BYTE)?False:True,mod,rm,DisP));
716 }
717 
arg_cpu_mod_rm(char * str,ix86Param * DisP)718 void __FASTCALL__ arg_cpu_mod_rm(char* str,ix86Param *DisP)
719 {
720   char mod = MODRM_MOD(DisP->RealCmd[1]);
721   char rm = MODRM_RM(DisP->RealCmd[1]);
722   tBool w = (DisP->insn_flags&INSN_OP_BYTE)?False:True;
723   if(mod<3) ix86_setModifier(str,ix86_sizes[ix86_calcModifier(DisP,w)]);
724   DisP->codelen++;
725   strcat(str,ix86_getModRM(w,mod,rm,DisP));
726 }
727 
arg_cpu_mod_rm_imm(char * str,ix86Param * DisP)728 void  __FASTCALL__ arg_cpu_mod_rm_imm(char *str,ix86Param *DisP)
729 {
730   arg_cpu_mod_rm(str,DisP);
731   ix86_CStile(DisP,str,ix86_GetDigitTile(DisP,(DisP->insn_flags&IMM_BYTE)?False:True,0,DisP->codelen));
732 }
733 
arg_cpu_modregrm_imm(char * str,ix86Param * DisP)734 void  __FASTCALL__ arg_cpu_modregrm_imm(char *str,ix86Param *DisP)
735 {
736   arg_cpu_modregrm(str,DisP);
737   ix86_CStile(DisP,str,ix86_GetDigitTile(DisP,(DisP->insn_flags&IMM_BYTE)?False:True,0,DisP->codelen));
738 }
739 
arg_cpu_modsegrm(char * str,ix86Param * DisP)740 void __FASTCALL__ arg_cpu_modsegrm(char * str,ix86Param *DisP)
741 {
742   char direct = ( DisP->RealCmd[0] & 0x02 ) >> 1;
743   char sreg  = MODRM_REG(DisP->RealCmd[1]);
744   char reg   = MODRM_RM(DisP->RealCmd[1]);
745   char mod   = MODRM_MOD(DisP->RealCmd[1]);
746   const char *tileptr,*sregptr;
747   unsigned long mode = DisP->mode;
748   DisP->mode&= ~MOD_WIDE_DATA; /* disable: 'mov eax, ds' constructions */
749   sregptr = getSREG(sreg);
750   DisP->codelen = 2;
751   tileptr = ix86_getModRM(True,mod,reg,DisP);
752   if(sreg > 3)
753     if(((DisP->pro_clone & IX86_CPUMASK) < 3) && (x86_Bitness != DAB_USE64))
754       DisP->pro_clone = IX86_CPU386;
755   DisP->mode = mode;
756   strcat(str,direct ? sregptr : tileptr);
757   ix86_CStile(DisP,str,direct ? tileptr : sregptr);
758 }
759 
arg_r0_imm(char * str,ix86Param * DisP)760 void __FASTCALL__ arg_r0_imm(char * str,ix86Param *DisP)
761 {
762   char w = DisP->RealCmd[0] & 0x01;
763   tBool wrex=0;
764   wrex = REX_W(K64_REX);
765   /* I guess that K9 will support "OP rax, imm64" forms
766      same as "OP rrx, imm64" since they are not longer
767      than 15 bytes in length
768      (example: "adc r13, 123456789ABCDEF0").
769      TODO: if(use64) w = -1; here */
770   strcat(str,k64_getREG(DisP,0,w,0,wrex));
771   ix86_CStile(DisP,str,ix86_GetDigitTile(DisP,w,0,1));
772 }
773 
arg_r0rm(char * str,ix86Param * DisP)774 void __FASTCALL__ arg_r0rm(char *str,ix86Param *DisP)
775 {
776   unsigned char rm = MODRM_RM(DisP->RealCmd[0]);
777   tBool brex,wrex;
778   brex = REX_B(K64_REX);
779   wrex = REX_W(K64_REX);
780   if(rm==0 && !HAS_REX) strcpy(str,"nop");
781   else {
782     strcat(str,k64_getREG(DisP,0,True,0,wrex));
783     ix86_CStile(DisP,str,k64_getREG(DisP,rm,True,brex,wrex));
784   }
785 }
786 
arg_r0mem(char * str,ix86Param * DisP)787 void __FASTCALL__ arg_r0mem(char *str,ix86Param *DisP)
788 {
789   unsigned char d = DisP->RealCmd[0] & 0x02;
790   const char *mem,*reg;
791   tBool wrex = REX_W(K64_REX);
792   if(x86_Bitness == DAB_USE64 && !HAS_67_IN64)
793   /* Opcodes A0 through A3 are address sized. In 64-bit mode, memory offset default to 64-bit. */
794   {
795     mem = Get16SquareDig(1,DisP,False,True);
796   }
797   else
798     mem = USE_WIDE_ADDR ?   Get8SquareDig(1,DisP,False,True,False) :
799 			    Get4SquareDig(1,DisP,False,True);
800   strcpy(ix86_appstr,"[");
801   strcat(ix86_appstr,ix86_segpref);
802   ix86_segpref[0] = 0;
803   strcat(ix86_appstr,mem);
804   strcat(ix86_appstr,"]");
805   reg = k64_getREG(DisP,0,DisP->RealCmd[0] & 0x01,0,wrex);
806   if(x86_Bitness == DAB_USE64 && !HAS_67_IN64) DisP->codelen = 9;
807   else  DisP->codelen = USE_WIDE_ADDR ? 5 : 3;
808   strcat(str,d ? ix86_appstr : reg);
809   ix86_CStile(DisP,str,d ? reg : ix86_appstr);
810 }
811 
arg_insnreg(char * str,ix86Param * DisP)812 void __FASTCALL__ arg_insnreg(char *str,ix86Param *DisP)
813 {
814   tBool brex,wrex;
815   brex = REX_B(K64_REX);
816   wrex = REX_W(K64_REX);
817   strcat(str,k64_getREG(DisP,MODRM_RM(DisP->RealCmd[0]),(DisP->insn_flags&INSN_OP_BYTE)?False:True,brex,(DisP->insn_flags&K64_FORCE64)?1:wrex));
818 }
819 
arg_insnreg_imm(char * str,ix86Param * DisP)820 void __FASTCALL__ arg_insnreg_imm(char * str,ix86Param *DisP)
821 {
822   char w = (DisP->insn_flags&INSN_OP_BYTE)?0:1;
823   arg_insnreg(str,DisP);
824   if(x86_Bitness == DAB_USE64 && REX_W(K64_REX) && w) w = -1; /* special case for do64 */
825   ix86_CStile(DisP,str,ix86_GetDigitTile(DisP,w,0,1));
826 }
827 
arg_imm(char * str,ix86Param * DisP)828 void __FASTCALL__ arg_imm(char *str,ix86Param *DisP)
829 {
830   char wrd = 1,sgn = 0;
831   if(DisP->insn_flags&IMM_BYTE) {
832     ix86_setModifier(str,ix86_sizes[ix86_calcModifier(DisP,1)]);
833     wrd = 0;
834     sgn = 1;
835   }
836   if(x86_Bitness == DAB_USE64 && REX_W(K64_REX)) wrd=-1;
837   strcat(str,ix86_GetDigitTile(DisP,wrd,sgn,1));
838 }
839 
arg_imm8(char * str,ix86Param * DisP)840 void __FASTCALL__ arg_imm8(char *str,ix86Param *DisP)
841 {
842   if(!((DisP->flags & __DISF_SIZEONLY) == __DISF_SIZEONLY))
843     disAppendDigits(str,DisP->CodeAddress + DisP->codelen,
844                  APREF_USE_TYPE,1,&DisP->RealCmd[DisP->codelen],DISARG_BYTE);
845   DisP->codelen++;
846 }
847 
arg_imm16(char * str,ix86Param * DisP)848 void __FASTCALL__ arg_imm16(char *str,ix86Param *DisP)
849 {
850   if(!((DisP->flags & __DISF_SIZEONLY) == __DISF_SIZEONLY))
851     disAppendDigits(str,DisP->CodeAddress + DisP->codelen,
852                  APREF_USE_TYPE,2,&DisP->RealCmd[DisP->codelen],DISARG_WORD | DISARG_IMM);
853   DisP->codelen+=2;
854 }
855 
arg_imm16_imm8(char * str,ix86Param * DisP)856 void __FASTCALL__ arg_imm16_imm8(char *str,ix86Param *DisP)
857 {
858   arg_imm16(str,DisP);
859   if(!((DisP->flags & __DISF_SIZEONLY) == __DISF_SIZEONLY)) strcat(str,",");
860   arg_imm8(str,DisP);
861 }
862 
ix86_ArgRmDigit(char * str,ix86Param * DisP,char w,char s)863 static void __FASTCALL__ ix86_ArgRmDigit(char *str,ix86Param *DisP,char w,char s)
864 {
865    char mod = MODRM_MOD(DisP->RealCmd[1]);
866    char rm = MODRM_RM(DisP->RealCmd[1]);
867    strcat(str,ix86_getModRM(w == 2 ? True : w,mod,rm,DisP));
868    DisP->codelen++;
869    ix86_CStile(DisP,str,ix86_GetDigitTile(DisP,w == 2 ? 0 : w,s,DisP->codelen));
870 }
871 
ix86_ArgOp1(char * str,ix86Param * DisP)872 void __FASTCALL__ ix86_ArgOp1(char *str,ix86Param *DisP)
873 {
874    unsigned char w = DisP->RealCmd[0] & 0x01;
875    unsigned char cop = MODRM_COP(DisP->RealCmd[1]);
876    strcpy(str,ix86_Op1Names[cop]);
877    TabSpace(str,TAB_POS);
878    ix86_ArgRmDigit(str,DisP,w,cop == 0 || cop == 2 || cop == 3 || cop == 5 ? 1 : 0);
879 }
880 
ix86_ArgOp2(char * str,ix86Param * DisP)881 void __FASTCALL__ ix86_ArgOp2(char *str,ix86Param *DisP)
882 {
883    unsigned char w = DisP->RealCmd[0] & 0x01;
884    unsigned char cop = MODRM_COP(DisP->RealCmd[1]);
885    strcpy(str,ix86_Op1Names[cop]);
886    TabSpace(str,TAB_POS);
887    if(w) ix86_setModifier(str,ix86_sizes[ix86_calcModifier(DisP,w)]);
888    ix86_ArgRmDigit(str,DisP,w ? 2 : w, w ? 1 : 0);
889 }
890 
ix86_ShOp2(char * str,ix86Param * DisP)891 void __FASTCALL__ ix86_ShOp2(char *str,ix86Param *DisP)
892 {
893    char *a1,*a2;
894    unsigned char cop = MODRM_COP(DisP->RealCmd[1]);
895    unsigned char mod = MODRM_MOD(DisP->RealCmd[1]);
896    unsigned char rm = MODRM_RM(DisP->RealCmd[1]);
897    unsigned char w = DisP->RealCmd[0] & 0x01;
898    DisP->codelen++;
899    strcpy(str,ix86_ShNames[cop]);
900    TabSpace(str,TAB_POS);
901    ix86_setModifier(str,ix86_sizes[ix86_calcModifier(DisP,w)]);
902    a1 = ix86_getModRM(w,mod,rm,DisP);
903    strcat(str,a1);
904    a2 = ix86_GetDigitTile(DisP,0,0,DisP->codelen);
905    ix86_CStile(DisP,str,a2);
906 }
907 
ix86_DblShift(char * str,ix86Param * DisP)908 void  __FASTCALL__ ix86_DblShift(char *str,ix86Param *DisP)
909 {
910     unsigned char code = DisP->RealCmd[0];
911     arg_cpu_modregrm(str,DisP);
912     if(code&0x01) ix86_CStile(DisP,str,"cl");
913     else {
914 	if(!((DisP->flags & __DISF_SIZEONLY) == __DISF_SIZEONLY)) strcat(str,",");
915 	arg_imm8(str,DisP);
916     }
917 }
918 
ix86_ShOp1(char * str,ix86Param * DisP)919 void __FASTCALL__ ix86_ShOp1(char *str,ix86Param *DisP)
920 {
921    char *a1;
922    unsigned char cop = MODRM_COP(DisP->RealCmd[1]);
923    unsigned char mod = MODRM_MOD(DisP->RealCmd[1]);
924    unsigned char rm = MODRM_RM(DisP->RealCmd[1]);
925    unsigned char w = DisP->RealCmd[0] & 0x01;
926    DisP->codelen++;
927    a1 = ix86_getModRM(w,mod,rm,DisP);
928    strcpy(str,ix86_ShNames[cop]);
929    TabSpace(str,TAB_POS);
930    ix86_setModifier(str,ix86_sizes[ix86_calcModifier(DisP,w)]);
931    strcat(str,a1);
932    ix86_CStile(DisP,str,"1");
933 }
934 
ix86_ShOpCL(char * str,ix86Param * DisP)935 void __FASTCALL__ ix86_ShOpCL(char *str,ix86Param *DisP)
936 {
937    char *a1;
938    unsigned char cop = MODRM_COP(DisP->RealCmd[1]);
939    unsigned char mod = MODRM_MOD(DisP->RealCmd[1]);
940    unsigned char rm = MODRM_RM(DisP->RealCmd[1]);
941    unsigned char w = DisP->RealCmd[0] & 0x01;
942    DisP->codelen++;
943    a1 = ix86_getModRM(w,mod,rm,DisP);
944    strcpy(str,ix86_ShNames[cop]);
945    TabSpace(str,TAB_POS);
946    ix86_setModifier(str,ix86_sizes[ix86_calcModifier(DisP,w)]);
947    strcat(str,a1);
948    ix86_CStile(DisP,str,"cl");
949 }
950 
ix86_ArgGrp1(char * str,ix86Param * DisP)951 void __FASTCALL__ ix86_ArgGrp1(char *str,ix86Param *DisP)
952 {
953    unsigned char cop = MODRM_COP(DisP->RealCmd[1]);
954    unsigned char mod = MODRM_MOD(DisP->RealCmd[1]);
955    unsigned char rm = MODRM_RM(DisP->RealCmd[1]);
956    unsigned char w = DisP->RealCmd[0] & 0x01;
957    strcpy(str,ix86_Gr1Names[cop]);
958    TabSpace(str,TAB_POS);
959    DisP->codelen++;
960    ix86_setModifier(str,ix86_sizes[ix86_calcModifier(DisP,w)]);
961    if(!cop) /** test only */
962    {
963      strcat(str,ix86_getModRM(w,mod,rm,DisP));
964      ix86_CStile(DisP,str,ix86_GetDigitTile(DisP,w == 2 ? 0 : w,0,DisP->codelen));
965    }
966    else
967    strcat(str,ix86_getModRM(w,mod,rm,DisP));
968 }
969 
ix86_ArgGrp2(char * str,ix86Param * DisP)970 void __FASTCALL__ ix86_ArgGrp2(char *str,ix86Param *DisP)
971 {
972    unsigned char cop = MODRM_COP(DisP->RealCmd[1]);
973    unsigned char mod = MODRM_MOD(DisP->RealCmd[1]);
974    unsigned char rm = MODRM_RM(DisP->RealCmd[1]);
975    unsigned char w = DisP->RealCmd[0] & 0x01;
976    unsigned char wrd = cop & 0x01;
977    unsigned sizptr;
978    unsigned oldDisNeedRef;
979    unsigned char REX = DisP->REX;
980    DisP->codelen++;
981    strcpy(str,ix86_Gr2Names[cop]);
982    /*
983       Added by "Kostya Nosov" <k-nosov@yandex.ru>:
984       make NEEDREF_ALL for indirect "jmp" and "call"
985    */
986    oldDisNeedRef = disNeedRef;
987 /*
988    if(code2 >= 2 && code2 <= 5 && disNeedRef != NEEDREF_NONE)
989                                              disNeedRef = NEEDREF_ALL;
990 */
991    TabSpace(str,TAB_POS);
992    if(cop >=2 && cop <= 5) DisP->REX|=0x08;
993    if(cop == 0 || cop == 1) { strcat(str,ix86_getModRM(w,mod,rm,DisP)); } /** inc dec */
994    else
995    {
996      wrd = cop == 0x06 || cop == 0x07 ? 0 : wrd; /** push / pop; */
997      if(x86_Bitness == DAB_USE64) sizptr = HAS_REX?REX_w(K64_REX)?QWORD_PTR:DWORD_PTR:QWORD_PTR;
998      else
999      if(!wrd) sizptr = USE_WIDE_DATA?DWORD_PTR:WORD_PTR;
1000      else     sizptr = USE_WIDE_DATA?PWORD_PTR:DWORD_PTR;
1001      ix86_setModifier(str,ix86_sizes[sizptr]);
1002      strcat(str,ix86_getModRM(True,mod,rm,DisP));
1003    }
1004    disNeedRef = oldDisNeedRef;
1005    DisP->REX = REX;
1006 }
1007 
ix86_InOut(char * str,ix86Param * DisP)1008 void __FASTCALL__ ix86_InOut(char * str,ix86Param *DisP)
1009 {
1010   const char *arg,*reg1,*reg2,*regptr,*dig;
1011   char i;
1012   regptr = k64_getREG(DisP,0,DisP->RealCmd[0] & 0x01,0,0);
1013   dig = Get2Digit(DisP->RealCmd[1]);
1014   i = DisP->RealCmd[0] & 0x08;
1015   if(!i) DisP->codelen++;
1016   arg = i ? "dx" : dig;
1017   if(DisP->RealCmd[0] & 0x02)
1018   {
1019       reg1  = arg;
1020       reg2  = regptr;
1021   }
1022   else
1023   {
1024       reg1  = regptr;
1025       reg2  = arg;
1026   }
1027   strcat(str,reg1);
1028   ix86_CStile(DisP,str,reg2);
1029 }
1030 
ix86_prepare_flags(const ix86_ExOpcodes * extable,ix86Param * DisP,unsigned char * code,unsigned char * codelen)1031 const ix86_ExOpcodes* __FASTCALL__ ix86_prepare_flags(const ix86_ExOpcodes *extable,ix86Param *DisP,unsigned char *code,unsigned char* codelen)
1032 {
1033  int in_chain=1;
1034  while(in_chain)
1035  {
1036     if(x86_Bitness == DAB_USE64)
1037     {
1038 	if(extable[*code].flags64&TAB_NAME_IS_TABLE)
1039 		extable=(ix86_ExOpcodes*)(extable[*code].name64);
1040 	else in_chain=0;
1041     }
1042     else
1043     if(extable[*code].pro_clone&TAB_NAME_IS_TABLE)
1044 	extable=(ix86_ExOpcodes*)(extable[*code].name);
1045     else in_chain = 0;
1046 
1047     if(in_chain) {
1048 	DisP->RealCmd = &DisP->RealCmd[1];
1049 	*code = DisP->RealCmd[0];
1050 	(*codelen)++;
1051     }
1052     else {
1053 	if(x86_Bitness == DAB_USE64) {
1054 		DisP->pro_clone = extable[*code].flags64&(~INSN_FLAGS_MASK);
1055 		DisP->insn_flags = extable[*code].flags64;
1056 	}
1057 	else {
1058 		DisP->pro_clone = extable[*code].pro_clone&(~INSN_FLAGS_MASK);
1059 		DisP->insn_flags = extable[*code].pro_clone;
1060 	}
1061 	in_chain=0;
1062     }
1063  }
1064  return extable;
1065 }
1066 
1067 /** 0f xx opcodes */
1068 
ix86_ExOpCodes(char * str,ix86Param * DisP)1069 void  __FASTCALL__ ix86_ExOpCodes(char *str,ix86Param *DisP)
1070 {
1071  unsigned char code,up;
1072  const ix86_ExOpcodes *extable=ix86_extable;
1073  DisP->RealCmd = &DisP->RealCmd[1];
1074  DisP->CodeAddress++;
1075  code = DisP->RealCmd[0];
1076  up = 0;
1077  extable=ix86_prepare_flags(extable,DisP,&code,&up);
1078  if(x86_Bitness == DAB_USE64)
1079     strcpy(str,extable[code].name64?extable[code].name64:"???");
1080  else
1081  strcpy(str,extable[code].name?extable[code].name:"???");
1082  if(x86_Bitness == DAB_USE64)
1083  {
1084    if(extable[code].method64)
1085    {
1086      TabSpace(str,TAB_POS);
1087      extable[code].method64(str,DisP);
1088    }
1089  }
1090  else
1091  if(extable[code].method)
1092  {
1093    TabSpace(str,TAB_POS);
1094    extable[code].method(str,DisP);
1095  }
1096  if(x86_Bitness == DAB_USE64) DisP->pro_clone = extable[code].flags64&K64_CPUMASK;
1097  else
1098  if((DisP->pro_clone&IX86_CPUMASK) < (extable[code].pro_clone&IX86_CPUMASK))
1099  {
1100 	DisP->pro_clone &= ~IX86_CPUMASK;
1101 	DisP->pro_clone |= extable[code].pro_clone;
1102  }
1103  DisP->codelen+=up+1;
1104 }
1105 
ix86_ArgExGr0(char * str,ix86Param * DisP)1106 void  __FASTCALL__ ix86_ArgExGr0(char *str,ix86Param *DisP)
1107 {
1108     unsigned char cop = MODRM_COP(DisP->RealCmd[1]);
1109     unsigned char reg = MODRM_RM(DisP->RealCmd[1]);
1110     unsigned char mod = MODRM_MOD(DisP->RealCmd[1]);
1111     strcpy(str,ix86_ExGrp0[cop]);
1112     TabSpace(str,TAB_POS);
1113     DisP->codelen++;
1114     ix86_setModifier(str,ix86_sizes[WORD_PTR]);
1115     strcat(str,ix86_getModRM(True,mod,reg,DisP));
1116     if((x86_Bitness != DAB_USE64) && (cop < 4)) DisP->pro_clone |= INSN_CPL0;
1117 }
1118 
1119 static char *ix86_vmxname[]={"???","???","???","???","???","???","vmclear","???",};
ix86_VMX(char * str,ix86Param * DisP)1120 void   __FASTCALL__ ix86_VMX(char *str,ix86Param *DisP)
1121 {
1122     unsigned char cop = MODRM_COP(DisP->RealCmd[1]);
1123     unsigned char rm  = MODRM_RM(DisP->RealCmd[1]);
1124     unsigned char mod = MODRM_MOD(DisP->RealCmd[1]);
1125     strcpy(str,ix86_vmxname[cop]);
1126     TabSpace(str,TAB_POS);
1127     DisP->codelen++;
1128     strcat(str,ix86_getModRM(True,mod,rm,DisP));
1129     DisP->pro_clone &= ~IX86_CPUMASK;
1130     DisP->pro_clone |= IX86_P6;
1131 }
1132 
1133 static const char *ix86_0Fvmxname[]={"???","cmpxchg8b","???","???","???","???","vmptrld","vmptrst",};
ix86_0FVMX(char * str,ix86Param * DisP)1134 void   __FASTCALL__ ix86_0FVMX(char *str,ix86Param *DisP)
1135 {
1136     unsigned char rm = MODRM_RM(DisP->RealCmd[1]);
1137     unsigned char cop = MODRM_COP(DisP->RealCmd[1]);
1138     unsigned char mod = MODRM_MOD(DisP->RealCmd[1]);
1139     if(x86_Bitness == DAB_USE64 && REX_W(K64_REX) && cop==1)
1140 	strcpy(str,"cmpxchg16b");
1141     else
1142     strcpy(str,ix86_0Fvmxname[cop]);
1143     TabSpace(str,TAB_POS);
1144     DisP->codelen++;
1145     strcat(str,ix86_getModRM(True,mod,rm,DisP));
1146     if(rm > 1) {
1147 	DisP->pro_clone &= ~IX86_CPUMASK;
1148 	DisP->pro_clone |= IX86_P6;
1149     }
1150 }
1151 
1152 static const char *ix86_660Fvmxname[]={"???","???","???","???","???","???","vmclear","???",};
ix86_660FVMX(char * str,ix86Param * DisP)1153 void   __FASTCALL__ ix86_660FVMX(char *str,ix86Param *DisP)
1154 {
1155     unsigned char rm = MODRM_RM(DisP->RealCmd[1]);
1156     unsigned char cop = MODRM_COP(DisP->RealCmd[1]);
1157     unsigned char mod = MODRM_MOD(DisP->RealCmd[1]);
1158     strcpy(str,ix86_660Fvmxname[cop]);
1159     TabSpace(str,TAB_POS);
1160     DisP->codelen++;
1161     strcat(str,ix86_getModRM(True,mod,rm,DisP));
1162     if(rm > 1) {
1163 	DisP->pro_clone &= ~IX86_CPUMASK;
1164 	DisP->pro_clone |= IX86_P6;
1165     }
1166 }
1167 
1168 static const char * ix86_ExGrp1[] = { "sgdt", "sidt", "lgdt", "lidt", "smsw", "???", "lmsw", "invlpg" };
ix86_ArgExGr1(char * str,ix86Param * DisP)1169 void  __FASTCALL__ ix86_ArgExGr1(char *str,ix86Param *DisP)
1170 {
1171     unsigned char cop = MODRM_COP(DisP->RealCmd[1]);
1172     unsigned char reg = MODRM_RM(DisP->RealCmd[1]);
1173     unsigned char mod = MODRM_MOD(DisP->RealCmd[1]);
1174     unsigned char buf,ptr;
1175     tBool word;
1176     if(x86_Bitness == DAB_USE64)
1177     {
1178       if(DisP->RealCmd[1] == 0xF8)
1179       {
1180 	strcpy(str,"swapgs");
1181 	DisP->codelen++;
1182 	DisP->pro_clone |= INSN_CPL0;
1183 	return;
1184       }
1185     }
1186     {
1187       if(DisP->RealCmd[1] == 0xC1)
1188       {
1189 	strcpy(str,"vmcall");
1190 	DisP->codelen++;
1191 	DisP->pro_clone &= ~IX86_CPUMASK;
1192 	DisP->pro_clone |= IX86_P6;
1193 	return;
1194       }
1195       else
1196       if(DisP->RealCmd[1] == 0xC2)
1197       {
1198 	strcpy(str,"vmlaunch");
1199 	DisP->codelen++;
1200 	DisP->pro_clone &= ~IX86_CPUMASK;
1201 	DisP->pro_clone |= IX86_P6;
1202 	return;
1203       }
1204       else
1205       if(DisP->RealCmd[1] == 0xC3)
1206       {
1207 	strcpy(str,"vmresume");
1208 	DisP->codelen++;
1209 	DisP->pro_clone &= ~IX86_CPUMASK;
1210 	DisP->pro_clone |= IX86_P6;
1211 	return;
1212       }
1213       else
1214       if(DisP->RealCmd[1] == 0xC4)
1215       {
1216 	strcpy(str,"vmxoff");
1217 	DisP->codelen++;
1218 	DisP->pro_clone &= ~IX86_CPUMASK;
1219 	DisP->pro_clone |= IX86_P6;
1220 	return;
1221       }
1222       else
1223       if(DisP->RealCmd[1] == 0xC8)
1224       {
1225 	strcpy(str,"monitor");
1226 	DisP->codelen++;
1227 	DisP->pro_clone &= ~(IX86_CPUMASK|INSN_CPL0);
1228 	DisP->pro_clone |= IX86_P5;
1229 	return;
1230       }
1231       else
1232       if(DisP->RealCmd[1] == 0xC9)
1233       {
1234 	strcpy(str,"mwait");
1235 	DisP->codelen++;
1236 	DisP->pro_clone &= ~(IX86_CPUMASK|INSN_CPL0);
1237 	DisP->pro_clone |= IX86_P5;
1238 	return;
1239       }
1240       else
1241       if(DisP->RealCmd[1] == 0xD0)
1242       {
1243 	strcpy(str,"xgetbv");
1244 	DisP->codelen++;
1245 	DisP->pro_clone &= ~(IX86_CPUMASK|INSN_CPL0);
1246 	DisP->pro_clone |= IX86_P8;
1247 	return;
1248       }
1249       else
1250       if(DisP->RealCmd[1] == 0xD1)
1251       {
1252 	strcpy(str,"xsetbv");
1253 	DisP->codelen++;
1254 	DisP->pro_clone &= ~(IX86_CPUMASK|INSN_CPL0);
1255 	DisP->pro_clone |= IX86_P8;
1256 	return;
1257       }
1258       else
1259       if(DisP->RealCmd[1] == 0xD8)
1260       {
1261 	strcpy(str,"vmrun");
1262 	DisP->codelen++;
1263 	DisP->pro_clone = K64_FAM10|INSN_CPL0;
1264 	TabSpace(str,TAB_POS);
1265 	strcat(str,k64_getREG(DisP,0,True,REX_B(K64_REX),REX_W(K64_REX)));
1266 	return;
1267       }
1268       else
1269       if(DisP->RealCmd[1] == 0xD9)
1270       {
1271 	strcpy(str,"vmmcall");
1272 	DisP->codelen++;
1273 	DisP->pro_clone = K64_FAM10|INSN_CPL0;
1274 	return;
1275       }
1276       else
1277       if(DisP->RealCmd[1] == 0xDA)
1278       {
1279 	strcpy(str,"vmload");
1280 	DisP->codelen++;
1281 	DisP->pro_clone = K64_FAM10|INSN_CPL0;
1282 	TabSpace(str,TAB_POS);
1283 	strcat(str,k64_getREG(DisP,0,True,REX_B(K64_REX),REX_W(K64_REX)));
1284 	return;
1285       }
1286       else
1287       if(DisP->RealCmd[1] == 0xDB)
1288       {
1289 	strcpy(str,"vmsave");
1290 	DisP->codelen++;
1291 	DisP->pro_clone = K64_FAM10|INSN_CPL0;
1292 	TabSpace(str,TAB_POS);
1293 	strcat(str,k64_getREG(DisP,0,True,REX_B(K64_REX),REX_W(K64_REX)));
1294 	return;
1295       }
1296       else
1297       if(DisP->RealCmd[1] == 0xDC)
1298       {
1299 	strcpy(str,"stgi");
1300 	DisP->codelen++;
1301 	DisP->pro_clone = K64_FAM10|INSN_CPL0;
1302 	return;
1303       }
1304       else
1305       if(DisP->RealCmd[1] == 0xDD)
1306       {
1307 	strcpy(str,"clgi");
1308 	DisP->codelen++;
1309 	DisP->pro_clone = K64_FAM10|INSN_CPL0;
1310 	return;
1311       }
1312       else
1313       if(DisP->RealCmd[1] == 0xDE)
1314       {
1315 	strcpy(str,"skinit");
1316 	DisP->codelen++;
1317 	DisP->pro_clone = K64_FAM10|INSN_CPL0;
1318 	TabSpace(str,TAB_POS);
1319 	strcat(str,"eax");
1320 	return;
1321       }
1322       else
1323       if(DisP->RealCmd[1] == 0xDF)
1324       {
1325 	strcpy(str,"invlpga");
1326 	DisP->codelen++;
1327 	DisP->pro_clone = K64_FAM10|INSN_CPL0;
1328 	TabSpace(str,TAB_POS);
1329 	strcat(str,k64_getREG(DisP,0,True,REX_B(K64_REX),REX_W(K64_REX)));
1330 	ix86_CStile(DisP,str,"ecx");
1331 	return;
1332       }
1333     }
1334     strcpy(str,ix86_ExGrp1[cop]);
1335     TabSpace(str,TAB_POS);
1336     DisP->codelen++;
1337     buf = DisP->RealCmd[1];
1338     ptr = PWORD_PTR;
1339     word = True;
1340     if(cop == 7)
1341     {
1342 	word = False;
1343 	if(x86_Bitness != DAB_USE64) DisP->pro_clone = IX86_CPU486;
1344 	buf = 1;
1345 	ptr = DUMMY_PTR;
1346     }
1347     else  if(cop == 4 || cop == 6) ptr = WORD_PTR;
1348     ix86_setModifier(str,ix86_sizes[ptr]);
1349     strcat(str,ix86_getModRM(word ? True : buf & 0x01,mod,reg,DisP));
1350 }
1351 
1352 static const char ** k64_xry[] = { k64_CrxRegs, k64_DrxRegs, k64_TrxRegs, k64_XrxRegs };
1353 
ix86_ArgMovXRY(char * str,ix86Param * DisP)1354 void  __FASTCALL__ ix86_ArgMovXRY(char *str,ix86Param *DisP)
1355 {
1356     unsigned char code = DisP->RealCmd[0];
1357     unsigned char xreg = MODRM_REG(DisP->RealCmd[1]);
1358     unsigned char reg = MODRM_RM(DisP->RealCmd[1]);
1359     unsigned char ridx = (code & 0x01) + ((code >> 1) & 0x02);
1360     unsigned char d = (code >> 1) & 0x01;
1361     unsigned long mode = DisP->mode;
1362     tBool brex,wrex;
1363     brex = REX_B(K64_REX);
1364     wrex = REX_W(K64_REX);
1365     if(x86_Bitness == DAB_USE64) wrex = 1;
1366     DisP->codelen++;
1367     DisP->mode|=MOD_WIDE_DATA;
1368     /* according on intel 30083401.pdf p# 1.4.3 to access cr8-tr15 is used REX.r */
1369     strcat(str,d ? k64_xry[ridx][xreg|(REX_R(K64_REX)<<3)] : k64_getREG(DisP,reg,True,brex,wrex));
1370     ix86_CStile(DisP,str,d ? k64_getREG(DisP,reg,True,brex,wrex) : k64_xry[ridx][xreg|(REX_R(K64_REX)<<3)]);
1371     DisP->mode=mode;
1372 }
1373 
1374 /* MMX and SSE(2) opcodes */
1375 
ix86_bridge_cpu_simd(char * str,ix86Param * DisP,tBool direct,tBool as_xmmx)1376 static void __NEAR__ __FASTCALL__ ix86_bridge_cpu_simd(char *str,ix86Param *DisP,tBool direct,tBool as_xmmx)
1377 {
1378    unsigned long mode=DisP->mode;
1379    if(as_xmmx) DisP->mode|=MOD_SSE;
1380    else        DisP->mode|=MOD_MMX;
1381    if((DisP->RealCmd[1] & 0xC0) != 0xC0) {
1382 	if(direct) DisP->mode=mode;
1383 	arg_cpu_modregrm(str,DisP);
1384    }
1385    else
1386    {
1387       const char *mmx,*exx,*vxx=NULL;
1388       tBool brex,wrex;
1389       brex = direct?REX_B(K64_REX):REX_R(K64_REX);
1390       wrex = REX_W(K64_REX);
1391       if(brex && !as_xmmx) brex = 0; /* Note: there are only 8 mmx registers */
1392       mmx = k64_getREG(DisP,direct?MODRM_RM(DisP->RealCmd[1]):MODRM_REG(DisP->RealCmd[1]),True,brex,wrex);
1393       if(DisP->pfx&PFX_VEX) vxx = get_VEX_reg(DisP);
1394       else {
1395 	if(as_xmmx) DisP->mode&=~MOD_SSE;
1396 	else        DisP->mode&=~MOD_MMX;
1397       }
1398       brex = direct?REX_R(K64_REX):REX_B(K64_REX);
1399       exx = k64_getREG(DisP,direct?MODRM_REG(DisP->RealCmd[1]):MODRM_RM(DisP->RealCmd[1]),True,brex,wrex);
1400       strcat(str,direct ? exx : mmx);
1401       if(vxx) ix86_CStile(DisP,str, vxx);
1402       ix86_CStile(DisP,str,direct ? mmx : exx);
1403       DisP->codelen++;
1404    }
1405    DisP->mode=mode;
1406 }
1407 
bridge_simd_cpu(char * str,ix86Param * DisP)1408 void   __FASTCALL__ bridge_simd_cpu(char *str,ix86Param* DisP)
1409 {
1410     ix86_bridge_cpu_simd(str,DisP,(DisP->insn_flags&BRIDGE_CPU_SSE)?True:False,(DisP->insn_flags&INSN_SSE)?True:False);
1411 }
1412 
bridge_simd_cpu_imm8(char * str,ix86Param * DisP)1413 void __FASTCALL__  bridge_simd_cpu_imm8(char *str,ix86Param *DisP)
1414 {
1415     bridge_simd_cpu(str,DisP);
1416     if(!((DisP->flags & __DISF_SIZEONLY) == __DISF_SIZEONLY)) strcat(str,",");
1417     arg_imm8(str,DisP);
1418 }
1419 
ix86_bridge_sse_mmx(char * str,ix86Param * DisP,tBool xmmx_first)1420 static void __NEAR__ __FASTCALL__ ix86_bridge_sse_mmx(char *str,ix86Param *DisP,tBool xmmx_first)
1421 {
1422    unsigned long mode=DisP->mode;
1423    if(xmmx_first) DisP->mode|=MOD_SSE;
1424    else           DisP->mode|=MOD_MMX;
1425    if((DisP->RealCmd[1] & 0xC0) != 0xC0)
1426 			arg_cpu_modregrm(str,DisP);
1427    else
1428    {
1429       const char *mmx,*exx;
1430       tBool brex,wrex;
1431       brex = REX_R(K64_REX);
1432       wrex = REX_W(K64_REX);
1433       if(brex && !xmmx_first) brex = 0; /* Note: there are only 8 mmx registers */
1434       mmx = k64_getREG(DisP,MODRM_REG(DisP->RealCmd[1]),True,brex,wrex);
1435       if(xmmx_first)
1436       {
1437         DisP->mode&=~MOD_SSE;
1438         DisP->mode|=MOD_MMX;
1439       }
1440       else
1441       {
1442         DisP->mode|=MOD_SSE;
1443         DisP->mode&=~MOD_MMX;
1444       }
1445       brex = REX_B(K64_REX);
1446       exx = k64_getREG(DisP,MODRM_RM(DisP->RealCmd[1]),True,brex,wrex);
1447       strcat(str,mmx);
1448       ix86_CStile(DisP,str,exx);
1449       DisP->codelen++;
1450    }
1451    DisP->mode=mode;
1452 }
1453 
bridge_sse_mmx(char * str,ix86Param * DisP)1454 void __FASTCALL__ bridge_sse_mmx(char *str,ix86Param* DisP)
1455 {
1456    ix86_bridge_sse_mmx(str,DisP,(DisP->insn_flags&BRIDGE_MMX_SSE)?False:True);
1457 }
1458 
arg_emms(char * str,ix86Param * DisP)1459 void __FASTCALL__ arg_emms(char *str,ix86Param *DisP)
1460 {
1461     if(DisP->pfx&PFX_VEX) {
1462 	if(DisP->VEX_vlp&0x04)	strcpy(str,"vzeroall");
1463 	else			strcpy(str,"vzeroupper");
1464     }
1465 }
1466 
arg_simd(char * str,ix86Param * DisP)1467 void __FASTCALL__ arg_simd(char *str,ix86Param *DisP)
1468 {
1469     unsigned long mode=DisP->mode;
1470     if(DisP->insn_flags&INSN_MMX)	DisP->mode|=MOD_MMX;
1471     else				DisP->mode|=MOD_SSE;
1472     arg_cpu_modregrm(str,DisP);
1473     DisP->mode=mode;
1474 }
1475 
ix86_ArgxMMXGroup(char * str,const char * name,ix86Param * DisP,tBool as_xmmx)1476 static void __NEAR__ __FASTCALL__ ix86_ArgxMMXGroup(char *str,const char *name,ix86Param *DisP,tBool as_xmmx)
1477 {
1478   unsigned long mode=DisP->mode;
1479   tBool brex,wrex;
1480   brex = REX_B(K64_REX);
1481   wrex = REX_W(K64_REX);
1482   if(brex && !as_xmmx) brex = 0; /* Note: there are only 8 mmx registers */
1483   DisP->codelen++;
1484   strcpy(str,name);
1485   TabSpace(str,TAB_POS);
1486   if(as_xmmx) DisP->mode|=MOD_SSE;
1487   else        DisP->mode|=MOD_MMX;
1488   strcat(str,k64_getREG(DisP,MODRM_RM(DisP->RealCmd[1]),True,brex,wrex));
1489   if(as_xmmx) DisP->mode&=~MOD_SSE;
1490   else        DisP->mode&=~MOD_MMX;
1491   ix86_CStile(DisP,str,Get2Digit(DisP->RealCmd[2]));
1492   DisP->codelen++;
1493   DisP->mode=mode;
1494 }
1495 
ix86_ArgMMXGr1(char * str,ix86Param * DisP)1496 void __FASTCALL__ ix86_ArgMMXGr1(char *str,ix86Param *DisP)
1497 {
1498   ix86_ArgxMMXGroup(str,ix86_MMXGr1[MODRM_COP(DisP->RealCmd[1])],DisP,False);
1499 }
1500 
ix86_ArgMMXGr2(char * str,ix86Param * DisP)1501 void __FASTCALL__ ix86_ArgMMXGr2(char *str,ix86Param *DisP)
1502 {
1503   ix86_ArgxMMXGroup(str,ix86_MMXGr2[MODRM_COP(DisP->RealCmd[1])],DisP,False);
1504 }
1505 
ix86_ArgMMXGr3(char * str,ix86Param * DisP)1506 void __FASTCALL__ ix86_ArgMMXGr3(char *str,ix86Param *DisP)
1507 {
1508   ix86_ArgxMMXGroup(str,ix86_MMXGr3[MODRM_COP(DisP->RealCmd[1])],DisP,False);
1509 }
1510 
ix86_ArgXMMXGr1(char * str,ix86Param * DisP)1511 void __FASTCALL__ ix86_ArgXMMXGr1(char *str,ix86Param *DisP)
1512 {
1513   ix86_ArgxMMXGroup(str,ix86_XMMXGr1[MODRM_COP(DisP->RealCmd[1])],DisP,True);
1514 }
1515 
ix86_ArgXMMXGr2(char * str,ix86Param * DisP)1516 void __FASTCALL__ ix86_ArgXMMXGr2(char *str,ix86Param *DisP)
1517 {
1518   ix86_ArgxMMXGroup(str,ix86_XMMXGr2[MODRM_COP(DisP->RealCmd[1])],DisP,True);
1519 }
1520 
ix86_ArgXMMXGr3(char * str,ix86Param * DisP)1521 void __FASTCALL__ ix86_ArgXMMXGr3(char *str,ix86Param *DisP)
1522 {
1523   ix86_ArgxMMXGroup(str,ix86_XMMXGr3[MODRM_COP(DisP->RealCmd[1])],DisP,True);
1524 }
1525 
ix86_ArgMovYX(char * str,ix86Param * DisP)1526 void __FASTCALL__ ix86_ArgMovYX(char *str,ix86Param *DisP)
1527 {
1528       const char *dst,*src;
1529       unsigned char mod;
1530       unsigned long mode=DisP->mode;
1531       tBool brex,wrex;
1532       brex = REX_R(K64_REX);
1533       wrex = REX_W(K64_REX);
1534       mod = MODRM_MOD(DisP->RealCmd[1]);
1535       /*ix86_setModifier(str,ix86_sizes[ix86_calcModifier(DisP,1)]);*/
1536       dst = k64_getREG(DisP,MODRM_REG(DisP->RealCmd[1]),True,brex,wrex);
1537       DisP->mode&=~MOD_WIDE_DATA;
1538       src = ix86_getModRM(DisP->RealCmd[0] & 0x01,mod,MODRM_RM(DisP->RealCmd[1]),DisP);
1539       DisP->mode=mode;
1540       strcat(str,dst);
1541       ix86_CStile(DisP,str,src);
1542       DisP->codelen++;
1543 }
1544 
ix86_BitGrp(char * str,ix86Param * DisP)1545 void __FASTCALL__ ix86_BitGrp(char *str,ix86Param *DisP)
1546 {
1547    unsigned char cop = MODRM_COP(DisP->RealCmd[1]);
1548    char mod = MODRM_MOD(DisP->RealCmd[1]);
1549    char rm = MODRM_RM(DisP->RealCmd[1]);
1550    strcpy(str,ix86_BitGrpNames[cop]);
1551    TabSpace(str,TAB_POS);
1552    strcat(str,ix86_getModRM(True,mod,rm,DisP));
1553    ix86_CStile(DisP,str,ix86_GetDigitTile(DisP,0,0,++DisP->codelen));
1554 }
1555 
1556 static const char *ix86_KatmaiGr1Names[] = { "fxsave", "fxrstor", "ldmxcsr", "stmxcsr", "xsave", "xrstor", "???", "???" };
1557 static const char *ix86_KatmaiGr1Names11[] = { "???", "???", "???", "???", "???", "lfence", "mfence", "sfence" };
ix86_ArgKatmaiGrp1(char * str,ix86Param * DisP)1558 void __FASTCALL__ ix86_ArgKatmaiGrp1(char *str,ix86Param *DisP)
1559 {
1560    unsigned char cop = MODRM_COP(DisP->RealCmd[1]);
1561    unsigned char mod = MODRM_MOD(DisP->RealCmd[1]);
1562    if(mod==3)	strcpy(str,ix86_KatmaiGr1Names11[cop]);
1563    else		strcpy(str,ix86_KatmaiGr1Names[cop]);
1564    if(mod < 3)
1565    {
1566      TabSpace(str,TAB_POS);
1567      arg_cpu_mod_rm(str,DisP);
1568 	if(x86_Bitness != DAB_USE64) {
1569 	    DisP->pro_clone &= ~IX86_CPUMASK;
1570 	    DisP->pro_clone |= IX86_P8|INSN_SSE;
1571 	}
1572 	else {
1573 	    DisP->pro_clone &= ~K64_CPUMASK;
1574 	    DisP->pro_clone |= K64_FAM11|INSN_SSE;
1575 	}
1576    }
1577    else DisP->codelen++;
1578    if((cop==5 || cop==6) && mod==3)
1579 	if(x86_Bitness != DAB_USE64) {
1580 	    DisP->pro_clone &= ~IX86_CPUMASK;
1581 	    DisP->pro_clone |= IX86_P4|INSN_MMX;
1582 	}
1583 }
1584 
ix86_ArgKatmaiGrp2(char * str,ix86Param * DisP)1585 void __FASTCALL__ ix86_ArgKatmaiGrp2(char *str,ix86Param *DisP)
1586 {
1587    unsigned char cop = MODRM_COP(DisP->RealCmd[1]);
1588    strcpy(str,ix86_KatmaiGr2Names[cop]);
1589    TabSpace(str,TAB_POS);
1590    arg_cpu_mod_rm(str,DisP);
1591 }
1592 
arg_simd_imm8(char * str,ix86Param * DisP)1593 void __FASTCALL__  arg_simd_imm8(char *str,ix86Param *DisP)
1594 {
1595     arg_simd(str,DisP);
1596     if(!((DisP->flags & __DISF_SIZEONLY) == __DISF_SIZEONLY)) strcat(str,",");
1597     arg_imm8(str,DisP);
1598 }
1599 
arg_simd_regrm(char * str,ix86Param * DisP)1600 void __FASTCALL__ arg_simd_regrm(char *str,ix86Param *DisP)
1601 {
1602   tBool brex,wrex;
1603   unsigned long mode=DisP->mode;
1604   DisP->codelen++;
1605   brex = REX_B(K64_REX);
1606   wrex = REX_W(K64_REX);
1607   DisP->mode|=MOD_SSE;
1608   strcat(str,k64_getREG(DisP,MODRM_REG(DisP->RealCmd[1]),True,brex,wrex));
1609   ix86_CStile(DisP,str,k64_getREG(DisP,MODRM_RM(DisP->RealCmd[1]),True,brex,wrex));
1610   DisP->mode=mode;
1611 }
1612 
arg_simd_regrm_imm8_imm8(char * str,ix86Param * DisP)1613 void __FASTCALL__ arg_simd_regrm_imm8_imm8(char *str,ix86Param *DisP)
1614 {
1615   arg_simd_regrm(str,DisP);
1616   if(!((DisP->flags & __DISF_SIZEONLY) == __DISF_SIZEONLY)) strcat(str,",");
1617   arg_imm8(str,DisP);
1618   if(!((DisP->flags & __DISF_SIZEONLY) == __DISF_SIZEONLY)) strcat(str,",");
1619   arg_imm8(str,DisP);
1620 }
1621 
arg_simd_rm_imm8_imm8(char * str,ix86Param * DisP)1622 void __FASTCALL__ arg_simd_rm_imm8_imm8(char *str,ix86Param *DisP)
1623 {
1624   tBool brex,wrex;
1625   unsigned long mode=DisP->mode;
1626   brex = REX_B(K64_REX);
1627   wrex = REX_W(K64_REX);
1628   DisP->mode|=MOD_SSE;
1629   strcat(str,k64_getREG(DisP,MODRM_RM(DisP->RealCmd[1]),True,brex,wrex));
1630   DisP->mode=mode;
1631   DisP->codelen++;
1632 
1633   if(!((DisP->flags & __DISF_SIZEONLY) == __DISF_SIZEONLY)) strcat(str,",");
1634   arg_imm8(str,DisP);
1635   if(!((DisP->flags & __DISF_SIZEONLY) == __DISF_SIZEONLY)) strcat(str,",");
1636   arg_imm8(str,DisP);
1637 }
1638 
ix86_ArgXMMCmp(char * str,ix86Param * DisP,const char ** sfx,unsigned nsfx,unsigned namlen,unsigned precopy)1639 static void __FASTCALL__  ix86_ArgXMMCmp(char *str,ix86Param *DisP,const char **sfx,unsigned nsfx,unsigned namlen,unsigned precopy)
1640 {
1641    char *a;
1642    unsigned char suffix;
1643    char name[6], realname[10];
1644    unsigned long mode=DisP->mode;
1645    DisP->mode|=MOD_SSE;
1646    ix86_Katmai_buff[0] = 0;
1647    arg_cpu_modregrm(ix86_Katmai_buff,DisP);
1648    suffix = DisP->RealCmd[DisP->codelen];
1649    a = NULL;
1650    if(suffix < nsfx)
1651    {
1652 	strncpy(name, str, namlen);
1653 	name[namlen] = 0;
1654 	strncpy(realname,name,precopy);
1655 	realname[precopy] = 0;
1656 	strcat(realname,sfx[suffix]);
1657 	strcat(realname, &name[precopy]);
1658 	strcpy(str, realname);
1659 	TabSpace(str, TAB_POS);
1660    }
1661    else {
1662 	a = Get2Digit(suffix);
1663    }
1664    strcat(str,ix86_Katmai_buff);
1665    if(a) ix86_CStile(DisP,str,a);
1666    DisP->mode = mode;
1667    DisP->codelen++;
1668 }
1669 
1670 static const char *ix86_KatmaiCmpSuffixes[] = { "eq", "lt", "le", "unord", "neq", "nlt", "nle", "ord" };
1671 static const char *vex_cmp_sfx[] = {
1672 "eq", "lt", "le", "unord", "neq", "nlt", "nle", "ord", "eq_uq", "nge", "ngt", "false", "neq_oq", "ge", "gt",
1673 "true", "eq_os", "lt_oq", "le_oq", "unord_s", "neq_us", "nlt_uq", "nle_uq", "ord_s", "eq_us" };
arg_simd_cmp(char * str,ix86Param * DisP)1674 void __FASTCALL__  arg_simd_cmp(char *str,ix86Param *DisP)
1675 {
1676     /*Note: this code suppose that name is cmpXY*/
1677     return (str[0]=='v' && (DisP->pfx&PFX_VEX))?
1678 		ix86_ArgXMMCmp(str,DisP,vex_cmp_sfx,0x19,6,4):
1679 		ix86_ArgXMMCmp(str,DisP,ix86_KatmaiCmpSuffixes,8,5,3);
1680 }
1681 
1682 
1683 static const char *xop_cmp_sfx[] = { "lt", "le", "gt", "ge", "eq", "ne", "false", "true" };
arg_xop_cmp(char * str,ix86Param * DisP)1684 void __FASTCALL__  arg_xop_cmp(char *str,ix86Param *DisP)
1685 {
1686     /*Note: this code suppose that name is vpcomXY?? */
1687     return ix86_ArgXMMCmp(str,DisP,xop_cmp_sfx,8,7,5);
1688 }
1689 
1690 static const char *ix86_clmul_sfx[] = { "lqlq", "hqlq", "lqh", "hqh" };
arg_simd_clmul(char * str,ix86Param * DisP)1691 void __FASTCALL__  arg_simd_clmul(char *str,ix86Param *DisP)
1692 {
1693    char *a;
1694    unsigned char suffix;
1695    char name[6], realname[10];
1696    unsigned long mode=DisP->mode;
1697    unsigned namlen,precopy;
1698    DisP->mode|=MOD_SSE;
1699    ix86_Katmai_buff[0] = 0;
1700    arg_cpu_modregrm(ix86_Katmai_buff,DisP);
1701    suffix = DisP->RealCmd[DisP->codelen];
1702    suffix = (suffix&0x0F)|((suffix&0xF0)>>3);
1703    namlen=8;
1704    precopy=6;
1705    if(str[0]=='v' && (DisP->pfx&PFX_VEX)) { namlen++; precopy++; }
1706    a = NULL;
1707    if(suffix < 4)
1708    {
1709 	strncpy(name, str, namlen);
1710 	name[namlen] = 0;
1711 	strncpy(realname,name,precopy);
1712 	realname[precopy] = 0;
1713 	strcat(realname,ix86_clmul_sfx[suffix]);
1714 	strcat(realname, &name[precopy]);
1715 	strcpy(str, realname);
1716 	TabSpace(str, TAB_POS);
1717    }
1718    else {
1719 	a = Get2Digit(suffix);
1720    }
1721    strcat(str,ix86_Katmai_buff);
1722    if(a) ix86_CStile(DisP,str,a);
1723    DisP->mode = mode;
1724    DisP->codelen++;
1725 }
1726 
arg_simd_xmm0(char * str,ix86Param * DisP)1727 void   __FASTCALL__ arg_simd_xmm0(char *str,ix86Param *DisP) {
1728    arg_simd(str,DisP);
1729    ix86_CStile(DisP,str,"xmm0");
1730 }
1731 
1732 /* TODO: fix it !!! */
arg_fma4(char * str,ix86Param * DisP)1733 void   __FASTCALL__ arg_fma4(char *str,ix86Param *DisP) {
1734     unsigned wrex;
1735     unsigned long mod = DisP->mode;
1736     unsigned char d;
1737     DisP->mode |= MOD_SSE;
1738     d = 0;
1739     if(DisP->insn_flags&INSN_VEXW_AS_SWAP && DisP->pfx&PFX_VEX) d = REX_W(K64_REX)^0x01;
1740     wrex=0;
1741     strcat(str,__buildModRegRmReg(DisP,d,wrex));
1742     DisP->mode = mod;
1743 }
1744 
arg_fma4_imm8(char * str,ix86Param * DisP)1745 void   __FASTCALL__ arg_fma4_imm8(char *str,ix86Param *DisP) {
1746     unsigned is4;
1747     arg_fma4(str,DisP);
1748     is4=DisP->RealCmd[DisP->codelen-1];
1749     ix86_CStile(DisP,str,Get2Digit(is4&0x0F));
1750 }
1751 
arg_fma(char * str,ix86Param * DisP)1752 void __FASTCALL__ arg_fma(char *str,ix86Param *DisP)
1753 {
1754     unsigned long mode=DisP->mode;
1755     if(DisP->insn_flags&INSN_MMX)	DisP->mode|=MOD_MMX;
1756     else				DisP->mode|=MOD_SSE;
1757     if(DisP->pfx&PFX_VEX) {
1758 	char *ptr;
1759 	char vex_w = REX_W(DisP->REX)^1; /* complement it back */
1760 	if(!vex_w) {
1761 	    ptr=strstr(str,"pd ");
1762 	    if(!ptr) ptr=strstr(str,"sd ");
1763 	    if(ptr) ptr[1] = 's';
1764 	}
1765     }
1766     arg_cpu_modregrm(str,DisP);
1767     DisP->mode=mode;
1768 }
1769 
ix86_3dNowOpCodes(char * str,ix86Param * DisP)1770 void __FASTCALL__ ix86_3dNowOpCodes( char *str,ix86Param *DisP)
1771 {
1772  unsigned char code;
1773  unsigned long mode=DisP->mode;
1774  DisP->mode|=MOD_MMX;
1775  ix86_Katmai_buff[0] = 0;
1776  arg_cpu_modregrm(ix86_Katmai_buff,DisP);
1777  DisP->mode=mode;
1778  code = DisP->RealCmd[DisP->codelen];
1779  DisP->codelen++;
1780  strcpy(str,ix86_3dNowtable[code].name);
1781  TabSpace(str,TAB_POS);
1782  strcat(str,ix86_Katmai_buff);
1783  if(x86_Bitness == DAB_USE64) DisP->pro_clone = K64_ATHLON|INSN_MMX;
1784  else DisP->pro_clone = ix86_3dNowtable[code].pro_clone;
1785 }
1786 
ix86_3dNowPrefetchGrp(char * str,ix86Param * DisP)1787 void __FASTCALL__ ix86_3dNowPrefetchGrp(char *str,ix86Param *DisP)
1788 {
1789    unsigned char cop = MODRM_COP(DisP->RealCmd[1]);
1790    strcpy(str,ix86_3dPrefetchGrp[cop]);
1791    TabSpace(str,TAB_POS);
1792    arg_cpu_mod_rm(str,DisP);
1793 }
1794 
1795