source: webkit/trunk/JavaScriptCore/assembler/X86Assembler.h@ 52729

Last change on this file since 52729 was 52729, checked in by [email protected], 15 years ago

2010-01-04 Maciej Stachowiak <[email protected]>

Reviewed by Adam Barth.

Reorganize, document and rename CPU() platform macros.
https://bugs.webkit.org/show_bug.cgi?id=33145
ExecutableAllocatorSymbian appears to have buggy ARM version check
https://bugs.webkit.org/show_bug.cgi?id=33138


  • wtf/Platform.h: Rename all macros related to detection of particular CPUs or classes of CPUs to CPU(), reorganize and document them.

All remaining changes are adapting to the renames, plus fixing the
second bug cited above.


  • assembler/ARMAssembler.cpp:
  • assembler/ARMAssembler.h:
  • assembler/ARMv7Assembler.h:
  • assembler/AbstractMacroAssembler.h: (JSC::AbstractMacroAssembler::Imm32::Imm32):
  • assembler/MacroAssembler.h:
  • assembler/MacroAssemblerARM.cpp:
  • assembler/MacroAssemblerARM.h:
  • assembler/MacroAssemblerCodeRef.h: (JSC::MacroAssemblerCodePtr::MacroAssemblerCodePtr):
  • assembler/MacroAssemblerX86.h:
  • assembler/MacroAssemblerX86Common.h:
  • assembler/MacroAssemblerX86_64.h:
  • assembler/X86Assembler.h: (JSC::X86Registers::): (JSC::X86Assembler::): (JSC::X86Assembler::movl_mEAX): (JSC::X86Assembler::movl_EAXm): (JSC::X86Assembler::repatchLoadPtrToLEA): (JSC::X86Assembler::X86InstructionFormatter::memoryModRM):
  • jit/ExecutableAllocator.h:
  • jit/ExecutableAllocatorFixedVMPool.cpp:
  • jit/ExecutableAllocatorPosix.cpp:
  • jit/ExecutableAllocatorSymbian.cpp: (JSC::ExecutableAllocator::intializePageSize):
  • jit/JIT.cpp:
  • jit/JIT.h:
  • jit/JITArithmetic.cpp:
  • jit/JITInlineMethods.h: (JSC::JIT::beginUninterruptedSequence): (JSC::JIT::restoreArgumentReferenceForTrampoline): (JSC::JIT::emitCount):
  • jit/JITOpcodes.cpp: (JSC::JIT::privateCompileCTIMachineTrampolines):
  • jit/JITPropertyAccess.cpp: (JSC::JIT::privateCompileGetByIdProto): (JSC::JIT::privateCompileGetByIdProtoList): (JSC::JIT::privateCompileGetByIdChainList): (JSC::JIT::privateCompileGetByIdChain):
  • jit/JITStubs.cpp: (JSC::JITThunks::JITThunks):
  • jit/JITStubs.h:
  • runtime/Collector.cpp: (JSC::currentThreadStackBase): (JSC::getPlatformThreadRegisters): (JSC::otherThreadStackPointer):
  • wrec/WREC.h:
  • wrec/WRECGenerator.cpp: (JSC::WREC::Generator::generateEnter): (JSC::WREC::Generator::generateReturnSuccess): (JSC::WREC::Generator::generateReturnFailure):
  • wrec/WRECGenerator.h:
  • wtf/FastMalloc.cpp:
  • wtf/TCSpinLock.h: (TCMalloc_SpinLock::Lock): (TCMalloc_SpinLock::Unlock): (TCMalloc_SlowLock):
  • wtf/Threading.h:
  • wtf/dtoa.cpp:
  • yarr/RegexJIT.cpp: (JSC::Yarr::RegexGenerator::generateEnter): (JSC::Yarr::RegexGenerator::generateReturn):
  • yarr/RegexJIT.h:

2010-01-04 Maciej Stachowiak <[email protected]>

