]> git.saurik.com Git - apple/javascriptcore.git/blame - assembler/X86Assembler.h
JavaScriptCore-621.1.tar.gz
[apple/javascriptcore.git] / assembler / X86Assembler.h
CommitLineData
9dae56ea
A
1/*
2 * Copyright (C) 2008 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
f9bf01c6 29#if ENABLE(ASSEMBLER) && (CPU(X86) || CPU(X86_64))
9dae56ea
A
30
31#include "AssemblerBuffer.h"
32#include <stdint.h>
33#include <wtf/Assertions.h>
34#include <wtf/Vector.h>
35
36namespace JSC {
37
38inline bool CAN_SIGN_EXTEND_8_32(int32_t value) { return value == (int32_t)(signed char)value; }
9dae56ea 39
f9bf01c6 40namespace X86Registers {
9dae56ea
A
41 typedef enum {
42 eax,
43 ecx,
44 edx,
45 ebx,
46 esp,
47 ebp,
48 esi,
49 edi,
50
f9bf01c6 51#if CPU(X86_64)
9dae56ea
A
52 r8,
53 r9,
54 r10,
55 r11,
56 r12,
57 r13,
58 r14,
59 r15,
60#endif
61 } RegisterID;
62
63 typedef enum {
64 xmm0,
65 xmm1,
66 xmm2,
67 xmm3,
68 xmm4,
69 xmm5,
70 xmm6,
71 xmm7,
72 } XMMRegisterID;
73}
74
75class X86Assembler {
76public:
f9bf01c6
A
77 typedef X86Registers::RegisterID RegisterID;
78 typedef X86Registers::XMMRegisterID XMMRegisterID;
ba379fdc 79 typedef XMMRegisterID FPRegisterID;
9dae56ea 80
ba379fdc
A
81 typedef enum {
82 ConditionO,
83 ConditionNO,
84 ConditionB,
85 ConditionAE,
86 ConditionE,
87 ConditionNE,
88 ConditionBE,
89 ConditionA,
90 ConditionS,
91 ConditionNS,
92 ConditionP,
93 ConditionNP,
94 ConditionL,
95 ConditionGE,
96 ConditionLE,
97 ConditionG,
98
99 ConditionC = ConditionB,
100 ConditionNC = ConditionAE,
101 } Condition;
102
103private:
9dae56ea
A
104 typedef enum {
105 OP_ADD_EvGv = 0x01,
106 OP_ADD_GvEv = 0x03,
107 OP_OR_EvGv = 0x09,
108 OP_OR_GvEv = 0x0B,
109 OP_2BYTE_ESCAPE = 0x0F,
110 OP_AND_EvGv = 0x21,
ba379fdc 111 OP_AND_GvEv = 0x23,
9dae56ea
A
112 OP_SUB_EvGv = 0x29,
113 OP_SUB_GvEv = 0x2B,
114 PRE_PREDICT_BRANCH_NOT_TAKEN = 0x2E,
115 OP_XOR_EvGv = 0x31,
ba379fdc 116 OP_XOR_GvEv = 0x33,
9dae56ea
A
117 OP_CMP_EvGv = 0x39,
118 OP_CMP_GvEv = 0x3B,
f9bf01c6 119#if CPU(X86_64)
9dae56ea
A
120 PRE_REX = 0x40,
121#endif
122 OP_PUSH_EAX = 0x50,
123 OP_POP_EAX = 0x58,
f9bf01c6 124#if CPU(X86_64)
9dae56ea
A
125 OP_MOVSXD_GvEv = 0x63,
126#endif
127 PRE_OPERAND_SIZE = 0x66,
128 PRE_SSE_66 = 0x66,
129 OP_PUSH_Iz = 0x68,
130 OP_IMUL_GvEvIz = 0x69,
4e4e5a6f 131 OP_GROUP1_EbIb = 0x80,
9dae56ea
A
132 OP_GROUP1_EvIz = 0x81,
133 OP_GROUP1_EvIb = 0x83,
134 OP_TEST_EvGv = 0x85,
135 OP_XCHG_EvGv = 0x87,
136 OP_MOV_EvGv = 0x89,
137 OP_MOV_GvEv = 0x8B,
138 OP_LEA = 0x8D,
139 OP_GROUP1A_Ev = 0x8F,
140 OP_CDQ = 0x99,
141 OP_MOV_EAXOv = 0xA1,
142 OP_MOV_OvEAX = 0xA3,
143 OP_MOV_EAXIv = 0xB8,
144 OP_GROUP2_EvIb = 0xC1,
145 OP_RET = 0xC3,
146 OP_GROUP11_EvIz = 0xC7,
147 OP_INT3 = 0xCC,
148 OP_GROUP2_Ev1 = 0xD1,
149 OP_GROUP2_EvCL = 0xD3,
150 OP_CALL_rel32 = 0xE8,
151 OP_JMP_rel32 = 0xE9,
152 PRE_SSE_F2 = 0xF2,
153 OP_HLT = 0xF4,
154 OP_GROUP3_EbIb = 0xF6,
155 OP_GROUP3_Ev = 0xF7,
156 OP_GROUP3_EvIz = 0xF7, // OP_GROUP3_Ev has an immediate, when instruction is a test.
157 OP_GROUP5_Ev = 0xFF,
158 } OneByteOpcodeID;
159
160 typedef enum {
161 OP2_MOVSD_VsdWsd = 0x10,
162 OP2_MOVSD_WsdVsd = 0x11,
163 OP2_CVTSI2SD_VsdEd = 0x2A,
164 OP2_CVTTSD2SI_GdWsd = 0x2C,
165 OP2_UCOMISD_VsdWsd = 0x2E,
166 OP2_ADDSD_VsdWsd = 0x58,
167 OP2_MULSD_VsdWsd = 0x59,
168 OP2_SUBSD_VsdWsd = 0x5C,
ba379fdc 169 OP2_DIVSD_VsdWsd = 0x5E,
4e4e5a6f 170 OP2_SQRTSD_VsdWsd = 0x51,
ba379fdc 171 OP2_XORPD_VpdWpd = 0x57,
9dae56ea
A
172 OP2_MOVD_VdEd = 0x6E,
173 OP2_MOVD_EdVd = 0x7E,
ba379fdc
A
174 OP2_JCC_rel32 = 0x80,
175 OP_SETCC = 0x90,
9dae56ea
A
176 OP2_IMUL_GvEv = 0xAF,
177 OP2_MOVZX_GvEb = 0xB6,
178 OP2_MOVZX_GvEw = 0xB7,
179 OP2_PEXTRW_GdUdIb = 0xC5,
180 } TwoByteOpcodeID;
181
ba379fdc
A
182 TwoByteOpcodeID jccRel32(Condition cond)
183 {
184 return (TwoByteOpcodeID)(OP2_JCC_rel32 + cond);
185 }
186
187 TwoByteOpcodeID setccOpcode(Condition cond)
188 {
189 return (TwoByteOpcodeID)(OP_SETCC + cond);
190 }
191
9dae56ea
A
192 typedef enum {
193 GROUP1_OP_ADD = 0,
194 GROUP1_OP_OR = 1,
ba379fdc 195 GROUP1_OP_ADC = 2,
9dae56ea
A
196 GROUP1_OP_AND = 4,
197 GROUP1_OP_SUB = 5,
198 GROUP1_OP_XOR = 6,
199 GROUP1_OP_CMP = 7,
200
201 GROUP1A_OP_POP = 0,
202
203 GROUP2_OP_SHL = 4,
4e4e5a6f 204 GROUP2_OP_SHR = 5,
9dae56ea
A
205 GROUP2_OP_SAR = 7,
206
207 GROUP3_OP_TEST = 0,
208 GROUP3_OP_NOT = 2,
ba379fdc 209 GROUP3_OP_NEG = 3,
9dae56ea
A
210 GROUP3_OP_IDIV = 7,
211
212 GROUP5_OP_CALLN = 2,
213 GROUP5_OP_JMPN = 4,
214 GROUP5_OP_PUSH = 6,
215
216 GROUP11_MOV = 0,
217 } GroupOpcodeID;
218
9dae56ea
A
219 class X86InstructionFormatter;
220public:
221
222 class JmpSrc {
223 friend class X86Assembler;
224 friend class X86InstructionFormatter;
225 public:
226 JmpSrc()
227 : m_offset(-1)
228 {
229 }
230
231 private:
232 JmpSrc(int offset)
233 : m_offset(offset)
234 {
235 }
236
237 int m_offset;
238 };
239
240 class JmpDst {
241 friend class X86Assembler;
242 friend class X86InstructionFormatter;
243 public:
244 JmpDst()
245 : m_offset(-1)
ba379fdc 246 , m_used(false)
9dae56ea
A
247 {
248 }
249
ba379fdc
A
250 bool isUsed() const { return m_used; }
251 void used() { m_used = true; }
9dae56ea
A
252 private:
253 JmpDst(int offset)
254 : m_offset(offset)
ba379fdc 255 , m_used(false)
9dae56ea 256 {
ba379fdc 257 ASSERT(m_offset == offset);
9dae56ea
A
258 }
259
ba379fdc
A
260 int m_offset : 31;
261 bool m_used : 1;
9dae56ea
A
262 };
263
264 X86Assembler()
265 {
266 }
267
268 size_t size() const { return m_formatter.size(); }
269
270 // Stack operations:
271
272 void push_r(RegisterID reg)
273 {
274 m_formatter.oneByteOp(OP_PUSH_EAX, reg);
275 }
276
277 void pop_r(RegisterID reg)
278 {
279 m_formatter.oneByteOp(OP_POP_EAX, reg);
280 }
281
282 void push_i32(int imm)
283 {
284 m_formatter.oneByteOp(OP_PUSH_Iz);
285 m_formatter.immediate32(imm);
286 }
287
288 void push_m(int offset, RegisterID base)
289 {
290 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_PUSH, base, offset);
291 }
292
293 void pop_m(int offset, RegisterID base)
294 {
295 m_formatter.oneByteOp(OP_GROUP1A_Ev, GROUP1A_OP_POP, base, offset);
296 }
297
298 // Arithmetic operations:
299
f9bf01c6 300#if !CPU(X86_64)
ba379fdc
A
301 void adcl_im(int imm, void* addr)
302 {
303 if (CAN_SIGN_EXTEND_8_32(imm)) {
304 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADC, addr);
305 m_formatter.immediate8(imm);
306 } else {
307 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADC, addr);
308 m_formatter.immediate32(imm);
309 }
310 }
311#endif
312
9dae56ea
A
313 void addl_rr(RegisterID src, RegisterID dst)
314 {
315 m_formatter.oneByteOp(OP_ADD_EvGv, src, dst);
316 }
317
318 void addl_mr(int offset, RegisterID base, RegisterID dst)
319 {
320 m_formatter.oneByteOp(OP_ADD_GvEv, dst, base, offset);
321 }
322
ba379fdc
A
323 void addl_rm(RegisterID src, int offset, RegisterID base)
324 {
325 m_formatter.oneByteOp(OP_ADD_EvGv, src, base, offset);
326 }
327
9dae56ea
A
328 void addl_ir(int imm, RegisterID dst)
329 {
330 if (CAN_SIGN_EXTEND_8_32(imm)) {
331 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, dst);
332 m_formatter.immediate8(imm);
333 } else {
334 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, dst);
335 m_formatter.immediate32(imm);
336 }
337 }
338
339 void addl_im(int imm, int offset, RegisterID base)
340 {
341 if (CAN_SIGN_EXTEND_8_32(imm)) {
342 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, base, offset);
343 m_formatter.immediate8(imm);
344 } else {
345 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, base, offset);
346 m_formatter.immediate32(imm);
347 }
348 }
349
f9bf01c6 350#if CPU(X86_64)
9dae56ea
A
351 void addq_rr(RegisterID src, RegisterID dst)
352 {
353 m_formatter.oneByteOp64(OP_ADD_EvGv, src, dst);
354 }
355
356 void addq_ir(int imm, RegisterID dst)
357 {
358 if (CAN_SIGN_EXTEND_8_32(imm)) {
359 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_ADD, dst);
360 m_formatter.immediate8(imm);
361 } else {
362 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_ADD, dst);
363 m_formatter.immediate32(imm);
364 }
365 }
ba379fdc
A
366
367 void addq_im(int imm, int offset, RegisterID base)
368 {
369 if (CAN_SIGN_EXTEND_8_32(imm)) {
370 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_ADD, base, offset);
371 m_formatter.immediate8(imm);
372 } else {
373 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_ADD, base, offset);
374 m_formatter.immediate32(imm);
375 }
376 }
9dae56ea
A
377#else
378 void addl_im(int imm, void* addr)
379 {
380 if (CAN_SIGN_EXTEND_8_32(imm)) {
381 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, addr);
382 m_formatter.immediate8(imm);
383 } else {
384 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, addr);
385 m_formatter.immediate32(imm);
386 }
387 }
388#endif
389
390 void andl_rr(RegisterID src, RegisterID dst)
391 {
392 m_formatter.oneByteOp(OP_AND_EvGv, src, dst);
393 }
394
ba379fdc
A
395 void andl_mr(int offset, RegisterID base, RegisterID dst)
396 {
397 m_formatter.oneByteOp(OP_AND_GvEv, dst, base, offset);
398 }
399
400 void andl_rm(RegisterID src, int offset, RegisterID base)
401 {
402 m_formatter.oneByteOp(OP_AND_EvGv, src, base, offset);
403 }
404
9dae56ea
A
405 void andl_ir(int imm, RegisterID dst)
406 {
407 if (CAN_SIGN_EXTEND_8_32(imm)) {
408 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, dst);
409 m_formatter.immediate8(imm);
410 } else {
411 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, dst);
412 m_formatter.immediate32(imm);
413 }
414 }
415
ba379fdc
A
416 void andl_im(int imm, int offset, RegisterID base)
417 {
418 if (CAN_SIGN_EXTEND_8_32(imm)) {
419 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, base, offset);
420 m_formatter.immediate8(imm);
421 } else {
422 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, base, offset);
423 m_formatter.immediate32(imm);
424 }
425 }
426
f9bf01c6 427#if CPU(X86_64)
9dae56ea
A
428 void andq_rr(RegisterID src, RegisterID dst)
429 {
430 m_formatter.oneByteOp64(OP_AND_EvGv, src, dst);
431 }
432
433 void andq_ir(int imm, RegisterID dst)
434 {
435 if (CAN_SIGN_EXTEND_8_32(imm)) {
436 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_AND, dst);
437 m_formatter.immediate8(imm);
438 } else {
439 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_AND, dst);
440 m_formatter.immediate32(imm);
441 }
442 }
ba379fdc
A
443#else
444 void andl_im(int imm, void* addr)
445 {
446 if (CAN_SIGN_EXTEND_8_32(imm)) {
447 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, addr);
448 m_formatter.immediate8(imm);
449 } else {
450 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, addr);
451 m_formatter.immediate32(imm);
452 }
453 }
9dae56ea
A
454#endif
455
ba379fdc
A
456 void negl_r(RegisterID dst)
457 {
458 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NEG, dst);
459 }
460
461 void negl_m(int offset, RegisterID base)
462 {
463 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NEG, base, offset);
464 }
465
9dae56ea
A
466 void notl_r(RegisterID dst)
467 {
468 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NOT, dst);
469 }
470
ba379fdc
A
471 void notl_m(int offset, RegisterID base)
472 {
473 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NOT, base, offset);
474 }
475
9dae56ea
A
476 void orl_rr(RegisterID src, RegisterID dst)
477 {
478 m_formatter.oneByteOp(OP_OR_EvGv, src, dst);
479 }
480
481 void orl_mr(int offset, RegisterID base, RegisterID dst)
482 {
483 m_formatter.oneByteOp(OP_OR_GvEv, dst, base, offset);
484 }
485
ba379fdc
A
486 void orl_rm(RegisterID src, int offset, RegisterID base)
487 {
488 m_formatter.oneByteOp(OP_OR_EvGv, src, base, offset);
489 }
490
9dae56ea
A
491 void orl_ir(int imm, RegisterID dst)
492 {
493 if (CAN_SIGN_EXTEND_8_32(imm)) {
494 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, dst);
495 m_formatter.immediate8(imm);
496 } else {
497 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, dst);
498 m_formatter.immediate32(imm);
499 }
500 }
501
ba379fdc
A
502 void orl_im(int imm, int offset, RegisterID base)
503 {
504 if (CAN_SIGN_EXTEND_8_32(imm)) {
505 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, base, offset);
506 m_formatter.immediate8(imm);
507 } else {
508 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, base, offset);
509 m_formatter.immediate32(imm);
510 }
511 }
512
f9bf01c6 513#if CPU(X86_64)
9dae56ea
A
514 void orq_rr(RegisterID src, RegisterID dst)
515 {
516 m_formatter.oneByteOp64(OP_OR_EvGv, src, dst);
517 }
518
519 void orq_ir(int imm, RegisterID dst)
520 {
521 if (CAN_SIGN_EXTEND_8_32(imm)) {
522 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_OR, dst);
523 m_formatter.immediate8(imm);
524 } else {
525 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_OR, dst);
526 m_formatter.immediate32(imm);
527 }
528 }
ba379fdc
A
529#else
530 void orl_im(int imm, void* addr)
531 {
532 if (CAN_SIGN_EXTEND_8_32(imm)) {
533 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, addr);
534 m_formatter.immediate8(imm);
535 } else {
536 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, addr);
537 m_formatter.immediate32(imm);
538 }
539 }
9dae56ea
A
540#endif
541
542 void subl_rr(RegisterID src, RegisterID dst)
543 {
544 m_formatter.oneByteOp(OP_SUB_EvGv, src, dst);
545 }
546
547 void subl_mr(int offset, RegisterID base, RegisterID dst)
548 {
549 m_formatter.oneByteOp(OP_SUB_GvEv, dst, base, offset);
550 }
551
ba379fdc
A
552 void subl_rm(RegisterID src, int offset, RegisterID base)
553 {
554 m_formatter.oneByteOp(OP_SUB_EvGv, src, base, offset);
555 }
556
9dae56ea
A
557 void subl_ir(int imm, RegisterID dst)
558 {
559 if (CAN_SIGN_EXTEND_8_32(imm)) {
560 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, dst);
561 m_formatter.immediate8(imm);
562 } else {
563 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, dst);
564 m_formatter.immediate32(imm);
565 }
566 }
567
568 void subl_im(int imm, int offset, RegisterID base)
569 {
570 if (CAN_SIGN_EXTEND_8_32(imm)) {
571 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, base, offset);
572 m_formatter.immediate8(imm);
573 } else {
574 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, base, offset);
575 m_formatter.immediate32(imm);
576 }
577 }
578
f9bf01c6 579#if CPU(X86_64)
9dae56ea
A
580 void subq_rr(RegisterID src, RegisterID dst)
581 {
582 m_formatter.oneByteOp64(OP_SUB_EvGv, src, dst);
583 }
584
585 void subq_ir(int imm, RegisterID dst)
586 {
587 if (CAN_SIGN_EXTEND_8_32(imm)) {
588 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_SUB, dst);
589 m_formatter.immediate8(imm);
590 } else {
591 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_SUB, dst);
592 m_formatter.immediate32(imm);
593 }
594 }
595#else
596 void subl_im(int imm, void* addr)
597 {
598 if (CAN_SIGN_EXTEND_8_32(imm)) {
599 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, addr);
600 m_formatter.immediate8(imm);
601 } else {
602 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, addr);
603 m_formatter.immediate32(imm);
604 }
605 }
606#endif
607
608 void xorl_rr(RegisterID src, RegisterID dst)
609 {
610 m_formatter.oneByteOp(OP_XOR_EvGv, src, dst);
611 }
612
ba379fdc
A
613 void xorl_mr(int offset, RegisterID base, RegisterID dst)
614 {
615 m_formatter.oneByteOp(OP_XOR_GvEv, dst, base, offset);
616 }
617
618 void xorl_rm(RegisterID src, int offset, RegisterID base)
619 {
620 m_formatter.oneByteOp(OP_XOR_EvGv, src, base, offset);
621 }
622
623 void xorl_im(int imm, int offset, RegisterID base)
624 {
625 if (CAN_SIGN_EXTEND_8_32(imm)) {
626 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_XOR, base, offset);
627 m_formatter.immediate8(imm);
628 } else {
629 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_XOR, base, offset);
630 m_formatter.immediate32(imm);
631 }
632 }
633
9dae56ea
A
634 void xorl_ir(int imm, RegisterID dst)
635 {
636 if (CAN_SIGN_EXTEND_8_32(imm)) {
637 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_XOR, dst);
638 m_formatter.immediate8(imm);
639 } else {
640 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_XOR, dst);
641 m_formatter.immediate32(imm);
642 }
643 }
644
f9bf01c6 645#if CPU(X86_64)
9dae56ea
A
646 void xorq_rr(RegisterID src, RegisterID dst)
647 {
648 m_formatter.oneByteOp64(OP_XOR_EvGv, src, dst);
649 }
650
651 void xorq_ir(int imm, RegisterID dst)
652 {
653 if (CAN_SIGN_EXTEND_8_32(imm)) {
654 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_XOR, dst);
655 m_formatter.immediate8(imm);
656 } else {
657 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_XOR, dst);
658 m_formatter.immediate32(imm);
659 }
660 }
661#endif
662
663 void sarl_i8r(int imm, RegisterID dst)
664 {
665 if (imm == 1)
666 m_formatter.oneByteOp(OP_GROUP2_Ev1, GROUP2_OP_SAR, dst);
667 else {
668 m_formatter.oneByteOp(OP_GROUP2_EvIb, GROUP2_OP_SAR, dst);
669 m_formatter.immediate8(imm);
670 }
671 }
672
673 void sarl_CLr(RegisterID dst)
674 {
675 m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SAR, dst);
676 }
4e4e5a6f
A
677
678 void shrl_i8r(int imm, RegisterID dst)
679 {
680 if (imm == 1)
681 m_formatter.oneByteOp(OP_GROUP2_Ev1, GROUP2_OP_SHR, dst);
682 else {
683 m_formatter.oneByteOp(OP_GROUP2_EvIb, GROUP2_OP_SHR, dst);
684 m_formatter.immediate8(imm);
685 }
686 }
687
688 void shrl_CLr(RegisterID dst)
689 {
690 m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SHR, dst);
691 }
9dae56ea
A
692
693 void shll_i8r(int imm, RegisterID dst)
694 {
695 if (imm == 1)
696 m_formatter.oneByteOp(OP_GROUP2_Ev1, GROUP2_OP_SHL, dst);
697 else {
698 m_formatter.oneByteOp(OP_GROUP2_EvIb, GROUP2_OP_SHL, dst);
699 m_formatter.immediate8(imm);
700 }
701 }
702
703 void shll_CLr(RegisterID dst)
704 {
705 m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SHL, dst);
706 }
707
f9bf01c6 708#if CPU(X86_64)
9dae56ea
A
709 void sarq_CLr(RegisterID dst)
710 {
711 m_formatter.oneByteOp64(OP_GROUP2_EvCL, GROUP2_OP_SAR, dst);
712 }
713
714 void sarq_i8r(int imm, RegisterID dst)
715 {
716 if (imm == 1)
717 m_formatter.oneByteOp64(OP_GROUP2_Ev1, GROUP2_OP_SAR, dst);
718 else {
719 m_formatter.oneByteOp64(OP_GROUP2_EvIb, GROUP2_OP_SAR, dst);
720 m_formatter.immediate8(imm);
721 }
722 }
723#endif
724
725 void imull_rr(RegisterID src, RegisterID dst)
726 {
727 m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, src);
728 }
ba379fdc
A
729
730 void imull_mr(int offset, RegisterID base, RegisterID dst)
731 {
732 m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, base, offset);
733 }
734
9dae56ea
A
735 void imull_i32r(RegisterID src, int32_t value, RegisterID dst)
736 {
737 m_formatter.oneByteOp(OP_IMUL_GvEvIz, dst, src);
738 m_formatter.immediate32(value);
739 }
740
741 void idivl_r(RegisterID dst)
742 {
743 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_IDIV, dst);
744 }
745
746 // Comparisons:
747
748 void cmpl_rr(RegisterID src, RegisterID dst)
749 {
750 m_formatter.oneByteOp(OP_CMP_EvGv, src, dst);
751 }
752
753 void cmpl_rm(RegisterID src, int offset, RegisterID base)
754 {
755 m_formatter.oneByteOp(OP_CMP_EvGv, src, base, offset);
756 }
757
758 void cmpl_mr(int offset, RegisterID base, RegisterID src)
759 {
760 m_formatter.oneByteOp(OP_CMP_GvEv, src, base, offset);
761 }
762
763 void cmpl_ir(int imm, RegisterID dst)
764 {
765 if (CAN_SIGN_EXTEND_8_32(imm)) {
766 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, dst);
767 m_formatter.immediate8(imm);
768 } else {
769 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
770 m_formatter.immediate32(imm);
771 }
772 }
773
774 void cmpl_ir_force32(int imm, RegisterID dst)
775 {
776 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
777 m_formatter.immediate32(imm);
778 }
4e4e5a6f 779
9dae56ea
A
780 void cmpl_im(int imm, int offset, RegisterID base)
781 {
782 if (CAN_SIGN_EXTEND_8_32(imm)) {
783 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, offset);
784 m_formatter.immediate8(imm);
785 } else {
786 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, offset);
787 m_formatter.immediate32(imm);
788 }
789 }
4e4e5a6f
A
790
791 void cmpb_im(int imm, int offset, RegisterID base)
792 {
793 m_formatter.oneByteOp(OP_GROUP1_EbIb, GROUP1_OP_CMP, base, offset);
794 m_formatter.immediate8(imm);
795 }
796
797 void cmpb_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
798 {
799 m_formatter.oneByteOp(OP_GROUP1_EbIb, GROUP1_OP_CMP, base, index, scale, offset);
800 m_formatter.immediate8(imm);
801 }
9dae56ea
A
802
803 void cmpl_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
804 {
805 if (CAN_SIGN_EXTEND_8_32(imm)) {
806 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, index, scale, offset);
807 m_formatter.immediate8(imm);
808 } else {
809 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, index, scale, offset);
810 m_formatter.immediate32(imm);
811 }
812 }
813
814 void cmpl_im_force32(int imm, int offset, RegisterID base)
815 {
816 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, offset);
817 m_formatter.immediate32(imm);
818 }
819
f9bf01c6 820#if CPU(X86_64)
9dae56ea
A
821 void cmpq_rr(RegisterID src, RegisterID dst)
822 {
823 m_formatter.oneByteOp64(OP_CMP_EvGv, src, dst);
824 }
825
826 void cmpq_rm(RegisterID src, int offset, RegisterID base)
827 {
828 m_formatter.oneByteOp64(OP_CMP_EvGv, src, base, offset);
829 }
830
ba379fdc
A
831 void cmpq_mr(int offset, RegisterID base, RegisterID src)
832 {
833 m_formatter.oneByteOp64(OP_CMP_GvEv, src, base, offset);
834 }
835
9dae56ea
A
836 void cmpq_ir(int imm, RegisterID dst)
837 {
838 if (CAN_SIGN_EXTEND_8_32(imm)) {
839 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_CMP, dst);
840 m_formatter.immediate8(imm);
841 } else {
842 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
843 m_formatter.immediate32(imm);
844 }
845 }
846
847 void cmpq_im(int imm, int offset, RegisterID base)
848 {
849 if (CAN_SIGN_EXTEND_8_32(imm)) {
850 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, offset);
851 m_formatter.immediate8(imm);
852 } else {
853 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, offset);
854 m_formatter.immediate32(imm);
855 }
856 }
857
858 void cmpq_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
859 {
860 if (CAN_SIGN_EXTEND_8_32(imm)) {
861 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, index, scale, offset);
862 m_formatter.immediate8(imm);
863 } else {
864 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, index, scale, offset);
865 m_formatter.immediate32(imm);
866 }
867 }
868#else
869 void cmpl_rm(RegisterID reg, void* addr)
870 {
871 m_formatter.oneByteOp(OP_CMP_EvGv, reg, addr);
872 }
873
874 void cmpl_im(int imm, void* addr)
875 {
876 if (CAN_SIGN_EXTEND_8_32(imm)) {
877 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, addr);
878 m_formatter.immediate8(imm);
879 } else {
880 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, addr);
881 m_formatter.immediate32(imm);
882 }
883 }
884#endif
885
886 void cmpw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
887 {
888 m_formatter.prefix(PRE_OPERAND_SIZE);
889 m_formatter.oneByteOp(OP_CMP_EvGv, src, base, index, scale, offset);
890 }
891
ba379fdc
A
892 void cmpw_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
893 {
894 if (CAN_SIGN_EXTEND_8_32(imm)) {
895 m_formatter.prefix(PRE_OPERAND_SIZE);
896 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, index, scale, offset);
897 m_formatter.immediate8(imm);
898 } else {
899 m_formatter.prefix(PRE_OPERAND_SIZE);
900 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, index, scale, offset);
901 m_formatter.immediate16(imm);
902 }
903 }
904
9dae56ea
A
905 void testl_rr(RegisterID src, RegisterID dst)
906 {
907 m_formatter.oneByteOp(OP_TEST_EvGv, src, dst);
908 }
909
910 void testl_i32r(int imm, RegisterID dst)
911 {
912 m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, dst);
913 m_formatter.immediate32(imm);
914 }
915
916 void testl_i32m(int imm, int offset, RegisterID base)
917 {
918 m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, offset);
919 m_formatter.immediate32(imm);
920 }
4e4e5a6f
A
921
922 void testb_im(int imm, int offset, RegisterID base)
923 {
924 m_formatter.oneByteOp(OP_GROUP3_EbIb, GROUP3_OP_TEST, base, offset);
925 m_formatter.immediate8(imm);
926 }
927
928 void testb_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
929 {
930 m_formatter.oneByteOp(OP_GROUP3_EbIb, GROUP3_OP_TEST, base, index, scale, offset);
931 m_formatter.immediate8(imm);
932 }
9dae56ea
A
933
934 void testl_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale)
935 {
936 m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, index, scale, offset);
937 m_formatter.immediate32(imm);
938 }
939
f9bf01c6 940#if CPU(X86_64)
9dae56ea
A
941 void testq_rr(RegisterID src, RegisterID dst)
942 {
943 m_formatter.oneByteOp64(OP_TEST_EvGv, src, dst);
944 }
945
946 void testq_i32r(int imm, RegisterID dst)
947 {
948 m_formatter.oneByteOp64(OP_GROUP3_EvIz, GROUP3_OP_TEST, dst);
949 m_formatter.immediate32(imm);
950 }
951
952 void testq_i32m(int imm, int offset, RegisterID base)
953 {
954 m_formatter.oneByteOp64(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, offset);
955 m_formatter.immediate32(imm);
956 }
957
958 void testq_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale)
959 {
960 m_formatter.oneByteOp64(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, index, scale, offset);
961 m_formatter.immediate32(imm);
962 }
963#endif
964
ba379fdc
A
965 void testw_rr(RegisterID src, RegisterID dst)
966 {
967 m_formatter.prefix(PRE_OPERAND_SIZE);
968 m_formatter.oneByteOp(OP_TEST_EvGv, src, dst);
969 }
970
9dae56ea
A
971 void testb_i8r(int imm, RegisterID dst)
972 {
973 m_formatter.oneByteOp8(OP_GROUP3_EbIb, GROUP3_OP_TEST, dst);
974 m_formatter.immediate8(imm);
975 }
976
ba379fdc
A
977 void setCC_r(Condition cond, RegisterID dst)
978 {
979 m_formatter.twoByteOp8(setccOpcode(cond), (GroupOpcodeID)0, dst);
980 }
981
9dae56ea
A
982 void sete_r(RegisterID dst)
983 {
ba379fdc 984 m_formatter.twoByteOp8(setccOpcode(ConditionE), (GroupOpcodeID)0, dst);
9dae56ea
A
985 }
986
987 void setz_r(RegisterID dst)
988 {
989 sete_r(dst);
990 }
991
992 void setne_r(RegisterID dst)
993 {
ba379fdc 994 m_formatter.twoByteOp8(setccOpcode(ConditionNE), (GroupOpcodeID)0, dst);
9dae56ea
A
995 }
996
997 void setnz_r(RegisterID dst)
998 {
999 setne_r(dst);
1000 }
1001
1002 // Various move ops:
1003
1004 void cdq()
1005 {
1006 m_formatter.oneByteOp(OP_CDQ);
1007 }
1008
1009 void xchgl_rr(RegisterID src, RegisterID dst)
1010 {
1011 m_formatter.oneByteOp(OP_XCHG_EvGv, src, dst);
1012 }
1013
f9bf01c6 1014#if CPU(X86_64)
9dae56ea
A
1015 void xchgq_rr(RegisterID src, RegisterID dst)
1016 {
1017 m_formatter.oneByteOp64(OP_XCHG_EvGv, src, dst);
1018 }
1019#endif
1020
1021 void movl_rr(RegisterID src, RegisterID dst)
1022 {
1023 m_formatter.oneByteOp(OP_MOV_EvGv, src, dst);
1024 }
1025
1026 void movl_rm(RegisterID src, int offset, RegisterID base)
1027 {
1028 m_formatter.oneByteOp(OP_MOV_EvGv, src, base, offset);
1029 }
1030
1031 void movl_rm_disp32(RegisterID src, int offset, RegisterID base)
1032 {
1033 m_formatter.oneByteOp_disp32(OP_MOV_EvGv, src, base, offset);
1034 }
1035
1036 void movl_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1037 {
1038 m_formatter.oneByteOp(OP_MOV_EvGv, src, base, index, scale, offset);
1039 }
1040
1041 void movl_mEAX(void* addr)
1042 {
1043 m_formatter.oneByteOp(OP_MOV_EAXOv);
f9bf01c6 1044#if CPU(X86_64)
9dae56ea
A
1045 m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
1046#else
1047 m_formatter.immediate32(reinterpret_cast<int>(addr));
1048#endif
1049 }
1050
1051 void movl_mr(int offset, RegisterID base, RegisterID dst)
1052 {
1053 m_formatter.oneByteOp(OP_MOV_GvEv, dst, base, offset);
1054 }
1055
1056 void movl_mr_disp32(int offset, RegisterID base, RegisterID dst)
1057 {
1058 m_formatter.oneByteOp_disp32(OP_MOV_GvEv, dst, base, offset);
1059 }
1060
1061 void movl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1062 {
1063 m_formatter.oneByteOp(OP_MOV_GvEv, dst, base, index, scale, offset);
1064 }
1065
1066 void movl_i32r(int imm, RegisterID dst)
1067 {
1068 m_formatter.oneByteOp(OP_MOV_EAXIv, dst);
1069 m_formatter.immediate32(imm);
1070 }
1071
1072 void movl_i32m(int imm, int offset, RegisterID base)
1073 {
1074 m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, base, offset);
1075 m_formatter.immediate32(imm);
1076 }
1077
1078 void movl_EAXm(void* addr)
1079 {
1080 m_formatter.oneByteOp(OP_MOV_OvEAX);
f9bf01c6 1081#if CPU(X86_64)
9dae56ea
A
1082 m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
1083#else
1084 m_formatter.immediate32(reinterpret_cast<int>(addr));
1085#endif
1086 }
1087
f9bf01c6 1088#if CPU(X86_64)
9dae56ea
A
1089 void movq_rr(RegisterID src, RegisterID dst)
1090 {
1091 m_formatter.oneByteOp64(OP_MOV_EvGv, src, dst);
1092 }
1093
1094 void movq_rm(RegisterID src, int offset, RegisterID base)
1095 {
1096 m_formatter.oneByteOp64(OP_MOV_EvGv, src, base, offset);
1097 }
1098
1099 void movq_rm_disp32(RegisterID src, int offset, RegisterID base)
1100 {
1101 m_formatter.oneByteOp64_disp32(OP_MOV_EvGv, src, base, offset);
1102 }
1103
1104 void movq_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1105 {
1106 m_formatter.oneByteOp64(OP_MOV_EvGv, src, base, index, scale, offset);
1107 }
1108
1109 void movq_mEAX(void* addr)
1110 {
1111 m_formatter.oneByteOp64(OP_MOV_EAXOv);
1112 m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
1113 }
1114
ba379fdc
A
1115 void movq_EAXm(void* addr)
1116 {
1117 m_formatter.oneByteOp64(OP_MOV_OvEAX);
1118 m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
1119 }
1120
9dae56ea
A
1121 void movq_mr(int offset, RegisterID base, RegisterID dst)
1122 {
1123 m_formatter.oneByteOp64(OP_MOV_GvEv, dst, base, offset);
1124 }
1125
1126 void movq_mr_disp32(int offset, RegisterID base, RegisterID dst)
1127 {
1128 m_formatter.oneByteOp64_disp32(OP_MOV_GvEv, dst, base, offset);
1129 }
1130
1131 void movq_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1132 {
1133 m_formatter.oneByteOp64(OP_MOV_GvEv, dst, base, index, scale, offset);
1134 }
1135
ba379fdc
A
1136 void movq_i32m(int imm, int offset, RegisterID base)
1137 {
1138 m_formatter.oneByteOp64(OP_GROUP11_EvIz, GROUP11_MOV, base, offset);
1139 m_formatter.immediate32(imm);
1140 }
1141
9dae56ea
A
1142 void movq_i64r(int64_t imm, RegisterID dst)
1143 {
1144 m_formatter.oneByteOp64(OP_MOV_EAXIv, dst);
1145 m_formatter.immediate64(imm);
1146 }
1147
1148 void movsxd_rr(RegisterID src, RegisterID dst)
1149 {
1150 m_formatter.oneByteOp64(OP_MOVSXD_GvEv, dst, src);
1151 }
1152
1153
1154#else
ba379fdc
A
1155 void movl_rm(RegisterID src, void* addr)
1156 {
f9bf01c6 1157 if (src == X86Registers::eax)
ba379fdc
A
1158 movl_EAXm(addr);
1159 else
1160 m_formatter.oneByteOp(OP_MOV_EvGv, src, addr);
1161 }
1162
9dae56ea
A
1163 void movl_mr(void* addr, RegisterID dst)
1164 {
f9bf01c6 1165 if (dst == X86Registers::eax)
9dae56ea
A
1166 movl_mEAX(addr);
1167 else
1168 m_formatter.oneByteOp(OP_MOV_GvEv, dst, addr);
1169 }
1170
1171 void movl_i32m(int imm, void* addr)
1172 {
1173 m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, addr);
1174 m_formatter.immediate32(imm);
1175 }
1176#endif
1177
1178 void movzwl_mr(int offset, RegisterID base, RegisterID dst)
1179 {
1180 m_formatter.twoByteOp(OP2_MOVZX_GvEw, dst, base, offset);
1181 }
1182
1183 void movzwl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1184 {
1185 m_formatter.twoByteOp(OP2_MOVZX_GvEw, dst, base, index, scale, offset);
1186 }
1187
1188 void movzbl_rr(RegisterID src, RegisterID dst)
1189 {
1190 // In 64-bit, this may cause an unnecessary REX to be planted (if the dst register
1191 // is in the range ESP-EDI, and the src would not have required a REX). Unneeded
1192 // REX prefixes are defined to be silently ignored by the processor.
1193 m_formatter.twoByteOp8(OP2_MOVZX_GvEb, dst, src);
1194 }
1195
1196 void leal_mr(int offset, RegisterID base, RegisterID dst)
1197 {
1198 m_formatter.oneByteOp(OP_LEA, dst, base, offset);
1199 }
f9bf01c6 1200#if CPU(X86_64)
ba379fdc
A
1201 void leaq_mr(int offset, RegisterID base, RegisterID dst)
1202 {
1203 m_formatter.oneByteOp64(OP_LEA, dst, base, offset);
1204 }
1205#endif
9dae56ea
A
1206
1207 // Flow control:
1208
1209 JmpSrc call()
1210 {
1211 m_formatter.oneByteOp(OP_CALL_rel32);
1212 return m_formatter.immediateRel32();
1213 }
1214
1215 JmpSrc call(RegisterID dst)
1216 {
1217 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_CALLN, dst);
1218 return JmpSrc(m_formatter.size());
1219 }
ba379fdc
A
1220
1221 void call_m(int offset, RegisterID base)
1222 {
1223 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_CALLN, base, offset);
1224 }
9dae56ea
A
1225
1226 JmpSrc jmp()
1227 {
1228 m_formatter.oneByteOp(OP_JMP_rel32);
1229 return m_formatter.immediateRel32();
1230 }
1231
ba379fdc
A
1232 // Return a JmpSrc so we have a label to the jump, so we can use this
1233 // To make a tail recursive call on x86-64. The MacroAssembler
1234 // really shouldn't wrap this as a Jump, since it can't be linked. :-/
1235 JmpSrc jmp_r(RegisterID dst)
9dae56ea
A
1236 {
1237 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, dst);
ba379fdc 1238 return JmpSrc(m_formatter.size());
9dae56ea
A
1239 }
1240
1241 void jmp_m(int offset, RegisterID base)
1242 {
1243 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, base, offset);
1244 }
1245
1246 JmpSrc jne()
1247 {
ba379fdc 1248 m_formatter.twoByteOp(jccRel32(ConditionNE));
9dae56ea
A
1249 return m_formatter.immediateRel32();
1250 }
1251
1252 JmpSrc jnz()
1253 {
1254 return jne();
1255 }
1256
1257 JmpSrc je()
1258 {
ba379fdc 1259 m_formatter.twoByteOp(jccRel32(ConditionE));
9dae56ea
A
1260 return m_formatter.immediateRel32();
1261 }
1262
ba379fdc
A
1263 JmpSrc jz()
1264 {
1265 return je();
1266 }
1267
9dae56ea
A
1268 JmpSrc jl()
1269 {
ba379fdc 1270 m_formatter.twoByteOp(jccRel32(ConditionL));
9dae56ea
A
1271 return m_formatter.immediateRel32();
1272 }
1273
1274 JmpSrc jb()
1275 {
ba379fdc 1276 m_formatter.twoByteOp(jccRel32(ConditionB));
9dae56ea
A
1277 return m_formatter.immediateRel32();
1278 }
1279
1280 JmpSrc jle()
1281 {
ba379fdc 1282 m_formatter.twoByteOp(jccRel32(ConditionLE));
9dae56ea
A
1283 return m_formatter.immediateRel32();
1284 }
1285
1286 JmpSrc jbe()
1287 {
ba379fdc 1288 m_formatter.twoByteOp(jccRel32(ConditionBE));
9dae56ea
A
1289 return m_formatter.immediateRel32();
1290 }
1291
1292 JmpSrc jge()
1293 {
ba379fdc 1294 m_formatter.twoByteOp(jccRel32(ConditionGE));
9dae56ea
A
1295 return m_formatter.immediateRel32();
1296 }
1297
1298 JmpSrc jg()
1299 {
ba379fdc 1300 m_formatter.twoByteOp(jccRel32(ConditionG));
9dae56ea
A
1301 return m_formatter.immediateRel32();
1302 }
1303
1304 JmpSrc ja()
1305 {
ba379fdc 1306 m_formatter.twoByteOp(jccRel32(ConditionA));
9dae56ea
A
1307 return m_formatter.immediateRel32();
1308 }
1309
1310 JmpSrc jae()
1311 {
ba379fdc 1312 m_formatter.twoByteOp(jccRel32(ConditionAE));
9dae56ea
A
1313 return m_formatter.immediateRel32();
1314 }
1315
1316 JmpSrc jo()
1317 {
ba379fdc 1318 m_formatter.twoByteOp(jccRel32(ConditionO));
9dae56ea
A
1319 return m_formatter.immediateRel32();
1320 }
1321
1322 JmpSrc jp()
1323 {
ba379fdc 1324 m_formatter.twoByteOp(jccRel32(ConditionP));
9dae56ea
A
1325 return m_formatter.immediateRel32();
1326 }
1327
1328 JmpSrc js()
1329 {
ba379fdc
A
1330 m_formatter.twoByteOp(jccRel32(ConditionS));
1331 return m_formatter.immediateRel32();
1332 }
1333
1334 JmpSrc jCC(Condition cond)
1335 {
1336 m_formatter.twoByteOp(jccRel32(cond));
9dae56ea
A
1337 return m_formatter.immediateRel32();
1338 }
1339
1340 // SSE operations:
1341
1342 void addsd_rr(XMMRegisterID src, XMMRegisterID dst)
1343 {
1344 m_formatter.prefix(PRE_SSE_F2);
1345 m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
1346 }
1347
1348 void addsd_mr(int offset, RegisterID base, XMMRegisterID dst)
1349 {
1350 m_formatter.prefix(PRE_SSE_F2);
1351 m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, base, offset);
1352 }
1353
1354 void cvtsi2sd_rr(RegisterID src, XMMRegisterID dst)
1355 {
1356 m_formatter.prefix(PRE_SSE_F2);
1357 m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, src);
1358 }
1359
ba379fdc
A
1360 void cvtsi2sd_mr(int offset, RegisterID base, XMMRegisterID dst)
1361 {
1362 m_formatter.prefix(PRE_SSE_F2);
1363 m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, base, offset);
1364 }
1365
f9bf01c6 1366#if !CPU(X86_64)
ba379fdc
A
1367 void cvtsi2sd_mr(void* address, XMMRegisterID dst)
1368 {
1369 m_formatter.prefix(PRE_SSE_F2);
1370 m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, address);
1371 }
1372#endif
1373
9dae56ea
A
1374 void cvttsd2si_rr(XMMRegisterID src, RegisterID dst)
1375 {
1376 m_formatter.prefix(PRE_SSE_F2);
1377 m_formatter.twoByteOp(OP2_CVTTSD2SI_GdWsd, dst, (RegisterID)src);
1378 }
1379
1380 void movd_rr(XMMRegisterID src, RegisterID dst)
1381 {
1382 m_formatter.prefix(PRE_SSE_66);
1383 m_formatter.twoByteOp(OP2_MOVD_EdVd, (RegisterID)src, dst);
1384 }
1385
f9bf01c6 1386#if CPU(X86_64)
9dae56ea
A
1387 void movq_rr(XMMRegisterID src, RegisterID dst)
1388 {
1389 m_formatter.prefix(PRE_SSE_66);
1390 m_formatter.twoByteOp64(OP2_MOVD_EdVd, (RegisterID)src, dst);
1391 }
1392
1393 void movq_rr(RegisterID src, XMMRegisterID dst)
1394 {
1395 m_formatter.prefix(PRE_SSE_66);
1396 m_formatter.twoByteOp64(OP2_MOVD_VdEd, (RegisterID)dst, src);
1397 }
1398#endif
1399
1400 void movsd_rm(XMMRegisterID src, int offset, RegisterID base)
1401 {
1402 m_formatter.prefix(PRE_SSE_F2);
1403 m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, offset);
1404 }
1405
1406 void movsd_mr(int offset, RegisterID base, XMMRegisterID dst)
1407 {
1408 m_formatter.prefix(PRE_SSE_F2);
1409 m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, base, offset);
1410 }
1411
f9bf01c6 1412#if !CPU(X86_64)
4e4e5a6f 1413 void movsd_mr(const void* address, XMMRegisterID dst)
ba379fdc
A
1414 {
1415 m_formatter.prefix(PRE_SSE_F2);
1416 m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, address);
1417 }
1418#endif
1419
9dae56ea
A
1420 void mulsd_rr(XMMRegisterID src, XMMRegisterID dst)
1421 {
1422 m_formatter.prefix(PRE_SSE_F2);
1423 m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
1424 }
1425
1426 void mulsd_mr(int offset, RegisterID base, XMMRegisterID dst)
1427 {
1428 m_formatter.prefix(PRE_SSE_F2);
1429 m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)dst, base, offset);
1430 }
1431
1432 void pextrw_irr(int whichWord, XMMRegisterID src, RegisterID dst)
1433 {
1434 m_formatter.prefix(PRE_SSE_66);
1435 m_formatter.twoByteOp(OP2_PEXTRW_GdUdIb, (RegisterID)dst, (RegisterID)src);
1436 m_formatter.immediate8(whichWord);
1437 }
1438
1439 void subsd_rr(XMMRegisterID src, XMMRegisterID dst)
1440 {
1441 m_formatter.prefix(PRE_SSE_F2);
1442 m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
1443 }
1444
1445 void subsd_mr(int offset, RegisterID base, XMMRegisterID dst)
1446 {
1447 m_formatter.prefix(PRE_SSE_F2);
1448 m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, base, offset);
1449 }
1450
1451 void ucomisd_rr(XMMRegisterID src, XMMRegisterID dst)
1452 {
1453 m_formatter.prefix(PRE_SSE_66);
1454 m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)dst, (RegisterID)src);
1455 }
1456
ba379fdc
A
1457 void ucomisd_mr(int offset, RegisterID base, XMMRegisterID dst)
1458 {
1459 m_formatter.prefix(PRE_SSE_66);
1460 m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)dst, base, offset);
1461 }
1462
1463 void divsd_rr(XMMRegisterID src, XMMRegisterID dst)
1464 {
1465 m_formatter.prefix(PRE_SSE_F2);
1466 m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
1467 }
1468
1469 void divsd_mr(int offset, RegisterID base, XMMRegisterID dst)
1470 {
1471 m_formatter.prefix(PRE_SSE_F2);
1472 m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)dst, base, offset);
1473 }
1474
1475 void xorpd_rr(XMMRegisterID src, XMMRegisterID dst)
1476 {
1477 m_formatter.prefix(PRE_SSE_66);
1478 m_formatter.twoByteOp(OP2_XORPD_VpdWpd, (RegisterID)dst, (RegisterID)src);
1479 }
1480
4e4e5a6f
A
1481 void sqrtsd_rr(XMMRegisterID src, XMMRegisterID dst)
1482 {
1483 m_formatter.prefix(PRE_SSE_F2);
1484 m_formatter.twoByteOp(OP2_SQRTSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
1485 }
1486
9dae56ea
A
1487 // Misc instructions:
1488
1489 void int3()
1490 {
1491 m_formatter.oneByteOp(OP_INT3);
1492 }
1493
1494 void ret()
1495 {
1496 m_formatter.oneByteOp(OP_RET);
1497 }
1498
1499 void predictNotTaken()
1500 {
1501 m_formatter.prefix(PRE_PREDICT_BRANCH_NOT_TAKEN);
1502 }
1503
1504 // Assembler admin methods:
1505
1506 JmpDst label()
1507 {
1508 return JmpDst(m_formatter.size());
1509 }
1510
ba379fdc
A
1511 static JmpDst labelFor(JmpSrc jump, intptr_t offset = 0)
1512 {
1513 return JmpDst(jump.m_offset + offset);
1514 }
1515
9dae56ea
A
1516 JmpDst align(int alignment)
1517 {
1518 while (!m_formatter.isAligned(alignment))
1519 m_formatter.oneByteOp(OP_HLT);
1520
1521 return label();
1522 }
1523
1524 // Linking & patching:
ba379fdc
A
1525 //
1526 // 'link' and 'patch' methods are for use on unprotected code - such as the code
1527 // within the AssemblerBuffer, and code being patched by the patch buffer. Once
1528 // code has been finalized it is (platform support permitting) within a non-
1529 // writable region of memory; to modify the code in an execute-only execuable
1530 // pool the 'repatch' and 'relink' methods should be used.
9dae56ea 1531
ba379fdc 1532 void linkJump(JmpSrc from, JmpDst to)
9dae56ea 1533 {
9dae56ea 1534 ASSERT(from.m_offset != -1);
ba379fdc
A
1535 ASSERT(to.m_offset != -1);
1536
1537 char* code = reinterpret_cast<char*>(m_formatter.data());
1538 setRel32(code + from.m_offset, code + to.m_offset);
9dae56ea
A
1539 }
1540
ba379fdc 1541 static void linkJump(void* code, JmpSrc from, void* to)
9dae56ea 1542 {
ba379fdc
A
1543 ASSERT(from.m_offset != -1);
1544
1545 setRel32(reinterpret_cast<char*>(code) + from.m_offset, to);
9dae56ea 1546 }
ba379fdc
A
1547
1548 static void linkCall(void* code, JmpSrc from, void* to)
9dae56ea
A
1549 {
1550 ASSERT(from.m_offset != -1);
ba379fdc
A
1551
1552 setRel32(reinterpret_cast<char*>(code) + from.m_offset, to);
1553 }
1554
1555 static void linkPointer(void* code, JmpDst where, void* value)
1556 {
1557 ASSERT(where.m_offset != -1);
1558
1559 setPointer(reinterpret_cast<char*>(code) + where.m_offset, value);
1560 }
1561
1562 static void relinkJump(void* from, void* to)
1563 {
1564 setRel32(from, to);
1565 }
1566
1567 static void relinkCall(void* from, void* to)
1568 {
1569 setRel32(from, to);
1570 }
1571
1572 static void repatchInt32(void* where, int32_t value)
1573 {
1574 setInt32(where, value);
1575 }
1576
1577 static void repatchPointer(void* where, void* value)
1578 {
1579 setPointer(where, value);
1580 }
1581
1582 static void repatchLoadPtrToLEA(void* where)
1583 {
f9bf01c6 1584#if CPU(X86_64)
ba379fdc
A
1585 // On x86-64 pointer memory accesses require a 64-bit operand, and as such a REX prefix.
1586 // Skip over the prefix byte.
1587 where = reinterpret_cast<char*>(where) + 1;
1588#endif
1589 *reinterpret_cast<unsigned char*>(where) = static_cast<unsigned char>(OP_LEA);
9dae56ea
A
1590 }
1591
ba379fdc
A
1592 static unsigned getCallReturnOffset(JmpSrc call)
1593 {
1594 ASSERT(call.m_offset >= 0);
1595 return call.m_offset;
1596 }
1597
9dae56ea
A
1598 static void* getRelocatedAddress(void* code, JmpSrc jump)
1599 {
ba379fdc
A
1600 ASSERT(jump.m_offset != -1);
1601
9dae56ea
A
1602 return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + jump.m_offset);
1603 }
1604
1605 static void* getRelocatedAddress(void* code, JmpDst destination)
1606 {
1607 ASSERT(destination.m_offset != -1);
1608
1609 return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + destination.m_offset);
1610 }
1611
1612 static int getDifferenceBetweenLabels(JmpDst src, JmpDst dst)
1613 {
1614 return dst.m_offset - src.m_offset;
1615 }
1616
1617 static int getDifferenceBetweenLabels(JmpDst src, JmpSrc dst)
1618 {
1619 return dst.m_offset - src.m_offset;
1620 }
1621
1622 static int getDifferenceBetweenLabels(JmpSrc src, JmpDst dst)
1623 {
1624 return dst.m_offset - src.m_offset;
1625 }
1626
9dae56ea
A
1627 void* executableCopy(ExecutablePool* allocator)
1628 {
1629 void* copy = m_formatter.executableCopy(allocator);
1630 ASSERT(copy);
1631 return copy;
1632 }
1633
1634private:
1635
ba379fdc
A
1636 static void setPointer(void* where, void* value)
1637 {
1638 reinterpret_cast<void**>(where)[-1] = value;
1639 }
1640
1641 static void setInt32(void* where, int32_t value)
1642 {
1643 reinterpret_cast<int32_t*>(where)[-1] = value;
1644 }
1645
1646 static void setRel32(void* from, void* to)
1647 {
1648 intptr_t offset = reinterpret_cast<intptr_t>(to) - reinterpret_cast<intptr_t>(from);
1649 ASSERT(offset == static_cast<int32_t>(offset));
1650
1651 setInt32(from, offset);
1652 }
1653
9dae56ea
A
1654 class X86InstructionFormatter {
1655
1656 static const int maxInstructionSize = 16;
1657
1658 public:
1659
1660 // Legacy prefix bytes:
1661 //
1662 // These are emmitted prior to the instruction.
1663
1664 void prefix(OneByteOpcodeID pre)
1665 {
1666 m_buffer.putByte(pre);
1667 }
1668
1669 // Word-sized operands / no operand instruction formatters.
1670 //
1671 // In addition to the opcode, the following operand permutations are supported:
1672 // * None - instruction takes no operands.
1673 // * One register - the low three bits of the RegisterID are added into the opcode.
1674 // * 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).
1675 // * Three argument ModRM - a register, and a register and an offset describing a memory operand.
1676 // * Five argument ModRM - a register, and a base register, an index, scale, and offset describing a memory operand.
1677 //
1678 // For 32-bit x86 targets, the address operand may also be provided as a void*.
1679 // On 64-bit targets REX prefixes will be planted as necessary, where high numbered registers are used.
1680 //
1681 // The twoByteOp methods plant two-byte Intel instructions sequences (first opcode byte 0x0F).
1682
1683 void oneByteOp(OneByteOpcodeID opcode)
1684 {
1685 m_buffer.ensureSpace(maxInstructionSize);
1686 m_buffer.putByteUnchecked(opcode);
1687 }
1688
1689 void oneByteOp(OneByteOpcodeID opcode, RegisterID reg)
1690 {
1691 m_buffer.ensureSpace(maxInstructionSize);
1692 emitRexIfNeeded(0, 0, reg);
1693 m_buffer.putByteUnchecked(opcode + (reg & 7));
1694 }
1695
1696 void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID rm)
1697 {
1698 m_buffer.ensureSpace(maxInstructionSize);
1699 emitRexIfNeeded(reg, 0, rm);
1700 m_buffer.putByteUnchecked(opcode);
1701 registerModRM(reg, rm);
1702 }
1703
1704 void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
1705 {
1706 m_buffer.ensureSpace(maxInstructionSize);
1707 emitRexIfNeeded(reg, 0, base);
1708 m_buffer.putByteUnchecked(opcode);
1709 memoryModRM(reg, base, offset);
1710 }
1711
1712 void oneByteOp_disp32(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
1713 {
1714 m_buffer.ensureSpace(maxInstructionSize);
1715 emitRexIfNeeded(reg, 0, base);
1716 m_buffer.putByteUnchecked(opcode);
1717 memoryModRM_disp32(reg, base, offset);
1718 }
1719
1720 void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
1721 {
1722 m_buffer.ensureSpace(maxInstructionSize);
1723 emitRexIfNeeded(reg, index, base);
1724 m_buffer.putByteUnchecked(opcode);
1725 memoryModRM(reg, base, index, scale, offset);
1726 }
1727
f9bf01c6 1728#if !CPU(X86_64)
9dae56ea
A
1729 void oneByteOp(OneByteOpcodeID opcode, int reg, void* address)
1730 {
1731 m_buffer.ensureSpace(maxInstructionSize);
1732 m_buffer.putByteUnchecked(opcode);
1733 memoryModRM(reg, address);
1734 }
1735#endif
1736
1737 void twoByteOp(TwoByteOpcodeID opcode)
1738 {
1739 m_buffer.ensureSpace(maxInstructionSize);
1740 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
1741 m_buffer.putByteUnchecked(opcode);
1742 }
1743
1744 void twoByteOp(TwoByteOpcodeID opcode, int reg, RegisterID rm)
1745 {
1746 m_buffer.ensureSpace(maxInstructionSize);
1747 emitRexIfNeeded(reg, 0, rm);
1748 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
1749 m_buffer.putByteUnchecked(opcode);
1750 registerModRM(reg, rm);
1751 }
1752
1753 void twoByteOp(TwoByteOpcodeID opcode, int reg, RegisterID base, int offset)
1754 {
1755 m_buffer.ensureSpace(maxInstructionSize);
1756 emitRexIfNeeded(reg, 0, base);
1757 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
1758 m_buffer.putByteUnchecked(opcode);
1759 memoryModRM(reg, base, offset);
1760 }
1761
1762 void twoByteOp(TwoByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
1763 {
1764 m_buffer.ensureSpace(maxInstructionSize);
1765 emitRexIfNeeded(reg, index, base);
1766 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
1767 m_buffer.putByteUnchecked(opcode);
1768 memoryModRM(reg, base, index, scale, offset);
1769 }
1770
f9bf01c6 1771#if !CPU(X86_64)
4e4e5a6f 1772 void twoByteOp(TwoByteOpcodeID opcode, int reg, const void* address)
ba379fdc
A
1773 {
1774 m_buffer.ensureSpace(maxInstructionSize);
1775 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
1776 m_buffer.putByteUnchecked(opcode);
1777 memoryModRM(reg, address);
1778 }
1779#endif
1780
f9bf01c6 1781#if CPU(X86_64)
9dae56ea
A
1782 // Quad-word-sized operands:
1783 //
1784 // Used to format 64-bit operantions, planting a REX.w prefix.
1785 // When planting d64 or f64 instructions, not requiring a REX.w prefix,
1786 // the normal (non-'64'-postfixed) formatters should be used.
1787
1788 void oneByteOp64(OneByteOpcodeID opcode)
1789 {
1790 m_buffer.ensureSpace(maxInstructionSize);
1791 emitRexW(0, 0, 0);
1792 m_buffer.putByteUnchecked(opcode);
1793 }
1794
1795 void oneByteOp64(OneByteOpcodeID opcode, RegisterID reg)
1796 {
1797 m_buffer.ensureSpace(maxInstructionSize);
1798 emitRexW(0, 0, reg);
1799 m_buffer.putByteUnchecked(opcode + (reg & 7));
1800 }
1801
1802 void oneByteOp64(OneByteOpcodeID opcode, int reg, RegisterID rm)
1803 {
1804 m_buffer.ensureSpace(maxInstructionSize);
1805 emitRexW(reg, 0, rm);
1806 m_buffer.putByteUnchecked(opcode);
1807 registerModRM(reg, rm);
1808 }
1809
1810 void oneByteOp64(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
1811 {
1812 m_buffer.ensureSpace(maxInstructionSize);
1813 emitRexW(reg, 0, base);
1814 m_buffer.putByteUnchecked(opcode);
1815 memoryModRM(reg, base, offset);
1816 }
1817
1818 void oneByteOp64_disp32(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
1819 {
1820 m_buffer.ensureSpace(maxInstructionSize);
1821 emitRexW(reg, 0, base);
1822 m_buffer.putByteUnchecked(opcode);
1823 memoryModRM_disp32(reg, base, offset);
1824 }
1825
1826 void oneByteOp64(OneByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
1827 {
1828 m_buffer.ensureSpace(maxInstructionSize);
1829 emitRexW(reg, index, base);
1830 m_buffer.putByteUnchecked(opcode);
1831 memoryModRM(reg, base, index, scale, offset);
1832 }
1833
1834 void twoByteOp64(TwoByteOpcodeID opcode, int reg, RegisterID rm)
1835 {
1836 m_buffer.ensureSpace(maxInstructionSize);
1837 emitRexW(reg, 0, rm);
1838 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
1839 m_buffer.putByteUnchecked(opcode);
1840 registerModRM(reg, rm);
1841 }
1842#endif
1843
1844 // Byte-operands:
1845 //
1846 // These methods format byte operations. Byte operations differ from the normal
1847 // formatters in the circumstances under which they will decide to emit REX prefixes.
1848 // These should be used where any register operand signifies a byte register.
1849 //
1850 // The disctinction is due to the handling of register numbers in the range 4..7 on
1851 // x86-64. These register numbers may either represent the second byte of the first
1852 // four registers (ah..bh) or the first byte of the second four registers (spl..dil).
1853 //
1854 // Since ah..bh cannot be used in all permutations of operands (specifically cannot
1855 // be accessed where a REX prefix is present), these are likely best treated as
1856 // deprecated. In order to ensure the correct registers spl..dil are selected a
1857 // REX prefix will be emitted for any byte register operand in the range 4..15.
1858 //
1859 // These formatters may be used in instructions where a mix of operand sizes, in which
1860 // case an unnecessary REX will be emitted, for example:
1861 // movzbl %al, %edi
1862 // In this case a REX will be planted since edi is 7 (and were this a byte operand
1863 // a REX would be required to specify dil instead of bh). Unneeded REX prefixes will
1864 // be silently ignored by the processor.
1865 //
1866 // Address operands should still be checked using regRequiresRex(), while byteRegRequiresRex()
1867 // is provided to check byte register operands.
1868
1869 void oneByteOp8(OneByteOpcodeID opcode, GroupOpcodeID groupOp, RegisterID rm)
1870 {
1871 m_buffer.ensureSpace(maxInstructionSize);
1872 emitRexIf(byteRegRequiresRex(rm), 0, 0, rm);
1873 m_buffer.putByteUnchecked(opcode);
1874 registerModRM(groupOp, rm);
1875 }
1876
1877 void twoByteOp8(TwoByteOpcodeID opcode, RegisterID reg, RegisterID rm)
1878 {
1879 m_buffer.ensureSpace(maxInstructionSize);
1880 emitRexIf(byteRegRequiresRex(reg)|byteRegRequiresRex(rm), reg, 0, rm);
1881 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
1882 m_buffer.putByteUnchecked(opcode);
1883 registerModRM(reg, rm);
1884 }
1885
1886 void twoByteOp8(TwoByteOpcodeID opcode, GroupOpcodeID groupOp, RegisterID rm)
1887 {
1888 m_buffer.ensureSpace(maxInstructionSize);
1889 emitRexIf(byteRegRequiresRex(rm), 0, 0, rm);
1890 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
1891 m_buffer.putByteUnchecked(opcode);
1892 registerModRM(groupOp, rm);
1893 }
1894
1895 // Immediates:
1896 //
1897 // An immedaite should be appended where appropriate after an op has been emitted.
1898 // The writes are unchecked since the opcode formatters above will have ensured space.
1899
1900 void immediate8(int imm)
1901 {
1902 m_buffer.putByteUnchecked(imm);
1903 }
1904
ba379fdc
A
1905 void immediate16(int imm)
1906 {
1907 m_buffer.putShortUnchecked(imm);
1908 }
1909
9dae56ea
A
1910 void immediate32(int imm)
1911 {
1912 m_buffer.putIntUnchecked(imm);
1913 }
1914
1915 void immediate64(int64_t imm)
1916 {
1917 m_buffer.putInt64Unchecked(imm);
1918 }
1919
1920 JmpSrc immediateRel32()
1921 {
1922 m_buffer.putIntUnchecked(0);
1923 return JmpSrc(m_buffer.size());
1924 }
1925
1926 // Administrative methods:
1927
1928 size_t size() const { return m_buffer.size(); }
1929 bool isAligned(int alignment) const { return m_buffer.isAligned(alignment); }
1930 void* data() const { return m_buffer.data(); }
1931 void* executableCopy(ExecutablePool* allocator) { return m_buffer.executableCopy(allocator); }
1932
1933 private:
1934
1935 // Internals; ModRm and REX formatters.
1936
f9bf01c6
A
1937 static const RegisterID noBase = X86Registers::ebp;
1938 static const RegisterID hasSib = X86Registers::esp;
1939 static const RegisterID noIndex = X86Registers::esp;
1940#if CPU(X86_64)
1941 static const RegisterID noBase2 = X86Registers::r13;
1942 static const RegisterID hasSib2 = X86Registers::r12;
9dae56ea
A
1943
1944 // Registers r8 & above require a REX prefixe.
1945 inline bool regRequiresRex(int reg)
1946 {
f9bf01c6 1947 return (reg >= X86Registers::r8);
9dae56ea
A
1948 }
1949
1950 // Byte operand register spl & above require a REX prefix (to prevent the 'H' registers be accessed).
1951 inline bool byteRegRequiresRex(int reg)
1952 {
f9bf01c6 1953 return (reg >= X86Registers::esp);
9dae56ea
A
1954 }
1955
1956 // Format a REX prefix byte.
1957 inline void emitRex(bool w, int r, int x, int b)
1958 {
1959 m_buffer.putByteUnchecked(PRE_REX | ((int)w << 3) | ((r>>3)<<2) | ((x>>3)<<1) | (b>>3));
1960 }
1961
1962 // Used to plant a REX byte with REX.w set (for 64-bit operations).
1963 inline void emitRexW(int r, int x, int b)
1964 {
1965 emitRex(true, r, x, b);
1966 }
1967
1968 // Used for operations with byte operands - use byteRegRequiresRex() to check register operands,
1969 // regRequiresRex() to check other registers (i.e. address base & index).
1970 inline void emitRexIf(bool condition, int r, int x, int b)
1971 {
1972 if (condition) emitRex(false, r, x, b);
1973 }
1974
1975 // Used for word sized operations, will plant a REX prefix if necessary (if any register is r8 or above).
1976 inline void emitRexIfNeeded(int r, int x, int b)
1977 {
1978 emitRexIf(regRequiresRex(r) || regRequiresRex(x) || regRequiresRex(b), r, x, b);
1979 }
1980#else
1981 // No REX prefix bytes on 32-bit x86.
1982 inline bool regRequiresRex(int) { return false; }
1983 inline bool byteRegRequiresRex(int) { return false; }
1984 inline void emitRexIf(bool, int, int, int) {}
1985 inline void emitRexIfNeeded(int, int, int) {}
1986#endif
1987
1988 enum ModRmMode {
1989 ModRmMemoryNoDisp,
1990 ModRmMemoryDisp8,
1991 ModRmMemoryDisp32,
1992 ModRmRegister,
1993 };
1994
1995 void putModRm(ModRmMode mode, int reg, RegisterID rm)
1996 {
1997 m_buffer.putByteUnchecked((mode << 6) | ((reg & 7) << 3) | (rm & 7));
1998 }
1999
2000 void putModRmSib(ModRmMode mode, int reg, RegisterID base, RegisterID index, int scale)
2001 {
2002 ASSERT(mode != ModRmRegister);
2003
9dae56ea 2004 putModRm(mode, reg, hasSib);
ba379fdc 2005 m_buffer.putByteUnchecked((scale << 6) | ((index & 7) << 3) | (base & 7));
9dae56ea
A
2006 }
2007
2008 void registerModRM(int reg, RegisterID rm)
2009 {
2010 putModRm(ModRmRegister, reg, rm);
2011 }
2012
2013 void memoryModRM(int reg, RegisterID base, int offset)
2014 {
2015 // A base of esp or r12 would be interpreted as a sib, so force a sib with no index & put the base in there.
f9bf01c6 2016#if CPU(X86_64)
9dae56ea
A
2017 if ((base == hasSib) || (base == hasSib2)) {
2018#else
2019 if (base == hasSib) {
2020#endif
2021 if (!offset) // No need to check if the base is noBase, since we know it is hasSib!
2022 putModRmSib(ModRmMemoryNoDisp, reg, base, noIndex, 0);
2023 else if (CAN_SIGN_EXTEND_8_32(offset)) {
2024 putModRmSib(ModRmMemoryDisp8, reg, base, noIndex, 0);
2025 m_buffer.putByteUnchecked(offset);
2026 } else {
2027 putModRmSib(ModRmMemoryDisp32, reg, base, noIndex, 0);
2028 m_buffer.putIntUnchecked(offset);
2029 }
2030 } else {
f9bf01c6 2031#if CPU(X86_64)
9dae56ea
A
2032 if (!offset && (base != noBase) && (base != noBase2))
2033#else
2034 if (!offset && (base != noBase))
2035#endif
2036 putModRm(ModRmMemoryNoDisp, reg, base);
2037 else if (CAN_SIGN_EXTEND_8_32(offset)) {
2038 putModRm(ModRmMemoryDisp8, reg, base);
2039 m_buffer.putByteUnchecked(offset);
2040 } else {
2041 putModRm(ModRmMemoryDisp32, reg, base);
2042 m_buffer.putIntUnchecked(offset);
2043 }
2044 }
2045 }
2046
2047 void memoryModRM_disp32(int reg, RegisterID base, int offset)
2048 {
2049 // A base of esp or r12 would be interpreted as a sib, so force a sib with no index & put the base in there.
f9bf01c6 2050#if CPU(X86_64)
9dae56ea
A
2051 if ((base == hasSib) || (base == hasSib2)) {
2052#else
2053 if (base == hasSib) {
2054#endif
2055 putModRmSib(ModRmMemoryDisp32, reg, base, noIndex, 0);
2056 m_buffer.putIntUnchecked(offset);
2057 } else {
2058 putModRm(ModRmMemoryDisp32, reg, base);
2059 m_buffer.putIntUnchecked(offset);
2060 }
2061 }
2062
2063 void memoryModRM(int reg, RegisterID base, RegisterID index, int scale, int offset)
2064 {
2065 ASSERT(index != noIndex);
2066
f9bf01c6 2067#if CPU(X86_64)
9dae56ea
A
2068 if (!offset && (base != noBase) && (base != noBase2))
2069#else
2070 if (!offset && (base != noBase))
2071#endif
2072 putModRmSib(ModRmMemoryNoDisp, reg, base, index, scale);
2073 else if (CAN_SIGN_EXTEND_8_32(offset)) {
2074 putModRmSib(ModRmMemoryDisp8, reg, base, index, scale);
2075 m_buffer.putByteUnchecked(offset);
2076 } else {
2077 putModRmSib(ModRmMemoryDisp32, reg, base, index, scale);
2078 m_buffer.putIntUnchecked(offset);
2079 }
2080 }
2081
f9bf01c6 2082#if !CPU(X86_64)
4e4e5a6f 2083 void memoryModRM(int reg, const void* address)
9dae56ea
A
2084 {
2085 // noBase + ModRmMemoryNoDisp means noBase + ModRmMemoryDisp32!
2086 putModRm(ModRmMemoryNoDisp, reg, noBase);
2087 m_buffer.putIntUnchecked(reinterpret_cast<int32_t>(address));
2088 }
2089#endif
2090
2091 AssemblerBuffer m_buffer;
2092 } m_formatter;
2093};
2094
2095} // namespace JSC
2096
f9bf01c6 2097#endif // ENABLE(ASSEMBLER) && CPU(X86)
9dae56ea
A
2098
2099#endif // X86Assembler_h