1/*
2 * Copyright (C) 2008-2018 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#if ENABLE(ASSEMBLER) && (CPU(X86) || CPU(X86_64))
29
30#include "AssemblerBuffer.h"
31#include "AssemblerCommon.h"
32#include "JITCompilationEffort.h"
33#include <limits.h>
34#include <stdint.h>
35#include <wtf/Assertions.h>
36#include <wtf/Vector.h>
37
38namespace JSC {
39
40inline bool CAN_SIGN_EXTEND_8_32(int32_t value) { return value == (int32_t)(signed char)value; }
41
42namespace X86Registers {
43
44#if COMPILER(MSVC)
45#define JSC_X86_ASM_REGISTER_ID_ENUM_BASE_TYPE
46#else
47#define JSC_X86_ASM_REGISTER_ID_ENUM_BASE_TYPE : int8_t
48#endif
49
50typedef enum JSC_X86_ASM_REGISTER_ID_ENUM_BASE_TYPE {
51 eax,
52 ecx,
53 edx,
54 ebx,
55 esp,
56 ebp,
57 esi,
58 edi,
59#if CPU(X86_64)
60 r8,
61 r9,
62 r10,
63 r11,
64 r12,
65 r13,
66 r14,
67 r15,
68#endif
69 InvalidGPRReg = -1,
70} RegisterID;
71
72typedef enum JSC_X86_ASM_REGISTER_ID_ENUM_BASE_TYPE {
73 eip,
74 eflags
75} SPRegisterID;
76
77typedef enum JSC_X86_ASM_REGISTER_ID_ENUM_BASE_TYPE {
78 xmm0,
79 xmm1,
80 xmm2,
81 xmm3,
82 xmm4,
83 xmm5,
84 xmm6,
85 xmm7,
86#if CPU(X86_64)
87 xmm8,
88 xmm9,
89 xmm10,
90 xmm11,
91 xmm12,
92 xmm13,
93 xmm14,
94 xmm15,
95#endif
96 InvalidFPRReg = -1,
97} XMMRegisterID;
98
99} // namespace X86Register
100
101class X86Assembler {
102public:
103 typedef X86Registers::RegisterID RegisterID;
104
105 static constexpr RegisterID firstRegister() { return X86Registers::eax; }
106 static constexpr RegisterID lastRegister()
107 {
108#if CPU(X86_64)
109 return X86Registers::r15;
110#else
111 return X86Registers::edi;
112#endif
113 }
114 static constexpr unsigned numberOfRegisters() { return lastRegister() - firstRegister() + 1; }
115
116 typedef X86Registers::SPRegisterID SPRegisterID;
117
118 static constexpr SPRegisterID firstSPRegister() { return X86Registers::eip; }
119 static constexpr SPRegisterID lastSPRegister() { return X86Registers::eflags; }
120 static constexpr unsigned numberOfSPRegisters() { return lastSPRegister() - firstSPRegister() + 1; }
121
122 typedef X86Registers::XMMRegisterID XMMRegisterID;
123 typedef XMMRegisterID FPRegisterID;
124
125 static constexpr FPRegisterID firstFPRegister() { return X86Registers::xmm0; }
126 static constexpr FPRegisterID lastFPRegister()
127 {
128#if CPU(X86_64)
129 return X86Registers::xmm15;
130#else
131 return X86Registers::xmm7;
132#endif
133 }
134 static constexpr unsigned numberOfFPRegisters() { return lastFPRegister() - firstFPRegister() + 1; }
135
136 static const char* gprName(RegisterID id)
137 {
138 ASSERT(id >= firstRegister() && id <= lastRegister());
139 static const char* const nameForRegister[numberOfRegisters()] = {
140#if CPU(X86_64)
141 "rax", "rcx", "rdx", "rbx",
142 "rsp", "rbp", "rsi", "rdi",
143 "r8", "r9", "r10", "r11",
144 "r12", "r13", "r14", "r15"
145#else
146 "eax", "ecx", "edx", "ebx",
147 "esp", "ebp", "esi", "edi",
148#endif
149 };
150 return nameForRegister[id];
151 }
152
153 static const char* sprName(SPRegisterID id)
154 {
155 ASSERT(id >= firstSPRegister() && id <= lastSPRegister());
156 static const char* const nameForRegister[numberOfSPRegisters()] = {
157#if CPU(X86_64)
158 "rip", "rflags"
159#else
160 "eip", "eflags"
161#endif
162 };
163 return nameForRegister[id];
164 }
165
166 static const char* fprName(FPRegisterID reg)
167 {
168 ASSERT(reg >= firstFPRegister() && reg <= lastFPRegister());
169 static const char* const nameForRegister[numberOfFPRegisters()] = {
170 "xmm0", "xmm1", "xmm2", "xmm3",
171 "xmm4", "xmm5", "xmm6", "xmm7",
172#if CPU(X86_64)
173 "xmm8", "xmm9", "xmm10", "xmm11",
174 "xmm12", "xmm13", "xmm14", "xmm15"
175#endif
176 };
177 return nameForRegister[reg];
178 }
179
180 typedef enum {
181 ConditionO,
182 ConditionNO,
183 ConditionB,
184 ConditionAE,
185 ConditionE,
186 ConditionNE,
187 ConditionBE,
188 ConditionA,
189 ConditionS,
190 ConditionNS,
191 ConditionP,
192 ConditionNP,
193 ConditionL,
194 ConditionGE,
195 ConditionLE,
196 ConditionG,
197
198 ConditionC = ConditionB,
199 ConditionNC = ConditionAE,
200 } Condition;
201
202private:
203 // OneByteOpcodeID defines the bytecode for 1 byte instruction. It also contains the prefixes
204 // for two bytes instructions.
205 // TwoByteOpcodeID, ThreeByteOpcodeID define the opcodes for the multibytes instructions.
206 //
207 // The encoding for each instruction can be found in the Intel Architecture Manual in the appendix
208 // "Opcode Map."
209 //
210 // Each opcode can have a suffix describing the type of argument. The full list of suffixes is
211 // in the "Key to Abbreviations" section of the "Opcode Map".
212 // The most common argument types are:
213 // -E: The argument is either a GPR or a memory address.
214 // -G: The argument is a GPR.
215 // -I: The argument is an immediate.
216 // The most common sizes are:
217 // -v: 32 or 64bit depending on the operand-size attribute.
218 // -z: 32bit in both 32bit and 64bit mode. Common for immediate values.
219 typedef enum {
220 OP_ADD_EbGb = 0x00,
221 OP_ADD_EvGv = 0x01,
222 OP_ADD_GvEv = 0x03,
223 OP_ADD_EAXIv = 0x05,
224 OP_OR_EvGb = 0x08,
225 OP_OR_EvGv = 0x09,
226 OP_OR_GvEv = 0x0B,
227 OP_OR_EAXIv = 0x0D,
228 OP_2BYTE_ESCAPE = 0x0F,
229 OP_AND_EvGb = 0x20,
230 OP_AND_EvGv = 0x21,
231 OP_AND_GvEv = 0x23,
232 OP_SUB_EvGb = 0x28,
233 OP_SUB_EvGv = 0x29,
234 OP_SUB_GvEv = 0x2B,
235 OP_SUB_EAXIv = 0x2D,
236 PRE_PREDICT_BRANCH_NOT_TAKEN = 0x2E,
237 OP_XOR_EvGb = 0x30,
238 OP_XOR_EvGv = 0x31,
239 OP_XOR_GvEv = 0x33,
240 OP_XOR_EAXIv = 0x35,
241 OP_CMP_EvGv = 0x39,
242 OP_CMP_GvEv = 0x3B,
243 OP_CMP_EAXIv = 0x3D,
244#if CPU(X86_64)
245 PRE_REX = 0x40,
246#endif
247 OP_PUSH_EAX = 0x50,
248 OP_POP_EAX = 0x58,
249#if CPU(X86_64)
250 OP_MOVSXD_GvEv = 0x63,
251#endif
252 PRE_GS = 0x65,
253 PRE_OPERAND_SIZE = 0x66,
254 PRE_SSE_66 = 0x66,
255 OP_PUSH_Iz = 0x68,
256 OP_IMUL_GvEvIz = 0x69,
257 OP_GROUP1_EbIb = 0x80,
258 OP_GROUP1_EvIz = 0x81,
259 OP_GROUP1_EvIb = 0x83,
260 OP_TEST_EbGb = 0x84,
261 OP_TEST_EvGv = 0x85,
262 OP_XCHG_EvGb = 0x86,
263 OP_XCHG_EvGv = 0x87,
264 OP_MOV_EbGb = 0x88,
265 OP_MOV_EvGv = 0x89,
266 OP_MOV_GvEv = 0x8B,
267 OP_LEA = 0x8D,
268 OP_GROUP1A_Ev = 0x8F,
269 OP_NOP = 0x90,
270 OP_XCHG_EAX = 0x90,
271 OP_PAUSE = 0x90,
272 OP_CDQ = 0x99,
273 OP_MOV_EAXOv = 0xA1,
274 OP_MOV_OvEAX = 0xA3,
275 OP_TEST_ALIb = 0xA8,
276 OP_TEST_EAXIv = 0xA9,
277 OP_MOV_EAXIv = 0xB8,
278 OP_GROUP2_EvIb = 0xC1,
279 OP_RET = 0xC3,
280 OP_GROUP11_EvIb = 0xC6,
281 OP_GROUP11_EvIz = 0xC7,
282 OP_INT3 = 0xCC,
283 OP_GROUP2_Ev1 = 0xD1,
284 OP_GROUP2_EvCL = 0xD3,
285 OP_ESCAPE_D9 = 0xD9,
286 OP_ESCAPE_DD = 0xDD,
287 OP_CALL_rel32 = 0xE8,
288 OP_JMP_rel32 = 0xE9,
289 PRE_LOCK = 0xF0,
290 PRE_SSE_F2 = 0xF2,
291 PRE_SSE_F3 = 0xF3,
292 OP_HLT = 0xF4,
293 OP_GROUP3_Eb = 0xF6,
294 OP_GROUP3_EbIb = 0xF6,
295 OP_GROUP3_Ev = 0xF7,
296 OP_GROUP3_EvIz = 0xF7, // OP_GROUP3_Ev has an immediate, when instruction is a test.
297 OP_GROUP5_Ev = 0xFF,
298 } OneByteOpcodeID;
299
300 typedef enum {
301 OP2_UD2 = 0xB,
302 OP2_MOVSD_VsdWsd = 0x10,
303 OP2_MOVSD_WsdVsd = 0x11,
304 OP2_MOVSS_VsdWsd = 0x10,
305 OP2_MOVSS_WsdVsd = 0x11,
306 OP2_MOVAPD_VpdWpd = 0x28,
307 OP2_MOVAPS_VpdWpd = 0x28,
308 OP2_CVTSI2SD_VsdEd = 0x2A,
309 OP2_CVTTSD2SI_GdWsd = 0x2C,
310 OP2_CVTTSS2SI_GdWsd = 0x2C,
311 OP2_UCOMISD_VsdWsd = 0x2E,
312 OP2_RDTSC = 0x31,
313 OP2_3BYTE_ESCAPE_3A = 0x3A,
314 OP2_CMOVCC = 0x40,
315 OP2_ADDSD_VsdWsd = 0x58,
316 OP2_MULSD_VsdWsd = 0x59,
317 OP2_CVTSD2SS_VsdWsd = 0x5A,
318 OP2_CVTSS2SD_VsdWsd = 0x5A,
319 OP2_SUBSD_VsdWsd = 0x5C,
320 OP2_DIVSD_VsdWsd = 0x5E,
321 OP2_MOVMSKPD_VdEd = 0x50,
322 OP2_SQRTSD_VsdWsd = 0x51,
323 OP2_ANDPS_VpdWpd = 0x54,
324 OP2_ANDNPD_VpdWpd = 0x55,
325 OP2_ORPS_VpdWpd = 0x56,
326 OP2_XORPD_VpdWpd = 0x57,
327 OP2_MOVD_VdEd = 0x6E,
328 OP2_MOVD_EdVd = 0x7E,
329 OP2_JCC_rel32 = 0x80,
330 OP_SETCC = 0x90,
331 OP2_CPUID = 0xA2,
332 OP2_3BYTE_ESCAPE_AE = 0xAE,
333 OP2_IMUL_GvEv = 0xAF,
334 OP2_CMPXCHGb = 0xB0,
335 OP2_CMPXCHG = 0xB1,
336 OP2_MOVZX_GvEb = 0xB6,
337 OP2_POPCNT = 0xB8,
338 OP2_BSF = 0xBC,
339 OP2_TZCNT = 0xBC,
340 OP2_BSR = 0xBD,
341 OP2_LZCNT = 0xBD,
342 OP2_MOVSX_GvEb = 0xBE,
343 OP2_MOVZX_GvEw = 0xB7,
344 OP2_MOVSX_GvEw = 0xBF,
345 OP2_XADDb = 0xC0,
346 OP2_XADD = 0xC1,
347 OP2_PEXTRW_GdUdIb = 0xC5,
348 OP2_BSWAP = 0xC8,
349 OP2_PSLLQ_UdqIb = 0x73,
350 OP2_PSRLQ_UdqIb = 0x73,
351 OP2_POR_VdqWdq = 0XEB,
352 } TwoByteOpcodeID;
353
354 typedef enum {
355 OP3_ROUNDSS_VssWssIb = 0x0A,
356 OP3_ROUNDSD_VsdWsdIb = 0x0B,
357 OP3_LFENCE = 0xE8,
358 OP3_MFENCE = 0xF0,
359 OP3_SFENCE = 0xF8,
360 } ThreeByteOpcodeID;
361
362 struct VexPrefix {
363 enum : uint8_t {
364 TwoBytes = 0xC5,
365 ThreeBytes = 0xC4
366 };
367 };
368 enum class VexImpliedBytes : uint8_t {
369 TwoBytesOp = 1,
370 ThreeBytesOp38 = 2,
371 ThreeBytesOp3A = 3
372 };
373
374 TwoByteOpcodeID cmovcc(Condition cond)
375 {
376 return (TwoByteOpcodeID)(OP2_CMOVCC + cond);
377 }
378
379 TwoByteOpcodeID jccRel32(Condition cond)
380 {
381 return (TwoByteOpcodeID)(OP2_JCC_rel32 + cond);
382 }
383
384 TwoByteOpcodeID setccOpcode(Condition cond)
385 {
386 return (TwoByteOpcodeID)(OP_SETCC + cond);
387 }
388
389 typedef enum {
390 GROUP1_OP_ADD = 0,
391 GROUP1_OP_OR = 1,
392 GROUP1_OP_ADC = 2,
393 GROUP1_OP_AND = 4,
394 GROUP1_OP_SUB = 5,
395 GROUP1_OP_XOR = 6,
396 GROUP1_OP_CMP = 7,
397
398 GROUP1A_OP_POP = 0,
399
400 GROUP2_OP_ROL = 0,
401 GROUP2_OP_ROR = 1,
402 GROUP2_OP_RCL = 2,
403 GROUP2_OP_RCR = 3,
404
405 GROUP2_OP_SHL = 4,
406 GROUP2_OP_SHR = 5,
407 GROUP2_OP_SAR = 7,
408
409 GROUP3_OP_TEST = 0,
410 GROUP3_OP_NOT = 2,
411 GROUP3_OP_NEG = 3,
412 GROUP3_OP_DIV = 6,
413 GROUP3_OP_IDIV = 7,
414
415 GROUP5_OP_CALLN = 2,
416 GROUP5_OP_JMPN = 4,
417 GROUP5_OP_PUSH = 6,
418
419 GROUP11_MOV = 0,
420
421 GROUP14_OP_PSLLQ = 6,
422 GROUP14_OP_PSRLQ = 2,
423
424 ESCAPE_D9_FSTP_singleReal = 3,
425 ESCAPE_DD_FSTP_doubleReal = 3,
426 } GroupOpcodeID;
427
428 class X86InstructionFormatter;
429public:
430
431 X86Assembler()
432 : m_indexOfLastWatchpoint(INT_MIN)
433 , m_indexOfTailOfLastWatchpoint(INT_MIN)
434 {
435 }
436
437 AssemblerBuffer& buffer() { return m_formatter.m_buffer; }
438
439 // Stack operations:
440
441 void push_r(RegisterID reg)
442 {
443 m_formatter.oneByteOp(OP_PUSH_EAX, reg);
444 }
445
446 void pop_r(RegisterID reg)
447 {
448 m_formatter.oneByteOp(OP_POP_EAX, reg);
449 }
450
451 void push_i32(int imm)
452 {
453 m_formatter.oneByteOp(OP_PUSH_Iz);
454 m_formatter.immediate32(imm);
455 }
456
457 void push_m(int offset, RegisterID base)
458 {
459 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_PUSH, base, offset);
460 }
461
462 void pop_m(int offset, RegisterID base)
463 {
464 m_formatter.oneByteOp(OP_GROUP1A_Ev, GROUP1A_OP_POP, base, offset);
465 }
466
467 // Arithmetic operations:
468
469#if !CPU(X86_64)
470 void adcl_im(int imm, const void* addr)
471 {
472 if (CAN_SIGN_EXTEND_8_32(imm)) {
473 m_formatter.oneByteOpAddr(OP_GROUP1_EvIb, GROUP1_OP_ADC, bitwise_cast<uint32_t>(addr));
474 m_formatter.immediate8(imm);
475 } else {
476 m_formatter.oneByteOpAddr(OP_GROUP1_EvIz, GROUP1_OP_ADC, bitwise_cast<uint32_t>(addr));
477 m_formatter.immediate32(imm);
478 }
479 }
480#endif
481
482 void addl_rr(RegisterID src, RegisterID dst)
483 {
484 m_formatter.oneByteOp(OP_ADD_EvGv, src, dst);
485 }
486
487 void addl_mr(int offset, RegisterID base, RegisterID dst)
488 {
489 m_formatter.oneByteOp(OP_ADD_GvEv, dst, base, offset);
490 }
491
492 void addl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
493 {
494 m_formatter.oneByteOp(OP_ADD_GvEv, dst, base, index, scale, offset);
495 }
496
497#if !CPU(X86_64)
498 void addl_mr(const void* addr, RegisterID dst)
499 {
500 m_formatter.oneByteOpAddr(OP_ADD_GvEv, dst, bitwise_cast<uint32_t>(addr));
501 }
502#endif
503
504 void addl_rm(RegisterID src, int offset, RegisterID base)
505 {
506 m_formatter.oneByteOp(OP_ADD_EvGv, src, base, offset);
507 }
508
509 void addl_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
510 {
511 m_formatter.oneByteOp(OP_ADD_EvGv, src, base, index, scale, offset);
512 }
513
514 void addb_rm(RegisterID src, int offset, RegisterID base)
515 {
516 m_formatter.oneByteOp8(OP_ADD_EbGb, src, base, offset);
517 }
518
519 void addb_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
520 {
521 m_formatter.oneByteOp8(OP_ADD_EbGb, src, base, index, scale, offset);
522 }
523
524 void addw_rm(RegisterID src, int offset, RegisterID base)
525 {
526 m_formatter.prefix(PRE_OPERAND_SIZE);
527 m_formatter.oneByteOp8(OP_ADD_EvGv, src, base, offset);
528 }
529
530 void addw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
531 {
532 m_formatter.prefix(PRE_OPERAND_SIZE);
533 m_formatter.oneByteOp8(OP_ADD_EvGv, src, base, index, scale, offset);
534 }
535
536 void addl_ir(int imm, RegisterID dst)
537 {
538 if (CAN_SIGN_EXTEND_8_32(imm)) {
539 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, dst);
540 m_formatter.immediate8(imm);
541 } else {
542 if (dst == X86Registers::eax)
543 m_formatter.oneByteOp(OP_ADD_EAXIv);
544 else
545 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, dst);
546 m_formatter.immediate32(imm);
547 }
548 }
549
550 void addl_im(int imm, int offset, RegisterID base)
551 {
552 if (CAN_SIGN_EXTEND_8_32(imm)) {
553 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, base, offset);
554 m_formatter.immediate8(imm);
555 } else {
556 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, base, offset);
557 m_formatter.immediate32(imm);
558 }
559 }
560
561 void addl_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
562 {
563 if (CAN_SIGN_EXTEND_8_32(imm)) {
564 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, base, index, scale, offset);
565 m_formatter.immediate8(imm);
566 } else {
567 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, base, index, scale, offset);
568 m_formatter.immediate32(imm);
569 }
570 }
571
572 void addb_im(int imm, int offset, RegisterID base)
573 {
574 m_formatter.oneByteOp8(OP_GROUP1_EbIb, GROUP1_OP_ADD, base, offset);
575 m_formatter.immediate8(imm);
576 }
577
578 void addb_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
579 {
580 m_formatter.oneByteOp8(OP_GROUP1_EbIb, GROUP1_OP_ADD, base, index, scale, offset);
581 m_formatter.immediate8(imm);
582 }
583
584 void addw_im(int imm, int offset, RegisterID base)
585 {
586 m_formatter.prefix(PRE_OPERAND_SIZE);
587 if (CAN_SIGN_EXTEND_8_32(imm)) {
588 m_formatter.oneByteOp8(OP_GROUP1_EvIb, GROUP1_OP_ADD, base, offset);
589 m_formatter.immediate8(imm);
590 } else {
591 m_formatter.oneByteOp8(OP_GROUP1_EvIz, GROUP1_OP_ADD, base, offset);
592 m_formatter.immediate16(imm);
593 }
594 }
595
596 void addw_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
597 {
598 m_formatter.prefix(PRE_OPERAND_SIZE);
599 if (CAN_SIGN_EXTEND_8_32(imm)) {
600 m_formatter.oneByteOp8(OP_GROUP1_EvIb, GROUP1_OP_ADD, base, index, scale, offset);
601 m_formatter.immediate8(imm);
602 } else {
603 m_formatter.oneByteOp8(OP_GROUP1_EvIz, GROUP1_OP_ADD, base, index, scale, offset);
604 m_formatter.immediate16(imm);
605 }
606 }
607
608#if CPU(X86_64)
609 void addq_rr(RegisterID src, RegisterID dst)
610 {
611 m_formatter.oneByteOp64(OP_ADD_EvGv, src, dst);
612 }
613
614 void addq_mr(int offset, RegisterID base, RegisterID dst)
615 {
616 m_formatter.oneByteOp64(OP_ADD_GvEv, dst, base, offset);
617 }
618
619 void addq_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
620 {
621 m_formatter.oneByteOp64(OP_ADD_GvEv, dst, base, index, scale, offset);
622 }
623
624 void addq_rm(RegisterID src, int offset, RegisterID base)
625 {
626 m_formatter.oneByteOp64(OP_ADD_EvGv, src, base, offset);
627 }
628
629 void addq_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
630 {
631 m_formatter.oneByteOp64(OP_ADD_EvGv, src, base, index, scale, offset);
632 }
633
634 void addq_ir(int imm, RegisterID dst)
635 {
636 if (CAN_SIGN_EXTEND_8_32(imm)) {
637 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_ADD, dst);
638 m_formatter.immediate8(imm);
639 } else {
640 if (dst == X86Registers::eax)
641 m_formatter.oneByteOp64(OP_ADD_EAXIv);
642 else
643 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_ADD, dst);
644 m_formatter.immediate32(imm);
645 }
646 }
647
648 void addq_im(int imm, int offset, RegisterID base)
649 {
650 if (CAN_SIGN_EXTEND_8_32(imm)) {
651 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_ADD, base, offset);
652 m_formatter.immediate8(imm);
653 } else {
654 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_ADD, base, offset);
655 m_formatter.immediate32(imm);
656 }
657 }
658
659 void addq_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
660 {
661 if (CAN_SIGN_EXTEND_8_32(imm)) {
662 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_ADD, base, index, scale, offset);
663 m_formatter.immediate8(imm);
664 } else {
665 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_ADD, base, index, scale, offset);
666 m_formatter.immediate32(imm);
667 }
668 }
669#else
670 void addl_im(int imm, const void* addr)
671 {
672 if (CAN_SIGN_EXTEND_8_32(imm)) {
673 m_formatter.oneByteOpAddr(OP_GROUP1_EvIb, GROUP1_OP_ADD, bitwise_cast<uint32_t>(addr));
674 m_formatter.immediate8(imm);
675 } else {
676 m_formatter.oneByteOpAddr(OP_GROUP1_EvIz, GROUP1_OP_ADD, bitwise_cast<uint32_t>(addr));
677 m_formatter.immediate32(imm);
678 }
679 }
680#endif
681
682 void andl_rr(RegisterID src, RegisterID dst)
683 {
684 m_formatter.oneByteOp(OP_AND_EvGv, src, dst);
685 }
686
687 void andl_mr(int offset, RegisterID base, RegisterID dst)
688 {
689 m_formatter.oneByteOp(OP_AND_GvEv, dst, base, offset);
690 }
691
692 void andl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
693 {
694 m_formatter.oneByteOp(OP_AND_GvEv, dst, base, index, scale, offset);
695 }
696
697 void andw_mr(int offset, RegisterID base, RegisterID dst)
698 {
699 m_formatter.prefix(PRE_OPERAND_SIZE);
700 andl_mr(offset, base, dst);
701 }
702
703 void andw_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
704 {
705 m_formatter.prefix(PRE_OPERAND_SIZE);
706 andl_mr(offset, base, index, scale, dst);
707 }
708
709 void andl_rm(RegisterID src, int offset, RegisterID base)
710 {
711 m_formatter.oneByteOp(OP_AND_EvGv, src, base, offset);
712 }
713
714 void andl_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
715 {
716 m_formatter.oneByteOp(OP_AND_EvGv, src, base, index, scale, offset);
717 }
718
719 void andw_rm(RegisterID src, int offset, RegisterID base)
720 {
721 m_formatter.prefix(PRE_OPERAND_SIZE);
722 andl_rm(src, offset, base);
723 }
724
725 void andw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
726 {
727 m_formatter.prefix(PRE_OPERAND_SIZE);
728 andl_rm(src, offset, base, index, scale);
729 }
730
731 void andb_rm(RegisterID src, int offset, RegisterID base)
732 {
733 m_formatter.oneByteOp(OP_AND_EvGb, src, base, offset);
734 }
735
736 void andb_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
737 {
738 m_formatter.oneByteOp(OP_AND_EvGb, src, base, index, scale, offset);
739 }
740
741 void andl_ir(int imm, RegisterID dst)
742 {
743 if (CAN_SIGN_EXTEND_8_32(imm)) {
744 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, dst);
745 m_formatter.immediate8(imm);
746 } else {
747 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, dst);
748 m_formatter.immediate32(imm);
749 }
750 }
751
752 void andl_im(int imm, int offset, RegisterID base)
753 {
754 if (CAN_SIGN_EXTEND_8_32(imm)) {
755 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, base, offset);
756 m_formatter.immediate8(imm);
757 } else {
758 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, base, offset);
759 m_formatter.immediate32(imm);
760 }
761 }
762
763 void andl_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
764 {
765 if (CAN_SIGN_EXTEND_8_32(imm)) {
766 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, base, index, scale, offset);
767 m_formatter.immediate8(imm);
768 } else {
769 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, base, index, scale, offset);
770 m_formatter.immediate32(imm);
771 }
772 }
773
774 void andw_im(int imm, int offset, RegisterID base)
775 {
776 m_formatter.prefix(PRE_OPERAND_SIZE);
777 if (CAN_SIGN_EXTEND_8_32(imm)) {
778 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, base, offset);
779 m_formatter.immediate8(imm);
780 } else {
781 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, base, offset);
782 m_formatter.immediate16(imm);
783 }
784 }
785
786 void andw_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
787 {
788 m_formatter.prefix(PRE_OPERAND_SIZE);
789 if (CAN_SIGN_EXTEND_8_32(imm)) {
790 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, base, index, scale, offset);
791 m_formatter.immediate8(imm);
792 } else {
793 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, base, index, scale, offset);
794 m_formatter.immediate16(imm);
795 }
796 }
797
798 void andb_im(int imm, int offset, RegisterID base)
799 {
800 m_formatter.oneByteOp(OP_GROUP1_EbIb, GROUP1_OP_AND, base, offset);
801 m_formatter.immediate8(imm);
802 }
803
804 void andb_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
805 {
806 m_formatter.oneByteOp(OP_GROUP1_EbIb, GROUP1_OP_AND, base, index, scale, offset);
807 m_formatter.immediate8(imm);
808 }
809
810#if CPU(X86_64)
811 void andq_rr(RegisterID src, RegisterID dst)
812 {
813 m_formatter.oneByteOp64(OP_AND_EvGv, src, dst);
814 }
815
816 void andq_ir(int imm, RegisterID dst)
817 {
818 if (CAN_SIGN_EXTEND_8_32(imm)) {
819 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_AND, dst);
820 m_formatter.immediate8(imm);
821 } else {
822 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_AND, dst);
823 m_formatter.immediate32(imm);
824 }
825 }
826
827 void andq_mr(int offset, RegisterID base, RegisterID dst)
828 {
829 m_formatter.oneByteOp64(OP_AND_GvEv, dst, base, offset);
830 }
831
832 void andq_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
833 {
834 m_formatter.oneByteOp64(OP_AND_GvEv, dst, base, index, scale, offset);
835 }
836
837 void andq_rm(RegisterID src, int offset, RegisterID base)
838 {
839 m_formatter.oneByteOp64(OP_AND_EvGv, src, base, offset);
840 }
841
842 void andq_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
843 {
844 m_formatter.oneByteOp64(OP_AND_EvGv, src, base, index, scale, offset);
845 }
846
847 void andq_im(int imm, int offset, RegisterID base)
848 {
849 if (CAN_SIGN_EXTEND_8_32(imm)) {
850 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_AND, base, offset);
851 m_formatter.immediate8(imm);
852 } else {
853 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_AND, base, offset);
854 m_formatter.immediate32(imm);
855 }
856 }
857
858 void andq_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
859 {
860 if (CAN_SIGN_EXTEND_8_32(imm)) {
861 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_AND, base, index, scale, offset);
862 m_formatter.immediate8(imm);
863 } else {
864 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_AND, base, index, scale, offset);
865 m_formatter.immediate32(imm);
866 }
867 }
868#else
869 void andl_im(int imm, const void* addr)
870 {
871 if (CAN_SIGN_EXTEND_8_32(imm)) {
872 m_formatter.oneByteOpAddr(OP_GROUP1_EvIb, GROUP1_OP_AND, bitwise_cast<uint32_t>(addr));
873 m_formatter.immediate8(imm);
874 } else {
875 m_formatter.oneByteOpAddr(OP_GROUP1_EvIz, GROUP1_OP_AND, bitwise_cast<uint32_t>(addr));
876 m_formatter.immediate32(imm);
877 }
878 }
879#endif
880
881 void dec_r(RegisterID dst)
882 {
883 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP1_OP_OR, dst);
884 }
885
886#if CPU(X86_64)
887 void decq_r(RegisterID dst)
888 {
889 m_formatter.oneByteOp64(OP_GROUP5_Ev, GROUP1_OP_OR, dst);
890 }
891#endif // CPU(X86_64)
892
893 // Only used for testing purposes.
894 void illegalInstruction()
895 {
896 m_formatter.twoByteOp(OP2_UD2);
897 }
898
899 void inc_r(RegisterID dst)
900 {
901 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP1_OP_ADD, dst);
902 }
903
904#if CPU(X86_64)
905 void incq_r(RegisterID dst)
906 {
907 m_formatter.oneByteOp64(OP_GROUP5_Ev, GROUP1_OP_ADD, dst);
908 }
909
910 void incq_m(int offset, RegisterID base)
911 {
912 m_formatter.oneByteOp64(OP_GROUP5_Ev, GROUP1_OP_ADD, base, offset);
913 }
914
915 void incq_m(int offset, RegisterID base, RegisterID index, int scale)
916 {
917 m_formatter.oneByteOp64(OP_GROUP5_Ev, GROUP1_OP_ADD, base, index, scale, offset);
918 }
919#endif // CPU(X86_64)
920
921 void negl_r(RegisterID dst)
922 {
923 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NEG, dst);
924 }
925
926#if CPU(X86_64)
927 void negq_r(RegisterID dst)
928 {
929 m_formatter.oneByteOp64(OP_GROUP3_Ev, GROUP3_OP_NEG, dst);
930 }
931
932 void negq_m(int offset, RegisterID base)
933 {
934 m_formatter.oneByteOp64(OP_GROUP3_Ev, GROUP3_OP_NEG, base, offset);
935 }
936
937 void negq_m(int offset, RegisterID base, RegisterID index, int scale)
938 {
939 m_formatter.oneByteOp64(OP_GROUP3_Ev, GROUP3_OP_NEG, base, index, scale, offset);
940 }
941#endif
942
943 void negl_m(int offset, RegisterID base)
944 {
945 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NEG, base, offset);
946 }
947
948 void negl_m(int offset, RegisterID base, RegisterID index, int scale)
949 {
950 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NEG, base, index, scale, offset);
951 }
952
953 void negw_m(int offset, RegisterID base)
954 {
955 m_formatter.prefix(PRE_OPERAND_SIZE);
956 negl_m(offset, base);
957 }
958
959 void negw_m(int offset, RegisterID base, RegisterID index, int scale)
960 {
961 m_formatter.prefix(PRE_OPERAND_SIZE);
962 negl_m(offset, base, index, scale);
963 }
964
965 void negb_m(int offset, RegisterID base)
966 {
967 m_formatter.oneByteOp(OP_GROUP3_Eb, GROUP3_OP_NEG, base, offset);
968 }
969
970 void negb_m(int offset, RegisterID base, RegisterID index, int scale)
971 {
972 m_formatter.oneByteOp(OP_GROUP3_Eb, GROUP3_OP_NEG, base, index, scale, offset);
973 }
974
975 void notl_r(RegisterID dst)
976 {
977 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NOT, dst);
978 }
979
980 void notl_m(int offset, RegisterID base)
981 {
982 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NOT, base, offset);
983 }
984
985 void notl_m(int offset, RegisterID base, RegisterID index, int scale)
986 {
987 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NOT, base, index, scale, offset);
988 }
989
990 void notw_m(int offset, RegisterID base)
991 {
992 m_formatter.prefix(PRE_OPERAND_SIZE);
993 notl_m(offset, base);
994 }
995
996 void notw_m(int offset, RegisterID base, RegisterID index, int scale)
997 {
998 m_formatter.prefix(PRE_OPERAND_SIZE);
999 notl_m(offset, base, index, scale);
1000 }
1001
1002 void notb_m(int offset, RegisterID base)
1003 {
1004 m_formatter.oneByteOp(OP_GROUP3_Eb, GROUP3_OP_NOT, base, offset);
1005 }
1006
1007 void notb_m(int offset, RegisterID base, RegisterID index, int scale)
1008 {
1009 m_formatter.oneByteOp(OP_GROUP3_Eb, GROUP3_OP_NOT, base, index, scale, offset);
1010 }
1011
1012#if CPU(X86_64)
1013 void notq_r(RegisterID dst)
1014 {
1015 m_formatter.oneByteOp64(OP_GROUP3_Ev, GROUP3_OP_NOT, dst);
1016 }
1017
1018 void notq_m(int offset, RegisterID base)
1019 {
1020 m_formatter.oneByteOp64(OP_GROUP3_Ev, GROUP3_OP_NOT, base, offset);
1021 }
1022
1023 void notq_m(int offset, RegisterID base, RegisterID index, int scale)
1024 {
1025 m_formatter.oneByteOp64(OP_GROUP3_Ev, GROUP3_OP_NOT, base, index, scale, offset);
1026 }
1027#endif
1028
1029 void orl_rr(RegisterID src, RegisterID dst)
1030 {
1031 m_formatter.oneByteOp(OP_OR_EvGv, src, dst);
1032 }
1033
1034 void orl_mr(int offset, RegisterID base, RegisterID dst)
1035 {
1036 m_formatter.oneByteOp(OP_OR_GvEv, dst, base, offset);
1037 }
1038
1039 void orl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1040 {
1041 m_formatter.oneByteOp(OP_OR_GvEv, dst, base, index, scale, offset);
1042 }
1043
1044 void orl_rm(RegisterID src, int offset, RegisterID base)
1045 {
1046 m_formatter.oneByteOp(OP_OR_EvGv, src, base, offset);
1047 }
1048
1049 void orl_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1050 {
1051 m_formatter.oneByteOp(OP_OR_EvGv, src, base, index, scale, offset);
1052 }
1053
1054 void orw_rm(RegisterID src, int offset, RegisterID base)
1055 {
1056 m_formatter.prefix(PRE_OPERAND_SIZE);
1057 orl_rm(src, offset, base);
1058 }
1059
1060 void orw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1061 {
1062 m_formatter.prefix(PRE_OPERAND_SIZE);
1063 orl_rm(src, offset, base, index, scale);
1064 }
1065
1066 void orb_rm(RegisterID src, int offset, RegisterID base)
1067 {
1068 m_formatter.oneByteOp(OP_OR_EvGb, src, base, offset);
1069 }
1070
1071 void orb_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1072 {
1073 m_formatter.oneByteOp(OP_OR_EvGb, src, base, index, scale, offset);
1074 }
1075
1076 void orl_ir(int imm, RegisterID dst)
1077 {
1078 if (CAN_SIGN_EXTEND_8_32(imm)) {
1079 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, dst);
1080 m_formatter.immediate8(imm);
1081 } else {
1082 if (dst == X86Registers::eax)
1083 m_formatter.oneByteOp(OP_OR_EAXIv);
1084 else
1085 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, dst);
1086 m_formatter.immediate32(imm);
1087 }
1088 }
1089
1090 void orl_im(int imm, int offset, RegisterID base)
1091 {
1092 if (CAN_SIGN_EXTEND_8_32(imm)) {
1093 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, base, offset);
1094 m_formatter.immediate8(imm);
1095 } else {
1096 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, base, offset);
1097 m_formatter.immediate32(imm);
1098 }
1099 }
1100
1101 void orl_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
1102 {
1103 if (CAN_SIGN_EXTEND_8_32(imm)) {
1104 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, base, index, scale, offset);
1105 m_formatter.immediate8(imm);
1106 } else {
1107 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, base, index, scale, offset);
1108 m_formatter.immediate32(imm);
1109 }
1110 }
1111
1112 void orw_im(int imm, int offset, RegisterID base)
1113 {
1114 m_formatter.prefix(PRE_OPERAND_SIZE);
1115 if (CAN_SIGN_EXTEND_8_32(imm)) {
1116 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, base, offset);
1117 m_formatter.immediate8(imm);
1118 } else {
1119 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, base, offset);
1120 m_formatter.immediate16(imm);
1121 }
1122 }
1123
1124 void orw_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
1125 {
1126 m_formatter.prefix(PRE_OPERAND_SIZE);
1127 if (CAN_SIGN_EXTEND_8_32(imm)) {
1128 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, base, index, scale, offset);
1129 m_formatter.immediate8(imm);
1130 } else {
1131 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, base, index, scale, offset);
1132 m_formatter.immediate16(imm);
1133 }
1134 }
1135
1136 void orb_im(int imm, int offset, RegisterID base)
1137 {
1138 m_formatter.oneByteOp(OP_GROUP1_EbIb, GROUP1_OP_OR, base, offset);
1139 m_formatter.immediate8(imm);
1140 }
1141
1142 void orb_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
1143 {
1144 m_formatter.oneByteOp(OP_GROUP1_EbIb, GROUP1_OP_OR, base, index, scale, offset);
1145 m_formatter.immediate8(imm);
1146 }
1147
1148#if CPU(X86_64)
1149 void orq_rr(RegisterID src, RegisterID dst)
1150 {
1151 m_formatter.oneByteOp64(OP_OR_EvGv, src, dst);
1152 }
1153
1154 void orq_mr(int offset, RegisterID base, RegisterID dst)
1155 {
1156 m_formatter.oneByteOp64(OP_OR_GvEv, dst, base, offset);
1157 }
1158
1159 void orq_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1160 {
1161 m_formatter.oneByteOp64(OP_OR_GvEv, dst, base, index, scale, offset);
1162 }
1163
1164 void orq_rm(RegisterID src, int offset, RegisterID base)
1165 {
1166 m_formatter.oneByteOp64(OP_OR_EvGv, src, base, offset);
1167 }
1168
1169 void orq_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1170 {
1171 m_formatter.oneByteOp64(OP_OR_EvGv, src, base, index, scale, offset);
1172 }
1173
1174 void orq_im(int imm, int offset, RegisterID base)
1175 {
1176 if (CAN_SIGN_EXTEND_8_32(imm)) {
1177 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_OR, base, offset);
1178 m_formatter.immediate8(imm);
1179 } else {
1180 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_OR, base, offset);
1181 m_formatter.immediate32(imm);
1182 }
1183 }
1184
1185 void orq_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
1186 {
1187 if (CAN_SIGN_EXTEND_8_32(imm)) {
1188 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_OR, base, index, scale, offset);
1189 m_formatter.immediate8(imm);
1190 } else {
1191 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_OR, base, index, scale, offset);
1192 m_formatter.immediate32(imm);
1193 }
1194 }
1195
1196 void orq_ir(int imm, RegisterID dst)
1197 {
1198 if (CAN_SIGN_EXTEND_8_32(imm)) {
1199 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_OR, dst);
1200 m_formatter.immediate8(imm);
1201 } else {
1202 if (dst == X86Registers::eax)
1203 m_formatter.oneByteOp64(OP_OR_EAXIv);
1204 else
1205 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_OR, dst);
1206 m_formatter.immediate32(imm);
1207 }
1208 }
1209#else
1210 void orl_im(int imm, const void* addr)
1211 {
1212 if (CAN_SIGN_EXTEND_8_32(imm)) {
1213 m_formatter.oneByteOpAddr(OP_GROUP1_EvIb, GROUP1_OP_OR, bitwise_cast<uint32_t>(addr));
1214 m_formatter.immediate8(imm);
1215 } else {
1216 m_formatter.oneByteOpAddr(OP_GROUP1_EvIz, GROUP1_OP_OR, bitwise_cast<uint32_t>(addr));
1217 m_formatter.immediate32(imm);
1218 }
1219 }
1220
1221 void orl_rm(RegisterID src, const void* addr)
1222 {
1223 m_formatter.oneByteOpAddr(OP_OR_EvGv, src, bitwise_cast<uint32_t>(addr));
1224 }
1225#endif
1226
1227 void subl_rr(RegisterID src, RegisterID dst)
1228 {
1229 m_formatter.oneByteOp(OP_SUB_EvGv, src, dst);
1230 }
1231
1232 void subl_mr(int offset, RegisterID base, RegisterID dst)
1233 {
1234 m_formatter.oneByteOp(OP_SUB_GvEv, dst, base, offset);
1235 }
1236
1237 void subl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1238 {
1239 m_formatter.oneByteOp(OP_SUB_GvEv, dst, base, index, scale, offset);
1240 }
1241
1242 void subl_rm(RegisterID src, int offset, RegisterID base)
1243 {
1244 m_formatter.oneByteOp(OP_SUB_EvGv, src, base, offset);
1245 }
1246
1247 void subl_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1248 {
1249 m_formatter.oneByteOp(OP_SUB_EvGv, src, base, index, scale, offset);
1250 }
1251
1252 void subw_rm(RegisterID src, int offset, RegisterID base)
1253 {
1254 m_formatter.prefix(PRE_OPERAND_SIZE);
1255 m_formatter.oneByteOp(OP_SUB_EvGv, src, base, offset);
1256 }
1257
1258 void subw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1259 {
1260 m_formatter.prefix(PRE_OPERAND_SIZE);
1261 m_formatter.oneByteOp(OP_SUB_EvGv, src, base, index, scale, offset);
1262 }
1263
1264 void subb_rm(RegisterID src, int offset, RegisterID base)
1265 {
1266 m_formatter.oneByteOp(OP_SUB_EvGb, src, base, offset);
1267 }
1268
1269 void subb_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1270 {
1271 m_formatter.oneByteOp(OP_SUB_EvGb, src, base, index, scale, offset);
1272 }
1273
1274 void subl_ir(int imm, RegisterID dst)
1275 {
1276 if (CAN_SIGN_EXTEND_8_32(imm)) {
1277 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, dst);
1278 m_formatter.immediate8(imm);
1279 } else {
1280 if (dst == X86Registers::eax)
1281 m_formatter.oneByteOp(OP_SUB_EAXIv);
1282 else
1283 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, dst);
1284 m_formatter.immediate32(imm);
1285 }
1286 }
1287
1288 void subl_im(int imm, int offset, RegisterID base)
1289 {
1290 if (CAN_SIGN_EXTEND_8_32(imm)) {
1291 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, base, offset);
1292 m_formatter.immediate8(imm);
1293 } else {
1294 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, base, offset);
1295 m_formatter.immediate32(imm);
1296 }
1297 }
1298
1299 void subl_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
1300 {
1301 if (CAN_SIGN_EXTEND_8_32(imm)) {
1302 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, base, index, scale, offset);
1303 m_formatter.immediate8(imm);
1304 } else {
1305 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, base, index, scale, offset);
1306 m_formatter.immediate32(imm);
1307 }
1308 }
1309
1310 void subw_im(int imm, int offset, RegisterID base)
1311 {
1312 m_formatter.prefix(PRE_OPERAND_SIZE);
1313 if (CAN_SIGN_EXTEND_8_32(imm)) {
1314 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, base, offset);
1315 m_formatter.immediate8(imm);
1316 } else {
1317 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, base, offset);
1318 m_formatter.immediate16(imm);
1319 }
1320 }
1321
1322 void subw_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
1323 {
1324 m_formatter.prefix(PRE_OPERAND_SIZE);
1325 if (CAN_SIGN_EXTEND_8_32(imm)) {
1326 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, base, index, scale, offset);
1327 m_formatter.immediate8(imm);
1328 } else {
1329 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, base, index, scale, offset);
1330 m_formatter.immediate16(imm);
1331 }
1332 }
1333
1334 void subb_im(int imm, int offset, RegisterID base)
1335 {
1336 m_formatter.oneByteOp(OP_GROUP1_EbIb, GROUP1_OP_SUB, base, offset);
1337 m_formatter.immediate8(imm);
1338 }
1339
1340 void subb_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
1341 {
1342 m_formatter.oneByteOp(OP_GROUP1_EbIb, GROUP1_OP_SUB, base, index, scale, offset);
1343 m_formatter.immediate8(imm);
1344 }
1345
1346#if CPU(X86_64)
1347 void subq_rr(RegisterID src, RegisterID dst)
1348 {
1349 m_formatter.oneByteOp64(OP_SUB_EvGv, src, dst);
1350 }
1351
1352 void subq_mr(int offset, RegisterID base, RegisterID dst)
1353 {
1354 m_formatter.oneByteOp64(OP_SUB_GvEv, dst, base, offset);
1355 }
1356
1357 void subq_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1358 {
1359 m_formatter.oneByteOp64(OP_SUB_GvEv, dst, base, index, scale, offset);
1360 }
1361
1362 void subq_rm(RegisterID src, int offset, RegisterID base)
1363 {
1364 m_formatter.oneByteOp64(OP_SUB_EvGv, src, base, offset);
1365 }
1366
1367 void subq_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1368 {
1369 m_formatter.oneByteOp64(OP_SUB_EvGv, src, base, index, scale, offset);
1370 }
1371
1372 void subq_ir(int imm, RegisterID dst)
1373 {
1374 if (CAN_SIGN_EXTEND_8_32(imm)) {
1375 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_SUB, dst);
1376 m_formatter.immediate8(imm);
1377 } else {
1378 if (dst == X86Registers::eax)
1379 m_formatter.oneByteOp64(OP_SUB_EAXIv);
1380 else
1381 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_SUB, dst);
1382 m_formatter.immediate32(imm);
1383 }
1384 }
1385
1386 void subq_im(int imm, int offset, RegisterID base)
1387 {
1388 if (CAN_SIGN_EXTEND_8_32(imm)) {
1389 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_SUB, base, offset);
1390 m_formatter.immediate8(imm);
1391 } else {
1392 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_SUB, base, offset);
1393 m_formatter.immediate32(imm);
1394 }
1395 }
1396
1397 void subq_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
1398 {
1399 if (CAN_SIGN_EXTEND_8_32(imm)) {
1400 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_SUB, base, index, scale, offset);
1401 m_formatter.immediate8(imm);
1402 } else {
1403 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_SUB, base, index, scale, offset);
1404 m_formatter.immediate32(imm);
1405 }
1406 }
1407#else
1408 void subl_im(int imm, const void* addr)
1409 {
1410 if (CAN_SIGN_EXTEND_8_32(imm)) {
1411 m_formatter.oneByteOpAddr(OP_GROUP1_EvIb, GROUP1_OP_SUB, bitwise_cast<uint32_t>(addr));
1412 m_formatter.immediate8(imm);
1413 } else {
1414 m_formatter.oneByteOpAddr(OP_GROUP1_EvIz, GROUP1_OP_SUB, bitwise_cast<uint32_t>(addr));
1415 m_formatter.immediate32(imm);
1416 }
1417 }
1418#endif
1419
1420 void xorl_rr(RegisterID src, RegisterID dst)
1421 {
1422 m_formatter.oneByteOp(OP_XOR_EvGv, src, dst);
1423 }
1424
1425 void xorl_mr(int offset, RegisterID base, RegisterID dst)
1426 {
1427 m_formatter.oneByteOp(OP_XOR_GvEv, dst, base, offset);
1428 }
1429
1430 void xorl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1431 {
1432 m_formatter.oneByteOp(OP_XOR_GvEv, dst, base, index, scale, offset);
1433 }
1434
1435 void xorl_rm(RegisterID src, int offset, RegisterID base)
1436 {
1437 m_formatter.oneByteOp(OP_XOR_EvGv, src, base, offset);
1438 }
1439
1440 void xorl_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1441 {
1442 m_formatter.oneByteOp(OP_XOR_EvGv, src, base, index, scale, offset);
1443 }
1444
1445 void xorl_im(int imm, int offset, RegisterID base)
1446 {
1447 if (CAN_SIGN_EXTEND_8_32(imm)) {
1448 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_XOR, base, offset);
1449 m_formatter.immediate8(imm);
1450 } else {
1451 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_XOR, base, offset);
1452 m_formatter.immediate32(imm);
1453 }
1454 }
1455
1456 void xorl_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
1457 {
1458 if (CAN_SIGN_EXTEND_8_32(imm)) {
1459 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_XOR, base, index, scale, offset);
1460 m_formatter.immediate8(imm);
1461 } else {
1462 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_XOR, base, index, scale, offset);
1463 m_formatter.immediate32(imm);
1464 }
1465 }
1466
1467 void xorw_rm(RegisterID src, int offset, RegisterID base)
1468 {
1469 m_formatter.prefix(PRE_OPERAND_SIZE);
1470 xorl_rm(src, offset, base);
1471 }
1472
1473 void xorw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1474 {
1475 m_formatter.prefix(PRE_OPERAND_SIZE);
1476 xorl_rm(src, offset, base, index, scale);
1477 }
1478
1479 void xorw_im(int imm, int offset, RegisterID base)
1480 {
1481 m_formatter.prefix(PRE_OPERAND_SIZE);
1482 if (CAN_SIGN_EXTEND_8_32(imm)) {
1483 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_XOR, base, offset);
1484 m_formatter.immediate8(imm);
1485 } else {
1486 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_XOR, base, offset);
1487 m_formatter.immediate16(imm);
1488 }
1489 }
1490
1491 void xorw_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
1492 {
1493 m_formatter.prefix(PRE_OPERAND_SIZE);
1494 if (CAN_SIGN_EXTEND_8_32(imm)) {
1495 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_XOR, base, index, scale, offset);
1496 m_formatter.immediate8(imm);
1497 } else {
1498 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_XOR, base, index, scale, offset);
1499 m_formatter.immediate16(imm);
1500 }
1501 }
1502
1503 void xorb_rm(RegisterID src, int offset, RegisterID base)
1504 {
1505 m_formatter.oneByteOp(OP_XOR_EvGb, src, base, offset);
1506 }
1507
1508 void xorb_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1509 {
1510 m_formatter.oneByteOp(OP_XOR_EvGb, src, base, index, scale, offset);
1511 }
1512
1513 void xorb_im(int imm, int offset, RegisterID base)
1514 {
1515 m_formatter.oneByteOp(OP_GROUP1_EbIb, GROUP1_OP_XOR, base, offset);
1516 m_formatter.immediate8(imm);
1517 }
1518
1519 void xorb_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
1520 {
1521 m_formatter.oneByteOp(OP_GROUP1_EbIb, GROUP1_OP_XOR, base, index, scale, offset);
1522 m_formatter.immediate8(imm);
1523 }
1524
1525 void xorl_ir(int imm, RegisterID dst)
1526 {
1527 if (CAN_SIGN_EXTEND_8_32(imm)) {
1528 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_XOR, dst);
1529 m_formatter.immediate8(imm);
1530 } else {
1531 if (dst == X86Registers::eax)
1532 m_formatter.oneByteOp(OP_XOR_EAXIv);
1533 else
1534 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_XOR, dst);
1535 m_formatter.immediate32(imm);
1536 }
1537 }
1538
1539#if CPU(X86_64)
1540 void xorq_rr(RegisterID src, RegisterID dst)
1541 {
1542 m_formatter.oneByteOp64(OP_XOR_EvGv, src, dst);
1543 }
1544
1545 void xorq_ir(int imm, RegisterID dst)
1546 {
1547 if (CAN_SIGN_EXTEND_8_32(imm)) {
1548 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_XOR, dst);
1549 m_formatter.immediate8(imm);
1550 } else {
1551 if (dst == X86Registers::eax)
1552 m_formatter.oneByteOp64(OP_XOR_EAXIv);
1553 else
1554 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_XOR, dst);
1555 m_formatter.immediate32(imm);
1556 }
1557 }
1558
1559 void xorq_im(int imm, int offset, RegisterID base)
1560 {
1561 if (CAN_SIGN_EXTEND_8_32(imm)) {
1562 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_XOR, base, offset);
1563 m_formatter.immediate8(imm);
1564 } else {
1565 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_XOR, base, offset);
1566 m_formatter.immediate32(imm);
1567 }
1568 }
1569
1570 void xorq_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
1571 {
1572 if (CAN_SIGN_EXTEND_8_32(imm)) {
1573 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_XOR, base, index, scale, offset);
1574 m_formatter.immediate8(imm);
1575 } else {
1576 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_XOR, base, index, scale, offset);
1577 m_formatter.immediate32(imm);
1578 }
1579 }
1580
1581 void xorq_rm(RegisterID src, int offset, RegisterID base)
1582 {
1583 m_formatter.oneByteOp64(OP_XOR_EvGv, src, base, offset);
1584 }
1585
1586 void xorq_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1587 {
1588 m_formatter.oneByteOp64(OP_XOR_EvGv, src, base, index, scale, offset);
1589 }
1590
1591 void xorq_mr(int offset, RegisterID base, RegisterID dest)
1592 {
1593 m_formatter.oneByteOp64(OP_XOR_GvEv, dest, base, offset);
1594 }
1595
1596 void xorq_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dest)
1597 {
1598 m_formatter.oneByteOp64(OP_XOR_GvEv, dest, base, index, scale, offset);
1599 }
1600#endif
1601
1602 void lzcnt_rr(RegisterID src, RegisterID dst)
1603 {
1604 m_formatter.prefix(PRE_SSE_F3);
1605 m_formatter.twoByteOp(OP2_LZCNT, dst, src);
1606 }
1607
1608 void lzcnt_mr(int offset, RegisterID base, RegisterID dst)
1609 {
1610 m_formatter.prefix(PRE_SSE_F3);
1611 m_formatter.twoByteOp(OP2_LZCNT, dst, base, offset);
1612 }
1613
1614#if CPU(X86_64)
1615 void lzcntq_rr(RegisterID src, RegisterID dst)
1616 {
1617 m_formatter.prefix(PRE_SSE_F3);
1618 m_formatter.twoByteOp64(OP2_LZCNT, dst, src);
1619 }
1620
1621 void lzcntq_mr(int offset, RegisterID base, RegisterID dst)
1622 {
1623 m_formatter.prefix(PRE_SSE_F3);
1624 m_formatter.twoByteOp64(OP2_LZCNT, dst, base, offset);
1625 }
1626#endif
1627
1628 void bsr_rr(RegisterID src, RegisterID dst)
1629 {
1630 m_formatter.twoByteOp(OP2_BSR, dst, src);
1631 }
1632
1633 void bsr_mr(int offset, RegisterID base, RegisterID dst)
1634 {
1635 m_formatter.twoByteOp(OP2_BSR, dst, base, offset);
1636 }
1637
1638#if CPU(X86_64)
1639 void bsrq_rr(RegisterID src, RegisterID dst)
1640 {
1641 m_formatter.twoByteOp64(OP2_BSR, dst, src);
1642 }
1643
1644 void bsrq_mr(int offset, RegisterID base, RegisterID dst)
1645 {
1646 m_formatter.twoByteOp64(OP2_BSR, dst, base, offset);
1647 }
1648#endif
1649
1650 void bswapl_r(RegisterID dst)
1651 {
1652 m_formatter.twoByteOp(OP2_BSWAP, dst);
1653 }
1654
1655#if CPU(X86_64)
1656 void bswapq_r(RegisterID dst)
1657 {
1658 m_formatter.twoByteOp64(OP2_BSWAP, dst);
1659 }
1660#endif
1661
1662 void tzcnt_rr(RegisterID src, RegisterID dst)
1663 {
1664 m_formatter.prefix(PRE_SSE_F3);
1665 m_formatter.twoByteOp(OP2_TZCNT, dst, src);
1666 }
1667
1668#if CPU(X86_64)
1669 void tzcntq_rr(RegisterID src, RegisterID dst)
1670 {
1671 m_formatter.prefix(PRE_SSE_F3);
1672 m_formatter.twoByteOp64(OP2_TZCNT, dst, src);
1673 }
1674#endif
1675
1676 void bsf_rr(RegisterID src, RegisterID dst)
1677 {
1678 m_formatter.twoByteOp(OP2_BSF, dst, src);
1679 }
1680
1681#if CPU(X86_64)
1682 void bsfq_rr(RegisterID src, RegisterID dst)
1683 {
1684 m_formatter.twoByteOp64(OP2_BSF, dst, src);
1685 }
1686#endif
1687
1688 void popcnt_rr(RegisterID src, RegisterID dst)
1689 {
1690 m_formatter.prefix(PRE_SSE_F3);
1691 m_formatter.twoByteOp(OP2_POPCNT, dst, src);
1692 }
1693
1694 void popcnt_mr(int offset, RegisterID base, RegisterID dst)
1695 {
1696 m_formatter.prefix(PRE_SSE_F3);
1697 m_formatter.twoByteOp(OP2_POPCNT, dst, base, offset);
1698 }
1699
1700#if CPU(X86_64)
1701 void popcntq_rr(RegisterID src, RegisterID dst)
1702 {
1703 m_formatter.prefix(PRE_SSE_F3);
1704 m_formatter.twoByteOp64(OP2_POPCNT, dst, src);
1705 }
1706
1707 void popcntq_mr(int offset, RegisterID base, RegisterID dst)
1708 {
1709 m_formatter.prefix(PRE_SSE_F3);
1710 m_formatter.twoByteOp64(OP2_POPCNT, dst, base, offset);
1711 }
1712#endif
1713
1714private:
1715 template<GroupOpcodeID op>
1716 void shiftInstruction32(int imm, RegisterID dst)
1717 {
1718 if (imm == 1)
1719 m_formatter.oneByteOp(OP_GROUP2_Ev1, op, dst);
1720 else {
1721 m_formatter.oneByteOp(OP_GROUP2_EvIb, op, dst);
1722 m_formatter.immediate8(imm);
1723 }
1724 }
1725
1726 template<GroupOpcodeID op>
1727 void shiftInstruction16(int imm, RegisterID dst)
1728 {
1729 m_formatter.prefix(PRE_OPERAND_SIZE);
1730 if (imm == 1)
1731 m_formatter.oneByteOp(OP_GROUP2_Ev1, op, dst);
1732 else {
1733 m_formatter.oneByteOp(OP_GROUP2_EvIb, op, dst);
1734 m_formatter.immediate8(imm);
1735 }
1736 }
1737public:
1738
1739 void sarl_i8r(int imm, RegisterID dst)
1740 {
1741 shiftInstruction32<GROUP2_OP_SAR>(imm, dst);
1742 }
1743
1744 void sarl_CLr(RegisterID dst)
1745 {
1746 m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SAR, dst);
1747 }
1748
1749 void shrl_i8r(int imm, RegisterID dst)
1750 {
1751 shiftInstruction32<GROUP2_OP_SHR>(imm, dst);
1752 }
1753
1754 void shrl_CLr(RegisterID dst)
1755 {
1756 m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SHR, dst);
1757 }
1758
1759 void shll_i8r(int imm, RegisterID dst)
1760 {
1761 shiftInstruction32<GROUP2_OP_SHL>(imm, dst);
1762 }
1763
1764 void shll_CLr(RegisterID dst)
1765 {
1766 m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SHL, dst);
1767 }
1768
1769 void rorl_i8r(int imm, RegisterID dst)
1770 {
1771 shiftInstruction32<GROUP2_OP_ROR>(imm, dst);
1772 }
1773
1774 void rorl_CLr(RegisterID dst)
1775 {
1776 m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_ROR, dst);
1777 }
1778
1779 void roll_i8r(int imm, RegisterID dst)
1780 {
1781 shiftInstruction32<GROUP2_OP_ROL>(imm, dst);
1782 }
1783
1784 void roll_CLr(RegisterID dst)
1785 {
1786 m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_ROL, dst);
1787 }
1788
1789 void rolw_i8r(int imm, RegisterID dst)
1790 {
1791 shiftInstruction16<GROUP2_OP_ROL>(imm, dst);
1792 }
1793
1794#if CPU(X86_64)
1795private:
1796 template<GroupOpcodeID op>
1797 void shiftInstruction64(int imm, RegisterID dst)
1798 {
1799 if (imm == 1)
1800 m_formatter.oneByteOp64(OP_GROUP2_Ev1, op, dst);
1801 else {
1802 m_formatter.oneByteOp64(OP_GROUP2_EvIb, op, dst);
1803 m_formatter.immediate8(imm);
1804 }
1805 }
1806public:
1807 void sarq_CLr(RegisterID dst)
1808 {
1809 m_formatter.oneByteOp64(OP_GROUP2_EvCL, GROUP2_OP_SAR, dst);
1810 }
1811
1812 void sarq_i8r(int imm, RegisterID dst)
1813 {
1814 shiftInstruction64<GROUP2_OP_SAR>(imm, dst);
1815 }
1816
1817 void shrq_i8r(int imm, RegisterID dst)
1818 {
1819 shiftInstruction64<GROUP2_OP_SHR>(imm, dst);
1820 }
1821
1822 void shrq_CLr(RegisterID dst)
1823 {
1824 m_formatter.oneByteOp64(OP_GROUP2_EvCL, GROUP2_OP_SHR, dst);
1825 }
1826
1827 void shlq_i8r(int imm, RegisterID dst)
1828 {
1829 shiftInstruction64<GROUP2_OP_SHL>(imm, dst);
1830 }
1831
1832 void shlq_CLr(RegisterID dst)
1833 {
1834 m_formatter.oneByteOp64(OP_GROUP2_EvCL, GROUP2_OP_SHL, dst);
1835 }
1836
1837 void rorq_i8r(int imm, RegisterID dst)
1838 {
1839 shiftInstruction64<GROUP2_OP_ROR>(imm, dst);
1840 }
1841
1842 void rorq_CLr(RegisterID dst)
1843 {
1844 m_formatter.oneByteOp64(OP_GROUP2_EvCL, GROUP2_OP_ROR, dst);
1845 }
1846
1847 void rolq_i8r(int imm, RegisterID dst)
1848 {
1849 shiftInstruction64<GROUP2_OP_ROL>(imm, dst);
1850 }
1851
1852 void rolq_CLr(RegisterID dst)
1853 {
1854 m_formatter.oneByteOp64(OP_GROUP2_EvCL, GROUP2_OP_ROL, dst);
1855 }
1856#endif // CPU(X86_64)
1857
1858 void imull_rr(RegisterID src, RegisterID dst)
1859 {
1860 m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, src);
1861 }
1862
1863#if CPU(X86_64)
1864 void imulq_rr(RegisterID src, RegisterID dst)
1865 {
1866 m_formatter.twoByteOp64(OP2_IMUL_GvEv, dst, src);
1867 }
1868#endif // CPU(X86_64)
1869
1870 void imull_mr(int offset, RegisterID base, RegisterID dst)
1871 {
1872 m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, base, offset);
1873 }
1874
1875 void imull_i32r(RegisterID src, int32_t value, RegisterID dst)
1876 {
1877 m_formatter.oneByteOp(OP_IMUL_GvEvIz, dst, src);
1878 m_formatter.immediate32(value);
1879 }
1880
1881 void divl_r(RegisterID dst)
1882 {
1883 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_DIV, dst);
1884 }
1885
1886 void idivl_r(RegisterID dst)
1887 {
1888 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_IDIV, dst);
1889 }
1890
1891#if CPU(X86_64)
1892 void divq_r(RegisterID dst)
1893 {
1894 m_formatter.oneByteOp64(OP_GROUP3_Ev, GROUP3_OP_DIV, dst);
1895 }
1896
1897 void idivq_r(RegisterID dst)
1898 {
1899 m_formatter.oneByteOp64(OP_GROUP3_Ev, GROUP3_OP_IDIV, dst);
1900 }
1901#endif // CPU(X86_64)
1902
1903 // Comparisons:
1904
1905 void cmpl_rr(RegisterID src, RegisterID dst)
1906 {
1907 m_formatter.oneByteOp(OP_CMP_EvGv, src, dst);
1908 }
1909
1910 void cmpl_rm(RegisterID src, int offset, RegisterID base)
1911 {
1912 m_formatter.oneByteOp(OP_CMP_EvGv, src, base, offset);
1913 }
1914
1915 void cmpl_mr(int offset, RegisterID base, RegisterID src)
1916 {
1917 m_formatter.oneByteOp(OP_CMP_GvEv, src, base, offset);
1918 }
1919
1920 void cmpl_ir(int imm, RegisterID dst)
1921 {
1922 if (CAN_SIGN_EXTEND_8_32(imm)) {
1923 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, dst);
1924 m_formatter.immediate8(imm);
1925 } else {
1926 if (dst == X86Registers::eax)
1927 m_formatter.oneByteOp(OP_CMP_EAXIv);
1928 else
1929 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
1930 m_formatter.immediate32(imm);
1931 }
1932 }
1933
1934 void cmpl_ir_force32(int imm, RegisterID dst)
1935 {
1936 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
1937 m_formatter.immediate32(imm);
1938 }
1939
1940 void cmpl_im(int imm, int offset, RegisterID base)
1941 {
1942 if (CAN_SIGN_EXTEND_8_32(imm)) {
1943 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, offset);
1944 m_formatter.immediate8(imm);
1945 } else {
1946 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, offset);
1947 m_formatter.immediate32(imm);
1948 }
1949 }
1950
1951 void cmpb_im(int imm, int offset, RegisterID base)
1952 {
1953 m_formatter.oneByteOp(OP_GROUP1_EbIb, GROUP1_OP_CMP, base, offset);
1954 m_formatter.immediate8(imm);
1955 }
1956
1957 void cmpb_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
1958 {
1959 m_formatter.oneByteOp(OP_GROUP1_EbIb, GROUP1_OP_CMP, base, index, scale, offset);
1960 m_formatter.immediate8(imm);
1961 }
1962
1963#if CPU(X86)
1964 void cmpb_im(int imm, const void* addr)
1965 {
1966 m_formatter.oneByteOpAddr(OP_GROUP1_EbIb, GROUP1_OP_CMP, bitwise_cast<uint32_t>(addr));
1967 m_formatter.immediate8(imm);
1968 }
1969#endif
1970
1971 void cmpl_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
1972 {
1973 if (CAN_SIGN_EXTEND_8_32(imm)) {
1974 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, index, scale, offset);
1975 m_formatter.immediate8(imm);
1976 } else {
1977 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, index, scale, offset);
1978 m_formatter.immediate32(imm);
1979 }
1980 }
1981
1982 void cmpl_im_force32(int imm, int offset, RegisterID base)
1983 {
1984 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, offset);
1985 m_formatter.immediate32(imm);
1986 }
1987
1988#if CPU(X86_64)
1989 void cmpq_rr(RegisterID src, RegisterID dst)
1990 {
1991 m_formatter.oneByteOp64(OP_CMP_EvGv, src, dst);
1992 }
1993
1994 void cmpq_rm(RegisterID src, int offset, RegisterID base)
1995 {
1996 m_formatter.oneByteOp64(OP_CMP_EvGv, src, base, offset);
1997 }
1998
1999 void cmpq_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
2000 {
2001 m_formatter.oneByteOp64(OP_CMP_EvGv, src, base, index, scale, offset);
2002 }
2003
2004 void cmpq_mr(int offset, RegisterID base, RegisterID src)
2005 {
2006 m_formatter.oneByteOp64(OP_CMP_GvEv, src, base, offset);
2007 }
2008
2009 void cmpq_ir(int imm, RegisterID dst)
2010 {
2011 if (CAN_SIGN_EXTEND_8_32(imm)) {
2012 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_CMP, dst);
2013 m_formatter.immediate8(imm);
2014 } else {
2015 if (dst == X86Registers::eax)
2016 m_formatter.oneByteOp64(OP_CMP_EAXIv);
2017 else
2018 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
2019 m_formatter.immediate32(imm);
2020 }
2021 }
2022
2023 void cmpq_im(int imm, int offset, RegisterID base)
2024 {
2025 if (CAN_SIGN_EXTEND_8_32(imm)) {
2026 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, offset);
2027 m_formatter.immediate8(imm);
2028 } else {
2029 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, offset);
2030 m_formatter.immediate32(imm);
2031 }
2032 }
2033
2034 void cmpq_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
2035 {
2036 if (CAN_SIGN_EXTEND_8_32(imm)) {
2037 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, index, scale, offset);
2038 m_formatter.immediate8(imm);
2039 } else {
2040 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, index, scale, offset);
2041 m_formatter.immediate32(imm);
2042 }
2043 }
2044#else
2045 void cmpl_rm(RegisterID reg, const void* addr)
2046 {
2047 m_formatter.oneByteOpAddr(OP_CMP_EvGv, reg, bitwise_cast<uint32_t>(addr));
2048 }
2049
2050 void cmpl_im(int imm, const void* addr)
2051 {
2052 if (CAN_SIGN_EXTEND_8_32(imm)) {
2053 m_formatter.oneByteOpAddr(OP_GROUP1_EvIb, GROUP1_OP_CMP, bitwise_cast<uint32_t>(addr));
2054 m_formatter.immediate8(imm);
2055 } else {
2056 m_formatter.oneByteOpAddr(OP_GROUP1_EvIz, GROUP1_OP_CMP, bitwise_cast<uint32_t>(addr));
2057 m_formatter.immediate32(imm);
2058 }
2059 }
2060#endif
2061
2062 void cmpw_ir(int imm, RegisterID dst)
2063 {
2064 if (CAN_SIGN_EXTEND_8_32(imm)) {
2065 m_formatter.prefix(PRE_OPERAND_SIZE);
2066 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, dst);
2067 m_formatter.immediate8(imm);
2068 } else {
2069 m_formatter.prefix(PRE_OPERAND_SIZE);
2070 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
2071 m_formatter.immediate16(imm);
2072 }
2073 }
2074
2075 void cmpw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
2076 {
2077 m_formatter.prefix(PRE_OPERAND_SIZE);
2078 m_formatter.oneByteOp(OP_CMP_EvGv, src, base, index, scale, offset);
2079 }
2080
2081 void cmpw_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
2082 {
2083 if (CAN_SIGN_EXTEND_8_32(imm)) {
2084 m_formatter.prefix(PRE_OPERAND_SIZE);
2085 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, index, scale, offset);
2086 m_formatter.immediate8(imm);
2087 } else {
2088 m_formatter.prefix(PRE_OPERAND_SIZE);
2089 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, index, scale, offset);
2090 m_formatter.immediate16(imm);
2091 }
2092 }
2093
2094 void testl_rr(RegisterID src, RegisterID dst)
2095 {
2096 m_formatter.oneByteOp(OP_TEST_EvGv, src, dst);
2097 }
2098
2099 void testl_i32r(int imm, RegisterID dst)
2100 {
2101 if (dst == X86Registers::eax)
2102 m_formatter.oneByteOp(OP_TEST_EAXIv);
2103 else
2104 m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, dst);
2105 m_formatter.immediate32(imm);
2106 }
2107
2108 void testl_i32m(int imm, int offset, RegisterID base)
2109 {
2110 m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, offset);
2111 m_formatter.immediate32(imm);
2112 }
2113
2114 void testb_rr(RegisterID src, RegisterID dst)
2115 {
2116 m_formatter.oneByteOp8(OP_TEST_EbGb, src, dst);
2117 }
2118
2119 void testb_im(int imm, int offset, RegisterID base)
2120 {
2121 m_formatter.oneByteOp(OP_GROUP3_EbIb, GROUP3_OP_TEST, base, offset);
2122 m_formatter.immediate8(imm);
2123 }
2124
2125 void testb_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
2126 {
2127 m_formatter.oneByteOp(OP_GROUP3_EbIb, GROUP3_OP_TEST, base, index, scale, offset);
2128 m_formatter.immediate8(imm);
2129 }
2130
2131#if CPU(X86)
2132 void testb_im(int imm, const void* addr)
2133 {
2134 m_formatter.oneByteOpAddr(OP_GROUP3_EbIb, GROUP3_OP_TEST, bitwise_cast<uint32_t>(addr));
2135 m_formatter.immediate8(imm);
2136 }
2137#endif
2138
2139 void testl_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale)
2140 {
2141 m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, index, scale, offset);
2142 m_formatter.immediate32(imm);
2143 }
2144
2145#if CPU(X86_64)
2146 void testq_rr(RegisterID src, RegisterID dst)
2147 {
2148 m_formatter.oneByteOp64(OP_TEST_EvGv, src, dst);
2149 }
2150
2151 void testq_rm(RegisterID src, int offset, RegisterID base)
2152 {
2153 m_formatter.oneByteOp64(OP_TEST_EvGv, src, base, offset);
2154 }
2155
2156 void testq_i32r(int imm, RegisterID dst)
2157 {
2158 if (dst == X86Registers::eax)
2159 m_formatter.oneByteOp64(OP_TEST_EAXIv);
2160 else
2161 m_formatter.oneByteOp64(OP_GROUP3_EvIz, GROUP3_OP_TEST, dst);
2162 m_formatter.immediate32(imm);
2163 }
2164
2165 void testq_i32m(int imm, int offset, RegisterID base)
2166 {
2167 m_formatter.oneByteOp64(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, offset);
2168 m_formatter.immediate32(imm);
2169 }
2170
2171 void testq_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale)
2172 {
2173 m_formatter.oneByteOp64(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, index, scale, offset);
2174 m_formatter.immediate32(imm);
2175 }
2176#endif
2177
2178 void testw_rr(RegisterID src, RegisterID dst)
2179 {
2180 m_formatter.prefix(PRE_OPERAND_SIZE);
2181 m_formatter.oneByteOp(OP_TEST_EvGv, src, dst);
2182 }
2183
2184 void testb_i8r(int imm, RegisterID dst)
2185 {
2186 if (dst == X86Registers::eax)
2187 m_formatter.oneByteOp(OP_TEST_ALIb);
2188 else
2189 m_formatter.oneByteOp8(OP_GROUP3_EbIb, GROUP3_OP_TEST, dst);
2190 m_formatter.immediate8(imm);
2191 }
2192
2193 void setCC_r(Condition cond, RegisterID dst)
2194 {
2195 m_formatter.twoByteOp8(setccOpcode(cond), (GroupOpcodeID)0, dst);
2196 }
2197
2198 void sete_r(RegisterID dst)
2199 {
2200 m_formatter.twoByteOp8(setccOpcode(ConditionE), (GroupOpcodeID)0, dst);
2201 }
2202
2203 void setz_r(RegisterID dst)
2204 {
2205 sete_r(dst);
2206 }
2207
2208 void setne_r(RegisterID dst)
2209 {
2210 m_formatter.twoByteOp8(setccOpcode(ConditionNE), (GroupOpcodeID)0, dst);
2211 }
2212
2213 void setnz_r(RegisterID dst)
2214 {
2215 setne_r(dst);
2216 }
2217
2218 void setnp_r(RegisterID dst)
2219 {
2220 m_formatter.twoByteOp8(setccOpcode(ConditionNP), (GroupOpcodeID)0, dst);
2221 }
2222
2223 void setp_r(RegisterID dst)
2224 {
2225 m_formatter.twoByteOp8(setccOpcode(ConditionP), (GroupOpcodeID)0, dst);
2226 }
2227
2228 // Various move ops:
2229
2230 void cdq()
2231 {
2232 m_formatter.oneByteOp(OP_CDQ);
2233 }
2234
2235#if CPU(X86_64)
2236 void cqo()
2237 {
2238 m_formatter.oneByteOp64(OP_CDQ);
2239 }
2240#endif
2241
2242 void fstps(int offset, RegisterID base)
2243 {
2244 m_formatter.oneByteOp(OP_ESCAPE_D9, ESCAPE_D9_FSTP_singleReal, base, offset);
2245 }
2246
2247 void fstpl(int offset, RegisterID base)
2248 {
2249 m_formatter.oneByteOp(OP_ESCAPE_DD, ESCAPE_DD_FSTP_doubleReal, base, offset);
2250 }
2251
2252 void xchgl_rr(RegisterID src, RegisterID dst)
2253 {
2254 if (src == X86Registers::eax)
2255 m_formatter.oneByteOp(OP_XCHG_EAX, dst);
2256 else if (dst == X86Registers::eax)
2257 m_formatter.oneByteOp(OP_XCHG_EAX, src);
2258 else
2259 m_formatter.oneByteOp(OP_XCHG_EvGv, src, dst);
2260 }
2261
2262 void xchgb_rm(RegisterID src, int offset, RegisterID base)
2263 {
2264 m_formatter.oneByteOp8(OP_XCHG_EvGb, src, base, offset);
2265 }
2266
2267 void xchgb_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
2268 {
2269 m_formatter.oneByteOp8(OP_XCHG_EvGb, src, base, index, scale, offset);
2270 }
2271
2272 void xchgw_rm(RegisterID src, int offset, RegisterID base)
2273 {
2274 m_formatter.prefix(PRE_OPERAND_SIZE);
2275 m_formatter.oneByteOp(OP_XCHG_EvGv, src, base, offset);
2276 }
2277
2278 void xchgw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
2279 {
2280 m_formatter.prefix(PRE_OPERAND_SIZE);
2281 m_formatter.oneByteOp(OP_XCHG_EvGv, src, base, index, scale, offset);
2282 }
2283
2284 void xchgl_rm(RegisterID src, int offset, RegisterID base)
2285 {
2286 m_formatter.oneByteOp(OP_XCHG_EvGv, src, base, offset);
2287 }
2288
2289 void xchgl_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
2290 {
2291 m_formatter.oneByteOp(OP_XCHG_EvGv, src, base, index, scale, offset);
2292 }
2293
2294#if CPU(X86_64)
2295 void xchgq_rr(RegisterID src, RegisterID dst)
2296 {
2297 if (src == X86Registers::eax)
2298 m_formatter.oneByteOp64(OP_XCHG_EAX, dst);
2299 else if (dst == X86Registers::eax)
2300 m_formatter.oneByteOp64(OP_XCHG_EAX, src);
2301 else
2302 m_formatter.oneByteOp64(OP_XCHG_EvGv, src, dst);
2303 }
2304
2305 void xchgq_rm(RegisterID src, int offset, RegisterID base)
2306 {
2307 m_formatter.oneByteOp64(OP_XCHG_EvGv, src, base, offset);
2308 }
2309
2310 void xchgq_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
2311 {
2312 m_formatter.oneByteOp64(OP_XCHG_EvGv, src, base, index, scale, offset);
2313 }
2314#endif
2315
2316 void movl_rr(RegisterID src, RegisterID dst)
2317 {
2318 m_formatter.oneByteOp(OP_MOV_EvGv, src, dst);
2319 }
2320
2321 void movl_rm(RegisterID src, int offset, RegisterID base)
2322 {
2323 m_formatter.oneByteOp(OP_MOV_EvGv, src, base, offset);
2324 }
2325
2326 void movl_rm_disp32(RegisterID src, int offset, RegisterID base)
2327 {
2328 m_formatter.oneByteOp_disp32(OP_MOV_EvGv, src, base, offset);
2329 }
2330
2331 void movl_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
2332 {
2333 m_formatter.oneByteOp(OP_MOV_EvGv, src, base, index, scale, offset);
2334 }
2335
2336 void movl_mEAX(const void* addr)
2337 {
2338 m_formatter.oneByteOp(OP_MOV_EAXOv);
2339#if CPU(X86_64)
2340 m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
2341#else
2342 m_formatter.immediate32(reinterpret_cast<int>(addr));
2343#endif
2344 }
2345
2346 void movl_mr(int offset, RegisterID base, RegisterID dst)
2347 {
2348 m_formatter.oneByteOp(OP_MOV_GvEv, dst, base, offset);
2349 }
2350
2351 void movl_mr_disp32(int offset, RegisterID base, RegisterID dst)
2352 {
2353 m_formatter.oneByteOp_disp32(OP_MOV_GvEv, dst, base, offset);
2354 }
2355
2356 void movl_mr_disp8(int offset, RegisterID base, RegisterID dst)
2357 {
2358 m_formatter.oneByteOp_disp8(OP_MOV_GvEv, dst, base, offset);
2359 }
2360
2361 void movl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
2362 {
2363 m_formatter.oneByteOp(OP_MOV_GvEv, dst, base, index, scale, offset);
2364 }
2365
2366 void movl_i32r(int imm, RegisterID dst)
2367 {
2368 m_formatter.oneByteOp(OP_MOV_EAXIv, dst);
2369 m_formatter.immediate32(imm);
2370 }
2371
2372 void movl_i32m(int imm, int offset, RegisterID base)
2373 {
2374 m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, base, offset);
2375 m_formatter.immediate32(imm);
2376 }
2377
2378 void movl_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale)
2379 {
2380 m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, base, index, scale, offset);
2381 m_formatter.immediate32(imm);
2382 }
2383
2384#if !CPU(X86_64)
2385 void movb_i8m(int imm, const void* addr)
2386 {
2387 ASSERT(-128 <= imm && imm < 128);
2388 m_formatter.oneByteOpAddr(OP_GROUP11_EvIb, GROUP11_MOV, bitwise_cast<uint32_t>(addr));
2389 m_formatter.immediate8(imm);
2390 }
2391#endif
2392
2393 void movb_i8m(int imm, int offset, RegisterID base)
2394 {
2395 ASSERT(-128 <= imm && imm < 128);
2396 m_formatter.oneByteOp(OP_GROUP11_EvIb, GROUP11_MOV, base, offset);
2397 m_formatter.immediate8(imm);
2398 }
2399
2400 void movb_i8m(int imm, int offset, RegisterID base, RegisterID index, int scale)
2401 {
2402 ASSERT(-128 <= imm && imm < 128);
2403 m_formatter.oneByteOp(OP_GROUP11_EvIb, GROUP11_MOV, base, index, scale, offset);
2404 m_formatter.immediate8(imm);
2405 }
2406
2407#if !CPU(X86_64)
2408 void movb_rm(RegisterID src, const void* addr)
2409 {
2410 m_formatter.oneByteOpAddr(OP_MOV_EbGb, src, bitwise_cast<uint32_t>(addr));
2411 }
2412#endif
2413
2414 void movb_rm(RegisterID src, int offset, RegisterID base)
2415 {
2416 m_formatter.oneByteOp8(OP_MOV_EbGb, src, base, offset);
2417 }
2418
2419 void movb_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
2420 {
2421 m_formatter.oneByteOp8(OP_MOV_EbGb, src, base, index, scale, offset);
2422 }
2423
2424 void movw_rm(RegisterID src, int offset, RegisterID base)
2425 {
2426 m_formatter.prefix(PRE_OPERAND_SIZE);
2427
2428 // FIXME: We often use oneByteOp8 for 16-bit operations. It's not clear that this is
2429 // necessary. https://bugs.webkit.org/show_bug.cgi?id=153433
2430 m_formatter.oneByteOp8(OP_MOV_EvGv, src, base, offset);
2431 }
2432
2433 void movw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
2434 {
2435 m_formatter.prefix(PRE_OPERAND_SIZE);
2436 m_formatter.oneByteOp8(OP_MOV_EvGv, src, base, index, scale, offset);
2437 }
2438
2439 void movw_im(int imm, int offset, RegisterID base)
2440 {
2441 m_formatter.prefix(PRE_OPERAND_SIZE);
2442 m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, base, offset);
2443 m_formatter.immediate16(imm);
2444 }
2445
2446 void movw_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
2447 {
2448 m_formatter.prefix(PRE_OPERAND_SIZE);
2449 m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, base, index, scale, offset);
2450 m_formatter.immediate16(imm);
2451 }
2452
2453 void movl_EAXm(const void* addr)
2454 {
2455 m_formatter.oneByteOp(OP_MOV_OvEAX);
2456#if CPU(X86_64)
2457 m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
2458#else
2459 m_formatter.immediate32(reinterpret_cast<int>(addr));
2460#endif
2461 }
2462
2463 void movl_mr(uint32_t addr, RegisterID dst)
2464 {
2465 m_formatter.oneByteOpAddr(OP_MOV_GvEv, dst, addr);
2466 }
2467
2468 void movl_rm(RegisterID src, uint32_t addr)
2469 {
2470 m_formatter.oneByteOpAddr(OP_MOV_EvGv, src, addr);
2471 }
2472
2473#if CPU(X86_64)
2474 void movq_rr(RegisterID src, RegisterID dst)
2475 {
2476 m_formatter.oneByteOp64(OP_MOV_EvGv, src, dst);
2477 }
2478
2479 void movq_rm(RegisterID src, int offset, RegisterID base)
2480 {
2481 m_formatter.oneByteOp64(OP_MOV_EvGv, src, base, offset);
2482 }
2483
2484 void movq_rm_disp32(RegisterID src, int offset, RegisterID base)
2485 {
2486 m_formatter.oneByteOp64_disp32(OP_MOV_EvGv, src, base, offset);
2487 }
2488
2489 void movq_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
2490 {
2491 m_formatter.oneByteOp64(OP_MOV_EvGv, src, base, index, scale, offset);
2492 }
2493
2494 void movq_rm(RegisterID src, int offset)
2495 {
2496 m_formatter.oneByteOp64Addr(OP_MOV_EvGv, src, offset);
2497 }
2498
2499 void movq_mEAX(const void* addr)
2500 {
2501 m_formatter.oneByteOp64(OP_MOV_EAXOv);
2502 m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
2503 }
2504
2505 void movq_EAXm(const void* addr)
2506 {
2507 m_formatter.oneByteOp64(OP_MOV_OvEAX);
2508 m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
2509 }
2510
2511 void movq_mr(int offset, RegisterID base, RegisterID dst)
2512 {
2513 m_formatter.oneByteOp64(OP_MOV_GvEv, dst, base, offset);
2514 }
2515
2516 void movq_mr_disp32(int offset, RegisterID base, RegisterID dst)
2517 {
2518 m_formatter.oneByteOp64_disp32(OP_MOV_GvEv, dst, base, offset);
2519 }
2520
2521 void movq_mr_disp8(int offset, RegisterID base, RegisterID dst)
2522 {
2523 m_formatter.oneByteOp64_disp8(OP_MOV_GvEv, dst, base, offset);
2524 }
2525
2526 void movq_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
2527 {
2528 m_formatter.oneByteOp64(OP_MOV_GvEv, dst, base, index, scale, offset);
2529 }
2530
2531 void movq_mr(uint32_t addr, RegisterID dst)
2532 {
2533 m_formatter.oneByteOp64Addr(OP_MOV_GvEv, dst, addr);
2534 }
2535
2536 void movq_i32m(int imm, int offset, RegisterID base)
2537 {
2538 m_formatter.oneByteOp64(OP_GROUP11_EvIz, GROUP11_MOV, base, offset);
2539 m_formatter.immediate32(imm);
2540 }
2541
2542 void movq_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale)
2543 {
2544 m_formatter.oneByteOp64(OP_GROUP11_EvIz, GROUP11_MOV, base, index, scale, offset);
2545 m_formatter.immediate32(imm);
2546 }
2547
2548 void movq_i64r(int64_t imm, RegisterID dst)
2549 {
2550 m_formatter.oneByteOp64(OP_MOV_EAXIv, dst);
2551 m_formatter.immediate64(imm);
2552 }
2553
2554 void mov_i32r(int32_t imm, RegisterID dst)
2555 {
2556 m_formatter.oneByteOp64(OP_GROUP11_EvIz, GROUP11_MOV, dst);
2557 m_formatter.immediate32(imm);
2558 }
2559
2560 void movsxd_rr(RegisterID src, RegisterID dst)
2561 {
2562 m_formatter.oneByteOp64(OP_MOVSXD_GvEv, dst, src);
2563 }
2564#else
2565 void movl_mr(const void* addr, RegisterID dst)
2566 {
2567 if (dst == X86Registers::eax)
2568 movl_mEAX(addr);
2569 else
2570 m_formatter.oneByteOpAddr(OP_MOV_GvEv, dst, bitwise_cast<uint32_t>(addr));
2571 }
2572
2573 void movl_rm(RegisterID src, const void* addr)
2574 {
2575 if (src == X86Registers::eax)
2576 movl_EAXm(addr);
2577 else
2578 m_formatter.oneByteOpAddr(OP_MOV_EvGv, src, bitwise_cast<uint32_t>(addr));
2579 }
2580
2581 void movl_i32m(int imm, const void* addr)
2582 {
2583 m_formatter.oneByteOpAddr(OP_GROUP11_EvIz, GROUP11_MOV, bitwise_cast<uint32_t>(addr));
2584 m_formatter.immediate32(imm);
2585 }
2586#endif
2587
2588 void movzwl_mr(int offset, RegisterID base, RegisterID dst)
2589 {
2590 m_formatter.twoByteOp(OP2_MOVZX_GvEw, dst, base, offset);
2591 }
2592
2593 void movzwl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
2594 {
2595 m_formatter.twoByteOp(OP2_MOVZX_GvEw, dst, base, index, scale, offset);
2596 }
2597
2598 void movswl_mr(int offset, RegisterID base, RegisterID dst)
2599 {
2600 m_formatter.twoByteOp(OP2_MOVSX_GvEw, dst, base, offset);
2601 }
2602
2603 void movswl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
2604 {
2605 m_formatter.twoByteOp(OP2_MOVSX_GvEw, dst, base, index, scale, offset);
2606 }
2607
2608 void movzbl_mr(int offset, RegisterID base, RegisterID dst)
2609 {
2610 m_formatter.twoByteOp(OP2_MOVZX_GvEb, dst, base, offset);
2611 }
2612
2613 void movzbl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
2614 {
2615 m_formatter.twoByteOp(OP2_MOVZX_GvEb, dst, base, index, scale, offset);
2616 }
2617
2618#if !CPU(X86_64)
2619 void movzbl_mr(const void* address, RegisterID dst)
2620 {
2621 m_formatter.twoByteOpAddr(OP2_MOVZX_GvEb, dst, bitwise_cast<uint32_t>(address));
2622 }
2623#endif
2624
2625 void movsbl_mr(int offset, RegisterID base, RegisterID dst)
2626 {
2627 m_formatter.twoByteOp(OP2_MOVSX_GvEb, dst, base, offset);
2628 }
2629
2630 void movsbl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
2631 {
2632 m_formatter.twoByteOp(OP2_MOVSX_GvEb, dst, base, index, scale, offset);
2633 }
2634
2635 void movzbl_rr(RegisterID src, RegisterID dst)
2636 {
2637 // In 64-bit, this may cause an unnecessary REX to be planted (if the dst register
2638 // is in the range ESP-EDI, and the src would not have required a REX). Unneeded
2639 // REX prefixes are defined to be silently ignored by the processor.
2640 m_formatter.twoByteOp8(OP2_MOVZX_GvEb, dst, src);
2641 }
2642
2643 void movsbl_rr(RegisterID src, RegisterID dst)
2644 {
2645 m_formatter.twoByteOp8(OP2_MOVSX_GvEb, dst, src);
2646 }
2647
2648 void movzwl_rr(RegisterID src, RegisterID dst)
2649 {
2650 m_formatter.twoByteOp8(OP2_MOVZX_GvEw, dst, src);
2651 }
2652
2653 void movswl_rr(RegisterID src, RegisterID dst)
2654 {
2655 m_formatter.twoByteOp8(OP2_MOVSX_GvEw, dst, src);
2656 }
2657
2658 void cmovl_rr(Condition cond, RegisterID src, RegisterID dst)
2659 {
2660 m_formatter.twoByteOp(cmovcc(cond), dst, src);
2661 }
2662
2663 void cmovl_mr(Condition cond, int offset, RegisterID base, RegisterID dst)
2664 {
2665 m_formatter.twoByteOp(cmovcc(cond), dst, base, offset);
2666 }
2667
2668 void cmovl_mr(Condition cond, int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
2669 {
2670 m_formatter.twoByteOp(cmovcc(cond), dst, base, index, scale, offset);
2671 }
2672
2673 void cmovel_rr(RegisterID src, RegisterID dst)
2674 {
2675 m_formatter.twoByteOp(cmovcc(ConditionE), dst, src);
2676 }
2677
2678 void cmovnel_rr(RegisterID src, RegisterID dst)
2679 {
2680 m_formatter.twoByteOp(cmovcc(ConditionNE), dst, src);
2681 }
2682
2683 void cmovpl_rr(RegisterID src, RegisterID dst)
2684 {
2685 m_formatter.twoByteOp(cmovcc(ConditionP), dst, src);
2686 }
2687
2688 void cmovnpl_rr(RegisterID src, RegisterID dst)
2689 {
2690 m_formatter.twoByteOp(cmovcc(ConditionNP), dst, src);
2691 }
2692
2693#if CPU(X86_64)
2694 void cmovq_rr(Condition cond, RegisterID src, RegisterID dst)
2695 {
2696 m_formatter.twoByteOp64(cmovcc(cond), dst, src);
2697 }
2698
2699 void cmovq_mr(Condition cond, int offset, RegisterID base, RegisterID dst)
2700 {
2701 m_formatter.twoByteOp64(cmovcc(cond), dst, base, offset);
2702 }
2703
2704 void cmovq_mr(Condition cond, int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
2705 {
2706 m_formatter.twoByteOp64(cmovcc(cond), dst, base, index, scale, offset);
2707 }
2708
2709 void cmoveq_rr(RegisterID src, RegisterID dst)
2710 {
2711 m_formatter.twoByteOp64(cmovcc(ConditionE), dst, src);
2712 }
2713
2714 void cmovneq_rr(RegisterID src, RegisterID dst)
2715 {
2716 m_formatter.twoByteOp64(cmovcc(ConditionNE), dst, src);
2717 }
2718
2719 void cmovpq_rr(RegisterID src, RegisterID dst)
2720 {
2721 m_formatter.twoByteOp64(cmovcc(ConditionP), dst, src);
2722 }
2723
2724 void cmovnpq_rr(RegisterID src, RegisterID dst)
2725 {
2726 m_formatter.twoByteOp64(cmovcc(ConditionNP), dst, src);
2727 }
2728#else
2729 void cmovl_mr(Condition cond, const void* addr, RegisterID dst)
2730 {
2731 m_formatter.twoByteOpAddr(cmovcc(cond), dst, bitwise_cast<uint32_t>(addr));
2732 }
2733#endif
2734
2735 void leal_mr(int offset, RegisterID base, RegisterID dst)
2736 {
2737 m_formatter.oneByteOp(OP_LEA, dst, base, offset);
2738 }
2739
2740 void leal_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
2741 {
2742 m_formatter.oneByteOp(OP_LEA, dst, base, index, scale, offset);
2743 }
2744
2745#if CPU(X86_64)
2746 void leaq_mr(int offset, RegisterID base, RegisterID dst)
2747 {
2748 m_formatter.oneByteOp64(OP_LEA, dst, base, offset);
2749 }
2750
2751 void leaq_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
2752 {
2753 m_formatter.oneByteOp64(OP_LEA, dst, base, index, scale, offset);
2754 }
2755#endif
2756
2757 // Flow control:
2758
2759 AssemblerLabel call()
2760 {
2761 m_formatter.oneByteOp(OP_CALL_rel32);
2762 return m_formatter.immediateRel32();
2763 }
2764
2765 AssemblerLabel call(RegisterID dst)
2766 {
2767 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_CALLN, dst);
2768 return m_formatter.label();
2769 }
2770
2771 void call_m(int offset, RegisterID base)
2772 {
2773 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_CALLN, base, offset);
2774 }
2775
2776 AssemblerLabel jmp()
2777 {
2778 m_formatter.oneByteOp(OP_JMP_rel32);
2779 return m_formatter.immediateRel32();
2780 }
2781
2782 // Return a AssemblerLabel so we have a label to the jump, so we can use this
2783 // To make a tail recursive call on x86-64. The MacroAssembler
2784 // really shouldn't wrap this as a Jump, since it can't be linked. :-/
2785 AssemblerLabel jmp_r(RegisterID dst)
2786 {
2787 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, dst);
2788 return m_formatter.label();
2789 }
2790
2791 void jmp_m(int offset, RegisterID base)
2792 {
2793 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, base, offset);
2794 }
2795
2796 void jmp_m(int offset, RegisterID base, RegisterID index, int scale)
2797 {
2798 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, base, index, scale, offset);
2799 }
2800
2801#if !CPU(X86_64)
2802 void jmp_m(const void* address)
2803 {
2804 m_formatter.oneByteOpAddr(OP_GROUP5_Ev, GROUP5_OP_JMPN, bitwise_cast<uint32_t>(address));
2805 }
2806#endif
2807
2808 AssemblerLabel jne()
2809 {
2810 m_formatter.twoByteOp(jccRel32(ConditionNE));
2811 return m_formatter.immediateRel32();
2812 }
2813
2814 AssemblerLabel jnz()
2815 {
2816 return jne();
2817 }
2818
2819 AssemblerLabel je()
2820 {
2821 m_formatter.twoByteOp(jccRel32(ConditionE));
2822 return m_formatter.immediateRel32();
2823 }
2824
2825 AssemblerLabel jz()
2826 {
2827 return je();
2828 }
2829
2830 AssemblerLabel jl()
2831 {
2832 m_formatter.twoByteOp(jccRel32(ConditionL));
2833 return m_formatter.immediateRel32();
2834 }
2835
2836 AssemblerLabel jb()
2837 {
2838 m_formatter.twoByteOp(jccRel32(ConditionB));
2839 return m_formatter.immediateRel32();
2840 }
2841
2842 AssemblerLabel jle()
2843 {
2844 m_formatter.twoByteOp(jccRel32(ConditionLE));
2845 return m_formatter.immediateRel32();
2846 }
2847
2848 AssemblerLabel jbe()
2849 {
2850 m_formatter.twoByteOp(jccRel32(ConditionBE));
2851 return m_formatter.immediateRel32();
2852 }
2853
2854 AssemblerLabel jge()
2855 {
2856 m_formatter.twoByteOp(jccRel32(ConditionGE));
2857 return m_formatter.immediateRel32();
2858 }
2859
2860 AssemblerLabel jg()
2861 {
2862 m_formatter.twoByteOp(jccRel32(ConditionG));
2863 return m_formatter.immediateRel32();
2864 }
2865
2866 AssemblerLabel ja()
2867 {
2868 m_formatter.twoByteOp(jccRel32(ConditionA));
2869 return m_formatter.immediateRel32();
2870 }
2871
2872 AssemblerLabel jae()
2873 {
2874 m_formatter.twoByteOp(jccRel32(ConditionAE));
2875 return m_formatter.immediateRel32();
2876 }
2877
2878 AssemblerLabel jo()
2879 {
2880 m_formatter.twoByteOp(jccRel32(ConditionO));
2881 return m_formatter.immediateRel32();
2882 }
2883
2884 AssemblerLabel jnp()
2885 {
2886 m_formatter.twoByteOp(jccRel32(ConditionNP));
2887 return m_formatter.immediateRel32();
2888 }
2889
2890 AssemblerLabel jp()
2891 {
2892 m_formatter.twoByteOp(jccRel32(ConditionP));
2893 return m_formatter.immediateRel32();
2894 }
2895
2896 AssemblerLabel js()
2897 {
2898 m_formatter.twoByteOp(jccRel32(ConditionS));
2899 return m_formatter.immediateRel32();
2900 }
2901
2902 AssemblerLabel jCC(Condition cond)
2903 {
2904 m_formatter.twoByteOp(jccRel32(cond));
2905 return m_formatter.immediateRel32();
2906 }
2907
2908 // SSE operations:
2909
2910 void addsd_rr(XMMRegisterID src, XMMRegisterID dst)
2911 {
2912 m_formatter.prefix(PRE_SSE_F2);
2913 m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
2914 }
2915
2916 void vaddsd_rr(XMMRegisterID a, XMMRegisterID b, XMMRegisterID dst)
2917 {
2918 m_formatter.vexNdsLigWigCommutativeTwoByteOp(PRE_SSE_F2, OP2_ADDSD_VsdWsd, (RegisterID)dst, (RegisterID)a, (RegisterID)b);
2919 }
2920
2921 void addsd_mr(int offset, RegisterID base, XMMRegisterID dst)
2922 {
2923 m_formatter.prefix(PRE_SSE_F2);
2924 m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, base, offset);
2925 }
2926
2927 void addsd_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
2928 {
2929 m_formatter.prefix(PRE_SSE_F2);
2930 m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, dst, base, index, scale, offset);
2931 }
2932
2933 void vaddsd_mr(int offset, RegisterID base, XMMRegisterID b, XMMRegisterID dst)
2934 {
2935 m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F2, OP2_ADDSD_VsdWsd, (RegisterID)dst, (RegisterID)b, base, offset);
2936 }
2937
2938 void vaddsd_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID b, XMMRegisterID dst)
2939 {
2940 m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F2, OP2_ADDSD_VsdWsd, (RegisterID)dst, (RegisterID)b, offset, base, index, scale);
2941 }
2942
2943 void addss_rr(XMMRegisterID src, XMMRegisterID dst)
2944 {
2945 m_formatter.prefix(PRE_SSE_F3);
2946 m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
2947 }
2948
2949 void vaddss_rr(XMMRegisterID a, XMMRegisterID b, XMMRegisterID dst)
2950 {
2951 m_formatter.vexNdsLigWigCommutativeTwoByteOp(PRE_SSE_F3, OP2_ADDSD_VsdWsd, (RegisterID)dst, (RegisterID)a, (RegisterID)b);
2952 }
2953
2954 void addss_mr(int offset, RegisterID base, XMMRegisterID dst)
2955 {
2956 m_formatter.prefix(PRE_SSE_F3);
2957 m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, base, offset);
2958 }
2959
2960 void addss_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
2961 {
2962 m_formatter.prefix(PRE_SSE_F3);
2963 m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, dst, base, index, scale, offset);
2964 }
2965
2966 void vaddss_mr(int offset, RegisterID base, XMMRegisterID b, XMMRegisterID dst)
2967 {
2968 m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F3, OP2_ADDSD_VsdWsd, (RegisterID)dst, (RegisterID)b, base, offset);
2969 }
2970
2971 void vaddss_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID b, XMMRegisterID dst)
2972 {
2973 m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F3, OP2_ADDSD_VsdWsd, (RegisterID)dst, (RegisterID)b, offset, base, index, scale);
2974 }
2975
2976#if !CPU(X86_64)
2977 void addsd_mr(const void* address, XMMRegisterID dst)
2978 {
2979 m_formatter.prefix(PRE_SSE_F2);
2980 m_formatter.twoByteOpAddr(OP2_ADDSD_VsdWsd, (RegisterID)dst, bitwise_cast<uint32_t>(address));
2981 }
2982#endif
2983
2984 void cvtsi2sd_rr(RegisterID src, XMMRegisterID dst)
2985 {
2986 m_formatter.prefix(PRE_SSE_F2);
2987 m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, src);
2988 }
2989
2990 void cvtsi2ss_rr(RegisterID src, XMMRegisterID dst)
2991 {
2992 m_formatter.prefix(PRE_SSE_F3);
2993 m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, src);
2994 }
2995
2996#if CPU(X86_64)
2997 void cvtsi2sdq_rr(RegisterID src, XMMRegisterID dst)
2998 {
2999 m_formatter.prefix(PRE_SSE_F2);
3000 m_formatter.twoByteOp64(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, src);
3001 }
3002
3003 void cvtsi2ssq_rr(RegisterID src, XMMRegisterID dst)
3004 {
3005 m_formatter.prefix(PRE_SSE_F3);
3006 m_formatter.twoByteOp64(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, src);
3007 }
3008
3009 void cvtsi2sdq_mr(int offset, RegisterID base, XMMRegisterID dst)
3010 {
3011 m_formatter.prefix(PRE_SSE_F2);
3012 m_formatter.twoByteOp64(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, base, offset);
3013 }
3014
3015 void cvtsi2ssq_mr(int offset, RegisterID base, XMMRegisterID dst)
3016 {
3017 m_formatter.prefix(PRE_SSE_F3);
3018 m_formatter.twoByteOp64(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, base, offset);
3019 }
3020#endif
3021
3022 void cvtsi2sd_mr(int offset, RegisterID base, XMMRegisterID dst)
3023 {
3024 m_formatter.prefix(PRE_SSE_F2);
3025 m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, base, offset);
3026 }
3027
3028 void cvtsi2ss_mr(int offset, RegisterID base, XMMRegisterID dst)
3029 {
3030 m_formatter.prefix(PRE_SSE_F3);
3031 m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, base, offset);
3032 }
3033
3034#if !CPU(X86_64)
3035 void cvtsi2sd_mr(const void* address, XMMRegisterID dst)
3036 {
3037 m_formatter.prefix(PRE_SSE_F2);
3038 m_formatter.twoByteOpAddr(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, bitwise_cast<uint32_t>(address));
3039 }
3040#endif
3041
3042 void cvttsd2si_rr(XMMRegisterID src, RegisterID dst)
3043 {
3044 m_formatter.prefix(PRE_SSE_F2);
3045 m_formatter.twoByteOp(OP2_CVTTSD2SI_GdWsd, dst, (RegisterID)src);
3046 }
3047
3048 void cvttss2si_rr(XMMRegisterID src, RegisterID dst)
3049 {
3050 m_formatter.prefix(PRE_SSE_F3);
3051 m_formatter.twoByteOp(OP2_CVTTSS2SI_GdWsd, dst, (RegisterID)src);
3052 }
3053
3054#if CPU(X86_64)
3055 void cvttss2siq_rr(XMMRegisterID src, RegisterID dst)
3056 {
3057 m_formatter.prefix(PRE_SSE_F3);
3058 m_formatter.twoByteOp64(OP2_CVTTSS2SI_GdWsd, dst, (RegisterID)src);
3059 }
3060#endif
3061
3062 void cvtsd2ss_rr(XMMRegisterID src, XMMRegisterID dst)
3063 {
3064 m_formatter.prefix(PRE_SSE_F2);
3065 m_formatter.twoByteOp(OP2_CVTSD2SS_VsdWsd, dst, (RegisterID)src);
3066 }
3067
3068 void cvtsd2ss_mr(int offset, RegisterID base, XMMRegisterID dst)
3069 {
3070 m_formatter.prefix(PRE_SSE_F2);
3071 m_formatter.twoByteOp(OP2_CVTSD2SS_VsdWsd, dst, base, offset);
3072 }
3073
3074 void cvtss2sd_rr(XMMRegisterID src, XMMRegisterID dst)
3075 {
3076 m_formatter.prefix(PRE_SSE_F3);
3077 m_formatter.twoByteOp(OP2_CVTSS2SD_VsdWsd, dst, (RegisterID)src);
3078 }
3079
3080 void cvtss2sd_mr(int offset, RegisterID base, XMMRegisterID dst)
3081 {
3082 m_formatter.prefix(PRE_SSE_F3);
3083 m_formatter.twoByteOp(OP2_CVTSS2SD_VsdWsd, dst, base, offset);
3084 }
3085
3086#if CPU(X86_64)
3087 void cvttsd2siq_rr(XMMRegisterID src, RegisterID dst)
3088 {
3089 m_formatter.prefix(PRE_SSE_F2);
3090 m_formatter.twoByteOp64(OP2_CVTTSD2SI_GdWsd, dst, (RegisterID)src);
3091 }
3092#endif
3093
3094 void movd_rr(XMMRegisterID src, RegisterID dst)
3095 {
3096 m_formatter.prefix(PRE_SSE_66);
3097 m_formatter.twoByteOp(OP2_MOVD_EdVd, (RegisterID)src, dst);
3098 }
3099
3100 void movd_rr(RegisterID src, XMMRegisterID dst)
3101 {
3102 m_formatter.prefix(PRE_SSE_66);
3103 m_formatter.twoByteOp(OP2_MOVD_VdEd, (RegisterID)dst, src);
3104 }
3105
3106#if CPU(X86_64)
3107 void movmskpd_rr(XMMRegisterID src, RegisterID dst)
3108 {
3109 m_formatter.prefix(PRE_SSE_66);
3110 m_formatter.twoByteOp64(OP2_MOVMSKPD_VdEd, dst, (RegisterID)src);
3111 }
3112
3113 void movq_rr(XMMRegisterID src, RegisterID dst)
3114 {
3115 m_formatter.prefix(PRE_SSE_66);
3116 m_formatter.twoByteOp64(OP2_MOVD_EdVd, (RegisterID)src, dst);
3117 }
3118
3119 void movq_rr(RegisterID src, XMMRegisterID dst)
3120 {
3121 m_formatter.prefix(PRE_SSE_66);
3122 m_formatter.twoByteOp64(OP2_MOVD_VdEd, (RegisterID)dst, src);
3123 }
3124#endif
3125
3126 void movapd_rr(XMMRegisterID src, XMMRegisterID dst)
3127 {
3128 m_formatter.prefix(PRE_SSE_66);
3129 m_formatter.twoByteOp(OP2_MOVAPD_VpdWpd, (RegisterID)dst, (RegisterID)src);
3130 }
3131
3132 void movaps_rr(XMMRegisterID src, XMMRegisterID dst)
3133 {
3134 m_formatter.twoByteOp(OP2_MOVAPS_VpdWpd, (RegisterID)dst, (RegisterID)src);
3135 }
3136
3137 void movsd_rr(XMMRegisterID src, XMMRegisterID dst)
3138 {
3139 m_formatter.prefix(PRE_SSE_F2);
3140 m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
3141 }
3142
3143 void movsd_rm(XMMRegisterID src, int offset, RegisterID base)
3144 {
3145 m_formatter.prefix(PRE_SSE_F2);
3146 m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, offset);
3147 }
3148
3149 void movsd_rm(XMMRegisterID src, int offset, RegisterID base, RegisterID index, int scale)
3150 {
3151 m_formatter.prefix(PRE_SSE_F2);
3152 m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, index, scale, offset);
3153 }
3154
3155 void movss_rm(XMMRegisterID src, int offset, RegisterID base)
3156 {
3157 m_formatter.prefix(PRE_SSE_F3);
3158 m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, offset);
3159 }
3160
3161 void movss_rm(XMMRegisterID src, int offset, RegisterID base, RegisterID index, int scale)
3162 {
3163 m_formatter.prefix(PRE_SSE_F3);
3164 m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, index, scale, offset);
3165 }
3166
3167 void movsd_mr(int offset, RegisterID base, XMMRegisterID dst)
3168 {
3169 m_formatter.prefix(PRE_SSE_F2);
3170 m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, base, offset);
3171 }
3172
3173 void movsd_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
3174 {
3175 m_formatter.prefix(PRE_SSE_F2);
3176 m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, dst, base, index, scale, offset);
3177 }
3178
3179 void movss_mr(int offset, RegisterID base, XMMRegisterID dst)
3180 {
3181 m_formatter.prefix(PRE_SSE_F3);
3182 m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, base, offset);
3183 }
3184
3185 void movss_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
3186 {
3187 m_formatter.prefix(PRE_SSE_F3);
3188 m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, dst, base, index, scale, offset);
3189 }
3190
3191#if !CPU(X86_64)
3192 void movsd_mr(const void* address, XMMRegisterID dst)
3193 {
3194 m_formatter.prefix(PRE_SSE_F2);
3195 m_formatter.twoByteOpAddr(OP2_MOVSD_VsdWsd, (RegisterID)dst, bitwise_cast<uint32_t>(address));
3196 }
3197 void movsd_rm(XMMRegisterID src, const void* address)
3198 {
3199 m_formatter.prefix(PRE_SSE_F2);
3200 m_formatter.twoByteOpAddr(OP2_MOVSD_WsdVsd, (RegisterID)src, bitwise_cast<uint32_t>(address));
3201 }
3202 void movss_mr(const void* address, XMMRegisterID dst)
3203 {
3204 m_formatter.prefix(PRE_SSE_F3);
3205 m_formatter.twoByteOpAddr(OP2_MOVSD_VsdWsd, (RegisterID)dst, bitwise_cast<uint32_t>(address));
3206 }
3207 void movss_rm(XMMRegisterID src, const void* address)
3208 {
3209 m_formatter.prefix(PRE_SSE_F3);
3210 m_formatter.twoByteOpAddr(OP2_MOVSD_WsdVsd, (RegisterID)src, bitwise_cast<uint32_t>(address));
3211 }
3212#endif
3213
3214 void mulsd_rr(XMMRegisterID src, XMMRegisterID dst)
3215 {
3216 m_formatter.prefix(PRE_SSE_F2);
3217 m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
3218 }
3219
3220 void vmulsd_rr(XMMRegisterID a, XMMRegisterID b, XMMRegisterID dst)
3221 {
3222 m_formatter.vexNdsLigWigCommutativeTwoByteOp(PRE_SSE_F2, OP2_MULSD_VsdWsd, (RegisterID)dst, (RegisterID)a, (RegisterID)b);
3223 }
3224
3225 void mulsd_mr(int offset, RegisterID base, XMMRegisterID dst)
3226 {
3227 m_formatter.prefix(PRE_SSE_F2);
3228 m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)dst, base, offset);
3229 }
3230
3231 void mulsd_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
3232 {
3233 m_formatter.prefix(PRE_SSE_F2);
3234 m_formatter.twoByteOp(OP2_MULSD_VsdWsd, dst, base, index, scale, offset);
3235 }
3236
3237 void vmulsd_mr(int offset, RegisterID base, XMMRegisterID b, XMMRegisterID dst)
3238 {
3239 m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F2, OP2_MULSD_VsdWsd, (RegisterID)dst, (RegisterID)b, base, offset);
3240 }
3241
3242 void vmulsd_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID b, XMMRegisterID dst)
3243 {
3244 m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F2, OP2_MULSD_VsdWsd, (RegisterID)dst, (RegisterID)b, offset, base, index, scale);
3245 }
3246
3247 void mulss_rr(XMMRegisterID src, XMMRegisterID dst)
3248 {
3249 m_formatter.prefix(PRE_SSE_F3);
3250 m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
3251 }
3252
3253 void vmulss_rr(XMMRegisterID a, XMMRegisterID b, XMMRegisterID dst)
3254 {
3255 m_formatter.vexNdsLigWigCommutativeTwoByteOp(PRE_SSE_F3, OP2_MULSD_VsdWsd, (RegisterID)dst, (RegisterID)a, (RegisterID)b);
3256 }
3257
3258 void mulss_mr(int offset, RegisterID base, XMMRegisterID dst)
3259 {
3260 m_formatter.prefix(PRE_SSE_F3);
3261 m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)dst, base, offset);
3262 }
3263
3264 void mulss_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
3265 {
3266 m_formatter.prefix(PRE_SSE_F3);
3267 m_formatter.twoByteOp(OP2_MULSD_VsdWsd, dst, base, index, scale, offset);
3268 }
3269
3270 void vmulss_mr(int offset, RegisterID base, XMMRegisterID b, XMMRegisterID dst)
3271 {
3272 m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F3, OP2_MULSD_VsdWsd, (RegisterID)dst, (RegisterID)b, base, offset);
3273 }
3274
3275 void vmulss_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID b, XMMRegisterID dst)
3276 {
3277 m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F3, OP2_MULSD_VsdWsd, (RegisterID)dst, (RegisterID)b, offset, base, index, scale);
3278 }
3279
3280 void pextrw_irr(int whichWord, XMMRegisterID src, RegisterID dst)
3281 {
3282 m_formatter.prefix(PRE_SSE_66);
3283 m_formatter.twoByteOp(OP2_PEXTRW_GdUdIb, (RegisterID)dst, (RegisterID)src);
3284 m_formatter.immediate8(whichWord);
3285 }
3286
3287 void psllq_i8r(int imm, XMMRegisterID dst)
3288 {
3289 m_formatter.prefix(PRE_SSE_66);
3290 m_formatter.twoByteOp8(OP2_PSLLQ_UdqIb, GROUP14_OP_PSLLQ, (RegisterID)dst);
3291 m_formatter.immediate8(imm);
3292 }
3293
3294 void psrlq_i8r(int imm, XMMRegisterID dst)
3295 {
3296 m_formatter.prefix(PRE_SSE_66);
3297 m_formatter.twoByteOp8(OP2_PSRLQ_UdqIb, GROUP14_OP_PSRLQ, (RegisterID)dst);
3298 m_formatter.immediate8(imm);
3299 }
3300
3301 void por_rr(XMMRegisterID src, XMMRegisterID dst)
3302 {
3303 m_formatter.prefix(PRE_SSE_66);
3304 m_formatter.twoByteOp(OP2_POR_VdqWdq, (RegisterID)dst, (RegisterID)src);
3305 }
3306
3307 void subsd_rr(XMMRegisterID src, XMMRegisterID dst)
3308 {
3309 m_formatter.prefix(PRE_SSE_F2);
3310 m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
3311 }
3312
3313 void vsubsd_rr(XMMRegisterID a, XMMRegisterID b, XMMRegisterID dst)
3314 {
3315 m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F2, OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)a, (RegisterID)b);
3316 }
3317
3318 void subsd_mr(int offset, RegisterID base, XMMRegisterID dst)
3319 {
3320 m_formatter.prefix(PRE_SSE_F2);
3321 m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, base, offset);
3322 }
3323
3324 void subsd_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
3325 {
3326 m_formatter.prefix(PRE_SSE_F2);
3327 m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, dst, base, index, scale, offset);
3328 }
3329
3330 void vsubsd_mr(XMMRegisterID b, int offset, RegisterID base, XMMRegisterID dst)
3331 {
3332 m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F2, OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)b, base, offset);
3333 }
3334
3335 void vsubsd_mr(XMMRegisterID b, int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
3336 {
3337 m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F2, OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)b, offset, base, index, scale);
3338 }
3339
3340 void subss_rr(XMMRegisterID src, XMMRegisterID dst)
3341 {
3342 m_formatter.prefix(PRE_SSE_F3);
3343 m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
3344 }
3345
3346 void vsubss_rr(XMMRegisterID a, XMMRegisterID b, XMMRegisterID dst)
3347 {
3348 m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F3, OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)a, (RegisterID)b);
3349 }
3350
3351 void subss_mr(int offset, RegisterID base, XMMRegisterID dst)
3352 {
3353 m_formatter.prefix(PRE_SSE_F3);
3354 m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, base, offset);
3355 }
3356
3357 void subss_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
3358 {
3359 m_formatter.prefix(PRE_SSE_F3);
3360 m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, dst, base, index, scale, offset);
3361 }
3362
3363 void vsubss_mr(XMMRegisterID b, int offset, RegisterID base, XMMRegisterID dst)
3364 {
3365 m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F3, OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)b, base, offset);
3366 }
3367
3368 void vsubss_mr(XMMRegisterID b, int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
3369 {
3370 m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F3, OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)b, offset, base, index, scale);
3371 }
3372
3373 void ucomisd_rr(XMMRegisterID src, XMMRegisterID dst)
3374 {
3375 m_formatter.prefix(PRE_SSE_66);
3376 m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)dst, (RegisterID)src);
3377 }
3378
3379 void ucomisd_mr(int offset, RegisterID base, XMMRegisterID dst)
3380 {
3381 m_formatter.prefix(PRE_SSE_66);
3382 m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)dst, base, offset);
3383 }
3384
3385 void ucomiss_rr(XMMRegisterID src, XMMRegisterID dst)
3386 {
3387 m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)dst, (RegisterID)src);
3388 }
3389
3390 void ucomiss_mr(int offset, RegisterID base, XMMRegisterID dst)
3391 {
3392 m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)dst, base, offset);
3393 }
3394
3395 void divsd_rr(XMMRegisterID src, XMMRegisterID dst)
3396 {
3397 m_formatter.prefix(PRE_SSE_F2);
3398 m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
3399 }
3400
3401 void divsd_mr(int offset, RegisterID base, XMMRegisterID dst)
3402 {
3403 m_formatter.prefix(PRE_SSE_F2);
3404 m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)dst, base, offset);
3405 }
3406
3407 void divss_rr(XMMRegisterID src, XMMRegisterID dst)
3408 {
3409 m_formatter.prefix(PRE_SSE_F3);
3410 m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
3411 }
3412
3413 void divss_mr(int offset, RegisterID base, XMMRegisterID dst)
3414 {
3415 m_formatter.prefix(PRE_SSE_F3);
3416 m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)dst, base, offset);
3417 }
3418
3419 void andps_rr(XMMRegisterID src, XMMRegisterID dst)
3420 {
3421 m_formatter.twoByteOp(OP2_ANDPS_VpdWpd, (RegisterID)dst, (RegisterID)src);
3422 }
3423
3424 void orps_rr(XMMRegisterID src, XMMRegisterID dst)
3425 {
3426 m_formatter.twoByteOp(OP2_ORPS_VpdWpd, (RegisterID)dst, (RegisterID)src);
3427 }
3428
3429 void xorps_rr(XMMRegisterID src, XMMRegisterID dst)
3430 {
3431 m_formatter.twoByteOp(OP2_XORPD_VpdWpd, (RegisterID)dst, (RegisterID)src);
3432 }
3433
3434 void xorpd_rr(XMMRegisterID src, XMMRegisterID dst)
3435 {
3436 if (src == dst) {
3437 xorps_rr(src, dst);
3438 return;
3439 }
3440 m_formatter.prefix(PRE_SSE_66);
3441 m_formatter.twoByteOp(OP2_XORPD_VpdWpd, (RegisterID)dst, (RegisterID)src);
3442 }
3443
3444 void andnpd_rr(XMMRegisterID src, XMMRegisterID dst)
3445 {
3446 m_formatter.prefix(PRE_SSE_66);
3447 m_formatter.twoByteOp(OP2_ANDNPD_VpdWpd, (RegisterID)dst, (RegisterID)src);
3448 }
3449
3450 void sqrtsd_rr(XMMRegisterID src, XMMRegisterID dst)
3451 {
3452 m_formatter.prefix(PRE_SSE_F2);
3453 m_formatter.twoByteOp(OP2_SQRTSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
3454 }
3455
3456 void sqrtsd_mr(int offset, RegisterID base, XMMRegisterID dst)
3457 {
3458 m_formatter.prefix(PRE_SSE_F2);
3459 m_formatter.twoByteOp(OP2_SQRTSD_VsdWsd, (RegisterID)dst, base, offset);
3460 }
3461
3462 void sqrtss_rr(XMMRegisterID src, XMMRegisterID dst)
3463 {
3464 m_formatter.prefix(PRE_SSE_F3);
3465 m_formatter.twoByteOp(OP2_SQRTSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
3466 }
3467
3468 void sqrtss_mr(int offset, RegisterID base, XMMRegisterID dst)
3469 {
3470 m_formatter.prefix(PRE_SSE_F3);
3471 m_formatter.twoByteOp(OP2_SQRTSD_VsdWsd, (RegisterID)dst, base, offset);
3472 }
3473
3474 enum class RoundingType : uint8_t {
3475 ToNearestWithTiesToEven = 0,
3476 TowardNegativeInfiniti = 1,
3477 TowardInfiniti = 2,
3478 TowardZero = 3
3479 };
3480
3481 void roundss_rr(XMMRegisterID src, XMMRegisterID dst, RoundingType rounding)
3482 {
3483 m_formatter.prefix(PRE_SSE_66);
3484 m_formatter.threeByteOp(OP2_3BYTE_ESCAPE_3A, OP3_ROUNDSS_VssWssIb, (RegisterID)dst, (RegisterID)src);
3485 m_formatter.immediate8(static_cast<uint8_t>(rounding));
3486 }
3487
3488 void roundss_mr(int offset, RegisterID base, XMMRegisterID dst, RoundingType rounding)
3489 {
3490 m_formatter.prefix(PRE_SSE_66);
3491 m_formatter.threeByteOp(OP2_3BYTE_ESCAPE_3A, OP3_ROUNDSS_VssWssIb, (RegisterID)dst, base, offset);
3492 m_formatter.immediate8(static_cast<uint8_t>(rounding));
3493 }
3494
3495 void roundsd_rr(XMMRegisterID src, XMMRegisterID dst, RoundingType rounding)
3496 {
3497 m_formatter.prefix(PRE_SSE_66);
3498 m_formatter.threeByteOp(OP2_3BYTE_ESCAPE_3A, OP3_ROUNDSD_VsdWsdIb, (RegisterID)dst, (RegisterID)src);
3499 m_formatter.immediate8(static_cast<uint8_t>(rounding));
3500 }
3501
3502 void roundsd_mr(int offset, RegisterID base, XMMRegisterID dst, RoundingType rounding)
3503 {
3504 m_formatter.prefix(PRE_SSE_66);
3505 m_formatter.threeByteOp(OP2_3BYTE_ESCAPE_3A, OP3_ROUNDSD_VsdWsdIb, (RegisterID)dst, base, offset);
3506 m_formatter.immediate8(static_cast<uint8_t>(rounding));
3507 }
3508
3509 // Misc instructions:
3510
3511 void int3()
3512 {
3513 m_formatter.oneByteOp(OP_INT3);
3514 }
3515
3516 static bool isInt3(void* address)
3517 {
3518 uint8_t candidateInstruction = *reinterpret_cast<uint8_t*>(address);
3519 return candidateInstruction == OP_INT3;
3520 }
3521
3522 void ret()
3523 {
3524 m_formatter.oneByteOp(OP_RET);
3525 }
3526
3527 void predictNotTaken()
3528 {
3529 m_formatter.prefix(PRE_PREDICT_BRANCH_NOT_TAKEN);
3530 }
3531
3532 void lock()
3533 {
3534 m_formatter.prefix(PRE_LOCK);
3535 }
3536
3537 // Causes the memory access in the next instruction to be offset by %gs. Usually you use
3538 // this with a 32-bit absolute address load. That "address" ends up being the offset to
3539 // %gs. This prefix is ignored by lea. Getting the value of %gs is hard - you can pretty
3540 // much just use it as a secret offset.
3541 void gs()
3542 {
3543 m_formatter.prefix(PRE_GS);
3544 }
3545
3546 void cmpxchgb_rm(RegisterID src, int offset, RegisterID base)
3547 {
3548 m_formatter.twoByteOp8(OP2_CMPXCHGb, src, base, offset);
3549 }
3550
3551 void cmpxchgb_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
3552 {
3553 m_formatter.twoByteOp8(OP2_CMPXCHGb, src, base, index, scale, offset);
3554 }
3555
3556 void cmpxchgw_rm(RegisterID src, int offset, RegisterID base)
3557 {
3558 m_formatter.prefix(PRE_OPERAND_SIZE);
3559 m_formatter.twoByteOp(OP2_CMPXCHG, src, base, offset);
3560 }
3561
3562 void cmpxchgw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
3563 {
3564 m_formatter.prefix(PRE_OPERAND_SIZE);
3565 m_formatter.twoByteOp(OP2_CMPXCHG, src, base, index, scale, offset);
3566 }
3567
3568 void cmpxchgl_rm(RegisterID src, int offset, RegisterID base)
3569 {
3570 m_formatter.twoByteOp(OP2_CMPXCHG, src, base, offset);
3571 }
3572
3573 void cmpxchgl_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
3574 {
3575 m_formatter.twoByteOp(OP2_CMPXCHG, src, base, index, scale, offset);
3576 }
3577
3578#if CPU(X86_64)
3579 void cmpxchgq_rm(RegisterID src, int offset, RegisterID base)
3580 {
3581 m_formatter.twoByteOp64(OP2_CMPXCHG, src, base, offset);
3582 }
3583
3584 void cmpxchgq_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
3585 {
3586 m_formatter.twoByteOp64(OP2_CMPXCHG, src, base, index, scale, offset);
3587 }
3588#endif // CPU(X86_64)
3589
3590 void xaddb_rm(RegisterID src, int offset, RegisterID base)
3591 {
3592 m_formatter.twoByteOp8(OP2_XADDb, src, base, offset);
3593 }
3594
3595 void xaddb_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
3596 {
3597 m_formatter.twoByteOp8(OP2_XADDb, src, base, index, scale, offset);
3598 }
3599
3600 void xaddw_rm(RegisterID src, int offset, RegisterID base)
3601 {
3602 m_formatter.prefix(PRE_OPERAND_SIZE);
3603 m_formatter.twoByteOp(OP2_XADD, src, base, offset);
3604 }
3605
3606 void xaddw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
3607 {
3608 m_formatter.prefix(PRE_OPERAND_SIZE);
3609 m_formatter.twoByteOp(OP2_XADD, src, base, index, scale, offset);
3610 }
3611
3612 void xaddl_rm(RegisterID src, int offset, RegisterID base)
3613 {
3614 m_formatter.twoByteOp(OP2_XADD, src, base, offset);
3615 }
3616
3617 void xaddl_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
3618 {
3619 m_formatter.twoByteOp(OP2_XADD, src, base, index, scale, offset);
3620 }
3621
3622#if CPU(X86_64)
3623 void xaddq_rm(RegisterID src, int offset, RegisterID base)
3624 {
3625 m_formatter.twoByteOp64(OP2_XADD, src, base, offset);
3626 }
3627
3628 void xaddq_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
3629 {
3630 m_formatter.twoByteOp64(OP2_XADD, src, base, index, scale, offset);
3631 }
3632#endif // CPU(X86_64)
3633
3634 void lfence()
3635 {
3636 m_formatter.threeByteOp(OP2_3BYTE_ESCAPE_AE, OP3_LFENCE);
3637 }
3638
3639 void mfence()
3640 {
3641 m_formatter.threeByteOp(OP2_3BYTE_ESCAPE_AE, OP3_MFENCE);
3642 }
3643
3644 void sfence()
3645 {
3646 m_formatter.threeByteOp(OP2_3BYTE_ESCAPE_AE, OP3_SFENCE);
3647 }
3648
3649 void rdtsc()
3650 {
3651 m_formatter.twoByteOp(OP2_RDTSC);
3652 }
3653
3654 void pause()
3655 {
3656 m_formatter.prefix(PRE_SSE_F3);
3657 m_formatter.oneByteOp(OP_PAUSE);
3658 }
3659
3660 void cpuid()
3661 {
3662 m_formatter.twoByteOp(OP2_CPUID);
3663 }
3664
3665 // Assembler admin methods:
3666
3667 size_t codeSize() const
3668 {
3669 return m_formatter.codeSize();
3670 }
3671
3672 AssemblerLabel labelForWatchpoint()
3673 {
3674 AssemblerLabel result = m_formatter.label();
3675 if (static_cast<int>(result.m_offset) != m_indexOfLastWatchpoint)
3676 result = label();
3677 m_indexOfLastWatchpoint = result.m_offset;
3678 m_indexOfTailOfLastWatchpoint = result.m_offset + maxJumpReplacementSize();
3679 return result;
3680 }
3681
3682 AssemblerLabel labelIgnoringWatchpoints()
3683 {
3684 return m_formatter.label();
3685 }
3686
3687 AssemblerLabel label()
3688 {
3689 AssemblerLabel result = m_formatter.label();
3690 while (UNLIKELY(static_cast<int>(result.m_offset) < m_indexOfTailOfLastWatchpoint)) {
3691 nop();
3692 result = m_formatter.label();
3693 }
3694 return result;
3695 }
3696
3697 AssemblerLabel align(int alignment)
3698 {
3699 while (!m_formatter.isAligned(alignment))
3700 m_formatter.oneByteOp(OP_HLT);
3701
3702 return label();
3703 }
3704
3705 // Linking & patching:
3706 //
3707 // 'link' and 'patch' methods are for use on unprotected code - such as the code
3708 // within the AssemblerBuffer, and code being patched by the patch buffer. Once
3709 // code has been finalized it is (platform support permitting) within a non-
3710 // writable region of memory; to modify the code in an execute-only execuable
3711 // pool the 'repatch' and 'relink' methods should be used.
3712
3713 void linkJump(AssemblerLabel from, AssemblerLabel to)
3714 {
3715 ASSERT(from.isSet());
3716 ASSERT(to.isSet());
3717
3718 char* code = reinterpret_cast<char*>(m_formatter.data());
3719 ASSERT(!WTF::unalignedLoad<int32_t>(bitwise_cast<int32_t*>(code + from.m_offset) - 1));
3720 setRel32(code + from.m_offset, code + to.m_offset);
3721 }
3722
3723 static void linkJump(void* code, AssemblerLabel from, void* to)
3724 {
3725 ASSERT(from.isSet());
3726
3727 setRel32(reinterpret_cast<char*>(code) + from.m_offset, to);
3728 }
3729
3730 static void linkCall(void* code, AssemblerLabel from, void* to)
3731 {
3732 ASSERT(from.isSet());
3733
3734 setRel32(reinterpret_cast<char*>(code) + from.m_offset, to);
3735 }
3736
3737 static void linkPointer(void* code, AssemblerLabel where, void* value)
3738 {
3739 ASSERT(where.isSet());
3740
3741 setPointer(reinterpret_cast<char*>(code) + where.m_offset, value);
3742 }
3743
3744 static void relinkJump(void* from, void* to)
3745 {
3746 setRel32(from, to);
3747 }
3748
3749 static void relinkJumpToNop(void* from)
3750 {
3751 setInt32(from, 0);
3752 }
3753
3754 static void relinkCall(void* from, void* to)
3755 {
3756 setRel32(from, to);
3757 }
3758
3759 static void repatchCompact(void* where, int32_t value)
3760 {
3761 ASSERT(value >= std::numeric_limits<int8_t>::min());
3762 ASSERT(value <= std::numeric_limits<int8_t>::max());
3763 setInt8(where, value);
3764 }
3765
3766 static void repatchInt32(void* where, int32_t value)
3767 {
3768 setInt32(where, value);
3769 }
3770
3771 static void repatchPointer(void* where, void* value)
3772 {
3773 setPointer(where, value);
3774 }
3775
3776 static void* readPointer(void* where)
3777 {
3778 return WTF::unalignedLoad<void*>(bitwise_cast<void**>(where) - 1);
3779 }
3780
3781 static void replaceWithHlt(void* instructionStart)
3782 {
3783 WTF::unalignedStore<uint8_t>(instructionStart, static_cast<uint8_t>(OP_HLT));
3784 }
3785
3786 static void replaceWithJump(void* instructionStart, void* to)
3787 {
3788 uint8_t* ptr = bitwise_cast<uint8_t*>(instructionStart);
3789 uint8_t* dstPtr = bitwise_cast<uint8_t*>(to);
3790 intptr_t distance = (intptr_t)(dstPtr - (ptr + 5));
3791 WTF::unalignedStore<uint8_t>(ptr, static_cast<uint8_t>(OP_JMP_rel32));
3792 WTF::unalignedStore<int32_t>(ptr + 1, static_cast<int32_t>(distance));
3793 }
3794
3795 static ptrdiff_t maxJumpReplacementSize()
3796 {
3797 return 5;
3798 }
3799
3800 static constexpr ptrdiff_t patchableJumpSize()
3801 {
3802 return 5;
3803 }
3804
3805#if CPU(X86_64)
3806 static void revertJumpTo_movq_i64r(void* instructionStart, int64_t imm, RegisterID dst)
3807 {
3808 const unsigned instructionSize = 10; // REX.W MOV IMM64
3809 const int rexBytes = 1;
3810 const int opcodeBytes = 1;
3811 uint8_t* ptr = reinterpret_cast<uint8_t*>(instructionStart);
3812 ptr[0] = PRE_REX | (1 << 3) | (dst >> 3);
3813 ptr[1] = OP_MOV_EAXIv | (dst & 7);
3814
3815 union {
3816 uint64_t asWord;
3817 uint8_t asBytes[8];
3818 } u;
3819 u.asWord = imm;
3820 for (unsigned i = rexBytes + opcodeBytes; i < instructionSize; ++i)
3821 ptr[i] = u.asBytes[i - rexBytes - opcodeBytes];
3822 }
3823
3824 static void revertJumpTo_movl_i32r(void* instructionStart, int32_t imm, RegisterID dst)
3825 {
3826 // We only revert jumps on inline caches, and inline caches always use the scratch register (r11).
3827 // FIXME: If the above is ever false then we need to make this smarter with respect to emitting
3828 // the REX byte.
3829 ASSERT(dst == X86Registers::r11);
3830 const unsigned instructionSize = 6; // REX MOV IMM32
3831 const int rexBytes = 1;
3832 const int opcodeBytes = 1;
3833 uint8_t* ptr = reinterpret_cast<uint8_t*>(instructionStart);
3834 ptr[0] = PRE_REX | (dst >> 3);
3835 ptr[1] = OP_MOV_EAXIv | (dst & 7);
3836
3837 union {
3838 uint32_t asWord;
3839 uint8_t asBytes[4];
3840 } u;
3841 u.asWord = imm;
3842 for (unsigned i = rexBytes + opcodeBytes; i < instructionSize; ++i)
3843 ptr[i] = u.asBytes[i - rexBytes - opcodeBytes];
3844 }
3845#endif
3846
3847 static void revertJumpTo_cmpl_ir_force32(void* instructionStart, int32_t imm, RegisterID dst)
3848 {
3849 const int opcodeBytes = 1;
3850 const int modRMBytes = 1;
3851 ASSERT(opcodeBytes + modRMBytes <= maxJumpReplacementSize());
3852 uint8_t* ptr = reinterpret_cast<uint8_t*>(instructionStart);
3853 ptr[0] = OP_GROUP1_EvIz;
3854 ptr[1] = (X86InstructionFormatter::ModRmRegister << 6) | (GROUP1_OP_CMP << 3) | dst;
3855 union {
3856 uint32_t asWord;
3857 uint8_t asBytes[4];
3858 } u;
3859 u.asWord = imm;
3860 for (unsigned i = opcodeBytes + modRMBytes; i < static_cast<unsigned>(maxJumpReplacementSize()); ++i)
3861 ptr[i] = u.asBytes[i - opcodeBytes - modRMBytes];
3862 }
3863
3864 static void revertJumpTo_cmpl_im_force32(void* instructionStart, int32_t imm, int offset, RegisterID dst)
3865 {
3866 ASSERT_UNUSED(offset, !offset);
3867 const int opcodeBytes = 1;
3868 const int modRMBytes = 1;
3869 ASSERT(opcodeBytes + modRMBytes <= maxJumpReplacementSize());
3870 uint8_t* ptr = reinterpret_cast<uint8_t*>(instructionStart);
3871 ptr[0] = OP_GROUP1_EvIz;
3872 ptr[1] = (X86InstructionFormatter::ModRmMemoryNoDisp << 6) | (GROUP1_OP_CMP << 3) | dst;
3873 union {
3874 uint32_t asWord;
3875 uint8_t asBytes[4];
3876 } u;
3877 u.asWord = imm;
3878 for (unsigned i = opcodeBytes + modRMBytes; i < static_cast<unsigned>(maxJumpReplacementSize()); ++i)
3879 ptr[i] = u.asBytes[i - opcodeBytes - modRMBytes];
3880 }
3881
3882 static void replaceWithLoad(void* instructionStart)
3883 {
3884 uint8_t* ptr = reinterpret_cast<uint8_t*>(instructionStart);
3885#if CPU(X86_64)
3886 if ((*ptr & ~15) == PRE_REX)
3887 ptr++;
3888#endif
3889 switch (*ptr) {
3890 case OP_MOV_GvEv:
3891 break;
3892 case OP_LEA:
3893 *ptr = OP_MOV_GvEv;
3894 break;
3895 default:
3896 RELEASE_ASSERT_NOT_REACHED();
3897 }
3898 }
3899
3900 static void replaceWithAddressComputation(void* instructionStart)
3901 {
3902 uint8_t* ptr = reinterpret_cast<uint8_t*>(instructionStart);
3903#if CPU(X86_64)
3904 if ((*ptr & ~15) == PRE_REX)
3905 ptr++;
3906#endif
3907 switch (*ptr) {
3908 case OP_MOV_GvEv:
3909 *ptr = OP_LEA;
3910 break;
3911 case OP_LEA:
3912 break;
3913 default:
3914 RELEASE_ASSERT_NOT_REACHED();
3915 }
3916 }
3917
3918 static unsigned getCallReturnOffset(AssemblerLabel call)
3919 {
3920 ASSERT(call.isSet());
3921 return call.m_offset;
3922 }
3923
3924 static void* getRelocatedAddress(void* code, AssemblerLabel label)
3925 {
3926 ASSERT(label.isSet());
3927 return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + label.m_offset);
3928 }
3929
3930 static int getDifferenceBetweenLabels(AssemblerLabel a, AssemblerLabel b)
3931 {
3932 return b.m_offset - a.m_offset;
3933 }
3934
3935 unsigned debugOffset() { return m_formatter.debugOffset(); }
3936
3937 void nop()
3938 {
3939 m_formatter.oneByteOp(OP_NOP);
3940 }
3941
3942 template <typename CopyFunction>
3943 static void fillNops(void* base, size_t size, CopyFunction copy)
3944 {
3945 UNUSED_PARAM(copy);
3946#if CPU(X86_64)
3947 static const uint8_t nops[10][10] = {
3948 // nop
3949 {0x90},
3950 // xchg %ax,%ax
3951 {0x66, 0x90},
3952 // nopl (%[re]ax)
3953 {0x0f, 0x1f, 0x00},
3954 // nopl 8(%[re]ax)
3955 {0x0f, 0x1f, 0x40, 0x08},
3956 // nopl 8(%[re]ax,%[re]ax,1)
3957 {0x0f, 0x1f, 0x44, 0x00, 0x08},
3958 // nopw 8(%[re]ax,%[re]ax,1)
3959 {0x66, 0x0f, 0x1f, 0x44, 0x00, 0x08},
3960 // nopl 512(%[re]ax)
3961 {0x0f, 0x1f, 0x80, 0x00, 0x02, 0x00, 0x00},
3962 // nopl 512(%[re]ax,%[re]ax,1)
3963 {0x0f, 0x1f, 0x84, 0x00, 0x00, 0x02, 0x00, 0x00},
3964 // nopw 512(%[re]ax,%[re]ax,1)
3965 {0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x02, 0x00, 0x00},
3966 // nopw %cs:512(%[re]ax,%[re]ax,1)
3967 {0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x02, 0x00, 0x00}
3968 };
3969
3970 uint8_t* where = reinterpret_cast<uint8_t*>(base);
3971 while (size) {
3972 unsigned nopSize = static_cast<unsigned>(std::min<size_t>(size, 15));
3973 unsigned numPrefixes = nopSize <= 10 ? 0 : nopSize - 10;
3974 for (unsigned i = 0; i != numPrefixes; ++i)
3975 *where++ = 0x66;
3976
3977 unsigned nopRest = nopSize - numPrefixes;
3978 for (unsigned i = 0; i != nopRest; ++i)
3979 *where++ = nops[nopRest-1][i];
3980
3981 size -= nopSize;
3982 }
3983#else
3984 memset(base, OP_NOP, size);
3985#endif
3986 }
3987
3988 // This is a no-op on x86
3989 ALWAYS_INLINE static void cacheFlush(void*, size_t) { }
3990
3991private:
3992
3993 static void setPointer(void* where, void* value)
3994 {
3995 WTF::unalignedStore<void*>(bitwise_cast<void**>(where) - 1, value);
3996 }
3997
3998 static void setInt32(void* where, int32_t value)
3999 {
4000 WTF::unalignedStore<int32_t>(bitwise_cast<int32_t*>(where) - 1, value);
4001 }
4002
4003 static void setInt8(void* where, int8_t value)
4004 {
4005 WTF::unalignedStore<int8_t>(bitwise_cast<int8_t*>(where) - 1, value);
4006 }
4007
4008 static void setRel32(void* from, void* to)
4009 {
4010 intptr_t offset = reinterpret_cast<intptr_t>(to) - reinterpret_cast<intptr_t>(from);
4011 ASSERT(offset == static_cast<int32_t>(offset));
4012
4013 setInt32(from, offset);
4014 }
4015
4016 class X86InstructionFormatter {
4017 static const int maxInstructionSize = 16;
4018
4019 public:
4020 enum ModRmMode {
4021 ModRmMemoryNoDisp = 0,
4022 ModRmMemoryDisp8 = 1 << 6,
4023 ModRmMemoryDisp32 = 2 << 6,
4024 ModRmRegister = 3 << 6,
4025 };
4026
4027 // Legacy prefix bytes:
4028 //
4029 // These are emmitted prior to the instruction.
4030
4031 void prefix(OneByteOpcodeID pre)
4032 {
4033 m_buffer.putByte(pre);
4034 }
4035
4036#if CPU(X86_64)
4037 // Byte operand register spl & above require a REX prefix (to prevent the 'H' registers be accessed).
4038 static bool byteRegRequiresRex(int reg)
4039 {
4040 static_assert(X86Registers::esp == 4, "Necessary condition for OR-masking");
4041 return (reg >= X86Registers::esp);
4042 }
4043 static bool byteRegRequiresRex(int a, int b)
4044 {
4045 return byteRegRequiresRex(a | b);
4046 }
4047
4048 // Registers r8 & above require a REX prefixe.
4049 static bool regRequiresRex(int reg)
4050 {
4051 static_assert(X86Registers::r8 == 8, "Necessary condition for OR-masking");
4052 return (reg >= X86Registers::r8);
4053 }
4054 static bool regRequiresRex(int a, int b)
4055 {
4056 return regRequiresRex(a | b);
4057 }
4058 static bool regRequiresRex(int a, int b, int c)
4059 {
4060 return regRequiresRex(a | b | c);
4061 }
4062#else
4063 static bool byteRegRequiresRex(int) { return false; }
4064 static bool byteRegRequiresRex(int, int) { return false; }
4065 static bool regRequiresRex(int) { return false; }
4066 static bool regRequiresRex(int, int) { return false; }
4067 static bool regRequiresRex(int, int, int) { return false; }
4068#endif
4069
4070 class SingleInstructionBufferWriter : public AssemblerBuffer::LocalWriter {
4071 public:
4072 SingleInstructionBufferWriter(AssemblerBuffer& buffer)
4073 : AssemblerBuffer::LocalWriter(buffer, maxInstructionSize)
4074 {
4075 }
4076
4077 // Internals; ModRm and REX formatters.
4078
4079 static constexpr RegisterID noBase = X86Registers::ebp;
4080 static constexpr RegisterID hasSib = X86Registers::esp;
4081 static constexpr RegisterID noIndex = X86Registers::esp;
4082
4083#if CPU(X86_64)
4084 static constexpr RegisterID noBase2 = X86Registers::r13;
4085 static constexpr RegisterID hasSib2 = X86Registers::r12;
4086
4087 // Format a REX prefix byte.
4088 ALWAYS_INLINE void emitRex(bool w, int r, int x, int b)
4089 {
4090 ASSERT(r >= 0);
4091 ASSERT(x >= 0);
4092 ASSERT(b >= 0);
4093 putByteUnchecked(PRE_REX | ((int)w << 3) | ((r>>3)<<2) | ((x>>3)<<1) | (b>>3));
4094 }
4095
4096 // Used to plant a REX byte with REX.w set (for 64-bit operations).
4097 ALWAYS_INLINE void emitRexW(int r, int x, int b)
4098 {
4099 emitRex(true, r, x, b);
4100 }
4101
4102 // Used for operations with byte operands - use byteRegRequiresRex() to check register operands,
4103 // regRequiresRex() to check other registers (i.e. address base & index).
4104 ALWAYS_INLINE void emitRexIf(bool condition, int r, int x, int b)
4105 {
4106 if (condition)
4107 emitRex(false, r, x, b);
4108 }
4109
4110 // Used for word sized operations, will plant a REX prefix if necessary (if any register is r8 or above).
4111 ALWAYS_INLINE void emitRexIfNeeded(int r, int x, int b)
4112 {
4113 emitRexIf(regRequiresRex(r, x, b), r, x, b);
4114 }
4115#else
4116 // No REX prefix bytes on 32-bit x86.
4117 ALWAYS_INLINE void emitRexIf(bool, int, int, int) { }
4118 ALWAYS_INLINE void emitRexIfNeeded(int, int, int) { }
4119#endif
4120
4121 ALWAYS_INLINE void putModRm(ModRmMode mode, int reg, RegisterID rm)
4122 {
4123 putByteUnchecked(mode | ((reg & 7) << 3) | (rm & 7));
4124 }
4125
4126 ALWAYS_INLINE void putModRmSib(ModRmMode mode, int reg, RegisterID base, RegisterID index, int scale)
4127 {
4128 ASSERT(mode != ModRmRegister);
4129
4130 putModRm(mode, reg, hasSib);
4131 putByteUnchecked((scale << 6) | ((index & 7) << 3) | (base & 7));
4132 }
4133
4134 ALWAYS_INLINE void registerModRM(int reg, RegisterID rm)
4135 {
4136 putModRm(ModRmRegister, reg, rm);
4137 }
4138
4139 ALWAYS_INLINE void memoryModRM(int reg, RegisterID base, int offset)
4140 {
4141 // A base of esp or r12 would be interpreted as a sib, so force a sib with no index & put the base in there.
4142#if CPU(X86_64)
4143 if ((base == hasSib) || (base == hasSib2)) {
4144#else
4145 if (base == hasSib) {
4146#endif
4147 if (!offset) // No need to check if the base is noBase, since we know it is hasSib!
4148 putModRmSib(ModRmMemoryNoDisp, reg, base, noIndex, 0);
4149 else if (CAN_SIGN_EXTEND_8_32(offset)) {
4150 putModRmSib(ModRmMemoryDisp8, reg, base, noIndex, 0);
4151 putByteUnchecked(offset);
4152 } else {
4153 putModRmSib(ModRmMemoryDisp32, reg, base, noIndex, 0);
4154 putIntUnchecked(offset);
4155 }
4156 } else {
4157#if CPU(X86_64)
4158 if (!offset && (base != noBase) && (base != noBase2))
4159#else
4160 if (!offset && (base != noBase))
4161#endif
4162 putModRm(ModRmMemoryNoDisp, reg, base);
4163 else if (CAN_SIGN_EXTEND_8_32(offset)) {
4164 putModRm(ModRmMemoryDisp8, reg, base);
4165 putByteUnchecked(offset);
4166 } else {
4167 putModRm(ModRmMemoryDisp32, reg, base);
4168 putIntUnchecked(offset);
4169 }
4170 }
4171 }
4172
4173 ALWAYS_INLINE void memoryModRM_disp8(int reg, RegisterID base, int offset)
4174 {
4175 // A base of esp or r12 would be interpreted as a sib, so force a sib with no index & put the base in there.
4176 ASSERT(CAN_SIGN_EXTEND_8_32(offset));
4177#if CPU(X86_64)
4178 if ((base == hasSib) || (base == hasSib2)) {
4179#else
4180 if (base == hasSib) {
4181#endif
4182 putModRmSib(ModRmMemoryDisp8, reg, base, noIndex, 0);
4183 putByteUnchecked(offset);
4184 } else {
4185 putModRm(ModRmMemoryDisp8, reg, base);
4186 putByteUnchecked(offset);
4187 }
4188 }
4189
4190 ALWAYS_INLINE void memoryModRM_disp32(int reg, RegisterID base, int offset)
4191 {
4192 // A base of esp or r12 would be interpreted as a sib, so force a sib with no index & put the base in there.
4193#if CPU(X86_64)
4194 if ((base == hasSib) || (base == hasSib2)) {
4195#else
4196 if (base == hasSib) {
4197#endif
4198 putModRmSib(ModRmMemoryDisp32, reg, base, noIndex, 0);
4199 putIntUnchecked(offset);
4200 } else {
4201 putModRm(ModRmMemoryDisp32, reg, base);
4202 putIntUnchecked(offset);
4203 }
4204 }
4205
4206 ALWAYS_INLINE void memoryModRM(int reg, RegisterID base, RegisterID index, int scale, int offset)
4207 {
4208 ASSERT(index != noIndex);
4209
4210#if CPU(X86_64)
4211 if (!offset && (base != noBase) && (base != noBase2))
4212#else
4213 if (!offset && (base != noBase))
4214#endif
4215 putModRmSib(ModRmMemoryNoDisp, reg, base, index, scale);
4216 else if (CAN_SIGN_EXTEND_8_32(offset)) {
4217 putModRmSib(ModRmMemoryDisp8, reg, base, index, scale);
4218 putByteUnchecked(offset);
4219 } else {
4220 putModRmSib(ModRmMemoryDisp32, reg, base, index, scale);
4221 putIntUnchecked(offset);
4222 }
4223 }
4224
4225 ALWAYS_INLINE void memoryModRMAddr(int reg, uint32_t address)
4226 {
4227#if CPU(X86_64)
4228 putModRmSib(ModRmMemoryNoDisp, reg, noBase, noIndex, 0);
4229#else
4230 // noBase + ModRmMemoryNoDisp means noBase + ModRmMemoryDisp32!
4231 putModRm(ModRmMemoryNoDisp, reg, noBase);
4232#endif
4233 putIntUnchecked(address);
4234 }
4235
4236 ALWAYS_INLINE void twoBytesVex(OneByteOpcodeID simdPrefix, RegisterID inOpReg, RegisterID r)
4237 {
4238 putByteUnchecked(VexPrefix::TwoBytes);
4239
4240 uint8_t secondByte = vexEncodeSimdPrefix(simdPrefix);
4241 secondByte |= (~inOpReg & 0xf) << 3;
4242 secondByte |= !regRequiresRex(r) << 7;
4243 putByteUnchecked(secondByte);
4244 }
4245
4246 ALWAYS_INLINE void threeBytesVexNds(OneByteOpcodeID simdPrefix, VexImpliedBytes impliedBytes, RegisterID r, RegisterID inOpReg, RegisterID x, RegisterID b)
4247 {
4248 putByteUnchecked(VexPrefix::ThreeBytes);
4249
4250 uint8_t secondByte = static_cast<uint8_t>(impliedBytes);
4251 secondByte |= !regRequiresRex(r) << 7;
4252 secondByte |= !regRequiresRex(x) << 6;
4253 secondByte |= !regRequiresRex(b) << 5;
4254 putByteUnchecked(secondByte);
4255
4256 uint8_t thirdByte = vexEncodeSimdPrefix(simdPrefix);
4257 thirdByte |= (~inOpReg & 0xf) << 3;
4258 putByteUnchecked(thirdByte);
4259 }
4260
4261 ALWAYS_INLINE void threeBytesVexNds(OneByteOpcodeID simdPrefix, VexImpliedBytes impliedBytes, RegisterID r, RegisterID inOpReg, RegisterID b)
4262 {
4263 putByteUnchecked(VexPrefix::ThreeBytes);
4264
4265 uint8_t secondByte = static_cast<uint8_t>(impliedBytes);
4266 secondByte |= !regRequiresRex(r) << 7;
4267 secondByte |= 1 << 6; // REX.X
4268 secondByte |= !regRequiresRex(b) << 5;
4269 putByteUnchecked(secondByte);
4270
4271 uint8_t thirdByte = vexEncodeSimdPrefix(simdPrefix);
4272 thirdByte |= (~inOpReg & 0xf) << 3;
4273 putByteUnchecked(thirdByte);
4274 }
4275 private:
4276 uint8_t vexEncodeSimdPrefix(OneByteOpcodeID simdPrefix)
4277 {
4278 switch (simdPrefix) {
4279 case 0x66:
4280 return 1;
4281 case 0xF3:
4282 return 2;
4283 case 0xF2:
4284 return 3;
4285 default:
4286 RELEASE_ASSERT_NOT_REACHED();
4287 }
4288 return 0;
4289 }
4290
4291 };
4292
4293 // Word-sized operands / no operand instruction formatters.
4294 //
4295 // In addition to the opcode, the following operand permutations are supported:
4296 // * None - instruction takes no operands.
4297 // * One register - the low three bits of the RegisterID are added into the opcode.
4298 // * Two registers - encode a register form ModRm (for all ModRm formats, the reg field is passed first, and a GroupOpcodeID may be passed in its place).
4299 // * Three argument ModRM - a register, and a register and an offset describing a memory operand.
4300 // * Five argument ModRM - a register, and a base register, an index, scale, and offset describing a memory operand.
4301 //
4302 // For 32-bit x86 targets, the address operand may also be provided as a void*.
4303 // On 64-bit targets REX prefixes will be planted as necessary, where high numbered registers are used.
4304 //
4305 // The twoByteOp methods plant two-byte Intel instructions sequences (first opcode byte 0x0F).
4306
4307 void oneByteOp(OneByteOpcodeID opcode)
4308 {
4309 SingleInstructionBufferWriter writer(m_buffer);
4310 writer.putByteUnchecked(opcode);
4311 }
4312
4313 void oneByteOp(OneByteOpcodeID opcode, RegisterID reg)
4314 {
4315 SingleInstructionBufferWriter writer(m_buffer);
4316 writer.emitRexIfNeeded(0, 0, reg);
4317 writer.putByteUnchecked(opcode + (reg & 7));
4318 }
4319
4320 void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID rm)
4321 {
4322 SingleInstructionBufferWriter writer(m_buffer);
4323 writer.emitRexIfNeeded(reg, 0, rm);
4324 writer.putByteUnchecked(opcode);
4325 writer.registerModRM(reg, rm);
4326 }
4327
4328 void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
4329 {
4330 SingleInstructionBufferWriter writer(m_buffer);
4331 writer.emitRexIfNeeded(reg, 0, base);
4332 writer.putByteUnchecked(opcode);
4333 writer.memoryModRM(reg, base, offset);
4334 }
4335
4336 void oneByteOp_disp32(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
4337 {
4338 SingleInstructionBufferWriter writer(m_buffer);
4339 writer.emitRexIfNeeded(reg, 0, base);
4340 writer.putByteUnchecked(opcode);
4341 writer.memoryModRM_disp32(reg, base, offset);
4342 }
4343
4344 void oneByteOp_disp8(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
4345 {
4346 SingleInstructionBufferWriter writer(m_buffer);
4347 writer.emitRexIfNeeded(reg, 0, base);
4348 writer.putByteUnchecked(opcode);
4349 writer.memoryModRM_disp8(reg, base, offset);
4350 }
4351
4352 void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
4353 {
4354 SingleInstructionBufferWriter writer(m_buffer);
4355 writer.emitRexIfNeeded(reg, index, base);
4356 writer.putByteUnchecked(opcode);
4357 writer.memoryModRM(reg, base, index, scale, offset);
4358 }
4359
4360 void oneByteOpAddr(OneByteOpcodeID opcode, int reg, uint32_t address)
4361 {
4362 SingleInstructionBufferWriter writer(m_buffer);
4363 writer.putByteUnchecked(opcode);
4364 writer.memoryModRMAddr(reg, address);
4365 }
4366
4367 void twoByteOp(TwoByteOpcodeID opcode)
4368 {
4369 SingleInstructionBufferWriter writer(m_buffer);
4370 writer.putByteUnchecked(OP_2BYTE_ESCAPE);
4371 writer.putByteUnchecked(opcode);
4372 }
4373
4374 void twoByteOp(TwoByteOpcodeID opcode, int reg)
4375 {
4376 SingleInstructionBufferWriter writer(m_buffer);
4377 writer.emitRexIfNeeded(0, 0, reg);
4378 writer.putByteUnchecked(OP_2BYTE_ESCAPE);
4379 writer.putByteUnchecked(opcode + (reg & 7));
4380 }
4381
4382 void twoByteOp(TwoByteOpcodeID opcode, int reg, RegisterID rm)
4383 {
4384 SingleInstructionBufferWriter writer(m_buffer);
4385 writer.emitRexIfNeeded(reg, 0, rm);
4386 writer.putByteUnchecked(OP_2BYTE_ESCAPE);
4387 writer.putByteUnchecked(opcode);
4388 writer.registerModRM(reg, rm);
4389 }
4390
4391 void twoByteOp(TwoByteOpcodeID opcode, int reg, RegisterID base, int offset)
4392 {
4393 SingleInstructionBufferWriter writer(m_buffer);
4394 writer.emitRexIfNeeded(reg, 0, base);
4395 writer.putByteUnchecked(OP_2BYTE_ESCAPE);
4396 writer.putByteUnchecked(opcode);
4397 writer.memoryModRM(reg, base, offset);
4398 }
4399
4400 void twoByteOp(TwoByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
4401 {
4402 SingleInstructionBufferWriter writer(m_buffer);
4403 writer.emitRexIfNeeded(reg, index, base);
4404 writer.putByteUnchecked(OP_2BYTE_ESCAPE);
4405 writer.putByteUnchecked(opcode);
4406 writer.memoryModRM(reg, base, index, scale, offset);
4407 }
4408
4409 void twoByteOpAddr(TwoByteOpcodeID opcode, int reg, uint32_t address)
4410 {
4411 SingleInstructionBufferWriter writer(m_buffer);
4412 writer.putByteUnchecked(OP_2BYTE_ESCAPE);
4413 writer.putByteUnchecked(opcode);
4414 writer.memoryModRMAddr(reg, address);
4415 }
4416
4417 void vexNdsLigWigTwoByteOp(OneByteOpcodeID simdPrefix, TwoByteOpcodeID opcode, RegisterID dest, RegisterID a, RegisterID b)
4418 {
4419 SingleInstructionBufferWriter writer(m_buffer);
4420 if (regRequiresRex(b))
4421 writer.threeBytesVexNds(simdPrefix, VexImpliedBytes::TwoBytesOp, dest, a, b);
4422 else
4423 writer.twoBytesVex(simdPrefix, a, dest);
4424 writer.putByteUnchecked(opcode);
4425 writer.registerModRM(dest, b);
4426 }
4427
4428 void vexNdsLigWigCommutativeTwoByteOp(OneByteOpcodeID simdPrefix, TwoByteOpcodeID opcode, RegisterID dest, RegisterID a, RegisterID b)
4429 {
4430 // Since this is a commutative operation, we can try switching the arguments.
4431 if (regRequiresRex(b))
4432 std::swap(a, b);
4433 vexNdsLigWigTwoByteOp(simdPrefix, opcode, dest, a, b);
4434 }
4435
4436 void vexNdsLigWigTwoByteOp(OneByteOpcodeID simdPrefix, TwoByteOpcodeID opcode, RegisterID dest, RegisterID a, RegisterID base, int offset)
4437 {
4438 SingleInstructionBufferWriter writer(m_buffer);
4439 if (regRequiresRex(base))
4440 writer.threeBytesVexNds(simdPrefix, VexImpliedBytes::TwoBytesOp, dest, a, base);
4441 else
4442 writer.twoBytesVex(simdPrefix, a, dest);
4443 writer.putByteUnchecked(opcode);
4444 writer.memoryModRM(dest, base, offset);
4445 }
4446
4447 void vexNdsLigWigTwoByteOp(OneByteOpcodeID simdPrefix, TwoByteOpcodeID opcode, RegisterID dest, RegisterID a, int offset, RegisterID base, RegisterID index, int scale)
4448 {
4449 SingleInstructionBufferWriter writer(m_buffer);
4450 if (regRequiresRex(base, index))
4451 writer.threeBytesVexNds(simdPrefix, VexImpliedBytes::TwoBytesOp, dest, a, index, base);
4452 else
4453 writer.twoBytesVex(simdPrefix, a, dest);
4454 writer.putByteUnchecked(opcode);
4455 writer.memoryModRM(dest, base, index, scale, offset);
4456 }
4457
4458 void threeByteOp(TwoByteOpcodeID twoBytePrefix, ThreeByteOpcodeID opcode)
4459 {
4460 SingleInstructionBufferWriter writer(m_buffer);
4461 writer.putByteUnchecked(OP_2BYTE_ESCAPE);
4462 writer.putByteUnchecked(twoBytePrefix);
4463 writer.putByteUnchecked(opcode);
4464 }
4465
4466 void threeByteOp(TwoByteOpcodeID twoBytePrefix, ThreeByteOpcodeID opcode, int reg, RegisterID rm)
4467 {
4468 SingleInstructionBufferWriter writer(m_buffer);
4469 writer.emitRexIfNeeded(reg, 0, rm);
4470 writer.putByteUnchecked(OP_2BYTE_ESCAPE);
4471 writer.putByteUnchecked(twoBytePrefix);
4472 writer.putByteUnchecked(opcode);
4473 writer.registerModRM(reg, rm);
4474 }
4475
4476 void threeByteOp(TwoByteOpcodeID twoBytePrefix, ThreeByteOpcodeID opcode, int reg, RegisterID base, int displacement)
4477 {
4478 SingleInstructionBufferWriter writer(m_buffer);
4479 writer.emitRexIfNeeded(reg, 0, base);
4480 writer.putByteUnchecked(OP_2BYTE_ESCAPE);
4481 writer.putByteUnchecked(twoBytePrefix);
4482 writer.putByteUnchecked(opcode);
4483 writer.memoryModRM(reg, base, displacement);
4484 }
4485
4486#if CPU(X86_64)
4487 // Quad-word-sized operands:
4488 //
4489 // Used to format 64-bit operantions, planting a REX.w prefix.
4490 // When planting d64 or f64 instructions, not requiring a REX.w prefix,
4491 // the normal (non-'64'-postfixed) formatters should be used.
4492
4493 void oneByteOp64(OneByteOpcodeID opcode)
4494 {
4495 SingleInstructionBufferWriter writer(m_buffer);
4496 writer.emitRexW(0, 0, 0);
4497 writer.putByteUnchecked(opcode);
4498 }
4499
4500 void oneByteOp64(OneByteOpcodeID opcode, RegisterID reg)
4501 {
4502 SingleInstructionBufferWriter writer(m_buffer);
4503 writer.emitRexW(0, 0, reg);
4504 writer.putByteUnchecked(opcode + (reg & 7));
4505 }
4506
4507 void oneByteOp64(OneByteOpcodeID opcode, int reg, RegisterID rm)
4508 {
4509 SingleInstructionBufferWriter writer(m_buffer);
4510 writer.emitRexW(reg, 0, rm);
4511 writer.putByteUnchecked(opcode);
4512 writer.registerModRM(reg, rm);
4513 }
4514
4515 void oneByteOp64(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
4516 {
4517 SingleInstructionBufferWriter writer(m_buffer);
4518 writer.emitRexW(reg, 0, base);
4519 writer.putByteUnchecked(opcode);
4520 writer.memoryModRM(reg, base, offset);
4521 }
4522
4523 void oneByteOp64_disp32(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
4524 {
4525 SingleInstructionBufferWriter writer(m_buffer);
4526 writer.emitRexW(reg, 0, base);
4527 writer.putByteUnchecked(opcode);
4528 writer.memoryModRM_disp32(reg, base, offset);
4529 }
4530
4531 void oneByteOp64_disp8(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
4532 {
4533 SingleInstructionBufferWriter writer(m_buffer);
4534 writer.emitRexW(reg, 0, base);
4535 writer.putByteUnchecked(opcode);
4536 writer.memoryModRM_disp8(reg, base, offset);
4537 }
4538
4539 void oneByteOp64(OneByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
4540 {
4541 SingleInstructionBufferWriter writer(m_buffer);
4542 writer.emitRexW(reg, index, base);
4543 writer.putByteUnchecked(opcode);
4544 writer.memoryModRM(reg, base, index, scale, offset);
4545 }
4546
4547 void oneByteOp64Addr(OneByteOpcodeID opcode, int reg, uint32_t address)
4548 {
4549 SingleInstructionBufferWriter writer(m_buffer);
4550 writer.emitRexW(reg, 0, 0);
4551 writer.putByteUnchecked(opcode);
4552 writer.memoryModRMAddr(reg, address);
4553 }
4554
4555 void twoByteOp64(TwoByteOpcodeID opcode, int reg)
4556 {
4557 SingleInstructionBufferWriter writer(m_buffer);
4558 writer.emitRexW(0, 0, reg);
4559 writer.putByteUnchecked(OP_2BYTE_ESCAPE);
4560 writer.putByteUnchecked(opcode + (reg & 7));
4561 }
4562
4563 void twoByteOp64(TwoByteOpcodeID opcode, int reg, RegisterID rm)
4564 {
4565 SingleInstructionBufferWriter writer(m_buffer);
4566 writer.emitRexW(reg, 0, rm);
4567 writer.putByteUnchecked(OP_2BYTE_ESCAPE);
4568 writer.putByteUnchecked(opcode);
4569 writer.registerModRM(reg, rm);
4570 }
4571
4572 void twoByteOp64(TwoByteOpcodeID opcode, int reg, RegisterID base, int offset)
4573 {
4574 SingleInstructionBufferWriter writer(m_buffer);
4575 writer.emitRexW(reg, 0, base);
4576 writer.putByteUnchecked(OP_2BYTE_ESCAPE);
4577 writer.putByteUnchecked(opcode);
4578 writer.memoryModRM(reg, base, offset);
4579 }
4580
4581 void twoByteOp64(TwoByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
4582 {
4583 SingleInstructionBufferWriter writer(m_buffer);
4584 writer.emitRexW(reg, index, base);
4585 writer.putByteUnchecked(OP_2BYTE_ESCAPE);
4586 writer.putByteUnchecked(opcode);
4587 writer.memoryModRM(reg, base, index, scale, offset);
4588 }
4589#endif
4590
4591 // Byte-operands:
4592 //
4593 // These methods format byte operations. Byte operations differ from the normal
4594 // formatters in the circumstances under which they will decide to emit REX prefixes.
4595 // These should be used where any register operand signifies a byte register.
4596 //
4597 // The disctinction is due to the handling of register numbers in the range 4..7 on
4598 // x86-64. These register numbers may either represent the second byte of the first
4599 // four registers (ah..bh) or the first byte of the second four registers (spl..dil).
4600 //
4601 // Since ah..bh cannot be used in all permutations of operands (specifically cannot
4602 // be accessed where a REX prefix is present), these are likely best treated as
4603 // deprecated. In order to ensure the correct registers spl..dil are selected a
4604 // REX prefix will be emitted for any byte register operand in the range 4..15.
4605 //
4606 // These formatters may be used in instructions where a mix of operand sizes, in which
4607 // case an unnecessary REX will be emitted, for example:
4608 // movzbl %al, %edi
4609 // In this case a REX will be planted since edi is 7 (and were this a byte operand
4610 // a REX would be required to specify dil instead of bh). Unneeded REX prefixes will
4611 // be silently ignored by the processor.
4612 //
4613 // Address operands should still be checked using regRequiresRex(), while byteRegRequiresRex()
4614 // is provided to check byte register operands.
4615
4616 void oneByteOp8(OneByteOpcodeID opcode, GroupOpcodeID groupOp, RegisterID rm)
4617 {
4618 SingleInstructionBufferWriter writer(m_buffer);
4619 writer.emitRexIf(byteRegRequiresRex(rm), 0, 0, rm);
4620 writer.putByteUnchecked(opcode);
4621 writer.registerModRM(groupOp, rm);
4622 }
4623
4624 void oneByteOp8(OneByteOpcodeID opcode, int reg, RegisterID rm)
4625 {
4626 SingleInstructionBufferWriter writer(m_buffer);
4627 writer.emitRexIf(byteRegRequiresRex(reg, rm), reg, 0, rm);
4628 writer.putByteUnchecked(opcode);
4629 writer.registerModRM(reg, rm);
4630 }
4631
4632 void oneByteOp8(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
4633 {
4634 SingleInstructionBufferWriter writer(m_buffer);
4635 writer.emitRexIf(byteRegRequiresRex(reg, base), reg, 0, base);
4636 writer.putByteUnchecked(opcode);
4637 writer.memoryModRM(reg, base, offset);
4638 }
4639
4640 void oneByteOp8(OneByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
4641 {
4642 SingleInstructionBufferWriter writer(m_buffer);
4643 writer.emitRexIf(byteRegRequiresRex(reg) || regRequiresRex(index, base), reg, index, base);
4644 writer.putByteUnchecked(opcode);
4645 writer.memoryModRM(reg, base, index, scale, offset);
4646 }
4647
4648 void twoByteOp8(TwoByteOpcodeID opcode, RegisterID reg, RegisterID rm)
4649 {
4650 SingleInstructionBufferWriter writer(m_buffer);
4651 writer.emitRexIf(byteRegRequiresRex(reg, rm), reg, 0, rm);
4652 writer.putByteUnchecked(OP_2BYTE_ESCAPE);
4653 writer.putByteUnchecked(opcode);
4654 writer.registerModRM(reg, rm);
4655 }
4656
4657 void twoByteOp8(TwoByteOpcodeID opcode, GroupOpcodeID groupOp, RegisterID rm)
4658 {
4659 SingleInstructionBufferWriter writer(m_buffer);
4660 writer.emitRexIf(byteRegRequiresRex(rm), 0, 0, rm);
4661 writer.putByteUnchecked(OP_2BYTE_ESCAPE);
4662 writer.putByteUnchecked(opcode);
4663 writer.registerModRM(groupOp, rm);
4664 }
4665
4666 void twoByteOp8(TwoByteOpcodeID opcode, int reg, RegisterID base, int offset)
4667 {
4668 SingleInstructionBufferWriter writer(m_buffer);
4669 writer.emitRexIf(byteRegRequiresRex(reg, base), reg, 0, base);
4670 writer.putByteUnchecked(OP_2BYTE_ESCAPE);
4671 writer.putByteUnchecked(opcode);
4672 writer.memoryModRM(reg, base, offset);
4673 }
4674
4675 void twoByteOp8(TwoByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
4676 {
4677 SingleInstructionBufferWriter writer(m_buffer);
4678 writer.emitRexIf(byteRegRequiresRex(reg) || regRequiresRex(index, base), reg, index, base);
4679 writer.putByteUnchecked(OP_2BYTE_ESCAPE);
4680 writer.putByteUnchecked(opcode);
4681 writer.memoryModRM(reg, base, index, scale, offset);
4682 }
4683
4684 // Immediates:
4685 //
4686 // An immedaite should be appended where appropriate after an op has been emitted.
4687 // The writes are unchecked since the opcode formatters above will have ensured space.
4688
4689 void immediate8(int imm)
4690 {
4691 m_buffer.putByteUnchecked(imm);
4692 }
4693
4694 void immediate16(int imm)
4695 {
4696 m_buffer.putShortUnchecked(imm);
4697 }
4698
4699 void immediate32(int imm)
4700 {
4701 m_buffer.putIntUnchecked(imm);
4702 }
4703
4704 void immediate64(int64_t imm)
4705 {
4706 m_buffer.putInt64Unchecked(imm);
4707 }
4708
4709 AssemblerLabel immediateRel32()
4710 {
4711 m_buffer.putIntUnchecked(0);
4712 return label();
4713 }
4714
4715 // Administrative methods:
4716
4717 size_t codeSize() const { return m_buffer.codeSize(); }
4718 AssemblerLabel label() const { return m_buffer.label(); }
4719 bool isAligned(int alignment) const { return m_buffer.isAligned(alignment); }
4720 void* data() const { return m_buffer.data(); }
4721
4722 unsigned debugOffset() { return m_buffer.debugOffset(); }
4723
4724 public:
4725 AssemblerBuffer m_buffer;
4726 } m_formatter;
4727 int m_indexOfLastWatchpoint;
4728 int m_indexOfTailOfLastWatchpoint;
4729};
4730
4731} // namespace JSC
4732
4733#endif // ENABLE(ASSEMBLER) && CPU(X86)
4734