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