blob: 0a3ed75f6f640ad7d1e0c5756e01bf1443172d3d [file] [log] [blame]
sewardjc97096c2004-06-30 09:28:04 +00001
2/*---------------------------------------------------------------*/
sewardj752f9062010-05-03 21:38:49 +00003/*--- begin host_x86_defs.h ---*/
sewardjc97096c2004-06-30 09:28:04 +00004/*---------------------------------------------------------------*/
5
sewardjf8ed9d82004-11-12 17:40:23 +00006/*
sewardj752f9062010-05-03 21:38:49 +00007 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
sewardjf8ed9d82004-11-12 17:40:23 +00009
Elliott Hughesed398002017-06-21 14:41:24 -070010 Copyright (C) 2004-2017 OpenWorks LLP
sewardj752f9062010-05-03 21:38:49 +000011 info@open-works.net
sewardjf8ed9d82004-11-12 17:40:23 +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.
sewardjf8ed9d82004-11-12 17:40:23 +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.
sewardjf8ed9d82004-11-12 17:40:23 +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.
sewardjf8ed9d82004-11-12 17:40:23 +000034*/
35
sewardjcef7d3e2009-07-02 12:21:59 +000036#ifndef __VEX_HOST_X86_DEFS_H
37#define __VEX_HOST_X86_DEFS_H
sewardjc97096c2004-06-30 09:28:04 +000038
florian58a637b2012-09-30 20:30:17 +000039#include "libvex_basictypes.h"
40#include "libvex.h" // VexArch
41#include "host_generic_regs.h" // HReg
sewardjc97096c2004-06-30 09:28:04 +000042
43/* --------- Registers. --------- */
44
45/* The usual HReg abstraction. There are 8 real int regs,
sewardjc0250e42005-02-01 20:27:57 +000046 6 real float regs, and 8 real vector regs.
sewardjc97096c2004-06-30 09:28:04 +000047*/
48
sewardja5b50222015-03-26 07:18:32 +000049#define ST_IN static inline
50ST_IN HReg hregX86_EAX ( void ) { return mkHReg(False, HRcInt32, 0, 0); }
51ST_IN HReg hregX86_EBX ( void ) { return mkHReg(False, HRcInt32, 3, 1); }
52ST_IN HReg hregX86_ECX ( void ) { return mkHReg(False, HRcInt32, 1, 2); }
53ST_IN HReg hregX86_EDX ( void ) { return mkHReg(False, HRcInt32, 2, 3); }
54ST_IN HReg hregX86_ESI ( void ) { return mkHReg(False, HRcInt32, 6, 4); }
55ST_IN HReg hregX86_EDI ( void ) { return mkHReg(False, HRcInt32, 7, 5); }
56
57ST_IN HReg hregX86_FAKE0 ( void ) { return mkHReg(False, HRcFlt64, 0, 6); }
58ST_IN HReg hregX86_FAKE1 ( void ) { return mkHReg(False, HRcFlt64, 1, 7); }
59ST_IN HReg hregX86_FAKE2 ( void ) { return mkHReg(False, HRcFlt64, 2, 8); }
60ST_IN HReg hregX86_FAKE3 ( void ) { return mkHReg(False, HRcFlt64, 3, 9); }
61ST_IN HReg hregX86_FAKE4 ( void ) { return mkHReg(False, HRcFlt64, 4, 10); }
62ST_IN HReg hregX86_FAKE5 ( void ) { return mkHReg(False, HRcFlt64, 5, 11); }
63
64ST_IN HReg hregX86_XMM0 ( void ) { return mkHReg(False, HRcVec128, 0, 12); }
65ST_IN HReg hregX86_XMM1 ( void ) { return mkHReg(False, HRcVec128, 1, 13); }
66ST_IN HReg hregX86_XMM2 ( void ) { return mkHReg(False, HRcVec128, 2, 14); }
67ST_IN HReg hregX86_XMM3 ( void ) { return mkHReg(False, HRcVec128, 3, 15); }
68ST_IN HReg hregX86_XMM4 ( void ) { return mkHReg(False, HRcVec128, 4, 16); }
69ST_IN HReg hregX86_XMM5 ( void ) { return mkHReg(False, HRcVec128, 5, 17); }
70ST_IN HReg hregX86_XMM6 ( void ) { return mkHReg(False, HRcVec128, 6, 18); }
71ST_IN HReg hregX86_XMM7 ( void ) { return mkHReg(False, HRcVec128, 7, 19); }
72
73ST_IN HReg hregX86_ESP ( void ) { return mkHReg(False, HRcInt32, 4, 20); }
74ST_IN HReg hregX86_EBP ( void ) { return mkHReg(False, HRcInt32, 5, 21); }
75#undef ST_IN
76
sewardj35421a32004-07-05 13:12:34 +000077extern void ppHRegX86 ( HReg );
sewardjc97096c2004-06-30 09:28:04 +000078
79
sewardj443cd9d2004-07-18 23:06:45 +000080/* --------- Condition codes, Intel encoding. --------- */
81
82typedef
83 enum {
84 Xcc_O = 0, /* overflow */
85 Xcc_NO = 1, /* no overflow */
86
87 Xcc_B = 2, /* below */
88 Xcc_NB = 3, /* not below */
89
90 Xcc_Z = 4, /* zero */
91 Xcc_NZ = 5, /* not zero */
92
93 Xcc_BE = 6, /* below or equal */
94 Xcc_NBE = 7, /* not below or equal */
95
96 Xcc_S = 8, /* negative */
97 Xcc_NS = 9, /* not negative */
98
99 Xcc_P = 10, /* parity even */
100 Xcc_NP = 11, /* not parity even */
101
102 Xcc_L = 12, /* jump less */
103 Xcc_NL = 13, /* not less */
104
105 Xcc_LE = 14, /* less or equal */
106 Xcc_NLE = 15, /* not less or equal */
107
108 Xcc_ALWAYS = 16 /* the usual hack */
109 }
110 X86CondCode;
111
florian55085f82012-11-21 00:36:55 +0000112extern const HChar* showX86CondCode ( X86CondCode );
sewardj443cd9d2004-07-18 23:06:45 +0000113
114
sewardjc97096c2004-06-30 09:28:04 +0000115/* --------- Memory address expressions (amodes). --------- */
116
117typedef
118 enum {
sewardj66f2f792004-06-30 16:37:16 +0000119 Xam_IR, /* Immediate + Reg */
120 Xam_IRRS /* Immediate + Reg1 + (Reg2 << Shift) */
sewardjc97096c2004-06-30 09:28:04 +0000121 }
122 X86AModeTag;
123
124typedef
125 struct {
126 X86AModeTag tag;
127 union {
128 struct {
129 UInt imm;
130 HReg reg;
131 } IR;
132 struct {
133 UInt imm;
134 HReg base;
135 HReg index;
136 Int shift; /* 0, 1, 2 or 3 only */
137 } IRRS;
138 } Xam;
139 }
140 X86AMode;
141
142extern X86AMode* X86AMode_IR ( UInt, HReg );
143extern X86AMode* X86AMode_IRRS ( UInt, HReg, HReg, Int );
144
sewardj218e29f2004-11-07 18:45:15 +0000145extern X86AMode* dopyX86AMode ( X86AMode* );
146
sewardj35421a32004-07-05 13:12:34 +0000147extern void ppX86AMode ( X86AMode* );
sewardjc97096c2004-06-30 09:28:04 +0000148
149
sewardj66f2f792004-06-30 16:37:16 +0000150/* --------- Operand, which can be reg, immediate or memory. --------- */
sewardjc97096c2004-06-30 09:28:04 +0000151
152typedef
153 enum {
sewardj66f2f792004-06-30 16:37:16 +0000154 Xrmi_Imm,
155 Xrmi_Reg,
156 Xrmi_Mem
sewardjc97096c2004-06-30 09:28:04 +0000157 }
sewardj66f2f792004-06-30 16:37:16 +0000158 X86RMITag;
sewardjc97096c2004-06-30 09:28:04 +0000159
160typedef
161 struct {
sewardj66f2f792004-06-30 16:37:16 +0000162 X86RMITag tag;
sewardjc97096c2004-06-30 09:28:04 +0000163 union {
164 struct {
165 UInt imm32;
166 } Imm;
167 struct {
168 HReg reg;
169 } Reg;
170 struct {
171 X86AMode* am;
172 } Mem;
173 }
sewardj66f2f792004-06-30 16:37:16 +0000174 Xrmi;
sewardjc97096c2004-06-30 09:28:04 +0000175 }
sewardj66f2f792004-06-30 16:37:16 +0000176 X86RMI;
sewardjc97096c2004-06-30 09:28:04 +0000177
sewardj66f2f792004-06-30 16:37:16 +0000178extern X86RMI* X86RMI_Imm ( UInt );
179extern X86RMI* X86RMI_Reg ( HReg );
180extern X86RMI* X86RMI_Mem ( X86AMode* );
sewardjc97096c2004-06-30 09:28:04 +0000181
sewardj35421a32004-07-05 13:12:34 +0000182extern void ppX86RMI ( X86RMI* );
sewardj66f2f792004-06-30 16:37:16 +0000183
184
185/* --------- Operand, which can be reg or immediate only. --------- */
186
187typedef
188 enum {
189 Xri_Imm,
190 Xri_Reg
191 }
192 X86RITag;
193
194typedef
195 struct {
196 X86RITag tag;
197 union {
198 struct {
199 UInt imm32;
200 } Imm;
201 struct {
202 HReg reg;
203 } Reg;
204 }
205 Xri;
206 }
207 X86RI;
208
209extern X86RI* X86RI_Imm ( UInt );
210extern X86RI* X86RI_Reg ( HReg );
211
sewardj35421a32004-07-05 13:12:34 +0000212extern void ppX86RI ( X86RI* );
sewardj66f2f792004-06-30 16:37:16 +0000213
214
215/* --------- Operand, which can be reg or memory only. --------- */
216
217typedef
218 enum {
219 Xrm_Reg,
220 Xrm_Mem
221 }
222 X86RMTag;
223
224typedef
225 struct {
226 X86RMTag tag;
227 union {
228 struct {
229 HReg reg;
230 } Reg;
231 struct {
232 X86AMode* am;
233 } Mem;
234 }
235 Xrm;
236 }
237 X86RM;
238
239extern X86RM* X86RM_Reg ( HReg );
240extern X86RM* X86RM_Mem ( X86AMode* );
241
sewardj35421a32004-07-05 13:12:34 +0000242extern void ppX86RM ( X86RM* );
sewardjc97096c2004-06-30 09:28:04 +0000243
244
245/* --------- Instructions. --------- */
246
sewardj66f2f792004-06-30 16:37:16 +0000247/* --------- */
sewardj60f4e3c2004-07-19 01:56:50 +0000248typedef
249 enum {
sewardj358b7d42004-11-08 18:54:50 +0000250 Xun_NEG,
251 Xun_NOT
sewardj60f4e3c2004-07-19 01:56:50 +0000252 }
253 X86UnaryOp;
254
florian55085f82012-11-21 00:36:55 +0000255extern const HChar* showX86UnaryOp ( X86UnaryOp );
sewardj60f4e3c2004-07-19 01:56:50 +0000256
257
258/* --------- */
sewardjc97096c2004-06-30 09:28:04 +0000259typedef
sewardje8e9d732004-07-16 21:03:45 +0000260 enum {
261 Xalu_INVALID,
sewardj66f2f792004-06-30 16:37:16 +0000262 Xalu_MOV,
sewardj4042c7e2004-07-18 01:28:30 +0000263 Xalu_CMP,
sewardj66f2f792004-06-30 16:37:16 +0000264 Xalu_ADD, Xalu_SUB, Xalu_ADC, Xalu_SBB,
sewardj60f4e3c2004-07-19 01:56:50 +0000265 Xalu_AND, Xalu_OR, Xalu_XOR,
266 Xalu_MUL
sewardj66f2f792004-06-30 16:37:16 +0000267 }
sewardjc97096c2004-06-30 09:28:04 +0000268 X86AluOp;
269
florian55085f82012-11-21 00:36:55 +0000270extern const HChar* showX86AluOp ( X86AluOp );
sewardjc97096c2004-06-30 09:28:04 +0000271
272
sewardj66f2f792004-06-30 16:37:16 +0000273/* --------- */
sewardjc97096c2004-06-30 09:28:04 +0000274typedef
275 enum {
sewardje8e9d732004-07-16 21:03:45 +0000276 Xsh_INVALID,
sewardjdf530452005-02-02 03:10:01 +0000277 Xsh_SHL, Xsh_SHR, Xsh_SAR
sewardj66f2f792004-06-30 16:37:16 +0000278 }
279 X86ShiftOp;
280
florian55085f82012-11-21 00:36:55 +0000281extern const HChar* showX86ShiftOp ( X86ShiftOp );
sewardj66f2f792004-06-30 16:37:16 +0000282
283
284/* --------- */
285typedef
286 enum {
sewardjbb53f8c2004-08-14 11:50:01 +0000287 Xfp_INVALID,
288 /* Binary */
sewardj46de4072004-09-11 19:23:24 +0000289 Xfp_ADD, Xfp_SUB, Xfp_MUL, Xfp_DIV,
sewardj442d0be2004-10-15 22:57:13 +0000290 Xfp_SCALE, Xfp_ATAN, Xfp_YL2X, Xfp_YL2XP1, Xfp_PREM, Xfp_PREM1,
sewardjbb53f8c2004-08-14 11:50:01 +0000291 /* Unary */
sewardj99016a72004-10-15 22:09:17 +0000292 Xfp_SQRT, Xfp_ABS, Xfp_NEG, Xfp_MOV, Xfp_SIN, Xfp_COS, Xfp_TAN,
sewardj06c32a02004-09-12 12:07:34 +0000293 Xfp_ROUND, Xfp_2XM1
sewardjd1725d12004-08-12 20:46:53 +0000294 }
295 X86FpOp;
296
florian55085f82012-11-21 00:36:55 +0000297extern const HChar* showX86FpOp ( X86FpOp );
sewardjd08f2d72004-12-01 23:19:36 +0000298
299
300/* --------- */
301typedef
302 enum {
303 Xsse_INVALID,
sewardj164f9272004-12-09 00:39:32 +0000304 /* mov */
305 Xsse_MOV,
306 /* Floating point binary */
sewardj176a59c2004-12-03 20:08:31 +0000307 Xsse_ADDF, Xsse_SUBF, Xsse_MULF, Xsse_DIVF,
308 Xsse_MAXF, Xsse_MINF,
sewardj164f9272004-12-09 00:39:32 +0000309 Xsse_CMPEQF, Xsse_CMPLTF, Xsse_CMPLEF, Xsse_CMPUNF,
310 /* Floating point unary */
sewardjc1e7dfc2004-12-05 19:29:45 +0000311 Xsse_RCPF, Xsse_RSQRTF, Xsse_SQRTF,
sewardj164f9272004-12-09 00:39:32 +0000312 /* Bitwise */
313 Xsse_AND, Xsse_OR, Xsse_XOR, Xsse_ANDN,
314 /* Integer binary */
315 Xsse_ADD8, Xsse_ADD16, Xsse_ADD32, Xsse_ADD64,
316 Xsse_QADD8U, Xsse_QADD16U,
317 Xsse_QADD8S, Xsse_QADD16S,
318 Xsse_SUB8, Xsse_SUB16, Xsse_SUB32, Xsse_SUB64,
319 Xsse_QSUB8U, Xsse_QSUB16U,
320 Xsse_QSUB8S, Xsse_QSUB16S,
321 Xsse_MUL16,
322 Xsse_MULHI16U,
323 Xsse_MULHI16S,
324 Xsse_AVG8U, Xsse_AVG16U,
325 Xsse_MAX16S,
326 Xsse_MAX8U,
327 Xsse_MIN16S,
328 Xsse_MIN8U,
329 Xsse_CMPEQ8, Xsse_CMPEQ16, Xsse_CMPEQ32,
330 Xsse_CMPGT8S, Xsse_CMPGT16S, Xsse_CMPGT32S,
331 Xsse_SHL16, Xsse_SHL32, Xsse_SHL64,
332 Xsse_SHR16, Xsse_SHR32, Xsse_SHR64,
333 Xsse_SAR16, Xsse_SAR32,
sewardj9e203592004-12-10 01:48:18 +0000334 Xsse_PACKSSD, Xsse_PACKSSW, Xsse_PACKUSW,
335 Xsse_UNPCKHB, Xsse_UNPCKHW, Xsse_UNPCKHD, Xsse_UNPCKHQ,
336 Xsse_UNPCKLB, Xsse_UNPCKLW, Xsse_UNPCKLD, Xsse_UNPCKLQ
sewardjd08f2d72004-12-01 23:19:36 +0000337 }
338 X86SseOp;
339
florian55085f82012-11-21 00:36:55 +0000340extern const HChar* showX86SseOp ( X86SseOp );
sewardjd1725d12004-08-12 20:46:53 +0000341
342
343/* --------- */
344typedef
345 enum {
sewardj66f2f792004-06-30 16:37:16 +0000346 Xin_Alu32R, /* 32-bit mov/arith/logical, dst=REG */
347 Xin_Alu32M, /* 32-bit mov/arith/logical, dst=MEM */
sewardjeba63f82005-02-23 13:31:25 +0000348 Xin_Sh32, /* 32-bit shift/rotate, dst=REG */
sewardjfb7373a2007-08-25 21:29:03 +0000349 Xin_Test32, /* 32-bit test of REG or MEM against imm32 (AND, set
sewardjeba63f82005-02-23 13:31:25 +0000350 flags, discard result) */
sewardj60f4e3c2004-07-19 01:56:50 +0000351 Xin_Unary32, /* 32-bit not and neg */
sewardj79e04f82007-03-31 14:30:12 +0000352 Xin_Lea32, /* 32-bit compute EA into a reg */
sewardjeba63f82005-02-23 13:31:25 +0000353 Xin_MulL, /* 32 x 32 -> 64 multiply */
354 Xin_Div, /* 64/32 -> (32,32) div and mod */
sewardj5c34dc92004-07-19 12:48:11 +0000355 Xin_Sh3232, /* shldl or shrdl */
sewardje8e9d732004-07-16 21:03:45 +0000356 Xin_Push, /* push (32-bit?) value on stack */
357 Xin_Call, /* call to address in register */
sewardjc6f970f2012-04-02 21:54:49 +0000358 Xin_XDirect, /* direct transfer to GA */
359 Xin_XIndir, /* indirect transfer to GA */
360 Xin_XAssisted, /* assisted transfer to GA */
sewardj5c34dc92004-07-19 12:48:11 +0000361 Xin_CMov32, /* conditional move */
sewardj443cd9d2004-07-18 23:06:45 +0000362 Xin_LoadEX, /* mov{s,z}{b,w}l from mem to reg */
sewardjd1725d12004-08-12 20:46:53 +0000363 Xin_Store, /* store 16/8 bit value in memory */
sewardjd7cb8532004-08-17 23:59:23 +0000364 Xin_Set32, /* convert condition code to 32-bit value */
sewardjce646f22004-08-31 23:55:54 +0000365 Xin_Bsfr32, /* 32-bit bsf/bsr */
mjw6c65c122013-08-27 10:19:03 +0000366 Xin_MFence, /* mem fence (not just sse2, but sse0 and 1/mmxext too) */
sewardje9d8a262009-07-01 08:06:34 +0000367 Xin_ACAS, /* 8/16/32-bit lock;cmpxchg */
368 Xin_DACAS, /* lock;cmpxchg8b (doubleword ACAS, 2 x 32-bit only) */
sewardjd08f2d72004-12-01 23:19:36 +0000369
sewardjd1725d12004-08-12 20:46:53 +0000370 Xin_FpUnary, /* FP fake unary op */
371 Xin_FpBinary, /* FP fake binary op */
372 Xin_FpLdSt, /* FP fake load/store */
sewardj89cd0932004-09-08 18:23:25 +0000373 Xin_FpLdStI, /* FP fake load/store, converting to/from Int */
sewardj3bca9062004-12-04 14:36:09 +0000374 Xin_Fp64to32, /* FP round IEEE754 double to IEEE754 single */
sewardjb9fa69b2004-12-09 23:25:14 +0000375 Xin_FpCMov, /* FP fake floating point conditional move */
sewardjeba63f82005-02-23 13:31:25 +0000376 Xin_FpLdCW, /* fldcw */
sewardj46de4072004-09-11 19:23:24 +0000377 Xin_FpStSW_AX, /* fstsw %ax */
sewardjd08f2d72004-12-01 23:19:36 +0000378 Xin_FpCmp, /* FP compare, generating a C320 value into int reg */
379
sewardj1e6ad742004-12-02 16:16:11 +0000380 Xin_SseConst, /* Generate restricted SSE literal */
sewardjd08f2d72004-12-01 23:19:36 +0000381 Xin_SseLdSt, /* SSE load/store, no alignment constraints */
sewardj129b3d92004-12-05 15:42:05 +0000382 Xin_SseLdzLO, /* SSE load low 32/64 bits, zero remainder of reg */
sewardjd08f2d72004-12-01 23:19:36 +0000383 Xin_Sse32Fx4, /* SSE binary, 32Fx4 */
sewardj636ad762004-12-07 11:16:04 +0000384 Xin_Sse32FLo, /* SSE binary, 32F in lowest lane only */
385 Xin_Sse64Fx2, /* SSE binary, 64Fx2 */
sewardj164f9272004-12-09 00:39:32 +0000386 Xin_Sse64FLo, /* SSE binary, 64F in lowest lane only */
sewardjb9fa69b2004-12-09 23:25:14 +0000387 Xin_SseReRg, /* SSE binary general reg-reg, Re, Rg */
sewardj109ffdb2004-12-10 21:45:38 +0000388 Xin_SseCMov, /* SSE conditional move */
sewardjc6f970f2012-04-02 21:54:49 +0000389 Xin_SseShuf, /* SSE2 shuffle (pshufd) */
390 Xin_EvCheck, /* Event check */
391 Xin_ProfInc /* 64-bit profile counter increment */
sewardjc97096c2004-06-30 09:28:04 +0000392 }
393 X86InstrTag;
394
sewardjd1725d12004-08-12 20:46:53 +0000395/* Destinations are on the RIGHT (second operand) */
sewardjc97096c2004-06-30 09:28:04 +0000396
397typedef
398 struct {
399 X86InstrTag tag;
400 union {
sewardjc97096c2004-06-30 09:28:04 +0000401 struct {
sewardj66f2f792004-06-30 16:37:16 +0000402 X86AluOp op;
403 X86RMI* src;
404 HReg dst;
405 } Alu32R;
sewardjc97096c2004-06-30 09:28:04 +0000406 struct {
sewardj66f2f792004-06-30 16:37:16 +0000407 X86AluOp op;
408 X86RI* src;
409 X86AMode* dst;
410 } Alu32M;
sewardje8c922f2004-07-23 01:34:11 +0000411 struct {
412 X86ShiftOp op;
sewardjeba63f82005-02-23 13:31:25 +0000413 UInt src; /* shift amount, or 0 means %cl */
414 HReg dst;
sewardje8c922f2004-07-23 01:34:11 +0000415 } Sh32;
416 struct {
sewardjfb7373a2007-08-25 21:29:03 +0000417 UInt imm32;
418 X86RM* dst; /* not written, only read */
sewardje8c922f2004-07-23 01:34:11 +0000419 } Test32;
sewardj60f4e3c2004-07-19 01:56:50 +0000420 /* Not and Neg */
sewardjc97096c2004-06-30 09:28:04 +0000421 struct {
sewardj60f4e3c2004-07-19 01:56:50 +0000422 X86UnaryOp op;
sewardjeba63f82005-02-23 13:31:25 +0000423 HReg dst;
sewardj60f4e3c2004-07-19 01:56:50 +0000424 } Unary32;
sewardj79e04f82007-03-31 14:30:12 +0000425 /* 32-bit compute EA into a reg */
426 struct {
427 X86AMode* am;
428 HReg dst;
429 } Lea32;
sewardjeba63f82005-02-23 13:31:25 +0000430 /* EDX:EAX = EAX *s/u r/m32 */
sewardj60f4e3c2004-07-19 01:56:50 +0000431 struct {
sewardjeba63f82005-02-23 13:31:25 +0000432 Bool syned;
433 X86RM* src;
sewardj60f4e3c2004-07-19 01:56:50 +0000434 } MulL;
sewardj1f40a0a2004-07-21 12:28:07 +0000435 /* x86 div/idiv instruction. Modifies EDX and EAX and reads src. */
sewardj5c34dc92004-07-19 12:48:11 +0000436 struct {
sewardjeba63f82005-02-23 13:31:25 +0000437 Bool syned;
438 X86RM* src;
sewardj5c34dc92004-07-19 12:48:11 +0000439 } Div;
sewardj5c34dc92004-07-19 12:48:11 +0000440 /* shld/shrd. op may only be Xsh_SHL or Xsh_SHR */
441 struct {
442 X86ShiftOp op;
sewardje8c922f2004-07-23 01:34:11 +0000443 UInt amt; /* shift amount, or 0 means %cl */
sewardje5f384c2004-07-30 16:17:28 +0000444 HReg src;
445 HReg dst;
sewardj5c34dc92004-07-19 12:48:11 +0000446 } Sh3232;
sewardje8e9d732004-07-16 21:03:45 +0000447 struct {
448 X86RMI* src;
449 } Push;
sewardj4b861de2004-11-03 15:24:42 +0000450 /* Pseudo-insn. Call target (an absolute address), on given
451 condition (which could be Xcc_ALWAYS). */
sewardje8e9d732004-07-16 21:03:45 +0000452 struct {
sewardj4b861de2004-11-03 15:24:42 +0000453 X86CondCode cond;
454 Addr32 target;
455 Int regparms; /* 0 .. 3 */
sewardjcfe046e2013-01-17 14:23:53 +0000456 RetLoc rloc; /* where the return value will be */
sewardje8e9d732004-07-16 21:03:45 +0000457 } Call;
sewardjc6f970f2012-04-02 21:54:49 +0000458 /* Update the guest EIP value, then exit requesting to chain
459 to it. May be conditional. Urr, use of Addr32 implicitly
460 assumes that wordsize(guest) == wordsize(host). */
sewardje8e9d732004-07-16 21:03:45 +0000461 struct {
sewardjc6f970f2012-04-02 21:54:49 +0000462 Addr32 dstGA; /* next guest address */
463 X86AMode* amEIP; /* amode in guest state for EIP */
464 X86CondCode cond; /* can be Xcc_ALWAYS */
465 Bool toFastEP; /* chain to the slow or fast point? */
466 } XDirect;
467 /* Boring transfer to a guest address not known at JIT time.
468 Not chainable. May be conditional. */
469 struct {
470 HReg dstGA;
471 X86AMode* amEIP;
472 X86CondCode cond; /* can be Xcc_ALWAYS */
473 } XIndir;
474 /* Assisted transfer to a guest address, most general case.
475 Not chainable. May be conditional. */
476 struct {
477 HReg dstGA;
478 X86AMode* amEIP;
479 X86CondCode cond; /* can be Xcc_ALWAYS */
sewardj750f4072004-07-26 22:39:11 +0000480 IRJumpKind jk;
sewardjc6f970f2012-04-02 21:54:49 +0000481 } XAssisted;
sewardj5c34dc92004-07-19 12:48:11 +0000482 /* Mov src to dst on the given condition, which may not
483 be the bogus Xcc_ALWAYS. */
sewardj4042c7e2004-07-18 01:28:30 +0000484 struct {
sewardj5c34dc92004-07-19 12:48:11 +0000485 X86CondCode cond;
sewardje8c922f2004-07-23 01:34:11 +0000486 X86RM* src;
487 HReg dst;
sewardj5c34dc92004-07-19 12:48:11 +0000488 } CMov32;
sewardj4042c7e2004-07-18 01:28:30 +0000489 /* Sign/Zero extending loads. Dst size is always 32 bits. */
490 struct {
491 UChar szSmall;
492 Bool syned;
493 X86AMode* src;
494 HReg dst;
495 } LoadEX;
sewardj443cd9d2004-07-18 23:06:45 +0000496 /* 16/8 bit stores, which are troublesome (particularly
497 8-bit) */
498 struct {
sewardje8c922f2004-07-23 01:34:11 +0000499 UChar sz; /* only 1 or 2 */
500 HReg src;
sewardj443cd9d2004-07-18 23:06:45 +0000501 X86AMode* dst;
502 } Store;
sewardjd7cb8532004-08-17 23:59:23 +0000503 /* Convert a x86 condition code to a 32-bit value (0 or 1). */
504 struct {
505 X86CondCode cond;
506 HReg dst;
507 } Set32;
sewardjce646f22004-08-31 23:55:54 +0000508 /* 32-bit bsf or bsr. */
509 struct {
510 Bool isFwds;
511 HReg src;
512 HReg dst;
513 } Bsfr32;
mjw6c65c122013-08-27 10:19:03 +0000514 /* Mem fence (not just sse2, but sse0 and sse1/mmxext too).
515 In short, an insn which flushes all preceding loads and
516 stores as much as possible before continuing. On SSE2
517 we emit a real "mfence", on SSE1 or the MMXEXT subset
518 "sfence ; lock addl $0,0(%esp)" and on SSE0
519 "lock addl $0,0(%esp)". This insn therefore carries the
520 host's hwcaps so the assembler knows what to emit. */
sewardj3e838932005-01-07 12:09:15 +0000521 struct {
sewardj5117ce12006-01-27 21:20:15 +0000522 UInt hwcaps;
sewardj3e838932005-01-07 12:09:15 +0000523 } MFence;
sewardje9d8a262009-07-01 08:06:34 +0000524 /* "lock;cmpxchg": mem address in .addr,
525 expected value in %eax, new value in %ebx */
526 struct {
527 X86AMode* addr;
528 UChar sz; /* 1, 2 or 4 */
529 } ACAS;
530 /* "lock;cmpxchg8b": mem address in .addr, expected value in
531 %edx:%eax, new value in %ecx:%ebx */
532 struct {
533 X86AMode* addr;
534 } DACAS;
sewardjd08f2d72004-12-01 23:19:36 +0000535
sewardjd1725d12004-08-12 20:46:53 +0000536 /* X86 Floating point (fake 3-operand, "flat reg file" insns) */
537 struct {
538 X86FpOp op;
539 HReg src;
540 HReg dst;
541 } FpUnary;
542 struct {
543 X86FpOp op;
544 HReg srcL;
545 HReg srcR;
546 HReg dst;
547 } FpBinary;
548 struct {
549 Bool isLoad;
550 UChar sz; /* only 4 (IEEE single) or 8 (IEEE double) */
551 HReg reg;
552 X86AMode* addr;
553 } FpLdSt;
sewardj89cd0932004-09-08 18:23:25 +0000554 /* Move 64-bit float to/from memory, converting to/from
sewardj3bca9062004-12-04 14:36:09 +0000555 signed int on the way. Note the conversions will observe
556 the host FPU rounding mode currently in force. */
sewardjd1725d12004-08-12 20:46:53 +0000557 struct {
sewardj89cd0932004-09-08 18:23:25 +0000558 Bool isLoad;
559 UChar sz; /* only 2, 4 or 8 */
560 HReg reg;
561 X86AMode* addr;
562 } FpLdStI;
sewardj3bca9062004-12-04 14:36:09 +0000563 /* By observing the current FPU rounding mode, round (etc)
564 src into dst given that dst should be interpreted as an
565 IEEE754 32-bit (float) type. */
566 struct {
567 HReg src;
568 HReg dst;
569 } Fp64to32;
sewardj33124f62004-08-30 17:54:18 +0000570 /* Mov src to dst on the given condition, which may not
571 be the bogus Xcc_ALWAYS. */
572 struct {
573 X86CondCode cond;
574 HReg src;
575 HReg dst;
576 } FpCMov;
sewardjeba63f82005-02-23 13:31:25 +0000577 /* Load the FPU's 16-bit control word (fldcw) */
sewardj8f3debf2004-09-08 23:42:23 +0000578 struct {
sewardj8f3debf2004-09-08 23:42:23 +0000579 X86AMode* addr;
580 }
sewardjeba63f82005-02-23 13:31:25 +0000581 FpLdCW;
sewardj46de4072004-09-11 19:23:24 +0000582 /* fstsw %ax */
583 struct {
584 /* no fields */
585 }
586 FpStSW_AX;
sewardjbdc7d212004-09-09 02:46:40 +0000587 /* Do a compare, generating the C320 bits into the dst. */
588 struct {
589 HReg srcL;
590 HReg srcR;
591 HReg dst;
592 } FpCmp;
sewardjd08f2d72004-12-01 23:19:36 +0000593
594 /* Simplistic SSE[123] */
595 struct {
sewardj1e6ad742004-12-02 16:16:11 +0000596 UShort con;
597 HReg dst;
598 } SseConst;
599 struct {
sewardjd08f2d72004-12-01 23:19:36 +0000600 Bool isLoad;
601 HReg reg;
602 X86AMode* addr;
603 } SseLdSt;
604 struct {
sewardjeba63f82005-02-23 13:31:25 +0000605 UChar sz; /* 4 or 8 only */
sewardj129b3d92004-12-05 15:42:05 +0000606 HReg reg;
607 X86AMode* addr;
608 } SseLdzLO;
609 struct {
sewardjd08f2d72004-12-01 23:19:36 +0000610 X86SseOp op;
611 HReg src;
612 HReg dst;
613 } Sse32Fx4;
614 struct {
615 X86SseOp op;
616 HReg src;
617 HReg dst;
618 } Sse32FLo;
sewardj636ad762004-12-07 11:16:04 +0000619 struct {
620 X86SseOp op;
621 HReg src;
622 HReg dst;
623 } Sse64Fx2;
624 struct {
625 X86SseOp op;
626 HReg src;
627 HReg dst;
628 } Sse64FLo;
sewardj164f9272004-12-09 00:39:32 +0000629 struct {
630 X86SseOp op;
631 HReg src;
632 HReg dst;
633 } SseReRg;
sewardjb9fa69b2004-12-09 23:25:14 +0000634 /* Mov src to dst on the given condition, which may not
635 be the bogus Xcc_ALWAYS. */
636 struct {
637 X86CondCode cond;
638 HReg src;
639 HReg dst;
640 } SseCMov;
sewardj109ffdb2004-12-10 21:45:38 +0000641 struct {
642 Int order; /* 0 <= order <= 0xFF */
643 HReg src;
644 HReg dst;
645 } SseShuf;
sewardjc6f970f2012-04-02 21:54:49 +0000646 struct {
647 X86AMode* amCounter;
648 X86AMode* amFailAddr;
649 } EvCheck;
650 struct {
651 /* No fields. The address of the counter to inc is
652 installed later, post-translation, by patching it in,
653 as it is not known at translation time. */
654 } ProfInc;
sewardjd08f2d72004-12-01 23:19:36 +0000655
sewardj33124f62004-08-30 17:54:18 +0000656 } Xin;
sewardjc97096c2004-06-30 09:28:04 +0000657 }
658 X86Instr;
659
sewardj46de4072004-09-11 19:23:24 +0000660extern X86Instr* X86Instr_Alu32R ( X86AluOp, X86RMI*, HReg );
661extern X86Instr* X86Instr_Alu32M ( X86AluOp, X86RI*, X86AMode* );
sewardjeba63f82005-02-23 13:31:25 +0000662extern X86Instr* X86Instr_Unary32 ( X86UnaryOp op, HReg dst );
sewardj79e04f82007-03-31 14:30:12 +0000663extern X86Instr* X86Instr_Lea32 ( X86AMode* am, HReg dst );
664
sewardjeba63f82005-02-23 13:31:25 +0000665extern X86Instr* X86Instr_Sh32 ( X86ShiftOp, UInt, HReg );
sewardjfb7373a2007-08-25 21:29:03 +0000666extern X86Instr* X86Instr_Test32 ( UInt imm32, X86RM* dst );
sewardjeba63f82005-02-23 13:31:25 +0000667extern X86Instr* X86Instr_MulL ( Bool syned, X86RM* );
668extern X86Instr* X86Instr_Div ( Bool syned, X86RM* );
sewardj46de4072004-09-11 19:23:24 +0000669extern X86Instr* X86Instr_Sh3232 ( X86ShiftOp, UInt amt, HReg src, HReg dst );
670extern X86Instr* X86Instr_Push ( X86RMI* );
sewardjcfe046e2013-01-17 14:23:53 +0000671extern X86Instr* X86Instr_Call ( X86CondCode, Addr32, Int, RetLoc );
sewardjc6f970f2012-04-02 21:54:49 +0000672extern X86Instr* X86Instr_XDirect ( Addr32 dstGA, X86AMode* amEIP,
673 X86CondCode cond, Bool toFastEP );
674extern X86Instr* X86Instr_XIndir ( HReg dstGA, X86AMode* amEIP,
675 X86CondCode cond );
676extern X86Instr* X86Instr_XAssisted ( HReg dstGA, X86AMode* amEIP,
677 X86CondCode cond, IRJumpKind jk );
sewardj46de4072004-09-11 19:23:24 +0000678extern X86Instr* X86Instr_CMov32 ( X86CondCode, X86RM* src, HReg dst );
679extern X86Instr* X86Instr_LoadEX ( UChar szSmall, Bool syned,
680 X86AMode* src, HReg dst );
681extern X86Instr* X86Instr_Store ( UChar sz, HReg src, X86AMode* dst );
682extern X86Instr* X86Instr_Set32 ( X86CondCode cond, HReg dst );
683extern X86Instr* X86Instr_Bsfr32 ( Bool isFwds, HReg src, HReg dst );
sewardj5117ce12006-01-27 21:20:15 +0000684extern X86Instr* X86Instr_MFence ( UInt hwcaps );
sewardje9d8a262009-07-01 08:06:34 +0000685extern X86Instr* X86Instr_ACAS ( X86AMode* addr, UChar sz );
686extern X86Instr* X86Instr_DACAS ( X86AMode* addr );
sewardjd08f2d72004-12-01 23:19:36 +0000687
sewardj46de4072004-09-11 19:23:24 +0000688extern X86Instr* X86Instr_FpUnary ( X86FpOp op, HReg src, HReg dst );
689extern X86Instr* X86Instr_FpBinary ( X86FpOp op, HReg srcL, HReg srcR, HReg dst );
690extern X86Instr* X86Instr_FpLdSt ( Bool isLoad, UChar sz, HReg reg, X86AMode* );
691extern X86Instr* X86Instr_FpLdStI ( Bool isLoad, UChar sz, HReg reg, X86AMode* );
sewardj3bca9062004-12-04 14:36:09 +0000692extern X86Instr* X86Instr_Fp64to32 ( HReg src, HReg dst );
sewardj46de4072004-09-11 19:23:24 +0000693extern X86Instr* X86Instr_FpCMov ( X86CondCode, HReg src, HReg dst );
sewardjeba63f82005-02-23 13:31:25 +0000694extern X86Instr* X86Instr_FpLdCW ( X86AMode* );
sewardj46de4072004-09-11 19:23:24 +0000695extern X86Instr* X86Instr_FpStSW_AX ( void );
696extern X86Instr* X86Instr_FpCmp ( HReg srcL, HReg srcR, HReg dst );
sewardj8f3debf2004-09-08 23:42:23 +0000697
sewardj1e6ad742004-12-02 16:16:11 +0000698extern X86Instr* X86Instr_SseConst ( UShort con, HReg dst );
sewardjd08f2d72004-12-01 23:19:36 +0000699extern X86Instr* X86Instr_SseLdSt ( Bool isLoad, HReg, X86AMode* );
sewardj129b3d92004-12-05 15:42:05 +0000700extern X86Instr* X86Instr_SseLdzLO ( Int sz, HReg, X86AMode* );
sewardjd08f2d72004-12-01 23:19:36 +0000701extern X86Instr* X86Instr_Sse32Fx4 ( X86SseOp, HReg, HReg );
702extern X86Instr* X86Instr_Sse32FLo ( X86SseOp, HReg, HReg );
sewardj636ad762004-12-07 11:16:04 +0000703extern X86Instr* X86Instr_Sse64Fx2 ( X86SseOp, HReg, HReg );
704extern X86Instr* X86Instr_Sse64FLo ( X86SseOp, HReg, HReg );
sewardj164f9272004-12-09 00:39:32 +0000705extern X86Instr* X86Instr_SseReRg ( X86SseOp, HReg, HReg );
sewardjb9fa69b2004-12-09 23:25:14 +0000706extern X86Instr* X86Instr_SseCMov ( X86CondCode, HReg src, HReg dst );
sewardj109ffdb2004-12-10 21:45:38 +0000707extern X86Instr* X86Instr_SseShuf ( Int order, HReg src, HReg dst );
sewardjc6f970f2012-04-02 21:54:49 +0000708extern X86Instr* X86Instr_EvCheck ( X86AMode* amCounter,
709 X86AMode* amFailAddr );
710extern X86Instr* X86Instr_ProfInc ( void );
sewardjd08f2d72004-12-01 23:19:36 +0000711
sewardjc97096c2004-06-30 09:28:04 +0000712
floriand8c64e02014-10-08 08:54:44 +0000713extern void ppX86Instr ( const X86Instr*, Bool );
sewardjc97096c2004-06-30 09:28:04 +0000714
sewardjf13a16a2004-07-05 17:10:14 +0000715/* Some functions that insulate the register allocator from details
sewardj194d54a2004-07-03 19:08:18 +0000716 of the underlying instruction set. */
floriand8c64e02014-10-08 08:54:44 +0000717extern void getRegUsage_X86Instr ( HRegUsage*, const X86Instr*, Bool );
cerion92b64362005-12-13 12:02:26 +0000718extern void mapRegs_X86Instr ( HRegRemap*, X86Instr*, Bool );
floriand8c64e02014-10-08 08:54:44 +0000719extern Bool isMove_X86Instr ( const X86Instr*, HReg*, HReg* );
florian8462d112014-09-24 15:18:09 +0000720extern Int emit_X86Instr ( /*MB_MOD*/Bool* is_profInc,
floriand8c64e02014-10-08 08:54:44 +0000721 UChar* buf, Int nbuf, const X86Instr* i,
florian8462d112014-09-24 15:18:09 +0000722 Bool mode64,
723 VexEndness endness_host,
724 const void* disp_cp_chain_me_to_slowEP,
725 const void* disp_cp_chain_me_to_fastEP,
726 const void* disp_cp_xindir,
727 const void* disp_cp_xassisted );
sewardj2a1ed8e2009-12-31 19:26:03 +0000728
729extern void genSpill_X86 ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
730 HReg rreg, Int offset, Bool );
731extern void genReload_X86 ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
732 HReg rreg, Int offset, Bool );
733
sewardja5b50222015-03-26 07:18:32 +0000734extern X86Instr* directReload_X86 ( X86Instr* i, HReg vreg, Short spill_off );
735
736extern const RRegUniverse* getRRegUniverse_X86 ( void );
737
floriancacba8e2014-12-15 18:58:07 +0000738extern HInstrArray* iselSB_X86 ( const IRSB*,
sewardjc6f970f2012-04-02 21:54:49 +0000739 VexArch,
floriand8c64e02014-10-08 08:54:44 +0000740 const VexArchInfo*,
741 const VexAbiInfo*,
sewardjc6f970f2012-04-02 21:54:49 +0000742 Int offs_Host_EvC_Counter,
743 Int offs_Host_EvC_FailAddr,
744 Bool chainingAllowed,
745 Bool addProfInc,
floriandcd6d232015-01-02 17:32:21 +0000746 Addr max_ga );
sewardjc6f970f2012-04-02 21:54:49 +0000747
748/* How big is an event check? This is kind of a kludge because it
749 depends on the offsets of host_EvC_FAILADDR and host_EvC_COUNTER,
750 and so assumes that they are both <= 128, and so can use the short
751 offset encoding. This is all checked with assertions, so in the
752 worst case we will merely assert at startup. */
florian7ce2cc82015-01-10 16:10:58 +0000753extern Int evCheckSzB_X86 (void);
sewardjc6f970f2012-04-02 21:54:49 +0000754
755/* Perform a chaining and unchaining of an XDirect jump. */
sewardj9b769162014-07-24 12:42:03 +0000756extern VexInvalRange chainXDirect_X86 ( VexEndness endness_host,
757 void* place_to_chain,
florian7d6f81d2014-09-22 21:43:37 +0000758 const void* disp_cp_chain_me_EXPECTED,
759 const void* place_to_jump_to );
sewardjc6f970f2012-04-02 21:54:49 +0000760
sewardj9b769162014-07-24 12:42:03 +0000761extern VexInvalRange unchainXDirect_X86 ( VexEndness endness_host,
762 void* place_to_unchain,
florian7d6f81d2014-09-22 21:43:37 +0000763 const void* place_to_jump_to_EXPECTED,
764 const void* disp_cp_chain_me );
sewardjc6f970f2012-04-02 21:54:49 +0000765
766/* Patch the counter location into an existing ProfInc point. */
sewardj9b769162014-07-24 12:42:03 +0000767extern VexInvalRange patchProfInc_X86 ( VexEndness endness_host,
768 void* place_to_patch,
florian7d6f81d2014-09-22 21:43:37 +0000769 const ULong* location_of_counter );
sewardjc6f970f2012-04-02 21:54:49 +0000770
sewardj6c77c952004-07-03 14:51:44 +0000771
sewardjcef7d3e2009-07-02 12:21:59 +0000772#endif /* ndef __VEX_HOST_X86_DEFS_H */
sewardj887a11a2004-07-05 17:26:47 +0000773
774/*---------------------------------------------------------------*/
sewardjcef7d3e2009-07-02 12:21:59 +0000775/*--- end host_x86_defs.h ---*/
sewardj887a11a2004-07-05 17:26:47 +0000776/*---------------------------------------------------------------*/