Reviewed by Adam Barth.

Reorganize, document and rename CPU() platform macros.
https://bugs.webkit.org/show_bug.cgi?id=33145

  • webkit/webkitwebsettings.cpp: (webkit_get_user_agent):

2010-01-04 Maciej Stachowiak <[email protected]>

Reviewed by Adam Barth.

Reorganize, document and rename CPU() platform macros.
https://bugs.webkit.org/show_bug.cgi?id=33145

  • page/NavigatorBase.cpp:
  • platform/text/AtomicString.cpp: (WebCore::equal):
  • platform/text/StringHash.h: (WebCore::StringHash::equal):
File size: 60.4 KB
Line 
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
38namespace JSC {
39
40inline bool CAN_SIGN_EXTEND_8_32(int32_t value) { return value == (int32_t)(signed char)value; }
41
42namespace 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
77class X86Assembler {
78public:
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
105private:
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
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
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;
219public:
220
221 class JmpSrc {
222 friend class X86Assembler;
223 friend class X86InstructionFormatter;
224 public:
225 JmpSrc()
226 : m_offset(-1)
227 {
228 }
229
230 private:
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:
243 JmpDst()
244 : m_offset(-1)
245 , m_used(false)
246 {
247 }
248
249 bool isUsed() const { return m_used; }
250 void used() { m_used = true; }
251 private:
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
263 X86Assembler()
264 {
265 }
266
267 size_t size() const { return m_formatter.size(); }
268
269 // Stack operations:
270
271 void push_r(RegisterID reg)
272 {
273 m_formatter.oneByteOp(OP_PUSH_EAX, reg);
274 }
275
276 void pop_r(RegisterID reg)
277 {
278 m_formatter.oneByteOp(OP_POP_EAX, reg);
279 }
280
281 void push_i32(int imm)
282 {
283 m_formatter.oneByteOp(OP_PUSH_Iz);
284 m_formatter.immediate32(imm);
285 }
286
287 void push_m(int offset, RegisterID base)
288 {
289 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_PUSH, base, offset);
290 }
291
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)
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
312 void addl_rr(RegisterID src, RegisterID dst)
313 {
314 m_formatter.oneByteOp(OP_ADD_EvGv, src, dst);
315 }
316
317 void addl_mr(int offset, RegisterID base, RegisterID dst)
318 {
319 m_formatter.oneByteOp(OP_ADD_GvEv, dst, base, offset);
320 }
321
322 void addl_rm(RegisterID src, int offset, RegisterID base)
323 {
324 m_formatter.oneByteOp(OP_ADD_EvGv, src, base, offset);
325 }
326
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
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)
350 void addq_rr(RegisterID src, RegisterID dst)
351 {
352 m_formatter.oneByteOp64(OP_ADD_EvGv, src, dst);
353 }
354
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
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
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
389 void andl_rr(RegisterID src, RegisterID dst)
390 {
391 m_formatter.oneByteOp(OP_AND_EvGv, src, dst);
392 }
393
394 void andl_mr(int offset, RegisterID base, RegisterID dst)
395 {
396 m_formatter.oneByteOp(OP_AND_GvEv, dst, base, offset);
397 }
398
399 void andl_rm(RegisterID src, int offset, RegisterID base)
400 {
401 m_formatter.oneByteOp(OP_AND_EvGv, src, base, offset);
402 }
403
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
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)
427 void andq_rr(RegisterID src, RegisterID dst)
428 {
429 m_formatter.oneByteOp64(OP_AND_EvGv, src, dst);
430 }
431
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
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
455 void negl_r(RegisterID dst)
456 {
457 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NEG, dst);
458 }
459
460 void negl_m(int offset, RegisterID base)
461 {
462 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NEG, base, offset);
463 }
464
465 void notl_r(RegisterID dst)
466 {
467 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NOT, dst);
468 }
469
470 void notl_m(int offset, RegisterID base)
471 {
472 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NOT, base, offset);
473 }
474
475 void orl_rr(RegisterID src, RegisterID dst)
476 {
477 m_formatter.oneByteOp(OP_OR_EvGv, src, dst);
478 }
479
480 void orl_mr(int offset, RegisterID base, RegisterID dst)
481 {
482 m_formatter.oneByteOp(OP_OR_GvEv, dst, base, offset);
483 }
484
485 void orl_rm(RegisterID src, int offset, RegisterID base)
486 {
487 m_formatter.oneByteOp(OP_OR_EvGv, src, base, offset);
488 }
489
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
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)
513 void orq_rr(RegisterID src, RegisterID dst)
514 {
515 m_formatter.oneByteOp64(OP_OR_EvGv, src, dst);
516 }
517
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
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
541 void subl_rr(RegisterID src, RegisterID dst)
542 {
543 m_formatter.oneByteOp(OP_SUB_EvGv, src, dst);
544 }
545
546 void subl_mr(int offset, RegisterID base, RegisterID dst)
547 {
548 m_formatter.oneByteOp(OP_SUB_GvEv, dst, base, offset);
549 }
550
551 void subl_rm(RegisterID src, int offset, RegisterID base)
552 {
553 m_formatter.oneByteOp(OP_SUB_EvGv, src, base, offset);
554 }
555
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
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)
579 void subq_rr(RegisterID src, RegisterID dst)
580 {
581 m_formatter.oneByteOp64(OP_SUB_EvGv, src, dst);
582 }
583
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
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
607 void xorl_rr(RegisterID src, RegisterID dst)
608 {
609 m_formatter.oneByteOp(OP_XOR_EvGv, src, dst);
610 }
611
612 void xorl_mr(int offset, RegisterID base, RegisterID dst)
613 {
614 m_formatter.oneByteOp(OP_XOR_GvEv, dst, base, offset);
615 }
616
617 void xorl_rm(RegisterID src, int offset, RegisterID base)
618 {
619 m_formatter.oneByteOp(OP_XOR_EvGv, src, base, offset);
620 }
621
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
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)
645 void xorq_rr(RegisterID src, RegisterID dst)
646 {
647 m_formatter.oneByteOp64(OP_XOR_EvGv, src, dst);
648 }
649
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
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
672 void sarl_CLr(RegisterID dst)
673 {
674 m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SAR, dst);
675 }
676
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
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)
693 void sarq_CLr(RegisterID dst)
694 {
695 m_formatter.oneByteOp64(OP_GROUP2_EvCL, GROUP2_OP_SAR, dst);
696 }
697
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
709 void imull_rr(RegisterID src, RegisterID dst)
710 {
711 m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, src);
712 }
713
714 void imull_mr(int offset, RegisterID base, RegisterID dst)
715 {
716 m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, base, offset);
717 }
718
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
725 void idivl_r(RegisterID dst)
726 {
727 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_IDIV, dst);
728 }
729
730 // Comparisons:
731
732 void cmpl_rr(RegisterID src, RegisterID dst)
733 {
734 m_formatter.oneByteOp(OP_CMP_EvGv, src, dst);
735 }
736
737 void cmpl_rm(RegisterID src, int offset, RegisterID base)
738 {
739 m_formatter.oneByteOp(OP_CMP_EvGv, src, base, offset);
740 }
741
742 void cmpl_mr(int offset, RegisterID base, RegisterID src)
743 {
744 m_formatter.oneByteOp(OP_CMP_GvEv, src, base, offset);
745 }
746
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
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
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
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
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)
793 void cmpq_rr(RegisterID src, RegisterID dst)
794 {
795 m_formatter.oneByteOp64(OP_CMP_EvGv, src, dst);
796 }
797
798 void cmpq_rm(RegisterID src, int offset, RegisterID base)
799 {
800 m_formatter.oneByteOp64(OP_CMP_EvGv, src, base, offset);
801 }
802
803 void cmpq_mr(int offset, RegisterID base, RegisterID src)
804 {
805 m_formatter.oneByteOp64(OP_CMP_GvEv, src, base, offset);
806 }
807
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
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
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
841 void cmpl_rm(RegisterID reg, void* addr)
842 {
843 m_formatter.oneByteOp(OP_CMP_EvGv, reg, addr);
844 }
845
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
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
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
877 void testl_rr(RegisterID src, RegisterID dst)
878 {
879 m_formatter.oneByteOp(OP_TEST_EvGv, src, dst);
880 }
881
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
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
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)
901 void testq_rr(RegisterID src, RegisterID dst)
902 {
903 m_formatter.oneByteOp64(OP_TEST_EvGv, src, dst);
904 }
905
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
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
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
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
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
937 void setCC_r(Condition cond, RegisterID dst)
938 {
939 m_formatter.twoByteOp8(setccOpcode(cond), (GroupOpcodeID)0, dst);
940 }
941
942 void sete_r(RegisterID dst)
943 {
944 m_formatter.twoByteOp8(setccOpcode(ConditionE), (GroupOpcodeID)0, dst);
945 }
946
947 void setz_r(RegisterID dst)
948 {
949 sete_r(dst);
950 }
951
952 void setne_r(RegisterID dst)
953 {
954 m_formatter.twoByteOp8(setccOpcode(ConditionNE), (GroupOpcodeID)0, dst);
955 }
956
957 void setnz_r(RegisterID dst)
958 {
959 setne_r(dst);
960 }
961
962 // Various move ops:
963
964 void cdq()
965 {
966 m_formatter.oneByteOp(OP_CDQ);
967 }
968
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)
975 void xchgq_rr(RegisterID src, RegisterID dst)
976 {
977 m_formatter.oneByteOp64(OP_XCHG_EvGv, src, dst);
978 }
979#endif
980
981 void movl_rr(RegisterID src, RegisterID dst)
982 {
983 m_formatter.oneByteOp(OP_MOV_EvGv, src, dst);
984 }
985
986 void movl_rm(RegisterID src, int offset, RegisterID base)
987 {
988 m_formatter.oneByteOp(OP_MOV_EvGv, src, base, offset);
989 }
990
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
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
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
1011 void movl_mr(int offset, RegisterID base, RegisterID dst)
1012 {
1013 m_formatter.oneByteOp(OP_MOV_GvEv, dst, base, offset);
1014 }
1015
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
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
1026 void movl_i32r(int imm, RegisterID dst)
1027 {
1028 m_formatter.oneByteOp(OP_MOV_EAXIv, dst);
1029 m_formatter.immediate32(imm);
1030 }
1031
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
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)
1049 void movq_rr(RegisterID src, RegisterID dst)
1050 {
1051 m_formatter.oneByteOp64(OP_MOV_EvGv, src, dst);
1052 }
1053
1054 void movq_rm(RegisterID src, int offset, RegisterID base)
1055 {
1056 m_formatter.oneByteOp64(OP_MOV_EvGv, src, base, offset);
1057 }
1058
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
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
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
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
1081 void movq_mr(int offset, RegisterID base, RegisterID dst)
1082 {
1083 m_formatter.oneByteOp64(OP_MOV_GvEv, dst, base, offset);
1084 }
1085
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
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
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
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
1108 void movsxd_rr(RegisterID src, RegisterID dst)
1109 {
1110 m_formatter.oneByteOp64(OP_MOVSXD_GvEv, dst, src);
1111 }
1112
1113
1114#else
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
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
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
1138 void movzwl_mr(int offset, RegisterID base, RegisterID dst)
1139 {
1140 m_formatter.twoByteOp(OP2_MOVZX_GvEw, dst, base, offset);
1141 }
1142
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
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
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)
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
1169 JmpSrc call()
1170 {
1171 m_formatter.oneByteOp(OP_CALL_rel32);
1172 return m_formatter.immediateRel32();
1173 }
1174
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
1181 void call_m(int offset, RegisterID base)
1182 {
1183 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_CALLN, base, offset);
1184 }
1185
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. :-/
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
1201 void jmp_m(int offset, RegisterID base)
1202 {
1203 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, base, offset);
1204 }
1205
1206 JmpSrc jne()
1207 {
1208 m_formatter.twoByteOp(jccRel32(ConditionNE));
1209 return m_formatter.immediateRel32();
1210 }
1211
1212 JmpSrc jnz()
1213 {
1214 return jne();
1215 }
1216
1217 JmpSrc je()
1218 {
1219 m_formatter.twoByteOp(jccRel32(ConditionE));
1220 return m_formatter.immediateRel32();
1221 }
1222
1223 JmpSrc jz()
1224 {
1225 return je();
1226 }
1227
1228 JmpSrc jl()
1229 {
1230 m_formatter.twoByteOp(jccRel32(ConditionL));
1231 return m_formatter.immediateRel32();
1232 }
1233
1234 JmpSrc jb()
1235 {
1236 m_formatter.twoByteOp(jccRel32(ConditionB));
1237 return m_formatter.immediateRel32();
1238 }
1239
1240 JmpSrc jle()
1241 {
1242 m_formatter.twoByteOp(jccRel32(ConditionLE));
1243 return m_formatter.immediateRel32();
1244 }
1245
1246 JmpSrc jbe()
1247 {
1248 m_formatter.twoByteOp(jccRel32(ConditionBE));
1249 return m_formatter.immediateRel32();
1250 }
1251
1252 JmpSrc jge()
1253 {
1254 m_formatter.twoByteOp(jccRel32(ConditionGE));
1255 return m_formatter.immediateRel32();
1256 }
1257
1258 JmpSrc jg()
1259 {
1260 m_formatter.twoByteOp(jccRel32(ConditionG));
1261 return m_formatter.immediateRel32();
1262 }
1263
1264 JmpSrc ja()
1265 {
1266 m_formatter.twoByteOp(jccRel32(ConditionA));
1267 return m_formatter.immediateRel32();
1268 }
1269
1270 JmpSrc jae()
1271 {
1272 m_formatter.twoByteOp(jccRel32(ConditionAE));
1273 return m_formatter.immediateRel32();
1274 }
1275
1276 JmpSrc jo()
1277 {
1278 m_formatter.twoByteOp(jccRel32(ConditionO));
1279 return m_formatter.immediateRel32();
1280 }
1281
1282 JmpSrc jp()
1283 {
1284 m_formatter.twoByteOp(jccRel32(ConditionP));
1285 return m_formatter.immediateRel32();
1286 }
1287
1288 JmpSrc js()
1289 {
1290 m_formatter.twoByteOp(jccRel32(ConditionS));
1291 return m_formatter.immediateRel32();
1292 }
1293
1294 JmpSrc jCC(Condition cond)
1295 {
1296 m_formatter.twoByteOp(jccRel32(cond));
1297 return m_formatter.immediateRel32();
1298 }
1299
1300 // SSE operations:
1301
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
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
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
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)
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
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
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)
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
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
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
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)
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
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
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
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
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
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
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
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
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
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
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
1443 void int3()
1444 {
1445 m_formatter.oneByteOp(OP_INT3);
1446 }
1447
1448 void ret()
1449 {
1450 m_formatter.oneByteOp(OP_RET);
1451 }
1452
1453 void predictNotTaken()
1454 {
1455 m_formatter.prefix(PRE_PREDICT_BRANCH_NOT_TAKEN);
1456 }
1457
1458 // Assembler admin methods:
1459
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
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
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
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
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
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
1516 static void relinkJump(void* from, void* to)
1517 {
1518 setRel32(from, to);
1519 }
1520
1521 static void relinkCall(void* from, void* to)
1522 {
1523 setRel32(from, to);
1524 }
1525
1526 static void repatchInt32(void* where, int32_t value)
1527 {
1528 setInt32(where, value);
1529 }
1530
1531 static void repatchPointer(void* where, void* value)
1532 {
1533 setPointer(where, value);
1534 }
1535
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
1546 static unsigned getCallReturnOffset(JmpSrc call)
1547 {
1548 ASSERT(call.m_offset >= 0);
1549 return call.m_offset;
1550 }
1551
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
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
1566 static int getDifferenceBetweenLabels(JmpDst src, JmpDst dst)
1567 {
1568 return dst.m_offset - src.m_offset;
1569 }
1570
1571 static int getDifferenceBetweenLabels(JmpDst src, JmpSrc dst)
1572 {
1573 return dst.m_offset - src.m_offset;
1574 }
1575
1576 static int getDifferenceBetweenLabels(JmpSrc src, JmpDst dst)
1577 {
1578 return dst.m_offset - src.m_offset;
1579 }
1580
1581 void* executableCopy(ExecutablePool* allocator)
1582 {
1583 void* copy = m_formatter.executableCopy(allocator);
1584 ASSERT(copy);
1585 return copy;
1586 }
1587
1588private:
1589
1590 static void setPointer(void* where, void* value)
1591 {
1592 reinterpret_cast<void**>(where)[-1] = value;
1593 }
1594
1595 static void setInt32(void* where, int32_t value)
1596 {
1597 reinterpret_cast<int32_t*>(where)[-1] = value;
1598 }
1599
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
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
1637 void oneByteOp(OneByteOpcodeID opcode)
1638 {
1639 m_buffer.ensureSpace(maxInstructionSize);
1640 m_buffer.putByteUnchecked(opcode);
1641 }
1642
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
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
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
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
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)
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
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
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
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
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)
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
1742 void oneByteOp64(OneByteOpcodeID opcode)
1743 {
1744 m_buffer.ensureSpace(maxInstructionSize);
1745 emitRexW(0, 0, 0);
1746 m_buffer.putByteUnchecked(opcode);
1747 }
1748
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
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
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
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
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
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
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
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
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
1854 void immediate8(int imm)
1855 {
1856 m_buffer.putByteUnchecked(imm);
1857 }
1858
1859 void immediate16(int imm)
1860 {
1861 m_buffer.putShortUnchecked(imm);
1862 }
1863
1864 void immediate32(int imm)
1865 {
1866 m_buffer.putIntUnchecked(imm);
1867 }
1868
1869 void immediate64(int64_t imm)
1870 {
1871 m_buffer.putInt64Unchecked(imm);
1872 }
1873
1874 JmpSrc immediateRel32()
1875 {
1876 m_buffer.putIntUnchecked(0);
1877 return JmpSrc(m_buffer.size());
1878 }
1879
1880 // Administrative methods:
1881
1882 size_t size() const { return m_buffer.size(); }
1883 bool isAligned(int alignment) const { return m_buffer.isAligned(alignment); }
1884 void* data() const { return m_buffer.data(); }
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.
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).
1905 inline bool byteRegRequiresRex(int reg)
1906 {
1907 return (reg >= X86Registers::esp);
1908 }
1909
1910 // Format a REX prefix byte.
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).
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).
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).
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.
1936 inline bool regRequiresRex(int) { return false; }
1937 inline bool byteRegRequiresRex(int) { return false; }
1938 inline void emitRexIf(bool, 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
1949 void putModRm(ModRmMode mode, int reg, RegisterID rm)
1950 {
1951 m_buffer.putByteUnchecked((mode << 6) | ((reg & 7) << 3) | (rm & 7));
1952 }
1953
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
1962 void registerModRM(int reg, RegisterID rm)
1963 {
1964 putModRm(ModRmRegister, reg, rm);
1965 }
1966
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
Note: See TracBrowser for help on using the repository browser.