1 
2 /*---------------------------------------------------------------*/
3 /*--- begin                                 host_amd64_defs.h ---*/
4 /*---------------------------------------------------------------*/
5 
6 /*
7    This file is part of Valgrind, a dynamic binary instrumentation
8    framework.
9 
10    Copyright (C) 2004-2017 OpenWorks LLP
11       info@open-works.net
12 
13    This program is free software; you can redistribute it and/or
14    modify it under the terms of the GNU General Public License as
15    published by the Free Software Foundation; either version 2 of the
16    License, or (at your option) any later version.
17 
18    This program is distributed in the hope that it will be useful, but
19    WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21    General Public License for more details.
22 
23    You should have received a copy of the GNU General Public License
24    along with this program; if not, write to the Free Software
25    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26    02110-1301, USA.
27 
28    The GNU General Public License is contained in the file COPYING.
29 
30    Neither the names of the U.S. Department of Energy nor the
31    University of California nor the names of its contributors may be
32    used to endorse or promote products derived from this software
33    without prior written permission.
34 */
35 
36 #ifndef __VEX_HOST_AMD64_DEFS_H
37 #define __VEX_HOST_AMD64_DEFS_H
38 
39 #include "libvex_basictypes.h"
40 #include "libvex.h"                      // VexArch
41 #include "host_generic_regs.h"           // HReg
42 
43 /* --------- Registers. --------- */
44 
45 /* The usual HReg abstraction.  There are 16 real int regs, 6 real
46    float regs, and 16 real vector regs.
47 */
48 
49 #define ST_IN static inline
hregAMD64_R12(void)50 ST_IN HReg hregAMD64_R12   ( void ) { return mkHReg(False, HRcInt64,  12,  0); }
hregAMD64_R13(void)51 ST_IN HReg hregAMD64_R13   ( void ) { return mkHReg(False, HRcInt64,  13,  1); }
hregAMD64_R14(void)52 ST_IN HReg hregAMD64_R14   ( void ) { return mkHReg(False, HRcInt64,  14,  2); }
hregAMD64_R15(void)53 ST_IN HReg hregAMD64_R15   ( void ) { return mkHReg(False, HRcInt64,  15,  3); }
hregAMD64_RBX(void)54 ST_IN HReg hregAMD64_RBX   ( void ) { return mkHReg(False, HRcInt64,   3,  4); }
hregAMD64_RSI(void)55 ST_IN HReg hregAMD64_RSI   ( void ) { return mkHReg(False, HRcInt64,   6,  5); }
hregAMD64_RDI(void)56 ST_IN HReg hregAMD64_RDI   ( void ) { return mkHReg(False, HRcInt64,   7,  6); }
hregAMD64_R8(void)57 ST_IN HReg hregAMD64_R8    ( void ) { return mkHReg(False, HRcInt64,   8,  7); }
hregAMD64_R9(void)58 ST_IN HReg hregAMD64_R9    ( void ) { return mkHReg(False, HRcInt64,   9,  8); }
hregAMD64_R10(void)59 ST_IN HReg hregAMD64_R10   ( void ) { return mkHReg(False, HRcInt64,  10,  9); }
60 
hregAMD64_XMM3(void)61 ST_IN HReg hregAMD64_XMM3  ( void ) { return mkHReg(False, HRcVec128,  3, 10); }
hregAMD64_XMM4(void)62 ST_IN HReg hregAMD64_XMM4  ( void ) { return mkHReg(False, HRcVec128,  4, 11); }
hregAMD64_XMM5(void)63 ST_IN HReg hregAMD64_XMM5  ( void ) { return mkHReg(False, HRcVec128,  5, 12); }
hregAMD64_XMM6(void)64 ST_IN HReg hregAMD64_XMM6  ( void ) { return mkHReg(False, HRcVec128,  6, 13); }
hregAMD64_XMM7(void)65 ST_IN HReg hregAMD64_XMM7  ( void ) { return mkHReg(False, HRcVec128,  7, 14); }
hregAMD64_XMM8(void)66 ST_IN HReg hregAMD64_XMM8  ( void ) { return mkHReg(False, HRcVec128,  8, 15); }
hregAMD64_XMM9(void)67 ST_IN HReg hregAMD64_XMM9  ( void ) { return mkHReg(False, HRcVec128,  9, 16); }
hregAMD64_XMM10(void)68 ST_IN HReg hregAMD64_XMM10 ( void ) { return mkHReg(False, HRcVec128, 10, 17); }
hregAMD64_XMM11(void)69 ST_IN HReg hregAMD64_XMM11 ( void ) { return mkHReg(False, HRcVec128, 11, 18); }
hregAMD64_XMM12(void)70 ST_IN HReg hregAMD64_XMM12 ( void ) { return mkHReg(False, HRcVec128, 12, 19); }
71 
hregAMD64_RAX(void)72 ST_IN HReg hregAMD64_RAX   ( void ) { return mkHReg(False, HRcInt64,   0, 20); }
hregAMD64_RCX(void)73 ST_IN HReg hregAMD64_RCX   ( void ) { return mkHReg(False, HRcInt64,   1, 21); }
hregAMD64_RDX(void)74 ST_IN HReg hregAMD64_RDX   ( void ) { return mkHReg(False, HRcInt64,   2, 22); }
hregAMD64_RSP(void)75 ST_IN HReg hregAMD64_RSP   ( void ) { return mkHReg(False, HRcInt64,   4, 23); }
hregAMD64_RBP(void)76 ST_IN HReg hregAMD64_RBP   ( void ) { return mkHReg(False, HRcInt64,   5, 24); }
hregAMD64_R11(void)77 ST_IN HReg hregAMD64_R11   ( void ) { return mkHReg(False, HRcInt64,  11, 25); }
78 
hregAMD64_XMM0(void)79 ST_IN HReg hregAMD64_XMM0  ( void ) { return mkHReg(False, HRcVec128,  0, 26); }
hregAMD64_XMM1(void)80 ST_IN HReg hregAMD64_XMM1  ( void ) { return mkHReg(False, HRcVec128,  1, 27); }
81 #undef ST_IN
82 
83 extern UInt ppHRegAMD64 ( HReg );
84 
85 
86 /* --------- Condition codes, AMD encoding. --------- */
87 
88 typedef
89    enum {
90       Acc_O      = 0,  /* overflow           */
91       Acc_NO     = 1,  /* no overflow        */
92 
93       Acc_B      = 2,  /* below              */
94       Acc_NB     = 3,  /* not below          */
95 
96       Acc_Z      = 4,  /* zero               */
97       Acc_NZ     = 5,  /* not zero           */
98 
99       Acc_BE     = 6,  /* below or equal     */
100       Acc_NBE    = 7,  /* not below or equal */
101 
102       Acc_S      = 8,  /* negative           */
103       Acc_NS     = 9,  /* not negative       */
104 
105       Acc_P      = 10, /* parity even        */
106       Acc_NP     = 11, /* not parity even    */
107 
108       Acc_L      = 12, /* jump less          */
109       Acc_NL     = 13, /* not less           */
110 
111       Acc_LE     = 14, /* less or equal      */
112       Acc_NLE    = 15, /* not less or equal  */
113 
114       Acc_ALWAYS = 16  /* the usual hack     */
115    }
116    AMD64CondCode;
117 
118 extern const HChar* showAMD64CondCode ( AMD64CondCode );
119 
120 
121 /* --------- Memory address expressions (amodes). --------- */
122 
123 typedef
124    enum {
125      Aam_IR,        /* Immediate + Reg */
126      Aam_IRRS       /* Immediate + Reg1 + (Reg2 << Shift) */
127    }
128    AMD64AModeTag;
129 
130 typedef
131    struct {
132       AMD64AModeTag tag;
133       union {
134          struct {
135             UInt imm;
136             HReg reg;
137          } IR;
138          struct {
139             UInt imm;
140             HReg base;
141             HReg index;
142             Int  shift; /* 0, 1, 2 or 3 only */
143          } IRRS;
144       } Aam;
145    }
146    AMD64AMode;
147 
148 extern AMD64AMode* AMD64AMode_IR   ( UInt, HReg );
149 extern AMD64AMode* AMD64AMode_IRRS ( UInt, HReg, HReg, Int );
150 
151 extern AMD64AMode* dopyAMD64AMode ( AMD64AMode* );
152 
153 extern void ppAMD64AMode ( AMD64AMode* );
154 
155 
156 /* --------- Operand, which can be reg, immediate or memory. --------- */
157 
158 typedef
159    enum {
160       Armi_Imm,
161       Armi_Reg,
162       Armi_Mem
163    }
164    AMD64RMITag;
165 
166 typedef
167    struct {
168       AMD64RMITag tag;
169       union {
170          struct {
171             UInt imm32;
172          } Imm;
173          struct {
174             HReg reg;
175          } Reg;
176          struct {
177             AMD64AMode* am;
178          } Mem;
179       }
180       Armi;
181    }
182    AMD64RMI;
183 
184 extern AMD64RMI* AMD64RMI_Imm ( UInt );
185 extern AMD64RMI* AMD64RMI_Reg ( HReg );
186 extern AMD64RMI* AMD64RMI_Mem ( AMD64AMode* );
187 
188 extern void ppAMD64RMI      ( AMD64RMI* );
189 extern void ppAMD64RMI_lo32 ( AMD64RMI* );
190 
191 
192 /* --------- Operand, which can be reg or immediate only. --------- */
193 
194 typedef
195    enum {
196       Ari_Imm,
197       Ari_Reg
198    }
199    AMD64RITag;
200 
201 typedef
202    struct {
203       AMD64RITag tag;
204       union {
205          struct {
206             UInt imm32;
207          } Imm;
208          struct {
209             HReg reg;
210          } Reg;
211       }
212       Ari;
213    }
214    AMD64RI;
215 
216 extern AMD64RI* AMD64RI_Imm ( UInt );
217 extern AMD64RI* AMD64RI_Reg ( HReg );
218 
219 extern void ppAMD64RI ( AMD64RI* );
220 
221 
222 /* --------- Operand, which can be reg or memory only. --------- */
223 
224 typedef
225    enum {
226       Arm_Reg,
227       Arm_Mem
228    }
229    AMD64RMTag;
230 
231 typedef
232    struct {
233       AMD64RMTag tag;
234       union {
235          struct {
236             HReg reg;
237          } Reg;
238          struct {
239             AMD64AMode* am;
240          } Mem;
241       }
242       Arm;
243    }
244    AMD64RM;
245 
246 extern AMD64RM* AMD64RM_Reg ( HReg );
247 extern AMD64RM* AMD64RM_Mem ( AMD64AMode* );
248 
249 extern void ppAMD64RM ( AMD64RM* );
250 
251 
252 /* --------- Instructions. --------- */
253 
254 /* --------- */
255 typedef
256    enum {
257       Aun_NEG,
258       Aun_NOT
259    }
260    AMD64UnaryOp;
261 
262 extern const HChar* showAMD64UnaryOp ( AMD64UnaryOp );
263 
264 
265 /* --------- */
266 typedef
267    enum {
268       Aalu_INVALID,
269       Aalu_MOV,
270       Aalu_CMP,
271       Aalu_ADD, Aalu_SUB, Aalu_ADC, Aalu_SBB,
272       Aalu_AND, Aalu_OR, Aalu_XOR,
273       Aalu_MUL
274    }
275    AMD64AluOp;
276 
277 extern const HChar* showAMD64AluOp ( AMD64AluOp );
278 
279 
280 /* --------- */
281 typedef
282    enum {
283       Ash_INVALID,
284       Ash_SHL, Ash_SHR, Ash_SAR
285    }
286    AMD64ShiftOp;
287 
288 extern const HChar* showAMD64ShiftOp ( AMD64ShiftOp );
289 
290 
291 /* --------- */
292 typedef
293    enum {
294       Afp_INVALID,
295       /* Binary */
296       Afp_SCALE, Afp_ATAN, Afp_YL2X, Afp_YL2XP1, Afp_PREM, Afp_PREM1,
297       /* Unary */
298       Afp_SQRT,
299       Afp_SIN, Afp_COS, Afp_TAN,
300       Afp_ROUND, Afp_2XM1
301    }
302    A87FpOp;
303 
304 extern const HChar* showA87FpOp ( A87FpOp );
305 
306 
307 /* --------- */
308 typedef
309    enum {
310       Asse_INVALID,
311       /* mov */
312       Asse_MOV,
313       /* Floating point binary */
314       Asse_ADDF, Asse_SUBF, Asse_MULF, Asse_DIVF,
315       Asse_MAXF, Asse_MINF,
316       Asse_CMPEQF, Asse_CMPLTF, Asse_CMPLEF, Asse_CMPUNF,
317       /* Floating point unary */
318       Asse_RCPF, Asse_RSQRTF, Asse_SQRTF,
319       /* Floating point conversion */
320       Asse_I2F, // i32-signed to float conversion, aka cvtdq2ps in vec form
321       Asse_F2I, // float to i32-signed conversion, aka cvtps2dq in vec form
322       /* Bitwise */
323       Asse_AND, Asse_OR, Asse_XOR, Asse_ANDN,
324       Asse_ADD8, Asse_ADD16, Asse_ADD32, Asse_ADD64,
325       Asse_QADD8U, Asse_QADD16U,
326       Asse_QADD8S, Asse_QADD16S,
327       Asse_SUB8, Asse_SUB16, Asse_SUB32, Asse_SUB64,
328       Asse_QSUB8U, Asse_QSUB16U,
329       Asse_QSUB8S, Asse_QSUB16S,
330       Asse_MUL16,
331       Asse_MULHI16U,
332       Asse_MULHI16S,
333       Asse_AVG8U, Asse_AVG16U,
334       Asse_MAX16S,
335       Asse_MAX8U,
336       Asse_MIN16S,
337       Asse_MIN8U,
338       Asse_CMPEQ8, Asse_CMPEQ16, Asse_CMPEQ32,
339       Asse_CMPGT8S, Asse_CMPGT16S, Asse_CMPGT32S,
340       Asse_SHL16, Asse_SHL32, Asse_SHL64, Asse_SHL128,
341       Asse_SHR16, Asse_SHR32, Asse_SHR64, Asse_SHR128,
342       Asse_SAR16, Asse_SAR32,
343       Asse_PACKSSD, Asse_PACKSSW, Asse_PACKUSW,
344       Asse_UNPCKHB, Asse_UNPCKHW, Asse_UNPCKHD, Asse_UNPCKHQ,
345       Asse_UNPCKLB, Asse_UNPCKLW, Asse_UNPCKLD, Asse_UNPCKLQ,
346       Asse_PSHUFB // Only for SSSE3 capable hosts
347    }
348    AMD64SseOp;
349 
350 extern const HChar* showAMD64SseOp ( AMD64SseOp );
351 
352 
353 /* --------- */
354 typedef
355    enum {
356       Ain_Imm64,       /* Generate 64-bit literal to register */
357       Ain_Alu64R,      /* 64-bit mov/arith/logical, dst=REG */
358       Ain_Alu64M,      /* 64-bit mov/arith/logical, dst=MEM */
359       Ain_Sh64,        /* 64-bit shift/rotate, dst=REG or MEM */
360       Ain_Test64,      /* 64-bit test (AND, set flags, discard result) */
361       Ain_Unary64,     /* 64-bit not and neg */
362       Ain_Lea64,       /* 64-bit compute EA into a reg */
363       Ain_Alu32R,      /* 32-bit add/sub/and/or/xor/cmp, dst=REG (a la Alu64R) */
364       Ain_MulL,        /* widening multiply */
365       Ain_Div,         /* div and mod */
366       Ain_Push,        /* push 64-bit value on stack */
367       Ain_Call,        /* call to address in register */
368       Ain_XDirect,     /* direct transfer to GA */
369       Ain_XIndir,      /* indirect transfer to GA */
370       Ain_XAssisted,   /* assisted transfer to GA */
371       Ain_CMov64,      /* conditional move, 64-bit reg-reg only */
372       Ain_CLoad,       /* cond. load to int reg, 32 bit ZX or 64 bit only */
373       Ain_CStore,      /* cond. store from int reg, 32 or 64 bit only */
374       Ain_MovxLQ,      /* reg-reg move, zx-ing/sx-ing top half */
375       Ain_LoadEX,      /* mov{s,z}{b,w,l}q from mem to reg */
376       Ain_Store,       /* store 32/16/8 bit value in memory */
377       Ain_Set64,       /* convert condition code to 64-bit value */
378       Ain_Bsfr64,      /* 64-bit bsf/bsr */
379       Ain_MFence,      /* mem fence */
380       Ain_ACAS,        /* 8/16/32/64-bit lock;cmpxchg */
381       Ain_DACAS,       /* lock;cmpxchg8b/16b (doubleword ACAS, 2 x
382                           32-bit or 2 x 64-bit only) */
383       Ain_A87Free,     /* free up x87 registers */
384       Ain_A87PushPop,  /* x87 loads/stores */
385       Ain_A87FpOp,     /* x87 operations */
386       Ain_A87LdCW,     /* load x87 control word */
387       Ain_A87StSW,     /* store x87 status word */
388       Ain_LdMXCSR,     /* load %mxcsr */
389       Ain_SseUComIS,   /* ucomisd/ucomiss, then get %rflags into int
390                           register */
391       Ain_SseSI2SF,    /* scalar 32/64 int to 32/64 float conversion */
392       Ain_SseSF2SI,    /* scalar 32/64 float to 32/64 int conversion */
393       Ain_SseSDSS,     /* scalar float32 to/from float64 */
394       Ain_SseLdSt,     /* SSE load/store 32/64/128 bits, no alignment
395                           constraints, upper 96/64/0 bits arbitrary */
396       Ain_SseCStore,   /* SSE conditional store, 128 bit only, any alignment */
397       Ain_SseCLoad,    /* SSE conditional load, 128 bit only, any alignment */
398       Ain_SseLdzLO,    /* SSE load low 32/64 bits, zero remainder of reg */
399       Ain_Sse32Fx4,    /* SSE binary, 32Fx4 */
400       Ain_Sse32FLo,    /* SSE binary, 32F in lowest lane only */
401       Ain_Sse64Fx2,    /* SSE binary, 64Fx2 */
402       Ain_Sse64FLo,    /* SSE binary, 64F in lowest lane only */
403       Ain_SseReRg,     /* SSE binary general reg-reg, Re, Rg */
404       Ain_SseCMov,     /* SSE conditional move */
405       Ain_SseShuf,     /* SSE2 shuffle (pshufd) */
406       Ain_SseShiftN,   /* SSE2 shift by immediate */
407       Ain_SseMOVQ,     /* SSE2 moves of xmm[63:0] to/from GPR */
408       //uu Ain_AvxLdSt,     /* AVX load/store 256 bits,
409       //uu                     no alignment constraints */
410       //uu Ain_AvxReRg,     /* AVX binary general reg-reg, Re, Rg */
411       Ain_EvCheck,     /* Event check */
412       Ain_ProfInc      /* 64-bit profile counter increment */
413    }
414    AMD64InstrTag;
415 
416 /* Destinations are on the RIGHT (second operand) */
417 
418 typedef
419    struct {
420       AMD64InstrTag tag;
421       union {
422          struct {
423             ULong imm64;
424             HReg  dst;
425          } Imm64;
426          struct {
427             AMD64AluOp op;
428             AMD64RMI*  src;
429             HReg       dst;
430          } Alu64R;
431          struct {
432             AMD64AluOp  op;
433             AMD64RI*    src;
434             AMD64AMode* dst;
435          } Alu64M;
436          struct {
437             AMD64ShiftOp op;
438             UInt         src;  /* shift amount, or 0 means %cl */
439             HReg         dst;
440          } Sh64;
441          struct {
442             UInt   imm32;
443             HReg   dst;
444          } Test64;
445          /* Not and Neg */
446          struct {
447             AMD64UnaryOp op;
448             HReg         dst;
449          } Unary64;
450          /* 64-bit compute EA into a reg */
451          struct {
452             AMD64AMode* am;
453             HReg        dst;
454          } Lea64;
455          /* 32-bit add/sub/and/or/xor/cmp, dst=REG (a la Alu64R) */
456          struct {
457             AMD64AluOp op;
458             AMD64RMI*  src;
459             HReg       dst;
460          } Alu32R;
461          /* 64 x 64 -> 128 bit widening multiply: RDX:RAX = RAX *s/u
462             r/m64 */
463          struct {
464             Bool     syned;
465             AMD64RM* src;
466          } MulL;
467           /* amd64 div/idiv instruction.  Modifies RDX and RAX and
468 	     reads src. */
469          struct {
470             Bool     syned;
471             Int      sz; /* 4 or 8 only */
472             AMD64RM* src;
473          } Div;
474          struct {
475             AMD64RMI* src;
476          } Push;
477          /* Pseudo-insn.  Call target (an absolute address), on given
478             condition (which could be Xcc_ALWAYS). */
479          struct {
480             AMD64CondCode cond;
481             Addr64        target;
482             Int           regparms; /* 0 .. 6 */
483             RetLoc        rloc;     /* where the return value will be */
484          } Call;
485          /* Update the guest RIP value, then exit requesting to chain
486             to it.  May be conditional. */
487          struct {
488             Addr64        dstGA;    /* next guest address */
489             AMD64AMode*   amRIP;    /* amode in guest state for RIP */
490             AMD64CondCode cond;     /* can be Acc_ALWAYS */
491             Bool          toFastEP; /* chain to the slow or fast point? */
492          } XDirect;
493          /* Boring transfer to a guest address not known at JIT time.
494             Not chainable.  May be conditional. */
495          struct {
496             HReg          dstGA;
497             AMD64AMode*   amRIP;
498             AMD64CondCode cond; /* can be Acc_ALWAYS */
499          } XIndir;
500          /* Assisted transfer to a guest address, most general case.
501             Not chainable.  May be conditional. */
502          struct {
503             HReg          dstGA;
504             AMD64AMode*   amRIP;
505             AMD64CondCode cond; /* can be Acc_ALWAYS */
506             IRJumpKind    jk;
507          } XAssisted;
508          /* Mov src to dst on the given condition, which may not
509             be the bogus Acc_ALWAYS. */
510          struct {
511             AMD64CondCode cond;
512             HReg          src;
513             HReg          dst;
514          } CMov64;
515          /* conditional load to int reg, 32 bit ZX or 64 bit only.
516             cond may not be Acc_ALWAYS. */
517          struct {
518             AMD64CondCode cond;
519             UChar         szB; /* 4 or 8 only */
520             AMD64AMode*   addr;
521             HReg          dst;
522          } CLoad;
523          /* cond. store from int reg, 32 or 64 bit only.
524             cond may not be Acc_ALWAYS. */
525          struct {
526             AMD64CondCode cond;
527             UChar         szB; /* 4 or 8 only */
528             HReg          src;
529             AMD64AMode*   addr;
530          } CStore;
531          /* reg-reg move, sx-ing/zx-ing top half */
532          struct {
533             Bool syned;
534             HReg src;
535             HReg dst;
536          } MovxLQ;
537          /* Sign/Zero extending loads.  Dst size is always 64 bits. */
538          struct {
539             UChar       szSmall; /* only 1, 2 or 4 */
540             Bool        syned;
541             AMD64AMode* src;
542             HReg        dst;
543          } LoadEX;
544          /* 32/16/8 bit stores. */
545          struct {
546             UChar       sz; /* only 1, 2 or 4 */
547             HReg        src;
548             AMD64AMode* dst;
549          } Store;
550          /* Convert an amd64 condition code to a 64-bit value (0 or 1). */
551          struct {
552             AMD64CondCode cond;
553             HReg          dst;
554          } Set64;
555          /* 64-bit bsf or bsr. */
556          struct {
557             Bool isFwds;
558             HReg src;
559             HReg dst;
560          } Bsfr64;
561          /* Mem fence.  In short, an insn which flushes all preceding
562             loads and stores as much as possible before continuing.
563             On AMD64 we emit a real "mfence". */
564          struct {
565          } MFence;
566          struct {
567             AMD64AMode* addr;
568             UChar       sz; /* 1, 2, 4 or 8 */
569          } ACAS;
570          struct {
571             AMD64AMode* addr;
572             UChar       sz; /* 4 or 8 only */
573          } DACAS;
574 
575          /* --- X87 --- */
576 
577          /* A very minimal set of x87 insns, that operate exactly in a
578             stack-like way so no need to think about x87 registers. */
579 
580          /* Do 'ffree' on %st(7) .. %st(7-nregs) */
581          struct {
582             Int nregs; /* 1 <= nregs <= 7 */
583          } A87Free;
584 
585          /* Push a 32- or 64-bit FP value from memory onto the stack,
586             or move a value from the stack to memory and remove it
587             from the stack. */
588          struct {
589             AMD64AMode* addr;
590             Bool        isPush;
591             UChar       szB; /* 4 or 8 */
592          } A87PushPop;
593 
594          /* Do an operation on the top-of-stack.  This can be unary, in
595             which case it is %st0 = OP( %st0 ), or binary: %st0 = OP(
596             %st0, %st1 ). */
597          struct {
598             A87FpOp op;
599          } A87FpOp;
600 
601          /* Load the FPU control word. */
602          struct {
603             AMD64AMode* addr;
604          } A87LdCW;
605 
606          /* Store the FPU status word (fstsw m16) */
607          struct {
608             AMD64AMode* addr;
609          } A87StSW;
610 
611          /* --- SSE --- */
612 
613          /* Load 32 bits into %mxcsr. */
614          struct {
615             AMD64AMode* addr;
616          }
617          LdMXCSR;
618          /* ucomisd/ucomiss, then get %rflags into int register */
619          struct {
620             UChar   sz;   /* 4 or 8 only */
621             HReg    srcL; /* xmm */
622             HReg    srcR; /* xmm */
623             HReg    dst;  /* int */
624          } SseUComIS;
625          /* scalar 32/64 int to 32/64 float conversion */
626          struct {
627             UChar szS; /* 4 or 8 */
628             UChar szD; /* 4 or 8 */
629             HReg  src; /* i class */
630             HReg  dst; /* v class */
631          } SseSI2SF;
632          /* scalar 32/64 float to 32/64 int conversion */
633          struct {
634             UChar szS; /* 4 or 8 */
635             UChar szD; /* 4 or 8 */
636             HReg  src; /* v class */
637             HReg  dst; /* i class */
638          } SseSF2SI;
639          /* scalar float32 to/from float64 */
640          struct {
641             Bool from64; /* True: 64->32; False: 32->64 */
642             HReg src;
643             HReg dst;
644          } SseSDSS;
645          struct {
646             Bool        isLoad;
647             UChar       sz; /* 4, 8 or 16 only */
648             HReg        reg;
649             AMD64AMode* addr;
650          } SseLdSt;
651          struct {
652             AMD64CondCode cond; /* may not be Acc_ALWAYS */
653             HReg          src;
654             AMD64AMode*   addr;
655          } SseCStore;
656          struct {
657             AMD64CondCode cond; /* may not be Acc_ALWAYS */
658             AMD64AMode*   addr;
659             HReg          dst;
660          } SseCLoad;
661          struct {
662             Int         sz; /* 4 or 8 only */
663             HReg        reg;
664             AMD64AMode* addr;
665          } SseLdzLO;
666          struct {
667             AMD64SseOp op;
668             HReg       src;
669             HReg       dst;
670          } Sse32Fx4;
671          struct {
672             AMD64SseOp op;
673             HReg       src;
674             HReg       dst;
675          } Sse32FLo;
676          struct {
677             AMD64SseOp op;
678             HReg       src;
679             HReg       dst;
680          } Sse64Fx2;
681          struct {
682             AMD64SseOp op;
683             HReg       src;
684             HReg       dst;
685          } Sse64FLo;
686          struct {
687             AMD64SseOp op;
688             HReg       src;
689             HReg       dst;
690          } SseReRg;
691          /* Mov src to dst on the given condition, which may not
692             be the bogus Xcc_ALWAYS. */
693          struct {
694             AMD64CondCode cond;
695             HReg          src;
696             HReg          dst;
697          } SseCMov;
698          struct {
699             Int    order; /* 0 <= order <= 0xFF */
700             HReg   src;
701             HReg   dst;
702          } SseShuf;
703          struct {
704             AMD64SseOp op;
705             UInt       shiftBits;
706             HReg       dst;
707          } SseShiftN;
708          struct {
709             HReg gpr;
710             HReg xmm;
711             Bool toXMM; // when moving to xmm, xmm[127:64] is zeroed out
712          } SseMOVQ;
713          //uu struct {
714          //uu    Bool        isLoad;
715          //uu    HReg        reg;
716          //uu    AMD64AMode* addr;
717          //uu } AvxLdSt;
718          //uu struct {
719          //uu    AMD64SseOp op;
720          //uu    HReg       src;
721          //uu    HReg       dst;
722          //uu } AvxReRg;
723          struct {
724             AMD64AMode* amCounter;
725             AMD64AMode* amFailAddr;
726          } EvCheck;
727          struct {
728             /* No fields.  The address of the counter to inc is
729                installed later, post-translation, by patching it in,
730                as it is not known at translation time. */
731          } ProfInc;
732 
733       } Ain;
734    }
735    AMD64Instr;
736 
737 extern AMD64Instr* AMD64Instr_Imm64      ( ULong imm64, HReg dst );
738 extern AMD64Instr* AMD64Instr_Alu64R     ( AMD64AluOp, AMD64RMI*, HReg );
739 extern AMD64Instr* AMD64Instr_Alu64M     ( AMD64AluOp, AMD64RI*,  AMD64AMode* );
740 extern AMD64Instr* AMD64Instr_Unary64    ( AMD64UnaryOp op, HReg dst );
741 extern AMD64Instr* AMD64Instr_Lea64      ( AMD64AMode* am, HReg dst );
742 extern AMD64Instr* AMD64Instr_Alu32R     ( AMD64AluOp, AMD64RMI*, HReg );
743 extern AMD64Instr* AMD64Instr_Sh64       ( AMD64ShiftOp, UInt, HReg );
744 extern AMD64Instr* AMD64Instr_Test64     ( UInt imm32, HReg dst );
745 extern AMD64Instr* AMD64Instr_MulL       ( Bool syned, AMD64RM* );
746 extern AMD64Instr* AMD64Instr_Div        ( Bool syned, Int sz, AMD64RM* );
747 extern AMD64Instr* AMD64Instr_Push       ( AMD64RMI* );
748 extern AMD64Instr* AMD64Instr_Call       ( AMD64CondCode, Addr64, Int, RetLoc );
749 extern AMD64Instr* AMD64Instr_XDirect    ( Addr64 dstGA, AMD64AMode* amRIP,
750                                            AMD64CondCode cond, Bool toFastEP );
751 extern AMD64Instr* AMD64Instr_XIndir     ( HReg dstGA, AMD64AMode* amRIP,
752                                            AMD64CondCode cond );
753 extern AMD64Instr* AMD64Instr_XAssisted  ( HReg dstGA, AMD64AMode* amRIP,
754                                            AMD64CondCode cond, IRJumpKind jk );
755 extern AMD64Instr* AMD64Instr_CMov64     ( AMD64CondCode, HReg src, HReg dst );
756 extern AMD64Instr* AMD64Instr_CLoad      ( AMD64CondCode cond, UChar szB,
757                                            AMD64AMode* addr, HReg dst );
758 extern AMD64Instr* AMD64Instr_CStore     ( AMD64CondCode cond, UChar szB,
759                                            HReg src, AMD64AMode* addr );
760 extern AMD64Instr* AMD64Instr_MovxLQ     ( Bool syned, HReg src, HReg dst );
761 extern AMD64Instr* AMD64Instr_LoadEX     ( UChar szSmall, Bool syned,
762                                            AMD64AMode* src, HReg dst );
763 extern AMD64Instr* AMD64Instr_Store      ( UChar sz, HReg src, AMD64AMode* dst );
764 extern AMD64Instr* AMD64Instr_Set64      ( AMD64CondCode cond, HReg dst );
765 extern AMD64Instr* AMD64Instr_Bsfr64     ( Bool isFwds, HReg src, HReg dst );
766 extern AMD64Instr* AMD64Instr_MFence     ( void );
767 extern AMD64Instr* AMD64Instr_ACAS       ( AMD64AMode* addr, UChar sz );
768 extern AMD64Instr* AMD64Instr_DACAS      ( AMD64AMode* addr, UChar sz );
769 
770 extern AMD64Instr* AMD64Instr_A87Free    ( Int nregs );
771 extern AMD64Instr* AMD64Instr_A87PushPop ( AMD64AMode* addr, Bool isPush, UChar szB );
772 extern AMD64Instr* AMD64Instr_A87FpOp    ( A87FpOp op );
773 extern AMD64Instr* AMD64Instr_A87LdCW    ( AMD64AMode* addr );
774 extern AMD64Instr* AMD64Instr_A87StSW    ( AMD64AMode* addr );
775 extern AMD64Instr* AMD64Instr_LdMXCSR    ( AMD64AMode* );
776 extern AMD64Instr* AMD64Instr_SseUComIS  ( Int sz, HReg srcL, HReg srcR, HReg dst );
777 extern AMD64Instr* AMD64Instr_SseSI2SF   ( Int szS, Int szD, HReg src, HReg dst );
778 extern AMD64Instr* AMD64Instr_SseSF2SI   ( Int szS, Int szD, HReg src, HReg dst );
779 extern AMD64Instr* AMD64Instr_SseSDSS    ( Bool from64, HReg src, HReg dst );
780 extern AMD64Instr* AMD64Instr_SseLdSt    ( Bool isLoad, Int sz, HReg, AMD64AMode* );
781 extern AMD64Instr* AMD64Instr_SseCStore  ( AMD64CondCode, HReg, AMD64AMode* );
782 extern AMD64Instr* AMD64Instr_SseCLoad   ( AMD64CondCode, AMD64AMode*, HReg );
783 extern AMD64Instr* AMD64Instr_SseLdzLO   ( Int sz, HReg, AMD64AMode* );
784 extern AMD64Instr* AMD64Instr_Sse32Fx4   ( AMD64SseOp, HReg, HReg );
785 extern AMD64Instr* AMD64Instr_Sse32FLo   ( AMD64SseOp, HReg, HReg );
786 extern AMD64Instr* AMD64Instr_Sse64Fx2   ( AMD64SseOp, HReg, HReg );
787 extern AMD64Instr* AMD64Instr_Sse64FLo   ( AMD64SseOp, HReg, HReg );
788 extern AMD64Instr* AMD64Instr_SseReRg    ( AMD64SseOp, HReg, HReg );
789 extern AMD64Instr* AMD64Instr_SseCMov    ( AMD64CondCode, HReg src, HReg dst );
790 extern AMD64Instr* AMD64Instr_SseShuf    ( Int order, HReg src, HReg dst );
791 extern AMD64Instr* AMD64Instr_SseShiftN  ( AMD64SseOp,
792                                            UInt shiftBits, HReg dst );
793 extern AMD64Instr* AMD64Instr_SseMOVQ    ( HReg gpr, HReg xmm, Bool toXMM );
794 //uu extern AMD64Instr* AMD64Instr_AvxLdSt    ( Bool isLoad, HReg, AMD64AMode* );
795 //uu extern AMD64Instr* AMD64Instr_AvxReRg    ( AMD64SseOp, HReg, HReg );
796 extern AMD64Instr* AMD64Instr_EvCheck    ( AMD64AMode* amCounter,
797                                            AMD64AMode* amFailAddr );
798 extern AMD64Instr* AMD64Instr_ProfInc    ( void );
799 
800 
801 extern void ppAMD64Instr ( const AMD64Instr*, Bool );
802 
803 /* Some functions that insulate the register allocator from details
804    of the underlying instruction set. */
805 extern void getRegUsage_AMD64Instr ( HRegUsage*, const AMD64Instr*, Bool );
806 extern void mapRegs_AMD64Instr     ( HRegRemap*, AMD64Instr*, Bool );
807 extern Int          emit_AMD64Instr   ( /*MB_MOD*/Bool* is_profInc,
808                                         UChar* buf, Int nbuf,
809                                         const AMD64Instr* i,
810                                         Bool mode64,
811                                         VexEndness endness_host,
812                                         const void* disp_cp_chain_me_to_slowEP,
813                                         const void* disp_cp_chain_me_to_fastEP,
814                                         const void* disp_cp_xindir,
815                                         const void* disp_cp_xassisted );
816 
817 extern void genSpill_AMD64  ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
818                               HReg rreg, Int offset, Bool );
819 extern void genReload_AMD64 ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
820                               HReg rreg, Int offset, Bool );
821 extern AMD64Instr* genMove_AMD64(HReg from, HReg to, Bool);
822 extern AMD64Instr* directReload_AMD64 ( AMD64Instr* i,
823                                         HReg vreg, Short spill_off );
824 
825 extern const RRegUniverse* getRRegUniverse_AMD64 ( void );
826 
827 extern HInstrArray* iselSB_AMD64           ( const IRSB*,
828                                              VexArch,
829                                              const VexArchInfo*,
830                                              const VexAbiInfo*,
831                                              Int offs_Host_EvC_Counter,
832                                              Int offs_Host_EvC_FailAddr,
833                                              Bool chainingAllowed,
834                                              Bool addProfInc,
835                                              Addr max_ga );
836 
837 /* How big is an event check?  This is kind of a kludge because it
838    depends on the offsets of host_EvC_FAILADDR and host_EvC_COUNTER,
839    and so assumes that they are both <= 128, and so can use the short
840    offset encoding.  This is all checked with assertions, so in the
841    worst case we will merely assert at startup. */
842 extern Int evCheckSzB_AMD64 (void);
843 
844 /* Perform a chaining and unchaining of an XDirect jump. */
845 extern VexInvalRange chainXDirect_AMD64 ( VexEndness endness_host,
846                                           void* place_to_chain,
847                                           const void* disp_cp_chain_me_EXPECTED,
848                                           const void* place_to_jump_to );
849 
850 extern VexInvalRange unchainXDirect_AMD64 ( VexEndness endness_host,
851                                             void* place_to_unchain,
852                                             const void* place_to_jump_to_EXPECTED,
853                                             const void* disp_cp_chain_me );
854 
855 /* Patch the counter location into an existing ProfInc point. */
856 extern VexInvalRange patchProfInc_AMD64 ( VexEndness endness_host,
857                                           void*  place_to_patch,
858                                           const ULong* location_of_counter );
859 
860 
861 #endif /* ndef __VEX_HOST_AMD64_DEFS_H */
862 
863 /*---------------------------------------------------------------*/
864 /*--- end                                   host_amd64_defs.h ---*/
865 /*---------------------------------------------------------------*/
866