Changeset 39316 in webkit for trunk/JavaScriptCore/assembler/X86Assembler.h
- Timestamp:
- Dec 15, 2008, 3:38:19 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/assembler/X86Assembler.h
r39287 r39316 38 38 namespace JSC { 39 39 40 #define MODRM(type, reg, rm) ((type << 6) | (reg << 3) | (rm))41 #define SIB(type, reg, rm) MODRM(type, reg, rm)42 40 #define CAN_SIGN_EXTEND_8_32(value) (value == ((int)(signed char)value)) 43 41 … … 53 51 edi, 54 52 55 noBase = ebp, 56 hasSib = esp, 57 noScale = esp, 53 #if PLATFORM(X86_64) 54 r8, 55 r9, 56 r10, 57 r11, 58 r12, 59 r13, 60 r14, 61 r15, 62 #endif 58 63 } RegisterID; 59 64 … … 88 93 OP_CMP_EvGv = 0x39, 89 94 OP_CMP_GvEv = 0x3B, 90 REX_W = 0x48, 95 #if PLATFORM(X86_64) 96 PRE_REX = 0x40, 97 #endif 91 98 OP_PUSH_EAX = 0x50, 92 99 OP_POP_EAX = 0x58, … … 104 111 OP_GROUP1A_Ev = 0x8F, 105 112 OP_CDQ = 0x99, 106 OP_SETE = 0x94,107 OP_SETNE = 0x95,108 113 OP_GROUP2_EvIb = 0xC1, 109 114 OP_RET = 0xC3, … … 120 125 OP_GROUP3_EvIz = 0xF7, // OP_GROUP3_Ev has an immediate, when instruction is a test. 121 126 OP_GROUP5_Ev = 0xFF, 122 127 } OneByteOpcodeID; 128 129 typedef enum { 123 130 OP2_MOVSD_VsdWsd = 0x10, 124 131 OP2_MOVSD_WsdVsd = 0x11, … … 143 150 OP2_JLE_rel32 = 0x8E, 144 151 OP2_JG_rel32 = 0x8F, 152 OP_SETE = 0x94, 153 OP_SETNE = 0x95, 145 154 OP2_IMUL_GvEv = 0xAF, 146 155 OP2_MOVZX_GvEb = 0xB6, 147 156 OP2_MOVZX_GvEw = 0xB7, 148 157 OP2_PEXTRW_GdUdIb = 0xC5, 149 158 } TwoByteOpcodeID; 159 160 typedef enum { 150 161 GROUP1_OP_ADD = 0, 151 162 GROUP1_OP_OR = 1, … … 168 179 169 180 GROUP11_MOV = 0, 170 } OpcodeID;181 } GroupOpcodeID; 171 182 172 183 // Opaque label types 173 184 185 class X86InstructionFormatter; 186 174 187 class JmpSrc { 175 188 friend class X86Assembler; 189 friend class X86InstructionFormatter; 176 190 public: 177 191 JmpSrc() … … 191 205 class JmpDst { 192 206 friend class X86Assembler; 207 friend class X86InstructionFormatter; 193 208 public: 194 209 JmpDst() … … 206 221 }; 207 222 208 static const int maxInstructionSize = 16;209 210 223 X86Assembler() 211 224 { 212 225 } 213 226 214 size_t size() const { return m_buffer.size(); } 215 216 void int3() 217 { 218 m_buffer.putByte(OP_INT3); 219 } 220 227 size_t size() const { return m_formatter.size(); } 228 229 // Stack operations: 230 231 void push_r(RegisterID reg) 232 { 233 m_formatter.oneByteOp(OP_PUSH_EAX, reg); 234 } 235 236 void pop_r(RegisterID reg) 237 { 238 m_formatter.oneByteOp(OP_POP_EAX, reg); 239 } 240 241 void push_i32(int imm) 242 { 243 m_formatter.oneByteOp(OP_PUSH_Iz); 244 m_formatter.immediate32(imm); 245 } 246 247 void push_m(int offset, RegisterID base) 248 { 249 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_PUSH, base, offset); 250 } 251 252 void pop_m(int offset, RegisterID base) 253 { 254 m_formatter.oneByteOp(OP_GROUP1A_Ev, GROUP1A_OP_POP, base, offset); 255 } 256 257 // Arithmetic operations: 258 259 void addl_rr(RegisterID src, RegisterID dst) 260 { 261 m_formatter.oneByteOp(OP_ADD_EvGv, src, dst); 262 } 263 264 void addl_mr(int offset, RegisterID base, RegisterID dst) 265 { 266 m_formatter.oneByteOp(OP_ADD_GvEv, dst, base, offset); 267 } 268 269 void addl_ir(int imm, RegisterID dst) 270 { 271 if (CAN_SIGN_EXTEND_8_32(imm)) { 272 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, dst); 273 m_formatter.immediate8(imm); 274 } else { 275 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, dst); 276 m_formatter.immediate32(imm); 277 } 278 } 279 221 280 #if PLATFORM(X86_64) 222 void pushq_r(RegisterID reg) 223 { 224 m_buffer.putByte(OP_PUSH_EAX + reg); 225 } 226 227 void popq_r(RegisterID reg) 228 { 229 m_buffer.putByte(OP_POP_EAX + reg); 281 void addq_ir(int imm, RegisterID dst) 282 { 283 if (CAN_SIGN_EXTEND_8_32(imm)) { 284 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_ADD, dst); 285 m_formatter.immediate8(imm); 286 } else { 287 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_ADD, dst); 288 m_formatter.immediate32(imm); 289 } 230 290 } 231 291 #else 232 void pushl_r(RegisterID reg) 233 { 234 m_buffer.putByte(OP_PUSH_EAX + reg); 235 } 236 237 void pushl_m(int offset, RegisterID base) 238 { 239 m_buffer.putByte(OP_GROUP5_Ev); 240 modRm_opm(GROUP5_OP_PUSH, base, offset); 241 } 242 243 void pushl_i32(int imm) 244 { 245 m_buffer.putByte(OP_PUSH_Iz); 246 m_buffer.putInt(imm); 247 } 248 249 void popl_r(RegisterID reg) 250 { 251 m_buffer.putByte(OP_POP_EAX + reg); 252 } 253 254 void popl_m(int offset, RegisterID base) 255 { 256 m_buffer.putByte(OP_GROUP1A_Ev); 257 modRm_opm(GROUP1A_OP_POP, base, offset); 292 void addl_im(int imm, void* addr) 293 { 294 if (CAN_SIGN_EXTEND_8_32(imm)) { 295 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, addr); 296 m_formatter.immediate8(imm); 297 } else { 298 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, addr); 299 m_formatter.immediate32(imm); 300 } 258 301 } 259 302 #endif 260 303 304 void andl_rr(RegisterID src, RegisterID dst) 305 { 306 m_formatter.oneByteOp(OP_AND_EvGv, src, dst); 307 } 308 309 void andl_ir(int imm, RegisterID dst) 310 { 311 if (CAN_SIGN_EXTEND_8_32(imm)) { 312 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, dst); 313 m_formatter.immediate8(imm); 314 } else { 315 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, dst); 316 m_formatter.immediate32(imm); 317 } 318 } 319 320 void orl_rr(RegisterID src, RegisterID dst) 321 { 322 m_formatter.oneByteOp(OP_OR_EvGv, src, dst); 323 } 324 325 void orl_mr(int offset, RegisterID base, RegisterID dst) 326 { 327 m_formatter.oneByteOp(OP_OR_GvEv, dst, base, offset); 328 } 329 330 void orl_ir(int imm, RegisterID dst) 331 { 332 if (CAN_SIGN_EXTEND_8_32(imm)) { 333 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, dst); 334 m_formatter.immediate8(imm); 335 } else { 336 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, dst); 337 m_formatter.immediate32(imm); 338 } 339 } 340 341 void subl_rr(RegisterID src, RegisterID dst) 342 { 343 m_formatter.oneByteOp(OP_SUB_EvGv, src, dst); 344 } 345 346 void subl_mr(int offset, RegisterID base, RegisterID dst) 347 { 348 m_formatter.oneByteOp(OP_SUB_GvEv, dst, base, offset); 349 } 350 351 void subl_ir(int imm, RegisterID dst) 352 { 353 if (CAN_SIGN_EXTEND_8_32(imm)) { 354 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, dst); 355 m_formatter.immediate8(imm); 356 } else { 357 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, dst); 358 m_formatter.immediate32(imm); 359 } 360 } 361 362 #if !PLATFORM(X86_64) 363 void subl_im(int imm, void* addr) 364 { 365 if (CAN_SIGN_EXTEND_8_32(imm)) { 366 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, addr); 367 m_formatter.immediate8(imm); 368 } else { 369 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, addr); 370 m_formatter.immediate32(imm); 371 } 372 } 373 #endif 374 375 void xorl_rr(RegisterID src, RegisterID dst) 376 { 377 m_formatter.oneByteOp(OP_XOR_EvGv, src, dst); 378 } 379 380 void xorl_ir(int imm, RegisterID dst) 381 { 382 if (CAN_SIGN_EXTEND_8_32(imm)) { 383 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_XOR, dst); 384 m_formatter.immediate8(imm); 385 } else { 386 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_XOR, dst); 387 m_formatter.immediate32(imm); 388 } 389 } 390 391 void sarl_i8r(int imm, RegisterID dst) 392 { 393 if (imm == 1) 394 m_formatter.oneByteOp(OP_GROUP2_Ev1, GROUP2_OP_SAR, dst); 395 else { 396 m_formatter.oneByteOp(OP_GROUP2_EvIb, GROUP2_OP_SAR, dst); 397 m_formatter.immediate8(imm); 398 } 399 } 400 401 void sarl_CLr(RegisterID dst) 402 { 403 m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SAR, dst); 404 } 405 406 void shll_i8r(int imm, RegisterID dst) 407 { 408 if (imm == 1) 409 m_formatter.oneByteOp(OP_GROUP2_Ev1, GROUP2_OP_SHL, dst); 410 else { 411 m_formatter.oneByteOp(OP_GROUP2_EvIb, GROUP2_OP_SHL, dst); 412 m_formatter.immediate8(imm); 413 } 414 } 415 416 void shll_CLr(RegisterID dst) 417 { 418 m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SHL, dst); 419 } 420 421 void imull_rr(RegisterID src, RegisterID dst) 422 { 423 m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, src); 424 } 425 426 void imull_i32r(RegisterID src, int32_t value, RegisterID dst) 427 { 428 m_formatter.oneByteOp(OP_IMUL_GvEvIz, dst, src); 429 m_formatter.immediate32(value); 430 } 431 432 void idivl_r(RegisterID dst) 433 { 434 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_IDIV, dst); 435 } 436 437 // Comparisons: 438 439 void cmpl_rr(RegisterID src, RegisterID dst) 440 { 441 m_formatter.oneByteOp(OP_CMP_EvGv, src, dst); 442 } 443 444 void cmpl_rm(RegisterID src, int offset, RegisterID base) 445 { 446 m_formatter.oneByteOp(OP_CMP_EvGv, src, base, offset); 447 } 448 449 void cmpl_mr(int offset, RegisterID base, RegisterID src) 450 { 451 m_formatter.oneByteOp(OP_CMP_GvEv, src, base, offset); 452 } 453 454 void cmpl_ir(int imm, RegisterID dst) 455 { 456 if (CAN_SIGN_EXTEND_8_32(imm)) { 457 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, dst); 458 m_formatter.immediate8(imm); 459 } else { 460 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst); 461 m_formatter.immediate32(imm); 462 } 463 } 464 465 void cmpl_ir_force32(int imm, RegisterID dst) 466 { 467 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst); 468 m_formatter.immediate32(imm); 469 } 470 471 void cmpl_im(int imm, int offset, RegisterID base) 472 { 473 if (CAN_SIGN_EXTEND_8_32(imm)) { 474 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, offset); 475 m_formatter.immediate8(imm); 476 } else { 477 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, offset); 478 m_formatter.immediate32(imm); 479 } 480 } 481 482 void cmpl_im(int imm, int offset, RegisterID base, RegisterID index, int scale) 483 { 484 if (CAN_SIGN_EXTEND_8_32(imm)) { 485 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, index, scale, offset); 486 m_formatter.immediate8(imm); 487 } else { 488 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, index, scale, offset); 489 m_formatter.immediate32(imm); 490 } 491 } 492 493 void cmpl_im_force32(int imm, int offset, RegisterID base) 494 { 495 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, offset); 496 m_formatter.immediate32(imm); 497 } 498 499 #if !PLATFORM(X86_64) 500 void cmpl_im(int imm, void* addr) 501 { 502 if (CAN_SIGN_EXTEND_8_32(imm)) { 503 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, addr); 504 m_formatter.immediate8(imm); 505 } else { 506 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, addr); 507 m_formatter.immediate32(imm); 508 } 509 } 510 #endif 511 512 void cmpw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale) 513 { 514 m_formatter.prefix(PRE_OPERAND_SIZE); 515 m_formatter.oneByteOp(OP_CMP_EvGv, src, base, index, scale, offset); 516 } 517 518 void testl_rr(RegisterID src, RegisterID dst) 519 { 520 m_formatter.oneByteOp(OP_TEST_EvGv, src, dst); 521 } 522 523 void testl_i32r(int imm, RegisterID dst) 524 { 525 m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, dst); 526 m_formatter.immediate32(imm); 527 } 528 529 void testl_i32m(int imm, int offset, RegisterID base) 530 { 531 m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, offset); 532 m_formatter.immediate32(imm); 533 } 534 535 void testl_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale) 536 { 537 m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, index, scale, offset); 538 m_formatter.immediate32(imm); 539 } 540 541 #if PLATFORM(X86_64) 542 void testq_rr(RegisterID src, RegisterID dst) 543 { 544 m_formatter.oneByteOp64(OP_TEST_EvGv, src, dst); 545 } 546 547 void testq_i32r(int imm, RegisterID dst) 548 { 549 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP3_OP_TEST, dst); 550 m_formatter.immediate32(imm); 551 } 552 #endif 553 554 void testb_i8r(int imm, RegisterID dst) 555 { 556 m_formatter.oneByteOp8(OP_GROUP3_EbIb, GROUP3_OP_TEST, dst); 557 m_formatter.immediate8(imm); 558 } 559 560 void sete_r(RegisterID dst) 561 { 562 m_formatter.twoByteOp8(OP_SETE, (GroupOpcodeID)0, dst); 563 } 564 565 void setz_r(RegisterID dst) 566 { 567 sete_r(dst); 568 } 569 570 void setne_r(RegisterID dst) 571 { 572 m_formatter.twoByteOp8(OP_SETNE, (GroupOpcodeID)0, dst); 573 } 574 575 void setnz_r(RegisterID dst) 576 { 577 setne_r(dst); 578 } 579 580 // Various move ops: 581 582 void cdq() 583 { 584 m_formatter.oneByteOp(OP_CDQ); 585 } 586 587 void xchgl_rr(RegisterID src, RegisterID dst) 588 { 589 m_formatter.oneByteOp(OP_XCHG_EvGv, src, dst); 590 } 591 592 #if PLATFORM(X86_64) 593 void xchgq_rr(RegisterID src, RegisterID dst) 594 { 595 m_formatter.oneByteOp64(OP_XCHG_EvGv, src, dst); 596 } 597 #endif 598 261 599 void movl_rr(RegisterID src, RegisterID dst) 262 600 { 263 m_buffer.putByte(OP_MOV_EvGv); 264 modRm_rr(src, dst); 265 } 266 601 m_formatter.oneByteOp(OP_MOV_EvGv, src, dst); 602 } 603 604 void movl_rm(RegisterID src, int offset, RegisterID base) 605 { 606 m_formatter.oneByteOp(OP_MOV_EvGv, src, base, offset); 607 } 608 609 void movl_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale) 610 { 611 m_formatter.oneByteOp(OP_MOV_EvGv, src, base, index, scale, offset); 612 } 613 614 void movl_mr(int offset, RegisterID base, RegisterID dst) 615 { 616 m_formatter.oneByteOp(OP_MOV_GvEv, dst, base, offset); 617 } 618 619 void movl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst) 620 { 621 m_formatter.oneByteOp(OP_MOV_GvEv, dst, base, index, scale, offset); 622 } 623 624 void movl_i32r(int imm, RegisterID dst) 625 { 626 m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, dst); 627 m_formatter.immediate32(imm); 628 } 629 630 void movl_i32m(int imm, int offset, RegisterID base) 631 { 632 m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, base, offset); 633 m_formatter.immediate32(imm); 634 } 635 267 636 #if PLATFORM(X86_64) 268 637 void movq_rr(RegisterID src, RegisterID dst) 269 638 { 270 m_buffer.putByte(REX_W); 271 m_buffer.putByte(OP_MOV_EvGv); 272 modRm_rr(src, dst); 639 m_formatter.oneByteOp64(OP_MOV_EvGv, src, dst); 640 } 641 642 void movq_rm(RegisterID src, int offset, RegisterID base) 643 { 644 m_formatter.oneByteOp64(OP_MOV_EvGv, src, base, offset); 645 } 646 647 void movq_mr(int offset, RegisterID base, RegisterID dst) 648 { 649 m_formatter.oneByteOp64(OP_MOV_GvEv, dst, base, offset); 650 } 651 #else 652 void movl_mr(void* addr, RegisterID dst) 653 { 654 m_formatter.oneByteOp(OP_MOV_GvEv, dst, addr); 655 } 656 657 void movl_i32m(int imm, void* addr) 658 { 659 m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, addr); 660 m_formatter.immediate32(imm); 273 661 } 274 662 #endif 275 663 276 void addl_rr(RegisterID src, RegisterID dst) 277 { 278 m_buffer.putByte(OP_ADD_EvGv); 279 modRm_rr(src, dst); 280 } 281 282 #if !PLATFORM(X86_64) 283 void addl_i8m(int imm, void* addr) 284 { 285 m_buffer.putByte(OP_GROUP1_EvIb); 286 modRm_opm(GROUP1_OP_ADD, addr); 287 m_buffer.putByte(imm); 288 } 289 #endif 290 291 void addl_i8r(int imm, RegisterID dst) 292 { 293 m_buffer.putByte(OP_GROUP1_EvIb); 294 modRm_opr(GROUP1_OP_ADD, dst); 295 m_buffer.putByte(imm); 296 } 297 298 void addl_i32r(int imm, RegisterID dst) 299 { 300 m_buffer.putByte(OP_GROUP1_EvIz); 301 modRm_opr(GROUP1_OP_ADD, dst); 302 m_buffer.putInt(imm); 303 } 304 305 #if PLATFORM(X86_64) 306 void addq_i8r(int imm, RegisterID dst) 307 { 308 m_buffer.putByte(REX_W); 309 m_buffer.putByte(OP_GROUP1_EvIb); 310 modRm_opr(GROUP1_OP_ADD, dst); 311 m_buffer.putByte(imm); 312 } 313 314 void addq_i32r(int imm, RegisterID dst) 315 { 316 m_buffer.putByte(REX_W); 317 m_buffer.putByte(OP_GROUP1_EvIz); 318 modRm_opr(GROUP1_OP_ADD, dst); 319 m_buffer.putInt(imm); 320 } 321 #endif 322 323 void addl_mr(RegisterID base, RegisterID dst) 324 { 325 m_buffer.putByte(OP_ADD_GvEv); 326 modRm_rm(dst, base); 327 } 328 329 void addl_mr(int offset, RegisterID base, RegisterID dst) 330 { 331 m_buffer.putByte(OP_ADD_GvEv); 332 modRm_rm(dst, base, offset); 333 } 334 335 void andl_rr(RegisterID src, RegisterID dst) 336 { 337 m_buffer.putByte(OP_AND_EvGv); 338 modRm_rr(src, dst); 339 } 340 341 void andl_i8r(int imm, RegisterID dst) 342 { 343 m_buffer.putByte(OP_GROUP1_EvIb); 344 modRm_opr(GROUP1_OP_AND, dst); 345 m_buffer.putByte(imm); 346 } 347 348 void andl_i32r(int imm, RegisterID dst) 349 { 350 m_buffer.putByte(OP_GROUP1_EvIz); 351 modRm_opr(GROUP1_OP_AND, dst); 352 m_buffer.putInt(imm); 353 } 354 355 void cmpl_i8r(int imm, RegisterID dst) 356 { 357 m_buffer.putByte(OP_GROUP1_EvIb); 358 modRm_opr(GROUP1_OP_CMP, dst); 359 m_buffer.putByte(imm); 360 } 361 362 void cmpl_rr(RegisterID src, RegisterID dst) 363 { 364 m_buffer.putByte(OP_CMP_EvGv); 365 modRm_rr(src, dst); 366 } 367 368 void cmpl_rm(RegisterID src, RegisterID base) 369 { 370 m_buffer.putByte(OP_CMP_EvGv); 371 modRm_rm(src, base); 372 } 373 374 void cmpl_rm(RegisterID src, int offset, RegisterID base) 375 { 376 m_buffer.putByte(OP_CMP_EvGv); 377 modRm_rm(src, base, offset); 378 } 379 380 void cmpl_mr(RegisterID base, RegisterID dst) 381 { 382 m_buffer.putByte(OP_CMP_GvEv); 383 modRm_rm(dst, base); 384 } 385 386 void cmpl_mr(int offset, RegisterID base, RegisterID dst) 387 { 388 m_buffer.putByte(OP_CMP_GvEv); 389 modRm_rm(dst, base, offset); 390 } 391 392 void cmpl_i32r(int imm, RegisterID dst) 393 { 394 m_buffer.putByte(OP_GROUP1_EvIz); 395 modRm_opr(GROUP1_OP_CMP, dst); 396 m_buffer.putInt(imm); 397 } 398 399 void cmpl_i32m(int imm, RegisterID dst) 400 { 401 m_buffer.putByte(OP_GROUP1_EvIz); 402 modRm_opm(GROUP1_OP_CMP, dst); 403 m_buffer.putInt(imm); 404 } 405 406 void cmpl_i32m(int imm, int offset, RegisterID dst) 407 { 408 m_buffer.putByte(OP_GROUP1_EvIz); 409 modRm_opm(GROUP1_OP_CMP, dst, offset); 410 m_buffer.putInt(imm); 411 } 412 413 #if !PLATFORM(X86_64) 414 void cmpl_i32m(int imm, void* addr) 415 { 416 m_buffer.putByte(OP_GROUP1_EvIz); 417 modRm_opm(GROUP1_OP_CMP, addr); 418 m_buffer.putInt(imm); 419 } 420 #endif 421 422 void cmpl_i8m(int imm, RegisterID dst) 423 { 424 m_buffer.putByte(OP_GROUP1_EvIb); 425 modRm_opm(GROUP1_OP_CMP, dst); 426 m_buffer.putByte(imm); 427 } 428 429 void cmpl_i8m(int imm, int offset, RegisterID dst) 430 { 431 m_buffer.putByte(OP_GROUP1_EvIb); 432 modRm_opm(GROUP1_OP_CMP, dst, offset); 433 m_buffer.putByte(imm); 434 } 435 436 void cmpl_i8m(int imm, RegisterID base, RegisterID index, int scale) 437 { 438 m_buffer.putByte(OP_GROUP1_EvIb); 439 modRm_opmsib(GROUP1_OP_CMP, base, index, scale); 440 m_buffer.putByte(imm); 441 } 442 443 void cmpl_i8m(int imm, int offset, RegisterID base, RegisterID index, int scale) 444 { 445 m_buffer.putByte(OP_GROUP1_EvIb); 446 modRm_opmsib(GROUP1_OP_CMP, base, index, scale, offset); 447 m_buffer.putByte(imm); 448 } 449 450 void cmpw_rm(RegisterID src, RegisterID base, RegisterID index, int scale) 451 { 452 m_buffer.putByte(PRE_OPERAND_SIZE); 453 m_buffer.putByte(OP_CMP_EvGv); 454 modRm_rmsib(src, base, index, scale); 455 } 456 457 void cmpw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale) 458 { 459 m_buffer.putByte(PRE_OPERAND_SIZE); 460 m_buffer.putByte(OP_CMP_EvGv); 461 modRm_rmsib(src, base, index, scale, offset); 462 } 463 464 void sete_r(RegisterID dst) 465 { 466 m_buffer.putByte(OP_2BYTE_ESCAPE); 467 m_buffer.putByte(OP_SETE); 468 m_buffer.putByte(MODRM(3, 0, dst)); 469 } 470 471 void setz_r(RegisterID dst) 472 { 473 sete_r(dst); 474 } 475 476 void setne_r(RegisterID dst) 477 { 478 m_buffer.putByte(OP_2BYTE_ESCAPE); 479 m_buffer.putByte(OP_SETNE); 480 m_buffer.putByte(MODRM(3, 0, dst)); 481 } 482 483 void setnz_r(RegisterID dst) 484 { 485 setne_r(dst); 486 } 487 488 void orl_rr(RegisterID src, RegisterID dst) 489 { 490 m_buffer.putByte(OP_OR_EvGv); 491 modRm_rr(src, dst); 492 } 493 494 void orl_mr(int offset, RegisterID base, RegisterID dst) 495 { 496 m_buffer.putByte(OP_OR_GvEv); 497 modRm_rm(dst, base, offset); 498 } 499 500 void orl_i8r(int imm, RegisterID dst) 501 { 502 m_buffer.putByte(OP_GROUP1_EvIb); 503 modRm_opr(GROUP1_OP_OR, dst); 504 m_buffer.putByte(imm); 505 } 506 507 void orl_i32r(int imm, RegisterID dst) 508 { 509 m_buffer.putByte(OP_GROUP1_EvIz); 510 modRm_opr(GROUP1_OP_OR, dst); 511 m_buffer.putInt(imm); 512 } 513 514 void subl_rr(RegisterID src, RegisterID dst) 515 { 516 m_buffer.putByte(OP_SUB_EvGv); 517 modRm_rr(src, dst); 518 } 519 520 void subl_i8r(int imm, RegisterID dst) 521 { 522 m_buffer.putByte(OP_GROUP1_EvIb); 523 modRm_opr(GROUP1_OP_SUB, dst); 524 m_buffer.putByte(imm); 525 } 526 527 #if !PLATFORM(X86_64) 528 void subl_i8m(int imm, void* addr) 529 { 530 m_buffer.putByte(OP_GROUP1_EvIb); 531 modRm_opm(GROUP1_OP_SUB, addr); 532 m_buffer.putByte(imm); 533 } 534 #endif 535 536 void subl_i32r(int imm, RegisterID dst) 537 { 538 m_buffer.putByte(OP_GROUP1_EvIz); 539 modRm_opr(GROUP1_OP_SUB, dst); 540 m_buffer.putInt(imm); 541 } 542 543 void subl_mr(RegisterID base, RegisterID dst) 544 { 545 m_buffer.putByte(OP_SUB_GvEv); 546 modRm_rm(dst, base); 547 } 548 549 void subl_mr(int offset, RegisterID base, RegisterID dst) 550 { 551 m_buffer.putByte(OP_SUB_GvEv); 552 modRm_rm(dst, base, offset); 553 } 554 555 void testb_i8r(int imm, RegisterID dst) 556 { 557 m_buffer.ensureSpace(maxInstructionSize); 558 m_buffer.putByteUnchecked(OP_GROUP3_EbIb); 559 modRm_opr_Unchecked(GROUP3_OP_TEST, dst); 560 m_buffer.putByteUnchecked(imm); 561 } 562 563 void testl_i32r(int imm, RegisterID dst) 564 { 565 m_buffer.ensureSpace(maxInstructionSize); 566 m_buffer.putByteUnchecked(OP_GROUP3_EvIz); 567 modRm_opr_Unchecked(GROUP3_OP_TEST, dst); 568 m_buffer.putIntUnchecked(imm); 569 } 570 571 void testl_i32m(int imm, RegisterID dst) 572 { 573 m_buffer.putByte(OP_GROUP3_EvIz); 574 modRm_opm(GROUP3_OP_TEST, dst); 575 m_buffer.putInt(imm); 576 } 577 578 void testl_i32m(int imm, int offset, RegisterID dst) 579 { 580 m_buffer.putByte(OP_GROUP3_EvIz); 581 modRm_opm(GROUP3_OP_TEST, dst, offset); 582 m_buffer.putInt(imm); 583 } 584 585 void testl_i32m(int imm, RegisterID base, RegisterID index, int scale) 586 { 587 m_buffer.putByte(OP_GROUP3_EvIz); 588 modRm_opmsib(GROUP3_OP_TEST, base, index, scale); 589 m_buffer.putInt(imm); 590 } 591 592 void testl_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale) 593 { 594 m_buffer.putByte(OP_GROUP3_EvIz); 595 modRm_opmsib(GROUP3_OP_TEST, base, index, scale, offset); 596 m_buffer.putInt(imm); 597 } 598 599 void testl_rr(RegisterID src, RegisterID dst) 600 { 601 m_buffer.putByte(OP_TEST_EvGv); 602 modRm_rr(src, dst); 603 } 604 605 #if PLATFORM(X86_64) 606 void testq_i32r(int imm, RegisterID dst) 607 { 608 m_buffer.ensureSpace(maxInstructionSize); 609 m_buffer.putByteUnchecked(REX_W); 610 m_buffer.putByteUnchecked(OP_GROUP3_EvIz); 611 modRm_opr_Unchecked(GROUP3_OP_TEST, dst); 612 m_buffer.putIntUnchecked(imm); 613 } 614 615 void testq_rr(RegisterID src, RegisterID dst) 616 { 617 m_buffer.putByte(REX_W); 618 m_buffer.putByte(OP_TEST_EvGv); 619 modRm_rr(src, dst); 620 } 621 #endif 622 623 void xorl_i8r(int imm, RegisterID dst) 624 { 625 m_buffer.putByte(OP_GROUP1_EvIb); 626 modRm_opr(GROUP1_OP_XOR, dst); 627 m_buffer.putByte(imm); 628 } 629 630 void xorl_i32r(int imm, RegisterID dst) 631 { 632 m_buffer.putByte(OP_GROUP1_EvIz); 633 modRm_opr(GROUP1_OP_XOR, dst); 634 m_buffer.putInt(imm); 635 } 636 637 void xorl_rr(RegisterID src, RegisterID dst) 638 { 639 m_buffer.putByte(OP_XOR_EvGv); 640 modRm_rr(src, dst); 641 } 642 643 void sarl_i8r(int imm, RegisterID dst) 644 { 645 if (imm == 1) { 646 m_buffer.putByte(OP_GROUP2_Ev1); 647 modRm_opr(GROUP2_OP_SAR, dst); 648 } else { 649 m_buffer.putByte(OP_GROUP2_EvIb); 650 modRm_opr(GROUP2_OP_SAR, dst); 651 m_buffer.putByte(imm); 652 } 653 } 654 655 void sarl_CLr(RegisterID dst) 656 { 657 m_buffer.putByte(OP_GROUP2_EvCL); 658 modRm_opr(GROUP2_OP_SAR, dst); 659 } 660 661 void shll_i8r(int imm, RegisterID dst) 662 { 663 if (imm == 1) { 664 m_buffer.putByte(OP_GROUP2_Ev1); 665 modRm_opr(GROUP2_OP_SHL, dst); 666 } else { 667 m_buffer.putByte(OP_GROUP2_EvIb); 668 modRm_opr(GROUP2_OP_SHL, dst); 669 m_buffer.putByte(imm); 670 } 671 } 672 673 void shll_CLr(RegisterID dst) 674 { 675 m_buffer.putByte(OP_GROUP2_EvCL); 676 modRm_opr(GROUP2_OP_SHL, dst); 677 } 678 679 void xchgl_rr(RegisterID src, RegisterID dst) 680 { 681 m_buffer.putByte(OP_XCHG_EvGv); 682 modRm_rr(src, dst); 683 } 684 685 void imull_rr(RegisterID src, RegisterID dst) 686 { 687 m_buffer.putByte(OP_2BYTE_ESCAPE); 688 m_buffer.putByte(OP2_IMUL_GvEv); 689 modRm_rr(dst, src); 690 } 691 692 void imull_i32r(RegisterID src, int32_t value, RegisterID dst) 693 { 694 m_buffer.putByte(OP_IMUL_GvEvIz); 695 modRm_rr(dst, src); 696 m_buffer.putInt(value); 697 } 698 699 void idivl_r(RegisterID dst) 700 { 701 m_buffer.putByte(OP_GROUP3_Ev); 702 modRm_opr(GROUP3_OP_IDIV, dst); 703 } 704 705 void cdq() 706 { 707 m_buffer.putByte(OP_CDQ); 708 } 709 710 void movl_mr(RegisterID base, RegisterID dst) 711 { 712 m_buffer.putByte(OP_MOV_GvEv); 713 modRm_rm(dst, base); 714 } 715 716 void movl_mr(int offset, RegisterID base, RegisterID dst) 717 { 718 m_buffer.ensureSpace(maxInstructionSize); 719 m_buffer.putByteUnchecked(OP_MOV_GvEv); 720 modRm_rm_Unchecked(dst, base, offset); 721 } 722 723 #if PLATFORM(X86_64) 724 void movq_mr(RegisterID base, RegisterID dst) 725 { 726 m_buffer.putByte(REX_W); 727 m_buffer.putByte(OP_MOV_GvEv); 728 modRm_rm(dst, base); 729 } 730 731 void movq_mr(int offset, RegisterID base, RegisterID dst) 732 { 733 m_buffer.ensureSpace(maxInstructionSize); 734 m_buffer.putByteUnchecked(REX_W); 735 m_buffer.putByteUnchecked(OP_MOV_GvEv); 736 modRm_rm_Unchecked(dst, base, offset); 737 } 738 #endif 739 740 #if !PLATFORM(X86_64) 741 void movl_mr(void* addr, RegisterID dst) 742 { 743 m_buffer.putByte(OP_MOV_GvEv); 744 modRm_rm(dst, addr); 745 } 746 #endif 747 748 void movl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst) 749 { 750 m_buffer.putByte(OP_MOV_GvEv); 751 modRm_rmsib(dst, base, index, scale, offset); 752 } 753 754 void movl_mr(RegisterID base, RegisterID index, int scale, RegisterID dst) 755 { 756 m_buffer.putByte(OP_MOV_GvEv); 757 modRm_rmsib(dst, base, index, scale); 664 void movzwl_mr(int offset, RegisterID base, RegisterID dst) 665 { 666 m_formatter.twoByteOp(OP2_MOVZX_GvEw, dst, base, offset); 667 } 668 669 void movzwl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst) 670 { 671 m_formatter.twoByteOp(OP2_MOVZX_GvEw, dst, base, index, scale, offset); 758 672 } 759 673 760 674 void movzbl_rr(RegisterID src, RegisterID dst) 761 675 { 762 m_buffer.putByte(OP_2BYTE_ESCAPE); 763 m_buffer.putByte(OP2_MOVZX_GvEb); 764 modRm_rr(dst, src); 765 } 766 767 void movzwl_mr(int offset, RegisterID base, RegisterID dst) 768 { 769 m_buffer.putByte(OP_2BYTE_ESCAPE); 770 m_buffer.putByte(OP2_MOVZX_GvEw); 771 modRm_rm(dst, base, offset); 772 } 773 774 void movzwl_mr(RegisterID base, RegisterID index, int scale, RegisterID dst) 775 { 776 m_buffer.putByte(OP_2BYTE_ESCAPE); 777 m_buffer.putByte(OP2_MOVZX_GvEw); 778 modRm_rmsib(dst, base, index, scale); 779 } 780 781 void movzwl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst) 782 { 783 m_buffer.putByte(OP_2BYTE_ESCAPE); 784 m_buffer.putByte(OP2_MOVZX_GvEw); 785 modRm_rmsib(dst, base, index, scale, offset); 786 } 787 788 void movl_rm(RegisterID src, RegisterID base) 789 { 790 m_buffer.putByte(OP_MOV_EvGv); 791 modRm_rm(src, base); 792 } 793 794 void movl_rm(RegisterID src, int offset, RegisterID base) 795 { 796 m_buffer.ensureSpace(maxInstructionSize); 797 m_buffer.putByteUnchecked(OP_MOV_EvGv); 798 modRm_rm_Unchecked(src, base, offset); 799 } 800 801 #if PLATFORM(X86_64) 802 void movq_rm(RegisterID src, RegisterID base) 803 { 804 m_buffer.putByte(REX_W); 805 m_buffer.putByte(OP_MOV_EvGv); 806 modRm_rm(src, base); 807 } 808 809 void movq_rm(RegisterID src, int offset, RegisterID base) 810 { 811 m_buffer.ensureSpace(maxInstructionSize); 812 m_buffer.putByteUnchecked(REX_W); 813 m_buffer.putByteUnchecked(OP_MOV_EvGv); 814 modRm_rm_Unchecked(src, base, offset); 815 } 816 #endif 817 818 void movl_rm(RegisterID src, RegisterID base, RegisterID index, int scale) 819 { 820 m_buffer.putByte(OP_MOV_EvGv); 821 modRm_rmsib(src, base, index, scale); 822 } 823 824 void movl_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale) 825 { 826 m_buffer.putByte(OP_MOV_EvGv); 827 modRm_rmsib(src, base, index, scale, offset); 828 } 829 830 void movl_i32r(int imm, RegisterID dst) 831 { 832 m_buffer.putByte(OP_GROUP11_EvIz); 833 modRm_opr(GROUP11_MOV, dst); 834 m_buffer.putInt(imm); 835 } 836 837 void movl_i32m(int imm, RegisterID base) 838 { 839 m_buffer.ensureSpace(maxInstructionSize); 840 m_buffer.putByteUnchecked(OP_GROUP11_EvIz); 841 modRm_opm_Unchecked(GROUP11_MOV, base); 842 m_buffer.putIntUnchecked(imm); 843 } 844 845 void movl_i32m(int imm, int offset, RegisterID base) 846 { 847 m_buffer.ensureSpace(maxInstructionSize); 848 m_buffer.putByteUnchecked(OP_GROUP11_EvIz); 849 modRm_opm_Unchecked(GROUP11_MOV, base, offset); 850 m_buffer.putIntUnchecked(imm); 851 } 852 853 #if !PLATFORM(X86_64) 854 void movl_i32m(int imm, void* addr) 855 { 856 m_buffer.putByte(OP_GROUP11_EvIz); 857 modRm_opm(GROUP11_MOV, addr); 858 m_buffer.putInt(imm); 859 } 860 #endif 676 // In 64-bit, this may cause an unnecessary REX to be planted (if the dst register 677 // is in the range ESP-EDI, and the src would not have required a REX). Unneeded 678 // REX prefixes are defined to be silently ignored by the processor. 679 m_formatter.twoByteOp8(OP2_MOVZX_GvEb, dst, src); 680 } 861 681 862 682 void leal_mr(int offset, RegisterID base, RegisterID dst) 863 683 { 864 m_buffer.putByte(OP_LEA); 865 modRm_rm(dst, base, offset); 866 } 867 868 void leal_mr(int offset, RegisterID index, int scale, RegisterID dst) 869 { 870 m_buffer.putByte(OP_LEA); 871 modRm_rmsib(dst, X86::noBase, index, scale, offset); 872 } 873 684 m_formatter.oneByteOp(OP_LEA, dst, base, offset); 685 } 686 687 // Flow control: 688 689 JmpSrc call() 690 { 691 m_formatter.oneByteOp(OP_CALL_rel32); 692 return m_formatter.immediateRel32(); 693 } 694 695 JmpSrc call(RegisterID dst) 696 { 697 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_CALLN, dst); 698 return JmpSrc(m_formatter.size()); 699 } 700 701 JmpSrc jmp() 702 { 703 m_formatter.oneByteOp(OP_JMP_rel32); 704 return m_formatter.immediateRel32(); 705 } 706 707 void jmp_r(RegisterID dst) 708 { 709 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, dst); 710 } 711 712 void jmp_m(int offset, RegisterID base) 713 { 714 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, base, offset); 715 } 716 717 JmpSrc jne() 718 { 719 m_formatter.twoByteOp(OP2_JNE_rel32); 720 return m_formatter.immediateRel32(); 721 } 722 723 JmpSrc jnz() 724 { 725 return jne(); 726 } 727 728 JmpSrc je() 729 { 730 m_formatter.twoByteOp(OP2_JE_rel32); 731 return m_formatter.immediateRel32(); 732 } 733 734 JmpSrc jl() 735 { 736 m_formatter.twoByteOp(OP2_JL_rel32); 737 return m_formatter.immediateRel32(); 738 } 739 740 JmpSrc jb() 741 { 742 m_formatter.twoByteOp(OP2_JB_rel32); 743 return m_formatter.immediateRel32(); 744 } 745 746 JmpSrc jle() 747 { 748 m_formatter.twoByteOp(OP2_JLE_rel32); 749 return m_formatter.immediateRel32(); 750 } 751 752 JmpSrc jbe() 753 { 754 m_formatter.twoByteOp(OP2_JBE_rel32); 755 return m_formatter.immediateRel32(); 756 } 757 758 JmpSrc jge() 759 { 760 m_formatter.twoByteOp(OP2_JGE_rel32); 761 return m_formatter.immediateRel32(); 762 } 763 764 JmpSrc jg() 765 { 766 m_formatter.twoByteOp(OP2_JG_rel32); 767 return m_formatter.immediateRel32(); 768 } 769 770 JmpSrc ja() 771 { 772 m_formatter.twoByteOp(OP2_JA_rel32); 773 return m_formatter.immediateRel32(); 774 } 775 776 JmpSrc jae() 777 { 778 m_formatter.twoByteOp(OP2_JAE_rel32); 779 return m_formatter.immediateRel32(); 780 } 781 782 JmpSrc jo() 783 { 784 m_formatter.twoByteOp(OP2_JO_rel32); 785 return m_formatter.immediateRel32(); 786 } 787 788 JmpSrc jp() 789 { 790 m_formatter.twoByteOp(OP2_JP_rel32); 791 return m_formatter.immediateRel32(); 792 } 793 794 JmpSrc js() 795 { 796 m_formatter.twoByteOp(OP2_JS_rel32); 797 return m_formatter.immediateRel32(); 798 } 799 800 // SSE operations: 801 802 void addsd_rr(XMMRegisterID src, XMMRegisterID dst) 803 { 804 m_formatter.prefix(PRE_SSE_F2); 805 m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, (RegisterID)src); 806 } 807 808 void addsd_mr(int offset, RegisterID base, XMMRegisterID dst) 809 { 810 m_formatter.prefix(PRE_SSE_F2); 811 m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, base, offset); 812 } 813 814 void cvtsi2sd_rr(RegisterID src, XMMRegisterID dst) 815 { 816 m_formatter.prefix(PRE_SSE_F2); 817 m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, src); 818 } 819 820 void cvttsd2si_rr(XMMRegisterID src, RegisterID dst) 821 { 822 m_formatter.prefix(PRE_SSE_F2); 823 m_formatter.twoByteOp(OP2_CVTTSD2SI_GdWsd, dst, (RegisterID)src); 824 } 825 826 void movd_rr(XMMRegisterID src, RegisterID dst) 827 { 828 m_formatter.prefix(PRE_SSE_66); 829 m_formatter.twoByteOp(OP2_MOVD_EdVd, (RegisterID)src, dst); 830 } 831 832 void movsd_rm(XMMRegisterID src, int offset, RegisterID base) 833 { 834 m_formatter.prefix(PRE_SSE_F2); 835 m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, offset); 836 } 837 838 void movsd_mr(int offset, RegisterID base, XMMRegisterID dst) 839 { 840 m_formatter.prefix(PRE_SSE_F2); 841 m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, base, offset); 842 } 843 844 void mulsd_rr(XMMRegisterID src, XMMRegisterID dst) 845 { 846 m_formatter.prefix(PRE_SSE_F2); 847 m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)dst, (RegisterID)src); 848 } 849 850 void mulsd_mr(int offset, RegisterID base, XMMRegisterID dst) 851 { 852 m_formatter.prefix(PRE_SSE_F2); 853 m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)dst, base, offset); 854 } 855 856 void pextrw_irr(int whichWord, XMMRegisterID src, RegisterID dst) 857 { 858 m_formatter.prefix(PRE_SSE_66); 859 m_formatter.twoByteOp(OP2_PEXTRW_GdUdIb, (RegisterID)dst, (RegisterID)src); 860 m_formatter.immediate8(whichWord); 861 } 862 863 void subsd_rr(XMMRegisterID src, XMMRegisterID dst) 864 { 865 m_formatter.prefix(PRE_SSE_F2); 866 m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)src); 867 } 868 869 void subsd_mr(int offset, RegisterID base, XMMRegisterID dst) 870 { 871 m_formatter.prefix(PRE_SSE_F2); 872 m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, base, offset); 873 } 874 875 void ucomis_rr(XMMRegisterID src, XMMRegisterID dst) 876 { 877 m_formatter.prefix(PRE_SSE_66); 878 m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)dst, (RegisterID)src); 879 } 880 881 // Misc instructions: 882 883 void int3() 884 { 885 m_formatter.oneByteOp(OP_INT3); 886 } 887 874 888 void ret() 875 889 { 876 m_buffer.putByte(OP_RET); 877 } 878 879 void jmp_r(RegisterID dst) 880 { 881 m_buffer.putByte(OP_GROUP5_Ev); 882 modRm_opr(GROUP5_OP_JMPN, dst); 883 } 884 885 void jmp_m(RegisterID base) 886 { 887 m_buffer.putByte(OP_GROUP5_Ev); 888 modRm_opm(GROUP5_OP_JMPN, base); 889 } 890 891 void jmp_m(int offset, RegisterID base) 892 { 893 m_buffer.putByte(OP_GROUP5_Ev); 894 modRm_opm(GROUP5_OP_JMPN, base, offset); 895 } 896 897 void movsd_mr(int offset, RegisterID base, XMMRegisterID dst) 898 { 899 m_buffer.putByte(PRE_SSE_F2); 900 m_buffer.putByte(OP_2BYTE_ESCAPE); 901 m_buffer.putByte(OP2_MOVSD_VsdWsd); 902 modRm_rm((RegisterID)dst, base, offset); 903 } 904 905 void movsd_rm(XMMRegisterID src, int offset, RegisterID base) 906 { 907 m_buffer.putByte(PRE_SSE_F2); 908 m_buffer.putByte(OP_2BYTE_ESCAPE); 909 m_buffer.putByte(OP2_MOVSD_WsdVsd); 910 modRm_rm((RegisterID)src, base, offset); 911 } 912 913 void movd_rr(XMMRegisterID src, RegisterID dst) 914 { 915 m_buffer.putByte(PRE_SSE_66); 916 m_buffer.putByte(OP_2BYTE_ESCAPE); 917 m_buffer.putByte(OP2_MOVD_EdVd); 918 modRm_rr((RegisterID)src, dst); 919 } 920 921 void cvtsi2sd_rr(RegisterID src, XMMRegisterID dst) 922 { 923 m_buffer.putByte(PRE_SSE_F2); 924 m_buffer.putByte(OP_2BYTE_ESCAPE); 925 m_buffer.putByte(OP2_CVTSI2SD_VsdEd); 926 modRm_rr((RegisterID)dst, src); 927 } 928 929 void cvttsd2si_rr(XMMRegisterID src, RegisterID dst) 930 { 931 m_buffer.putByte(PRE_SSE_F2); 932 m_buffer.putByte(OP_2BYTE_ESCAPE); 933 m_buffer.putByte(OP2_CVTTSD2SI_GdWsd); 934 modRm_rr(dst, (RegisterID)src); 935 } 936 937 void addsd_mr(int offset, RegisterID base, XMMRegisterID dst) 938 { 939 m_buffer.putByte(PRE_SSE_F2); 940 m_buffer.putByte(OP_2BYTE_ESCAPE); 941 m_buffer.putByte(OP2_ADDSD_VsdWsd); 942 modRm_rm((RegisterID)dst, base, offset); 943 } 944 945 void subsd_mr(int offset, RegisterID base, XMMRegisterID dst) 946 { 947 m_buffer.putByte(PRE_SSE_F2); 948 m_buffer.putByte(OP_2BYTE_ESCAPE); 949 m_buffer.putByte(OP2_SUBSD_VsdWsd); 950 modRm_rm((RegisterID)dst, base, offset); 951 } 952 953 void mulsd_mr(int offset, RegisterID base, XMMRegisterID dst) 954 { 955 m_buffer.putByte(PRE_SSE_F2); 956 m_buffer.putByte(OP_2BYTE_ESCAPE); 957 m_buffer.putByte(OP2_MULSD_VsdWsd); 958 modRm_rm((RegisterID)dst, base, offset); 959 } 960 961 void addsd_rr(XMMRegisterID src, XMMRegisterID dst) 962 { 963 m_buffer.putByte(PRE_SSE_F2); 964 m_buffer.putByte(OP_2BYTE_ESCAPE); 965 m_buffer.putByte(OP2_ADDSD_VsdWsd); 966 modRm_rr((RegisterID)dst, (RegisterID)src); 967 } 968 969 void subsd_rr(XMMRegisterID src, XMMRegisterID dst) 970 { 971 m_buffer.putByte(PRE_SSE_F2); 972 m_buffer.putByte(OP_2BYTE_ESCAPE); 973 m_buffer.putByte(OP2_SUBSD_VsdWsd); 974 modRm_rr((RegisterID)dst, (RegisterID)src); 975 } 976 977 void mulsd_rr(XMMRegisterID src, XMMRegisterID dst) 978 { 979 m_buffer.putByte(PRE_SSE_F2); 980 m_buffer.putByte(OP_2BYTE_ESCAPE); 981 m_buffer.putByte(OP2_MULSD_VsdWsd); 982 modRm_rr((RegisterID)dst, (RegisterID)src); 983 } 984 985 void ucomis_rr(XMMRegisterID src, XMMRegisterID dst) 986 { 987 m_buffer.putByte(PRE_SSE_66); 988 m_buffer.putByte(OP_2BYTE_ESCAPE); 989 m_buffer.putByte(OP2_UCOMISD_VsdWsd); 990 modRm_rr((RegisterID)dst, (RegisterID)src); 991 } 992 993 void pextrw_irr(int whichWord, XMMRegisterID src, RegisterID dst) 994 { 995 m_buffer.putByte(PRE_SSE_66); 996 m_buffer.putByte(OP_2BYTE_ESCAPE); 997 m_buffer.putByte(OP2_PEXTRW_GdUdIb); 998 modRm_rr(dst, (RegisterID)src); 999 m_buffer.putByte(whichWord); 1000 } 1001 1002 JmpSrc call() 1003 { 1004 m_buffer.putByte(OP_CALL_rel32); 1005 m_buffer.putInt(0); // FIXME: make this point to a global label, linked later. 1006 return JmpSrc(m_buffer.size()); 1007 } 1008 1009 JmpSrc call(RegisterID dst) 1010 { 1011 m_buffer.putByte(OP_GROUP5_Ev); 1012 modRm_opr(GROUP5_OP_CALLN, dst); 1013 return JmpSrc(m_buffer.size()); 1014 } 890 m_formatter.oneByteOp(OP_RET); 891 } 892 893 void predictNotTaken() 894 { 895 m_formatter.prefix(PRE_PREDICT_BRANCH_NOT_TAKEN); 896 } 897 898 // Assembler admin methods: 1015 899 1016 900 JmpDst label() 1017 901 { 1018 return JmpDst(m_ buffer.size());902 return JmpDst(m_formatter.size()); 1019 903 } 1020 904 1021 905 JmpDst align(int alignment) 1022 906 { 1023 while (!m_ buffer.isAligned(alignment))1024 m_ buffer.putByte(OP_HLT);907 while (!m_formatter.isAligned(alignment)) 908 m_formatter.oneByteOp(OP_HLT); 1025 909 1026 910 return label(); 1027 911 } 1028 912 1029 JmpSrc jmp() 1030 { 1031 m_buffer.putByte(OP_JMP_rel32); 1032 m_buffer.putInt(0); 1033 return JmpSrc(m_buffer.size()); 1034 } 1035 1036 JmpSrc jne() 1037 { 1038 m_buffer.putByte(OP_2BYTE_ESCAPE); 1039 m_buffer.putByte(OP2_JNE_rel32); 1040 m_buffer.putInt(0); 1041 return JmpSrc(m_buffer.size()); 1042 } 1043 1044 JmpSrc jnz() 1045 { 1046 return jne(); 1047 } 1048 1049 JmpSrc je() 1050 { 1051 m_buffer.ensureSpace(maxInstructionSize); 1052 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE); 1053 m_buffer.putByteUnchecked(OP2_JE_rel32); 1054 m_buffer.putIntUnchecked(0); 1055 return JmpSrc(m_buffer.size()); 1056 } 1057 1058 JmpSrc jl() 1059 { 1060 m_buffer.putByte(OP_2BYTE_ESCAPE); 1061 m_buffer.putByte(OP2_JL_rel32); 1062 m_buffer.putInt(0); 1063 return JmpSrc(m_buffer.size()); 1064 } 1065 1066 JmpSrc jb() 1067 { 1068 m_buffer.putByte(OP_2BYTE_ESCAPE); 1069 m_buffer.putByte(OP2_JB_rel32); 1070 m_buffer.putInt(0); 1071 return JmpSrc(m_buffer.size()); 1072 } 1073 1074 JmpSrc jle() 1075 { 1076 m_buffer.putByte(OP_2BYTE_ESCAPE); 1077 m_buffer.putByte(OP2_JLE_rel32); 1078 m_buffer.putInt(0); 1079 return JmpSrc(m_buffer.size()); 1080 } 1081 1082 JmpSrc jbe() 1083 { 1084 m_buffer.putByte(OP_2BYTE_ESCAPE); 1085 m_buffer.putByte(OP2_JBE_rel32); 1086 m_buffer.putInt(0); 1087 return JmpSrc(m_buffer.size()); 1088 } 1089 1090 JmpSrc jge() 1091 { 1092 m_buffer.putByte(OP_2BYTE_ESCAPE); 1093 m_buffer.putByte(OP2_JGE_rel32); 1094 m_buffer.putInt(0); 1095 return JmpSrc(m_buffer.size()); 1096 } 1097 1098 JmpSrc jg() 1099 { 1100 m_buffer.putByte(OP_2BYTE_ESCAPE); 1101 m_buffer.putByte(OP2_JG_rel32); 1102 m_buffer.putInt(0); 1103 return JmpSrc(m_buffer.size()); 1104 } 1105 1106 JmpSrc ja() 1107 { 1108 m_buffer.putByte(OP_2BYTE_ESCAPE); 1109 m_buffer.putByte(OP2_JA_rel32); 1110 m_buffer.putInt(0); 1111 return JmpSrc(m_buffer.size()); 1112 } 1113 1114 JmpSrc jae() 1115 { 1116 m_buffer.putByte(OP_2BYTE_ESCAPE); 1117 m_buffer.putByte(OP2_JAE_rel32); 1118 m_buffer.putInt(0); 1119 return JmpSrc(m_buffer.size()); 1120 } 1121 1122 JmpSrc jo() 1123 { 1124 m_buffer.putByte(OP_2BYTE_ESCAPE); 1125 m_buffer.putByte(OP2_JO_rel32); 1126 m_buffer.putInt(0); 1127 return JmpSrc(m_buffer.size()); 1128 } 1129 1130 JmpSrc jp() 1131 { 1132 m_buffer.putByte(OP_2BYTE_ESCAPE); 1133 m_buffer.putByte(OP2_JP_rel32); 1134 m_buffer.putInt(0); 1135 return JmpSrc(m_buffer.size()); 1136 } 1137 1138 JmpSrc js() 1139 { 1140 m_buffer.putByte(OP_2BYTE_ESCAPE); 1141 m_buffer.putByte(OP2_JS_rel32); 1142 m_buffer.putInt(0); 1143 return JmpSrc(m_buffer.size()); 1144 } 1145 1146 void predictNotTaken() 1147 { 1148 m_buffer.putByte(PRE_PREDICT_BRANCH_NOT_TAKEN); 1149 } 1150 913 // Linking & repatching: 914 1151 915 void link(JmpSrc from, JmpDst to) 1152 916 { … … 1154 918 ASSERT(from.m_offset != -1); 1155 919 1156 reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(m_ buffer.data()) + from.m_offset)[-1] = to.m_offset - from.m_offset;920 reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(m_formatter.data()) + from.m_offset)[-1] = to.m_offset - from.m_offset; 1157 921 } 1158 922 … … 1215 979 void* executableCopy(ExecutablePool* allocator) 1216 980 { 1217 void* copy = m_ buffer.executableCopy(allocator);981 void* copy = m_formatter.executableCopy(allocator); 1218 982 ASSERT(copy); 1219 983 return copy; … … 1221 985 1222 986 private: 1223 void modRm_rr(RegisterID reg, RegisterID rm) 1224 { 1225 m_buffer.ensureSpace(maxInstructionSize); 1226 modRm_rr_Unchecked(reg, rm); 1227 } 1228 1229 void modRm_rr_Unchecked(RegisterID reg, RegisterID rm) 1230 { 1231 m_buffer.putByteUnchecked(MODRM(3, reg, rm)); 1232 } 987 988 class X86InstructionFormatter { 989 990 static const int maxInstructionSize = 16; 991 992 public: 993 994 // Legacy prefix bytes: 995 // 996 // These are emmitted prior to the instruction. 997 998 void prefix(OneByteOpcodeID pre) 999 { 1000 m_buffer.putByte(pre); 1001 } 1002 1003 // Word-sized operands / no operand instruction formatters. 1004 // 1005 // In addition to the opcode, the following operand permutations are supported: 1006 // * None - instruction takes no operands. 1007 // * One register - the low three bits of the RegisterID are added into the opcode. 1008 // * 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). 1009 // * Three argument ModRM - a register, and a register and an offset describing a memory operand. 1010 // * Five argument ModRM - a register, and a base register, an index, scale, and offset describing a memory operand. 1011 // 1012 // For 32-bit x86 targets, the address operand may also be provided as a void*. 1013 // On 64-bit targets REX prefixes will be planted as necessary, where high numbered registers are used. 1014 // 1015 // The twoByteOp methods plant two-byte Intel instructions sequences (first opcode byte 0x0F). 1016 1017 void oneByteOp(OneByteOpcodeID opcode) 1018 { 1019 m_buffer.ensureSpace(maxInstructionSize); 1020 m_buffer.putByteUnchecked(opcode); 1021 } 1022 1023 void oneByteOp(OneByteOpcodeID opcode, RegisterID reg) 1024 { 1025 m_buffer.ensureSpace(maxInstructionSize); 1026 emitRexIfNeeded(reg, 0, 0); 1027 m_buffer.putByteUnchecked(opcode + reg); 1028 } 1029 1030 void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID rm) 1031 { 1032 m_buffer.ensureSpace(maxInstructionSize); 1033 emitRexIfNeeded(reg, 0, rm); 1034 m_buffer.putByteUnchecked(opcode); 1035 registerModRM(reg, rm); 1036 } 1037 1038 void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID base, int offset) 1039 { 1040 m_buffer.ensureSpace(maxInstructionSize); 1041 emitRexIfNeeded(reg, 0, base); 1042 m_buffer.putByteUnchecked(opcode); 1043 memoryModRM(reg, base, offset); 1044 } 1045 1046 void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset) 1047 { 1048 m_buffer.ensureSpace(maxInstructionSize); 1049 emitRexIfNeeded(reg, index, base); 1050 m_buffer.putByteUnchecked(opcode); 1051 memoryModRM(reg, base, index, scale, offset); 1052 } 1233 1053 1234 1054 #if !PLATFORM(X86_64) 1235 void modRm_rm(RegisterID reg, void* addr) 1236 { 1237 m_buffer.putByte(MODRM(0, reg, X86::noBase)); 1238 m_buffer.putInt((int)addr); 1239 } 1055 void oneByteOp(OneByteOpcodeID opcode, int reg, void* address) 1056 { 1057 m_buffer.ensureSpace(maxInstructionSize); 1058 m_buffer.putByteUnchecked(opcode); 1059 memoryModRM(reg, address); 1060 } 1240 1061 #endif 1241 1062 1242 void modRm_rm_Unchecked(RegisterID reg, RegisterID base) 1243 { 1244 if (base == X86::esp) { 1245 m_buffer.putByteUnchecked(MODRM(0, reg, X86::hasSib)); 1246 m_buffer.putByteUnchecked(SIB(0, X86::noScale, X86::esp)); 1247 } else { 1248 m_buffer.putByteUnchecked(MODRM(0, reg, base)); 1249 } 1250 } 1251 1252 void modRm_rm(RegisterID reg, RegisterID base) 1253 { 1254 if (base == X86::esp) { 1255 m_buffer.putByte(MODRM(0, reg, X86::hasSib)); 1256 m_buffer.putByte(SIB(0, X86::noScale, X86::esp)); 1257 } else 1258 m_buffer.putByte(MODRM(0, reg, base)); 1259 } 1260 1261 void modRm_rm_Unchecked(RegisterID reg, RegisterID base, int offset) 1262 { 1263 if (base == X86::esp) { 1264 if (CAN_SIGN_EXTEND_8_32(offset)) { 1265 m_buffer.putByteUnchecked(MODRM(1, reg, X86::hasSib)); 1266 m_buffer.putByteUnchecked(SIB(0, X86::noScale, X86::esp)); 1063 void twoByteOp(TwoByteOpcodeID opcode) 1064 { 1065 m_buffer.ensureSpace(maxInstructionSize); 1066 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE); 1067 m_buffer.putByteUnchecked(opcode); 1068 } 1069 1070 void twoByteOp(TwoByteOpcodeID opcode, int reg, RegisterID rm) 1071 { 1072 m_buffer.ensureSpace(maxInstructionSize); 1073 emitRexIfNeeded(reg, 0, rm); 1074 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE); 1075 m_buffer.putByteUnchecked(opcode); 1076 registerModRM(reg, rm); 1077 } 1078 1079 void twoByteOp(TwoByteOpcodeID opcode, int reg, RegisterID base, int offset) 1080 { 1081 m_buffer.ensureSpace(maxInstructionSize); 1082 emitRexIfNeeded(reg, 0, base); 1083 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE); 1084 m_buffer.putByteUnchecked(opcode); 1085 memoryModRM(reg, base, offset); 1086 } 1087 1088 void twoByteOp(TwoByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset) 1089 { 1090 m_buffer.ensureSpace(maxInstructionSize); 1091 emitRexIfNeeded(reg, index, base); 1092 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE); 1093 m_buffer.putByteUnchecked(opcode); 1094 memoryModRM(reg, base, index, scale, offset); 1095 } 1096 1097 #if PLATFORM(X86_64) 1098 // Quad-word-sized operands: 1099 // 1100 // Used to format 64-bit operantions, planting a REX.w prefix. 1101 // When planting d64 or f64 instructions, not requiring a REX.w prefix, 1102 // the normal (non-'64'-postfixed) formatters should be used. 1103 1104 void oneByteOp64(OneByteOpcodeID opcode, int reg, RegisterID rm) 1105 { 1106 m_buffer.ensureSpace(maxInstructionSize); 1107 emitRexW(reg, 0, rm); 1108 m_buffer.putByteUnchecked(opcode); 1109 registerModRM(reg, rm); 1110 } 1111 1112 void oneByteOp64(OneByteOpcodeID opcode, int reg, RegisterID base, int offset) 1113 { 1114 m_buffer.ensureSpace(maxInstructionSize); 1115 emitRexW(reg, 0, base); 1116 m_buffer.putByteUnchecked(opcode); 1117 memoryModRM(reg, base, offset); 1118 } 1119 1120 void oneByteOp64(OneByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset) 1121 { 1122 m_buffer.ensureSpace(maxInstructionSize); 1123 emitRexW(reg, index, base); 1124 m_buffer.putByteUnchecked(opcode); 1125 memoryModRM(reg, base, index, scale, offset); 1126 } 1127 #endif 1128 1129 // Byte-operands: 1130 // 1131 // These methods format byte operations. Byte operations differ from the normal 1132 // formatters in the circumstances under which they will decide to emit REX prefixes. 1133 // These should be used where any register operand signifies a byte register. 1134 // 1135 // The disctinction is due to the handling of register numbers in the range 4..7 on 1136 // x86-64. These register numbers may either represent the second byte of the first 1137 // four registers (ah..bh) or the first byte of the second four registers (spl..dil). 1138 // 1139 // Since ah..bh cannot be used in all permutations of operands (specifically cannot 1140 // be accessed where a REX prefix is present), these are likely best treated as 1141 // deprecated. In order to ensure the correct registers spl..dil are selected a 1142 // REX prefix will be emitted for any byte register operand in the range 4..15. 1143 // 1144 // These formatters may be used in instructions where a mix of operand sizes, in which 1145 // case an unnecessary REX will be emitted, for example: 1146 // movzbl %al, %edi 1147 // In this case a REX will be planted since edi is 7 (and were this a byte operand 1148 // a REX would be required to specify dil instead of bh). Unneeded REX prefixes will 1149 // be silently ignored by the processor. 1150 // 1151 // Address operands should still be checked using regRequiresRex(), while byteRegRequiresRex() 1152 // is provided to check byte register operands. 1153 1154 void oneByteOp8(OneByteOpcodeID opcode, GroupOpcodeID groupOp, RegisterID rm) 1155 { 1156 m_buffer.ensureSpace(maxInstructionSize); 1157 emitRexIf(byteRegRequiresRex(rm), 0, 0, rm); 1158 m_buffer.putByteUnchecked(opcode); 1159 registerModRM(groupOp, rm); 1160 } 1161 1162 void twoByteOp8(TwoByteOpcodeID opcode, RegisterID reg, RegisterID rm) 1163 { 1164 m_buffer.ensureSpace(maxInstructionSize); 1165 emitRexIf(byteRegRequiresRex(reg)|byteRegRequiresRex(rm), reg, 0, rm); 1166 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE); 1167 m_buffer.putByteUnchecked(opcode); 1168 registerModRM(reg, rm); 1169 } 1170 1171 void twoByteOp8(TwoByteOpcodeID opcode, GroupOpcodeID groupOp, RegisterID rm) 1172 { 1173 m_buffer.ensureSpace(maxInstructionSize); 1174 emitRexIf(byteRegRequiresRex(rm), 0, 0, rm); 1175 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE); 1176 m_buffer.putByteUnchecked(opcode); 1177 registerModRM(groupOp, rm); 1178 } 1179 1180 // Immediates: 1181 // 1182 // An immedaite should be appended where appropriate after an op has been emitted. 1183 // The writes are unchecked since the opcode formatters above will have ensured space. 1184 1185 void immediate8(int imm) 1186 { 1187 m_buffer.putByteUnchecked(imm); 1188 } 1189 1190 void immediate32(int imm) 1191 { 1192 m_buffer.putIntUnchecked(imm); 1193 } 1194 1195 JmpSrc immediateRel32() 1196 { 1197 m_buffer.putIntUnchecked(0); 1198 return JmpSrc(m_buffer.size()); 1199 } 1200 1201 // Administrative methods: 1202 1203 size_t size() const { return m_buffer.size(); } 1204 bool isAligned(int alignment) const { return m_buffer.isAligned(alignment); } 1205 void* data() const { return m_buffer.data(); } 1206 void* executableCopy(ExecutablePool* allocator) { return m_buffer.executableCopy(allocator); } 1207 1208 private: 1209 1210 // Internals; ModRm and REX formatters. 1211 1212 static const RegisterID noBase = X86::ebp; 1213 static const RegisterID hasSib = X86::esp; 1214 static const RegisterID noIndex = X86::esp; 1215 #if PLATFORM(X86_64) 1216 static const RegisterID noBase2 = X86::r13; 1217 static const RegisterID hasSib2 = X86::r12; 1218 1219 // Registers r8 & above require a REX prefixe. 1220 inline bool regRequiresRex(int reg) 1221 { 1222 return (reg >= X86::r8); 1223 } 1224 1225 // Byte operand register spl & above require a REX prefix (to prevent the 'H' registers be accessed). 1226 inline bool byteRegRequiresRex(int reg) 1227 { 1228 return (reg >= X86::esp); 1229 } 1230 1231 // Format a REX prefix byte. 1232 inline void emitRex(bool w, int r, int x, int b) 1233 { 1234 m_buffer.putByteUnchecked(PRE_REX | ((int)w << 3) | ((r>>3)<<2) | ((x>>3)<<1) | (b>>3)); 1235 } 1236 1237 // Used to plant a REX byte with REX.w set (for 64-bit operations). 1238 inline void emitRexW(int r, int x, int b) 1239 { 1240 emitRex(true, r, x, b); 1241 } 1242 1243 // Used for operations with byte operands - use byteRegRequiresRex() to check register operands, 1244 // regRequiresRex() to check other registers (i.e. address base & index). 1245 inline void emitRexIf(bool condition, int r, int x, int b) 1246 { 1247 if (condition) emitRex(false, r, x, b); 1248 } 1249 1250 // Used for word sized operations, will plant a REX prefix if necessary (if any register is r8 or above). 1251 inline void emitRexIfNeeded(int r, int x, int b) 1252 { 1253 emitRexIf(regRequiresRex(r) || regRequiresRex(x) || regRequiresRex(b), r, x, b); 1254 } 1255 #else 1256 // No REX prefix bytes on 32-bit x86. 1257 inline bool regRequiresRex(int) { return false; } 1258 inline bool byteRegRequiresRex(int) { return false; } 1259 inline void emitRexIf(bool, int, int, int) {} 1260 inline void emitRexIfNeeded(int, int, int) {} 1261 #endif 1262 1263 enum ModRmMode { 1264 ModRmMemoryNoDisp, 1265 ModRmMemoryDisp8, 1266 ModRmMemoryDisp32, 1267 ModRmRegister, 1268 }; 1269 1270 void putModRm(ModRmMode mode, int reg, RegisterID rm) 1271 { 1272 m_buffer.putByteUnchecked((mode << 6) | ((reg & 7) << 3) | (rm & 7)); 1273 } 1274 1275 void putModRmSib(ModRmMode mode, int reg, RegisterID base, RegisterID index, int scale) 1276 { 1277 ASSERT(mode != ModRmRegister); 1278 1279 // Encode sacle of (1,2,4,8) -> (0,1,2,3) 1280 int shift = 0; 1281 while (scale >>= 1) 1282 shift++; 1283 1284 putModRm(mode, reg, hasSib); 1285 m_buffer.putByteUnchecked((shift << 6) | ((index & 7) << 3) | (base & 7)); 1286 } 1287 1288 void registerModRM(int reg, RegisterID rm) 1289 { 1290 putModRm(ModRmRegister, reg, rm); 1291 } 1292 1293 void memoryModRM(int reg, RegisterID base, int offset) 1294 { 1295 // A base of esp or r12 would be interpreted as a sib, so force a sib with no index & put the base in there. 1296 #if PLATFORM(X86_64) 1297 if ((base == hasSib) || (base == hasSib2)) { 1298 #else 1299 if (base == hasSib) { 1300 #endif 1301 if (!offset) // No need to check if the base is noBase, since we know it is hasSib! 1302 putModRmSib(ModRmMemoryNoDisp, reg, base, noIndex, 0); 1303 else if (CAN_SIGN_EXTEND_8_32(offset)) { 1304 putModRmSib(ModRmMemoryDisp8, reg, base, noIndex, 0); 1305 m_buffer.putByteUnchecked(offset); 1306 } else { 1307 putModRmSib(ModRmMemoryDisp32, reg, base, noIndex, 0); 1308 m_buffer.putIntUnchecked(offset); 1309 } 1310 } else { 1311 #if PLATFORM(X86_64) 1312 if (!offset && (base != noBase) && (base != noBase2)) 1313 #else 1314 if (!offset && (base != noBase)) 1315 #endif 1316 putModRm(ModRmMemoryNoDisp, reg, base); 1317 else if (CAN_SIGN_EXTEND_8_32(offset)) { 1318 putModRm(ModRmMemoryDisp8, reg, base); 1319 m_buffer.putByteUnchecked(offset); 1320 } else { 1321 putModRm(ModRmMemoryDisp32, reg, base); 1322 m_buffer.putIntUnchecked(offset); 1323 } 1324 } 1325 } 1326 1327 void memoryModRM(int reg, RegisterID base, RegisterID index, int scale, int offset) 1328 { 1329 ASSERT(index != noIndex); 1330 1331 #if PLATFORM(X86_64) 1332 if (!offset && (base != noBase) && (base != noBase2)) 1333 #else 1334 if (!offset && (base != noBase)) 1335 #endif 1336 putModRmSib(ModRmMemoryNoDisp, reg, base, index, scale); 1337 else if (CAN_SIGN_EXTEND_8_32(offset)) { 1338 putModRmSib(ModRmMemoryDisp8, reg, base, index, scale); 1267 1339 m_buffer.putByteUnchecked(offset); 1268 1340 } else { 1269 m_buffer.putByteUnchecked(MODRM(2, reg, X86::hasSib)); 1270 m_buffer.putByteUnchecked(SIB(0, X86::noScale, X86::esp)); 1341 putModRmSib(ModRmMemoryDisp32, reg, base, index, scale); 1271 1342 m_buffer.putIntUnchecked(offset); 1272 1343 } 1273 } else { 1274 if (CAN_SIGN_EXTEND_8_32(offset)) { 1275 m_buffer.putByteUnchecked(MODRM(1, reg, base)); 1276 m_buffer.putByteUnchecked(offset); 1277 } else { 1278 m_buffer.putByteUnchecked(MODRM(2, reg, base)); 1279 m_buffer.putIntUnchecked(offset); 1280 } 1281 } 1282 } 1283 1284 void modRm_rm(RegisterID reg, RegisterID base, int offset) 1285 { 1286 m_buffer.ensureSpace(maxInstructionSize); 1287 modRm_rm_Unchecked(reg, base, offset); 1288 } 1289 1290 void modRm_rmsib(RegisterID reg, RegisterID base, RegisterID index, int scale) 1291 { 1292 int shift = 0; 1293 while (scale >>= 1) 1294 shift++; 1295 1296 m_buffer.putByte(MODRM(0, reg, X86::hasSib)); 1297 m_buffer.putByte(SIB(shift, index, base)); 1298 } 1299 1300 void modRm_rmsib(RegisterID reg, RegisterID base, RegisterID index, int scale, int offset) 1301 { 1302 int shift = 0; 1303 while (scale >>= 1) 1304 shift++; 1305 1306 if (CAN_SIGN_EXTEND_8_32(offset)) { 1307 m_buffer.putByte(MODRM(1, reg, X86::hasSib)); 1308 m_buffer.putByte(SIB(shift, index, base)); 1309 m_buffer.putByte(offset); 1310 } else { 1311 m_buffer.putByte(MODRM(2, reg, X86::hasSib)); 1312 m_buffer.putByte(SIB(shift, index, base)); 1313 m_buffer.putInt(offset); 1314 } 1315 } 1316 1317 void modRm_opr(OpcodeID opcodeID, RegisterID rm) 1318 { 1319 m_buffer.ensureSpace(maxInstructionSize); 1320 modRm_opr_Unchecked(opcodeID, rm); 1321 } 1322 1323 void modRm_opr_Unchecked(OpcodeID opcodeID, RegisterID rm) 1324 { 1325 modRm_rr_Unchecked(static_cast<RegisterID>(opcodeID), rm); 1326 } 1327 1328 void modRm_opm(OpcodeID opcodeID, RegisterID base) 1329 { 1330 modRm_rm(static_cast<RegisterID>(opcodeID), base); 1331 } 1332 1333 void modRm_opm_Unchecked(OpcodeID opcodeID, RegisterID base) 1334 { 1335 modRm_rm_Unchecked(static_cast<RegisterID>(opcodeID), base); 1336 } 1337 1338 void modRm_opm_Unchecked(OpcodeID opcodeID, RegisterID base, int offset) 1339 { 1340 modRm_rm_Unchecked(static_cast<RegisterID>(opcodeID), base, offset); 1341 } 1342 1343 void modRm_opm(OpcodeID opcodeID, RegisterID base, int offset) 1344 { 1345 modRm_rm(static_cast<RegisterID>(opcodeID), base, offset); 1346 } 1344 } 1347 1345 1348 1346 #if !PLATFORM(X86_64) 1349 void modRm_opm(OpcodeID opcodeID, void* addr) 1350 { 1351 modRm_rm(static_cast<RegisterID>(opcodeID), addr); 1352 } 1347 void memoryModRM(int reg, void* address) 1348 { 1349 // noBase + ModRmMemoryNoDisp means noBase + ModRmMemoryDisp32! 1350 putModRm(ModRmMemoryNoDisp, reg, noBase); 1351 m_buffer.putIntUnchecked(reinterpret_cast<int32_t>(address)); 1352 } 1353 1353 #endif 1354 1354 1355 void modRm_opmsib(OpcodeID opcodeID, RegisterID base, RegisterID index, int scale, int offset) 1356 { 1357 modRm_rmsib(static_cast<RegisterID>(opcodeID), base, index, scale, offset); 1358 } 1359 1360 void modRm_opmsib(OpcodeID opcodeID, RegisterID base, RegisterID index, int scale) 1361 { 1362 modRm_rmsib(static_cast<RegisterID>(opcodeID), base, index, scale); 1363 } 1364 1365 AssemblerBuffer m_buffer; 1355 AssemblerBuffer m_buffer; 1356 } m_formatter; 1366 1357 }; 1367 1358
Note:
See TracChangeset
for help on using the changeset viewer.