blob: 091ba80c138fde30ad3f9e8a1a7076d8ab1b551c [file] [log] [blame]
sewardja3e98302005-02-01 15:55:05 +00001
2/*---------------------------------------------------------------*/
sewardj752f9062010-05-03 21:38:49 +00003/*--- begin host_amd64_defs.h ---*/
sewardja3e98302005-02-01 15:55:05 +00004/*---------------------------------------------------------------*/
5
6/*
sewardj752f9062010-05-03 21:38:49 +00007 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
sewardja3e98302005-02-01 15:55:05 +00009
sewardj89ae8472013-10-18 14:12:58 +000010 Copyright (C) 2004-2013 OpenWorks LLP
sewardj752f9062010-05-03 21:38:49 +000011 info@open-works.net
sewardja3e98302005-02-01 15:55:05 +000012
sewardj752f9062010-05-03 21:38:49 +000013 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.
sewardja3e98302005-02-01 15:55:05 +000017
sewardj752f9062010-05-03 21:38:49 +000018 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
sewardj7bd6ffe2005-08-03 16:07:36 +000026 02110-1301, USA.
27
sewardj752f9062010-05-03 21:38:49 +000028 The GNU General Public License is contained in the file COPYING.
sewardja3e98302005-02-01 15:55:05 +000029
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.
sewardja3e98302005-02-01 15:55:05 +000034*/
35
sewardjcef7d3e2009-07-02 12:21:59 +000036#ifndef __VEX_HOST_AMD64_DEFS_H
37#define __VEX_HOST_AMD64_DEFS_H
sewardja3e98302005-02-01 15:55:05 +000038
florian58a637b2012-09-30 20:30:17 +000039#include "libvex_basictypes.h"
40#include "libvex.h" // VexArch
41#include "host_generic_regs.h" // HReg
sewardjc33671d2005-02-01 20:30:00 +000042
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
49extern void ppHRegAMD64 ( HReg );
50
51extern HReg hregAMD64_RAX ( void );
52extern HReg hregAMD64_RBX ( void );
53extern HReg hregAMD64_RCX ( void );
54extern HReg hregAMD64_RDX ( void );
55extern HReg hregAMD64_RSP ( void );
56extern HReg hregAMD64_RBP ( void );
57extern HReg hregAMD64_RSI ( void );
58extern HReg hregAMD64_RDI ( void );
59extern HReg hregAMD64_R8 ( void );
60extern HReg hregAMD64_R9 ( void );
61extern HReg hregAMD64_R10 ( void );
62extern HReg hregAMD64_R11 ( void );
63extern HReg hregAMD64_R12 ( void );
64extern HReg hregAMD64_R13 ( void );
65extern HReg hregAMD64_R14 ( void );
66extern HReg hregAMD64_R15 ( void );
67
68extern HReg hregAMD64_FAKE0 ( void );
69extern HReg hregAMD64_FAKE1 ( void );
70extern HReg hregAMD64_FAKE2 ( void );
71extern HReg hregAMD64_FAKE3 ( void );
72extern HReg hregAMD64_FAKE4 ( void );
73extern HReg hregAMD64_FAKE5 ( void );
74
75extern HReg hregAMD64_XMM0 ( void );
76extern HReg hregAMD64_XMM1 ( void );
sewardjc33671d2005-02-01 20:30:00 +000077extern HReg hregAMD64_XMM3 ( void );
78extern HReg hregAMD64_XMM4 ( void );
79extern HReg hregAMD64_XMM5 ( void );
80extern HReg hregAMD64_XMM6 ( void );
81extern HReg hregAMD64_XMM7 ( void );
82extern HReg hregAMD64_XMM8 ( void );
83extern HReg hregAMD64_XMM9 ( void );
84extern HReg hregAMD64_XMM10 ( void );
85extern HReg hregAMD64_XMM11 ( void );
86extern HReg hregAMD64_XMM12 ( void );
sewardjc4530ae2012-05-21 10:18:49 +000087
sewardjc33671d2005-02-01 20:30:00 +000088
89/* --------- Condition codes, AMD encoding. --------- */
90
91typedef
92 enum {
93 Acc_O = 0, /* overflow */
94 Acc_NO = 1, /* no overflow */
95
96 Acc_B = 2, /* below */
97 Acc_NB = 3, /* not below */
98
99 Acc_Z = 4, /* zero */
100 Acc_NZ = 5, /* not zero */
101
102 Acc_BE = 6, /* below or equal */
103 Acc_NBE = 7, /* not below or equal */
104
105 Acc_S = 8, /* negative */
106 Acc_NS = 9, /* not negative */
107
108 Acc_P = 10, /* parity even */
109 Acc_NP = 11, /* not parity even */
110
111 Acc_L = 12, /* jump less */
112 Acc_NL = 13, /* not less */
113
114 Acc_LE = 14, /* less or equal */
115 Acc_NLE = 15, /* not less or equal */
116
117 Acc_ALWAYS = 16 /* the usual hack */
118 }
119 AMD64CondCode;
120
florian55085f82012-11-21 00:36:55 +0000121extern const HChar* showAMD64CondCode ( AMD64CondCode );
sewardjc33671d2005-02-01 20:30:00 +0000122
123
124/* --------- Memory address expressions (amodes). --------- */
125
126typedef
127 enum {
128 Aam_IR, /* Immediate + Reg */
129 Aam_IRRS /* Immediate + Reg1 + (Reg2 << Shift) */
130 }
131 AMD64AModeTag;
132
133typedef
134 struct {
135 AMD64AModeTag tag;
136 union {
137 struct {
138 UInt imm;
139 HReg reg;
140 } IR;
141 struct {
142 UInt imm;
143 HReg base;
144 HReg index;
145 Int shift; /* 0, 1, 2 or 3 only */
146 } IRRS;
147 } Aam;
148 }
149 AMD64AMode;
150
151extern AMD64AMode* AMD64AMode_IR ( UInt, HReg );
152extern AMD64AMode* AMD64AMode_IRRS ( UInt, HReg, HReg, Int );
153
154extern AMD64AMode* dopyAMD64AMode ( AMD64AMode* );
155
156extern void ppAMD64AMode ( AMD64AMode* );
157
158
159/* --------- Operand, which can be reg, immediate or memory. --------- */
160
161typedef
162 enum {
163 Armi_Imm,
164 Armi_Reg,
165 Armi_Mem
166 }
167 AMD64RMITag;
168
169typedef
170 struct {
171 AMD64RMITag tag;
172 union {
173 struct {
174 UInt imm32;
175 } Imm;
176 struct {
177 HReg reg;
178 } Reg;
179 struct {
180 AMD64AMode* am;
181 } Mem;
182 }
183 Armi;
184 }
185 AMD64RMI;
186
187extern AMD64RMI* AMD64RMI_Imm ( UInt );
188extern AMD64RMI* AMD64RMI_Reg ( HReg );
189extern AMD64RMI* AMD64RMI_Mem ( AMD64AMode* );
190
sewardj9cc2bbf2011-06-05 17:56:03 +0000191extern void ppAMD64RMI ( AMD64RMI* );
192extern void ppAMD64RMI_lo32 ( AMD64RMI* );
sewardjc33671d2005-02-01 20:30:00 +0000193
194
195/* --------- Operand, which can be reg or immediate only. --------- */
196
197typedef
198 enum {
199 Ari_Imm,
200 Ari_Reg
201 }
202 AMD64RITag;
203
204typedef
205 struct {
206 AMD64RITag tag;
207 union {
208 struct {
209 UInt imm32;
210 } Imm;
211 struct {
212 HReg reg;
213 } Reg;
214 }
215 Ari;
216 }
217 AMD64RI;
218
219extern AMD64RI* AMD64RI_Imm ( UInt );
220extern AMD64RI* AMD64RI_Reg ( HReg );
221
222extern void ppAMD64RI ( AMD64RI* );
223
224
225/* --------- Operand, which can be reg or memory only. --------- */
226
227typedef
228 enum {
229 Arm_Reg,
230 Arm_Mem
231 }
232 AMD64RMTag;
233
234typedef
235 struct {
236 AMD64RMTag tag;
237 union {
238 struct {
239 HReg reg;
240 } Reg;
241 struct {
242 AMD64AMode* am;
243 } Mem;
244 }
245 Arm;
246 }
247 AMD64RM;
248
249extern AMD64RM* AMD64RM_Reg ( HReg );
250extern AMD64RM* AMD64RM_Mem ( AMD64AMode* );
251
252extern void ppAMD64RM ( AMD64RM* );
253
254
sewardjd0a12df2005-02-10 02:07:43 +0000255/* --------- Instructions. --------- */
256
257/* --------- */
258typedef
259 enum {
260 Aun_NEG,
261 Aun_NOT
262 }
263 AMD64UnaryOp;
264
florian55085f82012-11-21 00:36:55 +0000265extern const HChar* showAMD64UnaryOp ( AMD64UnaryOp );
sewardj614b3fb2005-02-02 02:16:03 +0000266
267
268/* --------- */
269typedef
270 enum {
271 Aalu_INVALID,
272 Aalu_MOV,
273 Aalu_CMP,
274 Aalu_ADD, Aalu_SUB, Aalu_ADC, Aalu_SBB,
275 Aalu_AND, Aalu_OR, Aalu_XOR,
276 Aalu_MUL
277 }
278 AMD64AluOp;
279
florian55085f82012-11-21 00:36:55 +0000280extern const HChar* showAMD64AluOp ( AMD64AluOp );
sewardj614b3fb2005-02-02 02:16:03 +0000281
282
sewardj8258a8c2005-02-02 03:11:24 +0000283/* --------- */
284typedef
285 enum {
286 Ash_INVALID,
287 Ash_SHL, Ash_SHR, Ash_SAR
288 }
289 AMD64ShiftOp;
290
florian55085f82012-11-21 00:36:55 +0000291extern const HChar* showAMD64ShiftOp ( AMD64ShiftOp );
sewardj8258a8c2005-02-02 03:11:24 +0000292
293
sewardj25a85812005-05-08 23:03:48 +0000294/* --------- */
295typedef
296 enum {
297 Afp_INVALID,
298 /* Binary */
sewardj4970e4e2008-10-11 10:07:55 +0000299 Afp_SCALE, Afp_ATAN, Afp_YL2X, Afp_YL2XP1, Afp_PREM, Afp_PREM1,
sewardj25a85812005-05-08 23:03:48 +0000300 /* Unary */
sewardj4796d662006-02-05 16:06:26 +0000301 Afp_SQRT,
sewardj5e205372005-05-09 02:57:08 +0000302 Afp_SIN, Afp_COS, Afp_TAN,
sewardj25a85812005-05-08 23:03:48 +0000303 Afp_ROUND, Afp_2XM1
304 }
305 A87FpOp;
306
florian55085f82012-11-21 00:36:55 +0000307extern const HChar* showA87FpOp ( A87FpOp );
sewardj1001dc42005-02-21 08:25:55 +0000308
309
310/* --------- */
311typedef
312 enum {
313 Asse_INVALID,
314 /* mov */
315 Asse_MOV,
316 /* Floating point binary */
317 Asse_ADDF, Asse_SUBF, Asse_MULF, Asse_DIVF,
sewardj1a01e652005-02-23 11:39:21 +0000318 Asse_MAXF, Asse_MINF,
sewardj8d965312005-02-25 02:48:47 +0000319 Asse_CMPEQF, Asse_CMPLTF, Asse_CMPLEF, Asse_CMPUNF,
sewardj1001dc42005-02-21 08:25:55 +0000320 /* Floating point unary */
321 Asse_RCPF, Asse_RSQRTF, Asse_SQRTF,
322 /* Bitwise */
323 Asse_AND, Asse_OR, Asse_XOR, Asse_ANDN,
sewardj97628592005-05-10 22:42:54 +0000324 Asse_ADD8, Asse_ADD16, Asse_ADD32, Asse_ADD64,
sewardj5992bd02005-05-11 02:13:42 +0000325 Asse_QADD8U, Asse_QADD16U,
326 Asse_QADD8S, Asse_QADD16S,
sewardj97628592005-05-10 22:42:54 +0000327 Asse_SUB8, Asse_SUB16, Asse_SUB32, Asse_SUB64,
328 Asse_QSUB8U, Asse_QSUB16U,
329 Asse_QSUB8S, Asse_QSUB16S,
sewardjadffcef2005-05-11 00:03:06 +0000330 Asse_MUL16,
331 Asse_MULHI16U,
332 Asse_MULHI16S,
sewardj5992bd02005-05-11 02:13:42 +0000333 Asse_AVG8U, Asse_AVG16U,
sewardjadffcef2005-05-11 00:03:06 +0000334 Asse_MAX16S,
335 Asse_MAX8U,
336 Asse_MIN16S,
337 Asse_MIN8U,
sewardj5992bd02005-05-11 02:13:42 +0000338 Asse_CMPEQ8, Asse_CMPEQ16, Asse_CMPEQ32,
339 Asse_CMPGT8S, Asse_CMPGT16S, Asse_CMPGT32S,
sewardjadffcef2005-05-11 00:03:06 +0000340 Asse_SHL16, Asse_SHL32, Asse_SHL64,
341 Asse_SHR16, Asse_SHR32, Asse_SHR64,
342 Asse_SAR16, Asse_SAR32,
sewardj97628592005-05-10 22:42:54 +0000343 Asse_PACKSSD, Asse_PACKSSW, Asse_PACKUSW,
344 Asse_UNPCKHB, Asse_UNPCKHW, Asse_UNPCKHD, Asse_UNPCKHQ,
345 Asse_UNPCKLB, Asse_UNPCKLW, Asse_UNPCKLD, Asse_UNPCKLQ
sewardj1001dc42005-02-21 08:25:55 +0000346 }
347 AMD64SseOp;
348
florian55085f82012-11-21 00:36:55 +0000349extern const HChar* showAMD64SseOp ( AMD64SseOp );
sewardjc33671d2005-02-01 20:30:00 +0000350
351
352/* --------- */
353typedef
354 enum {
sewardj25a85812005-05-08 23:03:48 +0000355 Ain_Imm64, /* Generate 64-bit literal to register */
356 Ain_Alu64R, /* 64-bit mov/arith/logical, dst=REG */
357 Ain_Alu64M, /* 64-bit mov/arith/logical, dst=MEM */
358 Ain_Sh64, /* 64-bit shift/rotate, dst=REG or MEM */
359 Ain_Test64, /* 64-bit test (AND, set flags, discard result) */
360 Ain_Unary64, /* 64-bit not and neg */
sewardj6ce1a232007-03-31 19:12:38 +0000361 Ain_Lea64, /* 64-bit compute EA into a reg */
sewardj9cc2bbf2011-06-05 17:56:03 +0000362 Ain_Alu32R, /* 32-bit add/sub/and/or/xor/cmp, dst=REG (a la Alu64R) */
sewardj25a85812005-05-08 23:03:48 +0000363 Ain_MulL, /* widening multiply */
364 Ain_Div, /* div and mod */
sewardj25a85812005-05-08 23:03:48 +0000365 Ain_Push, /* push 64-bit value on stack */
366 Ain_Call, /* call to address in register */
sewardjc6f970f2012-04-02 21:54:49 +0000367 Ain_XDirect, /* direct transfer to GA */
368 Ain_XIndir, /* indirect transfer to GA */
369 Ain_XAssisted, /* assisted transfer to GA */
sewardj25a85812005-05-08 23:03:48 +0000370 Ain_CMov64, /* conditional move */
sewardjca257bc2010-09-08 08:34:52 +0000371 Ain_MovxLQ, /* reg-reg move, zx-ing/sx-ing top half */
sewardj25a85812005-05-08 23:03:48 +0000372 Ain_LoadEX, /* mov{s,z}{b,w,l}q from mem to reg */
373 Ain_Store, /* store 32/16/8 bit value in memory */
374 Ain_Set64, /* convert condition code to 64-bit value */
375 Ain_Bsfr64, /* 64-bit bsf/bsr */
376 Ain_MFence, /* mem fence */
sewardje9d8a262009-07-01 08:06:34 +0000377 Ain_ACAS, /* 8/16/32/64-bit lock;cmpxchg */
378 Ain_DACAS, /* lock;cmpxchg8b/16b (doubleword ACAS, 2 x
379 32-bit or 2 x 64-bit only) */
sewardj25a85812005-05-08 23:03:48 +0000380 Ain_A87Free, /* free up x87 registers */
381 Ain_A87PushPop, /* x87 loads/stores */
382 Ain_A87FpOp, /* x87 operations */
383 Ain_A87LdCW, /* load x87 control word */
sewardjf4c803b2006-09-11 11:07:34 +0000384 Ain_A87StSW, /* store x87 status word */
sewardj25a85812005-05-08 23:03:48 +0000385 Ain_LdMXCSR, /* load %mxcsr */
sewardj25a85812005-05-08 23:03:48 +0000386 Ain_SseUComIS, /* ucomisd/ucomiss, then get %rflags into int
387 register */
388 Ain_SseSI2SF, /* scalar 32/64 int to 32/64 float conversion */
389 Ain_SseSF2SI, /* scalar 32/64 float to 32/64 int conversion */
390 Ain_SseSDSS, /* scalar float32 to/from float64 */
sewardj25a85812005-05-08 23:03:48 +0000391 Ain_SseLdSt, /* SSE load/store 32/64/128 bits, no alignment
392 constraints, upper 96/64/0 bits arbitrary */
393 Ain_SseLdzLO, /* SSE load low 32/64 bits, zero remainder of reg */
394 Ain_Sse32Fx4, /* SSE binary, 32Fx4 */
395 Ain_Sse32FLo, /* SSE binary, 32F in lowest lane only */
396 Ain_Sse64Fx2, /* SSE binary, 64Fx2 */
397 Ain_Sse64FLo, /* SSE binary, 64F in lowest lane only */
398 Ain_SseReRg, /* SSE binary general reg-reg, Re, Rg */
399 Ain_SseCMov, /* SSE conditional move */
sewardjc6f970f2012-04-02 21:54:49 +0000400 Ain_SseShuf, /* SSE2 shuffle (pshufd) */
sewardj3616a2e2012-05-27 16:18:13 +0000401 //uu Ain_AvxLdSt, /* AVX load/store 256 bits,
402 //uu no alignment constraints */
403 //uu Ain_AvxReRg, /* AVX binary general reg-reg, Re, Rg */
sewardjc6f970f2012-04-02 21:54:49 +0000404 Ain_EvCheck, /* Event check */
405 Ain_ProfInc /* 64-bit profile counter increment */
sewardjc33671d2005-02-01 20:30:00 +0000406 }
407 AMD64InstrTag;
408
409/* Destinations are on the RIGHT (second operand) */
410
411typedef
412 struct {
413 AMD64InstrTag tag;
sewardj614b3fb2005-02-02 02:16:03 +0000414 union {
415 struct {
sewardj53df0612005-02-04 21:15:39 +0000416 ULong imm64;
417 HReg dst;
418 } Imm64;
419 struct {
sewardj614b3fb2005-02-02 02:16:03 +0000420 AMD64AluOp op;
421 AMD64RMI* src;
422 HReg dst;
423 } Alu64R;
424 struct {
425 AMD64AluOp op;
426 AMD64RI* src;
427 AMD64AMode* dst;
428 } Alu64M;
sewardj8258a8c2005-02-02 03:11:24 +0000429 struct {
430 AMD64ShiftOp op;
431 UInt src; /* shift amount, or 0 means %cl */
sewardj501a3392005-05-11 15:37:50 +0000432 HReg dst;
sewardj8258a8c2005-02-02 03:11:24 +0000433 } Sh64;
sewardj05b3b6a2005-02-04 01:44:33 +0000434 struct {
sewardj501a3392005-05-11 15:37:50 +0000435 UInt imm32;
436 HReg dst;
sewardj05b3b6a2005-02-04 01:44:33 +0000437 } Test64;
sewardjd0a12df2005-02-10 02:07:43 +0000438 /* Not and Neg */
439 struct {
440 AMD64UnaryOp op;
sewardj501a3392005-05-11 15:37:50 +0000441 HReg dst;
sewardjd0a12df2005-02-10 02:07:43 +0000442 } Unary64;
sewardj6ce1a232007-03-31 19:12:38 +0000443 /* 64-bit compute EA into a reg */
444 struct {
445 AMD64AMode* am;
446 HReg dst;
447 } Lea64;
sewardj9cc2bbf2011-06-05 17:56:03 +0000448 /* 32-bit add/sub/and/or/xor/cmp, dst=REG (a la Alu64R) */
449 struct {
450 AMD64AluOp op;
451 AMD64RMI* src;
452 HReg dst;
453 } Alu32R;
sewardj501a3392005-05-11 15:37:50 +0000454 /* 64 x 64 -> 128 bit widening multiply: RDX:RAX = RAX *s/u
455 r/m64 */
sewardj9b967672005-02-08 11:13:09 +0000456 struct {
457 Bool syned;
sewardj9b967672005-02-08 11:13:09 +0000458 AMD64RM* src;
459 } MulL;
sewardj7de0d3c2005-02-13 02:26:41 +0000460 /* amd64 div/idiv instruction. Modifies RDX and RAX and
461 reads src. */
462 struct {
463 Bool syned;
464 Int sz; /* 4 or 8 only */
465 AMD64RM* src;
466 } Div;
sewardj1001dc42005-02-21 08:25:55 +0000467 struct {
468 AMD64RMI* src;
469 } Push;
sewardj05b3b6a2005-02-04 01:44:33 +0000470 /* Pseudo-insn. Call target (an absolute address), on given
471 condition (which could be Xcc_ALWAYS). */
472 struct {
473 AMD64CondCode cond;
474 Addr64 target;
475 Int regparms; /* 0 .. 6 */
sewardjcfe046e2013-01-17 14:23:53 +0000476 RetLoc rloc; /* where the return value will be */
sewardj05b3b6a2005-02-04 01:44:33 +0000477 } Call;
sewardjc6f970f2012-04-02 21:54:49 +0000478 /* Update the guest RIP value, then exit requesting to chain
479 to it. May be conditional. */
sewardjf67eadf2005-02-03 03:53:52 +0000480 struct {
sewardjc6f970f2012-04-02 21:54:49 +0000481 Addr64 dstGA; /* next guest address */
482 AMD64AMode* amRIP; /* amode in guest state for RIP */
483 AMD64CondCode cond; /* can be Acc_ALWAYS */
484 Bool toFastEP; /* chain to the slow or fast point? */
485 } XDirect;
486 /* Boring transfer to a guest address not known at JIT time.
487 Not chainable. May be conditional. */
488 struct {
489 HReg dstGA;
490 AMD64AMode* amRIP;
491 AMD64CondCode cond; /* can be Acc_ALWAYS */
492 } XIndir;
493 /* Assisted transfer to a guest address, most general case.
494 Not chainable. May be conditional. */
495 struct {
496 HReg dstGA;
497 AMD64AMode* amRIP;
498 AMD64CondCode cond; /* can be Acc_ALWAYS */
sewardjf67eadf2005-02-03 03:53:52 +0000499 IRJumpKind jk;
sewardjc6f970f2012-04-02 21:54:49 +0000500 } XAssisted;
sewardj05b3b6a2005-02-04 01:44:33 +0000501 /* Mov src to dst on the given condition, which may not
502 be the bogus Acc_ALWAYS. */
503 struct {
504 AMD64CondCode cond;
505 AMD64RM* src;
506 HReg dst;
507 } CMov64;
sewardjca257bc2010-09-08 08:34:52 +0000508 /* reg-reg move, sx-ing/zx-ing top half */
sewardjf67eadf2005-02-03 03:53:52 +0000509 struct {
sewardjca257bc2010-09-08 08:34:52 +0000510 Bool syned;
sewardjf67eadf2005-02-03 03:53:52 +0000511 HReg src;
512 HReg dst;
sewardjca257bc2010-09-08 08:34:52 +0000513 } MovxLQ;
sewardj8258a8c2005-02-02 03:11:24 +0000514 /* Sign/Zero extending loads. Dst size is always 64 bits. */
515 struct {
sewardj18303862005-02-21 12:36:54 +0000516 UChar szSmall; /* only 1, 2 or 4 */
sewardj8258a8c2005-02-02 03:11:24 +0000517 Bool syned;
518 AMD64AMode* src;
519 HReg dst;
520 } LoadEX;
sewardjf67eadf2005-02-03 03:53:52 +0000521 /* 32/16/8 bit stores. */
522 struct {
523 UChar sz; /* only 1, 2 or 4 */
524 HReg src;
525 AMD64AMode* dst;
526 } Store;
sewardja5bd0af2005-03-24 20:40:12 +0000527 /* Convert an amd64 condition code to a 64-bit value (0 or 1). */
528 struct {
529 AMD64CondCode cond;
530 HReg dst;
531 } Set64;
sewardjf53b7352005-04-06 20:01:56 +0000532 /* 64-bit bsf or bsr. */
533 struct {
534 Bool isFwds;
535 HReg src;
536 HReg dst;
537 } Bsfr64;
sewardjd0a12df2005-02-10 02:07:43 +0000538 /* Mem fence. In short, an insn which flushes all preceding
539 loads and stores as much as possible before continuing.
540 On AMD64 we emit a real "mfence". */
541 struct {
542 } MFence;
sewardje9d8a262009-07-01 08:06:34 +0000543 struct {
544 AMD64AMode* addr;
545 UChar sz; /* 1, 2, 4 or 8 */
546 } ACAS;
547 struct {
548 AMD64AMode* addr;
549 UChar sz; /* 4 or 8 only */
550 } DACAS;
sewardjd0a12df2005-02-10 02:07:43 +0000551
sewardj25a85812005-05-08 23:03:48 +0000552 /* --- X87 --- */
553
554 /* A very minimal set of x87 insns, that operate exactly in a
555 stack-like way so no need to think about x87 registers. */
556
557 /* Do 'ffree' on %st(7) .. %st(7-nregs) */
558 struct {
559 Int nregs; /* 1 <= nregs <= 7 */
560 } A87Free;
561
sewardjd15b5972010-06-27 09:06:34 +0000562 /* Push a 32- or 64-bit FP value from memory onto the stack,
563 or move a value from the stack to memory and remove it
564 from the stack. */
sewardj25a85812005-05-08 23:03:48 +0000565 struct {
566 AMD64AMode* addr;
567 Bool isPush;
sewardjd15b5972010-06-27 09:06:34 +0000568 UChar szB; /* 4 or 8 */
sewardj25a85812005-05-08 23:03:48 +0000569 } A87PushPop;
570
571 /* Do an operation on the top-of-stack. This can be unary, in
572 which case it is %st0 = OP( %st0 ), or binary: %st0 = OP(
573 %st0, %st1 ). */
574 struct {
575 A87FpOp op;
576 } A87FpOp;
577
578 /* Load the FPU control word. */
579 struct {
580 AMD64AMode* addr;
581 } A87LdCW;
582
sewardjf4c803b2006-09-11 11:07:34 +0000583 /* Store the FPU status word (fstsw m16) */
584 struct {
585 AMD64AMode* addr;
586 } A87StSW;
587
sewardj25a85812005-05-08 23:03:48 +0000588 /* --- SSE --- */
589
sewardj1a01e652005-02-23 11:39:21 +0000590 /* Load 32 bits into %mxcsr. */
591 struct {
592 AMD64AMode* addr;
593 }
594 LdMXCSR;
sewardj18303862005-02-21 12:36:54 +0000595 /* ucomisd/ucomiss, then get %rflags into int register */
596 struct {
597 UChar sz; /* 4 or 8 only */
598 HReg srcL; /* xmm */
599 HReg srcR; /* xmm */
600 HReg dst; /* int */
601 } SseUComIS;
sewardj1a01e652005-02-23 11:39:21 +0000602 /* scalar 32/64 int to 32/64 float conversion */
603 struct {
604 UChar szS; /* 4 or 8 */
605 UChar szD; /* 4 or 8 */
606 HReg src; /* i class */
607 HReg dst; /* v class */
608 } SseSI2SF;
609 /* scalar 32/64 float to 32/64 int conversion */
610 struct {
611 UChar szS; /* 4 or 8 */
612 UChar szD; /* 4 or 8 */
613 HReg src; /* v class */
614 HReg dst; /* i class */
615 } SseSF2SI;
sewardj8d965312005-02-25 02:48:47 +0000616 /* scalar float32 to/from float64 */
617 struct {
618 Bool from64; /* True: 64->32; False: 32->64 */
619 HReg src;
620 HReg dst;
621 } SseSDSS;
sewardj1001dc42005-02-21 08:25:55 +0000622 struct {
623 Bool isLoad;
sewardj18303862005-02-21 12:36:54 +0000624 UChar sz; /* 4, 8 or 16 only */
sewardj1001dc42005-02-21 08:25:55 +0000625 HReg reg;
626 AMD64AMode* addr;
627 } SseLdSt;
628 struct {
629 Int sz; /* 4 or 8 only */
630 HReg reg;
631 AMD64AMode* addr;
632 } SseLdzLO;
sewardj8d965312005-02-25 02:48:47 +0000633 struct {
634 AMD64SseOp op;
635 HReg src;
636 HReg dst;
637 } Sse32Fx4;
638 struct {
639 AMD64SseOp op;
640 HReg src;
641 HReg dst;
642 } Sse32FLo;
sewardj4c328cf2005-05-05 12:05:54 +0000643 struct {
644 AMD64SseOp op;
645 HReg src;
646 HReg dst;
647 } Sse64Fx2;
sewardj1001dc42005-02-21 08:25:55 +0000648 struct {
649 AMD64SseOp op;
650 HReg src;
651 HReg dst;
652 } Sse64FLo;
653 struct {
654 AMD64SseOp op;
655 HReg src;
656 HReg dst;
657 } SseReRg;
sewardj8d965312005-02-25 02:48:47 +0000658 /* Mov src to dst on the given condition, which may not
659 be the bogus Xcc_ALWAYS. */
660 struct {
661 AMD64CondCode cond;
662 HReg src;
663 HReg dst;
664 } SseCMov;
sewardj09717342005-05-05 21:34:02 +0000665 struct {
666 Int order; /* 0 <= order <= 0xFF */
667 HReg src;
668 HReg dst;
669 } SseShuf;
sewardj3616a2e2012-05-27 16:18:13 +0000670 //uu struct {
671 //uu Bool isLoad;
672 //uu HReg reg;
673 //uu AMD64AMode* addr;
674 //uu } AvxLdSt;
675 //uu struct {
676 //uu AMD64SseOp op;
677 //uu HReg src;
678 //uu HReg dst;
679 //uu } AvxReRg;
sewardjc4530ae2012-05-21 10:18:49 +0000680 struct {
sewardjc6f970f2012-04-02 21:54:49 +0000681 AMD64AMode* amCounter;
682 AMD64AMode* amFailAddr;
683 } EvCheck;
684 struct {
685 /* No fields. The address of the counter to inc is
686 installed later, post-translation, by patching it in,
687 as it is not known at translation time. */
688 } ProfInc;
sewardj614b3fb2005-02-02 02:16:03 +0000689
690 } Ain;
sewardjc33671d2005-02-01 20:30:00 +0000691 }
692 AMD64Instr;
693
sewardj25a85812005-05-08 23:03:48 +0000694extern AMD64Instr* AMD64Instr_Imm64 ( ULong imm64, HReg dst );
695extern AMD64Instr* AMD64Instr_Alu64R ( AMD64AluOp, AMD64RMI*, HReg );
696extern AMD64Instr* AMD64Instr_Alu64M ( AMD64AluOp, AMD64RI*, AMD64AMode* );
sewardj501a3392005-05-11 15:37:50 +0000697extern AMD64Instr* AMD64Instr_Unary64 ( AMD64UnaryOp op, HReg dst );
sewardj6ce1a232007-03-31 19:12:38 +0000698extern AMD64Instr* AMD64Instr_Lea64 ( AMD64AMode* am, HReg dst );
sewardj9cc2bbf2011-06-05 17:56:03 +0000699extern AMD64Instr* AMD64Instr_Alu32R ( AMD64AluOp, AMD64RMI*, HReg );
sewardj501a3392005-05-11 15:37:50 +0000700extern AMD64Instr* AMD64Instr_Sh64 ( AMD64ShiftOp, UInt, HReg );
701extern AMD64Instr* AMD64Instr_Test64 ( UInt imm32, HReg dst );
702extern AMD64Instr* AMD64Instr_MulL ( Bool syned, AMD64RM* );
sewardj25a85812005-05-08 23:03:48 +0000703extern AMD64Instr* AMD64Instr_Div ( Bool syned, Int sz, AMD64RM* );
sewardj25a85812005-05-08 23:03:48 +0000704extern AMD64Instr* AMD64Instr_Push ( AMD64RMI* );
sewardjcfe046e2013-01-17 14:23:53 +0000705extern AMD64Instr* AMD64Instr_Call ( AMD64CondCode, Addr64, Int, RetLoc );
sewardjc6f970f2012-04-02 21:54:49 +0000706extern AMD64Instr* AMD64Instr_XDirect ( Addr64 dstGA, AMD64AMode* amRIP,
707 AMD64CondCode cond, Bool toFastEP );
708extern AMD64Instr* AMD64Instr_XIndir ( HReg dstGA, AMD64AMode* amRIP,
709 AMD64CondCode cond );
710extern AMD64Instr* AMD64Instr_XAssisted ( HReg dstGA, AMD64AMode* amRIP,
711 AMD64CondCode cond, IRJumpKind jk );
sewardj25a85812005-05-08 23:03:48 +0000712extern AMD64Instr* AMD64Instr_CMov64 ( AMD64CondCode, AMD64RM* src, HReg dst );
sewardjca257bc2010-09-08 08:34:52 +0000713extern AMD64Instr* AMD64Instr_MovxLQ ( Bool syned, HReg src, HReg dst );
sewardj25a85812005-05-08 23:03:48 +0000714extern AMD64Instr* AMD64Instr_LoadEX ( UChar szSmall, Bool syned,
715 AMD64AMode* src, HReg dst );
716extern AMD64Instr* AMD64Instr_Store ( UChar sz, HReg src, AMD64AMode* dst );
717extern AMD64Instr* AMD64Instr_Set64 ( AMD64CondCode cond, HReg dst );
718extern AMD64Instr* AMD64Instr_Bsfr64 ( Bool isFwds, HReg src, HReg dst );
719extern AMD64Instr* AMD64Instr_MFence ( void );
sewardje9d8a262009-07-01 08:06:34 +0000720extern AMD64Instr* AMD64Instr_ACAS ( AMD64AMode* addr, UChar sz );
721extern AMD64Instr* AMD64Instr_DACAS ( AMD64AMode* addr, UChar sz );
722
sewardj25a85812005-05-08 23:03:48 +0000723extern AMD64Instr* AMD64Instr_A87Free ( Int nregs );
sewardjd15b5972010-06-27 09:06:34 +0000724extern AMD64Instr* AMD64Instr_A87PushPop ( AMD64AMode* addr, Bool isPush, UChar szB );
sewardj25a85812005-05-08 23:03:48 +0000725extern AMD64Instr* AMD64Instr_A87FpOp ( A87FpOp op );
726extern AMD64Instr* AMD64Instr_A87LdCW ( AMD64AMode* addr );
sewardjf4c803b2006-09-11 11:07:34 +0000727extern AMD64Instr* AMD64Instr_A87StSW ( AMD64AMode* addr );
sewardj25a85812005-05-08 23:03:48 +0000728extern AMD64Instr* AMD64Instr_LdMXCSR ( AMD64AMode* );
sewardj25a85812005-05-08 23:03:48 +0000729extern AMD64Instr* AMD64Instr_SseUComIS ( Int sz, HReg srcL, HReg srcR, HReg dst );
730extern AMD64Instr* AMD64Instr_SseSI2SF ( Int szS, Int szD, HReg src, HReg dst );
731extern AMD64Instr* AMD64Instr_SseSF2SI ( Int szS, Int szD, HReg src, HReg dst );
732extern AMD64Instr* AMD64Instr_SseSDSS ( Bool from64, HReg src, HReg dst );
sewardj25a85812005-05-08 23:03:48 +0000733extern AMD64Instr* AMD64Instr_SseLdSt ( Bool isLoad, Int sz, HReg, AMD64AMode* );
734extern AMD64Instr* AMD64Instr_SseLdzLO ( Int sz, HReg, AMD64AMode* );
735extern AMD64Instr* AMD64Instr_Sse32Fx4 ( AMD64SseOp, HReg, HReg );
736extern AMD64Instr* AMD64Instr_Sse32FLo ( AMD64SseOp, HReg, HReg );
737extern AMD64Instr* AMD64Instr_Sse64Fx2 ( AMD64SseOp, HReg, HReg );
738extern AMD64Instr* AMD64Instr_Sse64FLo ( AMD64SseOp, HReg, HReg );
739extern AMD64Instr* AMD64Instr_SseReRg ( AMD64SseOp, HReg, HReg );
740extern AMD64Instr* AMD64Instr_SseCMov ( AMD64CondCode, HReg src, HReg dst );
741extern AMD64Instr* AMD64Instr_SseShuf ( Int order, HReg src, HReg dst );
sewardj3616a2e2012-05-27 16:18:13 +0000742//uu extern AMD64Instr* AMD64Instr_AvxLdSt ( Bool isLoad, HReg, AMD64AMode* );
743//uu extern AMD64Instr* AMD64Instr_AvxReRg ( AMD64SseOp, HReg, HReg );
sewardjc6f970f2012-04-02 21:54:49 +0000744extern AMD64Instr* AMD64Instr_EvCheck ( AMD64AMode* amCounter,
745 AMD64AMode* amFailAddr );
746extern AMD64Instr* AMD64Instr_ProfInc ( void );
sewardjc33671d2005-02-01 20:30:00 +0000747
748
floriand8c64e02014-10-08 08:54:44 +0000749extern void ppAMD64Instr ( const AMD64Instr*, Bool );
sewardjc33671d2005-02-01 20:30:00 +0000750
751/* Some functions that insulate the register allocator from details
752 of the underlying instruction set. */
floriand8c64e02014-10-08 08:54:44 +0000753extern void getRegUsage_AMD64Instr ( HRegUsage*, const AMD64Instr*, Bool );
754extern void mapRegs_AMD64Instr ( HRegRemap*, AMD64Instr*, Bool );
755extern Bool isMove_AMD64Instr ( const AMD64Instr*, HReg*, HReg* );
florian8462d112014-09-24 15:18:09 +0000756extern Int emit_AMD64Instr ( /*MB_MOD*/Bool* is_profInc,
757 UChar* buf, Int nbuf,
floriand8c64e02014-10-08 08:54:44 +0000758 const AMD64Instr* i,
florian8462d112014-09-24 15:18:09 +0000759 Bool mode64,
760 VexEndness endness_host,
761 const void* disp_cp_chain_me_to_slowEP,
762 const void* disp_cp_chain_me_to_fastEP,
763 const void* disp_cp_xindir,
764 const void* disp_cp_xassisted );
sewardj2a1ed8e2009-12-31 19:26:03 +0000765
766extern void genSpill_AMD64 ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
767 HReg rreg, Int offset, Bool );
768extern void genReload_AMD64 ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
769 HReg rreg, Int offset, Bool );
770
sewardjc33671d2005-02-01 20:30:00 +0000771extern void getAllocableRegs_AMD64 ( Int*, HReg** );
sewardjc6f970f2012-04-02 21:54:49 +0000772extern HInstrArray* iselSB_AMD64 ( IRSB*,
773 VexArch,
floriand8c64e02014-10-08 08:54:44 +0000774 const VexArchInfo*,
775 const VexAbiInfo*,
sewardjc6f970f2012-04-02 21:54:49 +0000776 Int offs_Host_EvC_Counter,
777 Int offs_Host_EvC_FailAddr,
778 Bool chainingAllowed,
779 Bool addProfInc,
780 Addr64 max_ga );
781
782/* How big is an event check? This is kind of a kludge because it
783 depends on the offsets of host_EvC_FAILADDR and host_EvC_COUNTER,
784 and so assumes that they are both <= 128, and so can use the short
785 offset encoding. This is all checked with assertions, so in the
786 worst case we will merely assert at startup. */
sewardj9b769162014-07-24 12:42:03 +0000787extern Int evCheckSzB_AMD64 ( VexEndness endness_host );
sewardjc6f970f2012-04-02 21:54:49 +0000788
789/* Perform a chaining and unchaining of an XDirect jump. */
sewardj9b769162014-07-24 12:42:03 +0000790extern VexInvalRange chainXDirect_AMD64 ( VexEndness endness_host,
791 void* place_to_chain,
florian7d6f81d2014-09-22 21:43:37 +0000792 const void* disp_cp_chain_me_EXPECTED,
793 const void* place_to_jump_to );
sewardjc6f970f2012-04-02 21:54:49 +0000794
sewardj9b769162014-07-24 12:42:03 +0000795extern VexInvalRange unchainXDirect_AMD64 ( VexEndness endness_host,
796 void* place_to_unchain,
florian7d6f81d2014-09-22 21:43:37 +0000797 const void* place_to_jump_to_EXPECTED,
798 const void* disp_cp_chain_me );
sewardjc6f970f2012-04-02 21:54:49 +0000799
800/* Patch the counter location into an existing ProfInc point. */
sewardj9b769162014-07-24 12:42:03 +0000801extern VexInvalRange patchProfInc_AMD64 ( VexEndness endness_host,
802 void* place_to_patch,
florian7d6f81d2014-09-22 21:43:37 +0000803 const ULong* location_of_counter );
sewardjc6f970f2012-04-02 21:54:49 +0000804
sewardja3e98302005-02-01 15:55:05 +0000805
sewardjcef7d3e2009-07-02 12:21:59 +0000806#endif /* ndef __VEX_HOST_AMD64_DEFS_H */
sewardja3e98302005-02-01 15:55:05 +0000807
808/*---------------------------------------------------------------*/
sewardjcef7d3e2009-07-02 12:21:59 +0000809/*--- end host_amd64_defs.h ---*/
sewardja3e98302005-02-01 15:55:05 +0000810/*---------------------------------------------------------------*/