1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * vim: set ts=8 sw=4 et tw=79:
3 : *
4 : * ***** BEGIN LICENSE BLOCK *****
5 : * Copyright (C) 2008 Apple Inc. All rights reserved.
6 : *
7 : * Redistribution and use in source and binary forms, with or without
8 : * modification, are permitted provided that the following conditions
9 : * are met:
10 : * 1. Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : * 2. Redistributions in binary form must reproduce the above copyright
13 : * notice, this list of conditions and the following disclaimer in the
14 : * documentation and/or other materials provided with the distribution.
15 : *
16 : * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
17 : * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 : * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
20 : * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 : * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 : * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 : * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
24 : * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 : * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 : *
28 : * ***** END LICENSE BLOCK ***** */
29 :
30 : #ifndef X86Assembler_h
31 : #define X86Assembler_h
32 :
33 : #include "assembler/wtf/Platform.h"
34 :
35 : #if ENABLE_ASSEMBLER && (WTF_CPU_X86 || WTF_CPU_X86_64)
36 :
37 : #include "AssemblerBuffer.h"
38 : #include "assembler/wtf/Assertions.h"
39 : #include "js/Vector.h"
40 :
41 : #include "methodjit/Logging.h"
42 : #define IPFX " %s"
43 : #define ISPFX " "
44 : #ifdef JS_METHODJIT_SPEW
45 : # define MAYBE_PAD (isOOLPath ? "> " : "")
46 : # define PRETTY_PRINT_OFFSET(os) (((os)<0)?"-":""), (((os)<0)?-(os):(os))
47 : # define FIXME_INSN_PRINTING \
48 : do { \
49 : js::JaegerSpew(js::JSpew_Insns, \
50 : ISPFX "FIXME insn printing %s:%d\n", \
51 : __FILE__, __LINE__); \
52 : } while (0)
53 : #else
54 : # define MAYBE_PAD ""
55 : # define FIXME_INSN_PRINTING ((void) 0)
56 : # define PRETTY_PRINT_OFFSET(os) "", 0
57 : #endif
58 :
59 :
60 : namespace JSC {
61 :
62 77364335 : inline bool CAN_SIGN_EXTEND_8_32(int32_t value) { return value == (int32_t)(signed char)value; }
63 :
64 : namespace X86Registers {
65 : typedef enum {
66 : eax,
67 : ecx,
68 : edx,
69 : ebx,
70 : esp,
71 : ebp,
72 : esi,
73 : edi
74 :
75 : #if WTF_CPU_X86_64
76 : ,r8,
77 : r9,
78 : r10,
79 : r11,
80 : r12,
81 : r13,
82 : r14,
83 : r15
84 : #endif
85 : } RegisterID;
86 :
87 : typedef enum {
88 : xmm0,
89 : xmm1,
90 : xmm2,
91 : xmm3,
92 : xmm4,
93 : xmm5,
94 : xmm6,
95 : xmm7
96 : } XMMRegisterID;
97 :
98 5689937 : static const char* nameFPReg(XMMRegisterID fpreg)
99 : {
100 : static const char* xmmnames[8]
101 : = { "%xmm0", "%xmm1", "%xmm2", "%xmm3",
102 : "%xmm4", "%xmm5", "%xmm6", "%xmm7" };
103 5689937 : int off = (XMMRegisterID)fpreg - (XMMRegisterID)xmm0;
104 5689937 : return (off < 0 || off > 7) ? "%xmm?" : xmmnames[off];
105 : }
106 :
107 165949353 : static const char* nameIReg(int szB, RegisterID reg)
108 : {
109 : static const char* r64names[16]
110 : = { "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
111 : "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" };
112 : static const char* r32names[16]
113 : = { "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
114 : "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d" };
115 : static const char* r16names[16]
116 : = { "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
117 : "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w" };
118 : static const char* r8names[16]
119 : = { "%al", "%cl", "%dl", "%bl", "%ah/spl", "%ch/bpl", "%dh/sil", "%bh/dil",
120 : "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b" };
121 165949353 : int off = (RegisterID)reg - (RegisterID)eax;
122 165949353 : const char** tab = r64names;
123 165949353 : switch (szB) {
124 58080 : case 1: tab = r8names; break;
125 78 : case 2: tab = r16names; break;
126 165891195 : case 4: tab = r32names; break;
127 : }
128 165949353 : return (off < 0 || off > 15) ? "%r???" : tab[off];
129 : }
130 :
131 75667468 : static const char* nameIReg(RegisterID reg)
132 : {
133 : # if WTF_CPU_X86_64
134 : return nameIReg(8, reg);
135 : # else
136 75667468 : return nameIReg(4, reg);
137 : # endif
138 : }
139 :
140 : } /* namespace X86Registers */
141 :
142 :
143 763316 : class X86Assembler {
144 : public:
145 : typedef X86Registers::RegisterID RegisterID;
146 : typedef X86Registers::XMMRegisterID XMMRegisterID;
147 : typedef XMMRegisterID FPRegisterID;
148 :
149 : typedef enum {
150 : ConditionO,
151 : ConditionNO,
152 : ConditionB,
153 : ConditionAE,
154 : ConditionE,
155 : ConditionNE,
156 : ConditionBE,
157 : ConditionA,
158 : ConditionS,
159 : ConditionNS,
160 : ConditionP,
161 : ConditionNP,
162 : ConditionL,
163 : ConditionGE,
164 : ConditionLE,
165 : ConditionG,
166 :
167 : ConditionC = ConditionB,
168 : ConditionNC = ConditionAE
169 : } Condition;
170 :
171 9059274 : static const char* nameCC(Condition cc)
172 : {
173 : static const char* names[16]
174 : = { "o ", "no", "b ", "ae", "e ", "ne", "be", "a ",
175 : "s ", "ns", "p ", "np", "l ", "ge", "le", "g " };
176 9059274 : int ix = (int)cc;
177 9059274 : return (ix < 0 || ix > 15) ? "??" : names[ix];
178 : }
179 :
180 : private:
181 : typedef enum {
182 : OP_ADD_EvGv = 0x01,
183 : OP_ADD_GvEv = 0x03,
184 : OP_OR_EvGv = 0x09,
185 : OP_OR_GvEv = 0x0B,
186 : OP_2BYTE_ESCAPE = 0x0F,
187 : OP_3BYTE_ESCAPE = 0x3A,
188 : OP_AND_EvGv = 0x21,
189 : OP_AND_GvEv = 0x23,
190 : OP_SUB_EvGv = 0x29,
191 : OP_SUB_GvEv = 0x2B,
192 : PRE_PREDICT_BRANCH_NOT_TAKEN = 0x2E,
193 : OP_XOR_EvGv = 0x31,
194 : OP_XOR_GvEv = 0x33,
195 : OP_CMP_EvGv = 0x39,
196 : OP_CMP_GvEv = 0x3B,
197 : #if WTF_CPU_X86_64
198 : PRE_REX = 0x40,
199 : #endif
200 : OP_PUSH_EAX = 0x50,
201 : OP_POP_EAX = 0x58,
202 : #if WTF_CPU_X86
203 : OP_PUSHA = 0x60,
204 : OP_POPA = 0x61,
205 : #endif
206 : #if WTF_CPU_X86_64
207 : OP_MOVSXD_GvEv = 0x63,
208 : #endif
209 : PRE_OPERAND_SIZE = 0x66,
210 : PRE_SSE_66 = 0x66,
211 : OP_PUSH_Iz = 0x68,
212 : OP_IMUL_GvEvIz = 0x69,
213 : OP_GROUP1_EbIb = 0x80,
214 : OP_GROUP1_EvIz = 0x81,
215 : OP_GROUP1_EvIb = 0x83,
216 : OP_TEST_EvGv = 0x85,
217 : OP_XCHG_EvGv = 0x87,
218 : OP_MOV_EbGv = 0x88,
219 : OP_MOV_EvGv = 0x89,
220 : OP_MOV_GvEv = 0x8B,
221 : OP_LEA = 0x8D,
222 : OP_GROUP1A_Ev = 0x8F,
223 : OP_CDQ = 0x99,
224 : OP_MOV_EAXOv = 0xA1,
225 : OP_MOV_OvEAX = 0xA3,
226 : OP_MOV_EAXIv = 0xB8,
227 : OP_GROUP2_EvIb = 0xC1,
228 : OP_RET_Iz = 0xC2,
229 : OP_RET = 0xC3,
230 : OP_GROUP11_EvIb = 0xC6,
231 : OP_GROUP11_EvIz = 0xC7,
232 : OP_INT3 = 0xCC,
233 : OP_GROUP2_Ev1 = 0xD1,
234 : OP_GROUP2_EvCL = 0xD3,
235 : OP_CALL_rel32 = 0xE8,
236 : OP_JMP_rel32 = 0xE9,
237 : PRE_SSE_F2 = 0xF2,
238 : PRE_SSE_F3 = 0xF3,
239 : OP_HLT = 0xF4,
240 : OP_GROUP3_EbIb = 0xF6,
241 : OP_GROUP3_Ev = 0xF7,
242 : OP_GROUP3_EvIz = 0xF7, // OP_GROUP3_Ev has an immediate, when instruction is a test.
243 : OP_GROUP5_Ev = 0xFF
244 : } OneByteOpcodeID;
245 :
246 : typedef enum {
247 : OP2_MOVSD_VsdWsd = 0x10,
248 : OP2_MOVSD_WsdVsd = 0x11,
249 : OP2_UNPCKLPS_VsdWsd = 0x14,
250 : OP2_CVTSI2SD_VsdEd = 0x2A,
251 : OP2_CVTTSD2SI_GdWsd = 0x2C,
252 : OP2_UCOMISD_VsdWsd = 0x2E,
253 : OP2_ADDSD_VsdWsd = 0x58,
254 : OP2_MULSD_VsdWsd = 0x59,
255 : OP2_CVTSS2SD_VsdEd = 0x5A,
256 : OP2_CVTSD2SS_VsdEd = 0x5A,
257 : OP2_SUBSD_VsdWsd = 0x5C,
258 : OP2_DIVSD_VsdWsd = 0x5E,
259 : OP2_SQRTSD_VsdWsd = 0x51,
260 : OP2_ANDPD_VpdWpd = 0x54,
261 : OP2_XORPD_VpdWpd = 0x57,
262 : OP2_MOVD_VdEd = 0x6E,
263 : OP2_PSRLDQ_Vd = 0x73,
264 : OP2_MOVD_EdVd = 0x7E,
265 : OP2_JCC_rel32 = 0x80,
266 : OP_SETCC = 0x90,
267 : OP2_IMUL_GvEv = 0xAF,
268 : OP2_MOVSX_GvEb = 0xBE,
269 : OP2_MOVSX_GvEw = 0xBF,
270 : OP2_MOVZX_GvEb = 0xB6,
271 : OP2_MOVZX_GvEw = 0xB7,
272 : OP2_PEXTRW_GdUdIb = 0xC5
273 : } TwoByteOpcodeID;
274 :
275 : typedef enum {
276 : OP3_PINSRD_VsdWsd = 0x22
277 : } ThreeByteOpcodeID;
278 :
279 9016108 : TwoByteOpcodeID jccRel32(Condition cond)
280 : {
281 9016108 : return (TwoByteOpcodeID)(OP2_JCC_rel32 + cond);
282 : }
283 :
284 43691 : TwoByteOpcodeID setccOpcode(Condition cond)
285 : {
286 43691 : return (TwoByteOpcodeID)(OP_SETCC + cond);
287 : }
288 :
289 : typedef enum {
290 : GROUP1_OP_ADD = 0,
291 : GROUP1_OP_OR = 1,
292 : GROUP1_OP_ADC = 2,
293 : GROUP1_OP_AND = 4,
294 : GROUP1_OP_SUB = 5,
295 : GROUP1_OP_XOR = 6,
296 : GROUP1_OP_CMP = 7,
297 :
298 : GROUP1A_OP_POP = 0,
299 :
300 : GROUP2_OP_SHL = 4,
301 : GROUP2_OP_SHR = 5,
302 : GROUP2_OP_SAR = 7,
303 :
304 : GROUP3_OP_TEST = 0,
305 : GROUP3_OP_NOT = 2,
306 : GROUP3_OP_NEG = 3,
307 : GROUP3_OP_IDIV = 7,
308 :
309 : GROUP5_OP_CALLN = 2,
310 : GROUP5_OP_JMPN = 4,
311 : GROUP5_OP_PUSH = 6,
312 :
313 : GROUP11_MOV = 0
314 : } GroupOpcodeID;
315 :
316 : class X86InstructionFormatter;
317 : public:
318 :
319 : #ifdef JS_METHODJIT_SPEW
320 : bool isOOLPath;
321 : #endif
322 :
323 : class JmpSrc {
324 : friend class X86Assembler;
325 : friend class X86InstructionFormatter;
326 : public:
327 12395158 : JmpSrc()
328 12395158 : : m_offset(-1)
329 : {
330 12395158 : }
331 :
332 : private:
333 23191993 : JmpSrc(int offset)
334 23191993 : : m_offset(offset)
335 : {
336 23191993 : }
337 :
338 : int m_offset;
339 : };
340 :
341 : class JmpDst {
342 : friend class X86Assembler;
343 : friend class X86InstructionFormatter;
344 : public:
345 66857864 : JmpDst()
346 : : m_offset(-1)
347 66857864 : , m_used(false)
348 : {
349 66857864 : }
350 :
351 : bool isUsed() const { return m_used; }
352 : void used() { m_used = true; }
353 716980 : bool isValid() const { return m_offset != -1; }
354 : private:
355 52207431 : JmpDst(int offset)
356 : : m_offset(offset)
357 52207431 : , m_used(false)
358 : {
359 52207431 : ASSERT(m_offset == offset);
360 52207431 : }
361 :
362 : signed int m_offset : 31;
363 : bool m_used : 1;
364 : };
365 :
366 763316 : X86Assembler()
367 : #ifdef JS_METHODJIT_SPEW
368 763316 : : isOOLPath(false)
369 : #endif
370 : {
371 763316 : }
372 :
373 7872076 : size_t size() const { return m_formatter.size(); }
374 : unsigned char *buffer() const { return m_formatter.buffer(); }
375 2260344 : bool oom() const { return m_formatter.oom(); }
376 :
377 : // Stack operations:
378 :
379 233906 : void push_r(RegisterID reg)
380 : {
381 : js::JaegerSpew(js::JSpew_Insns,
382 233906 : IPFX "push %s\n", MAYBE_PAD, nameIReg(reg));
383 233906 : m_formatter.oneByteOp(OP_PUSH_EAX, reg);
384 233906 : }
385 :
386 449850 : void pop_r(RegisterID reg)
387 : {
388 : js::JaegerSpew(js::JSpew_Insns,
389 449850 : IPFX "pop %s\n", MAYBE_PAD, nameIReg(reg));
390 449850 : m_formatter.oneByteOp(OP_POP_EAX, reg);
391 449850 : }
392 :
393 : void push_i32(int imm)
394 : {
395 : js::JaegerSpew(js::JSpew_Insns,
396 : IPFX "pushl %s$0x%x\n", MAYBE_PAD,
397 : PRETTY_PRINT_OFFSET(imm));
398 : m_formatter.oneByteOp(OP_PUSH_Iz);
399 : m_formatter.immediate32(imm);
400 : }
401 :
402 : void push_m(int offset, RegisterID base)
403 : {
404 : js::JaegerSpew(js::JSpew_Insns,
405 : IPFX "push %s0x%x(%s)\n", MAYBE_PAD,
406 : PRETTY_PRINT_OFFSET(offset), nameIReg(base));
407 : m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_PUSH, base, offset);
408 : }
409 :
410 : void pop_m(int offset, RegisterID base)
411 : {
412 : FIXME_INSN_PRINTING;
413 : m_formatter.oneByteOp(OP_GROUP1A_Ev, GROUP1A_OP_POP, base, offset);
414 : }
415 :
416 : // Arithmetic operations:
417 :
418 : #if !WTF_CPU_X86_64
419 : void adcl_im(int imm, void* addr)
420 : {
421 : FIXME_INSN_PRINTING;
422 : if (CAN_SIGN_EXTEND_8_32(imm)) {
423 : m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADC, addr);
424 : m_formatter.immediate8(imm);
425 : } else {
426 : m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADC, addr);
427 : m_formatter.immediate32(imm);
428 : }
429 : }
430 : #endif
431 :
432 328883 : void addl_rr(RegisterID src, RegisterID dst)
433 : {
434 : js::JaegerSpew(js::JSpew_Insns,
435 : IPFX "addl %s, %s\n", MAYBE_PAD,
436 328883 : nameIReg(4,src), nameIReg(4,dst));
437 328883 : m_formatter.oneByteOp(OP_ADD_EvGv, src, dst);
438 328883 : }
439 :
440 276 : void addl_mr(int offset, RegisterID base, RegisterID dst)
441 : {
442 276 : FIXME_INSN_PRINTING;
443 276 : m_formatter.oneByteOp(OP_ADD_GvEv, dst, base, offset);
444 276 : }
445 :
446 : void addl_rm(RegisterID src, int offset, RegisterID base)
447 : {
448 : FIXME_INSN_PRINTING;
449 : m_formatter.oneByteOp(OP_ADD_EvGv, src, base, offset);
450 : }
451 :
452 5647032 : void addl_ir(int imm, RegisterID dst)
453 : {
454 : js::JaegerSpew(js::JSpew_Insns,
455 5647032 : IPFX "addl $0x%x, %s\n", MAYBE_PAD, imm, nameIReg(4,dst));
456 5647032 : if (CAN_SIGN_EXTEND_8_32(imm)) {
457 5615416 : m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, dst);
458 5615416 : m_formatter.immediate8(imm);
459 : } else {
460 31616 : m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, dst);
461 31616 : m_formatter.immediate32(imm);
462 : }
463 5647032 : }
464 :
465 : void addl_im(int imm, int offset, RegisterID base)
466 : {
467 : js::JaegerSpew(js::JSpew_Insns,
468 : IPFX "addl %d, %s0x%x(%s)\n", MAYBE_PAD,
469 : imm, PRETTY_PRINT_OFFSET(offset), nameIReg(8,base));
470 : if (CAN_SIGN_EXTEND_8_32(imm)) {
471 : m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, base, offset);
472 : m_formatter.immediate8(imm);
473 : } else {
474 : m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, base, offset);
475 : m_formatter.immediate32(imm);
476 : }
477 : }
478 :
479 : #if WTF_CPU_X86_64
480 : void addq_rr(RegisterID src, RegisterID dst)
481 : {
482 : FIXME_INSN_PRINTING;
483 : m_formatter.oneByteOp64(OP_ADD_EvGv, src, dst);
484 : }
485 :
486 : void addq_ir(int imm, RegisterID dst)
487 : {
488 : js::JaegerSpew(js::JSpew_Insns,
489 : IPFX "addq $0x%x, %s\n", MAYBE_PAD, imm, nameIReg(8,dst));
490 : if (CAN_SIGN_EXTEND_8_32(imm)) {
491 : m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_ADD, dst);
492 : m_formatter.immediate8(imm);
493 : } else {
494 : m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_ADD, dst);
495 : m_formatter.immediate32(imm);
496 : }
497 : }
498 :
499 : void addq_im(int imm, int offset, RegisterID base)
500 : {
501 : js::JaegerSpew(js::JSpew_Insns,
502 : IPFX "addq $0x%x, %s0x%x(%s)\n", MAYBE_PAD,
503 : imm, PRETTY_PRINT_OFFSET(offset), nameIReg(8,base));
504 : if (CAN_SIGN_EXTEND_8_32(imm)) {
505 : m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_ADD, base, offset);
506 : m_formatter.immediate8(imm);
507 : } else {
508 : m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_ADD, base, offset);
509 : m_formatter.immediate32(imm);
510 : }
511 : }
512 : #else
513 5197 : void addl_im(int imm, void* addr)
514 : {
515 5197 : FIXME_INSN_PRINTING;
516 5197 : if (CAN_SIGN_EXTEND_8_32(imm)) {
517 5197 : m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, addr);
518 5197 : m_formatter.immediate8(imm);
519 : } else {
520 0 : m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, addr);
521 0 : m_formatter.immediate32(imm);
522 : }
523 5197 : }
524 : #endif
525 :
526 914 : void andl_rr(RegisterID src, RegisterID dst)
527 : {
528 : js::JaegerSpew(js::JSpew_Insns,
529 : IPFX "andl %s, %s\n", MAYBE_PAD,
530 914 : nameIReg(4,src), nameIReg(4,dst));
531 914 : m_formatter.oneByteOp(OP_AND_EvGv, src, dst);
532 914 : }
533 :
534 20 : void andl_mr(int offset, RegisterID base, RegisterID dst)
535 : {
536 20 : FIXME_INSN_PRINTING;
537 20 : m_formatter.oneByteOp(OP_AND_GvEv, dst, base, offset);
538 20 : }
539 :
540 : void andl_rm(RegisterID src, int offset, RegisterID base)
541 : {
542 : FIXME_INSN_PRINTING;
543 : m_formatter.oneByteOp(OP_AND_EvGv, src, base, offset);
544 : }
545 :
546 154752 : void andl_ir(int imm, RegisterID dst)
547 : {
548 : js::JaegerSpew(js::JSpew_Insns,
549 154752 : IPFX "andl $0x%x, %s\n", MAYBE_PAD, imm, nameIReg(4,dst));
550 154752 : if (CAN_SIGN_EXTEND_8_32(imm)) {
551 842 : m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, dst);
552 842 : m_formatter.immediate8(imm);
553 : } else {
554 153910 : m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, dst);
555 153910 : m_formatter.immediate32(imm);
556 : }
557 154752 : }
558 :
559 : void andl_im(int imm, int offset, RegisterID base)
560 : {
561 : FIXME_INSN_PRINTING;
562 : if (CAN_SIGN_EXTEND_8_32(imm)) {
563 : m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, base, offset);
564 : m_formatter.immediate8(imm);
565 : } else {
566 : m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, base, offset);
567 : m_formatter.immediate32(imm);
568 : }
569 : }
570 :
571 : #if WTF_CPU_X86_64
572 : void andq_rr(RegisterID src, RegisterID dst)
573 : {
574 : js::JaegerSpew(js::JSpew_Insns,
575 : IPFX "andq %s, %s\n", MAYBE_PAD,
576 : nameIReg(8,src), nameIReg(8,dst));
577 : m_formatter.oneByteOp64(OP_AND_EvGv, src, dst);
578 : }
579 :
580 : void andq_mr(int offset, RegisterID base, RegisterID dst)
581 : {
582 : js::JaegerSpew(js::JSpew_Insns,
583 : IPFX "andq %s0x%x(%s), %s\n", MAYBE_PAD,
584 : PRETTY_PRINT_OFFSET(offset), nameIReg(8,base), nameIReg(8,dst));
585 : m_formatter.oneByteOp64(OP_AND_GvEv, dst, base, offset);
586 : }
587 :
588 : void orq_mr(int offset, RegisterID base, RegisterID dst)
589 : {
590 : js::JaegerSpew(js::JSpew_Insns,
591 : IPFX "orq %s0x%x(%s), %s\n", MAYBE_PAD,
592 : PRETTY_PRINT_OFFSET(offset), nameIReg(8,base), nameIReg(8,dst));
593 : m_formatter.oneByteOp64(OP_OR_GvEv, dst, base, offset);
594 : }
595 :
596 : void andq_ir(int imm, RegisterID dst)
597 : {
598 : js::JaegerSpew(js::JSpew_Insns,
599 : IPFX "andq $0x%x, %s\n", MAYBE_PAD, imm, nameIReg(8,dst));
600 : if (CAN_SIGN_EXTEND_8_32(imm)) {
601 : m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_AND, dst);
602 : m_formatter.immediate8(imm);
603 : } else {
604 : m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_AND, dst);
605 : m_formatter.immediate32(imm);
606 : }
607 : }
608 : #else
609 : void andl_im(int imm, void* addr)
610 : {
611 : FIXME_INSN_PRINTING;
612 : if (CAN_SIGN_EXTEND_8_32(imm)) {
613 : m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, addr);
614 : m_formatter.immediate8(imm);
615 : } else {
616 : m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, addr);
617 : m_formatter.immediate32(imm);
618 : }
619 : }
620 : #endif
621 :
622 21265 : void negl_r(RegisterID dst)
623 : {
624 : js::JaegerSpew(js::JSpew_Insns,
625 21265 : IPFX "negl %s\n", MAYBE_PAD, nameIReg(4,dst));
626 21265 : m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NEG, dst);
627 21265 : }
628 :
629 : void negl_m(int offset, RegisterID base)
630 : {
631 : FIXME_INSN_PRINTING;
632 : m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NEG, base, offset);
633 : }
634 :
635 167 : void notl_r(RegisterID dst)
636 : {
637 : js::JaegerSpew(js::JSpew_Insns,
638 167 : IPFX "notl %s\n", MAYBE_PAD, nameIReg(4,dst));
639 167 : m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NOT, dst);
640 167 : }
641 :
642 : void notl_m(int offset, RegisterID base)
643 : {
644 : FIXME_INSN_PRINTING;
645 : m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NOT, base, offset);
646 : }
647 :
648 2974 : void orl_rr(RegisterID src, RegisterID dst)
649 : {
650 : js::JaegerSpew(js::JSpew_Insns,
651 : IPFX "orl %s, %s\n", MAYBE_PAD,
652 2974 : nameIReg(4,src), nameIReg(4,dst));
653 2974 : m_formatter.oneByteOp(OP_OR_EvGv, src, dst);
654 2974 : }
655 :
656 0 : void orl_mr(int offset, RegisterID base, RegisterID dst)
657 : {
658 0 : FIXME_INSN_PRINTING;
659 0 : m_formatter.oneByteOp(OP_OR_GvEv, dst, base, offset);
660 0 : }
661 :
662 : void orl_rm(RegisterID src, int offset, RegisterID base)
663 : {
664 : FIXME_INSN_PRINTING;
665 : m_formatter.oneByteOp(OP_OR_EvGv, src, base, offset);
666 : }
667 :
668 55295 : void orl_ir(int imm, RegisterID dst)
669 : {
670 : js::JaegerSpew(js::JSpew_Insns,
671 55295 : IPFX "orl $0x%x, %s\n", MAYBE_PAD, imm, nameIReg(4,dst));
672 55295 : if (CAN_SIGN_EXTEND_8_32(imm)) {
673 963 : m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, dst);
674 963 : m_formatter.immediate8(imm);
675 : } else {
676 54332 : m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, dst);
677 54332 : m_formatter.immediate32(imm);
678 : }
679 55295 : }
680 :
681 : void orl_im(int imm, int offset, RegisterID base)
682 : {
683 : FIXME_INSN_PRINTING;
684 : if (CAN_SIGN_EXTEND_8_32(imm)) {
685 : m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, base, offset);
686 : m_formatter.immediate8(imm);
687 : } else {
688 : m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, base, offset);
689 : m_formatter.immediate32(imm);
690 : }
691 : }
692 :
693 : #if WTF_CPU_X86_64
694 : void negq_r(RegisterID dst)
695 : {
696 : js::JaegerSpew(js::JSpew_Insns,
697 : IPFX "negq %s\n", MAYBE_PAD, nameIReg(8,dst));
698 : m_formatter.oneByteOp64(OP_GROUP3_Ev, GROUP3_OP_NEG, dst);
699 : }
700 :
701 : void orq_rr(RegisterID src, RegisterID dst)
702 : {
703 : js::JaegerSpew(js::JSpew_Insns,
704 : IPFX "orq %s, %s\n", MAYBE_PAD,
705 : nameIReg(8,src), nameIReg(8,dst));
706 : m_formatter.oneByteOp64(OP_OR_EvGv, src, dst);
707 : }
708 :
709 : void orq_ir(int imm, RegisterID dst)
710 : {
711 : js::JaegerSpew(js::JSpew_Insns,
712 : IPFX "orq $0x%x, %s\n", MAYBE_PAD, imm, nameIReg(8,dst));
713 : if (CAN_SIGN_EXTEND_8_32(imm)) {
714 : m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_OR, dst);
715 : m_formatter.immediate8(imm);
716 : } else {
717 : m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_OR, dst);
718 : m_formatter.immediate32(imm);
719 : }
720 : }
721 :
722 : void notq_r(RegisterID dst)
723 : {
724 : js::JaegerSpew(js::JSpew_Insns,
725 : IPFX "notq %s\n", MAYBE_PAD, nameIReg(8,dst));
726 : m_formatter.oneByteOp64(OP_GROUP3_Ev, GROUP3_OP_NOT, dst);
727 : }
728 : #else
729 : void orl_im(int imm, void* addr)
730 : {
731 : FIXME_INSN_PRINTING;
732 : if (CAN_SIGN_EXTEND_8_32(imm)) {
733 : m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, addr);
734 : m_formatter.immediate8(imm);
735 : } else {
736 : m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, addr);
737 : m_formatter.immediate32(imm);
738 : }
739 : }
740 : #endif
741 :
742 4930 : void subl_rr(RegisterID src, RegisterID dst)
743 : {
744 : js::JaegerSpew(js::JSpew_Insns,
745 : IPFX "subl %s, %s\n", MAYBE_PAD,
746 4930 : nameIReg(4,src), nameIReg(4,dst));
747 4930 : m_formatter.oneByteOp(OP_SUB_EvGv, src, dst);
748 4930 : }
749 :
750 : void subl_mr(int offset, RegisterID base, RegisterID dst)
751 : {
752 : FIXME_INSN_PRINTING;
753 : m_formatter.oneByteOp(OP_SUB_GvEv, dst, base, offset);
754 : }
755 :
756 : void subl_rm(RegisterID src, int offset, RegisterID base)
757 : {
758 : FIXME_INSN_PRINTING;
759 : m_formatter.oneByteOp(OP_SUB_EvGv, src, base, offset);
760 : }
761 :
762 262959 : void subl_ir(int imm, RegisterID dst)
763 : {
764 : js::JaegerSpew(js::JSpew_Insns,
765 262959 : IPFX "subl $0x%x, %s\n", MAYBE_PAD, imm, nameIReg(4, dst));
766 262959 : if (CAN_SIGN_EXTEND_8_32(imm)) {
767 262681 : m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, dst);
768 262681 : m_formatter.immediate8(imm);
769 : } else {
770 278 : m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, dst);
771 278 : m_formatter.immediate32(imm);
772 : }
773 262959 : }
774 :
775 : void subl_im(int imm, int offset, RegisterID base)
776 : {
777 : js::JaegerSpew(js::JSpew_Insns,
778 : IPFX "subl $0x%x, %s0x%x(%s)\n", MAYBE_PAD,
779 : imm, PRETTY_PRINT_OFFSET(offset), nameIReg(4, base));
780 : if (CAN_SIGN_EXTEND_8_32(imm)) {
781 : m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, base, offset);
782 : m_formatter.immediate8(imm);
783 : } else {
784 : m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, base, offset);
785 : m_formatter.immediate32(imm);
786 : }
787 : }
788 :
789 : #if WTF_CPU_X86_64
790 : void subq_rr(RegisterID src, RegisterID dst)
791 : {
792 : FIXME_INSN_PRINTING;
793 : m_formatter.oneByteOp64(OP_SUB_EvGv, src, dst);
794 : }
795 :
796 : void subq_ir(int imm, RegisterID dst)
797 : {
798 : js::JaegerSpew(js::JSpew_Insns,
799 : IPFX "subq $0x%x, %s\n", MAYBE_PAD, imm, nameIReg(8,dst));
800 : if (CAN_SIGN_EXTEND_8_32(imm)) {
801 : m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_SUB, dst);
802 : m_formatter.immediate8(imm);
803 : } else {
804 : m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_SUB, dst);
805 : m_formatter.immediate32(imm);
806 : }
807 : }
808 : #else
809 2582 : void subl_im(int imm, void* addr)
810 : {
811 2582 : FIXME_INSN_PRINTING;
812 2582 : if (CAN_SIGN_EXTEND_8_32(imm)) {
813 2582 : m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, addr);
814 2582 : m_formatter.immediate8(imm);
815 : } else {
816 0 : m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, addr);
817 0 : m_formatter.immediate32(imm);
818 : }
819 2582 : }
820 : #endif
821 :
822 360561 : void xorl_rr(RegisterID src, RegisterID dst)
823 : {
824 : js::JaegerSpew(js::JSpew_Insns,
825 : IPFX "xorl %s, %s\n", MAYBE_PAD,
826 360561 : nameIReg(4,src), nameIReg(4,dst));
827 360561 : m_formatter.oneByteOp(OP_XOR_EvGv, src, dst);
828 360561 : }
829 :
830 0 : void xorl_mr(int offset, RegisterID base, RegisterID dst)
831 : {
832 0 : FIXME_INSN_PRINTING;
833 0 : m_formatter.oneByteOp(OP_XOR_GvEv, dst, base, offset);
834 0 : }
835 :
836 : void xorl_rm(RegisterID src, int offset, RegisterID base)
837 : {
838 : FIXME_INSN_PRINTING;
839 : m_formatter.oneByteOp(OP_XOR_EvGv, src, base, offset);
840 : }
841 :
842 : void xorl_im(int imm, int offset, RegisterID base)
843 : {
844 : FIXME_INSN_PRINTING;
845 : if (CAN_SIGN_EXTEND_8_32(imm)) {
846 : m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_XOR, base, offset);
847 : m_formatter.immediate8(imm);
848 : } else {
849 : m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_XOR, base, offset);
850 : m_formatter.immediate32(imm);
851 : }
852 : }
853 :
854 33178 : void xorl_ir(int imm, RegisterID dst)
855 : {
856 : js::JaegerSpew(js::JSpew_Insns,
857 : IPFX "xorl %d, %s\n", MAYBE_PAD,
858 33178 : imm, nameIReg(4,dst));
859 33178 : if (CAN_SIGN_EXTEND_8_32(imm)) {
860 33056 : m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_XOR, dst);
861 33056 : m_formatter.immediate8(imm);
862 : } else {
863 122 : m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_XOR, dst);
864 122 : m_formatter.immediate32(imm);
865 : }
866 33178 : }
867 :
868 : #if WTF_CPU_X86_64
869 : void xorq_rr(RegisterID src, RegisterID dst)
870 : {
871 : js::JaegerSpew(js::JSpew_Insns,
872 : IPFX "xorq %s, %s\n", MAYBE_PAD,
873 : nameIReg(8,src), nameIReg(8, dst));
874 : m_formatter.oneByteOp64(OP_XOR_EvGv, src, dst);
875 : }
876 :
877 : void xorq_ir(int imm, RegisterID dst)
878 : {
879 : js::JaegerSpew(js::JSpew_Insns,
880 : IPFX "xorq %d, %s\n", MAYBE_PAD,
881 : imm, nameIReg(8,dst));
882 : if (CAN_SIGN_EXTEND_8_32(imm)) {
883 : m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_XOR, dst);
884 : m_formatter.immediate8(imm);
885 : } else {
886 : m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_XOR, dst);
887 : m_formatter.immediate32(imm);
888 : }
889 : }
890 : #endif
891 :
892 3188 : void sarl_i8r(int imm, RegisterID dst)
893 : {
894 : js::JaegerSpew(js::JSpew_Insns,
895 3188 : IPFX "sarl $%d, %s\n", MAYBE_PAD, imm, nameIReg(4, dst));
896 3188 : if (imm == 1)
897 1492 : m_formatter.oneByteOp(OP_GROUP2_Ev1, GROUP2_OP_SAR, dst);
898 : else {
899 1696 : m_formatter.oneByteOp(OP_GROUP2_EvIb, GROUP2_OP_SAR, dst);
900 1696 : m_formatter.immediate8(imm);
901 : }
902 3188 : }
903 :
904 884 : void sarl_CLr(RegisterID dst)
905 : {
906 : js::JaegerSpew(js::JSpew_Insns,
907 884 : IPFX "sarl %%cl, %s\n", MAYBE_PAD, nameIReg(4, dst));
908 884 : m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SAR, dst);
909 884 : }
910 :
911 7373 : void shrl_i8r(int imm, RegisterID dst)
912 : {
913 7373 : if (imm == 1)
914 25 : m_formatter.oneByteOp(OP_GROUP2_Ev1, GROUP2_OP_SHR, dst);
915 : else {
916 7348 : m_formatter.oneByteOp(OP_GROUP2_EvIb, GROUP2_OP_SHR, dst);
917 7348 : m_formatter.immediate8(imm);
918 : }
919 7373 : }
920 :
921 429 : void shrl_CLr(RegisterID dst)
922 : {
923 429 : m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SHR, dst);
924 429 : }
925 :
926 2593 : void shll_i8r(int imm, RegisterID dst)
927 : {
928 : js::JaegerSpew(js::JSpew_Insns,
929 2593 : IPFX "shll $%d, %s\n", MAYBE_PAD, imm, nameIReg(4, dst));
930 2593 : if (imm == 1)
931 383 : m_formatter.oneByteOp(OP_GROUP2_Ev1, GROUP2_OP_SHL, dst);
932 : else {
933 2210 : m_formatter.oneByteOp(OP_GROUP2_EvIb, GROUP2_OP_SHL, dst);
934 2210 : m_formatter.immediate8(imm);
935 : }
936 2593 : }
937 :
938 1153 : void shll_CLr(RegisterID dst)
939 : {
940 : js::JaegerSpew(js::JSpew_Insns,
941 1153 : IPFX "shll %%cl, %s\n", MAYBE_PAD, nameIReg(4, dst));
942 1153 : m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SHL, dst);
943 1153 : }
944 :
945 : #if WTF_CPU_X86_64
946 : void sarq_CLr(RegisterID dst)
947 : {
948 : FIXME_INSN_PRINTING;
949 : m_formatter.oneByteOp64(OP_GROUP2_EvCL, GROUP2_OP_SAR, dst);
950 : }
951 :
952 : void sarq_i8r(int imm, RegisterID dst)
953 : {
954 : js::JaegerSpew(js::JSpew_Insns,
955 : IPFX "sarq $%d, %s\n", MAYBE_PAD, imm, nameIReg(8, dst));
956 : if (imm == 1)
957 : m_formatter.oneByteOp64(OP_GROUP2_Ev1, GROUP2_OP_SAR, dst);
958 : else {
959 : m_formatter.oneByteOp64(OP_GROUP2_EvIb, GROUP2_OP_SAR, dst);
960 : m_formatter.immediate8(imm);
961 : }
962 : }
963 :
964 : void shlq_i8r(int imm, RegisterID dst)
965 : {
966 : js::JaegerSpew(js::JSpew_Insns,
967 : IPFX "shlq $%d, %s\n", MAYBE_PAD, imm, nameIReg(8, dst));
968 : if (imm == 1)
969 : m_formatter.oneByteOp64(OP_GROUP2_Ev1, GROUP2_OP_SHL, dst);
970 : else {
971 : m_formatter.oneByteOp64(OP_GROUP2_EvIb, GROUP2_OP_SHL, dst);
972 : m_formatter.immediate8(imm);
973 : }
974 : }
975 : #endif
976 :
977 1939 : void imull_rr(RegisterID src, RegisterID dst)
978 : {
979 : js::JaegerSpew(js::JSpew_Insns,
980 1939 : IPFX "imull %s, %s\n", MAYBE_PAD, nameIReg(4,src), nameIReg(4, dst));
981 1939 : m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, src);
982 1939 : }
983 :
984 : void imull_mr(int offset, RegisterID base, RegisterID dst)
985 : {
986 : FIXME_INSN_PRINTING;
987 : m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, base, offset);
988 : }
989 :
990 1881 : void imull_i32r(RegisterID src, int32_t value, RegisterID dst)
991 : {
992 : js::JaegerSpew(js::JSpew_Insns,
993 : IPFX "imull %d, %s, %s\n",
994 1881 : MAYBE_PAD, value, nameIReg(4, src), nameIReg(4, dst));
995 1881 : m_formatter.oneByteOp(OP_IMUL_GvEvIz, dst, src);
996 1881 : m_formatter.immediate32(value);
997 1881 : }
998 :
999 3813 : void idivl_r(RegisterID dst)
1000 : {
1001 : js::JaegerSpew(js::JSpew_Insns,
1002 : IPFX "idivl %s\n", MAYBE_PAD,
1003 3813 : nameIReg(4, dst));
1004 3813 : m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_IDIV, dst);
1005 3813 : }
1006 :
1007 : // Comparisons:
1008 :
1009 266721 : void cmpl_rr(RegisterID src, RegisterID dst)
1010 : {
1011 : js::JaegerSpew(js::JSpew_Insns,
1012 : IPFX "cmpl %s, %s\n", MAYBE_PAD,
1013 266721 : nameIReg(4, src), nameIReg(4, dst));
1014 266721 : m_formatter.oneByteOp(OP_CMP_EvGv, src, dst);
1015 266721 : }
1016 :
1017 62448 : void cmpl_rm(RegisterID src, int offset, RegisterID base)
1018 : {
1019 : js::JaegerSpew(js::JSpew_Insns,
1020 : IPFX "cmpl %s, %s0x%x(%s)\n", MAYBE_PAD,
1021 62448 : nameIReg(4, src), PRETTY_PRINT_OFFSET(offset), nameIReg(base));
1022 62448 : m_formatter.oneByteOp(OP_CMP_EvGv, src, base, offset);
1023 62448 : }
1024 :
1025 88103 : void cmpl_mr(int offset, RegisterID base, RegisterID src)
1026 : {
1027 : js::JaegerSpew(js::JSpew_Insns,
1028 : IPFX "cmpl %s0x%x(%s), %s\n", MAYBE_PAD,
1029 88103 : PRETTY_PRINT_OFFSET(offset), nameIReg(4, base), nameIReg(src));
1030 88103 : m_formatter.oneByteOp(OP_CMP_GvEv, src, base, offset);
1031 88103 : }
1032 :
1033 4488683 : void cmpl_ir(int imm, RegisterID dst)
1034 : {
1035 : js::JaegerSpew(js::JSpew_Insns,
1036 4488683 : IPFX "cmpl $0x%x, %s\n", MAYBE_PAD, imm, nameIReg(4, dst));
1037 4488683 : if (CAN_SIGN_EXTEND_8_32(imm)) {
1038 3792982 : m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, dst);
1039 3792982 : m_formatter.immediate8(imm);
1040 : } else {
1041 695701 : m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
1042 695701 : m_formatter.immediate32(imm);
1043 : }
1044 4488683 : }
1045 :
1046 1032948 : void cmpl_ir_force32(int imm, RegisterID dst)
1047 : {
1048 : js::JaegerSpew(js::JSpew_Insns,
1049 1032948 : IPFX "cmpl $0x%x, %s\n", MAYBE_PAD, imm, nameIReg(4, dst));
1050 1032948 : m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
1051 1032948 : m_formatter.immediate32(imm);
1052 1032948 : }
1053 :
1054 739983 : void cmpl_im(int imm, int offset, RegisterID base)
1055 : {
1056 : js::JaegerSpew(js::JSpew_Insns,
1057 : IPFX "cmpl $0x%x, %s0x%x(%s)\n", MAYBE_PAD,
1058 739983 : imm, PRETTY_PRINT_OFFSET(offset), nameIReg(4,base));
1059 739983 : if (CAN_SIGN_EXTEND_8_32(imm)) {
1060 428280 : m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, offset);
1061 428280 : m_formatter.immediate8(imm);
1062 : } else {
1063 311703 : m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, offset);
1064 311703 : m_formatter.immediate32(imm);
1065 : }
1066 739983 : }
1067 :
1068 3435 : void cmpb_im(int imm, int offset, RegisterID base)
1069 : {
1070 3435 : m_formatter.oneByteOp(OP_GROUP1_EbIb, GROUP1_OP_CMP, base, offset);
1071 3435 : m_formatter.immediate8(imm);
1072 3435 : }
1073 :
1074 : void cmpb_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
1075 : {
1076 : m_formatter.oneByteOp(OP_GROUP1_EbIb, GROUP1_OP_CMP, base, index, scale, offset);
1077 : m_formatter.immediate8(imm);
1078 : }
1079 :
1080 74169 : void cmpl_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
1081 : {
1082 : js::JaegerSpew(js::JSpew_Insns,
1083 : IPFX "cmpl %d, %d(%s,%s,%d)\n", MAYBE_PAD,
1084 74169 : imm, offset, nameIReg(4,base), nameIReg(4,index), scale);
1085 74169 : if (CAN_SIGN_EXTEND_8_32(imm)) {
1086 4647 : m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, index, scale, offset);
1087 4647 : m_formatter.immediate8(imm);
1088 : } else {
1089 69522 : m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, index, scale, offset);
1090 69522 : m_formatter.immediate32(imm);
1091 : }
1092 74169 : }
1093 :
1094 : void cmpl_im_force32(int imm, int offset, RegisterID base)
1095 : {
1096 : FIXME_INSN_PRINTING;
1097 : m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, offset);
1098 : m_formatter.immediate32(imm);
1099 : }
1100 :
1101 : #if WTF_CPU_X86_64
1102 : void cmpq_rr(RegisterID src, RegisterID dst)
1103 : {
1104 : js::JaegerSpew(js::JSpew_Insns,
1105 : IPFX "cmpq %s, %s\n", MAYBE_PAD,
1106 : nameIReg(8, src), nameIReg(8, dst));
1107 : m_formatter.oneByteOp64(OP_CMP_EvGv, src, dst);
1108 : }
1109 :
1110 : void cmpq_rm(RegisterID src, int offset, RegisterID base)
1111 : {
1112 : js::JaegerSpew(js::JSpew_Insns,
1113 : IPFX "cmpq %s, %d(%s)\n", MAYBE_PAD,
1114 : nameIReg(8, src), offset, nameIReg(8, base));
1115 : m_formatter.oneByteOp64(OP_CMP_EvGv, src, base, offset);
1116 : }
1117 :
1118 : void cmpq_mr(int offset, RegisterID base, RegisterID src)
1119 : {
1120 : js::JaegerSpew(js::JSpew_Insns,
1121 : IPFX "cmpq %d(%s), %s\n", MAYBE_PAD,
1122 : offset, nameIReg(8, base), nameIReg(8, src));
1123 : m_formatter.oneByteOp64(OP_CMP_GvEv, src, base, offset);
1124 : }
1125 :
1126 : void cmpq_ir(int imm, RegisterID dst)
1127 : {
1128 : js::JaegerSpew(js::JSpew_Insns,
1129 : IPFX "cmpq %d, %s\n", MAYBE_PAD,
1130 : imm, nameIReg(8, dst));
1131 : if (CAN_SIGN_EXTEND_8_32(imm)) {
1132 : m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_CMP, dst);
1133 : m_formatter.immediate8(imm);
1134 : } else {
1135 : m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
1136 : m_formatter.immediate32(imm);
1137 : }
1138 : }
1139 :
1140 : void cmpq_im(int imm, int offset, RegisterID base)
1141 : {
1142 : FIXME_INSN_PRINTING;
1143 : if (CAN_SIGN_EXTEND_8_32(imm)) {
1144 : m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, offset);
1145 : m_formatter.immediate8(imm);
1146 : } else {
1147 : m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, offset);
1148 : m_formatter.immediate32(imm);
1149 : }
1150 : }
1151 :
1152 : void cmpq_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
1153 : {
1154 : FIXME_INSN_PRINTING;
1155 : if (CAN_SIGN_EXTEND_8_32(imm)) {
1156 : m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, index, scale, offset);
1157 : m_formatter.immediate8(imm);
1158 : } else {
1159 : m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, index, scale, offset);
1160 : m_formatter.immediate32(imm);
1161 : }
1162 : }
1163 : #else
1164 19127 : void cmpl_rm(RegisterID reg, void* addr)
1165 : {
1166 19127 : FIXME_INSN_PRINTING;
1167 19127 : m_formatter.oneByteOp(OP_CMP_EvGv, reg, addr);
1168 19127 : }
1169 :
1170 362293 : void cmpl_im(int imm, void* addr)
1171 : {
1172 362293 : FIXME_INSN_PRINTING;
1173 362293 : if (CAN_SIGN_EXTEND_8_32(imm)) {
1174 353285 : m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, addr);
1175 353285 : m_formatter.immediate8(imm);
1176 : } else {
1177 9008 : m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, addr);
1178 9008 : m_formatter.immediate32(imm);
1179 : }
1180 362293 : }
1181 : #endif
1182 :
1183 : void cmpw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1184 : {
1185 : FIXME_INSN_PRINTING;
1186 : m_formatter.prefix(PRE_OPERAND_SIZE);
1187 : m_formatter.oneByteOp(OP_CMP_EvGv, src, base, index, scale, offset);
1188 : }
1189 :
1190 57430 : void cmpw_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
1191 : {
1192 57430 : FIXME_INSN_PRINTING;
1193 57430 : if (CAN_SIGN_EXTEND_8_32(imm)) {
1194 57331 : m_formatter.prefix(PRE_OPERAND_SIZE);
1195 57331 : m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, index, scale, offset);
1196 57331 : m_formatter.immediate8(imm);
1197 : } else {
1198 99 : m_formatter.prefix(PRE_OPERAND_SIZE);
1199 99 : m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, index, scale, offset);
1200 99 : m_formatter.immediate16(imm);
1201 : }
1202 57430 : }
1203 :
1204 876952 : void testl_rr(RegisterID src, RegisterID dst)
1205 : {
1206 : js::JaegerSpew(js::JSpew_Insns,
1207 : IPFX "testl %s, %s\n", MAYBE_PAD,
1208 876952 : nameIReg(4,src), nameIReg(4,dst));
1209 876952 : m_formatter.oneByteOp(OP_TEST_EvGv, src, dst);
1210 876952 : }
1211 :
1212 11545 : void testl_i32r(int imm, RegisterID dst)
1213 : {
1214 : js::JaegerSpew(js::JSpew_Insns,
1215 : IPFX "testl $0x%x, %s\n", MAYBE_PAD,
1216 11545 : imm, nameIReg(dst));
1217 11545 : m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, dst);
1218 11545 : m_formatter.immediate32(imm);
1219 11545 : }
1220 :
1221 297748 : void testl_i32m(int imm, int offset, RegisterID base)
1222 : {
1223 : js::JaegerSpew(js::JSpew_Insns,
1224 : IPFX "testl $0x%x, %s0x%x(%s)\n", MAYBE_PAD,
1225 297748 : imm, PRETTY_PRINT_OFFSET(offset), nameIReg(base));
1226 297748 : m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, offset);
1227 297748 : m_formatter.immediate32(imm);
1228 297748 : }
1229 :
1230 0 : void testb_im(int imm, int offset, RegisterID base)
1231 : {
1232 0 : m_formatter.oneByteOp(OP_GROUP3_EbIb, GROUP3_OP_TEST, base, offset);
1233 0 : m_formatter.immediate8(imm);
1234 0 : }
1235 :
1236 : void testb_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
1237 : {
1238 : m_formatter.oneByteOp(OP_GROUP3_EbIb, GROUP3_OP_TEST, base, index, scale, offset);
1239 : m_formatter.immediate8(imm);
1240 : }
1241 :
1242 : void testl_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale)
1243 : {
1244 : FIXME_INSN_PRINTING;
1245 : m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, index, scale, offset);
1246 : m_formatter.immediate32(imm);
1247 : }
1248 :
1249 : #if WTF_CPU_X86_64
1250 : void testq_rr(RegisterID src, RegisterID dst)
1251 : {
1252 : js::JaegerSpew(js::JSpew_Insns,
1253 : IPFX "testq %s, %s\n", MAYBE_PAD,
1254 : nameIReg(8,src), nameIReg(8,dst));
1255 : m_formatter.oneByteOp64(OP_TEST_EvGv, src, dst);
1256 : }
1257 :
1258 : void testq_i32r(int imm, RegisterID dst)
1259 : {
1260 : FIXME_INSN_PRINTING;
1261 : m_formatter.oneByteOp64(OP_GROUP3_EvIz, GROUP3_OP_TEST, dst);
1262 : m_formatter.immediate32(imm);
1263 : }
1264 :
1265 : void testq_i32m(int imm, int offset, RegisterID base)
1266 : {
1267 : js::JaegerSpew(js::JSpew_Insns,
1268 : IPFX "testq $0x%x, %s0x%x(%s)\n", MAYBE_PAD,
1269 : imm, PRETTY_PRINT_OFFSET(offset), nameIReg(base));
1270 : m_formatter.oneByteOp64(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, offset);
1271 : m_formatter.immediate32(imm);
1272 : }
1273 :
1274 : void testq_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale)
1275 : {
1276 : FIXME_INSN_PRINTING;
1277 : m_formatter.oneByteOp64(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, index, scale, offset);
1278 : m_formatter.immediate32(imm);
1279 : }
1280 : #endif
1281 :
1282 : void testw_rr(RegisterID src, RegisterID dst)
1283 : {
1284 : FIXME_INSN_PRINTING;
1285 : m_formatter.prefix(PRE_OPERAND_SIZE);
1286 : m_formatter.oneByteOp(OP_TEST_EvGv, src, dst);
1287 : }
1288 :
1289 14215 : void testb_i8r(int imm, RegisterID dst)
1290 : {
1291 : js::JaegerSpew(js::JSpew_Insns,
1292 : IPFX "testb $0x%x, %s\n", MAYBE_PAD,
1293 14215 : imm, nameIReg(1,dst));
1294 14215 : m_formatter.oneByteOp8(OP_GROUP3_EbIb, GROUP3_OP_TEST, dst);
1295 14215 : m_formatter.immediate8(imm);
1296 14215 : }
1297 :
1298 43691 : void setCC_r(Condition cond, RegisterID dst)
1299 : {
1300 : js::JaegerSpew(js::JSpew_Insns,
1301 : IPFX "set%s %s\n", MAYBE_PAD,
1302 43691 : nameCC(cond), nameIReg(1,dst));
1303 43691 : m_formatter.twoByteOp8(setccOpcode(cond), (GroupOpcodeID)0, dst);
1304 43691 : }
1305 :
1306 : void sete_r(RegisterID dst)
1307 : {
1308 : FIXME_INSN_PRINTING;
1309 : m_formatter.twoByteOp8(setccOpcode(ConditionE), (GroupOpcodeID)0, dst);
1310 : }
1311 :
1312 : void setz_r(RegisterID dst)
1313 : {
1314 : FIXME_INSN_PRINTING;
1315 : sete_r(dst);
1316 : }
1317 :
1318 : void setne_r(RegisterID dst)
1319 : {
1320 : FIXME_INSN_PRINTING;
1321 : m_formatter.twoByteOp8(setccOpcode(ConditionNE), (GroupOpcodeID)0, dst);
1322 : }
1323 :
1324 : void setnz_r(RegisterID dst)
1325 : {
1326 : FIXME_INSN_PRINTING;
1327 : setne_r(dst);
1328 : }
1329 :
1330 : // Various move ops:
1331 :
1332 3813 : void cdq()
1333 : {
1334 : js::JaegerSpew(js::JSpew_Insns,
1335 3813 : IPFX "cdq \n", MAYBE_PAD);
1336 3813 : m_formatter.oneByteOp(OP_CDQ);
1337 3813 : }
1338 :
1339 0 : void xchgl_rr(RegisterID src, RegisterID dst)
1340 : {
1341 : js::JaegerSpew(js::JSpew_Insns,
1342 : IPFX "xchgl %s, %s\n", MAYBE_PAD,
1343 0 : nameIReg(4,src), nameIReg(4,dst));
1344 0 : m_formatter.oneByteOp(OP_XCHG_EvGv, src, dst);
1345 0 : }
1346 :
1347 : #if WTF_CPU_X86_64
1348 : void xchgq_rr(RegisterID src, RegisterID dst)
1349 : {
1350 : js::JaegerSpew(js::JSpew_Insns,
1351 : IPFX "xchgq %s, %s\n", MAYBE_PAD,
1352 : nameIReg(8,src), nameIReg(8,dst));
1353 : m_formatter.oneByteOp64(OP_XCHG_EvGv, src, dst);
1354 : }
1355 : #endif
1356 :
1357 11177925 : void movl_rr(RegisterID src, RegisterID dst)
1358 : {
1359 : js::JaegerSpew(js::JSpew_Insns,
1360 : IPFX "movl %s, %s\n", MAYBE_PAD,
1361 11177925 : nameIReg(4,src), nameIReg(4,dst));
1362 11177925 : m_formatter.oneByteOp(OP_MOV_EvGv, src, dst);
1363 11177925 : }
1364 :
1365 18 : void movw_rm(RegisterID src, int offset, RegisterID base)
1366 : {
1367 : js::JaegerSpew(js::JSpew_Insns,
1368 : IPFX "movw %s, %s0x%x(%s)\n", MAYBE_PAD,
1369 18 : nameIReg(2,src), PRETTY_PRINT_OFFSET(offset), nameIReg(base));
1370 18 : m_formatter.prefix(PRE_OPERAND_SIZE);
1371 18 : m_formatter.oneByteOp(OP_MOV_EvGv, src, base, offset);
1372 18 : }
1373 :
1374 23398600 : void movl_rm(RegisterID src, int offset, RegisterID base)
1375 : {
1376 : js::JaegerSpew(js::JSpew_Insns,
1377 : IPFX "movl %s, %s0x%x(%s)\n", MAYBE_PAD,
1378 23398600 : nameIReg(4,src), PRETTY_PRINT_OFFSET(offset), nameIReg(base));
1379 23398600 : m_formatter.oneByteOp(OP_MOV_EvGv, src, base, offset);
1380 23398600 : }
1381 :
1382 : void movl_rm_disp32(RegisterID src, int offset, RegisterID base)
1383 : {
1384 : FIXME_INSN_PRINTING;
1385 : m_formatter.oneByteOp_disp32(OP_MOV_EvGv, src, base, offset);
1386 : }
1387 :
1388 60 : void movw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1389 : {
1390 : js::JaegerSpew(js::JSpew_Insns,
1391 : IPFX "movw %s, %d(%s,%s,%d)\n", MAYBE_PAD,
1392 60 : nameIReg(2, src), offset, nameIReg(base), nameIReg(index), scale);
1393 60 : m_formatter.prefix(PRE_OPERAND_SIZE);
1394 60 : m_formatter.oneByteOp(OP_MOV_EvGv, src, base, index, scale, offset);
1395 60 : }
1396 :
1397 14444 : void movl_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1398 : {
1399 : js::JaegerSpew(js::JSpew_Insns,
1400 : IPFX "movl %s, %d(%s,%s,%d)\n", MAYBE_PAD,
1401 14444 : nameIReg(4, src), offset, nameIReg(base), nameIReg(index), scale);
1402 14444 : m_formatter.oneByteOp(OP_MOV_EvGv, src, base, index, scale, offset);
1403 14444 : }
1404 :
1405 1490 : void movl_mEAX(void* addr)
1406 : {
1407 1490 : FIXME_INSN_PRINTING;
1408 1490 : m_formatter.oneByteOp(OP_MOV_EAXOv);
1409 : #if WTF_CPU_X86_64
1410 : m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
1411 : #else
1412 1490 : m_formatter.immediate32(reinterpret_cast<int>(addr));
1413 : #endif
1414 1490 : }
1415 :
1416 22263999 : void movl_mr(int offset, RegisterID base, RegisterID dst)
1417 : {
1418 : js::JaegerSpew(js::JSpew_Insns,
1419 : IPFX "movl %s0x%x(%s), %s\n", MAYBE_PAD,
1420 22263999 : PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameIReg(4, dst));
1421 22263999 : m_formatter.oneByteOp(OP_MOV_GvEv, dst, base, offset);
1422 22263999 : }
1423 :
1424 : void movl_mr_disp32(int offset, RegisterID base, RegisterID dst)
1425 : {
1426 : FIXME_INSN_PRINTING;
1427 : m_formatter.oneByteOp_disp32(OP_MOV_GvEv, dst, base, offset);
1428 : }
1429 :
1430 56465 : void movl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1431 : {
1432 : js::JaegerSpew(js::JSpew_Insns,
1433 : IPFX "movl %d(%s,%s,%d), %s\n", MAYBE_PAD,
1434 56465 : offset, nameIReg(base), nameIReg(index), scale, nameIReg(4, dst));
1435 56465 : m_formatter.oneByteOp(OP_MOV_GvEv, dst, base, index, scale, offset);
1436 56465 : }
1437 :
1438 3715295 : void movl_i32r(int imm, RegisterID dst)
1439 : {
1440 : js::JaegerSpew(js::JSpew_Insns,
1441 : IPFX "movl $0x%x, %s\n", MAYBE_PAD,
1442 3715295 : imm, nameIReg(dst));
1443 3715295 : m_formatter.oneByteOp(OP_MOV_EAXIv, dst);
1444 3715295 : m_formatter.immediate32(imm);
1445 3715295 : }
1446 :
1447 108 : void movb_i8m(int imm, int offset, RegisterID base)
1448 : {
1449 : js::JaegerSpew(js::JSpew_Insns,
1450 : IPFX "movb $0x%x, %s0x%x(%s)\n", MAYBE_PAD,
1451 108 : imm, PRETTY_PRINT_OFFSET(offset), nameIReg(base));
1452 108 : m_formatter.oneByteOp(OP_GROUP11_EvIb, GROUP11_MOV, base, offset);
1453 108 : m_formatter.immediate8(imm);
1454 108 : }
1455 :
1456 316 : void movb_i8m(int imm, int offset, RegisterID base, RegisterID index, int scale)
1457 : {
1458 : js::JaegerSpew(js::JSpew_Insns,
1459 : IPFX "movb $0x%x, %d(%s,%s,%d)\n", MAYBE_PAD,
1460 316 : imm, offset, nameIReg(base), nameIReg(index), scale);
1461 316 : m_formatter.oneByteOp(OP_GROUP11_EvIb, GROUP11_MOV, base, index, scale, offset);
1462 316 : m_formatter.immediate8(imm);
1463 316 : }
1464 :
1465 68 : void movw_i16m(int imm, int offset, RegisterID base)
1466 : {
1467 : js::JaegerSpew(js::JSpew_Insns,
1468 : IPFX "movw $0x%x, %s0x%x(%s)\n", MAYBE_PAD,
1469 68 : imm, PRETTY_PRINT_OFFSET(offset), nameIReg(base));
1470 68 : m_formatter.prefix(PRE_OPERAND_SIZE);
1471 68 : m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, base, offset);
1472 68 : m_formatter.immediate16(imm);
1473 68 : }
1474 :
1475 14360881 : void movl_i32m(int imm, int offset, RegisterID base)
1476 : {
1477 : js::JaegerSpew(js::JSpew_Insns,
1478 : IPFX "movl $0x%x, %s0x%x(%s)\n", MAYBE_PAD,
1479 14360881 : imm, PRETTY_PRINT_OFFSET(offset), nameIReg(base));
1480 14360881 : m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, base, offset);
1481 14360881 : m_formatter.immediate32(imm);
1482 14360881 : }
1483 :
1484 114 : void movw_i16m(int imm, int offset, RegisterID base, RegisterID index, int scale)
1485 : {
1486 : js::JaegerSpew(js::JSpew_Insns,
1487 : IPFX "movw $0x%x, %d(%s,%s,%d)\n", MAYBE_PAD,
1488 114 : imm, offset, nameIReg(base), nameIReg(index), scale);
1489 114 : m_formatter.prefix(PRE_OPERAND_SIZE);
1490 114 : m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, base, index, scale, offset);
1491 114 : m_formatter.immediate16(imm);
1492 114 : }
1493 :
1494 8153 : void movl_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale)
1495 : {
1496 : js::JaegerSpew(js::JSpew_Insns,
1497 : IPFX "movl $0x%x, %d(%s,%s,%d)\n", MAYBE_PAD,
1498 8153 : imm, offset, nameIReg(base), nameIReg(index), scale);
1499 8153 : m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, base, index, scale, offset);
1500 8153 : m_formatter.immediate32(imm);
1501 8153 : }
1502 :
1503 408 : void movl_EAXm(void* addr)
1504 : {
1505 408 : FIXME_INSN_PRINTING;
1506 408 : m_formatter.oneByteOp(OP_MOV_OvEAX);
1507 : #if WTF_CPU_X86_64
1508 : m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
1509 : #else
1510 408 : m_formatter.immediate32(reinterpret_cast<int>(addr));
1511 : #endif
1512 408 : }
1513 :
1514 : #if WTF_CPU_X86_64
1515 : void movq_rr(RegisterID src, RegisterID dst)
1516 : {
1517 : js::JaegerSpew(js::JSpew_Insns,
1518 : IPFX "movq %s, %s\n", MAYBE_PAD,
1519 : nameIReg(8,src), nameIReg(8,dst));
1520 : m_formatter.oneByteOp64(OP_MOV_EvGv, src, dst);
1521 : }
1522 :
1523 : void movq_rm(RegisterID src, int offset, RegisterID base)
1524 : {
1525 : js::JaegerSpew(js::JSpew_Insns,
1526 : IPFX "movq %s, %s0x%x(%s)\n", MAYBE_PAD,
1527 : nameIReg(8,src), PRETTY_PRINT_OFFSET(offset), nameIReg(base));
1528 : m_formatter.oneByteOp64(OP_MOV_EvGv, src, base, offset);
1529 : }
1530 :
1531 : void movq_rm_disp32(RegisterID src, int offset, RegisterID base)
1532 : {
1533 : FIXME_INSN_PRINTING;
1534 : m_formatter.oneByteOp64_disp32(OP_MOV_EvGv, src, base, offset);
1535 : }
1536 :
1537 : void movq_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1538 : {
1539 : js::JaegerSpew(js::JSpew_Insns,
1540 : IPFX "movq %s, %s0x%x(%s)\n", MAYBE_PAD,
1541 : nameIReg(8,src), PRETTY_PRINT_OFFSET(offset), nameIReg(base));
1542 : m_formatter.oneByteOp64(OP_MOV_EvGv, src, base, index, scale, offset);
1543 : }
1544 :
1545 : void movq_mEAX(void* addr)
1546 : {
1547 : FIXME_INSN_PRINTING;
1548 : m_formatter.oneByteOp64(OP_MOV_EAXOv);
1549 : m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
1550 : }
1551 :
1552 : void movq_EAXm(void* addr)
1553 : {
1554 : FIXME_INSN_PRINTING;
1555 : m_formatter.oneByteOp64(OP_MOV_OvEAX);
1556 : m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
1557 : }
1558 :
1559 : void movq_mr(int offset, RegisterID base, RegisterID dst)
1560 : {
1561 : js::JaegerSpew(js::JSpew_Insns,
1562 : IPFX "movq %s0x%x(%s), %s\n", MAYBE_PAD,
1563 : PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameIReg(8,dst));
1564 : m_formatter.oneByteOp64(OP_MOV_GvEv, dst, base, offset);
1565 : }
1566 :
1567 : void movq_mr_disp32(int offset, RegisterID base, RegisterID dst)
1568 : {
1569 : FIXME_INSN_PRINTING;
1570 : m_formatter.oneByteOp64_disp32(OP_MOV_GvEv, dst, base, offset);
1571 : }
1572 :
1573 : void movq_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1574 : {
1575 : js::JaegerSpew(js::JSpew_Insns,
1576 : IPFX "movq %d(%s,%s,%d), %s\n", MAYBE_PAD,
1577 : offset, nameIReg(base), nameIReg(index), scale, nameIReg(8,dst));
1578 : m_formatter.oneByteOp64(OP_MOV_GvEv, dst, base, index, scale, offset);
1579 : }
1580 :
1581 : void leaq_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1582 : {
1583 : js::JaegerSpew(js::JSpew_Insns,
1584 : IPFX "leaq %d(%s,%s,%d), %s\n", MAYBE_PAD,
1585 : offset, nameIReg(base), nameIReg(index), scale, nameIReg(8,dst)),
1586 : m_formatter.oneByteOp64(OP_LEA, dst, base, index, scale, offset);
1587 : }
1588 :
1589 : void movq_i32m(int imm, int offset, RegisterID base)
1590 : {
1591 : js::JaegerSpew(js::JSpew_Insns,
1592 : IPFX "movq $%d, %s0x%x(%s)\n", MAYBE_PAD,
1593 : imm, PRETTY_PRINT_OFFSET(offset), nameIReg(base));
1594 : m_formatter.oneByteOp64(OP_GROUP11_EvIz, GROUP11_MOV, base, offset);
1595 : m_formatter.immediate32(imm);
1596 : }
1597 :
1598 : void movq_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale)
1599 : {
1600 : js::JaegerSpew(js::JSpew_Insns,
1601 : IPFX "movq $%d, %s0x%x(%s)\n", MAYBE_PAD,
1602 : imm, PRETTY_PRINT_OFFSET(offset), nameIReg(base));
1603 : m_formatter.oneByteOp64(OP_GROUP11_EvIz, GROUP11_MOV, base, index, scale, offset);
1604 : m_formatter.immediate32(imm);
1605 : }
1606 :
1607 : void movq_i64r(int64_t imm, RegisterID dst)
1608 : {
1609 : js::JaegerSpew(js::JSpew_Insns,
1610 : IPFX "movabsq $0x%llx, %s\n", MAYBE_PAD,
1611 : (unsigned long long int)imm, nameIReg(8,dst));
1612 : m_formatter.oneByteOp64(OP_MOV_EAXIv, dst);
1613 : m_formatter.immediate64(imm);
1614 : }
1615 :
1616 : void movsxd_rr(RegisterID src, RegisterID dst)
1617 : {
1618 : js::JaegerSpew(js::JSpew_Insns,
1619 : IPFX "movsxd %s, %s\n", MAYBE_PAD,
1620 : nameIReg(4, src), nameIReg(8, dst));
1621 : m_formatter.oneByteOp64(OP_MOVSXD_GvEv, dst, src);
1622 : }
1623 :
1624 :
1625 : #else
1626 19127 : void movl_rm(RegisterID src, void* addr)
1627 : {
1628 19127 : FIXME_INSN_PRINTING;
1629 19127 : if (src == X86Registers::eax)
1630 408 : movl_EAXm(addr);
1631 : else
1632 18719 : m_formatter.oneByteOp(OP_MOV_EvGv, src, addr);
1633 19127 : }
1634 :
1635 431088 : void movl_mr(void* addr, RegisterID dst)
1636 : {
1637 : js::JaegerSpew(js::JSpew_Insns,
1638 : IPFX "movl 0(%p), %s\n", MAYBE_PAD,
1639 431088 : addr, nameIReg(4, dst));
1640 431088 : if (dst == X86Registers::eax)
1641 1490 : movl_mEAX(addr);
1642 : else
1643 429598 : m_formatter.oneByteOp(OP_MOV_GvEv, dst, addr);
1644 431088 : }
1645 :
1646 : void movl_i32m(int imm, void* addr)
1647 : {
1648 : FIXME_INSN_PRINTING;
1649 : m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, addr);
1650 : m_formatter.immediate32(imm);
1651 : }
1652 : #endif
1653 :
1654 27 : void movb_rm(RegisterID src, int offset, RegisterID base)
1655 : {
1656 : js::JaegerSpew(js::JSpew_Insns,
1657 : IPFX "movb %s, %s0x%x(%s)\n", MAYBE_PAD,
1658 27 : nameIReg(1, src), PRETTY_PRINT_OFFSET(offset), nameIReg(base));
1659 27 : m_formatter.oneByteOp8(OP_MOV_EbGv, src, base, offset);
1660 27 : }
1661 :
1662 147 : void movb_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1663 : {
1664 : js::JaegerSpew(js::JSpew_Insns,
1665 : IPFX "movb %s, %d(%s,%s,%d)\n", MAYBE_PAD,
1666 147 : nameIReg(1, src), offset, nameIReg(base), nameIReg(index), scale);
1667 147 : m_formatter.oneByteOp8(OP_MOV_EbGv, src, base, index, scale, offset);
1668 147 : }
1669 :
1670 306 : void movzbl_mr(int offset, RegisterID base, RegisterID dst)
1671 : {
1672 : js::JaegerSpew(js::JSpew_Insns,
1673 : IPFX "movzbl %s0x%x(%s), %s\n", MAYBE_PAD,
1674 306 : PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameIReg(4, dst));
1675 306 : m_formatter.twoByteOp(OP2_MOVZX_GvEb, dst, base, offset);
1676 306 : }
1677 :
1678 63 : void movzbl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1679 : {
1680 : js::JaegerSpew(js::JSpew_Insns,
1681 : IPFX "movzbl %d(%s,%s,%d), %s\n", MAYBE_PAD,
1682 63 : offset, nameIReg(base), nameIReg(index), scale, nameIReg(dst));
1683 63 : m_formatter.twoByteOp(OP2_MOVZX_GvEb, dst, base, index, scale, offset);
1684 63 : }
1685 :
1686 162 : void movxbl_mr(int offset, RegisterID base, RegisterID dst)
1687 : {
1688 : js::JaegerSpew(js::JSpew_Insns,
1689 : IPFX "movxbl %s0x%x(%s), %s\n", MAYBE_PAD,
1690 162 : PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameIReg(4, dst));
1691 162 : m_formatter.twoByteOp(OP2_MOVSX_GvEb, dst, base, offset);
1692 162 : }
1693 :
1694 30 : void movxbl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1695 : {
1696 : js::JaegerSpew(js::JSpew_Insns,
1697 : IPFX "movxbl %d(%s,%s,%d), %s\n", MAYBE_PAD,
1698 30 : offset, nameIReg(base), nameIReg(index), scale, nameIReg(dst));
1699 30 : m_formatter.twoByteOp(OP2_MOVSX_GvEb, dst, base, index, scale, offset);
1700 30 : }
1701 :
1702 148055 : void movzwl_mr(int offset, RegisterID base, RegisterID dst)
1703 : {
1704 : js::JaegerSpew(js::JSpew_Insns,
1705 : IPFX "movzwl %s0x%x(%s), %s\n", MAYBE_PAD,
1706 148055 : PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameIReg(4, dst));
1707 148055 : m_formatter.twoByteOp(OP2_MOVZX_GvEw, dst, base, offset);
1708 148055 : }
1709 :
1710 62978 : void movzwl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1711 : {
1712 : js::JaegerSpew(js::JSpew_Insns,
1713 : IPFX "movzwl %d(%s,%s,%d), %s\n", MAYBE_PAD,
1714 62978 : offset, nameIReg(base), nameIReg(index), scale, nameIReg(dst));
1715 62978 : m_formatter.twoByteOp(OP2_MOVZX_GvEw, dst, base, index, scale, offset);
1716 62978 : }
1717 :
1718 153 : void movxwl_mr(int offset, RegisterID base, RegisterID dst)
1719 : {
1720 : js::JaegerSpew(js::JSpew_Insns,
1721 : IPFX "movxwl %s0x%x(%s), %s\n", MAYBE_PAD,
1722 153 : PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameIReg(4, dst));
1723 153 : m_formatter.twoByteOp(OP2_MOVSX_GvEw, dst, base, offset);
1724 153 : }
1725 :
1726 32 : void movxwl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1727 : {
1728 : js::JaegerSpew(js::JSpew_Insns,
1729 : IPFX "movxwl %d(%s,%s,%d), %s\n", MAYBE_PAD,
1730 32 : offset, nameIReg(base), nameIReg(index), scale, nameIReg(dst));
1731 32 : m_formatter.twoByteOp(OP2_MOVSX_GvEw, dst, base, index, scale, offset);
1732 32 : }
1733 :
1734 43691 : void movzbl_rr(RegisterID src, RegisterID dst)
1735 : {
1736 : // In 64-bit, this may cause an unnecessary REX to be planted (if the dst register
1737 : // is in the range ESP-EDI, and the src would not have required a REX). Unneeded
1738 : // REX prefixes are defined to be silently ignored by the processor.
1739 : js::JaegerSpew(js::JSpew_Insns,
1740 : IPFX "movzbl %s, %s\n", MAYBE_PAD,
1741 43691 : nameIReg(4,src), nameIReg(4,dst));
1742 43691 : m_formatter.twoByteOp8(OP2_MOVZX_GvEb, dst, src);
1743 43691 : }
1744 :
1745 2 : void leal_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1746 : {
1747 : js::JaegerSpew(js::JSpew_Insns,
1748 : IPFX "leal %d(%s,%s,%d), %s\n", MAYBE_PAD,
1749 2 : offset, nameIReg(base), nameIReg(index), scale, nameIReg(dst));
1750 2 : m_formatter.oneByteOp(OP_LEA, dst, base, index, scale, offset);
1751 2 : }
1752 :
1753 5028931 : void leal_mr(int offset, RegisterID base, RegisterID dst)
1754 : {
1755 : js::JaegerSpew(js::JSpew_Insns,
1756 : IPFX "leal %s0x%x(%s), %s\n", MAYBE_PAD,
1757 5028931 : PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameIReg(4,dst));
1758 5028931 : m_formatter.oneByteOp(OP_LEA, dst, base, offset);
1759 5028931 : }
1760 : #if WTF_CPU_X86_64
1761 : void leaq_mr(int offset, RegisterID base, RegisterID dst)
1762 : {
1763 : js::JaegerSpew(js::JSpew_Insns,
1764 : IPFX "leaq %s0x%x(%s), %s\n", MAYBE_PAD,
1765 : PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameIReg(8,dst));
1766 : m_formatter.oneByteOp64(OP_LEA, dst, base, offset);
1767 : }
1768 : #endif
1769 :
1770 : // Flow control:
1771 :
1772 4905615 : JmpSrc call()
1773 : {
1774 4905615 : m_formatter.oneByteOp(OP_CALL_rel32);
1775 4905615 : JmpSrc r = m_formatter.immediateRel32();
1776 : js::JaegerSpew(js::JSpew_Insns,
1777 4905615 : IPFX "call ((%d))\n", MAYBE_PAD, r.m_offset);
1778 : return r;
1779 : }
1780 :
1781 : JmpSrc call(RegisterID dst)
1782 : {
1783 : m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_CALLN, dst);
1784 : JmpSrc r = JmpSrc(m_formatter.size());
1785 : js::JaegerSpew(js::JSpew_Insns,
1786 : IPFX "call *%s\n", MAYBE_PAD, nameIReg(dst));
1787 : return r;
1788 : }
1789 :
1790 : void call_m(int offset, RegisterID base)
1791 : {
1792 : FIXME_INSN_PRINTING;
1793 : m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_CALLN, base, offset);
1794 : }
1795 :
1796 8690929 : JmpSrc jmp()
1797 : {
1798 8690929 : m_formatter.oneByteOp(OP_JMP_rel32);
1799 8690929 : JmpSrc r = m_formatter.immediateRel32();
1800 : js::JaegerSpew(js::JSpew_Insns,
1801 8690929 : IPFX "jmp ((%d))\n", MAYBE_PAD, r.m_offset);
1802 : return r;
1803 : }
1804 :
1805 : // Return a JmpSrc so we have a label to the jump, so we can use this
1806 : // To make a tail recursive call on x86-64. The MacroAssembler
1807 : // really shouldn't wrap this as a Jump, since it can't be linked. :-/
1808 579341 : JmpSrc jmp_r(RegisterID dst)
1809 : {
1810 : js::JaegerSpew(js::JSpew_Insns,
1811 : IPFX "jmp ((%s))\n", MAYBE_PAD,
1812 579341 : nameIReg(dst));
1813 579341 : m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, dst);
1814 579341 : return JmpSrc(m_formatter.size());
1815 : }
1816 :
1817 2921 : void jmp_m(int offset, RegisterID base)
1818 : {
1819 2921 : FIXME_INSN_PRINTING;
1820 2921 : m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, base, offset);
1821 2921 : }
1822 :
1823 274 : void jmp_m(int offset, RegisterID base, RegisterID index, int scale) {
1824 : js::JaegerSpew(js::JSpew_Insns,
1825 : IPFX "jmp ((%d(%s,%s,%d)))\n", MAYBE_PAD,
1826 274 : offset, nameIReg(base), nameIReg(index), scale);
1827 274 : m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, base, index, scale, offset);
1828 274 : }
1829 :
1830 7137 : JmpSrc jne()
1831 : {
1832 7137 : return jCC(ConditionNE);
1833 : }
1834 :
1835 : JmpSrc jnz()
1836 : {
1837 : // printing done by jne()
1838 : return jne();
1839 : }
1840 :
1841 525 : JmpSrc je()
1842 : {
1843 525 : FIXME_INSN_PRINTING;
1844 525 : m_formatter.twoByteOp(jccRel32(ConditionE));
1845 525 : return m_formatter.immediateRel32();
1846 : }
1847 :
1848 : JmpSrc jz()
1849 : {
1850 : // printing done by je()
1851 : return je();
1852 : }
1853 :
1854 : JmpSrc jl()
1855 : {
1856 : FIXME_INSN_PRINTING;
1857 : m_formatter.twoByteOp(jccRel32(ConditionL));
1858 : return m_formatter.immediateRel32();
1859 : }
1860 :
1861 : JmpSrc jb()
1862 : {
1863 : FIXME_INSN_PRINTING;
1864 : m_formatter.twoByteOp(jccRel32(ConditionB));
1865 : return m_formatter.immediateRel32();
1866 : }
1867 :
1868 : JmpSrc jle()
1869 : {
1870 : FIXME_INSN_PRINTING;
1871 : m_formatter.twoByteOp(jccRel32(ConditionLE));
1872 : return m_formatter.immediateRel32();
1873 : }
1874 :
1875 : JmpSrc jbe()
1876 : {
1877 : FIXME_INSN_PRINTING;
1878 : m_formatter.twoByteOp(jccRel32(ConditionBE));
1879 : return m_formatter.immediateRel32();
1880 : }
1881 :
1882 : JmpSrc jge()
1883 : {
1884 : FIXME_INSN_PRINTING;
1885 : m_formatter.twoByteOp(jccRel32(ConditionGE));
1886 : return m_formatter.immediateRel32();
1887 : }
1888 :
1889 : JmpSrc jg()
1890 : {
1891 : FIXME_INSN_PRINTING;
1892 : m_formatter.twoByteOp(jccRel32(ConditionG));
1893 : return m_formatter.immediateRel32();
1894 : }
1895 :
1896 : JmpSrc ja()
1897 : {
1898 : FIXME_INSN_PRINTING;
1899 : m_formatter.twoByteOp(jccRel32(ConditionA));
1900 : return m_formatter.immediateRel32();
1901 : }
1902 :
1903 : JmpSrc jae()
1904 : {
1905 : FIXME_INSN_PRINTING;
1906 : m_formatter.twoByteOp(jccRel32(ConditionAE));
1907 : return m_formatter.immediateRel32();
1908 : }
1909 :
1910 : JmpSrc jo()
1911 : {
1912 : FIXME_INSN_PRINTING;
1913 : m_formatter.twoByteOp(jccRel32(ConditionO));
1914 : return m_formatter.immediateRel32();
1915 : }
1916 :
1917 7662 : JmpSrc jp()
1918 : {
1919 7662 : return jCC(ConditionP);
1920 : }
1921 :
1922 : JmpSrc js()
1923 : {
1924 : FIXME_INSN_PRINTING;
1925 : m_formatter.twoByteOp(jccRel32(ConditionS));
1926 : return m_formatter.immediateRel32();
1927 : }
1928 :
1929 9015583 : JmpSrc jCC(Condition cond)
1930 : {
1931 9015583 : m_formatter.twoByteOp(jccRel32(cond));
1932 9015583 : JmpSrc r = m_formatter.immediateRel32();
1933 : js::JaegerSpew(js::JSpew_Insns,
1934 : IPFX "j%s ((%d))\n", MAYBE_PAD,
1935 9015583 : nameCC(cond), r.m_offset);
1936 : return r;
1937 : }
1938 :
1939 : // SSE operations:
1940 :
1941 529223 : void addsd_rr(XMMRegisterID src, XMMRegisterID dst)
1942 : {
1943 : js::JaegerSpew(js::JSpew_Insns,
1944 : IPFX "addsd %s, %s\n", MAYBE_PAD,
1945 529223 : nameFPReg(src), nameFPReg(dst));
1946 529223 : m_formatter.prefix(PRE_SSE_F2);
1947 529223 : m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
1948 529223 : }
1949 :
1950 195 : void addsd_mr(int offset, RegisterID base, XMMRegisterID dst)
1951 : {
1952 : js::JaegerSpew(js::JSpew_Insns,
1953 : IPFX "addsd %s0x%x(%s), %s\n", MAYBE_PAD,
1954 195 : PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
1955 195 : m_formatter.prefix(PRE_SSE_F2);
1956 195 : m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, base, offset);
1957 195 : }
1958 :
1959 341 : void cvtss2sd_rr(XMMRegisterID src, XMMRegisterID dst)
1960 : {
1961 : js::JaegerSpew(js::JSpew_Insns,
1962 : IPFX "cvtps2pd %s, %s\n", MAYBE_PAD,
1963 341 : nameFPReg(src), nameFPReg(dst));
1964 341 : m_formatter.prefix(PRE_SSE_F3);
1965 341 : m_formatter.twoByteOp(OP2_CVTSS2SD_VsdEd, (RegisterID)dst, (RegisterID)src);
1966 341 : }
1967 :
1968 104 : void cvtsd2ss_rr(XMMRegisterID src, XMMRegisterID dst)
1969 : {
1970 : js::JaegerSpew(js::JSpew_Insns,
1971 : IPFX "cvtps2pd %s, %s\n", MAYBE_PAD,
1972 104 : nameFPReg(src), nameFPReg(dst));
1973 104 : m_formatter.prefix(PRE_SSE_F2);
1974 104 : m_formatter.twoByteOp(OP2_CVTSD2SS_VsdEd, (RegisterID)dst, (RegisterID)src);
1975 104 : }
1976 :
1977 717462 : void cvtsi2sd_rr(RegisterID src, XMMRegisterID dst)
1978 : {
1979 : js::JaegerSpew(js::JSpew_Insns,
1980 : IPFX "cvtsi2sd %s, %s\n", MAYBE_PAD,
1981 717462 : nameIReg(src), nameFPReg(dst));
1982 717462 : m_formatter.prefix(PRE_SSE_F2);
1983 717462 : m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, src);
1984 717462 : }
1985 :
1986 : #if WTF_CPU_X86_64
1987 : void cvtsq2sd_rr(RegisterID src, XMMRegisterID dst)
1988 : {
1989 : js::JaegerSpew(js::JSpew_Insns,
1990 : IPFX "cvtsq2sd %s, %s\n", MAYBE_PAD,
1991 : nameIReg(src), nameFPReg(dst));
1992 : m_formatter.prefix(PRE_SSE_F2);
1993 : m_formatter.twoByteOp64(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, src);
1994 : }
1995 : #endif
1996 :
1997 24669 : void cvtsi2sd_mr(int offset, RegisterID base, XMMRegisterID dst)
1998 : {
1999 : js::JaegerSpew(js::JSpew_Insns,
2000 : IPFX "cvtsi2sd %s0x%x(%s), %s\n", MAYBE_PAD,
2001 24669 : PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
2002 24669 : m_formatter.prefix(PRE_SSE_F2);
2003 24669 : m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, base, offset);
2004 24669 : }
2005 :
2006 : #if !WTF_CPU_X86_64
2007 : void cvtsi2sd_mr(void* address, XMMRegisterID dst)
2008 : {
2009 : js::JaegerSpew(js::JSpew_Insns,
2010 : IPFX "cvtsi2sd %p, %s\n", MAYBE_PAD,
2011 : address, nameFPReg(dst));
2012 : m_formatter.prefix(PRE_SSE_F2);
2013 : m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, address);
2014 : }
2015 : #endif
2016 :
2017 13457 : void cvttsd2si_rr(XMMRegisterID src, RegisterID dst)
2018 : {
2019 : js::JaegerSpew(js::JSpew_Insns,
2020 : IPFX "cvttsd2si %s, %s\n", MAYBE_PAD,
2021 13457 : nameFPReg(src), nameIReg(dst));
2022 13457 : m_formatter.prefix(PRE_SSE_F2);
2023 13457 : m_formatter.twoByteOp(OP2_CVTTSD2SI_GdWsd, dst, (RegisterID)src);
2024 13457 : }
2025 :
2026 293 : void unpcklps_rr(XMMRegisterID src, XMMRegisterID dst)
2027 : {
2028 : js::JaegerSpew(js::JSpew_Insns,
2029 : IPFX "unpcklps %s, %s\n", MAYBE_PAD,
2030 293 : nameFPReg(src), nameFPReg(dst));
2031 293 : m_formatter.twoByteOp(OP2_UNPCKLPS_VsdWsd, (RegisterID)dst, (RegisterID)src);
2032 293 : }
2033 :
2034 1322566 : void movd_rr(RegisterID src, XMMRegisterID dst)
2035 : {
2036 : js::JaegerSpew(js::JSpew_Insns,
2037 : IPFX "movd %s, %s\n", MAYBE_PAD,
2038 1322566 : nameIReg(src), nameFPReg(dst));
2039 1322566 : m_formatter.prefix(PRE_SSE_66);
2040 1322566 : m_formatter.twoByteOp(OP2_MOVD_VdEd, (RegisterID)dst, src);
2041 1322566 : }
2042 :
2043 1113 : void psrldq_rr(XMMRegisterID dest, int shift)
2044 : {
2045 : js::JaegerSpew(js::JSpew_Insns,
2046 : IPFX "pslldq %s, %d\n", MAYBE_PAD,
2047 1113 : nameFPReg(dest), shift);
2048 1113 : m_formatter.prefix(PRE_SSE_66);
2049 1113 : m_formatter.twoByteOp(OP2_PSRLDQ_Vd, (RegisterID)3, (RegisterID)dest);
2050 1113 : m_formatter.immediate8(shift);
2051 1113 : }
2052 :
2053 2226 : void movd_rr(XMMRegisterID src, RegisterID dst)
2054 : {
2055 : js::JaegerSpew(js::JSpew_Insns,
2056 : IPFX "movd %s, %s\n", MAYBE_PAD,
2057 2226 : nameFPReg(src), nameIReg(dst));
2058 2226 : m_formatter.prefix(PRE_SSE_66);
2059 2226 : m_formatter.twoByteOp(OP2_MOVD_EdVd, (RegisterID)src, dst);
2060 2226 : }
2061 :
2062 : #if WTF_CPU_X86_64
2063 : void movq_rr(XMMRegisterID src, RegisterID dst)
2064 : {
2065 : js::JaegerSpew(js::JSpew_Insns,
2066 : IPFX "movq %s, %s\n", MAYBE_PAD,
2067 : nameFPReg(src), nameIReg(dst));
2068 : m_formatter.prefix(PRE_SSE_66);
2069 : m_formatter.twoByteOp64(OP2_MOVD_EdVd, (RegisterID)src, dst);
2070 : }
2071 :
2072 : void movq_rr(RegisterID src, XMMRegisterID dst)
2073 : {
2074 : js::JaegerSpew(js::JSpew_Insns,
2075 : IPFX "movq %s, %s\n", MAYBE_PAD,
2076 : nameIReg(src), nameFPReg(dst));
2077 : m_formatter.prefix(PRE_SSE_66);
2078 : m_formatter.twoByteOp64(OP2_MOVD_VdEd, (RegisterID)dst, src);
2079 : }
2080 : #endif
2081 :
2082 630156 : void movsd_rm(XMMRegisterID src, int offset, RegisterID base)
2083 : {
2084 : js::JaegerSpew(js::JSpew_Insns,
2085 : IPFX "movsd %s, %s0x%x(%s)\n", MAYBE_PAD,
2086 630156 : nameFPReg(src), PRETTY_PRINT_OFFSET(offset), nameIReg(base));
2087 630156 : m_formatter.prefix(PRE_SSE_F2);
2088 630156 : m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, offset);
2089 630156 : }
2090 :
2091 67 : void movss_rm(XMMRegisterID src, int offset, RegisterID base)
2092 : {
2093 : js::JaegerSpew(js::JSpew_Insns,
2094 : IPFX "movss %s, %s0x%x(%s)\n", MAYBE_PAD,
2095 67 : nameFPReg(src), PRETTY_PRINT_OFFSET(offset), nameIReg(base));
2096 67 : m_formatter.prefix(PRE_SSE_F3);
2097 67 : m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, offset);
2098 67 : }
2099 :
2100 303 : void movss_mr(int offset, RegisterID base, XMMRegisterID dst)
2101 : {
2102 : js::JaegerSpew(js::JSpew_Insns,
2103 : IPFX "movss %s0x%x(%s), %s\n", MAYBE_PAD,
2104 303 : PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
2105 303 : m_formatter.prefix(PRE_SSE_F3);
2106 303 : m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, base, offset);
2107 303 : }
2108 :
2109 1099 : void movsd_rm(XMMRegisterID src, int offset, RegisterID base, RegisterID index, int scale)
2110 : {
2111 : js::JaegerSpew(js::JSpew_Insns,
2112 : IPFX "movsd %s, %d(%s,%s,%d)\n", MAYBE_PAD,
2113 1099 : nameFPReg(src), offset, nameIReg(base), nameIReg(index), scale);
2114 1099 : m_formatter.prefix(PRE_SSE_F2);
2115 1099 : m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, index, scale, offset);
2116 1099 : }
2117 :
2118 37 : void movss_rm(XMMRegisterID src, int offset, RegisterID base, RegisterID index, int scale)
2119 : {
2120 : js::JaegerSpew(js::JSpew_Insns,
2121 : IPFX "movss %s, %d(%s,%s,%d)\n", MAYBE_PAD,
2122 37 : nameFPReg(src), offset, nameIReg(base), nameIReg(index), scale);
2123 37 : m_formatter.prefix(PRE_SSE_F3);
2124 37 : m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, index, scale, offset);
2125 37 : }
2126 :
2127 38 : void movss_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
2128 : {
2129 : js::JaegerSpew(js::JSpew_Insns,
2130 : IPFX "movss %d(%s,%s,%d), %s\n", MAYBE_PAD,
2131 38 : offset, nameIReg(base), nameIReg(index), scale, nameFPReg(dst));
2132 38 : m_formatter.prefix(PRE_SSE_F3);
2133 38 : m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, base, index, scale, offset);
2134 38 : }
2135 :
2136 52134 : void movsd_mr(int offset, RegisterID base, XMMRegisterID dst)
2137 : {
2138 : js::JaegerSpew(js::JSpew_Insns,
2139 : IPFX "movsd %s0x%x(%s), %s\n", MAYBE_PAD,
2140 52134 : PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
2141 52134 : m_formatter.prefix(PRE_SSE_F2);
2142 52134 : m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, base, offset);
2143 52134 : }
2144 :
2145 50 : void movsd_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
2146 : {
2147 : js::JaegerSpew(js::JSpew_Insns,
2148 : IPFX "movsd %d(%s,%s,%d), %s\n", MAYBE_PAD,
2149 50 : offset, nameIReg(base), nameIReg(index), scale, nameFPReg(dst));
2150 50 : m_formatter.prefix(PRE_SSE_F2);
2151 50 : m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, base, index, scale, offset);
2152 50 : }
2153 :
2154 5200 : void movsd_rr(XMMRegisterID src, XMMRegisterID dst)
2155 : {
2156 : js::JaegerSpew(js::JSpew_Insns,
2157 : IPFX "movsd %s, %s\n", MAYBE_PAD,
2158 5200 : nameFPReg(src), nameFPReg(dst));
2159 5200 : m_formatter.prefix(PRE_SSE_F2);
2160 5200 : m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
2161 5200 : }
2162 :
2163 : #if !WTF_CPU_X86_64
2164 280569 : void movsd_mr(const void* address, XMMRegisterID dst)
2165 : {
2166 : js::JaegerSpew(js::JSpew_Insns,
2167 : IPFX "movsd %p, %s\n", MAYBE_PAD,
2168 280569 : address, nameFPReg(dst));
2169 280569 : m_formatter.prefix(PRE_SSE_F2);
2170 280569 : m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, address);
2171 280569 : }
2172 : #endif
2173 :
2174 4933 : void mulsd_rr(XMMRegisterID src, XMMRegisterID dst)
2175 : {
2176 : js::JaegerSpew(js::JSpew_Insns,
2177 : IPFX "mulsd %s, %s\n", MAYBE_PAD,
2178 4933 : nameFPReg(src), nameFPReg(dst));
2179 4933 : m_formatter.prefix(PRE_SSE_F2);
2180 4933 : m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
2181 4933 : }
2182 :
2183 : void mulsd_mr(int offset, RegisterID base, XMMRegisterID dst)
2184 : {
2185 : js::JaegerSpew(js::JSpew_Insns,
2186 : IPFX "mulsd %s0x%x(%s), %s\n", MAYBE_PAD,
2187 : PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
2188 : m_formatter.prefix(PRE_SSE_F2);
2189 : m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)dst, base, offset);
2190 : }
2191 :
2192 : void pextrw_irr(int whichWord, XMMRegisterID src, RegisterID dst)
2193 : {
2194 : FIXME_INSN_PRINTING;
2195 : m_formatter.prefix(PRE_SSE_66);
2196 : m_formatter.twoByteOp(OP2_PEXTRW_GdUdIb, (RegisterID)dst, (RegisterID)src);
2197 : m_formatter.immediate8(whichWord);
2198 : }
2199 :
2200 34525 : void subsd_rr(XMMRegisterID src, XMMRegisterID dst)
2201 : {
2202 : js::JaegerSpew(js::JSpew_Insns,
2203 : IPFX "subsd %s, %s\n", MAYBE_PAD,
2204 34525 : nameFPReg(src), nameFPReg(dst));
2205 34525 : m_formatter.prefix(PRE_SSE_F2);
2206 34525 : m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
2207 34525 : }
2208 :
2209 : void subsd_mr(int offset, RegisterID base, XMMRegisterID dst)
2210 : {
2211 : js::JaegerSpew(js::JSpew_Insns,
2212 : IPFX "subsd %s0x%x(%s), %s\n", MAYBE_PAD,
2213 : PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
2214 : m_formatter.prefix(PRE_SSE_F2);
2215 : m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, base, offset);
2216 : }
2217 :
2218 63336 : void ucomisd_rr(XMMRegisterID src, XMMRegisterID dst)
2219 : {
2220 : js::JaegerSpew(js::JSpew_Insns,
2221 : IPFX "ucomisd %s, %s\n", MAYBE_PAD,
2222 63336 : nameFPReg(src), nameFPReg(dst));
2223 63336 : m_formatter.prefix(PRE_SSE_66);
2224 63336 : m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)dst, (RegisterID)src);
2225 63336 : }
2226 :
2227 : void ucomisd_mr(int offset, RegisterID base, XMMRegisterID dst)
2228 : {
2229 : js::JaegerSpew(js::JSpew_Insns,
2230 : IPFX "ucomisd %s0x%x(%s), %s\n", MAYBE_PAD,
2231 : PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
2232 : m_formatter.prefix(PRE_SSE_66);
2233 : m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)dst, base, offset);
2234 : }
2235 :
2236 7983 : void divsd_rr(XMMRegisterID src, XMMRegisterID dst)
2237 : {
2238 : js::JaegerSpew(js::JSpew_Insns,
2239 : IPFX "divsd %s, %s\n", MAYBE_PAD,
2240 7983 : nameFPReg(src), nameFPReg(dst));
2241 7983 : m_formatter.prefix(PRE_SSE_F2);
2242 7983 : m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
2243 7983 : }
2244 :
2245 : void divsd_mr(int offset, RegisterID base, XMMRegisterID dst)
2246 : {
2247 : js::JaegerSpew(js::JSpew_Insns,
2248 : IPFX "divsd %s0x%x(%s), %s\n", MAYBE_PAD,
2249 : PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
2250 : m_formatter.prefix(PRE_SSE_F2);
2251 : m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)dst, base, offset);
2252 : }
2253 :
2254 4199 : void xorpd_rr(XMMRegisterID src, XMMRegisterID dst)
2255 : {
2256 : js::JaegerSpew(js::JSpew_Insns,
2257 : IPFX "xorpd %s, %s\n", MAYBE_PAD,
2258 4199 : nameFPReg(src), nameFPReg(dst));
2259 4199 : m_formatter.prefix(PRE_SSE_66);
2260 4199 : m_formatter.twoByteOp(OP2_XORPD_VpdWpd, (RegisterID)dst, (RegisterID)src);
2261 4199 : }
2262 :
2263 85 : void andpd_rr(XMMRegisterID src, XMMRegisterID dst)
2264 : {
2265 : js::JaegerSpew(js::JSpew_Insns,
2266 : IPFX "andpd %s, %s\n", MAYBE_PAD,
2267 85 : nameFPReg(src), nameFPReg(dst));
2268 85 : m_formatter.prefix(PRE_SSE_66);
2269 85 : m_formatter.twoByteOp(OP2_ANDPD_VpdWpd, (RegisterID)dst, (RegisterID)src);
2270 85 : }
2271 :
2272 188 : void sqrtsd_rr(XMMRegisterID src, XMMRegisterID dst)
2273 : {
2274 : js::JaegerSpew(js::JSpew_Insns,
2275 : IPFX "sqrtsd %s, %s\n", MAYBE_PAD,
2276 188 : nameFPReg(src), nameFPReg(dst));
2277 188 : m_formatter.prefix(PRE_SSE_F2);
2278 188 : m_formatter.twoByteOp(OP2_SQRTSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
2279 188 : }
2280 :
2281 1321980 : void pinsrd_rr(RegisterID src, XMMRegisterID dst)
2282 : {
2283 : js::JaegerSpew(js::JSpew_Insns,
2284 : IPFX "pinsrd $1, %s, %s\n", MAYBE_PAD,
2285 1321980 : nameIReg(src), nameFPReg(dst));
2286 1321980 : m_formatter.prefix(PRE_SSE_66);
2287 1321980 : m_formatter.threeByteOp(OP3_PINSRD_VsdWsd, (RegisterID)dst, (RegisterID)src);
2288 1321980 : m_formatter.immediate8(0x01); // the $1
2289 1321980 : }
2290 :
2291 : // Misc instructions:
2292 :
2293 : void int3()
2294 : {
2295 : js::JaegerSpew(js::JSpew_Insns, IPFX "int3\n", MAYBE_PAD);
2296 : m_formatter.oneByteOp(OP_INT3);
2297 : }
2298 :
2299 112212 : void ret()
2300 : {
2301 112212 : js::JaegerSpew(js::JSpew_Insns, IPFX "ret\n", MAYBE_PAD);
2302 112212 : m_formatter.oneByteOp(OP_RET);
2303 112212 : }
2304 :
2305 : void ret(int imm)
2306 : {
2307 : js::JaegerSpew(js::JSpew_Insns,
2308 : IPFX "ret %d\n", MAYBE_PAD,
2309 : imm);
2310 : m_formatter.oneByteOp(OP_RET_Iz);
2311 : m_formatter.immediate16(imm);
2312 : }
2313 :
2314 : void predictNotTaken()
2315 : {
2316 : FIXME_INSN_PRINTING;
2317 : m_formatter.prefix(PRE_PREDICT_BRANCH_NOT_TAKEN);
2318 : }
2319 :
2320 : #if WTF_CPU_X86
2321 : void pusha()
2322 : {
2323 : js::JaegerSpew(js::JSpew_Insns, IPFX "pusha\n", MAYBE_PAD);
2324 : m_formatter.oneByteOp(OP_PUSHA);
2325 : }
2326 :
2327 : void popa()
2328 : {
2329 : js::JaegerSpew(js::JSpew_Insns, IPFX "popa\n", MAYBE_PAD);
2330 : m_formatter.oneByteOp(OP_POPA);
2331 : }
2332 : #endif
2333 :
2334 : // Assembler admin methods:
2335 :
2336 52207431 : JmpDst label()
2337 : {
2338 52207431 : JmpDst r = JmpDst(m_formatter.size());
2339 : js::JaegerSpew(js::JSpew_Insns,
2340 52207431 : IPFX "#label ((%d))\n", MAYBE_PAD, r.m_offset);
2341 : return r;
2342 : }
2343 :
2344 : static JmpDst labelFor(JmpSrc jump, intptr_t offset = 0)
2345 : {
2346 : FIXME_INSN_PRINTING;
2347 : return JmpDst(jump.m_offset + offset);
2348 : }
2349 :
2350 : JmpDst align(int alignment)
2351 : {
2352 : FIXME_INSN_PRINTING;
2353 : while (!m_formatter.isAligned(alignment))
2354 : m_formatter.oneByteOp(OP_HLT);
2355 :
2356 : return label();
2357 : }
2358 :
2359 : // Linking & patching:
2360 : //
2361 : // 'link' and 'patch' methods are for use on unprotected code - such as the code
2362 : // within the AssemblerBuffer, and code being patched by the patch buffer. Once
2363 : // code has been finalized it is (platform support permitting) within a non-
2364 : // writable region of memory; to modify the code in an execute-only execuable
2365 : // pool the 'repatch' and 'relink' methods should be used.
2366 :
2367 7602636 : void linkJump(JmpSrc from, JmpDst to)
2368 : {
2369 7602636 : ASSERT(from.m_offset != -1);
2370 7602636 : ASSERT(to.m_offset != -1);
2371 :
2372 : js::JaegerSpew(js::JSpew_Insns,
2373 : IPFX "##link ((%d)) jumps to ((%d))\n", MAYBE_PAD,
2374 7602636 : from.m_offset, to.m_offset);
2375 7602636 : char* code = reinterpret_cast<char*>(m_formatter.data());
2376 7602636 : setRel32(code + from.m_offset, code + to.m_offset);
2377 7602636 : }
2378 :
2379 9954223 : static void linkJump(void* code, JmpSrc from, void* to)
2380 : {
2381 9954223 : ASSERT(from.m_offset != -1);
2382 :
2383 : js::JaegerSpew(js::JSpew_Insns,
2384 : ISPFX "##link ((%d)) jumps to ((%p))\n",
2385 9954223 : from.m_offset, to);
2386 9954223 : setRel32(reinterpret_cast<char*>(code) + from.m_offset, to);
2387 9954223 : }
2388 :
2389 4905105 : static void linkCall(void* code, JmpSrc from, void* to)
2390 : {
2391 4905105 : ASSERT(from.m_offset != -1);
2392 :
2393 4905105 : FIXME_INSN_PRINTING;
2394 4905105 : setRel32(reinterpret_cast<char*>(code) + from.m_offset, to);
2395 4905105 : }
2396 :
2397 2325033 : static void linkPointer(void* code, JmpDst where, void* value)
2398 : {
2399 2325033 : ASSERT(where.m_offset != -1);
2400 :
2401 2325033 : FIXME_INSN_PRINTING;
2402 2325033 : setPointer(reinterpret_cast<char*>(code) + where.m_offset, value);
2403 2325033 : }
2404 :
2405 347394 : static void relinkJump(void* from, void* to)
2406 : {
2407 : js::JaegerSpew(js::JSpew_Insns,
2408 : ISPFX "##relinkJump ((from=%p)) ((to=%p))\n",
2409 347394 : from, to);
2410 347394 : setRel32(from, to);
2411 347394 : }
2412 :
2413 13004 : static bool canRelinkJump(void* from, void* to)
2414 : {
2415 13004 : intptr_t offset = reinterpret_cast<intptr_t>(to) - reinterpret_cast<intptr_t>(from);
2416 13004 : return (offset == static_cast<int32_t>(offset));
2417 : }
2418 :
2419 66466 : static void relinkCall(void* from, void* to)
2420 : {
2421 : js::JaegerSpew(js::JSpew_Insns,
2422 : ISPFX "##relinkCall ((from=%p)) ((to=%p))\n",
2423 66466 : from, to);
2424 66466 : setRel32(from, to);
2425 66466 : }
2426 :
2427 672202 : static void repatchInt32(void* where, int32_t value)
2428 : {
2429 : js::JaegerSpew(js::JSpew_Insns,
2430 : ISPFX "##relinkInt32 ((where=%p)) ((value=%d))\n",
2431 672202 : where, value);
2432 672202 : setInt32(where, value);
2433 672202 : }
2434 :
2435 355607 : static void repatchPointer(void* where, void* value)
2436 : {
2437 : js::JaegerSpew(js::JSpew_Insns,
2438 : ISPFX "##repatchPtr ((where=%p)) ((value=%p))\n",
2439 355607 : where, value);
2440 355607 : setPointer(where, value);
2441 355607 : }
2442 :
2443 101792 : static void repatchLoadPtrToLEA(void* where)
2444 : {
2445 : js::JaegerSpew(js::JSpew_Insns,
2446 : ISPFX "##repatchLoadPtrToLEA ((where=%p))\n",
2447 101792 : where);
2448 :
2449 : #if WTF_CPU_X86_64
2450 : // On x86-64 pointer memory accesses require a 64-bit operand, and as such a REX prefix.
2451 : // Skip over the prefix byte.
2452 : where = reinterpret_cast<char*>(where) + 1;
2453 : #endif
2454 101792 : *reinterpret_cast<unsigned char*>(where) = static_cast<unsigned char>(OP_LEA);
2455 101792 : }
2456 :
2457 : static void repatchLEAToLoadPtr(void* where)
2458 : {
2459 : js::JaegerSpew(js::JSpew_Insns,
2460 : ISPFX "##repatchLEAToLoadPtr ((where=%p))\n",
2461 : where);
2462 : #if WTF_CPU_X86_64
2463 : // On x86-64 pointer memory accesses require a 64-bit operand, and as such a REX prefix.
2464 : // Skip over the prefix byte.
2465 : where = reinterpret_cast<char*>(where) + 1;
2466 : #endif
2467 : *reinterpret_cast<unsigned char*>(where) = static_cast<unsigned char>(OP_MOV_GvEv);
2468 : }
2469 :
2470 4762722 : static unsigned getCallReturnOffset(JmpSrc call)
2471 : {
2472 4762722 : ASSERT(call.m_offset >= 0);
2473 4762722 : return call.m_offset;
2474 : }
2475 :
2476 2037320 : static void* getRelocatedAddress(void* code, JmpSrc jump)
2477 : {
2478 2037320 : ASSERT(jump.m_offset != -1);
2479 :
2480 2037320 : return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + jump.m_offset);
2481 : }
2482 :
2483 15988181 : static void* getRelocatedAddress(void* code, JmpDst destination)
2484 : {
2485 15988181 : ASSERT(destination.m_offset != -1);
2486 :
2487 15988181 : return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + destination.m_offset);
2488 : }
2489 :
2490 8862587 : static int getDifferenceBetweenLabels(JmpDst src, JmpDst dst)
2491 : {
2492 8862587 : return dst.m_offset - src.m_offset;
2493 : }
2494 :
2495 527351 : static int getDifferenceBetweenLabels(JmpDst src, JmpSrc dst)
2496 : {
2497 527351 : return dst.m_offset - src.m_offset;
2498 : }
2499 :
2500 : static int getDifferenceBetweenLabels(JmpSrc src, JmpDst dst)
2501 : {
2502 : return dst.m_offset - src.m_offset;
2503 : }
2504 :
2505 373153 : void* executableAllocAndCopy(ExecutableAllocator* allocator, ExecutablePool **poolp, CodeKind kind)
2506 : {
2507 373153 : return m_formatter.executableAllocAndCopy(allocator, poolp, kind);
2508 : }
2509 :
2510 257654 : void executableCopy(void* buffer)
2511 : {
2512 257654 : memcpy(buffer, m_formatter.buffer(), size());
2513 257654 : }
2514 :
2515 : private:
2516 :
2517 2680640 : static void setPointer(void* where, void* value)
2518 : {
2519 : js::JaegerSpew(js::JSpew_Insns,
2520 2680640 : ISPFX "##setPtr ((where=%p)) ((value=%p))\n", where, value);
2521 2680640 : reinterpret_cast<void**>(where)[-1] = value;
2522 2680640 : }
2523 :
2524 23548026 : static void setInt32(void* where, int32_t value)
2525 : {
2526 23548026 : reinterpret_cast<int32_t*>(where)[-1] = value;
2527 23548026 : }
2528 :
2529 22875824 : static void setRel32(void* from, void* to)
2530 : {
2531 22875824 : intptr_t offset = reinterpret_cast<intptr_t>(to) - reinterpret_cast<intptr_t>(from);
2532 : ASSERT(offset == static_cast<int32_t>(offset));
2533 : #define JS_CRASH(x) *(int *)x = 0
2534 : if (offset != static_cast<int32_t>(offset))
2535 : JS_CRASH(0xC0DE);
2536 : #undef JS_CRASH
2537 :
2538 : js::JaegerSpew(js::JSpew_Insns,
2539 22875824 : ISPFX "##setRel32 ((from=%p)) ((to=%p))\n", from, to);
2540 22875824 : setInt32(from, offset);
2541 22875824 : }
2542 :
2543 1526632 : class X86InstructionFormatter {
2544 :
2545 : static const int maxInstructionSize = 16;
2546 :
2547 : public:
2548 :
2549 : // Legacy prefix bytes:
2550 : //
2551 : // These are emmitted prior to the instruction.
2552 :
2553 5075928 : void prefix(OneByteOpcodeID pre)
2554 : {
2555 5075928 : m_buffer.putByte(pre);
2556 5075928 : }
2557 :
2558 : // Word-sized operands / no operand instruction formatters.
2559 : //
2560 : // In addition to the opcode, the following operand permutations are supported:
2561 : // * None - instruction takes no operands.
2562 : // * One register - the low three bits of the RegisterID are added into the opcode.
2563 : // * 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).
2564 : // * Three argument ModRM - a register, and a register and an offset describing a memory operand.
2565 : // * Five argument ModRM - a register, and a base register, an index, scale, and offset describing a memory operand.
2566 : //
2567 : // For 32-bit x86 targets, the address operand may also be provided as a void*.
2568 : // On 64-bit targets REX prefixes will be planted as necessary, where high numbered registers are used.
2569 : //
2570 : // The twoByteOp methods plant two-byte Intel instructions sequences (first opcode byte 0x0F).
2571 :
2572 13714467 : void oneByteOp(OneByteOpcodeID opcode)
2573 : {
2574 13714467 : m_buffer.ensureSpace(maxInstructionSize);
2575 13714467 : m_buffer.putByteUnchecked(opcode);
2576 13714467 : }
2577 :
2578 4399051 : void oneByteOp(OneByteOpcodeID opcode, RegisterID reg)
2579 : {
2580 4399051 : m_buffer.ensureSpace(maxInstructionSize);
2581 4399051 : emitRexIfNeeded(0, 0, reg);
2582 4399051 : m_buffer.putByteUnchecked(opcode + (reg & 7));
2583 4399051 : }
2584 :
2585 25328339 : void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID rm)
2586 : {
2587 25328339 : m_buffer.ensureSpace(maxInstructionSize);
2588 25328339 : emitRexIfNeeded(reg, 0, rm);
2589 25328339 : m_buffer.putByteUnchecked(opcode);
2590 25328339 : registerModRM(reg, rm);
2591 25328339 : }
2592 :
2593 66247539 : void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
2594 : {
2595 66247539 : m_buffer.ensureSpace(maxInstructionSize);
2596 66247539 : emitRexIfNeeded(reg, 0, base);
2597 66247539 : m_buffer.putByteUnchecked(opcode);
2598 66247539 : memoryModRM(reg, base, offset);
2599 66247539 : }
2600 :
2601 : void oneByteOp_disp32(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
2602 : {
2603 : m_buffer.ensureSpace(maxInstructionSize);
2604 : emitRexIfNeeded(reg, 0, base);
2605 : m_buffer.putByteUnchecked(opcode);
2606 : memoryModRM_disp32(reg, base, offset);
2607 : }
2608 :
2609 211427 : void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
2610 : {
2611 211427 : m_buffer.ensureSpace(maxInstructionSize);
2612 211427 : emitRexIfNeeded(reg, index, base);
2613 211427 : m_buffer.putByteUnchecked(opcode);
2614 211427 : memoryModRM(reg, base, index, scale, offset);
2615 211427 : }
2616 :
2617 : #if !WTF_CPU_X86_64
2618 837516 : void oneByteOp(OneByteOpcodeID opcode, int reg, void* address)
2619 : {
2620 837516 : m_buffer.ensureSpace(maxInstructionSize);
2621 837516 : m_buffer.putByteUnchecked(opcode);
2622 837516 : memoryModRM(reg, address);
2623 837516 : }
2624 : #endif
2625 :
2626 9016108 : void twoByteOp(TwoByteOpcodeID opcode)
2627 : {
2628 9016108 : m_buffer.ensureSpace(maxInstructionSize);
2629 9016108 : m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
2630 9016108 : m_buffer.putByteUnchecked(opcode);
2631 9016108 : }
2632 :
2633 2709173 : void twoByteOp(TwoByteOpcodeID opcode, int reg, RegisterID rm)
2634 : {
2635 2709173 : m_buffer.ensureSpace(maxInstructionSize);
2636 2709173 : emitRexIfNeeded(reg, 0, rm);
2637 2709173 : m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
2638 2709173 : m_buffer.putByteUnchecked(opcode);
2639 2709173 : registerModRM(reg, rm);
2640 2709173 : }
2641 :
2642 856200 : void twoByteOp(TwoByteOpcodeID opcode, int reg, RegisterID base, int offset)
2643 : {
2644 856200 : m_buffer.ensureSpace(maxInstructionSize);
2645 856200 : emitRexIfNeeded(reg, 0, base);
2646 856200 : m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
2647 856200 : m_buffer.putByteUnchecked(opcode);
2648 856200 : memoryModRM(reg, base, offset);
2649 856200 : }
2650 :
2651 64327 : void twoByteOp(TwoByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
2652 : {
2653 64327 : m_buffer.ensureSpace(maxInstructionSize);
2654 64327 : emitRexIfNeeded(reg, index, base);
2655 64327 : m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
2656 64327 : m_buffer.putByteUnchecked(opcode);
2657 64327 : memoryModRM(reg, base, index, scale, offset);
2658 64327 : }
2659 :
2660 : #if !WTF_CPU_X86_64
2661 280569 : void twoByteOp(TwoByteOpcodeID opcode, int reg, const void* address)
2662 : {
2663 280569 : m_buffer.ensureSpace(maxInstructionSize);
2664 280569 : m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
2665 280569 : m_buffer.putByteUnchecked(opcode);
2666 280569 : memoryModRM(reg, address);
2667 280569 : }
2668 : #endif
2669 :
2670 1321980 : void threeByteOp(ThreeByteOpcodeID opcode, int reg, RegisterID rm)
2671 : {
2672 1321980 : m_buffer.ensureSpace(maxInstructionSize);
2673 1321980 : emitRexIfNeeded(reg, 0, rm);
2674 1321980 : m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
2675 1321980 : m_buffer.putByteUnchecked(OP_3BYTE_ESCAPE);
2676 1321980 : m_buffer.putByteUnchecked(opcode);
2677 1321980 : registerModRM(reg, rm);
2678 1321980 : }
2679 :
2680 : #if WTF_CPU_X86_64
2681 : // Quad-word-sized operands:
2682 : //
2683 : // Used to format 64-bit operantions, planting a REX.w prefix.
2684 : // When planting d64 or f64 instructions, not requiring a REX.w prefix,
2685 : // the normal (non-'64'-postfixed) formatters should be used.
2686 :
2687 : void oneByteOp64(OneByteOpcodeID opcode)
2688 : {
2689 : m_buffer.ensureSpace(maxInstructionSize);
2690 : emitRexW(0, 0, 0);
2691 : m_buffer.putByteUnchecked(opcode);
2692 : }
2693 :
2694 : void oneByteOp64(OneByteOpcodeID opcode, RegisterID reg)
2695 : {
2696 : m_buffer.ensureSpace(maxInstructionSize);
2697 : emitRexW(0, 0, reg);
2698 : m_buffer.putByteUnchecked(opcode + (reg & 7));
2699 : }
2700 :
2701 : void oneByteOp64(OneByteOpcodeID opcode, int reg, RegisterID rm)
2702 : {
2703 : m_buffer.ensureSpace(maxInstructionSize);
2704 : emitRexW(reg, 0, rm);
2705 : m_buffer.putByteUnchecked(opcode);
2706 : registerModRM(reg, rm);
2707 : }
2708 :
2709 : void oneByteOp64(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
2710 : {
2711 : m_buffer.ensureSpace(maxInstructionSize);
2712 : emitRexW(reg, 0, base);
2713 : m_buffer.putByteUnchecked(opcode);
2714 : memoryModRM(reg, base, offset);
2715 : }
2716 :
2717 : void oneByteOp64_disp32(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
2718 : {
2719 : m_buffer.ensureSpace(maxInstructionSize);
2720 : emitRexW(reg, 0, base);
2721 : m_buffer.putByteUnchecked(opcode);
2722 : memoryModRM_disp32(reg, base, offset);
2723 : }
2724 :
2725 : void oneByteOp64(OneByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
2726 : {
2727 : m_buffer.ensureSpace(maxInstructionSize);
2728 : emitRexW(reg, index, base);
2729 : m_buffer.putByteUnchecked(opcode);
2730 : memoryModRM(reg, base, index, scale, offset);
2731 : }
2732 :
2733 : void twoByteOp64(TwoByteOpcodeID opcode, int reg, RegisterID rm)
2734 : {
2735 : m_buffer.ensureSpace(maxInstructionSize);
2736 : emitRexW(reg, 0, rm);
2737 : m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
2738 : m_buffer.putByteUnchecked(opcode);
2739 : registerModRM(reg, rm);
2740 : }
2741 : #endif
2742 :
2743 : // Byte-operands:
2744 : //
2745 : // These methods format byte operations. Byte operations differ from the normal
2746 : // formatters in the circumstances under which they will decide to emit REX prefixes.
2747 : // These should be used where any register operand signifies a byte register.
2748 : //
2749 : // The disctinction is due to the handling of register numbers in the range 4..7 on
2750 : // x86-64. These register numbers may either represent the second byte of the first
2751 : // four registers (ah..bh) or the first byte of the second four registers (spl..dil).
2752 : //
2753 : // Since ah..bh cannot be used in all permutations of operands (specifically cannot
2754 : // be accessed where a REX prefix is present), these are likely best treated as
2755 : // deprecated. In order to ensure the correct registers spl..dil are selected a
2756 : // REX prefix will be emitted for any byte register operand in the range 4..15.
2757 : //
2758 : // These formatters may be used in instructions where a mix of operand sizes, in which
2759 : // case an unnecessary REX will be emitted, for example:
2760 : // movzbl %al, %edi
2761 : // In this case a REX will be planted since edi is 7 (and were this a byte operand
2762 : // a REX would be required to specify dil instead of bh). Unneeded REX prefixes will
2763 : // be silently ignored by the processor.
2764 : //
2765 : // Address operands should still be checked using regRequiresRex(), while byteRegRequiresRex()
2766 : // is provided to check byte register operands.
2767 :
2768 14215 : void oneByteOp8(OneByteOpcodeID opcode, GroupOpcodeID groupOp, RegisterID rm)
2769 : {
2770 : #if !WTF_CPU_X86_64
2771 14215 : ASSERT(!byteRegRequiresRex(rm));
2772 : #endif
2773 14215 : m_buffer.ensureSpace(maxInstructionSize);
2774 14215 : emitRexIf(byteRegRequiresRex(rm), 0, 0, rm);
2775 14215 : m_buffer.putByteUnchecked(opcode);
2776 14215 : registerModRM(groupOp, rm);
2777 14215 : }
2778 :
2779 27 : void oneByteOp8(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
2780 : {
2781 : #if !WTF_CPU_X86_64
2782 27 : ASSERT(!byteRegRequiresRex(reg));
2783 : #endif
2784 27 : m_buffer.ensureSpace(maxInstructionSize);
2785 27 : emitRexIf(byteRegRequiresRex(reg), reg, 0, base);
2786 27 : m_buffer.putByteUnchecked(opcode);
2787 27 : memoryModRM(reg, base, offset);
2788 27 : }
2789 :
2790 147 : void oneByteOp8(OneByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
2791 : {
2792 : #if !WTF_CPU_X86_64
2793 147 : ASSERT(!byteRegRequiresRex(reg));
2794 : #endif
2795 147 : m_buffer.ensureSpace(maxInstructionSize);
2796 147 : emitRexIf(byteRegRequiresRex(reg), reg, index, base);
2797 147 : m_buffer.putByteUnchecked(opcode);
2798 147 : memoryModRM(reg, base, index, scale, offset);
2799 147 : }
2800 :
2801 43691 : void twoByteOp8(TwoByteOpcodeID opcode, RegisterID reg, RegisterID rm)
2802 : {
2803 43691 : m_buffer.ensureSpace(maxInstructionSize);
2804 43691 : emitRexIf(byteRegRequiresRex(reg)|byteRegRequiresRex(rm), reg, 0, rm);
2805 43691 : m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
2806 43691 : m_buffer.putByteUnchecked(opcode);
2807 43691 : registerModRM(reg, rm);
2808 43691 : }
2809 :
2810 43691 : void twoByteOp8(TwoByteOpcodeID opcode, GroupOpcodeID groupOp, RegisterID rm)
2811 : {
2812 43691 : m_buffer.ensureSpace(maxInstructionSize);
2813 43691 : emitRexIf(byteRegRequiresRex(rm), 0, 0, rm);
2814 43691 : m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
2815 43691 : m_buffer.putByteUnchecked(opcode);
2816 43691 : registerModRM(groupOp, rm);
2817 43691 : }
2818 :
2819 : // Immediates:
2820 : //
2821 : // An immedaite should be appended where appropriate after an op has been emitted.
2822 : // The writes are unchecked since the opcode formatters above will have ensured space.
2823 :
2824 11909683 : void immediate8(int imm)
2825 : {
2826 11909683 : m_buffer.putByteUnchecked(imm);
2827 11909683 : }
2828 :
2829 281 : void immediate16(int imm)
2830 : {
2831 281 : m_buffer.putShortUnchecked(imm);
2832 281 : }
2833 :
2834 20756541 : void immediate32(int imm)
2835 : {
2836 20756541 : m_buffer.putIntUnchecked(imm);
2837 20756541 : }
2838 :
2839 : void immediate64(int64_t imm)
2840 : {
2841 : m_buffer.putInt64Unchecked(imm);
2842 : }
2843 :
2844 22612652 : JmpSrc immediateRel32()
2845 : {
2846 22612652 : m_buffer.putIntUnchecked(0);
2847 22612652 : return JmpSrc(m_buffer.size());
2848 : }
2849 :
2850 : // Administrative methods:
2851 :
2852 60658848 : size_t size() const { return m_buffer.size(); }
2853 257654 : unsigned char *buffer() const { return m_buffer.buffer(); }
2854 2260344 : bool oom() const { return m_buffer.oom(); }
2855 : bool isAligned(int alignment) const { return m_buffer.isAligned(alignment); }
2856 7602636 : void* data() const { return m_buffer.data(); }
2857 373153 : void* executableAllocAndCopy(ExecutableAllocator* allocator, ExecutablePool** poolp, CodeKind kind) {
2858 373153 : return m_buffer.executableAllocAndCopy(allocator, poolp, kind);
2859 : }
2860 :
2861 : private:
2862 :
2863 : // Internals; ModRm and REX formatters.
2864 :
2865 : // Byte operand register spl & above require a REX prefix (to prevent the 'H' registers be accessed).
2866 159851 : inline bool byteRegRequiresRex(int reg)
2867 : {
2868 159851 : return (reg >= X86Registers::esp);
2869 : }
2870 :
2871 : static const RegisterID noBase = X86Registers::ebp;
2872 : static const RegisterID hasSib = X86Registers::esp;
2873 : static const RegisterID noIndex = X86Registers::esp;
2874 : #if WTF_CPU_X86_64
2875 : static const RegisterID noBase2 = X86Registers::r13;
2876 : static const RegisterID hasSib2 = X86Registers::r12;
2877 :
2878 : // Registers r8 & above require a REX prefixe.
2879 : inline bool regRequiresRex(int reg)
2880 : {
2881 : return (reg >= X86Registers::r8);
2882 : }
2883 :
2884 : // Format a REX prefix byte.
2885 : inline void emitRex(bool w, int r, int x, int b)
2886 : {
2887 : m_buffer.putByteUnchecked(PRE_REX | ((int)w << 3) | ((r>>3)<<2) | ((x>>3)<<1) | (b>>3));
2888 : }
2889 :
2890 : // Used to plant a REX byte with REX.w set (for 64-bit operations).
2891 : inline void emitRexW(int r, int x, int b)
2892 : {
2893 : emitRex(true, r, x, b);
2894 : }
2895 :
2896 : // Used for operations with byte operands - use byteRegRequiresRex() to check register operands,
2897 : // regRequiresRex() to check other registers (i.e. address base & index).
2898 : //
2899 : // NB: WebKit's use of emitRexIf() is limited such that the reqRequiresRex() checks are
2900 : // not needed. SpiderMonkey extends oneByteOp8 functionality such that r, x, and b can
2901 : // all be used.
2902 : inline void emitRexIf(bool condition, int r, int x, int b)
2903 : {
2904 : if (condition || regRequiresRex(r) || regRequiresRex(x) || regRequiresRex(b))
2905 : emitRex(false, r, x, b);
2906 : }
2907 :
2908 : // Used for word sized operations, will plant a REX prefix if necessary (if any register is r8 or above).
2909 : inline void emitRexIfNeeded(int r, int x, int b)
2910 : {
2911 : emitRexIf(regRequiresRex(r) || regRequiresRex(x) || regRequiresRex(b), r, x, b);
2912 : }
2913 : #else
2914 : // No REX prefix bytes on 32-bit x86.
2915 : inline bool regRequiresRex(int) { return false; }
2916 101771 : inline void emitRexIf(bool, int, int, int) {}
2917 101138036 : inline void emitRexIfNeeded(int, int, int) {}
2918 : #endif
2919 :
2920 : enum ModRmMode {
2921 : ModRmMemoryNoDisp,
2922 : ModRmMemoryDisp8,
2923 : ModRmMemoryDisp32,
2924 : ModRmRegister
2925 : };
2926 :
2927 97958841 : void putModRm(ModRmMode mode, int reg, RegisterID rm)
2928 : {
2929 97958841 : m_buffer.putByteUnchecked((mode << 6) | ((reg & 7) << 3) | (rm & 7));
2930 97958841 : }
2931 :
2932 21907425 : void putModRmSib(ModRmMode mode, int reg, RegisterID base, RegisterID index, int scale)
2933 : {
2934 21907425 : ASSERT(mode != ModRmRegister);
2935 :
2936 21907425 : putModRm(mode, reg, hasSib);
2937 21907425 : m_buffer.putByteUnchecked((scale << 6) | ((index & 7) << 3) | (base & 7));
2938 21907425 : }
2939 :
2940 29461089 : void registerModRM(int reg, RegisterID rm)
2941 : {
2942 29461089 : putModRm(ModRmRegister, reg, rm);
2943 29461089 : }
2944 :
2945 67103766 : void memoryModRM(int reg, RegisterID base, int offset)
2946 : {
2947 : // A base of esp or r12 would be interpreted as a sib, so force a sib with no index & put the base in there.
2948 : #if WTF_CPU_X86_64
2949 : if ((base == hasSib) || (base == hasSib2))
2950 : #else
2951 67103766 : if (base == hasSib)
2952 : #endif
2953 : {
2954 21631524 : if (!offset) // No need to check if the base is noBase, since we know it is hasSib!
2955 91969 : putModRmSib(ModRmMemoryNoDisp, reg, base, noIndex, 0);
2956 21539555 : else if (CAN_SIGN_EXTEND_8_32(offset)) {
2957 21539555 : putModRmSib(ModRmMemoryDisp8, reg, base, noIndex, 0);
2958 21539555 : m_buffer.putByteUnchecked(offset);
2959 : } else {
2960 0 : putModRmSib(ModRmMemoryDisp32, reg, base, noIndex, 0);
2961 0 : m_buffer.putIntUnchecked(offset);
2962 : }
2963 : } else {
2964 : #if WTF_CPU_X86_64
2965 : if (!offset && (base != noBase) && (base != noBase2))
2966 : #else
2967 45472242 : if (!offset && (base != noBase))
2968 : #endif
2969 1737197 : putModRm(ModRmMemoryNoDisp, reg, base);
2970 43735045 : else if (CAN_SIGN_EXTEND_8_32(offset)) {
2971 36530737 : putModRm(ModRmMemoryDisp8, reg, base);
2972 36530737 : m_buffer.putByteUnchecked(offset);
2973 : } else {
2974 7204308 : putModRm(ModRmMemoryDisp32, reg, base);
2975 7204308 : m_buffer.putIntUnchecked(offset);
2976 : }
2977 : }
2978 67103766 : }
2979 :
2980 : void memoryModRM_disp32(int reg, RegisterID base, int offset)
2981 : {
2982 : // A base of esp or r12 would be interpreted as a sib, so force a sib with no index & put the base in there.
2983 : #if WTF_CPU_X86_64
2984 : if ((base == hasSib) || (base == hasSib2))
2985 : #else
2986 : if (base == hasSib)
2987 : #endif
2988 : {
2989 : putModRmSib(ModRmMemoryDisp32, reg, base, noIndex, 0);
2990 : m_buffer.putIntUnchecked(offset);
2991 : } else {
2992 : putModRm(ModRmMemoryDisp32, reg, base);
2993 : m_buffer.putIntUnchecked(offset);
2994 : }
2995 : }
2996 :
2997 275901 : void memoryModRM(int reg, RegisterID base, RegisterID index, int scale, int offset)
2998 : {
2999 275901 : ASSERT(index != noIndex);
3000 :
3001 : #if WTF_CPU_X86_64
3002 : if (!offset && (base != noBase) && (base != noBase2))
3003 : #else
3004 275901 : if (!offset && (base != noBase))
3005 : #endif
3006 69719 : putModRmSib(ModRmMemoryNoDisp, reg, base, index, scale);
3007 206182 : else if (CAN_SIGN_EXTEND_8_32(offset)) {
3008 206182 : putModRmSib(ModRmMemoryDisp8, reg, base, index, scale);
3009 206182 : m_buffer.putByteUnchecked(offset);
3010 : } else {
3011 0 : putModRmSib(ModRmMemoryDisp32, reg, base, index, scale);
3012 0 : m_buffer.putIntUnchecked(offset);
3013 : }
3014 275901 : }
3015 :
3016 : #if !WTF_CPU_X86_64
3017 1118085 : void memoryModRM(int reg, const void* address)
3018 : {
3019 : // noBase + ModRmMemoryNoDisp means noBase + ModRmMemoryDisp32!
3020 1118085 : putModRm(ModRmMemoryNoDisp, reg, noBase);
3021 1118085 : m_buffer.putIntUnchecked(reinterpret_cast<int32_t>(address));
3022 1118085 : }
3023 : #endif
3024 :
3025 : AssemblerBuffer m_buffer;
3026 : } m_formatter;
3027 : };
3028 :
3029 : } // namespace JSC
3030 :
3031 : #endif // ENABLE(ASSEMBLER) && CPU(X86)
3032 :
3033 : #endif // X86Assembler_h
|