]> git.saurik.com Git - apple/javascriptcore.git/blob - assembler/X86Assembler.h
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / assembler / X86Assembler.h
1 /*
2 * Copyright (C) 2008, 2012-2015 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 #ifndef X86Assembler_h
27 #define X86Assembler_h
28
29 #if ENABLE(ASSEMBLER) && (CPU(X86) || CPU(X86_64))
30
31 #include "AssemblerBuffer.h"
32 #include "JITCompilationEffort.h"
33 #include <limits.h>
34 #include <stdint.h>
35 #include <wtf/Assertions.h>
36 #include <wtf/Vector.h>
37
38 namespace JSC {
39
40 inline bool CAN_SIGN_EXTEND_8_32(int32_t value) { return value == (int32_t)(signed char)value; }
41
42 namespace X86Registers {
43
44 #define FOR_EACH_CPU_REGISTER(V) \
45 FOR_EACH_CPU_GPREGISTER(V) \
46 FOR_EACH_CPU_SPECIAL_REGISTER(V) \
47 FOR_EACH_CPU_FPREGISTER(V)
48
49 // The following are defined as pairs of the following value:
50 // 1. type of the storage needed to save the register value by the JIT probe.
51 // 2. name of the register.
52 #define FOR_EACH_CPU_GPREGISTER(V) \
53 V(void*, eax) \
54 V(void*, ecx) \
55 V(void*, edx) \
56 V(void*, ebx) \
57 V(void*, esp) \
58 V(void*, ebp) \
59 V(void*, esi) \
60 V(void*, edi) \
61 FOR_EACH_X86_64_CPU_GPREGISTER(V)
62
63 #define FOR_EACH_CPU_SPECIAL_REGISTER(V) \
64 V(void*, eip) \
65 V(void*, eflags) \
66
67 // Note: the JITs only stores double values in the FP registers.
68 #define FOR_EACH_CPU_FPREGISTER(V) \
69 V(double, xmm0) \
70 V(double, xmm1) \
71 V(double, xmm2) \
72 V(double, xmm3) \
73 V(double, xmm4) \
74 V(double, xmm5) \
75 V(double, xmm6) \
76 V(double, xmm7) \
77 FOR_EACH_X86_64_CPU_FPREGISTER(V)
78
79 #if CPU(X86)
80
81 #define FOR_EACH_X86_64_CPU_GPREGISTER(V) // Nothing to add.
82 #define FOR_EACH_X86_64_CPU_FPREGISTER(V) // Nothing to add.
83
84 #elif CPU(X86_64)
85
86 #define FOR_EACH_X86_64_CPU_GPREGISTER(V) \
87 V(void*, r8) \
88 V(void*, r9) \
89 V(void*, r10) \
90 V(void*, r11) \
91 V(void*, r12) \
92 V(void*, r13) \
93 V(void*, r14) \
94 V(void*, r15)
95
96 #define FOR_EACH_X86_64_CPU_FPREGISTER(V) \
97 V(double, xmm8) \
98 V(double, xmm9) \
99 V(double, xmm10) \
100 V(double, xmm11) \
101 V(double, xmm12) \
102 V(double, xmm13) \
103 V(double, xmm14) \
104 V(double, xmm15)
105
106 #endif // CPU(X86_64)
107
108 typedef enum {
109 #define DECLARE_REGISTER(_type, _regName) _regName,
110 FOR_EACH_CPU_GPREGISTER(DECLARE_REGISTER)
111 #undef DECLARE_REGISTER
112 } RegisterID;
113
114 typedef enum {
115 #define DECLARE_REGISTER(_type, _regName) _regName,
116 FOR_EACH_CPU_FPREGISTER(DECLARE_REGISTER)
117 #undef DECLARE_REGISTER
118 } XMMRegisterID;
119
120 } // namespace X86Register
121
122 class X86Assembler {
123 public:
124 typedef X86Registers::RegisterID RegisterID;
125
126 static RegisterID firstRegister() { return X86Registers::eax; }
127 static RegisterID lastRegister()
128 {
129 #if CPU(X86_64)
130 return X86Registers::r15;
131 #else
132 return X86Registers::edi;
133 #endif
134 }
135
136 typedef X86Registers::XMMRegisterID XMMRegisterID;
137 typedef XMMRegisterID FPRegisterID;
138
139 static FPRegisterID firstFPRegister() { return X86Registers::xmm0; }
140 static FPRegisterID lastFPRegister()
141 {
142 #if CPU(X86_64)
143 return X86Registers::xmm15;
144 #else
145 return X86Registers::xmm7;
146 #endif
147 }
148
149 typedef enum {
150 ConditionO,
151 ConditionNO,
152 ConditionB,
153 ConditionAE,
154 ConditionE,
155 ConditionNE,
156 ConditionBE,
157 ConditionA,
158 ConditionS,
159 ConditionNS,
160 ConditionP,
161 ConditionNP,
162 ConditionL,
163 ConditionGE,
164 ConditionLE,
165 ConditionG,
166
167 ConditionC = ConditionB,
168 ConditionNC = ConditionAE,
169 } Condition;
170
171 private:
172 typedef enum {
173 OP_ADD_EvGv = 0x01,
174 OP_ADD_GvEv = 0x03,
175 OP_ADD_EAXIv = 0x05,
176 OP_OR_EvGv = 0x09,
177 OP_OR_GvEv = 0x0B,
178 OP_OR_EAXIv = 0x0D,
179 OP_2BYTE_ESCAPE = 0x0F,
180 OP_AND_EvGv = 0x21,
181 OP_AND_GvEv = 0x23,
182 OP_SUB_EvGv = 0x29,
183 OP_SUB_GvEv = 0x2B,
184 OP_SUB_EAXIv = 0x2D,
185 PRE_PREDICT_BRANCH_NOT_TAKEN = 0x2E,
186 OP_XOR_EvGv = 0x31,
187 OP_XOR_GvEv = 0x33,
188 OP_XOR_EAXIv = 0x35,
189 OP_CMP_EvGv = 0x39,
190 OP_CMP_GvEv = 0x3B,
191 OP_CMP_EAXIv = 0x3D,
192 #if CPU(X86_64)
193 PRE_REX = 0x40,
194 #endif
195 OP_PUSH_EAX = 0x50,
196 OP_POP_EAX = 0x58,
197 #if CPU(X86_64)
198 OP_MOVSXD_GvEv = 0x63,
199 #endif
200 PRE_OPERAND_SIZE = 0x66,
201 PRE_SSE_66 = 0x66,
202 OP_PUSH_Iz = 0x68,
203 OP_IMUL_GvEvIz = 0x69,
204 OP_GROUP1_EbIb = 0x80,
205 OP_GROUP1_EvIz = 0x81,
206 OP_GROUP1_EvIb = 0x83,
207 OP_TEST_EbGb = 0x84,
208 OP_TEST_EvGv = 0x85,
209 OP_XCHG_EvGv = 0x87,
210 OP_MOV_EbGb = 0x88,
211 OP_MOV_EvGv = 0x89,
212 OP_MOV_GvEv = 0x8B,
213 OP_LEA = 0x8D,
214 OP_GROUP1A_Ev = 0x8F,
215 OP_NOP = 0x90,
216 OP_XCHG_EAX = 0x90,
217 OP_CDQ = 0x99,
218 OP_MOV_EAXOv = 0xA1,
219 OP_MOV_OvEAX = 0xA3,
220 OP_TEST_ALIb = 0xA8,
221 OP_TEST_EAXIv = 0xA9,
222 OP_MOV_EAXIv = 0xB8,
223 OP_GROUP2_EvIb = 0xC1,
224 OP_RET = 0xC3,
225 OP_GROUP11_EvIb = 0xC6,
226 OP_GROUP11_EvIz = 0xC7,
227 OP_INT3 = 0xCC,
228 OP_GROUP2_Ev1 = 0xD1,
229 OP_GROUP2_EvCL = 0xD3,
230 OP_ESCAPE_DD = 0xDD,
231 OP_CALL_rel32 = 0xE8,
232 OP_JMP_rel32 = 0xE9,
233 PRE_SSE_F2 = 0xF2,
234 PRE_SSE_F3 = 0xF3,
235 OP_HLT = 0xF4,
236 OP_GROUP3_EbIb = 0xF6,
237 OP_GROUP3_Ev = 0xF7,
238 OP_GROUP3_EvIz = 0xF7, // OP_GROUP3_Ev has an immediate, when instruction is a test.
239 OP_GROUP5_Ev = 0xFF,
240 } OneByteOpcodeID;
241
242 typedef enum {
243 OP2_MOVSD_VsdWsd = 0x10,
244 OP2_MOVSD_WsdVsd = 0x11,
245 OP2_MOVSS_VsdWsd = 0x10,
246 OP2_MOVSS_WsdVsd = 0x11,
247 OP2_CVTSI2SD_VsdEd = 0x2A,
248 OP2_CVTTSD2SI_GdWsd = 0x2C,
249 OP2_UCOMISD_VsdWsd = 0x2E,
250 OP2_ADDSD_VsdWsd = 0x58,
251 OP2_MULSD_VsdWsd = 0x59,
252 OP2_CVTSD2SS_VsdWsd = 0x5A,
253 OP2_CVTSS2SD_VsdWsd = 0x5A,
254 OP2_SUBSD_VsdWsd = 0x5C,
255 OP2_DIVSD_VsdWsd = 0x5E,
256 OP2_MOVMSKPD_VdEd = 0x50,
257 OP2_SQRTSD_VsdWsd = 0x51,
258 OP2_ANDNPD_VpdWpd = 0x55,
259 OP2_XORPD_VpdWpd = 0x57,
260 OP2_MOVD_VdEd = 0x6E,
261 OP2_MOVD_EdVd = 0x7E,
262 OP2_JCC_rel32 = 0x80,
263 OP_SETCC = 0x90,
264 OP2_3BYTE_ESCAPE = 0xAE,
265 OP2_IMUL_GvEv = 0xAF,
266 OP2_MOVZX_GvEb = 0xB6,
267 OP2_BSR = 0xBD,
268 OP2_MOVSX_GvEb = 0xBE,
269 OP2_MOVZX_GvEw = 0xB7,
270 OP2_MOVSX_GvEw = 0xBF,
271 OP2_PEXTRW_GdUdIb = 0xC5,
272 OP2_PSLLQ_UdqIb = 0x73,
273 OP2_PSRLQ_UdqIb = 0x73,
274 OP2_POR_VdqWdq = 0XEB,
275 } TwoByteOpcodeID;
276
277 typedef enum {
278 OP3_MFENCE = 0xF0,
279 } ThreeByteOpcodeID;
280
281 TwoByteOpcodeID jccRel32(Condition cond)
282 {
283 return (TwoByteOpcodeID)(OP2_JCC_rel32 + cond);
284 }
285
286 TwoByteOpcodeID setccOpcode(Condition cond)
287 {
288 return (TwoByteOpcodeID)(OP_SETCC + cond);
289 }
290
291 typedef enum {
292 GROUP1_OP_ADD = 0,
293 GROUP1_OP_OR = 1,
294 GROUP1_OP_ADC = 2,
295 GROUP1_OP_AND = 4,
296 GROUP1_OP_SUB = 5,
297 GROUP1_OP_XOR = 6,
298 GROUP1_OP_CMP = 7,
299
300 GROUP1A_OP_POP = 0,
301
302 GROUP2_OP_ROL = 0,
303 GROUP2_OP_ROR = 1,
304 GROUP2_OP_RCL = 2,
305 GROUP2_OP_RCR = 3,
306
307 GROUP2_OP_SHL = 4,
308 GROUP2_OP_SHR = 5,
309 GROUP2_OP_SAR = 7,
310
311 GROUP3_OP_TEST = 0,
312 GROUP3_OP_NOT = 2,
313 GROUP3_OP_NEG = 3,
314 GROUP3_OP_IDIV = 7,
315
316 GROUP5_OP_CALLN = 2,
317 GROUP5_OP_JMPN = 4,
318 GROUP5_OP_PUSH = 6,
319
320 GROUP11_MOV = 0,
321
322 GROUP14_OP_PSLLQ = 6,
323 GROUP14_OP_PSRLQ = 2,
324
325 ESCAPE_DD_FSTP_doubleReal = 3,
326 } GroupOpcodeID;
327
328 class X86InstructionFormatter;
329 public:
330
331 X86Assembler()
332 : m_indexOfLastWatchpoint(INT_MIN)
333 , m_indexOfTailOfLastWatchpoint(INT_MIN)
334 {
335 }
336
337 AssemblerBuffer& buffer() { return m_formatter.m_buffer; }
338
339 // Stack operations:
340
341 void push_r(RegisterID reg)
342 {
343 m_formatter.oneByteOp(OP_PUSH_EAX, reg);
344 }
345
346 void pop_r(RegisterID reg)
347 {
348 m_formatter.oneByteOp(OP_POP_EAX, reg);
349 }
350
351 void push_i32(int imm)
352 {
353 m_formatter.oneByteOp(OP_PUSH_Iz);
354 m_formatter.immediate32(imm);
355 }
356
357 void push_m(int offset, RegisterID base)
358 {
359 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_PUSH, base, offset);
360 }
361
362 void pop_m(int offset, RegisterID base)
363 {
364 m_formatter.oneByteOp(OP_GROUP1A_Ev, GROUP1A_OP_POP, base, offset);
365 }
366
367 // Arithmetic operations:
368
369 #if !CPU(X86_64)
370 void adcl_im(int imm, const void* addr)
371 {
372 if (CAN_SIGN_EXTEND_8_32(imm)) {
373 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADC, addr);
374 m_formatter.immediate8(imm);
375 } else {
376 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADC, addr);
377 m_formatter.immediate32(imm);
378 }
379 }
380 #endif
381
382 void addl_rr(RegisterID src, RegisterID dst)
383 {
384 m_formatter.oneByteOp(OP_ADD_EvGv, src, dst);
385 }
386
387 void addl_mr(int offset, RegisterID base, RegisterID dst)
388 {
389 m_formatter.oneByteOp(OP_ADD_GvEv, dst, base, offset);
390 }
391
392 #if !CPU(X86_64)
393 void addl_mr(const void* addr, RegisterID dst)
394 {
395 m_formatter.oneByteOp(OP_ADD_GvEv, dst, addr);
396 }
397 #endif
398
399 void addl_rm(RegisterID src, int offset, RegisterID base)
400 {
401 m_formatter.oneByteOp(OP_ADD_EvGv, src, base, offset);
402 }
403
404 void addl_ir(int imm, RegisterID dst)
405 {
406 if (CAN_SIGN_EXTEND_8_32(imm)) {
407 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, dst);
408 m_formatter.immediate8(imm);
409 } else {
410 if (dst == X86Registers::eax)
411 m_formatter.oneByteOp(OP_ADD_EAXIv);
412 else
413 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, dst);
414 m_formatter.immediate32(imm);
415 }
416 }
417
418 void addl_im(int imm, int offset, RegisterID base)
419 {
420 if (CAN_SIGN_EXTEND_8_32(imm)) {
421 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, base, offset);
422 m_formatter.immediate8(imm);
423 } else {
424 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, base, offset);
425 m_formatter.immediate32(imm);
426 }
427 }
428
429 #if CPU(X86_64)
430 void addq_rr(RegisterID src, RegisterID dst)
431 {
432 m_formatter.oneByteOp64(OP_ADD_EvGv, src, dst);
433 }
434
435 void addq_mr(int offset, RegisterID base, RegisterID dst)
436 {
437 m_formatter.oneByteOp64(OP_ADD_GvEv, dst, base, offset);
438 }
439
440 void addq_ir(int imm, RegisterID dst)
441 {
442 if (CAN_SIGN_EXTEND_8_32(imm)) {
443 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_ADD, dst);
444 m_formatter.immediate8(imm);
445 } else {
446 if (dst == X86Registers::eax)
447 m_formatter.oneByteOp64(OP_ADD_EAXIv);
448 else
449 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_ADD, dst);
450 m_formatter.immediate32(imm);
451 }
452 }
453
454 void addq_im(int imm, int offset, RegisterID base)
455 {
456 if (CAN_SIGN_EXTEND_8_32(imm)) {
457 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_ADD, base, offset);
458 m_formatter.immediate8(imm);
459 } else {
460 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_ADD, base, offset);
461 m_formatter.immediate32(imm);
462 }
463 }
464 #else
465 void addl_im(int imm, const void* addr)
466 {
467 if (CAN_SIGN_EXTEND_8_32(imm)) {
468 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, addr);
469 m_formatter.immediate8(imm);
470 } else {
471 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, addr);
472 m_formatter.immediate32(imm);
473 }
474 }
475 #endif
476
477 void andl_rr(RegisterID src, RegisterID dst)
478 {
479 m_formatter.oneByteOp(OP_AND_EvGv, src, dst);
480 }
481
482 void andl_mr(int offset, RegisterID base, RegisterID dst)
483 {
484 m_formatter.oneByteOp(OP_AND_GvEv, dst, base, offset);
485 }
486
487 void andl_rm(RegisterID src, int offset, RegisterID base)
488 {
489 m_formatter.oneByteOp(OP_AND_EvGv, src, base, offset);
490 }
491
492 void andl_ir(int imm, RegisterID dst)
493 {
494 if (CAN_SIGN_EXTEND_8_32(imm)) {
495 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, dst);
496 m_formatter.immediate8(imm);
497 } else {
498 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, dst);
499 m_formatter.immediate32(imm);
500 }
501 }
502
503 void andl_im(int imm, int offset, RegisterID base)
504 {
505 if (CAN_SIGN_EXTEND_8_32(imm)) {
506 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, base, offset);
507 m_formatter.immediate8(imm);
508 } else {
509 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, base, offset);
510 m_formatter.immediate32(imm);
511 }
512 }
513
514 #if CPU(X86_64)
515 void andq_rr(RegisterID src, RegisterID dst)
516 {
517 m_formatter.oneByteOp64(OP_AND_EvGv, src, dst);
518 }
519
520 void andq_ir(int imm, RegisterID dst)
521 {
522 if (CAN_SIGN_EXTEND_8_32(imm)) {
523 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_AND, dst);
524 m_formatter.immediate8(imm);
525 } else {
526 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_AND, dst);
527 m_formatter.immediate32(imm);
528 }
529 }
530 #else
531 void andl_im(int imm, const void* addr)
532 {
533 if (CAN_SIGN_EXTEND_8_32(imm)) {
534 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, addr);
535 m_formatter.immediate8(imm);
536 } else {
537 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, addr);
538 m_formatter.immediate32(imm);
539 }
540 }
541 #endif
542
543 void dec_r(RegisterID dst)
544 {
545 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP1_OP_OR, dst);
546 }
547
548 #if CPU(X86_64)
549 void decq_r(RegisterID dst)
550 {
551 m_formatter.oneByteOp64(OP_GROUP5_Ev, GROUP1_OP_OR, dst);
552 }
553 #endif // CPU(X86_64)
554
555 void inc_r(RegisterID dst)
556 {
557 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP1_OP_ADD, dst);
558 }
559
560 #if CPU(X86_64)
561 void incq_r(RegisterID dst)
562 {
563 m_formatter.oneByteOp64(OP_GROUP5_Ev, GROUP1_OP_ADD, dst);
564 }
565
566 void incq_m(int offset, RegisterID base)
567 {
568 m_formatter.oneByteOp64(OP_GROUP5_Ev, GROUP1_OP_ADD, base, offset);
569 }
570 #endif // CPU(X86_64)
571
572 void negl_r(RegisterID dst)
573 {
574 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NEG, dst);
575 }
576
577 #if CPU(X86_64)
578 void negq_r(RegisterID dst)
579 {
580 m_formatter.oneByteOp64(OP_GROUP3_Ev, GROUP3_OP_NEG, dst);
581 }
582 #endif
583
584 void negl_m(int offset, RegisterID base)
585 {
586 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NEG, base, offset);
587 }
588
589 void notl_r(RegisterID dst)
590 {
591 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NOT, dst);
592 }
593
594 void notl_m(int offset, RegisterID base)
595 {
596 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NOT, base, offset);
597 }
598
599 void orl_rr(RegisterID src, RegisterID dst)
600 {
601 m_formatter.oneByteOp(OP_OR_EvGv, src, dst);
602 }
603
604 void orl_mr(int offset, RegisterID base, RegisterID dst)
605 {
606 m_formatter.oneByteOp(OP_OR_GvEv, dst, base, offset);
607 }
608
609 void orl_rm(RegisterID src, int offset, RegisterID base)
610 {
611 m_formatter.oneByteOp(OP_OR_EvGv, src, base, offset);
612 }
613
614 void orl_ir(int imm, RegisterID dst)
615 {
616 if (CAN_SIGN_EXTEND_8_32(imm)) {
617 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, dst);
618 m_formatter.immediate8(imm);
619 } else {
620 if (dst == X86Registers::eax)
621 m_formatter.oneByteOp(OP_OR_EAXIv);
622 else
623 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, dst);
624 m_formatter.immediate32(imm);
625 }
626 }
627
628 void orl_im(int imm, int offset, RegisterID base)
629 {
630 if (CAN_SIGN_EXTEND_8_32(imm)) {
631 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, base, offset);
632 m_formatter.immediate8(imm);
633 } else {
634 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, base, offset);
635 m_formatter.immediate32(imm);
636 }
637 }
638
639 #if CPU(X86_64)
640 void orq_rr(RegisterID src, RegisterID dst)
641 {
642 m_formatter.oneByteOp64(OP_OR_EvGv, src, dst);
643 }
644
645 void orq_ir(int imm, RegisterID dst)
646 {
647 if (CAN_SIGN_EXTEND_8_32(imm)) {
648 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_OR, dst);
649 m_formatter.immediate8(imm);
650 } else {
651 if (dst == X86Registers::eax)
652 m_formatter.oneByteOp64(OP_OR_EAXIv);
653 else
654 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_OR, dst);
655 m_formatter.immediate32(imm);
656 }
657 }
658 #else
659 void orl_im(int imm, const void* addr)
660 {
661 if (CAN_SIGN_EXTEND_8_32(imm)) {
662 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, addr);
663 m_formatter.immediate8(imm);
664 } else {
665 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, addr);
666 m_formatter.immediate32(imm);
667 }
668 }
669
670 void orl_rm(RegisterID src, const void* addr)
671 {
672 m_formatter.oneByteOp(OP_OR_EvGv, src, addr);
673 }
674 #endif
675
676 void subl_rr(RegisterID src, RegisterID dst)
677 {
678 m_formatter.oneByteOp(OP_SUB_EvGv, src, dst);
679 }
680
681 void subl_mr(int offset, RegisterID base, RegisterID dst)
682 {
683 m_formatter.oneByteOp(OP_SUB_GvEv, dst, base, offset);
684 }
685
686 void subl_rm(RegisterID src, int offset, RegisterID base)
687 {
688 m_formatter.oneByteOp(OP_SUB_EvGv, src, base, offset);
689 }
690
691 void subl_ir(int imm, RegisterID dst)
692 {
693 if (CAN_SIGN_EXTEND_8_32(imm)) {
694 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, dst);
695 m_formatter.immediate8(imm);
696 } else {
697 if (dst == X86Registers::eax)
698 m_formatter.oneByteOp(OP_SUB_EAXIv);
699 else
700 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, dst);
701 m_formatter.immediate32(imm);
702 }
703 }
704
705 void subl_im(int imm, int offset, RegisterID base)
706 {
707 if (CAN_SIGN_EXTEND_8_32(imm)) {
708 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, base, offset);
709 m_formatter.immediate8(imm);
710 } else {
711 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, base, offset);
712 m_formatter.immediate32(imm);
713 }
714 }
715
716 #if CPU(X86_64)
717 void subq_rr(RegisterID src, RegisterID dst)
718 {
719 m_formatter.oneByteOp64(OP_SUB_EvGv, src, dst);
720 }
721
722 void subq_ir(int imm, RegisterID dst)
723 {
724 if (CAN_SIGN_EXTEND_8_32(imm)) {
725 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_SUB, dst);
726 m_formatter.immediate8(imm);
727 } else {
728 if (dst == X86Registers::eax)
729 m_formatter.oneByteOp64(OP_SUB_EAXIv);
730 else
731 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_SUB, dst);
732 m_formatter.immediate32(imm);
733 }
734 }
735 #else
736 void subl_im(int imm, const void* addr)
737 {
738 if (CAN_SIGN_EXTEND_8_32(imm)) {
739 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, addr);
740 m_formatter.immediate8(imm);
741 } else {
742 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, addr);
743 m_formatter.immediate32(imm);
744 }
745 }
746 #endif
747
748 void xorl_rr(RegisterID src, RegisterID dst)
749 {
750 m_formatter.oneByteOp(OP_XOR_EvGv, src, dst);
751 }
752
753 void xorl_mr(int offset, RegisterID base, RegisterID dst)
754 {
755 m_formatter.oneByteOp(OP_XOR_GvEv, dst, base, offset);
756 }
757
758 void xorl_rm(RegisterID src, int offset, RegisterID base)
759 {
760 m_formatter.oneByteOp(OP_XOR_EvGv, src, base, offset);
761 }
762
763 void xorl_im(int imm, int offset, RegisterID base)
764 {
765 if (CAN_SIGN_EXTEND_8_32(imm)) {
766 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_XOR, base, offset);
767 m_formatter.immediate8(imm);
768 } else {
769 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_XOR, base, offset);
770 m_formatter.immediate32(imm);
771 }
772 }
773
774 void xorl_ir(int imm, RegisterID dst)
775 {
776 if (CAN_SIGN_EXTEND_8_32(imm)) {
777 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_XOR, dst);
778 m_formatter.immediate8(imm);
779 } else {
780 if (dst == X86Registers::eax)
781 m_formatter.oneByteOp(OP_XOR_EAXIv);
782 else
783 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_XOR, dst);
784 m_formatter.immediate32(imm);
785 }
786 }
787
788 #if CPU(X86_64)
789 void xorq_rr(RegisterID src, RegisterID dst)
790 {
791 m_formatter.oneByteOp64(OP_XOR_EvGv, src, dst);
792 }
793
794 void xorq_ir(int imm, RegisterID dst)
795 {
796 if (CAN_SIGN_EXTEND_8_32(imm)) {
797 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_XOR, dst);
798 m_formatter.immediate8(imm);
799 } else {
800 if (dst == X86Registers::eax)
801 m_formatter.oneByteOp64(OP_XOR_EAXIv);
802 else
803 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_XOR, dst);
804 m_formatter.immediate32(imm);
805 }
806 }
807
808 void xorq_rm(RegisterID src, int offset, RegisterID base)
809 {
810 m_formatter.oneByteOp64(OP_XOR_EvGv, src, base, offset);
811 }
812
813 void rorq_i8r(int imm, RegisterID dst)
814 {
815 if (imm == 1)
816 m_formatter.oneByteOp64(OP_GROUP2_Ev1, GROUP2_OP_ROR, dst);
817 else {
818 m_formatter.oneByteOp64(OP_GROUP2_EvIb, GROUP2_OP_ROR, dst);
819 m_formatter.immediate8(imm);
820 }
821 }
822
823 #endif
824
825 void bsr_rr(RegisterID src, RegisterID dst)
826 {
827 m_formatter.twoByteOp(OP2_BSR, dst, src);
828 }
829
830 void sarl_i8r(int imm, RegisterID dst)
831 {
832 if (imm == 1)
833 m_formatter.oneByteOp(OP_GROUP2_Ev1, GROUP2_OP_SAR, dst);
834 else {
835 m_formatter.oneByteOp(OP_GROUP2_EvIb, GROUP2_OP_SAR, dst);
836 m_formatter.immediate8(imm);
837 }
838 }
839
840 void sarl_CLr(RegisterID dst)
841 {
842 m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SAR, dst);
843 }
844
845 void shrl_i8r(int imm, RegisterID dst)
846 {
847 if (imm == 1)
848 m_formatter.oneByteOp(OP_GROUP2_Ev1, GROUP2_OP_SHR, dst);
849 else {
850 m_formatter.oneByteOp(OP_GROUP2_EvIb, GROUP2_OP_SHR, dst);
851 m_formatter.immediate8(imm);
852 }
853 }
854
855 void shrl_CLr(RegisterID dst)
856 {
857 m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SHR, dst);
858 }
859
860 void shll_i8r(int imm, RegisterID dst)
861 {
862 if (imm == 1)
863 m_formatter.oneByteOp(OP_GROUP2_Ev1, GROUP2_OP_SHL, dst);
864 else {
865 m_formatter.oneByteOp(OP_GROUP2_EvIb, GROUP2_OP_SHL, dst);
866 m_formatter.immediate8(imm);
867 }
868 }
869
870 void shll_CLr(RegisterID dst)
871 {
872 m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SHL, dst);
873 }
874
875 #if CPU(X86_64)
876 void sarq_CLr(RegisterID dst)
877 {
878 m_formatter.oneByteOp64(OP_GROUP2_EvCL, GROUP2_OP_SAR, dst);
879 }
880
881 void sarq_i8r(int imm, RegisterID dst)
882 {
883 if (imm == 1)
884 m_formatter.oneByteOp64(OP_GROUP2_Ev1, GROUP2_OP_SAR, dst);
885 else {
886 m_formatter.oneByteOp64(OP_GROUP2_EvIb, GROUP2_OP_SAR, dst);
887 m_formatter.immediate8(imm);
888 }
889 }
890
891 void shrq_i8r(int imm, RegisterID dst)
892 {
893 if (imm == 1)
894 m_formatter.oneByteOp64(OP_GROUP2_Ev1, GROUP2_OP_SHR, dst);
895 else {
896 m_formatter.oneByteOp64(OP_GROUP2_EvIb, GROUP2_OP_SHR, dst);
897 m_formatter.immediate8(imm);
898 }
899 }
900
901 void shlq_i8r(int imm, RegisterID dst)
902 {
903 if (imm == 1)
904 m_formatter.oneByteOp64(OP_GROUP2_Ev1, GROUP2_OP_SHL, dst);
905 else {
906 m_formatter.oneByteOp64(OP_GROUP2_EvIb, GROUP2_OP_SHL, dst);
907 m_formatter.immediate8(imm);
908 }
909 }
910 #endif // CPU(X86_64)
911
912 void imull_rr(RegisterID src, RegisterID dst)
913 {
914 m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, src);
915 }
916
917 #if CPU(X86_64)
918 void imulq_rr(RegisterID src, RegisterID dst)
919 {
920 m_formatter.twoByteOp64(OP2_IMUL_GvEv, dst, src);
921 }
922 #endif // CPU(X86_64)
923
924 void imull_mr(int offset, RegisterID base, RegisterID dst)
925 {
926 m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, base, offset);
927 }
928
929 void imull_i32r(RegisterID src, int32_t value, RegisterID dst)
930 {
931 m_formatter.oneByteOp(OP_IMUL_GvEvIz, dst, src);
932 m_formatter.immediate32(value);
933 }
934
935 void idivl_r(RegisterID dst)
936 {
937 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_IDIV, dst);
938 }
939
940 // Comparisons:
941
942 void cmpl_rr(RegisterID src, RegisterID dst)
943 {
944 m_formatter.oneByteOp(OP_CMP_EvGv, src, dst);
945 }
946
947 void cmpl_rm(RegisterID src, int offset, RegisterID base)
948 {
949 m_formatter.oneByteOp(OP_CMP_EvGv, src, base, offset);
950 }
951
952 void cmpl_mr(int offset, RegisterID base, RegisterID src)
953 {
954 m_formatter.oneByteOp(OP_CMP_GvEv, src, base, offset);
955 }
956
957 void cmpl_ir(int imm, RegisterID dst)
958 {
959 if (CAN_SIGN_EXTEND_8_32(imm)) {
960 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, dst);
961 m_formatter.immediate8(imm);
962 } else {
963 if (dst == X86Registers::eax)
964 m_formatter.oneByteOp(OP_CMP_EAXIv);
965 else
966 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
967 m_formatter.immediate32(imm);
968 }
969 }
970
971 void cmpl_ir_force32(int imm, RegisterID dst)
972 {
973 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
974 m_formatter.immediate32(imm);
975 }
976
977 void cmpl_im(int imm, int offset, RegisterID base)
978 {
979 if (CAN_SIGN_EXTEND_8_32(imm)) {
980 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, offset);
981 m_formatter.immediate8(imm);
982 } else {
983 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, offset);
984 m_formatter.immediate32(imm);
985 }
986 }
987
988 void cmpb_im(int imm, int offset, RegisterID base)
989 {
990 m_formatter.oneByteOp(OP_GROUP1_EbIb, GROUP1_OP_CMP, base, offset);
991 m_formatter.immediate8(imm);
992 }
993
994 void cmpb_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
995 {
996 m_formatter.oneByteOp(OP_GROUP1_EbIb, GROUP1_OP_CMP, base, index, scale, offset);
997 m_formatter.immediate8(imm);
998 }
999
1000 #if CPU(X86)
1001 void cmpb_im(int imm, const void* addr)
1002 {
1003 m_formatter.oneByteOp(OP_GROUP1_EbIb, GROUP1_OP_CMP, addr);
1004 m_formatter.immediate8(imm);
1005 }
1006 #endif
1007
1008 void cmpl_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
1009 {
1010 if (CAN_SIGN_EXTEND_8_32(imm)) {
1011 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, index, scale, offset);
1012 m_formatter.immediate8(imm);
1013 } else {
1014 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, index, scale, offset);
1015 m_formatter.immediate32(imm);
1016 }
1017 }
1018
1019 void cmpl_im_force32(int imm, int offset, RegisterID base)
1020 {
1021 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, offset);
1022 m_formatter.immediate32(imm);
1023 }
1024
1025 #if CPU(X86_64)
1026 void cmpq_rr(RegisterID src, RegisterID dst)
1027 {
1028 m_formatter.oneByteOp64(OP_CMP_EvGv, src, dst);
1029 }
1030
1031 void cmpq_rm(RegisterID src, int offset, RegisterID base)
1032 {
1033 m_formatter.oneByteOp64(OP_CMP_EvGv, src, base, offset);
1034 }
1035
1036 void cmpq_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1037 {
1038 m_formatter.oneByteOp64(OP_CMP_EvGv, src, base, index, scale, offset);
1039 }
1040
1041 void cmpq_mr(int offset, RegisterID base, RegisterID src)
1042 {
1043 m_formatter.oneByteOp64(OP_CMP_GvEv, src, base, offset);
1044 }
1045
1046 void cmpq_ir(int imm, RegisterID dst)
1047 {
1048 if (CAN_SIGN_EXTEND_8_32(imm)) {
1049 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_CMP, dst);
1050 m_formatter.immediate8(imm);
1051 } else {
1052 if (dst == X86Registers::eax)
1053 m_formatter.oneByteOp64(OP_CMP_EAXIv);
1054 else
1055 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
1056 m_formatter.immediate32(imm);
1057 }
1058 }
1059
1060 void cmpq_im(int imm, int offset, RegisterID base)
1061 {
1062 if (CAN_SIGN_EXTEND_8_32(imm)) {
1063 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, offset);
1064 m_formatter.immediate8(imm);
1065 } else {
1066 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, offset);
1067 m_formatter.immediate32(imm);
1068 }
1069 }
1070
1071 void cmpq_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
1072 {
1073 if (CAN_SIGN_EXTEND_8_32(imm)) {
1074 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, index, scale, offset);
1075 m_formatter.immediate8(imm);
1076 } else {
1077 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, index, scale, offset);
1078 m_formatter.immediate32(imm);
1079 }
1080 }
1081 #else
1082 void cmpl_rm(RegisterID reg, const void* addr)
1083 {
1084 m_formatter.oneByteOp(OP_CMP_EvGv, reg, addr);
1085 }
1086
1087 void cmpl_im(int imm, const void* addr)
1088 {
1089 if (CAN_SIGN_EXTEND_8_32(imm)) {
1090 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, addr);
1091 m_formatter.immediate8(imm);
1092 } else {
1093 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, addr);
1094 m_formatter.immediate32(imm);
1095 }
1096 }
1097 #endif
1098
1099 void cmpw_ir(int imm, RegisterID dst)
1100 {
1101 if (CAN_SIGN_EXTEND_8_32(imm)) {
1102 m_formatter.prefix(PRE_OPERAND_SIZE);
1103 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, dst);
1104 m_formatter.immediate8(imm);
1105 } else {
1106 m_formatter.prefix(PRE_OPERAND_SIZE);
1107 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
1108 m_formatter.immediate16(imm);
1109 }
1110 }
1111
1112 void cmpw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1113 {
1114 m_formatter.prefix(PRE_OPERAND_SIZE);
1115 m_formatter.oneByteOp(OP_CMP_EvGv, src, base, index, scale, offset);
1116 }
1117
1118 void cmpw_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
1119 {
1120 if (CAN_SIGN_EXTEND_8_32(imm)) {
1121 m_formatter.prefix(PRE_OPERAND_SIZE);
1122 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, index, scale, offset);
1123 m_formatter.immediate8(imm);
1124 } else {
1125 m_formatter.prefix(PRE_OPERAND_SIZE);
1126 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, index, scale, offset);
1127 m_formatter.immediate16(imm);
1128 }
1129 }
1130
1131 void testl_rr(RegisterID src, RegisterID dst)
1132 {
1133 m_formatter.oneByteOp(OP_TEST_EvGv, src, dst);
1134 }
1135
1136 void testl_i32r(int imm, RegisterID dst)
1137 {
1138 if (dst == X86Registers::eax)
1139 m_formatter.oneByteOp(OP_TEST_EAXIv);
1140 else
1141 m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, dst);
1142 m_formatter.immediate32(imm);
1143 }
1144
1145 void testl_i32m(int imm, int offset, RegisterID base)
1146 {
1147 m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, offset);
1148 m_formatter.immediate32(imm);
1149 }
1150
1151 void testb_rr(RegisterID src, RegisterID dst)
1152 {
1153 m_formatter.oneByteOp8(OP_TEST_EbGb, src, dst);
1154 }
1155
1156 void testb_im(int imm, int offset, RegisterID base)
1157 {
1158 m_formatter.oneByteOp(OP_GROUP3_EbIb, GROUP3_OP_TEST, base, offset);
1159 m_formatter.immediate8(imm);
1160 }
1161
1162 void testb_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
1163 {
1164 m_formatter.oneByteOp(OP_GROUP3_EbIb, GROUP3_OP_TEST, base, index, scale, offset);
1165 m_formatter.immediate8(imm);
1166 }
1167
1168 #if CPU(X86)
1169 void testb_im(int imm, const void* addr)
1170 {
1171 m_formatter.oneByteOp(OP_GROUP3_EbIb, GROUP3_OP_TEST, addr);
1172 m_formatter.immediate8(imm);
1173 }
1174 #endif
1175
1176 void testl_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale)
1177 {
1178 m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, index, scale, offset);
1179 m_formatter.immediate32(imm);
1180 }
1181
1182 #if CPU(X86_64)
1183 void testq_rr(RegisterID src, RegisterID dst)
1184 {
1185 m_formatter.oneByteOp64(OP_TEST_EvGv, src, dst);
1186 }
1187
1188 void testq_rm(RegisterID src, int offset, RegisterID base)
1189 {
1190 m_formatter.oneByteOp64(OP_TEST_EvGv, src, base, offset);
1191 }
1192
1193 void testq_i32r(int imm, RegisterID dst)
1194 {
1195 if (dst == X86Registers::eax)
1196 m_formatter.oneByteOp64(OP_TEST_EAXIv);
1197 else
1198 m_formatter.oneByteOp64(OP_GROUP3_EvIz, GROUP3_OP_TEST, dst);
1199 m_formatter.immediate32(imm);
1200 }
1201
1202 void testq_i32m(int imm, int offset, RegisterID base)
1203 {
1204 m_formatter.oneByteOp64(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, offset);
1205 m_formatter.immediate32(imm);
1206 }
1207
1208 void testq_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale)
1209 {
1210 m_formatter.oneByteOp64(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, index, scale, offset);
1211 m_formatter.immediate32(imm);
1212 }
1213 #endif
1214
1215 void testw_rr(RegisterID src, RegisterID dst)
1216 {
1217 m_formatter.prefix(PRE_OPERAND_SIZE);
1218 m_formatter.oneByteOp(OP_TEST_EvGv, src, dst);
1219 }
1220
1221 void testb_i8r(int imm, RegisterID dst)
1222 {
1223 if (dst == X86Registers::eax)
1224 m_formatter.oneByteOp(OP_TEST_ALIb);
1225 else
1226 m_formatter.oneByteOp8(OP_GROUP3_EbIb, GROUP3_OP_TEST, dst);
1227 m_formatter.immediate8(imm);
1228 }
1229
1230 void setCC_r(Condition cond, RegisterID dst)
1231 {
1232 m_formatter.twoByteOp8(setccOpcode(cond), (GroupOpcodeID)0, dst);
1233 }
1234
1235 void sete_r(RegisterID dst)
1236 {
1237 m_formatter.twoByteOp8(setccOpcode(ConditionE), (GroupOpcodeID)0, dst);
1238 }
1239
1240 void setz_r(RegisterID dst)
1241 {
1242 sete_r(dst);
1243 }
1244
1245 void setne_r(RegisterID dst)
1246 {
1247 m_formatter.twoByteOp8(setccOpcode(ConditionNE), (GroupOpcodeID)0, dst);
1248 }
1249
1250 void setnz_r(RegisterID dst)
1251 {
1252 setne_r(dst);
1253 }
1254
1255 // Various move ops:
1256
1257 void cdq()
1258 {
1259 m_formatter.oneByteOp(OP_CDQ);
1260 }
1261
1262 void fstpl(int offset, RegisterID base)
1263 {
1264 m_formatter.oneByteOp(OP_ESCAPE_DD, ESCAPE_DD_FSTP_doubleReal, base, offset);
1265 }
1266
1267 void xchgl_rr(RegisterID src, RegisterID dst)
1268 {
1269 if (src == X86Registers::eax)
1270 m_formatter.oneByteOp(OP_XCHG_EAX, dst);
1271 else if (dst == X86Registers::eax)
1272 m_formatter.oneByteOp(OP_XCHG_EAX, src);
1273 else
1274 m_formatter.oneByteOp(OP_XCHG_EvGv, src, dst);
1275 }
1276
1277 #if CPU(X86_64)
1278 void xchgq_rr(RegisterID src, RegisterID dst)
1279 {
1280 if (src == X86Registers::eax)
1281 m_formatter.oneByteOp64(OP_XCHG_EAX, dst);
1282 else if (dst == X86Registers::eax)
1283 m_formatter.oneByteOp64(OP_XCHG_EAX, src);
1284 else
1285 m_formatter.oneByteOp64(OP_XCHG_EvGv, src, dst);
1286 }
1287 #endif
1288
1289 void movl_rr(RegisterID src, RegisterID dst)
1290 {
1291 m_formatter.oneByteOp(OP_MOV_EvGv, src, dst);
1292 }
1293
1294 void movl_rm(RegisterID src, int offset, RegisterID base)
1295 {
1296 m_formatter.oneByteOp(OP_MOV_EvGv, src, base, offset);
1297 }
1298
1299 void movl_rm_disp32(RegisterID src, int offset, RegisterID base)
1300 {
1301 m_formatter.oneByteOp_disp32(OP_MOV_EvGv, src, base, offset);
1302 }
1303
1304 void movl_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1305 {
1306 m_formatter.oneByteOp(OP_MOV_EvGv, src, base, index, scale, offset);
1307 }
1308
1309 void movl_mEAX(const void* addr)
1310 {
1311 m_formatter.oneByteOp(OP_MOV_EAXOv);
1312 #if CPU(X86_64)
1313 m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
1314 #else
1315 m_formatter.immediate32(reinterpret_cast<int>(addr));
1316 #endif
1317 }
1318
1319 void movl_mr(int offset, RegisterID base, RegisterID dst)
1320 {
1321 m_formatter.oneByteOp(OP_MOV_GvEv, dst, base, offset);
1322 }
1323
1324 void movl_mr_disp32(int offset, RegisterID base, RegisterID dst)
1325 {
1326 m_formatter.oneByteOp_disp32(OP_MOV_GvEv, dst, base, offset);
1327 }
1328
1329 void movl_mr_disp8(int offset, RegisterID base, RegisterID dst)
1330 {
1331 m_formatter.oneByteOp_disp8(OP_MOV_GvEv, dst, base, offset);
1332 }
1333
1334 void movl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1335 {
1336 m_formatter.oneByteOp(OP_MOV_GvEv, dst, base, index, scale, offset);
1337 }
1338
1339 void movl_i32r(int imm, RegisterID dst)
1340 {
1341 m_formatter.oneByteOp(OP_MOV_EAXIv, dst);
1342 m_formatter.immediate32(imm);
1343 }
1344
1345 void movl_i32m(int imm, int offset, RegisterID base)
1346 {
1347 m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, base, offset);
1348 m_formatter.immediate32(imm);
1349 }
1350
1351 void movl_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale)
1352 {
1353 m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, base, index, scale, offset);
1354 m_formatter.immediate32(imm);
1355 }
1356
1357 #if !CPU(X86_64)
1358 void movb_i8m(int imm, const void* addr)
1359 {
1360 ASSERT(-128 <= imm && imm < 128);
1361 m_formatter.oneByteOp(OP_GROUP11_EvIb, GROUP11_MOV, addr);
1362 m_formatter.immediate8(imm);
1363 }
1364 #endif
1365
1366 void movb_i8m(int imm, int offset, RegisterID base)
1367 {
1368 ASSERT(-128 <= imm && imm < 128);
1369 m_formatter.oneByteOp(OP_GROUP11_EvIb, GROUP11_MOV, base, offset);
1370 m_formatter.immediate8(imm);
1371 }
1372
1373 void movb_i8m(int imm, int offset, RegisterID base, RegisterID index, int scale)
1374 {
1375 ASSERT(-128 <= imm && imm < 128);
1376 m_formatter.oneByteOp(OP_GROUP11_EvIb, GROUP11_MOV, base, index, scale, offset);
1377 m_formatter.immediate8(imm);
1378 }
1379
1380 #if !CPU(X86_64)
1381 void movb_rm(RegisterID src, const void* addr)
1382 {
1383 m_formatter.oneByteOp(OP_MOV_EbGb, src, addr);
1384 }
1385 #endif
1386
1387 void movb_rm(RegisterID src, int offset, RegisterID base)
1388 {
1389 m_formatter.oneByteOp8(OP_MOV_EbGb, src, base, offset);
1390 }
1391
1392 void movb_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1393 {
1394 m_formatter.oneByteOp8(OP_MOV_EbGb, src, base, index, scale, offset);
1395 }
1396
1397 void movw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1398 {
1399 m_formatter.prefix(PRE_OPERAND_SIZE);
1400 m_formatter.oneByteOp8(OP_MOV_EvGv, src, base, index, scale, offset);
1401 }
1402
1403 void movl_EAXm(const void* addr)
1404 {
1405 m_formatter.oneByteOp(OP_MOV_OvEAX);
1406 #if CPU(X86_64)
1407 m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
1408 #else
1409 m_formatter.immediate32(reinterpret_cast<int>(addr));
1410 #endif
1411 }
1412
1413 #if CPU(X86_64)
1414 void movq_rr(RegisterID src, RegisterID dst)
1415 {
1416 m_formatter.oneByteOp64(OP_MOV_EvGv, src, dst);
1417 }
1418
1419 void movq_rm(RegisterID src, int offset, RegisterID base)
1420 {
1421 m_formatter.oneByteOp64(OP_MOV_EvGv, src, base, offset);
1422 }
1423
1424 void movq_rm_disp32(RegisterID src, int offset, RegisterID base)
1425 {
1426 m_formatter.oneByteOp64_disp32(OP_MOV_EvGv, src, base, offset);
1427 }
1428
1429 void movq_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1430 {
1431 m_formatter.oneByteOp64(OP_MOV_EvGv, src, base, index, scale, offset);
1432 }
1433
1434 void movq_mEAX(const void* addr)
1435 {
1436 m_formatter.oneByteOp64(OP_MOV_EAXOv);
1437 m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
1438 }
1439
1440 void movq_EAXm(const void* addr)
1441 {
1442 m_formatter.oneByteOp64(OP_MOV_OvEAX);
1443 m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
1444 }
1445
1446 void movq_mr(int offset, RegisterID base, RegisterID dst)
1447 {
1448 m_formatter.oneByteOp64(OP_MOV_GvEv, dst, base, offset);
1449 }
1450
1451 void movq_mr_disp32(int offset, RegisterID base, RegisterID dst)
1452 {
1453 m_formatter.oneByteOp64_disp32(OP_MOV_GvEv, dst, base, offset);
1454 }
1455
1456 void movq_mr_disp8(int offset, RegisterID base, RegisterID dst)
1457 {
1458 m_formatter.oneByteOp64_disp8(OP_MOV_GvEv, dst, base, offset);
1459 }
1460
1461 void movq_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1462 {
1463 m_formatter.oneByteOp64(OP_MOV_GvEv, dst, base, index, scale, offset);
1464 }
1465
1466 void movq_i32m(int imm, int offset, RegisterID base)
1467 {
1468 m_formatter.oneByteOp64(OP_GROUP11_EvIz, GROUP11_MOV, base, offset);
1469 m_formatter.immediate32(imm);
1470 }
1471
1472 void movq_i64r(int64_t imm, RegisterID dst)
1473 {
1474 m_formatter.oneByteOp64(OP_MOV_EAXIv, dst);
1475 m_formatter.immediate64(imm);
1476 }
1477
1478 void movsxd_rr(RegisterID src, RegisterID dst)
1479 {
1480 m_formatter.oneByteOp64(OP_MOVSXD_GvEv, dst, src);
1481 }
1482
1483
1484 #else
1485 void movl_rm(RegisterID src, const void* addr)
1486 {
1487 if (src == X86Registers::eax)
1488 movl_EAXm(addr);
1489 else
1490 m_formatter.oneByteOp(OP_MOV_EvGv, src, addr);
1491 }
1492
1493 void movl_mr(const void* addr, RegisterID dst)
1494 {
1495 if (dst == X86Registers::eax)
1496 movl_mEAX(addr);
1497 else
1498 m_formatter.oneByteOp(OP_MOV_GvEv, dst, addr);
1499 }
1500
1501 void movl_i32m(int imm, const void* addr)
1502 {
1503 m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, addr);
1504 m_formatter.immediate32(imm);
1505 }
1506 #endif
1507
1508 void movzwl_mr(int offset, RegisterID base, RegisterID dst)
1509 {
1510 m_formatter.twoByteOp(OP2_MOVZX_GvEw, dst, base, offset);
1511 }
1512
1513 void movzwl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1514 {
1515 m_formatter.twoByteOp(OP2_MOVZX_GvEw, dst, base, index, scale, offset);
1516 }
1517
1518 void movswl_mr(int offset, RegisterID base, RegisterID dst)
1519 {
1520 m_formatter.twoByteOp(OP2_MOVSX_GvEw, dst, base, offset);
1521 }
1522
1523 void movswl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1524 {
1525 m_formatter.twoByteOp(OP2_MOVSX_GvEw, dst, base, index, scale, offset);
1526 }
1527
1528 void movzbl_mr(int offset, RegisterID base, RegisterID dst)
1529 {
1530 m_formatter.twoByteOp(OP2_MOVZX_GvEb, dst, base, offset);
1531 }
1532
1533 void movzbl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1534 {
1535 m_formatter.twoByteOp(OP2_MOVZX_GvEb, dst, base, index, scale, offset);
1536 }
1537
1538 #if !CPU(X86_64)
1539 void movzbl_mr(const void* address, RegisterID dst)
1540 {
1541 m_formatter.twoByteOp(OP2_MOVZX_GvEb, dst, address);
1542 }
1543 #endif
1544
1545 void movsbl_mr(int offset, RegisterID base, RegisterID dst)
1546 {
1547 m_formatter.twoByteOp(OP2_MOVSX_GvEb, dst, base, offset);
1548 }
1549
1550 void movsbl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1551 {
1552 m_formatter.twoByteOp(OP2_MOVSX_GvEb, dst, base, index, scale, offset);
1553 }
1554
1555 void movzbl_rr(RegisterID src, RegisterID dst)
1556 {
1557 // In 64-bit, this may cause an unnecessary REX to be planted (if the dst register
1558 // is in the range ESP-EDI, and the src would not have required a REX). Unneeded
1559 // REX prefixes are defined to be silently ignored by the processor.
1560 m_formatter.twoByteOp8(OP2_MOVZX_GvEb, dst, src);
1561 }
1562
1563 void leal_mr(int offset, RegisterID base, RegisterID dst)
1564 {
1565 m_formatter.oneByteOp(OP_LEA, dst, base, offset);
1566 }
1567 #if CPU(X86_64)
1568 void leaq_mr(int offset, RegisterID base, RegisterID dst)
1569 {
1570 m_formatter.oneByteOp64(OP_LEA, dst, base, offset);
1571 }
1572 #endif
1573
1574 // Flow control:
1575
1576 AssemblerLabel call()
1577 {
1578 m_formatter.oneByteOp(OP_CALL_rel32);
1579 return m_formatter.immediateRel32();
1580 }
1581
1582 AssemblerLabel call(RegisterID dst)
1583 {
1584 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_CALLN, dst);
1585 return m_formatter.label();
1586 }
1587
1588 void call_m(int offset, RegisterID base)
1589 {
1590 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_CALLN, base, offset);
1591 }
1592
1593 AssemblerLabel jmp()
1594 {
1595 m_formatter.oneByteOp(OP_JMP_rel32);
1596 return m_formatter.immediateRel32();
1597 }
1598
1599 // Return a AssemblerLabel so we have a label to the jump, so we can use this
1600 // To make a tail recursive call on x86-64. The MacroAssembler
1601 // really shouldn't wrap this as a Jump, since it can't be linked. :-/
1602 AssemblerLabel jmp_r(RegisterID dst)
1603 {
1604 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, dst);
1605 return m_formatter.label();
1606 }
1607
1608 void jmp_m(int offset, RegisterID base)
1609 {
1610 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, base, offset);
1611 }
1612
1613 #if !CPU(X86_64)
1614 void jmp_m(const void* address)
1615 {
1616 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, address);
1617 }
1618 #endif
1619
1620 AssemblerLabel jne()
1621 {
1622 m_formatter.twoByteOp(jccRel32(ConditionNE));
1623 return m_formatter.immediateRel32();
1624 }
1625
1626 AssemblerLabel jnz()
1627 {
1628 return jne();
1629 }
1630
1631 AssemblerLabel je()
1632 {
1633 m_formatter.twoByteOp(jccRel32(ConditionE));
1634 return m_formatter.immediateRel32();
1635 }
1636
1637 AssemblerLabel jz()
1638 {
1639 return je();
1640 }
1641
1642 AssemblerLabel jl()
1643 {
1644 m_formatter.twoByteOp(jccRel32(ConditionL));
1645 return m_formatter.immediateRel32();
1646 }
1647
1648 AssemblerLabel jb()
1649 {
1650 m_formatter.twoByteOp(jccRel32(ConditionB));
1651 return m_formatter.immediateRel32();
1652 }
1653
1654 AssemblerLabel jle()
1655 {
1656 m_formatter.twoByteOp(jccRel32(ConditionLE));
1657 return m_formatter.immediateRel32();
1658 }
1659
1660 AssemblerLabel jbe()
1661 {
1662 m_formatter.twoByteOp(jccRel32(ConditionBE));
1663 return m_formatter.immediateRel32();
1664 }
1665
1666 AssemblerLabel jge()
1667 {
1668 m_formatter.twoByteOp(jccRel32(ConditionGE));
1669 return m_formatter.immediateRel32();
1670 }
1671
1672 AssemblerLabel jg()
1673 {
1674 m_formatter.twoByteOp(jccRel32(ConditionG));
1675 return m_formatter.immediateRel32();
1676 }
1677
1678 AssemblerLabel ja()
1679 {
1680 m_formatter.twoByteOp(jccRel32(ConditionA));
1681 return m_formatter.immediateRel32();
1682 }
1683
1684 AssemblerLabel jae()
1685 {
1686 m_formatter.twoByteOp(jccRel32(ConditionAE));
1687 return m_formatter.immediateRel32();
1688 }
1689
1690 AssemblerLabel jo()
1691 {
1692 m_formatter.twoByteOp(jccRel32(ConditionO));
1693 return m_formatter.immediateRel32();
1694 }
1695
1696 AssemblerLabel jnp()
1697 {
1698 m_formatter.twoByteOp(jccRel32(ConditionNP));
1699 return m_formatter.immediateRel32();
1700 }
1701
1702 AssemblerLabel jp()
1703 {
1704 m_formatter.twoByteOp(jccRel32(ConditionP));
1705 return m_formatter.immediateRel32();
1706 }
1707
1708 AssemblerLabel js()
1709 {
1710 m_formatter.twoByteOp(jccRel32(ConditionS));
1711 return m_formatter.immediateRel32();
1712 }
1713
1714 AssemblerLabel jCC(Condition cond)
1715 {
1716 m_formatter.twoByteOp(jccRel32(cond));
1717 return m_formatter.immediateRel32();
1718 }
1719
1720 // SSE operations:
1721
1722 void addsd_rr(XMMRegisterID src, XMMRegisterID dst)
1723 {
1724 m_formatter.prefix(PRE_SSE_F2);
1725 m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
1726 }
1727
1728 void addsd_mr(int offset, RegisterID base, XMMRegisterID dst)
1729 {
1730 m_formatter.prefix(PRE_SSE_F2);
1731 m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, base, offset);
1732 }
1733
1734 #if !CPU(X86_64)
1735 void addsd_mr(const void* address, XMMRegisterID dst)
1736 {
1737 m_formatter.prefix(PRE_SSE_F2);
1738 m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, address);
1739 }
1740 #endif
1741
1742 void cvtsi2sd_rr(RegisterID src, XMMRegisterID dst)
1743 {
1744 m_formatter.prefix(PRE_SSE_F2);
1745 m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, src);
1746 }
1747
1748 #if CPU(X86_64)
1749 void cvtsi2sdq_rr(RegisterID src, XMMRegisterID dst)
1750 {
1751 m_formatter.prefix(PRE_SSE_F2);
1752 m_formatter.twoByteOp64(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, src);
1753 }
1754 #endif
1755
1756 void cvtsi2sd_mr(int offset, RegisterID base, XMMRegisterID dst)
1757 {
1758 m_formatter.prefix(PRE_SSE_F2);
1759 m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, base, offset);
1760 }
1761
1762 #if !CPU(X86_64)
1763 void cvtsi2sd_mr(const void* address, XMMRegisterID dst)
1764 {
1765 m_formatter.prefix(PRE_SSE_F2);
1766 m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, address);
1767 }
1768 #endif
1769
1770 void cvttsd2si_rr(XMMRegisterID src, RegisterID dst)
1771 {
1772 m_formatter.prefix(PRE_SSE_F2);
1773 m_formatter.twoByteOp(OP2_CVTTSD2SI_GdWsd, dst, (RegisterID)src);
1774 }
1775
1776 void cvtsd2ss_rr(XMMRegisterID src, XMMRegisterID dst)
1777 {
1778 m_formatter.prefix(PRE_SSE_F2);
1779 m_formatter.twoByteOp(OP2_CVTSD2SS_VsdWsd, dst, (RegisterID)src);
1780 }
1781
1782 void cvtss2sd_rr(XMMRegisterID src, XMMRegisterID dst)
1783 {
1784 m_formatter.prefix(PRE_SSE_F3);
1785 m_formatter.twoByteOp(OP2_CVTSS2SD_VsdWsd, dst, (RegisterID)src);
1786 }
1787
1788 #if CPU(X86_64)
1789 void cvttsd2siq_rr(XMMRegisterID src, RegisterID dst)
1790 {
1791 m_formatter.prefix(PRE_SSE_F2);
1792 m_formatter.twoByteOp64(OP2_CVTTSD2SI_GdWsd, dst, (RegisterID)src);
1793 }
1794 #endif
1795
1796 void movd_rr(XMMRegisterID src, RegisterID dst)
1797 {
1798 m_formatter.prefix(PRE_SSE_66);
1799 m_formatter.twoByteOp(OP2_MOVD_EdVd, (RegisterID)src, dst);
1800 }
1801
1802 void movd_rr(RegisterID src, XMMRegisterID dst)
1803 {
1804 m_formatter.prefix(PRE_SSE_66);
1805 m_formatter.twoByteOp(OP2_MOVD_VdEd, (RegisterID)dst, src);
1806 }
1807
1808 #if CPU(X86_64)
1809 void movmskpd_rr(XMMRegisterID src, RegisterID dst)
1810 {
1811 m_formatter.prefix(PRE_SSE_66);
1812 m_formatter.twoByteOp64(OP2_MOVMSKPD_VdEd, dst, (RegisterID)src);
1813 }
1814
1815 void movq_rr(XMMRegisterID src, RegisterID dst)
1816 {
1817 m_formatter.prefix(PRE_SSE_66);
1818 m_formatter.twoByteOp64(OP2_MOVD_EdVd, (RegisterID)src, dst);
1819 }
1820
1821 void movq_rr(RegisterID src, XMMRegisterID dst)
1822 {
1823 m_formatter.prefix(PRE_SSE_66);
1824 m_formatter.twoByteOp64(OP2_MOVD_VdEd, (RegisterID)dst, src);
1825 }
1826 #endif
1827
1828 void movsd_rr(XMMRegisterID src, XMMRegisterID dst)
1829 {
1830 m_formatter.prefix(PRE_SSE_F2);
1831 m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
1832 }
1833
1834 void movsd_rm(XMMRegisterID src, int offset, RegisterID base)
1835 {
1836 m_formatter.prefix(PRE_SSE_F2);
1837 m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, offset);
1838 }
1839
1840 void movsd_rm(XMMRegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1841 {
1842 m_formatter.prefix(PRE_SSE_F2);
1843 m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, index, scale, offset);
1844 }
1845
1846 void movss_rm(XMMRegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1847 {
1848 m_formatter.prefix(PRE_SSE_F3);
1849 m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, index, scale, offset);
1850 }
1851
1852 void movsd_mr(int offset, RegisterID base, XMMRegisterID dst)
1853 {
1854 m_formatter.prefix(PRE_SSE_F2);
1855 m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, base, offset);
1856 }
1857
1858 void movsd_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
1859 {
1860 m_formatter.prefix(PRE_SSE_F2);
1861 m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, dst, base, index, scale, offset);
1862 }
1863
1864 void movss_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
1865 {
1866 m_formatter.prefix(PRE_SSE_F3);
1867 m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, dst, base, index, scale, offset);
1868 }
1869
1870 #if !CPU(X86_64)
1871 void movsd_mr(const void* address, XMMRegisterID dst)
1872 {
1873 m_formatter.prefix(PRE_SSE_F2);
1874 m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, address);
1875 }
1876 void movsd_rm(XMMRegisterID src, const void* address)
1877 {
1878 m_formatter.prefix(PRE_SSE_F2);
1879 m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, address);
1880 }
1881 #endif
1882
1883 void mulsd_rr(XMMRegisterID src, XMMRegisterID dst)
1884 {
1885 m_formatter.prefix(PRE_SSE_F2);
1886 m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
1887 }
1888
1889 void mulsd_mr(int offset, RegisterID base, XMMRegisterID dst)
1890 {
1891 m_formatter.prefix(PRE_SSE_F2);
1892 m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)dst, base, offset);
1893 }
1894
1895 void pextrw_irr(int whichWord, XMMRegisterID src, RegisterID dst)
1896 {
1897 m_formatter.prefix(PRE_SSE_66);
1898 m_formatter.twoByteOp(OP2_PEXTRW_GdUdIb, (RegisterID)dst, (RegisterID)src);
1899 m_formatter.immediate8(whichWord);
1900 }
1901
1902 void psllq_i8r(int imm, XMMRegisterID dst)
1903 {
1904 m_formatter.prefix(PRE_SSE_66);
1905 m_formatter.twoByteOp8(OP2_PSLLQ_UdqIb, GROUP14_OP_PSLLQ, (RegisterID)dst);
1906 m_formatter.immediate8(imm);
1907 }
1908
1909 void psrlq_i8r(int imm, XMMRegisterID dst)
1910 {
1911 m_formatter.prefix(PRE_SSE_66);
1912 m_formatter.twoByteOp8(OP2_PSRLQ_UdqIb, GROUP14_OP_PSRLQ, (RegisterID)dst);
1913 m_formatter.immediate8(imm);
1914 }
1915
1916 void por_rr(XMMRegisterID src, XMMRegisterID dst)
1917 {
1918 m_formatter.prefix(PRE_SSE_66);
1919 m_formatter.twoByteOp(OP2_POR_VdqWdq, (RegisterID)dst, (RegisterID)src);
1920 }
1921
1922 void subsd_rr(XMMRegisterID src, XMMRegisterID dst)
1923 {
1924 m_formatter.prefix(PRE_SSE_F2);
1925 m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
1926 }
1927
1928 void subsd_mr(int offset, RegisterID base, XMMRegisterID dst)
1929 {
1930 m_formatter.prefix(PRE_SSE_F2);
1931 m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, base, offset);
1932 }
1933
1934 void ucomisd_rr(XMMRegisterID src, XMMRegisterID dst)
1935 {
1936 m_formatter.prefix(PRE_SSE_66);
1937 m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)dst, (RegisterID)src);
1938 }
1939
1940 void ucomisd_mr(int offset, RegisterID base, XMMRegisterID dst)
1941 {
1942 m_formatter.prefix(PRE_SSE_66);
1943 m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)dst, base, offset);
1944 }
1945
1946 void divsd_rr(XMMRegisterID src, XMMRegisterID dst)
1947 {
1948 m_formatter.prefix(PRE_SSE_F2);
1949 m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
1950 }
1951
1952 void divsd_mr(int offset, RegisterID base, XMMRegisterID dst)
1953 {
1954 m_formatter.prefix(PRE_SSE_F2);
1955 m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)dst, base, offset);
1956 }
1957
1958 void xorpd_rr(XMMRegisterID src, XMMRegisterID dst)
1959 {
1960 m_formatter.prefix(PRE_SSE_66);
1961 m_formatter.twoByteOp(OP2_XORPD_VpdWpd, (RegisterID)dst, (RegisterID)src);
1962 }
1963
1964 void andnpd_rr(XMMRegisterID src, XMMRegisterID dst)
1965 {
1966 m_formatter.prefix(PRE_SSE_66);
1967 m_formatter.twoByteOp(OP2_ANDNPD_VpdWpd, (RegisterID)dst, (RegisterID)src);
1968 }
1969
1970 void sqrtsd_rr(XMMRegisterID src, XMMRegisterID dst)
1971 {
1972 m_formatter.prefix(PRE_SSE_F2);
1973 m_formatter.twoByteOp(OP2_SQRTSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
1974 }
1975
1976 // Misc instructions:
1977
1978 void int3()
1979 {
1980 m_formatter.oneByteOp(OP_INT3);
1981 }
1982
1983 void ret()
1984 {
1985 m_formatter.oneByteOp(OP_RET);
1986 }
1987
1988 void predictNotTaken()
1989 {
1990 m_formatter.prefix(PRE_PREDICT_BRANCH_NOT_TAKEN);
1991 }
1992
1993 void mfence()
1994 {
1995 m_formatter.threeByteOp(OP3_MFENCE);
1996 }
1997
1998 // Assembler admin methods:
1999
2000 size_t codeSize() const
2001 {
2002 return m_formatter.codeSize();
2003 }
2004
2005 AssemblerLabel labelForWatchpoint()
2006 {
2007 AssemblerLabel result = m_formatter.label();
2008 if (static_cast<int>(result.m_offset) != m_indexOfLastWatchpoint)
2009 result = label();
2010 m_indexOfLastWatchpoint = result.m_offset;
2011 m_indexOfTailOfLastWatchpoint = result.m_offset + maxJumpReplacementSize();
2012 return result;
2013 }
2014
2015 AssemblerLabel labelIgnoringWatchpoints()
2016 {
2017 return m_formatter.label();
2018 }
2019
2020 AssemblerLabel label()
2021 {
2022 AssemblerLabel result = m_formatter.label();
2023 while (UNLIKELY(static_cast<int>(result.m_offset) < m_indexOfTailOfLastWatchpoint)) {
2024 nop();
2025 result = m_formatter.label();
2026 }
2027 return result;
2028 }
2029
2030 AssemblerLabel align(int alignment)
2031 {
2032 while (!m_formatter.isAligned(alignment))
2033 m_formatter.oneByteOp(OP_HLT);
2034
2035 return label();
2036 }
2037
2038 // Linking & patching:
2039 //
2040 // 'link' and 'patch' methods are for use on unprotected code - such as the code
2041 // within the AssemblerBuffer, and code being patched by the patch buffer. Once
2042 // code has been finalized it is (platform support permitting) within a non-
2043 // writable region of memory; to modify the code in an execute-only execuable
2044 // pool the 'repatch' and 'relink' methods should be used.
2045
2046 void linkJump(AssemblerLabel from, AssemblerLabel to)
2047 {
2048 ASSERT(from.isSet());
2049 ASSERT(to.isSet());
2050
2051 char* code = reinterpret_cast<char*>(m_formatter.data());
2052 ASSERT(!reinterpret_cast<int32_t*>(code + from.m_offset)[-1]);
2053 setRel32(code + from.m_offset, code + to.m_offset);
2054 }
2055
2056 static void linkJump(void* code, AssemblerLabel from, void* to)
2057 {
2058 ASSERT(from.isSet());
2059
2060 setRel32(reinterpret_cast<char*>(code) + from.m_offset, to);
2061 }
2062
2063 static void linkCall(void* code, AssemblerLabel from, void* to)
2064 {
2065 ASSERT(from.isSet());
2066
2067 setRel32(reinterpret_cast<char*>(code) + from.m_offset, to);
2068 }
2069
2070 static void linkPointer(void* code, AssemblerLabel where, void* value)
2071 {
2072 ASSERT(where.isSet());
2073
2074 setPointer(reinterpret_cast<char*>(code) + where.m_offset, value);
2075 }
2076
2077 static void relinkJump(void* from, void* to)
2078 {
2079 setRel32(from, to);
2080 }
2081
2082 static void relinkCall(void* from, void* to)
2083 {
2084 setRel32(from, to);
2085 }
2086
2087 static void repatchCompact(void* where, int32_t value)
2088 {
2089 ASSERT(value >= std::numeric_limits<int8_t>::min());
2090 ASSERT(value <= std::numeric_limits<int8_t>::max());
2091 setInt8(where, value);
2092 }
2093
2094 static void repatchInt32(void* where, int32_t value)
2095 {
2096 setInt32(where, value);
2097 }
2098
2099 static void repatchPointer(void* where, void* value)
2100 {
2101 setPointer(where, value);
2102 }
2103
2104 static void* readPointer(void* where)
2105 {
2106 return reinterpret_cast<void**>(where)[-1];
2107 }
2108
2109 static void replaceWithJump(void* instructionStart, void* to)
2110 {
2111 uint8_t* ptr = reinterpret_cast<uint8_t*>(instructionStart);
2112 uint8_t* dstPtr = reinterpret_cast<uint8_t*>(to);
2113 intptr_t distance = (intptr_t)(dstPtr - (ptr + 5));
2114 ptr[0] = static_cast<uint8_t>(OP_JMP_rel32);
2115 *reinterpret_cast<int32_t*>(ptr + 1) = static_cast<int32_t>(distance);
2116 }
2117
2118 static ptrdiff_t maxJumpReplacementSize()
2119 {
2120 return 5;
2121 }
2122
2123 #if CPU(X86_64)
2124 static void revertJumpTo_movq_i64r(void* instructionStart, int64_t imm, RegisterID dst)
2125 {
2126 const unsigned instructionSize = 10; // REX.W MOV IMM64
2127 const int rexBytes = 1;
2128 const int opcodeBytes = 1;
2129 uint8_t* ptr = reinterpret_cast<uint8_t*>(instructionStart);
2130 ptr[0] = PRE_REX | (1 << 3) | (dst >> 3);
2131 ptr[1] = OP_MOV_EAXIv | (dst & 7);
2132
2133 union {
2134 uint64_t asWord;
2135 uint8_t asBytes[8];
2136 } u;
2137 u.asWord = imm;
2138 for (unsigned i = rexBytes + opcodeBytes; i < instructionSize; ++i)
2139 ptr[i] = u.asBytes[i - rexBytes - opcodeBytes];
2140 }
2141
2142 static void revertJumpTo_movl_i32r(void* instructionStart, int32_t imm, RegisterID dst)
2143 {
2144 // We only revert jumps on inline caches, and inline caches always use the scratch register (r11).
2145 // FIXME: If the above is ever false then we need to make this smarter with respect to emitting
2146 // the REX byte.
2147 ASSERT(dst == X86Registers::r11);
2148 const unsigned instructionSize = 6; // REX MOV IMM32
2149 const int rexBytes = 1;
2150 const int opcodeBytes = 1;
2151 uint8_t* ptr = reinterpret_cast<uint8_t*>(instructionStart);
2152 ptr[0] = PRE_REX | (dst >> 3);
2153 ptr[1] = OP_MOV_EAXIv | (dst & 7);
2154
2155 union {
2156 uint32_t asWord;
2157 uint8_t asBytes[4];
2158 } u;
2159 u.asWord = imm;
2160 for (unsigned i = rexBytes + opcodeBytes; i < instructionSize; ++i)
2161 ptr[i] = u.asBytes[i - rexBytes - opcodeBytes];
2162 }
2163 #endif
2164
2165 static void revertJumpTo_cmpl_ir_force32(void* instructionStart, int32_t imm, RegisterID dst)
2166 {
2167 const int opcodeBytes = 1;
2168 const int modRMBytes = 1;
2169 ASSERT(opcodeBytes + modRMBytes <= maxJumpReplacementSize());
2170 uint8_t* ptr = reinterpret_cast<uint8_t*>(instructionStart);
2171 ptr[0] = OP_GROUP1_EvIz;
2172 ptr[1] = (X86InstructionFormatter::ModRmRegister << 6) | (GROUP1_OP_CMP << 3) | dst;
2173 union {
2174 uint32_t asWord;
2175 uint8_t asBytes[4];
2176 } u;
2177 u.asWord = imm;
2178 for (unsigned i = opcodeBytes + modRMBytes; i < static_cast<unsigned>(maxJumpReplacementSize()); ++i)
2179 ptr[i] = u.asBytes[i - opcodeBytes - modRMBytes];
2180 }
2181
2182 static void revertJumpTo_cmpl_im_force32(void* instructionStart, int32_t imm, int offset, RegisterID dst)
2183 {
2184 ASSERT_UNUSED(offset, !offset);
2185 const int opcodeBytes = 1;
2186 const int modRMBytes = 1;
2187 ASSERT(opcodeBytes + modRMBytes <= maxJumpReplacementSize());
2188 uint8_t* ptr = reinterpret_cast<uint8_t*>(instructionStart);
2189 ptr[0] = OP_GROUP1_EvIz;
2190 ptr[1] = (X86InstructionFormatter::ModRmMemoryNoDisp << 6) | (GROUP1_OP_CMP << 3) | dst;
2191 union {
2192 uint32_t asWord;
2193 uint8_t asBytes[4];
2194 } u;
2195 u.asWord = imm;
2196 for (unsigned i = opcodeBytes + modRMBytes; i < static_cast<unsigned>(maxJumpReplacementSize()); ++i)
2197 ptr[i] = u.asBytes[i - opcodeBytes - modRMBytes];
2198 }
2199
2200 static void replaceWithLoad(void* instructionStart)
2201 {
2202 uint8_t* ptr = reinterpret_cast<uint8_t*>(instructionStart);
2203 #if CPU(X86_64)
2204 if ((*ptr & ~15) == PRE_REX)
2205 ptr++;
2206 #endif
2207 switch (*ptr) {
2208 case OP_MOV_GvEv:
2209 break;
2210 case OP_LEA:
2211 *ptr = OP_MOV_GvEv;
2212 break;
2213 default:
2214 RELEASE_ASSERT_NOT_REACHED();
2215 }
2216 }
2217
2218 static void replaceWithAddressComputation(void* instructionStart)
2219 {
2220 uint8_t* ptr = reinterpret_cast<uint8_t*>(instructionStart);
2221 #if CPU(X86_64)
2222 if ((*ptr & ~15) == PRE_REX)
2223 ptr++;
2224 #endif
2225 switch (*ptr) {
2226 case OP_MOV_GvEv:
2227 *ptr = OP_LEA;
2228 break;
2229 case OP_LEA:
2230 break;
2231 default:
2232 RELEASE_ASSERT_NOT_REACHED();
2233 }
2234 }
2235
2236 static unsigned getCallReturnOffset(AssemblerLabel call)
2237 {
2238 ASSERT(call.isSet());
2239 return call.m_offset;
2240 }
2241
2242 static void* getRelocatedAddress(void* code, AssemblerLabel label)
2243 {
2244 ASSERT(label.isSet());
2245 return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + label.m_offset);
2246 }
2247
2248 static int getDifferenceBetweenLabels(AssemblerLabel a, AssemblerLabel b)
2249 {
2250 return b.m_offset - a.m_offset;
2251 }
2252
2253 unsigned debugOffset() { return m_formatter.debugOffset(); }
2254
2255 void nop()
2256 {
2257 m_formatter.oneByteOp(OP_NOP);
2258 }
2259
2260 static void fillNops(void* base, size_t size)
2261 {
2262 #if CPU(X86_64)
2263 static const uint8_t nops[10][10] = {
2264 // nop
2265 {0x90},
2266 // xchg %ax,%ax
2267 {0x66, 0x90},
2268 // nopl (%[re]ax)
2269 {0x0f, 0x1f, 0x00},
2270 // nopl 8(%[re]ax)
2271 {0x0f, 0x1f, 0x40, 0x08},
2272 // nopl 8(%[re]ax,%[re]ax,1)
2273 {0x0f, 0x1f, 0x44, 0x00, 0x08},
2274 // nopw 8(%[re]ax,%[re]ax,1)
2275 {0x66, 0x0f, 0x1f, 0x44, 0x00, 0x08},
2276 // nopl 512(%[re]ax)
2277 {0x0f, 0x1f, 0x80, 0x00, 0x02, 0x00, 0x00},
2278 // nopl 512(%[re]ax,%[re]ax,1)
2279 {0x0f, 0x1f, 0x84, 0x00, 0x00, 0x02, 0x00, 0x00},
2280 // nopw 512(%[re]ax,%[re]ax,1)
2281 {0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x02, 0x00, 0x00},
2282 // nopw %cs:512(%[re]ax,%[re]ax,1)
2283 {0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x02, 0x00, 0x00}
2284 };
2285
2286 uint8_t* where = reinterpret_cast<uint8_t*>(base);
2287 while (size) {
2288 unsigned nopSize = static_cast<unsigned>(std::min<size_t>(size, 15));
2289 unsigned numPrefixes = nopSize <= 10 ? 0 : nopSize - 10;
2290 for (unsigned i = 0; i != numPrefixes; ++i)
2291 *where++ = 0x66;
2292
2293 unsigned nopRest = nopSize - numPrefixes;
2294 for (unsigned i = 0; i != nopRest; ++i)
2295 *where++ = nops[nopRest-1][i];
2296
2297 size -= nopSize;
2298 }
2299 #else
2300 memset(base, OP_NOP, size);
2301 #endif
2302 }
2303
2304 // This is a no-op on x86
2305 ALWAYS_INLINE static void cacheFlush(void*, size_t) { }
2306
2307 private:
2308
2309 static void setPointer(void* where, void* value)
2310 {
2311 reinterpret_cast<void**>(where)[-1] = value;
2312 }
2313
2314 static void setInt32(void* where, int32_t value)
2315 {
2316 reinterpret_cast<int32_t*>(where)[-1] = value;
2317 }
2318
2319 static void setInt8(void* where, int8_t value)
2320 {
2321 reinterpret_cast<int8_t*>(where)[-1] = value;
2322 }
2323
2324 static void setRel32(void* from, void* to)
2325 {
2326 intptr_t offset = reinterpret_cast<intptr_t>(to) - reinterpret_cast<intptr_t>(from);
2327 ASSERT(offset == static_cast<int32_t>(offset));
2328
2329 setInt32(from, offset);
2330 }
2331
2332 class X86InstructionFormatter {
2333
2334 static const int maxInstructionSize = 16;
2335
2336 public:
2337
2338 enum ModRmMode {
2339 ModRmMemoryNoDisp,
2340 ModRmMemoryDisp8,
2341 ModRmMemoryDisp32,
2342 ModRmRegister,
2343 };
2344
2345 // Legacy prefix bytes:
2346 //
2347 // These are emmitted prior to the instruction.
2348
2349 void prefix(OneByteOpcodeID pre)
2350 {
2351 m_buffer.putByte(pre);
2352 }
2353
2354 // Word-sized operands / no operand instruction formatters.
2355 //
2356 // In addition to the opcode, the following operand permutations are supported:
2357 // * None - instruction takes no operands.
2358 // * One register - the low three bits of the RegisterID are added into the opcode.
2359 // * 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).
2360 // * Three argument ModRM - a register, and a register and an offset describing a memory operand.
2361 // * Five argument ModRM - a register, and a base register, an index, scale, and offset describing a memory operand.
2362 //
2363 // For 32-bit x86 targets, the address operand may also be provided as a void*.
2364 // On 64-bit targets REX prefixes will be planted as necessary, where high numbered registers are used.
2365 //
2366 // The twoByteOp methods plant two-byte Intel instructions sequences (first opcode byte 0x0F).
2367
2368 void oneByteOp(OneByteOpcodeID opcode)
2369 {
2370 m_buffer.ensureSpace(maxInstructionSize);
2371 m_buffer.putByteUnchecked(opcode);
2372 }
2373
2374 void oneByteOp(OneByteOpcodeID opcode, RegisterID reg)
2375 {
2376 m_buffer.ensureSpace(maxInstructionSize);
2377 emitRexIfNeeded(0, 0, reg);
2378 m_buffer.putByteUnchecked(opcode + (reg & 7));
2379 }
2380
2381 void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID rm)
2382 {
2383 m_buffer.ensureSpace(maxInstructionSize);
2384 emitRexIfNeeded(reg, 0, rm);
2385 m_buffer.putByteUnchecked(opcode);
2386 registerModRM(reg, rm);
2387 }
2388
2389 void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
2390 {
2391 m_buffer.ensureSpace(maxInstructionSize);
2392 emitRexIfNeeded(reg, 0, base);
2393 m_buffer.putByteUnchecked(opcode);
2394 memoryModRM(reg, base, offset);
2395 }
2396
2397 void oneByteOp_disp32(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
2398 {
2399 m_buffer.ensureSpace(maxInstructionSize);
2400 emitRexIfNeeded(reg, 0, base);
2401 m_buffer.putByteUnchecked(opcode);
2402 memoryModRM_disp32(reg, base, offset);
2403 }
2404
2405 void oneByteOp_disp8(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
2406 {
2407 m_buffer.ensureSpace(maxInstructionSize);
2408 emitRexIfNeeded(reg, 0, base);
2409 m_buffer.putByteUnchecked(opcode);
2410 memoryModRM_disp8(reg, base, offset);
2411 }
2412
2413 void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
2414 {
2415 m_buffer.ensureSpace(maxInstructionSize);
2416 emitRexIfNeeded(reg, index, base);
2417 m_buffer.putByteUnchecked(opcode);
2418 memoryModRM(reg, base, index, scale, offset);
2419 }
2420
2421 #if !CPU(X86_64)
2422 void oneByteOp(OneByteOpcodeID opcode, int reg, const void* address)
2423 {
2424 m_buffer.ensureSpace(maxInstructionSize);
2425 m_buffer.putByteUnchecked(opcode);
2426 memoryModRM(reg, address);
2427 }
2428 #endif
2429
2430 void twoByteOp(TwoByteOpcodeID opcode)
2431 {
2432 m_buffer.ensureSpace(maxInstructionSize);
2433 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
2434 m_buffer.putByteUnchecked(opcode);
2435 }
2436
2437 void twoByteOp(TwoByteOpcodeID opcode, int reg, RegisterID rm)
2438 {
2439 m_buffer.ensureSpace(maxInstructionSize);
2440 emitRexIfNeeded(reg, 0, rm);
2441 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
2442 m_buffer.putByteUnchecked(opcode);
2443 registerModRM(reg, rm);
2444 }
2445
2446 void twoByteOp(TwoByteOpcodeID opcode, int reg, RegisterID base, int offset)
2447 {
2448 m_buffer.ensureSpace(maxInstructionSize);
2449 emitRexIfNeeded(reg, 0, base);
2450 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
2451 m_buffer.putByteUnchecked(opcode);
2452 memoryModRM(reg, base, offset);
2453 }
2454
2455 void twoByteOp(TwoByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
2456 {
2457 m_buffer.ensureSpace(maxInstructionSize);
2458 emitRexIfNeeded(reg, index, base);
2459 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
2460 m_buffer.putByteUnchecked(opcode);
2461 memoryModRM(reg, base, index, scale, offset);
2462 }
2463
2464 #if !CPU(X86_64)
2465 void twoByteOp(TwoByteOpcodeID opcode, int reg, const void* address)
2466 {
2467 m_buffer.ensureSpace(maxInstructionSize);
2468 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
2469 m_buffer.putByteUnchecked(opcode);
2470 memoryModRM(reg, address);
2471 }
2472 #endif
2473
2474 void threeByteOp(ThreeByteOpcodeID opcode)
2475 {
2476 m_buffer.ensureSpace(maxInstructionSize);
2477 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
2478 m_buffer.putByteUnchecked(OP2_3BYTE_ESCAPE);
2479 m_buffer.putByteUnchecked(opcode);
2480 }
2481
2482 #if CPU(X86_64)
2483 // Quad-word-sized operands:
2484 //
2485 // Used to format 64-bit operantions, planting a REX.w prefix.
2486 // When planting d64 or f64 instructions, not requiring a REX.w prefix,
2487 // the normal (non-'64'-postfixed) formatters should be used.
2488
2489 void oneByteOp64(OneByteOpcodeID opcode)
2490 {
2491 m_buffer.ensureSpace(maxInstructionSize);
2492 emitRexW(0, 0, 0);
2493 m_buffer.putByteUnchecked(opcode);
2494 }
2495
2496 void oneByteOp64(OneByteOpcodeID opcode, RegisterID reg)
2497 {
2498 m_buffer.ensureSpace(maxInstructionSize);
2499 emitRexW(0, 0, reg);
2500 m_buffer.putByteUnchecked(opcode + (reg & 7));
2501 }
2502
2503 void oneByteOp64(OneByteOpcodeID opcode, int reg, RegisterID rm)
2504 {
2505 m_buffer.ensureSpace(maxInstructionSize);
2506 emitRexW(reg, 0, rm);
2507 m_buffer.putByteUnchecked(opcode);
2508 registerModRM(reg, rm);
2509 }
2510
2511 void oneByteOp64(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
2512 {
2513 m_buffer.ensureSpace(maxInstructionSize);
2514 emitRexW(reg, 0, base);
2515 m_buffer.putByteUnchecked(opcode);
2516 memoryModRM(reg, base, offset);
2517 }
2518
2519 void oneByteOp64_disp32(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
2520 {
2521 m_buffer.ensureSpace(maxInstructionSize);
2522 emitRexW(reg, 0, base);
2523 m_buffer.putByteUnchecked(opcode);
2524 memoryModRM_disp32(reg, base, offset);
2525 }
2526
2527 void oneByteOp64_disp8(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
2528 {
2529 m_buffer.ensureSpace(maxInstructionSize);
2530 emitRexW(reg, 0, base);
2531 m_buffer.putByteUnchecked(opcode);
2532 memoryModRM_disp8(reg, base, offset);
2533 }
2534
2535 void oneByteOp64(OneByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
2536 {
2537 m_buffer.ensureSpace(maxInstructionSize);
2538 emitRexW(reg, index, base);
2539 m_buffer.putByteUnchecked(opcode);
2540 memoryModRM(reg, base, index, scale, offset);
2541 }
2542
2543 void twoByteOp64(TwoByteOpcodeID opcode, int reg, RegisterID rm)
2544 {
2545 m_buffer.ensureSpace(maxInstructionSize);
2546 emitRexW(reg, 0, rm);
2547 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
2548 m_buffer.putByteUnchecked(opcode);
2549 registerModRM(reg, rm);
2550 }
2551 #endif
2552
2553 // Byte-operands:
2554 //
2555 // These methods format byte operations. Byte operations differ from the normal
2556 // formatters in the circumstances under which they will decide to emit REX prefixes.
2557 // These should be used where any register operand signifies a byte register.
2558 //
2559 // The disctinction is due to the handling of register numbers in the range 4..7 on
2560 // x86-64. These register numbers may either represent the second byte of the first
2561 // four registers (ah..bh) or the first byte of the second four registers (spl..dil).
2562 //
2563 // Since ah..bh cannot be used in all permutations of operands (specifically cannot
2564 // be accessed where a REX prefix is present), these are likely best treated as
2565 // deprecated. In order to ensure the correct registers spl..dil are selected a
2566 // REX prefix will be emitted for any byte register operand in the range 4..15.
2567 //
2568 // These formatters may be used in instructions where a mix of operand sizes, in which
2569 // case an unnecessary REX will be emitted, for example:
2570 // movzbl %al, %edi
2571 // In this case a REX will be planted since edi is 7 (and were this a byte operand
2572 // a REX would be required to specify dil instead of bh). Unneeded REX prefixes will
2573 // be silently ignored by the processor.
2574 //
2575 // Address operands should still be checked using regRequiresRex(), while byteRegRequiresRex()
2576 // is provided to check byte register operands.
2577
2578 void oneByteOp8(OneByteOpcodeID opcode, GroupOpcodeID groupOp, RegisterID rm)
2579 {
2580 m_buffer.ensureSpace(maxInstructionSize);
2581 emitRexIf(byteRegRequiresRex(rm), 0, 0, rm);
2582 m_buffer.putByteUnchecked(opcode);
2583 registerModRM(groupOp, rm);
2584 }
2585
2586 void oneByteOp8(OneByteOpcodeID opcode, int reg, RegisterID rm)
2587 {
2588 m_buffer.ensureSpace(maxInstructionSize);
2589 emitRexIf(byteRegRequiresRex(reg) || byteRegRequiresRex(rm), reg, 0, rm);
2590 m_buffer.putByteUnchecked(opcode);
2591 registerModRM(reg, rm);
2592 }
2593
2594 void oneByteOp8(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
2595 {
2596 m_buffer.ensureSpace(maxInstructionSize);
2597 emitRexIf(byteRegRequiresRex(reg) || byteRegRequiresRex(base), reg, 0, base);
2598 m_buffer.putByteUnchecked(opcode);
2599 memoryModRM(reg, base, offset);
2600 }
2601
2602 void oneByteOp8(OneByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
2603 {
2604 m_buffer.ensureSpace(maxInstructionSize);
2605 emitRexIf(byteRegRequiresRex(reg) || regRequiresRex(index) || regRequiresRex(base), reg, index, base);
2606 m_buffer.putByteUnchecked(opcode);
2607 memoryModRM(reg, base, index, scale, offset);
2608 }
2609
2610 void twoByteOp8(TwoByteOpcodeID opcode, RegisterID reg, RegisterID rm)
2611 {
2612 m_buffer.ensureSpace(maxInstructionSize);
2613 emitRexIf(byteRegRequiresRex(reg)|byteRegRequiresRex(rm), reg, 0, rm);
2614 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
2615 m_buffer.putByteUnchecked(opcode);
2616 registerModRM(reg, rm);
2617 }
2618
2619 void twoByteOp8(TwoByteOpcodeID opcode, GroupOpcodeID groupOp, RegisterID rm)
2620 {
2621 m_buffer.ensureSpace(maxInstructionSize);
2622 emitRexIf(byteRegRequiresRex(rm), 0, 0, rm);
2623 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
2624 m_buffer.putByteUnchecked(opcode);
2625 registerModRM(groupOp, rm);
2626 }
2627
2628 // Immediates:
2629 //
2630 // An immedaite should be appended where appropriate after an op has been emitted.
2631 // The writes are unchecked since the opcode formatters above will have ensured space.
2632
2633 void immediate8(int imm)
2634 {
2635 m_buffer.putByteUnchecked(imm);
2636 }
2637
2638 void immediate16(int imm)
2639 {
2640 m_buffer.putShortUnchecked(imm);
2641 }
2642
2643 void immediate32(int imm)
2644 {
2645 m_buffer.putIntUnchecked(imm);
2646 }
2647
2648 void immediate64(int64_t imm)
2649 {
2650 m_buffer.putInt64Unchecked(imm);
2651 }
2652
2653 AssemblerLabel immediateRel32()
2654 {
2655 m_buffer.putIntUnchecked(0);
2656 return label();
2657 }
2658
2659 // Administrative methods:
2660
2661 size_t codeSize() const { return m_buffer.codeSize(); }
2662 AssemblerLabel label() const { return m_buffer.label(); }
2663 bool isAligned(int alignment) const { return m_buffer.isAligned(alignment); }
2664 void* data() const { return m_buffer.data(); }
2665
2666 unsigned debugOffset() { return m_buffer.debugOffset(); }
2667
2668 private:
2669
2670 // Internals; ModRm and REX formatters.
2671
2672 static const RegisterID noBase = X86Registers::ebp;
2673 static const RegisterID hasSib = X86Registers::esp;
2674 static const RegisterID noIndex = X86Registers::esp;
2675 #if CPU(X86_64)
2676 static const RegisterID noBase2 = X86Registers::r13;
2677 static const RegisterID hasSib2 = X86Registers::r12;
2678
2679 // Registers r8 & above require a REX prefixe.
2680 inline bool regRequiresRex(int reg)
2681 {
2682 return (reg >= X86Registers::r8);
2683 }
2684
2685 // Byte operand register spl & above require a REX prefix (to prevent the 'H' registers be accessed).
2686 inline bool byteRegRequiresRex(int reg)
2687 {
2688 return (reg >= X86Registers::esp);
2689 }
2690
2691 // Format a REX prefix byte.
2692 inline void emitRex(bool w, int r, int x, int b)
2693 {
2694 ASSERT(r >= 0);
2695 ASSERT(x >= 0);
2696 ASSERT(b >= 0);
2697 m_buffer.putByteUnchecked(PRE_REX | ((int)w << 3) | ((r>>3)<<2) | ((x>>3)<<1) | (b>>3));
2698 }
2699
2700 // Used to plant a REX byte with REX.w set (for 64-bit operations).
2701 inline void emitRexW(int r, int x, int b)
2702 {
2703 emitRex(true, r, x, b);
2704 }
2705
2706 // Used for operations with byte operands - use byteRegRequiresRex() to check register operands,
2707 // regRequiresRex() to check other registers (i.e. address base & index).
2708 inline void emitRexIf(bool condition, int r, int x, int b)
2709 {
2710 if (condition) emitRex(false, r, x, b);
2711 }
2712
2713 // Used for word sized operations, will plant a REX prefix if necessary (if any register is r8 or above).
2714 inline void emitRexIfNeeded(int r, int x, int b)
2715 {
2716 emitRexIf(regRequiresRex(r) || regRequiresRex(x) || regRequiresRex(b), r, x, b);
2717 }
2718 #else
2719 // No REX prefix bytes on 32-bit x86.
2720 inline bool regRequiresRex(int) { return false; }
2721 inline bool byteRegRequiresRex(int) { return false; }
2722 inline void emitRexIf(bool, int, int, int) {}
2723 inline void emitRexIfNeeded(int, int, int) {}
2724 #endif
2725
2726 void putModRm(ModRmMode mode, int reg, RegisterID rm)
2727 {
2728 m_buffer.putByteUnchecked((mode << 6) | ((reg & 7) << 3) | (rm & 7));
2729 }
2730
2731 void putModRmSib(ModRmMode mode, int reg, RegisterID base, RegisterID index, int scale)
2732 {
2733 ASSERT(mode != ModRmRegister);
2734
2735 putModRm(mode, reg, hasSib);
2736 m_buffer.putByteUnchecked((scale << 6) | ((index & 7) << 3) | (base & 7));
2737 }
2738
2739 void registerModRM(int reg, RegisterID rm)
2740 {
2741 putModRm(ModRmRegister, reg, rm);
2742 }
2743
2744 void memoryModRM(int reg, RegisterID base, int offset)
2745 {
2746 // A base of esp or r12 would be interpreted as a sib, so force a sib with no index & put the base in there.
2747 #if CPU(X86_64)
2748 if ((base == hasSib) || (base == hasSib2)) {
2749 #else
2750 if (base == hasSib) {
2751 #endif
2752 if (!offset) // No need to check if the base is noBase, since we know it is hasSib!
2753 putModRmSib(ModRmMemoryNoDisp, reg, base, noIndex, 0);
2754 else if (CAN_SIGN_EXTEND_8_32(offset)) {
2755 putModRmSib(ModRmMemoryDisp8, reg, base, noIndex, 0);
2756 m_buffer.putByteUnchecked(offset);
2757 } else {
2758 putModRmSib(ModRmMemoryDisp32, reg, base, noIndex, 0);
2759 m_buffer.putIntUnchecked(offset);
2760 }
2761 } else {
2762 #if CPU(X86_64)
2763 if (!offset && (base != noBase) && (base != noBase2))
2764 #else
2765 if (!offset && (base != noBase))
2766 #endif
2767 putModRm(ModRmMemoryNoDisp, reg, base);
2768 else if (CAN_SIGN_EXTEND_8_32(offset)) {
2769 putModRm(ModRmMemoryDisp8, reg, base);
2770 m_buffer.putByteUnchecked(offset);
2771 } else {
2772 putModRm(ModRmMemoryDisp32, reg, base);
2773 m_buffer.putIntUnchecked(offset);
2774 }
2775 }
2776 }
2777
2778 void memoryModRM_disp8(int reg, RegisterID base, int offset)
2779 {
2780 // A base of esp or r12 would be interpreted as a sib, so force a sib with no index & put the base in there.
2781 ASSERT(CAN_SIGN_EXTEND_8_32(offset));
2782 #if CPU(X86_64)
2783 if ((base == hasSib) || (base == hasSib2)) {
2784 #else
2785 if (base == hasSib) {
2786 #endif
2787 putModRmSib(ModRmMemoryDisp8, reg, base, noIndex, 0);
2788 m_buffer.putByteUnchecked(offset);
2789 } else {
2790 putModRm(ModRmMemoryDisp8, reg, base);
2791 m_buffer.putByteUnchecked(offset);
2792 }
2793 }
2794
2795 void memoryModRM_disp32(int reg, RegisterID base, int offset)
2796 {
2797 // A base of esp or r12 would be interpreted as a sib, so force a sib with no index & put the base in there.
2798 #if CPU(X86_64)
2799 if ((base == hasSib) || (base == hasSib2)) {
2800 #else
2801 if (base == hasSib) {
2802 #endif
2803 putModRmSib(ModRmMemoryDisp32, reg, base, noIndex, 0);
2804 m_buffer.putIntUnchecked(offset);
2805 } else {
2806 putModRm(ModRmMemoryDisp32, reg, base);
2807 m_buffer.putIntUnchecked(offset);
2808 }
2809 }
2810
2811 void memoryModRM(int reg, RegisterID base, RegisterID index, int scale, int offset)
2812 {
2813 ASSERT(index != noIndex);
2814
2815 #if CPU(X86_64)
2816 if (!offset && (base != noBase) && (base != noBase2))
2817 #else
2818 if (!offset && (base != noBase))
2819 #endif
2820 putModRmSib(ModRmMemoryNoDisp, reg, base, index, scale);
2821 else if (CAN_SIGN_EXTEND_8_32(offset)) {
2822 putModRmSib(ModRmMemoryDisp8, reg, base, index, scale);
2823 m_buffer.putByteUnchecked(offset);
2824 } else {
2825 putModRmSib(ModRmMemoryDisp32, reg, base, index, scale);
2826 m_buffer.putIntUnchecked(offset);
2827 }
2828 }
2829
2830 #if !CPU(X86_64)
2831 void memoryModRM(int reg, const void* address)
2832 {
2833 // noBase + ModRmMemoryNoDisp means noBase + ModRmMemoryDisp32!
2834 putModRm(ModRmMemoryNoDisp, reg, noBase);
2835 m_buffer.putIntUnchecked(reinterpret_cast<int32_t>(address));
2836 }
2837 #endif
2838
2839 public:
2840 AssemblerBuffer m_buffer;
2841 } m_formatter;
2842 int m_indexOfLastWatchpoint;
2843 int m_indexOfTailOfLastWatchpoint;
2844 };
2845
2846 } // namespace JSC
2847
2848 #endif // ENABLE(ASSEMBLER) && CPU(X86)
2849
2850 #endif // X86Assembler_h