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