blob: 3d809f4ea926d740a0780fc237682d30b93b3f4f [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
sewardj25e54732012-08-05 15:36:51 +000010 Copyright (C) 2004-2012 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
sewardj35421a32004-07-05 13:12:34 +000049extern void ppHRegX86 ( HReg );
sewardjc97096c2004-06-30 09:28:04 +000050
sewardj53f85a92004-07-02 13:45:17 +000051extern HReg hregX86_EAX ( void );
sewardj2cd80dc2004-07-02 15:20:40 +000052extern HReg hregX86_EBX ( void );
sewardj53f85a92004-07-02 13:45:17 +000053extern HReg hregX86_ECX ( void );
sewardj2cd80dc2004-07-02 15:20:40 +000054extern HReg hregX86_EDX ( void );
sewardjf13a16a2004-07-05 17:10:14 +000055extern HReg hregX86_ESP ( void );
sewardj53f85a92004-07-02 13:45:17 +000056extern HReg hregX86_EBP ( void );
sewardjf13a16a2004-07-05 17:10:14 +000057extern HReg hregX86_ESI ( void );
sewardj887a11a2004-07-05 17:26:47 +000058extern HReg hregX86_EDI ( void );
sewardj53f85a92004-07-02 13:45:17 +000059
sewardj70dff0c2004-11-30 13:37:21 +000060extern HReg hregX86_FAKE0 ( void );
61extern HReg hregX86_FAKE1 ( void );
62extern HReg hregX86_FAKE2 ( void );
63extern HReg hregX86_FAKE3 ( void );
64extern HReg hregX86_FAKE4 ( void );
65extern HReg hregX86_FAKE5 ( void );
66
sewardjd08f2d72004-12-01 23:19:36 +000067extern HReg hregX86_XMM0 ( void );
68extern HReg hregX86_XMM1 ( void );
69extern HReg hregX86_XMM2 ( void );
70extern HReg hregX86_XMM3 ( void );
71extern HReg hregX86_XMM4 ( void );
72extern HReg hregX86_XMM5 ( void );
73extern HReg hregX86_XMM6 ( void );
74extern HReg hregX86_XMM7 ( void );
75
sewardjc97096c2004-06-30 09:28:04 +000076
sewardj443cd9d2004-07-18 23:06:45 +000077/* --------- Condition codes, Intel encoding. --------- */
78
79typedef
80 enum {
81 Xcc_O = 0, /* overflow */
82 Xcc_NO = 1, /* no overflow */
83
84 Xcc_B = 2, /* below */
85 Xcc_NB = 3, /* not below */
86
87 Xcc_Z = 4, /* zero */
88 Xcc_NZ = 5, /* not zero */
89
90 Xcc_BE = 6, /* below or equal */
91 Xcc_NBE = 7, /* not below or equal */
92
93 Xcc_S = 8, /* negative */
94 Xcc_NS = 9, /* not negative */
95
96 Xcc_P = 10, /* parity even */
97 Xcc_NP = 11, /* not parity even */
98
99 Xcc_L = 12, /* jump less */
100 Xcc_NL = 13, /* not less */
101
102 Xcc_LE = 14, /* less or equal */
103 Xcc_NLE = 15, /* not less or equal */
104
105 Xcc_ALWAYS = 16 /* the usual hack */
106 }
107 X86CondCode;
108
florian55085f82012-11-21 00:36:55 +0000109extern const HChar* showX86CondCode ( X86CondCode );
sewardj443cd9d2004-07-18 23:06:45 +0000110
111
sewardjc97096c2004-06-30 09:28:04 +0000112/* --------- Memory address expressions (amodes). --------- */
113
114typedef
115 enum {
sewardj66f2f792004-06-30 16:37:16 +0000116 Xam_IR, /* Immediate + Reg */
117 Xam_IRRS /* Immediate + Reg1 + (Reg2 << Shift) */
sewardjc97096c2004-06-30 09:28:04 +0000118 }
119 X86AModeTag;
120
121typedef
122 struct {
123 X86AModeTag tag;
124 union {
125 struct {
126 UInt imm;
127 HReg reg;
128 } IR;
129 struct {
130 UInt imm;
131 HReg base;
132 HReg index;
133 Int shift; /* 0, 1, 2 or 3 only */
134 } IRRS;
135 } Xam;
136 }
137 X86AMode;
138
139extern X86AMode* X86AMode_IR ( UInt, HReg );
140extern X86AMode* X86AMode_IRRS ( UInt, HReg, HReg, Int );
141
sewardj218e29f2004-11-07 18:45:15 +0000142extern X86AMode* dopyX86AMode ( X86AMode* );
143
sewardj35421a32004-07-05 13:12:34 +0000144extern void ppX86AMode ( X86AMode* );
sewardjc97096c2004-06-30 09:28:04 +0000145
146
sewardj66f2f792004-06-30 16:37:16 +0000147/* --------- Operand, which can be reg, immediate or memory. --------- */
sewardjc97096c2004-06-30 09:28:04 +0000148
149typedef
150 enum {
sewardj66f2f792004-06-30 16:37:16 +0000151 Xrmi_Imm,
152 Xrmi_Reg,
153 Xrmi_Mem
sewardjc97096c2004-06-30 09:28:04 +0000154 }
sewardj66f2f792004-06-30 16:37:16 +0000155 X86RMITag;
sewardjc97096c2004-06-30 09:28:04 +0000156
157typedef
158 struct {
sewardj66f2f792004-06-30 16:37:16 +0000159 X86RMITag tag;
sewardjc97096c2004-06-30 09:28:04 +0000160 union {
161 struct {
162 UInt imm32;
163 } Imm;
164 struct {
165 HReg reg;
166 } Reg;
167 struct {
168 X86AMode* am;
169 } Mem;
170 }
sewardj66f2f792004-06-30 16:37:16 +0000171 Xrmi;
sewardjc97096c2004-06-30 09:28:04 +0000172 }
sewardj66f2f792004-06-30 16:37:16 +0000173 X86RMI;
sewardjc97096c2004-06-30 09:28:04 +0000174
sewardj66f2f792004-06-30 16:37:16 +0000175extern X86RMI* X86RMI_Imm ( UInt );
176extern X86RMI* X86RMI_Reg ( HReg );
177extern X86RMI* X86RMI_Mem ( X86AMode* );
sewardjc97096c2004-06-30 09:28:04 +0000178
sewardj35421a32004-07-05 13:12:34 +0000179extern void ppX86RMI ( X86RMI* );
sewardj66f2f792004-06-30 16:37:16 +0000180
181
182/* --------- Operand, which can be reg or immediate only. --------- */
183
184typedef
185 enum {
186 Xri_Imm,
187 Xri_Reg
188 }
189 X86RITag;
190
191typedef
192 struct {
193 X86RITag tag;
194 union {
195 struct {
196 UInt imm32;
197 } Imm;
198 struct {
199 HReg reg;
200 } Reg;
201 }
202 Xri;
203 }
204 X86RI;
205
206extern X86RI* X86RI_Imm ( UInt );
207extern X86RI* X86RI_Reg ( HReg );
208
sewardj35421a32004-07-05 13:12:34 +0000209extern void ppX86RI ( X86RI* );
sewardj66f2f792004-06-30 16:37:16 +0000210
211
212/* --------- Operand, which can be reg or memory only. --------- */
213
214typedef
215 enum {
216 Xrm_Reg,
217 Xrm_Mem
218 }
219 X86RMTag;
220
221typedef
222 struct {
223 X86RMTag tag;
224 union {
225 struct {
226 HReg reg;
227 } Reg;
228 struct {
229 X86AMode* am;
230 } Mem;
231 }
232 Xrm;
233 }
234 X86RM;
235
236extern X86RM* X86RM_Reg ( HReg );
237extern X86RM* X86RM_Mem ( X86AMode* );
238
sewardj35421a32004-07-05 13:12:34 +0000239extern void ppX86RM ( X86RM* );
sewardjc97096c2004-06-30 09:28:04 +0000240
241
242/* --------- Instructions. --------- */
243
sewardj66f2f792004-06-30 16:37:16 +0000244/* --------- */
sewardj60f4e3c2004-07-19 01:56:50 +0000245typedef
246 enum {
sewardj358b7d42004-11-08 18:54:50 +0000247 Xun_NEG,
248 Xun_NOT
sewardj60f4e3c2004-07-19 01:56:50 +0000249 }
250 X86UnaryOp;
251
florian55085f82012-11-21 00:36:55 +0000252extern const HChar* showX86UnaryOp ( X86UnaryOp );
sewardj60f4e3c2004-07-19 01:56:50 +0000253
254
255/* --------- */
sewardjc97096c2004-06-30 09:28:04 +0000256typedef
sewardje8e9d732004-07-16 21:03:45 +0000257 enum {
258 Xalu_INVALID,
sewardj66f2f792004-06-30 16:37:16 +0000259 Xalu_MOV,
sewardj4042c7e2004-07-18 01:28:30 +0000260 Xalu_CMP,
sewardj66f2f792004-06-30 16:37:16 +0000261 Xalu_ADD, Xalu_SUB, Xalu_ADC, Xalu_SBB,
sewardj60f4e3c2004-07-19 01:56:50 +0000262 Xalu_AND, Xalu_OR, Xalu_XOR,
263 Xalu_MUL
sewardj66f2f792004-06-30 16:37:16 +0000264 }
sewardjc97096c2004-06-30 09:28:04 +0000265 X86AluOp;
266
florian55085f82012-11-21 00:36:55 +0000267extern const HChar* showX86AluOp ( X86AluOp );
sewardjc97096c2004-06-30 09:28:04 +0000268
269
sewardj66f2f792004-06-30 16:37:16 +0000270/* --------- */
sewardjc97096c2004-06-30 09:28:04 +0000271typedef
272 enum {
sewardje8e9d732004-07-16 21:03:45 +0000273 Xsh_INVALID,
sewardjdf530452005-02-02 03:10:01 +0000274 Xsh_SHL, Xsh_SHR, Xsh_SAR
sewardj66f2f792004-06-30 16:37:16 +0000275 }
276 X86ShiftOp;
277
florian55085f82012-11-21 00:36:55 +0000278extern const HChar* showX86ShiftOp ( X86ShiftOp );
sewardj66f2f792004-06-30 16:37:16 +0000279
280
281/* --------- */
282typedef
283 enum {
sewardjbb53f8c2004-08-14 11:50:01 +0000284 Xfp_INVALID,
285 /* Binary */
sewardj46de4072004-09-11 19:23:24 +0000286 Xfp_ADD, Xfp_SUB, Xfp_MUL, Xfp_DIV,
sewardj442d0be2004-10-15 22:57:13 +0000287 Xfp_SCALE, Xfp_ATAN, Xfp_YL2X, Xfp_YL2XP1, Xfp_PREM, Xfp_PREM1,
sewardjbb53f8c2004-08-14 11:50:01 +0000288 /* Unary */
sewardj99016a72004-10-15 22:09:17 +0000289 Xfp_SQRT, Xfp_ABS, Xfp_NEG, Xfp_MOV, Xfp_SIN, Xfp_COS, Xfp_TAN,
sewardj06c32a02004-09-12 12:07:34 +0000290 Xfp_ROUND, Xfp_2XM1
sewardjd1725d12004-08-12 20:46:53 +0000291 }
292 X86FpOp;
293
florian55085f82012-11-21 00:36:55 +0000294extern const HChar* showX86FpOp ( X86FpOp );
sewardjd08f2d72004-12-01 23:19:36 +0000295
296
297/* --------- */
298typedef
299 enum {
300 Xsse_INVALID,
sewardj164f9272004-12-09 00:39:32 +0000301 /* mov */
302 Xsse_MOV,
303 /* Floating point binary */
sewardj176a59c2004-12-03 20:08:31 +0000304 Xsse_ADDF, Xsse_SUBF, Xsse_MULF, Xsse_DIVF,
305 Xsse_MAXF, Xsse_MINF,
sewardj164f9272004-12-09 00:39:32 +0000306 Xsse_CMPEQF, Xsse_CMPLTF, Xsse_CMPLEF, Xsse_CMPUNF,
307 /* Floating point unary */
sewardjc1e7dfc2004-12-05 19:29:45 +0000308 Xsse_RCPF, Xsse_RSQRTF, Xsse_SQRTF,
sewardj164f9272004-12-09 00:39:32 +0000309 /* Bitwise */
310 Xsse_AND, Xsse_OR, Xsse_XOR, Xsse_ANDN,
311 /* Integer binary */
312 Xsse_ADD8, Xsse_ADD16, Xsse_ADD32, Xsse_ADD64,
313 Xsse_QADD8U, Xsse_QADD16U,
314 Xsse_QADD8S, Xsse_QADD16S,
315 Xsse_SUB8, Xsse_SUB16, Xsse_SUB32, Xsse_SUB64,
316 Xsse_QSUB8U, Xsse_QSUB16U,
317 Xsse_QSUB8S, Xsse_QSUB16S,
318 Xsse_MUL16,
319 Xsse_MULHI16U,
320 Xsse_MULHI16S,
321 Xsse_AVG8U, Xsse_AVG16U,
322 Xsse_MAX16S,
323 Xsse_MAX8U,
324 Xsse_MIN16S,
325 Xsse_MIN8U,
326 Xsse_CMPEQ8, Xsse_CMPEQ16, Xsse_CMPEQ32,
327 Xsse_CMPGT8S, Xsse_CMPGT16S, Xsse_CMPGT32S,
328 Xsse_SHL16, Xsse_SHL32, Xsse_SHL64,
329 Xsse_SHR16, Xsse_SHR32, Xsse_SHR64,
330 Xsse_SAR16, Xsse_SAR32,
sewardj9e203592004-12-10 01:48:18 +0000331 Xsse_PACKSSD, Xsse_PACKSSW, Xsse_PACKUSW,
332 Xsse_UNPCKHB, Xsse_UNPCKHW, Xsse_UNPCKHD, Xsse_UNPCKHQ,
333 Xsse_UNPCKLB, Xsse_UNPCKLW, Xsse_UNPCKLD, Xsse_UNPCKLQ
sewardjd08f2d72004-12-01 23:19:36 +0000334 }
335 X86SseOp;
336
florian55085f82012-11-21 00:36:55 +0000337extern const HChar* showX86SseOp ( X86SseOp );
sewardjd1725d12004-08-12 20:46:53 +0000338
339
340/* --------- */
341typedef
342 enum {
sewardj66f2f792004-06-30 16:37:16 +0000343 Xin_Alu32R, /* 32-bit mov/arith/logical, dst=REG */
344 Xin_Alu32M, /* 32-bit mov/arith/logical, dst=MEM */
sewardjeba63f82005-02-23 13:31:25 +0000345 Xin_Sh32, /* 32-bit shift/rotate, dst=REG */
sewardjfb7373a2007-08-25 21:29:03 +0000346 Xin_Test32, /* 32-bit test of REG or MEM against imm32 (AND, set
sewardjeba63f82005-02-23 13:31:25 +0000347 flags, discard result) */
sewardj60f4e3c2004-07-19 01:56:50 +0000348 Xin_Unary32, /* 32-bit not and neg */
sewardj79e04f82007-03-31 14:30:12 +0000349 Xin_Lea32, /* 32-bit compute EA into a reg */
sewardjeba63f82005-02-23 13:31:25 +0000350 Xin_MulL, /* 32 x 32 -> 64 multiply */
351 Xin_Div, /* 64/32 -> (32,32) div and mod */
sewardj5c34dc92004-07-19 12:48:11 +0000352 Xin_Sh3232, /* shldl or shrdl */
sewardje8e9d732004-07-16 21:03:45 +0000353 Xin_Push, /* push (32-bit?) value on stack */
354 Xin_Call, /* call to address in register */
sewardjc6f970f2012-04-02 21:54:49 +0000355 Xin_XDirect, /* direct transfer to GA */
356 Xin_XIndir, /* indirect transfer to GA */
357 Xin_XAssisted, /* assisted transfer to GA */
sewardj5c34dc92004-07-19 12:48:11 +0000358 Xin_CMov32, /* conditional move */
sewardj443cd9d2004-07-18 23:06:45 +0000359 Xin_LoadEX, /* mov{s,z}{b,w}l from mem to reg */
sewardjd1725d12004-08-12 20:46:53 +0000360 Xin_Store, /* store 16/8 bit value in memory */
sewardjd7cb8532004-08-17 23:59:23 +0000361 Xin_Set32, /* convert condition code to 32-bit value */
sewardjce646f22004-08-31 23:55:54 +0000362 Xin_Bsfr32, /* 32-bit bsf/bsr */
sewardj3e838932005-01-07 12:09:15 +0000363 Xin_MFence, /* mem fence (not just sse2, but sse0 and 1 too) */
sewardje9d8a262009-07-01 08:06:34 +0000364 Xin_ACAS, /* 8/16/32-bit lock;cmpxchg */
365 Xin_DACAS, /* lock;cmpxchg8b (doubleword ACAS, 2 x 32-bit only) */
sewardjd08f2d72004-12-01 23:19:36 +0000366
sewardjd1725d12004-08-12 20:46:53 +0000367 Xin_FpUnary, /* FP fake unary op */
368 Xin_FpBinary, /* FP fake binary op */
369 Xin_FpLdSt, /* FP fake load/store */
sewardj89cd0932004-09-08 18:23:25 +0000370 Xin_FpLdStI, /* FP fake load/store, converting to/from Int */
sewardj3bca9062004-12-04 14:36:09 +0000371 Xin_Fp64to32, /* FP round IEEE754 double to IEEE754 single */
sewardjb9fa69b2004-12-09 23:25:14 +0000372 Xin_FpCMov, /* FP fake floating point conditional move */
sewardjeba63f82005-02-23 13:31:25 +0000373 Xin_FpLdCW, /* fldcw */
sewardj46de4072004-09-11 19:23:24 +0000374 Xin_FpStSW_AX, /* fstsw %ax */
sewardjd08f2d72004-12-01 23:19:36 +0000375 Xin_FpCmp, /* FP compare, generating a C320 value into int reg */
376
sewardj1e6ad742004-12-02 16:16:11 +0000377 Xin_SseConst, /* Generate restricted SSE literal */
sewardjd08f2d72004-12-01 23:19:36 +0000378 Xin_SseLdSt, /* SSE load/store, no alignment constraints */
sewardj129b3d92004-12-05 15:42:05 +0000379 Xin_SseLdzLO, /* SSE load low 32/64 bits, zero remainder of reg */
sewardjd08f2d72004-12-01 23:19:36 +0000380 Xin_Sse32Fx4, /* SSE binary, 32Fx4 */
sewardj636ad762004-12-07 11:16:04 +0000381 Xin_Sse32FLo, /* SSE binary, 32F in lowest lane only */
382 Xin_Sse64Fx2, /* SSE binary, 64Fx2 */
sewardj164f9272004-12-09 00:39:32 +0000383 Xin_Sse64FLo, /* SSE binary, 64F in lowest lane only */
sewardjb9fa69b2004-12-09 23:25:14 +0000384 Xin_SseReRg, /* SSE binary general reg-reg, Re, Rg */
sewardj109ffdb2004-12-10 21:45:38 +0000385 Xin_SseCMov, /* SSE conditional move */
sewardjc6f970f2012-04-02 21:54:49 +0000386 Xin_SseShuf, /* SSE2 shuffle (pshufd) */
387 Xin_EvCheck, /* Event check */
388 Xin_ProfInc /* 64-bit profile counter increment */
sewardjc97096c2004-06-30 09:28:04 +0000389 }
390 X86InstrTag;
391
sewardjd1725d12004-08-12 20:46:53 +0000392/* Destinations are on the RIGHT (second operand) */
sewardjc97096c2004-06-30 09:28:04 +0000393
394typedef
395 struct {
396 X86InstrTag tag;
397 union {
sewardjc97096c2004-06-30 09:28:04 +0000398 struct {
sewardj66f2f792004-06-30 16:37:16 +0000399 X86AluOp op;
400 X86RMI* src;
401 HReg dst;
402 } Alu32R;
sewardjc97096c2004-06-30 09:28:04 +0000403 struct {
sewardj66f2f792004-06-30 16:37:16 +0000404 X86AluOp op;
405 X86RI* src;
406 X86AMode* dst;
407 } Alu32M;
sewardje8c922f2004-07-23 01:34:11 +0000408 struct {
409 X86ShiftOp op;
sewardjeba63f82005-02-23 13:31:25 +0000410 UInt src; /* shift amount, or 0 means %cl */
411 HReg dst;
sewardje8c922f2004-07-23 01:34:11 +0000412 } Sh32;
413 struct {
sewardjfb7373a2007-08-25 21:29:03 +0000414 UInt imm32;
415 X86RM* dst; /* not written, only read */
sewardje8c922f2004-07-23 01:34:11 +0000416 } Test32;
sewardj60f4e3c2004-07-19 01:56:50 +0000417 /* Not and Neg */
sewardjc97096c2004-06-30 09:28:04 +0000418 struct {
sewardj60f4e3c2004-07-19 01:56:50 +0000419 X86UnaryOp op;
sewardjeba63f82005-02-23 13:31:25 +0000420 HReg dst;
sewardj60f4e3c2004-07-19 01:56:50 +0000421 } Unary32;
sewardj79e04f82007-03-31 14:30:12 +0000422 /* 32-bit compute EA into a reg */
423 struct {
424 X86AMode* am;
425 HReg dst;
426 } Lea32;
sewardjeba63f82005-02-23 13:31:25 +0000427 /* EDX:EAX = EAX *s/u r/m32 */
sewardj60f4e3c2004-07-19 01:56:50 +0000428 struct {
sewardjeba63f82005-02-23 13:31:25 +0000429 Bool syned;
430 X86RM* src;
sewardj60f4e3c2004-07-19 01:56:50 +0000431 } MulL;
sewardj1f40a0a2004-07-21 12:28:07 +0000432 /* x86 div/idiv instruction. Modifies EDX and EAX and reads src. */
sewardj5c34dc92004-07-19 12:48:11 +0000433 struct {
sewardjeba63f82005-02-23 13:31:25 +0000434 Bool syned;
435 X86RM* src;
sewardj5c34dc92004-07-19 12:48:11 +0000436 } Div;
sewardj5c34dc92004-07-19 12:48:11 +0000437 /* shld/shrd. op may only be Xsh_SHL or Xsh_SHR */
438 struct {
439 X86ShiftOp op;
sewardje8c922f2004-07-23 01:34:11 +0000440 UInt amt; /* shift amount, or 0 means %cl */
sewardje5f384c2004-07-30 16:17:28 +0000441 HReg src;
442 HReg dst;
sewardj5c34dc92004-07-19 12:48:11 +0000443 } Sh3232;
sewardje8e9d732004-07-16 21:03:45 +0000444 struct {
445 X86RMI* src;
446 } Push;
sewardj4b861de2004-11-03 15:24:42 +0000447 /* Pseudo-insn. Call target (an absolute address), on given
448 condition (which could be Xcc_ALWAYS). */
sewardje8e9d732004-07-16 21:03:45 +0000449 struct {
sewardj4b861de2004-11-03 15:24:42 +0000450 X86CondCode cond;
451 Addr32 target;
452 Int regparms; /* 0 .. 3 */
sewardje8e9d732004-07-16 21:03:45 +0000453 } Call;
sewardjc6f970f2012-04-02 21:54:49 +0000454 /* Update the guest EIP value, then exit requesting to chain
455 to it. May be conditional. Urr, use of Addr32 implicitly
456 assumes that wordsize(guest) == wordsize(host). */
sewardje8e9d732004-07-16 21:03:45 +0000457 struct {
sewardjc6f970f2012-04-02 21:54:49 +0000458 Addr32 dstGA; /* next guest address */
459 X86AMode* amEIP; /* amode in guest state for EIP */
460 X86CondCode cond; /* can be Xcc_ALWAYS */
461 Bool toFastEP; /* chain to the slow or fast point? */
462 } XDirect;
463 /* Boring transfer to a guest address not known at JIT time.
464 Not chainable. May be conditional. */
465 struct {
466 HReg dstGA;
467 X86AMode* amEIP;
468 X86CondCode cond; /* can be Xcc_ALWAYS */
469 } XIndir;
470 /* Assisted transfer to a guest address, most general case.
471 Not chainable. May be conditional. */
472 struct {
473 HReg dstGA;
474 X86AMode* amEIP;
475 X86CondCode cond; /* can be Xcc_ALWAYS */
sewardj750f4072004-07-26 22:39:11 +0000476 IRJumpKind jk;
sewardjc6f970f2012-04-02 21:54:49 +0000477 } XAssisted;
sewardj5c34dc92004-07-19 12:48:11 +0000478 /* Mov src to dst on the given condition, which may not
479 be the bogus Xcc_ALWAYS. */
sewardj4042c7e2004-07-18 01:28:30 +0000480 struct {
sewardj5c34dc92004-07-19 12:48:11 +0000481 X86CondCode cond;
sewardje8c922f2004-07-23 01:34:11 +0000482 X86RM* src;
483 HReg dst;
sewardj5c34dc92004-07-19 12:48:11 +0000484 } CMov32;
sewardj4042c7e2004-07-18 01:28:30 +0000485 /* Sign/Zero extending loads. Dst size is always 32 bits. */
486 struct {
487 UChar szSmall;
488 Bool syned;
489 X86AMode* src;
490 HReg dst;
491 } LoadEX;
sewardj443cd9d2004-07-18 23:06:45 +0000492 /* 16/8 bit stores, which are troublesome (particularly
493 8-bit) */
494 struct {
sewardje8c922f2004-07-23 01:34:11 +0000495 UChar sz; /* only 1 or 2 */
496 HReg src;
sewardj443cd9d2004-07-18 23:06:45 +0000497 X86AMode* dst;
498 } Store;
sewardjd7cb8532004-08-17 23:59:23 +0000499 /* Convert a x86 condition code to a 32-bit value (0 or 1). */
500 struct {
501 X86CondCode cond;
502 HReg dst;
503 } Set32;
sewardjce646f22004-08-31 23:55:54 +0000504 /* 32-bit bsf or bsr. */
505 struct {
506 Bool isFwds;
507 HReg src;
508 HReg dst;
509 } Bsfr32;
sewardj3e838932005-01-07 12:09:15 +0000510 /* Mem fence (not just sse2, but sse0 and 1 too). In short,
511 an insn which flushes all preceding loads and stores as
512 much as possible before continuing. On SSE2 we emit a
513 real "mfence", on SSE1 "sfence ; lock addl $0,0(%esp)" and
514 on SSE0 "lock addl $0,0(%esp)". This insn therefore
sewardj5117ce12006-01-27 21:20:15 +0000515 carries the host's hwcaps so the assembler knows what to
sewardj3e838932005-01-07 12:09:15 +0000516 emit. */
517 struct {
sewardj5117ce12006-01-27 21:20:15 +0000518 UInt hwcaps;
sewardj3e838932005-01-07 12:09:15 +0000519 } MFence;
sewardje9d8a262009-07-01 08:06:34 +0000520 /* "lock;cmpxchg": mem address in .addr,
521 expected value in %eax, new value in %ebx */
522 struct {
523 X86AMode* addr;
524 UChar sz; /* 1, 2 or 4 */
525 } ACAS;
526 /* "lock;cmpxchg8b": mem address in .addr, expected value in
527 %edx:%eax, new value in %ecx:%ebx */
528 struct {
529 X86AMode* addr;
530 } DACAS;
sewardjd08f2d72004-12-01 23:19:36 +0000531
sewardjd1725d12004-08-12 20:46:53 +0000532 /* X86 Floating point (fake 3-operand, "flat reg file" insns) */
533 struct {
534 X86FpOp op;
535 HReg src;
536 HReg dst;
537 } FpUnary;
538 struct {
539 X86FpOp op;
540 HReg srcL;
541 HReg srcR;
542 HReg dst;
543 } FpBinary;
544 struct {
545 Bool isLoad;
546 UChar sz; /* only 4 (IEEE single) or 8 (IEEE double) */
547 HReg reg;
548 X86AMode* addr;
549 } FpLdSt;
sewardj89cd0932004-09-08 18:23:25 +0000550 /* Move 64-bit float to/from memory, converting to/from
sewardj3bca9062004-12-04 14:36:09 +0000551 signed int on the way. Note the conversions will observe
552 the host FPU rounding mode currently in force. */
sewardjd1725d12004-08-12 20:46:53 +0000553 struct {
sewardj89cd0932004-09-08 18:23:25 +0000554 Bool isLoad;
555 UChar sz; /* only 2, 4 or 8 */
556 HReg reg;
557 X86AMode* addr;
558 } FpLdStI;
sewardj3bca9062004-12-04 14:36:09 +0000559 /* By observing the current FPU rounding mode, round (etc)
560 src into dst given that dst should be interpreted as an
561 IEEE754 32-bit (float) type. */
562 struct {
563 HReg src;
564 HReg dst;
565 } Fp64to32;
sewardj33124f62004-08-30 17:54:18 +0000566 /* Mov src to dst on the given condition, which may not
567 be the bogus Xcc_ALWAYS. */
568 struct {
569 X86CondCode cond;
570 HReg src;
571 HReg dst;
572 } FpCMov;
sewardjeba63f82005-02-23 13:31:25 +0000573 /* Load the FPU's 16-bit control word (fldcw) */
sewardj8f3debf2004-09-08 23:42:23 +0000574 struct {
sewardj8f3debf2004-09-08 23:42:23 +0000575 X86AMode* addr;
576 }
sewardjeba63f82005-02-23 13:31:25 +0000577 FpLdCW;
sewardj46de4072004-09-11 19:23:24 +0000578 /* fstsw %ax */
579 struct {
580 /* no fields */
581 }
582 FpStSW_AX;
sewardjbdc7d212004-09-09 02:46:40 +0000583 /* Do a compare, generating the C320 bits into the dst. */
584 struct {
585 HReg srcL;
586 HReg srcR;
587 HReg dst;
588 } FpCmp;
sewardjd08f2d72004-12-01 23:19:36 +0000589
590 /* Simplistic SSE[123] */
591 struct {
sewardj1e6ad742004-12-02 16:16:11 +0000592 UShort con;
593 HReg dst;
594 } SseConst;
595 struct {
sewardjd08f2d72004-12-01 23:19:36 +0000596 Bool isLoad;
597 HReg reg;
598 X86AMode* addr;
599 } SseLdSt;
600 struct {
sewardjeba63f82005-02-23 13:31:25 +0000601 UChar sz; /* 4 or 8 only */
sewardj129b3d92004-12-05 15:42:05 +0000602 HReg reg;
603 X86AMode* addr;
604 } SseLdzLO;
605 struct {
sewardjd08f2d72004-12-01 23:19:36 +0000606 X86SseOp op;
607 HReg src;
608 HReg dst;
609 } Sse32Fx4;
610 struct {
611 X86SseOp op;
612 HReg src;
613 HReg dst;
614 } Sse32FLo;
sewardj636ad762004-12-07 11:16:04 +0000615 struct {
616 X86SseOp op;
617 HReg src;
618 HReg dst;
619 } Sse64Fx2;
620 struct {
621 X86SseOp op;
622 HReg src;
623 HReg dst;
624 } Sse64FLo;
sewardj164f9272004-12-09 00:39:32 +0000625 struct {
626 X86SseOp op;
627 HReg src;
628 HReg dst;
629 } SseReRg;
sewardjb9fa69b2004-12-09 23:25:14 +0000630 /* Mov src to dst on the given condition, which may not
631 be the bogus Xcc_ALWAYS. */
632 struct {
633 X86CondCode cond;
634 HReg src;
635 HReg dst;
636 } SseCMov;
sewardj109ffdb2004-12-10 21:45:38 +0000637 struct {
638 Int order; /* 0 <= order <= 0xFF */
639 HReg src;
640 HReg dst;
641 } SseShuf;
sewardjc6f970f2012-04-02 21:54:49 +0000642 struct {
643 X86AMode* amCounter;
644 X86AMode* amFailAddr;
645 } EvCheck;
646 struct {
647 /* No fields. The address of the counter to inc is
648 installed later, post-translation, by patching it in,
649 as it is not known at translation time. */
650 } ProfInc;
sewardjd08f2d72004-12-01 23:19:36 +0000651
sewardj33124f62004-08-30 17:54:18 +0000652 } Xin;
sewardjc97096c2004-06-30 09:28:04 +0000653 }
654 X86Instr;
655
sewardj46de4072004-09-11 19:23:24 +0000656extern X86Instr* X86Instr_Alu32R ( X86AluOp, X86RMI*, HReg );
657extern X86Instr* X86Instr_Alu32M ( X86AluOp, X86RI*, X86AMode* );
sewardjeba63f82005-02-23 13:31:25 +0000658extern X86Instr* X86Instr_Unary32 ( X86UnaryOp op, HReg dst );
sewardj79e04f82007-03-31 14:30:12 +0000659extern X86Instr* X86Instr_Lea32 ( X86AMode* am, HReg dst );
660
sewardjeba63f82005-02-23 13:31:25 +0000661extern X86Instr* X86Instr_Sh32 ( X86ShiftOp, UInt, HReg );
sewardjfb7373a2007-08-25 21:29:03 +0000662extern X86Instr* X86Instr_Test32 ( UInt imm32, X86RM* dst );
sewardjeba63f82005-02-23 13:31:25 +0000663extern X86Instr* X86Instr_MulL ( Bool syned, X86RM* );
664extern X86Instr* X86Instr_Div ( Bool syned, X86RM* );
sewardj46de4072004-09-11 19:23:24 +0000665extern X86Instr* X86Instr_Sh3232 ( X86ShiftOp, UInt amt, HReg src, HReg dst );
666extern X86Instr* X86Instr_Push ( X86RMI* );
sewardj4b861de2004-11-03 15:24:42 +0000667extern X86Instr* X86Instr_Call ( X86CondCode, Addr32, Int );
sewardjc6f970f2012-04-02 21:54:49 +0000668extern X86Instr* X86Instr_XDirect ( Addr32 dstGA, X86AMode* amEIP,
669 X86CondCode cond, Bool toFastEP );
670extern X86Instr* X86Instr_XIndir ( HReg dstGA, X86AMode* amEIP,
671 X86CondCode cond );
672extern X86Instr* X86Instr_XAssisted ( HReg dstGA, X86AMode* amEIP,
673 X86CondCode cond, IRJumpKind jk );
sewardj46de4072004-09-11 19:23:24 +0000674extern X86Instr* X86Instr_CMov32 ( X86CondCode, X86RM* src, HReg dst );
675extern X86Instr* X86Instr_LoadEX ( UChar szSmall, Bool syned,
676 X86AMode* src, HReg dst );
677extern X86Instr* X86Instr_Store ( UChar sz, HReg src, X86AMode* dst );
678extern X86Instr* X86Instr_Set32 ( X86CondCode cond, HReg dst );
679extern X86Instr* X86Instr_Bsfr32 ( Bool isFwds, HReg src, HReg dst );
sewardj5117ce12006-01-27 21:20:15 +0000680extern X86Instr* X86Instr_MFence ( UInt hwcaps );
sewardje9d8a262009-07-01 08:06:34 +0000681extern X86Instr* X86Instr_ACAS ( X86AMode* addr, UChar sz );
682extern X86Instr* X86Instr_DACAS ( X86AMode* addr );
sewardjd08f2d72004-12-01 23:19:36 +0000683
sewardj46de4072004-09-11 19:23:24 +0000684extern X86Instr* X86Instr_FpUnary ( X86FpOp op, HReg src, HReg dst );
685extern X86Instr* X86Instr_FpBinary ( X86FpOp op, HReg srcL, HReg srcR, HReg dst );
686extern X86Instr* X86Instr_FpLdSt ( Bool isLoad, UChar sz, HReg reg, X86AMode* );
687extern X86Instr* X86Instr_FpLdStI ( Bool isLoad, UChar sz, HReg reg, X86AMode* );
sewardj3bca9062004-12-04 14:36:09 +0000688extern X86Instr* X86Instr_Fp64to32 ( HReg src, HReg dst );
sewardj46de4072004-09-11 19:23:24 +0000689extern X86Instr* X86Instr_FpCMov ( X86CondCode, HReg src, HReg dst );
sewardjeba63f82005-02-23 13:31:25 +0000690extern X86Instr* X86Instr_FpLdCW ( X86AMode* );
sewardj46de4072004-09-11 19:23:24 +0000691extern X86Instr* X86Instr_FpStSW_AX ( void );
692extern X86Instr* X86Instr_FpCmp ( HReg srcL, HReg srcR, HReg dst );
sewardj8f3debf2004-09-08 23:42:23 +0000693
sewardj1e6ad742004-12-02 16:16:11 +0000694extern X86Instr* X86Instr_SseConst ( UShort con, HReg dst );
sewardjd08f2d72004-12-01 23:19:36 +0000695extern X86Instr* X86Instr_SseLdSt ( Bool isLoad, HReg, X86AMode* );
sewardj129b3d92004-12-05 15:42:05 +0000696extern X86Instr* X86Instr_SseLdzLO ( Int sz, HReg, X86AMode* );
sewardjd08f2d72004-12-01 23:19:36 +0000697extern X86Instr* X86Instr_Sse32Fx4 ( X86SseOp, HReg, HReg );
698extern X86Instr* X86Instr_Sse32FLo ( X86SseOp, HReg, HReg );
sewardj636ad762004-12-07 11:16:04 +0000699extern X86Instr* X86Instr_Sse64Fx2 ( X86SseOp, HReg, HReg );
700extern X86Instr* X86Instr_Sse64FLo ( X86SseOp, HReg, HReg );
sewardj164f9272004-12-09 00:39:32 +0000701extern X86Instr* X86Instr_SseReRg ( X86SseOp, HReg, HReg );
sewardjb9fa69b2004-12-09 23:25:14 +0000702extern X86Instr* X86Instr_SseCMov ( X86CondCode, HReg src, HReg dst );
sewardj109ffdb2004-12-10 21:45:38 +0000703extern X86Instr* X86Instr_SseShuf ( Int order, HReg src, HReg dst );
sewardjc6f970f2012-04-02 21:54:49 +0000704extern X86Instr* X86Instr_EvCheck ( X86AMode* amCounter,
705 X86AMode* amFailAddr );
706extern X86Instr* X86Instr_ProfInc ( void );
sewardjd08f2d72004-12-01 23:19:36 +0000707
sewardjc97096c2004-06-30 09:28:04 +0000708
cerion92b64362005-12-13 12:02:26 +0000709extern void ppX86Instr ( X86Instr*, Bool );
sewardjc97096c2004-06-30 09:28:04 +0000710
sewardjf13a16a2004-07-05 17:10:14 +0000711/* Some functions that insulate the register allocator from details
sewardj194d54a2004-07-03 19:08:18 +0000712 of the underlying instruction set. */
cerion92b64362005-12-13 12:02:26 +0000713extern void getRegUsage_X86Instr ( HRegUsage*, X86Instr*, Bool );
714extern void mapRegs_X86Instr ( HRegRemap*, X86Instr*, Bool );
sewardjf13a16a2004-07-05 17:10:14 +0000715extern Bool isMove_X86Instr ( X86Instr*, HReg*, HReg* );
sewardjc6f970f2012-04-02 21:54:49 +0000716extern Int emit_X86Instr ( /*MB_MOD*/Bool* is_profInc,
717 UChar* buf, Int nbuf, X86Instr* i,
718 Bool mode64,
719 void* disp_cp_chain_me_to_slowEP,
720 void* disp_cp_chain_me_to_fastEP,
721 void* disp_cp_xindir,
722 void* disp_cp_xassisted );
sewardj2a1ed8e2009-12-31 19:26:03 +0000723
724extern void genSpill_X86 ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
725 HReg rreg, Int offset, Bool );
726extern void genReload_X86 ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
727 HReg rreg, Int offset, Bool );
728
sewardjfb7373a2007-08-25 21:29:03 +0000729extern X86Instr* directReload_X86 ( X86Instr* i,
730 HReg vreg, Short spill_off );
sewardjf13a16a2004-07-05 17:10:14 +0000731extern void getAllocableRegs_X86 ( Int*, HReg** );
sewardjc6f970f2012-04-02 21:54:49 +0000732extern HInstrArray* iselSB_X86 ( IRSB*,
733 VexArch,
734 VexArchInfo*,
735 VexAbiInfo*,
736 Int offs_Host_EvC_Counter,
737 Int offs_Host_EvC_FailAddr,
738 Bool chainingAllowed,
739 Bool addProfInc,
740 Addr64 max_ga );
741
742/* How big is an event check? This is kind of a kludge because it
743 depends on the offsets of host_EvC_FAILADDR and host_EvC_COUNTER,
744 and so assumes that they are both <= 128, and so can use the short
745 offset encoding. This is all checked with assertions, so in the
746 worst case we will merely assert at startup. */
747extern Int evCheckSzB_X86 ( void );
748
749/* Perform a chaining and unchaining of an XDirect jump. */
750extern VexInvalRange chainXDirect_X86 ( void* place_to_chain,
751 void* disp_cp_chain_me_EXPECTED,
752 void* place_to_jump_to );
753
754extern VexInvalRange unchainXDirect_X86 ( void* place_to_unchain,
755 void* place_to_jump_to_EXPECTED,
756 void* disp_cp_chain_me );
757
758/* Patch the counter location into an existing ProfInc point. */
759extern VexInvalRange patchProfInc_X86 ( void* place_to_patch,
760 ULong* location_of_counter );
761
sewardj6c77c952004-07-03 14:51:44 +0000762
sewardjcef7d3e2009-07-02 12:21:59 +0000763#endif /* ndef __VEX_HOST_X86_DEFS_H */
sewardj887a11a2004-07-05 17:26:47 +0000764
765/*---------------------------------------------------------------*/
sewardjcef7d3e2009-07-02 12:21:59 +0000766/*--- end host_x86_defs.h ---*/
sewardj887a11a2004-07-05 17:26:47 +0000767/*---------------------------------------------------------------*/