Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * vim: set ts=8 sts=4 et sw=4 tw=99:
3 : * This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #ifndef jit_x86_shared_Encoding_x86_shared_h
8 : #define jit_x86_shared_Encoding_x86_shared_h
9 :
10 : #include "jit/x86-shared/Constants-x86-shared.h"
11 :
12 : namespace js {
13 : namespace jit {
14 :
15 : namespace X86Encoding {
16 :
17 : static const size_t MaxInstructionSize = 16;
18 :
19 : // These enumerated values are following the Intel documentation Volume 2C [1],
20 : // Appendix A.2 and Appendix A.3.
21 : //
22 : // Operand size/types as listed in the Appendix A.2. Tables of the instructions
23 : // and their operands can be found in the Appendix A.3.
24 : //
25 : // E = reg/mem
26 : // G = reg (reg field of ModR/M)
27 : // U = xmm (R/M field of ModR/M)
28 : // V = xmm (reg field of ModR/M)
29 : // W = xmm/mem64
30 : // I = immediate
31 : // O = offset
32 : //
33 : // b = byte (8-bit)
34 : // w = word (16-bit)
35 : // v = register size
36 : // d = double (32-bit)
37 : // dq = double-quad (128-bit) (xmm)
38 : // ss = scalar float 32 (xmm)
39 : // ps = packed float 32 (xmm)
40 : // sd = scalar double (xmm)
41 : // pd = packed double (xmm)
42 : // z = 16/32/64-bit
43 : // vqp = (*)
44 : //
45 : // (*) Some website [2] provides a convenient list of all instructions, but be
46 : // aware that they do not follow the Intel documentation naming, as the
47 : // following enumeration does. Do not use these names as a reference for adding
48 : // new instructions.
49 : //
50 : // [1] http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-manual-325462.html
51 : // [2] http://ref.x86asm.net/geek.html
52 : //
53 : // OPn_NAME_DstSrc
54 : enum OneByteOpcodeID {
55 : OP_NOP_00 = 0x00,
56 : OP_ADD_EbGb = 0x00,
57 : OP_ADD_EvGv = 0x01,
58 : OP_ADD_GvEv = 0x03,
59 : OP_ADD_EAXIv = 0x05,
60 : OP_OR_EbGb = 0x08,
61 : OP_OR_EvGv = 0x09,
62 : OP_OR_GvEv = 0x0B,
63 : OP_OR_EAXIv = 0x0D,
64 : OP_2BYTE_ESCAPE = 0x0F,
65 : OP_NOP_0F = 0x0F,
66 : OP_ADC_GvEv = 0x13,
67 : OP_SBB_GvEv = 0x1B,
68 : OP_NOP_1F = 0x1F,
69 : OP_AND_EbGb = 0x20,
70 : OP_AND_EvGv = 0x21,
71 : OP_AND_GvEv = 0x23,
72 : OP_AND_EAXIv = 0x25,
73 : OP_SUB_EbGb = 0x28,
74 : OP_SUB_EvGv = 0x29,
75 : OP_SUB_GvEv = 0x2B,
76 : OP_SUB_EAXIv = 0x2D,
77 : PRE_PREDICT_BRANCH_NOT_TAKEN = 0x2E,
78 : OP_XOR_EbGb = 0x30,
79 : OP_XOR_EvGv = 0x31,
80 : OP_XOR_GvEv = 0x33,
81 : OP_XOR_EAXIv = 0x35,
82 : OP_CMP_EvGv = 0x39,
83 : OP_CMP_GvEv = 0x3B,
84 : OP_CMP_EAXIv = 0x3D,
85 : #ifdef JS_CODEGEN_X64
86 : PRE_REX = 0x40,
87 : #endif
88 : OP_NOP_40 = 0x40,
89 : OP_NOP_44 = 0x44,
90 : OP_PUSH_EAX = 0x50,
91 : OP_POP_EAX = 0x58,
92 : #ifdef JS_CODEGEN_X86
93 : OP_PUSHA = 0x60,
94 : OP_POPA = 0x61,
95 : #endif
96 : #ifdef JS_CODEGEN_X64
97 : OP_MOVSXD_GvEv = 0x63,
98 : #endif
99 : PRE_OPERAND_SIZE = 0x66,
100 : PRE_SSE_66 = 0x66,
101 : OP_NOP_66 = 0x66,
102 : OP_PUSH_Iz = 0x68,
103 : OP_IMUL_GvEvIz = 0x69,
104 : OP_PUSH_Ib = 0x6a,
105 : OP_IMUL_GvEvIb = 0x6b,
106 : OP_JCC_rel8 = 0x70,
107 : OP_GROUP1_EbIb = 0x80,
108 : OP_NOP_80 = 0x80,
109 : OP_GROUP1_EvIz = 0x81,
110 : OP_GROUP1_EvIb = 0x83,
111 : OP_TEST_EbGb = 0x84,
112 : OP_NOP_84 = 0x84,
113 : OP_TEST_EvGv = 0x85,
114 : OP_XCHG_GbEb = 0x86,
115 : OP_XCHG_GvEv = 0x87,
116 : OP_MOV_EbGv = 0x88,
117 : OP_MOV_EvGv = 0x89,
118 : OP_MOV_GvEb = 0x8A,
119 : OP_MOV_GvEv = 0x8B,
120 : OP_LEA = 0x8D,
121 : OP_GROUP1A_Ev = 0x8F,
122 : OP_NOP = 0x90,
123 : OP_PUSHFLAGS = 0x9C,
124 : OP_POPFLAGS = 0x9D,
125 : OP_CDQ = 0x99,
126 : OP_MOV_EAXOv = 0xA1,
127 : OP_MOV_OvEAX = 0xA3,
128 : OP_TEST_EAXIb = 0xA8,
129 : OP_TEST_EAXIv = 0xA9,
130 : OP_MOV_EbIb = 0xB0,
131 : OP_MOV_EAXIv = 0xB8,
132 : OP_GROUP2_EvIb = 0xC1,
133 : OP_ADDP_ST0_ST1 = 0xC1,
134 : OP_RET_Iz = 0xC2,
135 : PRE_VEX_C4 = 0xC4,
136 : PRE_VEX_C5 = 0xC5,
137 : OP_RET = 0xC3,
138 : OP_GROUP11_EvIb = 0xC6,
139 : OP_GROUP11_EvIz = 0xC7,
140 : OP_INT3 = 0xCC,
141 : OP_GROUP2_Ev1 = 0xD1,
142 : OP_GROUP2_EvCL = 0xD3,
143 : OP_FPU6 = 0xDD,
144 : OP_FPU6_F32 = 0xD9,
145 : OP_FPU6_ADDP = 0xDE,
146 : OP_FILD = 0xDF,
147 : OP_CALL_rel32 = 0xE8,
148 : OP_JMP_rel32 = 0xE9,
149 : OP_JMP_rel8 = 0xEB,
150 : PRE_LOCK = 0xF0,
151 : PRE_SSE_F2 = 0xF2,
152 : PRE_SSE_F3 = 0xF3,
153 : OP_HLT = 0xF4,
154 : OP_GROUP3_EbIb = 0xF6,
155 : OP_GROUP3_Ev = 0xF7,
156 : OP_GROUP3_EvIz = 0xF7, // OP_GROUP3_Ev has an immediate, when instruction is a test.
157 : OP_GROUP5_Ev = 0xFF
158 : };
159 :
160 : enum class ShiftID {
161 : vpsrlx = 2,
162 : vpsrldq = 3,
163 : vpsrad = 4,
164 : vpsllx = 6
165 : };
166 :
167 : enum TwoByteOpcodeID {
168 : OP2_UD2 = 0x0B,
169 : OP2_MOVSD_VsdWsd = 0x10,
170 : OP2_MOVPS_VpsWps = 0x10,
171 : OP2_MOVSD_WsdVsd = 0x11,
172 : OP2_MOVPS_WpsVps = 0x11,
173 : OP2_MOVDDUP_VqWq = 0x12,
174 : OP2_MOVHLPS_VqUq = 0x12,
175 : OP2_MOVSLDUP_VpsWps = 0x12,
176 : OP2_UNPCKLPS_VsdWsd = 0x14,
177 : OP2_UNPCKHPS_VsdWsd = 0x15,
178 : OP2_MOVLHPS_VqUq = 0x16,
179 : OP2_MOVSHDUP_VpsWps = 0x16,
180 : OP2_MOVAPD_VsdWsd = 0x28,
181 : OP2_MOVAPS_VsdWsd = 0x28,
182 : OP2_MOVAPS_WsdVsd = 0x29,
183 : OP2_CVTSI2SD_VsdEd = 0x2A,
184 : OP2_CVTTSD2SI_GdWsd = 0x2C,
185 : OP2_UCOMISD_VsdWsd = 0x2E,
186 : OP2_CMOVZ_GvEv = 0x44,
187 : OP2_MOVMSKPD_EdVd = 0x50,
188 : OP2_ANDPS_VpsWps = 0x54,
189 : OP2_ANDNPS_VpsWps = 0x55,
190 : OP2_ORPS_VpsWps = 0x56,
191 : OP2_XORPS_VpsWps = 0x57,
192 : OP2_ADDSD_VsdWsd = 0x58,
193 : OP2_ADDPS_VpsWps = 0x58,
194 : OP2_MULSD_VsdWsd = 0x59,
195 : OP2_MULPS_VpsWps = 0x59,
196 : OP2_CVTSS2SD_VsdEd = 0x5A,
197 : OP2_CVTSD2SS_VsdEd = 0x5A,
198 : OP2_CVTTPS2DQ_VdqWps = 0x5B,
199 : OP2_CVTDQ2PS_VpsWdq = 0x5B,
200 : OP2_SUBSD_VsdWsd = 0x5C,
201 : OP2_SUBPS_VpsWps = 0x5C,
202 : OP2_MINSD_VsdWsd = 0x5D,
203 : OP2_MINSS_VssWss = 0x5D,
204 : OP2_MINPS_VpsWps = 0x5D,
205 : OP2_DIVSD_VsdWsd = 0x5E,
206 : OP2_DIVPS_VpsWps = 0x5E,
207 : OP2_MAXSD_VsdWsd = 0x5F,
208 : OP2_MAXSS_VssWss = 0x5F,
209 : OP2_MAXPS_VpsWps = 0x5F,
210 : OP2_SQRTSD_VsdWsd = 0x51,
211 : OP2_SQRTSS_VssWss = 0x51,
212 : OP2_SQRTPS_VpsWps = 0x51,
213 : OP2_RSQRTPS_VpsWps = 0x52,
214 : OP2_RCPPS_VpsWps = 0x53,
215 : OP2_ANDPD_VpdWpd = 0x54,
216 : OP2_ORPD_VpdWpd = 0x56,
217 : OP2_XORPD_VpdWpd = 0x57,
218 : OP2_PUNPCKLDQ = 0x62,
219 : OP2_PCMPGTB_VdqWdq = 0x64,
220 : OP2_PCMPGTW_VdqWdq = 0x65,
221 : OP2_PCMPGTD_VdqWdq = 0x66,
222 : OP2_MOVD_VdEd = 0x6E,
223 : OP2_MOVDQ_VsdWsd = 0x6F,
224 : OP2_MOVDQ_VdqWdq = 0x6F,
225 : OP2_PSHUFD_VdqWdqIb = 0x70,
226 : OP2_PSHUFLW_VdqWdqIb = 0x70,
227 : OP2_PSHUFHW_VdqWdqIb = 0x70,
228 : OP2_PSLLW_UdqIb = 0x71,
229 : OP2_PSRAW_UdqIb = 0x71,
230 : OP2_PSRLW_UdqIb = 0x71,
231 : OP2_PSLLD_UdqIb = 0x72,
232 : OP2_PSRAD_UdqIb = 0x72,
233 : OP2_PSRLD_UdqIb = 0x72,
234 : OP2_PSRLDQ_Vd = 0x73,
235 : OP2_PCMPEQB_VdqWdq = 0x74,
236 : OP2_PCMPEQW_VdqWdq = 0x75,
237 : OP2_PCMPEQD_VdqWdq = 0x76,
238 : OP2_HADDPD = 0x7C,
239 : OP2_MOVD_EdVd = 0x7E,
240 : OP2_MOVQ_VdWd = 0x7E,
241 : OP2_MOVDQ_WdqVdq = 0x7F,
242 : OP2_JCC_rel32 = 0x80,
243 : OP_SETCC = 0x90,
244 : OP2_SHLD = 0xA4,
245 : OP2_SHLD_GvEv = 0xA5,
246 : OP2_SHRD = 0xAC,
247 : OP2_SHRD_GvEv = 0xAD,
248 : OP_FENCE = 0xAE,
249 : OP2_IMUL_GvEv = 0xAF,
250 : OP2_CMPXCHG_GvEb = 0xB0,
251 : OP2_CMPXCHG_GvEw = 0xB1,
252 : OP2_POPCNT_GvEv = 0xB8,
253 : OP2_BSF_GvEv = 0xBC,
254 : OP2_BSR_GvEv = 0xBD,
255 : OP2_MOVSX_GvEb = 0xBE,
256 : OP2_MOVSX_GvEw = 0xBF,
257 : OP2_MOVZX_GvEb = 0xB6,
258 : OP2_MOVZX_GvEw = 0xB7,
259 : OP2_XADD_EbGb = 0xC0,
260 : OP2_XADD_EvGv = 0xC1,
261 : OP2_CMPPS_VpsWps = 0xC2,
262 : OP2_PINSRW = 0xC4,
263 : OP2_PEXTRW_GdUdIb = 0xC5,
264 : OP2_SHUFPS_VpsWpsIb = 0xC6,
265 : OP2_PSRLW_VdqWdq = 0xD1,
266 : OP2_PSRLD_VdqWdq = 0xD2,
267 : OP2_PMULLW_VdqWdq = 0xD5,
268 : OP2_MOVQ_WdVd = 0xD6,
269 : OP2_PMOVMSKB_EdVd = 0xD7,
270 : OP2_PSUBUSB_VdqWdq = 0xD8,
271 : OP2_PSUBUSW_VdqWdq = 0xD9,
272 : OP2_PANDDQ_VdqWdq = 0xDB,
273 : OP2_PADDUSB_VdqWdq = 0xDC,
274 : OP2_PADDUSW_VdqWdq = 0xDD,
275 : OP2_PANDNDQ_VdqWdq = 0xDF,
276 : OP2_PSRAW_VdqWdq = 0xE1,
277 : OP2_PSRAD_VdqWdq = 0xE2,
278 : OP2_PSUBSB_VdqWdq = 0xE8,
279 : OP2_PSUBSW_VdqWdq = 0xE9,
280 : OP2_PORDQ_VdqWdq = 0xEB,
281 : OP2_PADDSB_VdqWdq = 0xEC,
282 : OP2_PADDSW_VdqWdq = 0xED,
283 : OP2_PXORDQ_VdqWdq = 0xEF,
284 : OP2_PSLLW_VdqWdq = 0xF1,
285 : OP2_PSLLD_VdqWdq = 0xF2,
286 : OP2_PMULUDQ_VdqWdq = 0xF4,
287 : OP2_PSUBB_VdqWdq = 0xF8,
288 : OP2_PSUBW_VdqWdq = 0xF9,
289 : OP2_PSUBD_VdqWdq = 0xFA,
290 : OP2_PADDB_VdqWdq = 0xFC,
291 : OP2_PADDW_VdqWdq = 0xFD,
292 : OP2_PADDD_VdqWdq = 0xFE
293 : };
294 :
295 : enum ThreeByteOpcodeID {
296 : OP3_PSHUFB_VdqWdq = 0x00,
297 : OP3_ROUNDSS_VsdWsd = 0x0A,
298 : OP3_ROUNDSD_VsdWsd = 0x0B,
299 : OP3_BLENDVPS_VdqWdq = 0x14,
300 : OP3_PEXTRB_EdVdqIb = 0x14,
301 : OP3_PEXTRD_EdVdqIb = 0x16,
302 : OP3_BLENDPS_VpsWpsIb = 0x0C,
303 : OP3_PTEST_VdVd = 0x17,
304 : OP3_PINSRB_VdqEdIb = 0x20,
305 : OP3_INSERTPS_VpsUps = 0x21,
306 : OP3_PINSRD_VdqEdIb = 0x22,
307 : OP3_PMULLD_VdqWdq = 0x40,
308 : OP3_VBLENDVPS_VdqWdq = 0x4A
309 : };
310 :
311 : // Test whether the given opcode should be printed with its operands reversed.
312 331443 : inline bool IsXMMReversedOperands(TwoByteOpcodeID opcode)
313 : {
314 331443 : switch (opcode) {
315 : case OP2_MOVSD_WsdVsd: // also OP2_MOVPS_WpsVps
316 : case OP2_MOVAPS_WsdVsd:
317 : case OP2_MOVDQ_WdqVdq:
318 : case OP3_PEXTRD_EdVdqIb:
319 165680 : return true;
320 : default:
321 165763 : break;
322 : }
323 165763 : return false;
324 : }
325 :
326 : enum ThreeByteEscape {
327 : ESCAPE_38 = 0x38,
328 : ESCAPE_3A = 0x3A
329 : };
330 :
331 : enum VexOperandType {
332 : VEX_PS = 0,
333 : VEX_PD = 1,
334 : VEX_SS = 2,
335 : VEX_SD = 3
336 : };
337 :
338 245 : inline OneByteOpcodeID jccRel8(Condition cond)
339 : {
340 245 : return OneByteOpcodeID(OP_JCC_rel8 + cond);
341 : }
342 40659 : inline TwoByteOpcodeID jccRel32(Condition cond)
343 : {
344 40659 : return TwoByteOpcodeID(OP2_JCC_rel32 + cond);
345 : }
346 186 : inline TwoByteOpcodeID setccOpcode(Condition cond)
347 : {
348 186 : return TwoByteOpcodeID(OP_SETCC + cond);
349 : }
350 :
351 : enum GroupOpcodeID {
352 : GROUP1_OP_ADD = 0,
353 : GROUP1_OP_OR = 1,
354 : GROUP1_OP_ADC = 2,
355 : GROUP1_OP_SBB = 3,
356 : GROUP1_OP_AND = 4,
357 : GROUP1_OP_SUB = 5,
358 : GROUP1_OP_XOR = 6,
359 : GROUP1_OP_CMP = 7,
360 :
361 : GROUP1A_OP_POP = 0,
362 :
363 : GROUP2_OP_ROL = 0,
364 : GROUP2_OP_ROR = 1,
365 : GROUP2_OP_SHL = 4,
366 : GROUP2_OP_SHR = 5,
367 : GROUP2_OP_SAR = 7,
368 :
369 : GROUP3_OP_TEST = 0,
370 : GROUP3_OP_NOT = 2,
371 : GROUP3_OP_NEG = 3,
372 : GROUP3_OP_MUL = 4,
373 : GROUP3_OP_IMUL = 5,
374 : GROUP3_OP_DIV = 6,
375 : GROUP3_OP_IDIV = 7,
376 :
377 : GROUP5_OP_INC = 0,
378 : GROUP5_OP_DEC = 1,
379 : GROUP5_OP_CALLN = 2,
380 : GROUP5_OP_JMPN = 4,
381 : GROUP5_OP_PUSH = 6,
382 :
383 : FILD_OP_64 = 5,
384 :
385 : FPU6_OP_FLD = 0,
386 : FPU6_OP_FISTTP = 1,
387 : FPU6_OP_FSTP = 3,
388 : FPU6_OP_FLDCW = 5,
389 : FPU6_OP_FISTP = 7,
390 :
391 : GROUP11_MOV = 0
392 : };
393 :
394 : static const RegisterID noBase = rbp;
395 : static const RegisterID hasSib = rsp;
396 : static const RegisterID noIndex = rsp;
397 : #ifdef JS_CODEGEN_X64
398 : static const RegisterID noBase2 = r13;
399 : static const RegisterID hasSib2 = r12;
400 : #endif
401 :
402 : enum ModRmMode {
403 : ModRmMemoryNoDisp,
404 : ModRmMemoryDisp8,
405 : ModRmMemoryDisp32,
406 : ModRmRegister
407 : };
408 :
409 : } // namespace X86Encoding
410 :
411 : } // namespace jit
412 : } // namespace js
413 :
414 : #endif /* jit_x86_shared_Encoding_x86_shared_h */
|