blob: f810ab4f615fabb2101560ed55e174d0bd2c01d2 [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 */
sewardjcfe046e2013-01-17 14:23:53 +0000453 RetLoc rloc; /* where the return value will be */
sewardje8e9d732004-07-16 21:03:45 +0000454 } Call;
sewardjc6f970f2012-04-02 21:54:49 +0000455 /* Update the guest EIP value, then exit requesting to chain
456 to it. May be conditional. Urr, use of Addr32 implicitly
457 assumes that wordsize(guest) == wordsize(host). */
sewardje8e9d732004-07-16 21:03:45 +0000458 struct {
sewardjc6f970f2012-04-02 21:54:49 +0000459 Addr32 dstGA; /* next guest address */
460 X86AMode* amEIP; /* amode in guest state for EIP */
461 X86CondCode cond; /* can be Xcc_ALWAYS */
462 Bool toFastEP; /* chain to the slow or fast point? */
463 } XDirect;
464 /* Boring transfer to a guest address not known at JIT time.
465 Not chainable. May be conditional. */
466 struct {
467 HReg dstGA;
468 X86AMode* amEIP;
469 X86CondCode cond; /* can be Xcc_ALWAYS */
470 } XIndir;
471 /* Assisted transfer to a guest address, most general case.
472 Not chainable. May be conditional. */
473 struct {
474 HReg dstGA;
475 X86AMode* amEIP;
476 X86CondCode cond; /* can be Xcc_ALWAYS */
sewardj750f4072004-07-26 22:39:11 +0000477 IRJumpKind jk;
sewardjc6f970f2012-04-02 21:54:49 +0000478 } XAssisted;
sewardj5c34dc92004-07-19 12:48:11 +0000479 /* Mov src to dst on the given condition, which may not
480 be the bogus Xcc_ALWAYS. */
sewardj4042c7e2004-07-18 01:28:30 +0000481 struct {
sewardj5c34dc92004-07-19 12:48:11 +0000482 X86CondCode cond;
sewardje8c922f2004-07-23 01:34:11 +0000483 X86RM* src;
484 HReg dst;
sewardj5c34dc92004-07-19 12:48:11 +0000485 } CMov32;
sewardj4042c7e2004-07-18 01:28:30 +0000486 /* Sign/Zero extending loads. Dst size is always 32 bits. */
487 struct {
488 UChar szSmall;
489 Bool syned;
490 X86AMode* src;
491 HReg dst;
492 } LoadEX;
sewardj443cd9d2004-07-18 23:06:45 +0000493 /* 16/8 bit stores, which are troublesome (particularly
494 8-bit) */
495 struct {
sewardje8c922f2004-07-23 01:34:11 +0000496 UChar sz; /* only 1 or 2 */
497 HReg src;
sewardj443cd9d2004-07-18 23:06:45 +0000498 X86AMode* dst;
499 } Store;
sewardjd7cb8532004-08-17 23:59:23 +0000500 /* Convert a x86 condition code to a 32-bit value (0 or 1). */
501 struct {
502 X86CondCode cond;
503 HReg dst;
504 } Set32;
sewardjce646f22004-08-31 23:55:54 +0000505 /* 32-bit bsf or bsr. */
506 struct {
507 Bool isFwds;
508 HReg src;
509 HReg dst;
510 } Bsfr32;
sewardj3e838932005-01-07 12:09:15 +0000511 /* Mem fence (not just sse2, but sse0 and 1 too). In short,
512 an insn which flushes all preceding loads and stores as
513 much as possible before continuing. On SSE2 we emit a
514 real "mfence", on SSE1 "sfence ; lock addl $0,0(%esp)" and
515 on SSE0 "lock addl $0,0(%esp)". This insn therefore
sewardj5117ce12006-01-27 21:20:15 +0000516 carries the host's hwcaps so the assembler knows what to
sewardj3e838932005-01-07 12:09:15 +0000517 emit. */
518 struct {
sewardj5117ce12006-01-27 21:20:15 +0000519 UInt hwcaps;
sewardj3e838932005-01-07 12:09:15 +0000520 } MFence;
sewardje9d8a262009-07-01 08:06:34 +0000521 /* "lock;cmpxchg": mem address in .addr,
522 expected value in %eax, new value in %ebx */
523 struct {
524 X86AMode* addr;
525 UChar sz; /* 1, 2 or 4 */
526 } ACAS;
527 /* "lock;cmpxchg8b": mem address in .addr, expected value in
528 %edx:%eax, new value in %ecx:%ebx */
529 struct {
530 X86AMode* addr;
531 } DACAS;
sewardjd08f2d72004-12-01 23:19:36 +0000532
sewardjd1725d12004-08-12 20:46:53 +0000533 /* X86 Floating point (fake 3-operand, "flat reg file" insns) */
534 struct {
535 X86FpOp op;
536 HReg src;
537 HReg dst;
538 } FpUnary;
539 struct {
540 X86FpOp op;
541 HReg srcL;
542 HReg srcR;
543 HReg dst;
544 } FpBinary;
545 struct {
546 Bool isLoad;
547 UChar sz; /* only 4 (IEEE single) or 8 (IEEE double) */
548 HReg reg;
549 X86AMode* addr;
550 } FpLdSt;
sewardj89cd0932004-09-08 18:23:25 +0000551 /* Move 64-bit float to/from memory, converting to/from
sewardj3bca9062004-12-04 14:36:09 +0000552 signed int on the way. Note the conversions will observe
553 the host FPU rounding mode currently in force. */
sewardjd1725d12004-08-12 20:46:53 +0000554 struct {
sewardj89cd0932004-09-08 18:23:25 +0000555 Bool isLoad;
556 UChar sz; /* only 2, 4 or 8 */
557 HReg reg;
558 X86AMode* addr;
559 } FpLdStI;
sewardj3bca9062004-12-04 14:36:09 +0000560 /* By observing the current FPU rounding mode, round (etc)
561 src into dst given that dst should be interpreted as an
562 IEEE754 32-bit (float) type. */
563 struct {
564 HReg src;
565 HReg dst;
566 } Fp64to32;
sewardj33124f62004-08-30 17:54:18 +0000567 /* Mov src to dst on the given condition, which may not
568 be the bogus Xcc_ALWAYS. */
569 struct {
570 X86CondCode cond;
571 HReg src;
572 HReg dst;
573 } FpCMov;
sewardjeba63f82005-02-23 13:31:25 +0000574 /* Load the FPU's 16-bit control word (fldcw) */
sewardj8f3debf2004-09-08 23:42:23 +0000575 struct {
sewardj8f3debf2004-09-08 23:42:23 +0000576 X86AMode* addr;
577 }
sewardjeba63f82005-02-23 13:31:25 +0000578 FpLdCW;
sewardj46de4072004-09-11 19:23:24 +0000579 /* fstsw %ax */
580 struct {
581 /* no fields */
582 }
583 FpStSW_AX;
sewardjbdc7d212004-09-09 02:46:40 +0000584 /* Do a compare, generating the C320 bits into the dst. */
585 struct {
586 HReg srcL;
587 HReg srcR;
588 HReg dst;
589 } FpCmp;
sewardjd08f2d72004-12-01 23:19:36 +0000590
591 /* Simplistic SSE[123] */
592 struct {
sewardj1e6ad742004-12-02 16:16:11 +0000593 UShort con;
594 HReg dst;
595 } SseConst;
596 struct {
sewardjd08f2d72004-12-01 23:19:36 +0000597 Bool isLoad;
598 HReg reg;
599 X86AMode* addr;
600 } SseLdSt;
601 struct {
sewardjeba63f82005-02-23 13:31:25 +0000602 UChar sz; /* 4 or 8 only */
sewardj129b3d92004-12-05 15:42:05 +0000603 HReg reg;
604 X86AMode* addr;
605 } SseLdzLO;
606 struct {
sewardjd08f2d72004-12-01 23:19:36 +0000607 X86SseOp op;
608 HReg src;
609 HReg dst;
610 } Sse32Fx4;
611 struct {
612 X86SseOp op;
613 HReg src;
614 HReg dst;
615 } Sse32FLo;
sewardj636ad762004-12-07 11:16:04 +0000616 struct {
617 X86SseOp op;
618 HReg src;
619 HReg dst;
620 } Sse64Fx2;
621 struct {
622 X86SseOp op;
623 HReg src;
624 HReg dst;
625 } Sse64FLo;
sewardj164f9272004-12-09 00:39:32 +0000626 struct {
627 X86SseOp op;
628 HReg src;
629 HReg dst;
630 } SseReRg;
sewardjb9fa69b2004-12-09 23:25:14 +0000631 /* Mov src to dst on the given condition, which may not
632 be the bogus Xcc_ALWAYS. */
633 struct {
634 X86CondCode cond;
635 HReg src;
636 HReg dst;
637 } SseCMov;
sewardj109ffdb2004-12-10 21:45:38 +0000638 struct {
639 Int order; /* 0 <= order <= 0xFF */
640 HReg src;
641 HReg dst;
642 } SseShuf;
sewardjc6f970f2012-04-02 21:54:49 +0000643 struct {
644 X86AMode* amCounter;
645 X86AMode* amFailAddr;
646 } EvCheck;
647 struct {
648 /* No fields. The address of the counter to inc is
649 installed later, post-translation, by patching it in,
650 as it is not known at translation time. */
651 } ProfInc;
sewardjd08f2d72004-12-01 23:19:36 +0000652
sewardj33124f62004-08-30 17:54:18 +0000653 } Xin;
sewardjc97096c2004-06-30 09:28:04 +0000654 }
655 X86Instr;
656
sewardj46de4072004-09-11 19:23:24 +0000657extern X86Instr* X86Instr_Alu32R ( X86AluOp, X86RMI*, HReg );
658extern X86Instr* X86Instr_Alu32M ( X86AluOp, X86RI*, X86AMode* );
sewardjeba63f82005-02-23 13:31:25 +0000659extern X86Instr* X86Instr_Unary32 ( X86UnaryOp op, HReg dst );
sewardj79e04f82007-03-31 14:30:12 +0000660extern X86Instr* X86Instr_Lea32 ( X86AMode* am, HReg dst );
661
sewardjeba63f82005-02-23 13:31:25 +0000662extern X86Instr* X86Instr_Sh32 ( X86ShiftOp, UInt, HReg );
sewardjfb7373a2007-08-25 21:29:03 +0000663extern X86Instr* X86Instr_Test32 ( UInt imm32, X86RM* dst );
sewardjeba63f82005-02-23 13:31:25 +0000664extern X86Instr* X86Instr_MulL ( Bool syned, X86RM* );
665extern X86Instr* X86Instr_Div ( Bool syned, X86RM* );
sewardj46de4072004-09-11 19:23:24 +0000666extern X86Instr* X86Instr_Sh3232 ( X86ShiftOp, UInt amt, HReg src, HReg dst );
667extern X86Instr* X86Instr_Push ( X86RMI* );
sewardjcfe046e2013-01-17 14:23:53 +0000668extern X86Instr* X86Instr_Call ( X86CondCode, Addr32, Int, RetLoc );
sewardjc6f970f2012-04-02 21:54:49 +0000669extern X86Instr* X86Instr_XDirect ( Addr32 dstGA, X86AMode* amEIP,
670 X86CondCode cond, Bool toFastEP );
671extern X86Instr* X86Instr_XIndir ( HReg dstGA, X86AMode* amEIP,
672 X86CondCode cond );
673extern X86Instr* X86Instr_XAssisted ( HReg dstGA, X86AMode* amEIP,
674 X86CondCode cond, IRJumpKind jk );
sewardj46de4072004-09-11 19:23:24 +0000675extern X86Instr* X86Instr_CMov32 ( X86CondCode, X86RM* src, HReg dst );
676extern X86Instr* X86Instr_LoadEX ( UChar szSmall, Bool syned,
677 X86AMode* src, HReg dst );
678extern X86Instr* X86Instr_Store ( UChar sz, HReg src, X86AMode* dst );
679extern X86Instr* X86Instr_Set32 ( X86CondCode cond, HReg dst );
680extern X86Instr* X86Instr_Bsfr32 ( Bool isFwds, HReg src, HReg dst );
sewardj5117ce12006-01-27 21:20:15 +0000681extern X86Instr* X86Instr_MFence ( UInt hwcaps );
sewardje9d8a262009-07-01 08:06:34 +0000682extern X86Instr* X86Instr_ACAS ( X86AMode* addr, UChar sz );
683extern X86Instr* X86Instr_DACAS ( X86AMode* addr );
sewardjd08f2d72004-12-01 23:19:36 +0000684
sewardj46de4072004-09-11 19:23:24 +0000685extern X86Instr* X86Instr_FpUnary ( X86FpOp op, HReg src, HReg dst );
686extern X86Instr* X86Instr_FpBinary ( X86FpOp op, HReg srcL, HReg srcR, HReg dst );
687extern X86Instr* X86Instr_FpLdSt ( Bool isLoad, UChar sz, HReg reg, X86AMode* );
688extern X86Instr* X86Instr_FpLdStI ( Bool isLoad, UChar sz, HReg reg, X86AMode* );
sewardj3bca9062004-12-04 14:36:09 +0000689extern X86Instr* X86Instr_Fp64to32 ( HReg src, HReg dst );
sewardj46de4072004-09-11 19:23:24 +0000690extern X86Instr* X86Instr_FpCMov ( X86CondCode, HReg src, HReg dst );
sewardjeba63f82005-02-23 13:31:25 +0000691extern X86Instr* X86Instr_FpLdCW ( X86AMode* );
sewardj46de4072004-09-11 19:23:24 +0000692extern X86Instr* X86Instr_FpStSW_AX ( void );
693extern X86Instr* X86Instr_FpCmp ( HReg srcL, HReg srcR, HReg dst );
sewardj8f3debf2004-09-08 23:42:23 +0000694
sewardj1e6ad742004-12-02 16:16:11 +0000695extern X86Instr* X86Instr_SseConst ( UShort con, HReg dst );
sewardjd08f2d72004-12-01 23:19:36 +0000696extern X86Instr* X86Instr_SseLdSt ( Bool isLoad, HReg, X86AMode* );
sewardj129b3d92004-12-05 15:42:05 +0000697extern X86Instr* X86Instr_SseLdzLO ( Int sz, HReg, X86AMode* );
sewardjd08f2d72004-12-01 23:19:36 +0000698extern X86Instr* X86Instr_Sse32Fx4 ( X86SseOp, HReg, HReg );
699extern X86Instr* X86Instr_Sse32FLo ( X86SseOp, HReg, HReg );
sewardj636ad762004-12-07 11:16:04 +0000700extern X86Instr* X86Instr_Sse64Fx2 ( X86SseOp, HReg, HReg );
701extern X86Instr* X86Instr_Sse64FLo ( X86SseOp, HReg, HReg );
sewardj164f9272004-12-09 00:39:32 +0000702extern X86Instr* X86Instr_SseReRg ( X86SseOp, HReg, HReg );
sewardjb9fa69b2004-12-09 23:25:14 +0000703extern X86Instr* X86Instr_SseCMov ( X86CondCode, HReg src, HReg dst );
sewardj109ffdb2004-12-10 21:45:38 +0000704extern X86Instr* X86Instr_SseShuf ( Int order, HReg src, HReg dst );
sewardjc6f970f2012-04-02 21:54:49 +0000705extern X86Instr* X86Instr_EvCheck ( X86AMode* amCounter,
706 X86AMode* amFailAddr );
707extern X86Instr* X86Instr_ProfInc ( void );
sewardjd08f2d72004-12-01 23:19:36 +0000708
sewardjc97096c2004-06-30 09:28:04 +0000709
cerion92b64362005-12-13 12:02:26 +0000710extern void ppX86Instr ( X86Instr*, Bool );
sewardjc97096c2004-06-30 09:28:04 +0000711
sewardjf13a16a2004-07-05 17:10:14 +0000712/* Some functions that insulate the register allocator from details
sewardj194d54a2004-07-03 19:08:18 +0000713 of the underlying instruction set. */
cerion92b64362005-12-13 12:02:26 +0000714extern void getRegUsage_X86Instr ( HRegUsage*, X86Instr*, Bool );
715extern void mapRegs_X86Instr ( HRegRemap*, X86Instr*, Bool );
sewardjf13a16a2004-07-05 17:10:14 +0000716extern Bool isMove_X86Instr ( X86Instr*, HReg*, HReg* );
sewardjc6f970f2012-04-02 21:54:49 +0000717extern Int emit_X86Instr ( /*MB_MOD*/Bool* is_profInc,
718 UChar* buf, Int nbuf, X86Instr* i,
719 Bool mode64,
720 void* disp_cp_chain_me_to_slowEP,
721 void* disp_cp_chain_me_to_fastEP,
722 void* disp_cp_xindir,
723 void* disp_cp_xassisted );
sewardj2a1ed8e2009-12-31 19:26:03 +0000724
725extern void genSpill_X86 ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
726 HReg rreg, Int offset, Bool );
727extern void genReload_X86 ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
728 HReg rreg, Int offset, Bool );
729
sewardjfb7373a2007-08-25 21:29:03 +0000730extern X86Instr* directReload_X86 ( X86Instr* i,
731 HReg vreg, Short spill_off );
sewardjf13a16a2004-07-05 17:10:14 +0000732extern void getAllocableRegs_X86 ( Int*, HReg** );
sewardjc6f970f2012-04-02 21:54:49 +0000733extern HInstrArray* iselSB_X86 ( IRSB*,
734 VexArch,
735 VexArchInfo*,
736 VexAbiInfo*,
737 Int offs_Host_EvC_Counter,
738 Int offs_Host_EvC_FailAddr,
739 Bool chainingAllowed,
740 Bool addProfInc,
741 Addr64 max_ga );
742
743/* How big is an event check? This is kind of a kludge because it
744 depends on the offsets of host_EvC_FAILADDR and host_EvC_COUNTER,
745 and so assumes that they are both <= 128, and so can use the short
746 offset encoding. This is all checked with assertions, so in the
747 worst case we will merely assert at startup. */
748extern Int evCheckSzB_X86 ( void );
749
750/* Perform a chaining and unchaining of an XDirect jump. */
751extern VexInvalRange chainXDirect_X86 ( void* place_to_chain,
752 void* disp_cp_chain_me_EXPECTED,
753 void* place_to_jump_to );
754
755extern VexInvalRange unchainXDirect_X86 ( void* place_to_unchain,
756 void* place_to_jump_to_EXPECTED,
757 void* disp_cp_chain_me );
758
759/* Patch the counter location into an existing ProfInc point. */
760extern VexInvalRange patchProfInc_X86 ( void* place_to_patch,
761 ULong* location_of_counter );
762
sewardj6c77c952004-07-03 14:51:44 +0000763
sewardjcef7d3e2009-07-02 12:21:59 +0000764#endif /* ndef __VEX_HOST_X86_DEFS_H */
sewardj887a11a2004-07-05 17:26:47 +0000765
766/*---------------------------------------------------------------*/
sewardjcef7d3e2009-07-02 12:21:59 +0000767/*--- end host_x86_defs.h ---*/
sewardj887a11a2004-07-05 17:26:47 +0000768/*---------------------------------------------------------------*/