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