1 // Copyright (c) 1994-2006 Sun Microsystems Inc. 2 // 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 // 8 // - Redistributions of source code must retain the above copyright notice, 9 // this list of conditions and the following disclaimer. 10 // 11 // - Redistribution in binary form must reproduce the above copyright 12 // notice, this list of conditions and the following disclaimer in the 13 // documentation and/or other materials provided with the 14 // distribution. 15 // 16 // - Neither the name of Sun Microsystems or the names of contributors may 17 // be used to endorse or promote products derived from this software without 18 // specific prior written permission. 19 // 20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24 // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 29 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 31 // OF THE POSSIBILITY OF SUCH DAMAGE. 32 33 // The original source code covered by the above license above has been modified 34 // significantly by Google Inc. 35 // Copyright 2012 the V8 project authors. All rights reserved. 36 37 #include "src/ia32/assembler-ia32.h" 38 39 #include <cstring> 40 41 #if V8_TARGET_ARCH_IA32 42 43 #if V8_LIBC_MSVCRT 44 #include <intrin.h> // _xgetbv() 45 #endif 46 #if V8_OS_MACOSX 47 #include <sys/sysctl.h> 48 #endif 49 50 #include "src/assembler-inl.h" 51 #include "src/base/bits.h" 52 #include "src/base/cpu.h" 53 #include "src/code-stubs.h" 54 #include "src/conversions-inl.h" 55 #include "src/deoptimizer.h" 56 #include "src/disassembler.h" 57 #include "src/macro-assembler.h" 58 #include "src/v8.h" 59 60 namespace v8 { 61 namespace internal { 62 63 Immediate Immediate::EmbeddedNumber(double value) { 64 int32_t smi; 65 if (DoubleToSmiInteger(value, &smi)) return Immediate(Smi::FromInt(smi)); 66 Immediate result(0, RelocInfo::EMBEDDED_OBJECT); 67 result.is_heap_object_request_ = true; 68 result.value_.heap_object_request = HeapObjectRequest(value); 69 return result; 70 } 71 72 Immediate Immediate::EmbeddedCode(CodeStub* stub) { 73 Immediate result(0, RelocInfo::CODE_TARGET); 74 result.is_heap_object_request_ = true; 75 result.value_.heap_object_request = HeapObjectRequest(stub); 76 return result; 77 } 78 79 // ----------------------------------------------------------------------------- 80 // Implementation of CpuFeatures 81 82 namespace { 83 84 #if !V8_LIBC_MSVCRT 85 86 V8_INLINE uint64_t _xgetbv(unsigned int xcr) { 87 unsigned eax, edx; 88 // Check xgetbv; this uses a .byte sequence instead of the instruction 89 // directly because older assemblers do not include support for xgetbv and 90 // there is no easy way to conditionally compile based on the assembler 91 // used. 92 __asm__ volatile(".byte 0x0F, 0x01, 0xD0" : "=a"(eax), "=d"(edx) : "c"(xcr)); 93 return static_cast<uint64_t>(eax) | (static_cast<uint64_t>(edx) << 32); 94 } 95 96 #define _XCR_XFEATURE_ENABLED_MASK 0 97 98 #endif // !V8_LIBC_MSVCRT 99 100 101 bool OSHasAVXSupport() { 102 #if V8_OS_MACOSX 103 // Mac OS X up to 10.9 has a bug where AVX transitions were indeed being 104 // caused by ISRs, so we detect that here and disable AVX in that case. 105 char buffer[128]; 106 size_t buffer_size = arraysize(buffer); 107 int ctl_name[] = {CTL_KERN, KERN_OSRELEASE}; 108 if (sysctl(ctl_name, 2, buffer, &buffer_size, nullptr, 0) != 0) { 109 FATAL("V8 failed to get kernel version"); 110 } 111 // The buffer now contains a string of the form XX.YY.ZZ, where 112 // XX is the major kernel version component. 113 char* period_pos = strchr(buffer, '.'); 114 DCHECK_NOT_NULL(period_pos); 115 *period_pos = '\0'; 116 long kernel_version_major = strtol(buffer, nullptr, 10); // NOLINT 117 if (kernel_version_major <= 13) return false; 118 #endif // V8_OS_MACOSX 119 // Check whether OS claims to support AVX. 120 uint64_t feature_mask = _xgetbv(_XCR_XFEATURE_ENABLED_MASK); 121 return (feature_mask & 0x6) == 0x6; 122 } 123 124 } // namespace 125 126 127 void CpuFeatures::ProbeImpl(bool cross_compile) { 128 base::CPU cpu; 129 CHECK(cpu.has_sse2()); // SSE2 support is mandatory. 130 CHECK(cpu.has_cmov()); // CMOV support is mandatory. 131 132 // Only use statically determined features for cross compile (snapshot). 133 if (cross_compile) return; 134 135 if (cpu.has_sse41() && FLAG_enable_sse4_1) supported_ |= 1u << SSE4_1; 136 if (cpu.has_ssse3() && FLAG_enable_ssse3) supported_ |= 1u << SSSE3; 137 if (cpu.has_sse3() && FLAG_enable_sse3) supported_ |= 1u << SSE3; 138 if (cpu.has_avx() && FLAG_enable_avx && cpu.has_osxsave() && 139 OSHasAVXSupport()) { 140 supported_ |= 1u << AVX; 141 } 142 if (cpu.has_fma3() && FLAG_enable_fma3 && cpu.has_osxsave() && 143 OSHasAVXSupport()) { 144 supported_ |= 1u << FMA3; 145 } 146 if (cpu.has_bmi1() && FLAG_enable_bmi1) supported_ |= 1u << BMI1; 147 if (cpu.has_bmi2() && FLAG_enable_bmi2) supported_ |= 1u << BMI2; 148 if (cpu.has_lzcnt() && FLAG_enable_lzcnt) supported_ |= 1u << LZCNT; 149 if (cpu.has_popcnt() && FLAG_enable_popcnt) supported_ |= 1u << POPCNT; 150 if (strcmp(FLAG_mcpu, "auto") == 0) { 151 if (cpu.is_atom()) supported_ |= 1u << ATOM; 152 } else if (strcmp(FLAG_mcpu, "atom") == 0) { 153 supported_ |= 1u << ATOM; 154 } 155 } 156 157 158 void CpuFeatures::PrintTarget() { } 159 void CpuFeatures::PrintFeatures() { 160 printf( 161 "SSE3=%d SSSE3=%d SSE4_1=%d AVX=%d FMA3=%d BMI1=%d BMI2=%d LZCNT=%d " 162 "POPCNT=%d ATOM=%d\n", 163 CpuFeatures::IsSupported(SSE3), CpuFeatures::IsSupported(SSSE3), 164 CpuFeatures::IsSupported(SSE4_1), CpuFeatures::IsSupported(AVX), 165 CpuFeatures::IsSupported(FMA3), CpuFeatures::IsSupported(BMI1), 166 CpuFeatures::IsSupported(BMI2), CpuFeatures::IsSupported(LZCNT), 167 CpuFeatures::IsSupported(POPCNT), CpuFeatures::IsSupported(ATOM)); 168 } 169 170 171 // ----------------------------------------------------------------------------- 172 // Implementation of Displacement 173 174 void Displacement::init(Label* L, Type type) { 175 DCHECK(!L->is_bound()); 176 int next = 0; 177 if (L->is_linked()) { 178 next = L->pos(); 179 DCHECK_GT(next, 0); // Displacements must be at positions > 0 180 } 181 // Ensure that we _never_ overflow the next field. 182 DCHECK(NextField::is_valid(Assembler::kMaximalBufferSize)); 183 data_ = NextField::encode(next) | TypeField::encode(type); 184 } 185 186 187 // ----------------------------------------------------------------------------- 188 // Implementation of RelocInfo 189 190 const int RelocInfo::kApplyMask = 191 RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | 192 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) | 193 RelocInfo::ModeMask(RelocInfo::JS_TO_WASM_CALL) | 194 RelocInfo::ModeMask(RelocInfo::OFF_HEAP_TARGET) | 195 RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY); 196 197 bool RelocInfo::IsCodedSpecially() { 198 // The deserializer needs to know whether a pointer is specially coded. Being 199 // specially coded on IA32 means that it is a relative address, as used by 200 // branch instructions. These are also the ones that need changing when a 201 // code object moves. 202 return RelocInfo::ModeMask(rmode_) & kApplyMask; 203 } 204 205 206 bool RelocInfo::IsInConstantPool() { 207 return false; 208 } 209 210 int RelocInfo::GetDeoptimizationId(Isolate* isolate, DeoptimizeKind kind) { 211 DCHECK(IsRuntimeEntry(rmode_)); 212 return Deoptimizer::GetDeoptimizationId(isolate, target_address(), kind); 213 } 214 215 void RelocInfo::set_js_to_wasm_address(Address address, 216 ICacheFlushMode icache_flush_mode) { 217 DCHECK_EQ(rmode_, JS_TO_WASM_CALL); 218 Assembler::set_target_address_at(pc_, constant_pool_, address, 219 icache_flush_mode); 220 } 221 222 Address RelocInfo::js_to_wasm_address() const { 223 DCHECK_EQ(rmode_, JS_TO_WASM_CALL); 224 return Assembler::target_address_at(pc_, constant_pool_); 225 } 226 227 uint32_t RelocInfo::wasm_call_tag() const { 228 DCHECK(rmode_ == WASM_CALL || rmode_ == WASM_STUB_CALL); 229 return Memory<uint32_t>(pc_); 230 } 231 232 // ----------------------------------------------------------------------------- 233 // Implementation of Operand 234 235 Operand::Operand(Register base, int32_t disp, RelocInfo::Mode rmode) { 236 // [base + disp/r] 237 if (disp == 0 && RelocInfo::IsNone(rmode) && base != ebp) { 238 // [base] 239 set_modrm(0, base); 240 if (base == esp) set_sib(times_1, esp, base); 241 } else if (is_int8(disp) && RelocInfo::IsNone(rmode)) { 242 // [base + disp8] 243 set_modrm(1, base); 244 if (base == esp) set_sib(times_1, esp, base); 245 set_disp8(disp); 246 } else { 247 // [base + disp/r] 248 set_modrm(2, base); 249 if (base == esp) set_sib(times_1, esp, base); 250 set_dispr(disp, rmode); 251 } 252 } 253 254 255 Operand::Operand(Register base, 256 Register index, 257 ScaleFactor scale, 258 int32_t disp, 259 RelocInfo::Mode rmode) { 260 DCHECK(index != esp); // illegal addressing mode 261 // [base + index*scale + disp/r] 262 if (disp == 0 && RelocInfo::IsNone(rmode) && base != ebp) { 263 // [base + index*scale] 264 set_modrm(0, esp); 265 set_sib(scale, index, base); 266 } else if (is_int8(disp) && RelocInfo::IsNone(rmode)) { 267 // [base + index*scale + disp8] 268 set_modrm(1, esp); 269 set_sib(scale, index, base); 270 set_disp8(disp); 271 } else { 272 // [base + index*scale + disp/r] 273 set_modrm(2, esp); 274 set_sib(scale, index, base); 275 set_dispr(disp, rmode); 276 } 277 } 278 279 280 Operand::Operand(Register index, 281 ScaleFactor scale, 282 int32_t disp, 283 RelocInfo::Mode rmode) { 284 DCHECK(index != esp); // illegal addressing mode 285 // [index*scale + disp/r] 286 set_modrm(0, esp); 287 set_sib(scale, index, ebp); 288 set_dispr(disp, rmode); 289 } 290 291 292 bool Operand::is_reg_only() const { 293 return (buf_[0] & 0xF8) == 0xC0; // Addressing mode is register only. 294 } 295 296 297 Register Operand::reg() const { 298 DCHECK(is_reg_only()); 299 return Register::from_code(buf_[0] & 0x07); 300 } 301 302 void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) { 303 for (auto& request : heap_object_requests_) { 304 Handle<HeapObject> object; 305 switch (request.kind()) { 306 case HeapObjectRequest::kHeapNumber: 307 object = 308 isolate->factory()->NewHeapNumber(request.heap_number(), TENURED); 309 break; 310 case HeapObjectRequest::kCodeStub: 311 request.code_stub()->set_isolate(isolate); 312 object = request.code_stub()->GetCode(); 313 break; 314 } 315 Address pc = reinterpret_cast<Address>(buffer_) + request.offset(); 316 Memory<Handle<Object>>(pc) = object; 317 } 318 } 319 320 // ----------------------------------------------------------------------------- 321 // Implementation of Assembler. 322 323 // Emit a single byte. Must always be inlined. 324 #define EMIT(x) \ 325 *pc_++ = (x) 326 327 Assembler::Assembler(const AssemblerOptions& options, void* buffer, 328 int buffer_size) 329 : AssemblerBase(options, buffer, buffer_size) { 330 // Clear the buffer in debug mode unless it was provided by the 331 // caller in which case we can't be sure it's okay to overwrite 332 // existing code in it. 333 #ifdef DEBUG 334 if (own_buffer_) ZapCode(reinterpret_cast<Address>(buffer_), buffer_size_); 335 #endif 336 337 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_); 338 } 339 340 void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) { 341 // Finalize code (at this point overflow() may be true, but the gap ensures 342 // that we are still not overlapping instructions and relocation info). 343 DCHECK(pc_ <= reloc_info_writer.pos()); // No overlap. 344 345 AllocateAndInstallRequestedHeapObjects(isolate); 346 347 // Set up code descriptor. 348 desc->buffer = buffer_; 349 desc->buffer_size = buffer_size_; 350 desc->instr_size = pc_offset(); 351 desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos(); 352 desc->origin = this; 353 desc->constant_pool_size = 0; 354 desc->unwinding_info_size = 0; 355 desc->unwinding_info = nullptr; 356 357 // Collection stage 358 auto jump_opt = jump_optimization_info(); 359 if (jump_opt && jump_opt->is_collecting()) { 360 auto& bitmap = jump_opt->farjmp_bitmap(); 361 int num = static_cast<int>(farjmp_positions_.size()); 362 if (num && bitmap.empty()) { 363 bool can_opt = false; 364 365 bitmap.resize((num + 31) / 32, 0); 366 for (int i = 0; i < num; i++) { 367 int disp_pos = farjmp_positions_[i]; 368 int disp = long_at(disp_pos); 369 if (is_int8(disp)) { 370 bitmap[i / 32] |= 1 << (i & 31); 371 can_opt = true; 372 } 373 } 374 if (can_opt) { 375 jump_opt->set_optimizable(); 376 } 377 } 378 } 379 } 380 381 382 void Assembler::Align(int m) { 383 DCHECK(base::bits::IsPowerOfTwo(m)); 384 int mask = m - 1; 385 int addr = pc_offset(); 386 Nop((m - (addr & mask)) & mask); 387 } 388 389 390 bool Assembler::IsNop(Address addr) { 391 byte* a = reinterpret_cast<byte*>(addr); 392 while (*a == 0x66) a++; 393 if (*a == 0x90) return true; 394 if (a[0] == 0xF && a[1] == 0x1F) return true; 395 return false; 396 } 397 398 399 void Assembler::Nop(int bytes) { 400 EnsureSpace ensure_space(this); 401 402 // Multi byte nops from http://support.amd.com/us/Processor_TechDocs/40546.pdf 403 while (bytes > 0) { 404 switch (bytes) { 405 case 2: 406 EMIT(0x66); 407 V8_FALLTHROUGH; 408 case 1: 409 EMIT(0x90); 410 return; 411 case 3: 412 EMIT(0xF); 413 EMIT(0x1F); 414 EMIT(0); 415 return; 416 case 4: 417 EMIT(0xF); 418 EMIT(0x1F); 419 EMIT(0x40); 420 EMIT(0); 421 return; 422 case 6: 423 EMIT(0x66); 424 V8_FALLTHROUGH; 425 case 5: 426 EMIT(0xF); 427 EMIT(0x1F); 428 EMIT(0x44); 429 EMIT(0); 430 EMIT(0); 431 return; 432 case 7: 433 EMIT(0xF); 434 EMIT(0x1F); 435 EMIT(0x80); 436 EMIT(0); 437 EMIT(0); 438 EMIT(0); 439 EMIT(0); 440 return; 441 default: 442 case 11: 443 EMIT(0x66); 444 bytes--; 445 V8_FALLTHROUGH; 446 case 10: 447 EMIT(0x66); 448 bytes--; 449 V8_FALLTHROUGH; 450 case 9: 451 EMIT(0x66); 452 bytes--; 453 V8_FALLTHROUGH; 454 case 8: 455 EMIT(0xF); 456 EMIT(0x1F); 457 EMIT(0x84); 458 EMIT(0); 459 EMIT(0); 460 EMIT(0); 461 EMIT(0); 462 EMIT(0); 463 bytes -= 8; 464 } 465 } 466 } 467 468 469 void Assembler::CodeTargetAlign() { 470 Align(16); // Preferred alignment of jump targets on ia32. 471 } 472 473 474 void Assembler::cpuid() { 475 EnsureSpace ensure_space(this); 476 EMIT(0x0F); 477 EMIT(0xA2); 478 } 479 480 481 void Assembler::pushad() { 482 EnsureSpace ensure_space(this); 483 EMIT(0x60); 484 } 485 486 487 void Assembler::popad() { 488 EnsureSpace ensure_space(this); 489 EMIT(0x61); 490 } 491 492 493 void Assembler::pushfd() { 494 EnsureSpace ensure_space(this); 495 EMIT(0x9C); 496 } 497 498 499 void Assembler::popfd() { 500 EnsureSpace ensure_space(this); 501 EMIT(0x9D); 502 } 503 504 505 void Assembler::push(const Immediate& x) { 506 EnsureSpace ensure_space(this); 507 if (x.is_int8()) { 508 EMIT(0x6A); 509 EMIT(x.immediate()); 510 } else { 511 EMIT(0x68); 512 emit(x); 513 } 514 } 515 516 517 void Assembler::push_imm32(int32_t imm32) { 518 EnsureSpace ensure_space(this); 519 EMIT(0x68); 520 emit(imm32); 521 } 522 523 524 void Assembler::push(Register src) { 525 EnsureSpace ensure_space(this); 526 EMIT(0x50 | src.code()); 527 } 528 529 void Assembler::push(Operand src) { 530 EnsureSpace ensure_space(this); 531 EMIT(0xFF); 532 emit_operand(esi, src); 533 } 534 535 536 void Assembler::pop(Register dst) { 537 DCHECK_NOT_NULL(reloc_info_writer.last_pc()); 538 EnsureSpace ensure_space(this); 539 EMIT(0x58 | dst.code()); 540 } 541 542 void Assembler::pop(Operand dst) { 543 EnsureSpace ensure_space(this); 544 EMIT(0x8F); 545 emit_operand(eax, dst); 546 } 547 548 549 void Assembler::enter(const Immediate& size) { 550 EnsureSpace ensure_space(this); 551 EMIT(0xC8); 552 emit_w(size); 553 EMIT(0); 554 } 555 556 557 void Assembler::leave() { 558 EnsureSpace ensure_space(this); 559 EMIT(0xC9); 560 } 561 562 void Assembler::mov_b(Register dst, Operand src) { 563 CHECK(dst.is_byte_register()); 564 EnsureSpace ensure_space(this); 565 EMIT(0x8A); 566 emit_operand(dst, src); 567 } 568 569 void Assembler::mov_b(Operand dst, const Immediate& src) { 570 EnsureSpace ensure_space(this); 571 EMIT(0xC6); 572 emit_operand(eax, dst); 573 EMIT(static_cast<int8_t>(src.immediate())); 574 } 575 576 void Assembler::mov_b(Operand dst, Register src) { 577 CHECK(src.is_byte_register()); 578 EnsureSpace ensure_space(this); 579 EMIT(0x88); 580 emit_operand(src, dst); 581 } 582 583 void Assembler::mov_w(Register dst, Operand src) { 584 EnsureSpace ensure_space(this); 585 EMIT(0x66); 586 EMIT(0x8B); 587 emit_operand(dst, src); 588 } 589 590 void Assembler::mov_w(Operand dst, Register src) { 591 EnsureSpace ensure_space(this); 592 EMIT(0x66); 593 EMIT(0x89); 594 emit_operand(src, dst); 595 } 596 597 void Assembler::mov_w(Operand dst, const Immediate& src) { 598 EnsureSpace ensure_space(this); 599 EMIT(0x66); 600 EMIT(0xC7); 601 emit_operand(eax, dst); 602 EMIT(static_cast<int8_t>(src.immediate() & 0xFF)); 603 EMIT(static_cast<int8_t>(src.immediate() >> 8)); 604 } 605 606 607 void Assembler::mov(Register dst, int32_t imm32) { 608 EnsureSpace ensure_space(this); 609 EMIT(0xB8 | dst.code()); 610 emit(imm32); 611 } 612 613 614 void Assembler::mov(Register dst, const Immediate& x) { 615 EnsureSpace ensure_space(this); 616 EMIT(0xB8 | dst.code()); 617 emit(x); 618 } 619 620 void Assembler::mov(Register dst, Handle<HeapObject> handle) { 621 EnsureSpace ensure_space(this); 622 EMIT(0xB8 | dst.code()); 623 emit(handle); 624 } 625 626 void Assembler::mov(Register dst, Operand src) { 627 EnsureSpace ensure_space(this); 628 EMIT(0x8B); 629 emit_operand(dst, src); 630 } 631 632 633 void Assembler::mov(Register dst, Register src) { 634 EnsureSpace ensure_space(this); 635 EMIT(0x89); 636 EMIT(0xC0 | src.code() << 3 | dst.code()); 637 } 638 639 void Assembler::mov(Operand dst, const Immediate& x) { 640 EnsureSpace ensure_space(this); 641 EMIT(0xC7); 642 emit_operand(eax, dst); 643 emit(x); 644 } 645 646 void Assembler::mov(Operand dst, Address src, RelocInfo::Mode rmode) { 647 EnsureSpace ensure_space(this); 648 EMIT(0xC7); 649 emit_operand(eax, dst); 650 emit(src, rmode); 651 } 652 653 void Assembler::mov(Operand dst, Handle<HeapObject> handle) { 654 EnsureSpace ensure_space(this); 655 EMIT(0xC7); 656 emit_operand(eax, dst); 657 emit(handle); 658 } 659 660 void Assembler::mov(Operand dst, Register src) { 661 EnsureSpace ensure_space(this); 662 EMIT(0x89); 663 emit_operand(src, dst); 664 } 665 666 void Assembler::movsx_b(Register dst, Operand src) { 667 EnsureSpace ensure_space(this); 668 EMIT(0x0F); 669 EMIT(0xBE); 670 emit_operand(dst, src); 671 } 672 673 void Assembler::movsx_w(Register dst, Operand src) { 674 EnsureSpace ensure_space(this); 675 EMIT(0x0F); 676 EMIT(0xBF); 677 emit_operand(dst, src); 678 } 679 680 void Assembler::movzx_b(Register dst, Operand src) { 681 EnsureSpace ensure_space(this); 682 EMIT(0x0F); 683 EMIT(0xB6); 684 emit_operand(dst, src); 685 } 686 687 void Assembler::movzx_w(Register dst, Operand src) { 688 EnsureSpace ensure_space(this); 689 EMIT(0x0F); 690 EMIT(0xB7); 691 emit_operand(dst, src); 692 } 693 694 void Assembler::movq(XMMRegister dst, Operand src) { 695 EnsureSpace ensure_space(this); 696 EMIT(0xF3); 697 EMIT(0x0F); 698 EMIT(0x7E); 699 emit_operand(dst, src); 700 } 701 702 void Assembler::cmov(Condition cc, Register dst, Operand src) { 703 EnsureSpace ensure_space(this); 704 // Opcode: 0f 40 + cc /r. 705 EMIT(0x0F); 706 EMIT(0x40 + cc); 707 emit_operand(dst, src); 708 } 709 710 711 void Assembler::cld() { 712 EnsureSpace ensure_space(this); 713 EMIT(0xFC); 714 } 715 716 717 void Assembler::rep_movs() { 718 EnsureSpace ensure_space(this); 719 EMIT(0xF3); 720 EMIT(0xA5); 721 } 722 723 724 void Assembler::rep_stos() { 725 EnsureSpace ensure_space(this); 726 EMIT(0xF3); 727 EMIT(0xAB); 728 } 729 730 731 void Assembler::stos() { 732 EnsureSpace ensure_space(this); 733 EMIT(0xAB); 734 } 735 736 737 void Assembler::xchg(Register dst, Register src) { 738 EnsureSpace ensure_space(this); 739 if (src == eax || dst == eax) { // Single-byte encoding. 740 EMIT(0x90 | (src == eax ? dst.code() : src.code())); 741 } else { 742 EMIT(0x87); 743 EMIT(0xC0 | src.code() << 3 | dst.code()); 744 } 745 } 746 747 void Assembler::xchg(Register dst, Operand src) { 748 EnsureSpace ensure_space(this); 749 EMIT(0x87); 750 emit_operand(dst, src); 751 } 752 753 void Assembler::xchg_b(Register reg, Operand op) { 754 DCHECK(reg.is_byte_register()); 755 EnsureSpace ensure_space(this); 756 EMIT(0x86); 757 emit_operand(reg, op); 758 } 759 760 void Assembler::xchg_w(Register reg, Operand op) { 761 EnsureSpace ensure_space(this); 762 EMIT(0x66); 763 EMIT(0x87); 764 emit_operand(reg, op); 765 } 766 767 void Assembler::lock() { 768 EnsureSpace ensure_space(this); 769 EMIT(0xF0); 770 } 771 772 void Assembler::cmpxchg(Operand dst, Register src) { 773 EnsureSpace ensure_space(this); 774 EMIT(0x0F); 775 EMIT(0xB1); 776 emit_operand(src, dst); 777 } 778 779 void Assembler::cmpxchg_b(Operand dst, Register src) { 780 DCHECK(src.is_byte_register()); 781 EnsureSpace ensure_space(this); 782 EMIT(0x0F); 783 EMIT(0xB0); 784 emit_operand(src, dst); 785 } 786 787 void Assembler::cmpxchg_w(Operand dst, Register src) { 788 EnsureSpace ensure_space(this); 789 EMIT(0x66); 790 EMIT(0x0F); 791 EMIT(0xB1); 792 emit_operand(src, dst); 793 } 794 795 void Assembler::cmpxchg8b(Operand dst) { 796 EnsureSpace enure_space(this); 797 EMIT(0x0F); 798 EMIT(0xC7); 799 emit_operand(ecx, dst); 800 } 801 802 void Assembler::lfence() { 803 EnsureSpace ensure_space(this); 804 EMIT(0x0F); 805 EMIT(0xAE); 806 EMIT(0xE8); 807 } 808 809 void Assembler::pause() { 810 EnsureSpace ensure_space(this); 811 EMIT(0xF3); 812 EMIT(0x90); 813 } 814 815 void Assembler::adc(Register dst, int32_t imm32) { 816 EnsureSpace ensure_space(this); 817 emit_arith(2, Operand(dst), Immediate(imm32)); 818 } 819 820 void Assembler::adc(Register dst, Operand src) { 821 EnsureSpace ensure_space(this); 822 EMIT(0x13); 823 emit_operand(dst, src); 824 } 825 826 void Assembler::add(Register dst, Operand src) { 827 EnsureSpace ensure_space(this); 828 EMIT(0x03); 829 emit_operand(dst, src); 830 } 831 832 void Assembler::add(Operand dst, Register src) { 833 EnsureSpace ensure_space(this); 834 EMIT(0x01); 835 emit_operand(src, dst); 836 } 837 838 void Assembler::add(Operand dst, const Immediate& x) { 839 DCHECK_NOT_NULL(reloc_info_writer.last_pc()); 840 EnsureSpace ensure_space(this); 841 emit_arith(0, dst, x); 842 } 843 844 845 void Assembler::and_(Register dst, int32_t imm32) { 846 and_(dst, Immediate(imm32)); 847 } 848 849 850 void Assembler::and_(Register dst, const Immediate& x) { 851 EnsureSpace ensure_space(this); 852 emit_arith(4, Operand(dst), x); 853 } 854 855 void Assembler::and_(Register dst, Operand src) { 856 EnsureSpace ensure_space(this); 857 EMIT(0x23); 858 emit_operand(dst, src); 859 } 860 861 void Assembler::and_(Operand dst, const Immediate& x) { 862 EnsureSpace ensure_space(this); 863 emit_arith(4, dst, x); 864 } 865 866 void Assembler::and_(Operand dst, Register src) { 867 EnsureSpace ensure_space(this); 868 EMIT(0x21); 869 emit_operand(src, dst); 870 } 871 872 void Assembler::cmpb(Operand op, Immediate imm8) { 873 DCHECK(imm8.is_int8() || imm8.is_uint8()); 874 EnsureSpace ensure_space(this); 875 if (op.is_reg(eax)) { 876 EMIT(0x3C); 877 } else { 878 EMIT(0x80); 879 emit_operand(edi, op); // edi == 7 880 } 881 emit_b(imm8); 882 } 883 884 void Assembler::cmpb(Operand op, Register reg) { 885 CHECK(reg.is_byte_register()); 886 EnsureSpace ensure_space(this); 887 EMIT(0x38); 888 emit_operand(reg, op); 889 } 890 891 void Assembler::cmpb(Register reg, Operand op) { 892 CHECK(reg.is_byte_register()); 893 EnsureSpace ensure_space(this); 894 EMIT(0x3A); 895 emit_operand(reg, op); 896 } 897 898 void Assembler::cmpw(Operand op, Immediate imm16) { 899 DCHECK(imm16.is_int16() || imm16.is_uint16()); 900 EnsureSpace ensure_space(this); 901 EMIT(0x66); 902 EMIT(0x81); 903 emit_operand(edi, op); 904 emit_w(imm16); 905 } 906 907 void Assembler::cmpw(Register reg, Operand op) { 908 EnsureSpace ensure_space(this); 909 EMIT(0x66); 910 EMIT(0x3B); 911 emit_operand(reg, op); 912 } 913 914 void Assembler::cmpw(Operand op, Register reg) { 915 EnsureSpace ensure_space(this); 916 EMIT(0x66); 917 EMIT(0x39); 918 emit_operand(reg, op); 919 } 920 921 void Assembler::cmp(Register reg, int32_t imm32) { 922 EnsureSpace ensure_space(this); 923 emit_arith(7, Operand(reg), Immediate(imm32)); 924 } 925 926 void Assembler::cmp(Register reg, Handle<HeapObject> handle) { 927 EnsureSpace ensure_space(this); 928 emit_arith(7, Operand(reg), Immediate(handle)); 929 } 930 931 void Assembler::cmp(Register reg, Operand op) { 932 EnsureSpace ensure_space(this); 933 EMIT(0x3B); 934 emit_operand(reg, op); 935 } 936 937 void Assembler::cmp(Operand op, Register reg) { 938 EnsureSpace ensure_space(this); 939 EMIT(0x39); 940 emit_operand(reg, op); 941 } 942 943 void Assembler::cmp(Operand op, const Immediate& imm) { 944 EnsureSpace ensure_space(this); 945 emit_arith(7, op, imm); 946 } 947 948 void Assembler::cmp(Operand op, Handle<HeapObject> handle) { 949 EnsureSpace ensure_space(this); 950 emit_arith(7, op, Immediate(handle)); 951 } 952 953 void Assembler::cmpb_al(Operand op) { 954 EnsureSpace ensure_space(this); 955 EMIT(0x38); // CMP r/m8, r8 956 emit_operand(eax, op); // eax has same code as register al. 957 } 958 959 void Assembler::cmpw_ax(Operand op) { 960 EnsureSpace ensure_space(this); 961 EMIT(0x66); 962 EMIT(0x39); // CMP r/m16, r16 963 emit_operand(eax, op); // eax has same code as register ax. 964 } 965 966 967 void Assembler::dec_b(Register dst) { 968 CHECK(dst.is_byte_register()); 969 EnsureSpace ensure_space(this); 970 EMIT(0xFE); 971 EMIT(0xC8 | dst.code()); 972 } 973 974 void Assembler::dec_b(Operand dst) { 975 EnsureSpace ensure_space(this); 976 EMIT(0xFE); 977 emit_operand(ecx, dst); 978 } 979 980 981 void Assembler::dec(Register dst) { 982 EnsureSpace ensure_space(this); 983 EMIT(0x48 | dst.code()); 984 } 985 986 void Assembler::dec(Operand dst) { 987 EnsureSpace ensure_space(this); 988 EMIT(0xFF); 989 emit_operand(ecx, dst); 990 } 991 992 993 void Assembler::cdq() { 994 EnsureSpace ensure_space(this); 995 EMIT(0x99); 996 } 997 998 void Assembler::idiv(Operand src) { 999 EnsureSpace ensure_space(this); 1000 EMIT(0xF7); 1001 emit_operand(edi, src); 1002 } 1003 1004 void Assembler::div(Operand src) { 1005 EnsureSpace ensure_space(this); 1006 EMIT(0xF7); 1007 emit_operand(esi, src); 1008 } 1009 1010 1011 void Assembler::imul(Register reg) { 1012 EnsureSpace ensure_space(this); 1013 EMIT(0xF7); 1014 EMIT(0xE8 | reg.code()); 1015 } 1016 1017 void Assembler::imul(Register dst, Operand src) { 1018 EnsureSpace ensure_space(this); 1019 EMIT(0x0F); 1020 EMIT(0xAF); 1021 emit_operand(dst, src); 1022 } 1023 1024 1025 void Assembler::imul(Register dst, Register src, int32_t imm32) { 1026 imul(dst, Operand(src), imm32); 1027 } 1028 1029 void Assembler::imul(Register dst, Operand src, int32_t imm32) { 1030 EnsureSpace ensure_space(this); 1031 if (is_int8(imm32)) { 1032 EMIT(0x6B); 1033 emit_operand(dst, src); 1034 EMIT(imm32); 1035 } else { 1036 EMIT(0x69); 1037 emit_operand(dst, src); 1038 emit(imm32); 1039 } 1040 } 1041 1042 1043 void Assembler::inc(Register dst) { 1044 EnsureSpace ensure_space(this); 1045 EMIT(0x40 | dst.code()); 1046 } 1047 1048 void Assembler::inc(Operand dst) { 1049 EnsureSpace ensure_space(this); 1050 EMIT(0xFF); 1051 emit_operand(eax, dst); 1052 } 1053 1054 void Assembler::lea(Register dst, Operand src) { 1055 EnsureSpace ensure_space(this); 1056 EMIT(0x8D); 1057 emit_operand(dst, src); 1058 } 1059 1060 1061 void Assembler::mul(Register src) { 1062 EnsureSpace ensure_space(this); 1063 EMIT(0xF7); 1064 EMIT(0xE0 | src.code()); 1065 } 1066 1067 1068 void Assembler::neg(Register dst) { 1069 EnsureSpace ensure_space(this); 1070 EMIT(0xF7); 1071 EMIT(0xD8 | dst.code()); 1072 } 1073 1074 void Assembler::neg(Operand dst) { 1075 EnsureSpace ensure_space(this); 1076 EMIT(0xF7); 1077 emit_operand(ebx, dst); 1078 } 1079 1080 1081 void Assembler::not_(Register dst) { 1082 EnsureSpace ensure_space(this); 1083 EMIT(0xF7); 1084 EMIT(0xD0 | dst.code()); 1085 } 1086 1087 void Assembler::not_(Operand dst) { 1088 EnsureSpace ensure_space(this); 1089 EMIT(0xF7); 1090 emit_operand(edx, dst); 1091 } 1092 1093 1094 void Assembler::or_(Register dst, int32_t imm32) { 1095 EnsureSpace ensure_space(this); 1096 emit_arith(1, Operand(dst), Immediate(imm32)); 1097 } 1098 1099 void Assembler::or_(Register dst, Operand src) { 1100 EnsureSpace ensure_space(this); 1101 EMIT(0x0B); 1102 emit_operand(dst, src); 1103 } 1104 1105 void Assembler::or_(Operand dst, const Immediate& x) { 1106 EnsureSpace ensure_space(this); 1107 emit_arith(1, dst, x); 1108 } 1109 1110 void Assembler::or_(Operand dst, Register src) { 1111 EnsureSpace ensure_space(this); 1112 EMIT(0x09); 1113 emit_operand(src, dst); 1114 } 1115 1116 1117 void Assembler::rcl(Register dst, uint8_t imm8) { 1118 EnsureSpace ensure_space(this); 1119 DCHECK(is_uint5(imm8)); // illegal shift count 1120 if (imm8 == 1) { 1121 EMIT(0xD1); 1122 EMIT(0xD0 | dst.code()); 1123 } else { 1124 EMIT(0xC1); 1125 EMIT(0xD0 | dst.code()); 1126 EMIT(imm8); 1127 } 1128 } 1129 1130 1131 void Assembler::rcr(Register dst, uint8_t imm8) { 1132 EnsureSpace ensure_space(this); 1133 DCHECK(is_uint5(imm8)); // illegal shift count 1134 if (imm8 == 1) { 1135 EMIT(0xD1); 1136 EMIT(0xD8 | dst.code()); 1137 } else { 1138 EMIT(0xC1); 1139 EMIT(0xD8 | dst.code()); 1140 EMIT(imm8); 1141 } 1142 } 1143 1144 void Assembler::ror(Operand dst, uint8_t imm8) { 1145 EnsureSpace ensure_space(this); 1146 DCHECK(is_uint5(imm8)); // illegal shift count 1147 if (imm8 == 1) { 1148 EMIT(0xD1); 1149 emit_operand(ecx, dst); 1150 } else { 1151 EMIT(0xC1); 1152 emit_operand(ecx, dst); 1153 EMIT(imm8); 1154 } 1155 } 1156 1157 void Assembler::ror_cl(Operand dst) { 1158 EnsureSpace ensure_space(this); 1159 EMIT(0xD3); 1160 emit_operand(ecx, dst); 1161 } 1162 1163 void Assembler::sar(Operand dst, uint8_t imm8) { 1164 EnsureSpace ensure_space(this); 1165 DCHECK(is_uint5(imm8)); // illegal shift count 1166 if (imm8 == 1) { 1167 EMIT(0xD1); 1168 emit_operand(edi, dst); 1169 } else { 1170 EMIT(0xC1); 1171 emit_operand(edi, dst); 1172 EMIT(imm8); 1173 } 1174 } 1175 1176 void Assembler::sar_cl(Operand dst) { 1177 EnsureSpace ensure_space(this); 1178 EMIT(0xD3); 1179 emit_operand(edi, dst); 1180 } 1181 1182 void Assembler::sbb(Register dst, Operand src) { 1183 EnsureSpace ensure_space(this); 1184 EMIT(0x1B); 1185 emit_operand(dst, src); 1186 } 1187 1188 void Assembler::shld(Register dst, Register src, uint8_t shift) { 1189 DCHECK(is_uint5(shift)); 1190 EnsureSpace ensure_space(this); 1191 EMIT(0x0F); 1192 EMIT(0xA4); 1193 emit_operand(src, Operand(dst)); 1194 EMIT(shift); 1195 } 1196 1197 void Assembler::shld_cl(Register dst, Register src) { 1198 EnsureSpace ensure_space(this); 1199 EMIT(0x0F); 1200 EMIT(0xA5); 1201 emit_operand(src, Operand(dst)); 1202 } 1203 1204 void Assembler::shl(Operand dst, uint8_t imm8) { 1205 EnsureSpace ensure_space(this); 1206 DCHECK(is_uint5(imm8)); // illegal shift count 1207 if (imm8 == 1) { 1208 EMIT(0xD1); 1209 emit_operand(esp, dst); 1210 } else { 1211 EMIT(0xC1); 1212 emit_operand(esp, dst); 1213 EMIT(imm8); 1214 } 1215 } 1216 1217 void Assembler::shl_cl(Operand dst) { 1218 EnsureSpace ensure_space(this); 1219 EMIT(0xD3); 1220 emit_operand(esp, dst); 1221 } 1222 1223 void Assembler::shr(Operand dst, uint8_t imm8) { 1224 EnsureSpace ensure_space(this); 1225 DCHECK(is_uint5(imm8)); // illegal shift count 1226 if (imm8 == 1) { 1227 EMIT(0xD1); 1228 emit_operand(ebp, dst); 1229 } else { 1230 EMIT(0xC1); 1231 emit_operand(ebp, dst); 1232 EMIT(imm8); 1233 } 1234 } 1235 1236 void Assembler::shr_cl(Operand dst) { 1237 EnsureSpace ensure_space(this); 1238 EMIT(0xD3); 1239 emit_operand(ebp, dst); 1240 } 1241 1242 void Assembler::shrd(Register dst, Register src, uint8_t shift) { 1243 DCHECK(is_uint5(shift)); 1244 EnsureSpace ensure_space(this); 1245 EMIT(0x0F); 1246 EMIT(0xAC); 1247 emit_operand(dst, Operand(src)); 1248 EMIT(shift); 1249 } 1250 1251 void Assembler::shrd_cl(Operand dst, Register src) { 1252 EnsureSpace ensure_space(this); 1253 EMIT(0x0F); 1254 EMIT(0xAD); 1255 emit_operand(src, dst); 1256 } 1257 1258 void Assembler::sub(Operand dst, const Immediate& x) { 1259 EnsureSpace ensure_space(this); 1260 emit_arith(5, dst, x); 1261 } 1262 1263 void Assembler::sub(Register dst, Operand src) { 1264 EnsureSpace ensure_space(this); 1265 EMIT(0x2B); 1266 emit_operand(dst, src); 1267 } 1268 1269 void Assembler::sub(Operand dst, Register src) { 1270 EnsureSpace ensure_space(this); 1271 EMIT(0x29); 1272 emit_operand(src, dst); 1273 } 1274 1275 void Assembler::sub_sp_32(uint32_t imm) { 1276 EnsureSpace ensure_space(this); 1277 EMIT(0x81); // using a literal 32-bit immediate. 1278 static constexpr Register ireg = Register::from_code<5>(); 1279 emit_operand(ireg, Operand(esp)); 1280 emit(imm); 1281 } 1282 1283 void Assembler::test(Register reg, const Immediate& imm) { 1284 if (imm.is_uint8()) { 1285 test_b(reg, imm); 1286 return; 1287 } 1288 1289 EnsureSpace ensure_space(this); 1290 // This is not using emit_arith because test doesn't support 1291 // sign-extension of 8-bit operands. 1292 if (reg == eax) { 1293 EMIT(0xA9); 1294 } else { 1295 EMIT(0xF7); 1296 EMIT(0xC0 | reg.code()); 1297 } 1298 emit(imm); 1299 } 1300 1301 void Assembler::test(Register reg, Operand op) { 1302 EnsureSpace ensure_space(this); 1303 EMIT(0x85); 1304 emit_operand(reg, op); 1305 } 1306 1307 void Assembler::test_b(Register reg, Operand op) { 1308 CHECK(reg.is_byte_register()); 1309 EnsureSpace ensure_space(this); 1310 EMIT(0x84); 1311 emit_operand(reg, op); 1312 } 1313 1314 void Assembler::test(Operand op, const Immediate& imm) { 1315 if (op.is_reg_only()) { 1316 test(op.reg(), imm); 1317 return; 1318 } 1319 if (imm.is_uint8()) { 1320 return test_b(op, imm); 1321 } 1322 EnsureSpace ensure_space(this); 1323 EMIT(0xF7); 1324 emit_operand(eax, op); 1325 emit(imm); 1326 } 1327 1328 void Assembler::test_b(Register reg, Immediate imm8) { 1329 DCHECK(imm8.is_uint8()); 1330 EnsureSpace ensure_space(this); 1331 // Only use test against byte for registers that have a byte 1332 // variant: eax, ebx, ecx, and edx. 1333 if (reg == eax) { 1334 EMIT(0xA8); 1335 emit_b(imm8); 1336 } else if (reg.is_byte_register()) { 1337 emit_arith_b(0xF6, 0xC0, reg, static_cast<uint8_t>(imm8.immediate())); 1338 } else { 1339 EMIT(0x66); 1340 EMIT(0xF7); 1341 EMIT(0xC0 | reg.code()); 1342 emit_w(imm8); 1343 } 1344 } 1345 1346 void Assembler::test_b(Operand op, Immediate imm8) { 1347 if (op.is_reg_only()) { 1348 test_b(op.reg(), imm8); 1349 return; 1350 } 1351 EnsureSpace ensure_space(this); 1352 EMIT(0xF6); 1353 emit_operand(eax, op); 1354 emit_b(imm8); 1355 } 1356 1357 void Assembler::test_w(Register reg, Immediate imm16) { 1358 DCHECK(imm16.is_int16() || imm16.is_uint16()); 1359 EnsureSpace ensure_space(this); 1360 if (reg == eax) { 1361 EMIT(0xA9); 1362 emit_w(imm16); 1363 } else { 1364 EMIT(0x66); 1365 EMIT(0xF7); 1366 EMIT(0xC0 | reg.code()); 1367 emit_w(imm16); 1368 } 1369 } 1370 1371 void Assembler::test_w(Register reg, Operand op) { 1372 EnsureSpace ensure_space(this); 1373 EMIT(0x66); 1374 EMIT(0x85); 1375 emit_operand(reg, op); 1376 } 1377 1378 void Assembler::test_w(Operand op, Immediate imm16) { 1379 DCHECK(imm16.is_int16() || imm16.is_uint16()); 1380 if (op.is_reg_only()) { 1381 test_w(op.reg(), imm16); 1382 return; 1383 } 1384 EnsureSpace ensure_space(this); 1385 EMIT(0x66); 1386 EMIT(0xF7); 1387 emit_operand(eax, op); 1388 emit_w(imm16); 1389 } 1390 1391 void Assembler::xor_(Register dst, int32_t imm32) { 1392 EnsureSpace ensure_space(this); 1393 emit_arith(6, Operand(dst), Immediate(imm32)); 1394 } 1395 1396 void Assembler::xor_(Register dst, Operand src) { 1397 EnsureSpace ensure_space(this); 1398 EMIT(0x33); 1399 emit_operand(dst, src); 1400 } 1401 1402 void Assembler::xor_(Operand dst, Register src) { 1403 EnsureSpace ensure_space(this); 1404 EMIT(0x31); 1405 emit_operand(src, dst); 1406 } 1407 1408 void Assembler::xor_(Operand dst, const Immediate& x) { 1409 EnsureSpace ensure_space(this); 1410 emit_arith(6, dst, x); 1411 } 1412 1413 void Assembler::bswap(Register dst) { 1414 EnsureSpace ensure_space(this); 1415 EMIT(0x0F); 1416 EMIT(0xC8 + dst.code()); 1417 } 1418 1419 void Assembler::bt(Operand dst, Register src) { 1420 EnsureSpace ensure_space(this); 1421 EMIT(0x0F); 1422 EMIT(0xA3); 1423 emit_operand(src, dst); 1424 } 1425 1426 void Assembler::bts(Operand dst, Register src) { 1427 EnsureSpace ensure_space(this); 1428 EMIT(0x0F); 1429 EMIT(0xAB); 1430 emit_operand(src, dst); 1431 } 1432 1433 void Assembler::bsr(Register dst, Operand src) { 1434 EnsureSpace ensure_space(this); 1435 EMIT(0x0F); 1436 EMIT(0xBD); 1437 emit_operand(dst, src); 1438 } 1439 1440 void Assembler::bsf(Register dst, Operand src) { 1441 EnsureSpace ensure_space(this); 1442 EMIT(0x0F); 1443 EMIT(0xBC); 1444 emit_operand(dst, src); 1445 } 1446 1447 1448 void Assembler::hlt() { 1449 EnsureSpace ensure_space(this); 1450 EMIT(0xF4); 1451 } 1452 1453 1454 void Assembler::int3() { 1455 EnsureSpace ensure_space(this); 1456 EMIT(0xCC); 1457 } 1458 1459 1460 void Assembler::nop() { 1461 EnsureSpace ensure_space(this); 1462 EMIT(0x90); 1463 } 1464 1465 1466 void Assembler::ret(int imm16) { 1467 EnsureSpace ensure_space(this); 1468 DCHECK(is_uint16(imm16)); 1469 if (imm16 == 0) { 1470 EMIT(0xC3); 1471 } else { 1472 EMIT(0xC2); 1473 EMIT(imm16 & 0xFF); 1474 EMIT((imm16 >> 8) & 0xFF); 1475 } 1476 } 1477 1478 1479 void Assembler::ud2() { 1480 EnsureSpace ensure_space(this); 1481 EMIT(0x0F); 1482 EMIT(0x0B); 1483 } 1484 1485 1486 // Labels refer to positions in the (to be) generated code. 1487 // There are bound, linked, and unused labels. 1488 // 1489 // Bound labels refer to known positions in the already 1490 // generated code. pos() is the position the label refers to. 1491 // 1492 // Linked labels refer to unknown positions in the code 1493 // to be generated; pos() is the position of the 32bit 1494 // Displacement of the last instruction using the label. 1495 1496 void Assembler::print(const Label* L) { 1497 if (L->is_unused()) { 1498 PrintF("unused label\n"); 1499 } else if (L->is_bound()) { 1500 PrintF("bound label to %d\n", L->pos()); 1501 } else if (L->is_linked()) { 1502 Label l; 1503 l.link_to(L->pos()); 1504 PrintF("unbound label"); 1505 while (l.is_linked()) { 1506 Displacement disp = disp_at(&l); 1507 PrintF("@ %d ", l.pos()); 1508 disp.print(); 1509 PrintF("\n"); 1510 disp.next(&l); 1511 } 1512 } else { 1513 PrintF("label in inconsistent state (pos = %d)\n", L->pos_); 1514 } 1515 } 1516 1517 1518 void Assembler::bind_to(Label* L, int pos) { 1519 EnsureSpace ensure_space(this); 1520 DCHECK(0 <= pos && pos <= pc_offset()); // must have a valid binding position 1521 while (L->is_linked()) { 1522 Displacement disp = disp_at(L); 1523 int fixup_pos = L->pos(); 1524 if (disp.type() == Displacement::CODE_ABSOLUTE) { 1525 long_at_put(fixup_pos, reinterpret_cast<int>(buffer_ + pos)); 1526 internal_reference_positions_.push_back(fixup_pos); 1527 } else if (disp.type() == Displacement::CODE_RELATIVE) { 1528 // Relative to Code* heap object pointer. 1529 long_at_put(fixup_pos, pos + Code::kHeaderSize - kHeapObjectTag); 1530 } else { 1531 if (disp.type() == Displacement::UNCONDITIONAL_JUMP) { 1532 DCHECK_EQ(byte_at(fixup_pos - 1), 0xE9); // jmp expected 1533 } 1534 // Relative address, relative to point after address. 1535 int imm32 = pos - (fixup_pos + sizeof(int32_t)); 1536 long_at_put(fixup_pos, imm32); 1537 } 1538 disp.next(L); 1539 } 1540 while (L->is_near_linked()) { 1541 int fixup_pos = L->near_link_pos(); 1542 int offset_to_next = 1543 static_cast<int>(*reinterpret_cast<int8_t*>(addr_at(fixup_pos))); 1544 DCHECK_LE(offset_to_next, 0); 1545 // Relative address, relative to point after address. 1546 int disp = pos - fixup_pos - sizeof(int8_t); 1547 CHECK(0 <= disp && disp <= 127); 1548 set_byte_at(fixup_pos, disp); 1549 if (offset_to_next < 0) { 1550 L->link_to(fixup_pos + offset_to_next, Label::kNear); 1551 } else { 1552 L->UnuseNear(); 1553 } 1554 } 1555 1556 // Optimization stage 1557 auto jump_opt = jump_optimization_info(); 1558 if (jump_opt && jump_opt->is_optimizing()) { 1559 auto it = label_farjmp_maps_.find(L); 1560 if (it != label_farjmp_maps_.end()) { 1561 auto& pos_vector = it->second; 1562 for (auto fixup_pos : pos_vector) { 1563 int disp = pos - (fixup_pos + sizeof(int8_t)); 1564 CHECK(is_int8(disp)); 1565 set_byte_at(fixup_pos, disp); 1566 } 1567 label_farjmp_maps_.erase(it); 1568 } 1569 } 1570 L->bind_to(pos); 1571 } 1572 1573 1574 void Assembler::bind(Label* L) { 1575 EnsureSpace ensure_space(this); 1576 DCHECK(!L->is_bound()); // label can only be bound once 1577 bind_to(L, pc_offset()); 1578 } 1579 1580 void Assembler::record_farjmp_position(Label* L, int pos) { 1581 auto& pos_vector = label_farjmp_maps_[L]; 1582 pos_vector.push_back(pos); 1583 } 1584 1585 bool Assembler::is_optimizable_farjmp(int idx) { 1586 if (predictable_code_size()) return false; 1587 1588 auto jump_opt = jump_optimization_info(); 1589 CHECK(jump_opt->is_optimizing()); 1590 1591 auto& bitmap = jump_opt->farjmp_bitmap(); 1592 CHECK(idx < static_cast<int>(bitmap.size() * 32)); 1593 return !!(bitmap[idx / 32] & (1 << (idx & 31))); 1594 } 1595 1596 void Assembler::call(Label* L) { 1597 EnsureSpace ensure_space(this); 1598 if (L->is_bound()) { 1599 const int long_size = 5; 1600 int offs = L->pos() - pc_offset(); 1601 DCHECK_LE(offs, 0); 1602 // 1110 1000 #32-bit disp. 1603 EMIT(0xE8); 1604 emit(offs - long_size); 1605 } else { 1606 // 1110 1000 #32-bit disp. 1607 EMIT(0xE8); 1608 emit_disp(L, Displacement::OTHER); 1609 } 1610 } 1611 1612 void Assembler::call(Address entry, RelocInfo::Mode rmode) { 1613 EnsureSpace ensure_space(this); 1614 DCHECK(!RelocInfo::IsCodeTarget(rmode)); 1615 EMIT(0xE8); 1616 if (RelocInfo::IsRuntimeEntry(rmode)) { 1617 emit(entry, rmode); 1618 } else { 1619 emit(entry - (reinterpret_cast<Address>(pc_) + sizeof(int32_t)), rmode); 1620 } 1621 } 1622 1623 void Assembler::wasm_call(Address entry, RelocInfo::Mode rmode) { 1624 EnsureSpace ensure_space(this); 1625 EMIT(0xE8); 1626 emit(entry, rmode); 1627 } 1628 1629 void Assembler::call(Operand adr) { 1630 EnsureSpace ensure_space(this); 1631 EMIT(0xFF); 1632 emit_operand(edx, adr); 1633 } 1634 1635 void Assembler::call(Handle<Code> code, RelocInfo::Mode rmode) { 1636 EnsureSpace ensure_space(this); 1637 DCHECK(RelocInfo::IsCodeTarget(rmode)); 1638 EMIT(0xE8); 1639 emit(code, rmode); 1640 } 1641 1642 void Assembler::call(CodeStub* stub) { 1643 EnsureSpace ensure_space(this); 1644 EMIT(0xE8); 1645 emit(Immediate::EmbeddedCode(stub)); 1646 } 1647 1648 void Assembler::jmp_rel(int offset) { 1649 EnsureSpace ensure_space(this); 1650 const int short_size = 2; 1651 const int long_size = 5; 1652 if (is_int8(offset - short_size)) { 1653 // 1110 1011 #8-bit disp. 1654 EMIT(0xEB); 1655 EMIT((offset - short_size) & 0xFF); 1656 } else { 1657 // 1110 1001 #32-bit disp. 1658 EMIT(0xE9); 1659 emit(offset - long_size); 1660 } 1661 } 1662 1663 void Assembler::jmp(Label* L, Label::Distance distance) { 1664 if (L->is_bound()) { 1665 int offset = L->pos() - pc_offset(); 1666 DCHECK_LE(offset, 0); // backward jump. 1667 jmp_rel(offset); 1668 return; 1669 } 1670 1671 EnsureSpace ensure_space(this); 1672 if (distance == Label::kNear) { 1673 EMIT(0xEB); 1674 emit_near_disp(L); 1675 } else { 1676 auto jump_opt = jump_optimization_info(); 1677 if (V8_UNLIKELY(jump_opt)) { 1678 if (jump_opt->is_optimizing() && is_optimizable_farjmp(farjmp_num_++)) { 1679 EMIT(0xEB); 1680 record_farjmp_position(L, pc_offset()); 1681 EMIT(0); 1682 return; 1683 } 1684 if (jump_opt->is_collecting()) { 1685 farjmp_positions_.push_back(pc_offset() + 1); 1686 } 1687 } 1688 // 1110 1001 #32-bit disp. 1689 EMIT(0xE9); 1690 emit_disp(L, Displacement::UNCONDITIONAL_JUMP); 1691 } 1692 } 1693 1694 void Assembler::jmp(Address entry, RelocInfo::Mode rmode) { 1695 EnsureSpace ensure_space(this); 1696 DCHECK(!RelocInfo::IsCodeTarget(rmode)); 1697 EMIT(0xE9); 1698 if (RelocInfo::IsRuntimeEntry(rmode)) { 1699 emit(entry, rmode); 1700 } else { 1701 emit(entry - (reinterpret_cast<Address>(pc_) + sizeof(int32_t)), rmode); 1702 } 1703 } 1704 1705 void Assembler::jmp(Operand adr) { 1706 EnsureSpace ensure_space(this); 1707 EMIT(0xFF); 1708 emit_operand(esp, adr); 1709 } 1710 1711 1712 void Assembler::jmp(Handle<Code> code, RelocInfo::Mode rmode) { 1713 EnsureSpace ensure_space(this); 1714 DCHECK(RelocInfo::IsCodeTarget(rmode)); 1715 EMIT(0xE9); 1716 emit(code, rmode); 1717 } 1718 1719 1720 void Assembler::j(Condition cc, Label* L, Label::Distance distance) { 1721 EnsureSpace ensure_space(this); 1722 DCHECK(0 <= cc && static_cast<int>(cc) < 16); 1723 if (L->is_bound()) { 1724 const int short_size = 2; 1725 const int long_size = 6; 1726 int offs = L->pos() - pc_offset(); 1727 DCHECK_LE(offs, 0); 1728 if (is_int8(offs - short_size)) { 1729 // 0111 tttn #8-bit disp 1730 EMIT(0x70 | cc); 1731 EMIT((offs - short_size) & 0xFF); 1732 } else { 1733 // 0000 1111 1000 tttn #32-bit disp 1734 EMIT(0x0F); 1735 EMIT(0x80 | cc); 1736 emit(offs - long_size); 1737 } 1738 } else if (distance == Label::kNear) { 1739 EMIT(0x70 | cc); 1740 emit_near_disp(L); 1741 } else { 1742 auto jump_opt = jump_optimization_info(); 1743 if (V8_UNLIKELY(jump_opt)) { 1744 if (jump_opt->is_optimizing() && is_optimizable_farjmp(farjmp_num_++)) { 1745 // 0111 tttn #8-bit disp 1746 EMIT(0x70 | cc); 1747 record_farjmp_position(L, pc_offset()); 1748 EMIT(0); 1749 return; 1750 } 1751 if (jump_opt->is_collecting()) { 1752 farjmp_positions_.push_back(pc_offset() + 2); 1753 } 1754 } 1755 // 0000 1111 1000 tttn #32-bit disp 1756 // Note: could eliminate cond. jumps to this jump if condition 1757 // is the same however, seems to be rather unlikely case. 1758 EMIT(0x0F); 1759 EMIT(0x80 | cc); 1760 emit_disp(L, Displacement::OTHER); 1761 } 1762 } 1763 1764 1765 void Assembler::j(Condition cc, byte* entry, RelocInfo::Mode rmode) { 1766 EnsureSpace ensure_space(this); 1767 DCHECK((0 <= cc) && (static_cast<int>(cc) < 16)); 1768 // 0000 1111 1000 tttn #32-bit disp. 1769 EMIT(0x0F); 1770 EMIT(0x80 | cc); 1771 if (RelocInfo::IsRuntimeEntry(rmode)) { 1772 emit(reinterpret_cast<uint32_t>(entry), rmode); 1773 } else { 1774 emit(entry - (pc_ + sizeof(int32_t)), rmode); 1775 } 1776 } 1777 1778 1779 void Assembler::j(Condition cc, Handle<Code> code, RelocInfo::Mode rmode) { 1780 EnsureSpace ensure_space(this); 1781 // 0000 1111 1000 tttn #32-bit disp 1782 EMIT(0x0F); 1783 EMIT(0x80 | cc); 1784 emit(code, rmode); 1785 } 1786 1787 1788 // FPU instructions. 1789 1790 void Assembler::fld(int i) { 1791 EnsureSpace ensure_space(this); 1792 emit_farith(0xD9, 0xC0, i); 1793 } 1794 1795 1796 void Assembler::fstp(int i) { 1797 EnsureSpace ensure_space(this); 1798 emit_farith(0xDD, 0xD8, i); 1799 } 1800 1801 1802 void Assembler::fld1() { 1803 EnsureSpace ensure_space(this); 1804 EMIT(0xD9); 1805 EMIT(0xE8); 1806 } 1807 1808 1809 void Assembler::fldpi() { 1810 EnsureSpace ensure_space(this); 1811 EMIT(0xD9); 1812 EMIT(0xEB); 1813 } 1814 1815 1816 void Assembler::fldz() { 1817 EnsureSpace ensure_space(this); 1818 EMIT(0xD9); 1819 EMIT(0xEE); 1820 } 1821 1822 1823 void Assembler::fldln2() { 1824 EnsureSpace ensure_space(this); 1825 EMIT(0xD9); 1826 EMIT(0xED); 1827 } 1828 1829 void Assembler::fld_s(Operand adr) { 1830 EnsureSpace ensure_space(this); 1831 EMIT(0xD9); 1832 emit_operand(eax, adr); 1833 } 1834 1835 void Assembler::fld_d(Operand adr) { 1836 EnsureSpace ensure_space(this); 1837 EMIT(0xDD); 1838 emit_operand(eax, adr); 1839 } 1840 1841 void Assembler::fstp_s(Operand adr) { 1842 EnsureSpace ensure_space(this); 1843 EMIT(0xD9); 1844 emit_operand(ebx, adr); 1845 } 1846 1847 void Assembler::fst_s(Operand adr) { 1848 EnsureSpace ensure_space(this); 1849 EMIT(0xD9); 1850 emit_operand(edx, adr); 1851 } 1852 1853 void Assembler::fstp_d(Operand adr) { 1854 EnsureSpace ensure_space(this); 1855 EMIT(0xDD); 1856 emit_operand(ebx, adr); 1857 } 1858 1859 void Assembler::fst_d(Operand adr) { 1860 EnsureSpace ensure_space(this); 1861 EMIT(0xDD); 1862 emit_operand(edx, adr); 1863 } 1864 1865 void Assembler::fild_s(Operand adr) { 1866 EnsureSpace ensure_space(this); 1867 EMIT(0xDB); 1868 emit_operand(eax, adr); 1869 } 1870 1871 void Assembler::fild_d(Operand adr) { 1872 EnsureSpace ensure_space(this); 1873 EMIT(0xDF); 1874 emit_operand(ebp, adr); 1875 } 1876 1877 void Assembler::fistp_s(Operand adr) { 1878 EnsureSpace ensure_space(this); 1879 EMIT(0xDB); 1880 emit_operand(ebx, adr); 1881 } 1882 1883 void Assembler::fisttp_s(Operand adr) { 1884 DCHECK(IsEnabled(SSE3)); 1885 EnsureSpace ensure_space(this); 1886 EMIT(0xDB); 1887 emit_operand(ecx, adr); 1888 } 1889 1890 void Assembler::fisttp_d(Operand adr) { 1891 DCHECK(IsEnabled(SSE3)); 1892 EnsureSpace ensure_space(this); 1893 EMIT(0xDD); 1894 emit_operand(ecx, adr); 1895 } 1896 1897 void Assembler::fist_s(Operand adr) { 1898 EnsureSpace ensure_space(this); 1899 EMIT(0xDB); 1900 emit_operand(edx, adr); 1901 } 1902 1903 void Assembler::fistp_d(Operand adr) { 1904 EnsureSpace ensure_space(this); 1905 EMIT(0xDF); 1906 emit_operand(edi, adr); 1907 } 1908 1909 1910 void Assembler::fabs() { 1911 EnsureSpace ensure_space(this); 1912 EMIT(0xD9); 1913 EMIT(0xE1); 1914 } 1915 1916 1917 void Assembler::fchs() { 1918 EnsureSpace ensure_space(this); 1919 EMIT(0xD9); 1920 EMIT(0xE0); 1921 } 1922 1923 1924 void Assembler::fcos() { 1925 EnsureSpace ensure_space(this); 1926 EMIT(0xD9); 1927 EMIT(0xFF); 1928 } 1929 1930 1931 void Assembler::fsin() { 1932 EnsureSpace ensure_space(this); 1933 EMIT(0xD9); 1934 EMIT(0xFE); 1935 } 1936 1937 1938 void Assembler::fptan() { 1939 EnsureSpace ensure_space(this); 1940 EMIT(0xD9); 1941 EMIT(0xF2); 1942 } 1943 1944 1945 void Assembler::fyl2x() { 1946 EnsureSpace ensure_space(this); 1947 EMIT(0xD9); 1948 EMIT(0xF1); 1949 } 1950 1951 1952 void Assembler::f2xm1() { 1953 EnsureSpace ensure_space(this); 1954 EMIT(0xD9); 1955 EMIT(0xF0); 1956 } 1957 1958 1959 void Assembler::fscale() { 1960 EnsureSpace ensure_space(this); 1961 EMIT(0xD9); 1962 EMIT(0xFD); 1963 } 1964 1965 1966 void Assembler::fninit() { 1967 EnsureSpace ensure_space(this); 1968 EMIT(0xDB); 1969 EMIT(0xE3); 1970 } 1971 1972 1973 void Assembler::fadd(int i) { 1974 EnsureSpace ensure_space(this); 1975 emit_farith(0xDC, 0xC0, i); 1976 } 1977 1978 1979 void Assembler::fadd_i(int i) { 1980 EnsureSpace ensure_space(this); 1981 emit_farith(0xD8, 0xC0, i); 1982 } 1983 1984 1985 void Assembler::fsub(int i) { 1986 EnsureSpace ensure_space(this); 1987 emit_farith(0xDC, 0xE8, i); 1988 } 1989 1990 1991 void Assembler::fsub_i(int i) { 1992 EnsureSpace ensure_space(this); 1993 emit_farith(0xD8, 0xE0, i); 1994 } 1995 1996 void Assembler::fisub_s(Operand adr) { 1997 EnsureSpace ensure_space(this); 1998 EMIT(0xDA); 1999 emit_operand(esp, adr); 2000 } 2001 2002 2003 void Assembler::fmul_i(int i) { 2004 EnsureSpace ensure_space(this); 2005 emit_farith(0xD8, 0xC8, i); 2006 } 2007 2008 2009 void Assembler::fmul(int i) { 2010 EnsureSpace ensure_space(this); 2011 emit_farith(0xDC, 0xC8, i); 2012 } 2013 2014 2015 void Assembler::fdiv(int i) { 2016 EnsureSpace ensure_space(this); 2017 emit_farith(0xDC, 0xF8, i); 2018 } 2019 2020 2021 void Assembler::fdiv_i(int i) { 2022 EnsureSpace ensure_space(this); 2023 emit_farith(0xD8, 0xF0, i); 2024 } 2025 2026 2027 void Assembler::faddp(int i) { 2028 EnsureSpace ensure_space(this); 2029 emit_farith(0xDE, 0xC0, i); 2030 } 2031 2032 2033 void Assembler::fsubp(int i) { 2034 EnsureSpace ensure_space(this); 2035 emit_farith(0xDE, 0xE8, i); 2036 } 2037 2038 2039 void Assembler::fsubrp(int i) { 2040 EnsureSpace ensure_space(this); 2041 emit_farith(0xDE, 0xE0, i); 2042 } 2043 2044 2045 void Assembler::fmulp(int i) { 2046 EnsureSpace ensure_space(this); 2047 emit_farith(0xDE, 0xC8, i); 2048 } 2049 2050 2051 void Assembler::fdivp(int i) { 2052 EnsureSpace ensure_space(this); 2053 emit_farith(0xDE, 0xF8, i); 2054 } 2055 2056 2057 void Assembler::fprem() { 2058 EnsureSpace ensure_space(this); 2059 EMIT(0xD9); 2060 EMIT(0xF8); 2061 } 2062 2063 2064 void Assembler::fprem1() { 2065 EnsureSpace ensure_space(this); 2066 EMIT(0xD9); 2067 EMIT(0xF5); 2068 } 2069 2070 2071 void Assembler::fxch(int i) { 2072 EnsureSpace ensure_space(this); 2073 emit_farith(0xD9, 0xC8, i); 2074 } 2075 2076 2077 void Assembler::fincstp() { 2078 EnsureSpace ensure_space(this); 2079 EMIT(0xD9); 2080 EMIT(0xF7); 2081 } 2082 2083 2084 void Assembler::ffree(int i) { 2085 EnsureSpace ensure_space(this); 2086 emit_farith(0xDD, 0xC0, i); 2087 } 2088 2089 2090 void Assembler::ftst() { 2091 EnsureSpace ensure_space(this); 2092 EMIT(0xD9); 2093 EMIT(0xE4); 2094 } 2095 2096 2097 void Assembler::fucomp(int i) { 2098 EnsureSpace ensure_space(this); 2099 emit_farith(0xDD, 0xE8, i); 2100 } 2101 2102 2103 void Assembler::fucompp() { 2104 EnsureSpace ensure_space(this); 2105 EMIT(0xDA); 2106 EMIT(0xE9); 2107 } 2108 2109 2110 void Assembler::fucomi(int i) { 2111 EnsureSpace ensure_space(this); 2112 EMIT(0xDB); 2113 EMIT(0xE8 + i); 2114 } 2115 2116 2117 void Assembler::fucomip() { 2118 EnsureSpace ensure_space(this); 2119 EMIT(0xDF); 2120 EMIT(0xE9); 2121 } 2122 2123 2124 void Assembler::fcompp() { 2125 EnsureSpace ensure_space(this); 2126 EMIT(0xDE); 2127 EMIT(0xD9); 2128 } 2129 2130 2131 void Assembler::fnstsw_ax() { 2132 EnsureSpace ensure_space(this); 2133 EMIT(0xDF); 2134 EMIT(0xE0); 2135 } 2136 2137 2138 void Assembler::fwait() { 2139 EnsureSpace ensure_space(this); 2140 EMIT(0x9B); 2141 } 2142 2143 2144 void Assembler::frndint() { 2145 EnsureSpace ensure_space(this); 2146 EMIT(0xD9); 2147 EMIT(0xFC); 2148 } 2149 2150 2151 void Assembler::fnclex() { 2152 EnsureSpace ensure_space(this); 2153 EMIT(0xDB); 2154 EMIT(0xE2); 2155 } 2156 2157 2158 void Assembler::sahf() { 2159 EnsureSpace ensure_space(this); 2160 EMIT(0x9E); 2161 } 2162 2163 2164 void Assembler::setcc(Condition cc, Register reg) { 2165 DCHECK(reg.is_byte_register()); 2166 EnsureSpace ensure_space(this); 2167 EMIT(0x0F); 2168 EMIT(0x90 | cc); 2169 EMIT(0xC0 | reg.code()); 2170 } 2171 2172 void Assembler::cvttss2si(Register dst, Operand src) { 2173 EnsureSpace ensure_space(this); 2174 EMIT(0xF3); 2175 EMIT(0x0F); 2176 EMIT(0x2C); 2177 emit_operand(dst, src); 2178 } 2179 2180 void Assembler::cvttsd2si(Register dst, Operand src) { 2181 EnsureSpace ensure_space(this); 2182 EMIT(0xF2); 2183 EMIT(0x0F); 2184 EMIT(0x2C); 2185 emit_operand(dst, src); 2186 } 2187 2188 2189 void Assembler::cvtsd2si(Register dst, XMMRegister src) { 2190 EnsureSpace ensure_space(this); 2191 EMIT(0xF2); 2192 EMIT(0x0F); 2193 EMIT(0x2D); 2194 emit_sse_operand(dst, src); 2195 } 2196 2197 void Assembler::cvtsi2ss(XMMRegister dst, Operand src) { 2198 EnsureSpace ensure_space(this); 2199 EMIT(0xF3); 2200 EMIT(0x0F); 2201 EMIT(0x2A); 2202 emit_sse_operand(dst, src); 2203 } 2204 2205 void Assembler::cvtsi2sd(XMMRegister dst, Operand src) { 2206 EnsureSpace ensure_space(this); 2207 EMIT(0xF2); 2208 EMIT(0x0F); 2209 EMIT(0x2A); 2210 emit_sse_operand(dst, src); 2211 } 2212 2213 void Assembler::cvtss2sd(XMMRegister dst, Operand src) { 2214 EnsureSpace ensure_space(this); 2215 EMIT(0xF3); 2216 EMIT(0x0F); 2217 EMIT(0x5A); 2218 emit_sse_operand(dst, src); 2219 } 2220 2221 void Assembler::cvtsd2ss(XMMRegister dst, Operand src) { 2222 EnsureSpace ensure_space(this); 2223 EMIT(0xF2); 2224 EMIT(0x0F); 2225 EMIT(0x5A); 2226 emit_sse_operand(dst, src); 2227 } 2228 2229 void Assembler::cvtdq2ps(XMMRegister dst, Operand src) { 2230 EnsureSpace ensure_space(this); 2231 EMIT(0x0F); 2232 EMIT(0x5B); 2233 emit_sse_operand(dst, src); 2234 } 2235 2236 void Assembler::cvttps2dq(XMMRegister dst, Operand src) { 2237 EnsureSpace ensure_space(this); 2238 EMIT(0xF3); 2239 EMIT(0x0F); 2240 EMIT(0x5B); 2241 emit_sse_operand(dst, src); 2242 } 2243 2244 void Assembler::addsd(XMMRegister dst, Operand src) { 2245 EnsureSpace ensure_space(this); 2246 EMIT(0xF2); 2247 EMIT(0x0F); 2248 EMIT(0x58); 2249 emit_sse_operand(dst, src); 2250 } 2251 2252 void Assembler::mulsd(XMMRegister dst, Operand src) { 2253 EnsureSpace ensure_space(this); 2254 EMIT(0xF2); 2255 EMIT(0x0F); 2256 EMIT(0x59); 2257 emit_sse_operand(dst, src); 2258 } 2259 2260 void Assembler::subsd(XMMRegister dst, Operand src) { 2261 EnsureSpace ensure_space(this); 2262 EMIT(0xF2); 2263 EMIT(0x0F); 2264 EMIT(0x5C); 2265 emit_sse_operand(dst, src); 2266 } 2267 2268 void Assembler::divsd(XMMRegister dst, Operand src) { 2269 EnsureSpace ensure_space(this); 2270 EMIT(0xF2); 2271 EMIT(0x0F); 2272 EMIT(0x5E); 2273 emit_sse_operand(dst, src); 2274 } 2275 2276 void Assembler::xorpd(XMMRegister dst, Operand src) { 2277 EnsureSpace ensure_space(this); 2278 EMIT(0x66); 2279 EMIT(0x0F); 2280 EMIT(0x57); 2281 emit_sse_operand(dst, src); 2282 } 2283 2284 void Assembler::andps(XMMRegister dst, Operand src) { 2285 EnsureSpace ensure_space(this); 2286 EMIT(0x0F); 2287 EMIT(0x54); 2288 emit_sse_operand(dst, src); 2289 } 2290 2291 void Assembler::orps(XMMRegister dst, Operand src) { 2292 EnsureSpace ensure_space(this); 2293 EMIT(0x0F); 2294 EMIT(0x56); 2295 emit_sse_operand(dst, src); 2296 } 2297 2298 void Assembler::xorps(XMMRegister dst, Operand src) { 2299 EnsureSpace ensure_space(this); 2300 EMIT(0x0F); 2301 EMIT(0x57); 2302 emit_sse_operand(dst, src); 2303 } 2304 2305 void Assembler::addps(XMMRegister dst, Operand src) { 2306 EnsureSpace ensure_space(this); 2307 EMIT(0x0F); 2308 EMIT(0x58); 2309 emit_sse_operand(dst, src); 2310 } 2311 2312 void Assembler::subps(XMMRegister dst, Operand src) { 2313 EnsureSpace ensure_space(this); 2314 EMIT(0x0F); 2315 EMIT(0x5C); 2316 emit_sse_operand(dst, src); 2317 } 2318 2319 void Assembler::mulps(XMMRegister dst, Operand src) { 2320 EnsureSpace ensure_space(this); 2321 EMIT(0x0F); 2322 EMIT(0x59); 2323 emit_sse_operand(dst, src); 2324 } 2325 2326 void Assembler::divps(XMMRegister dst, Operand src) { 2327 EnsureSpace ensure_space(this); 2328 EMIT(0x0F); 2329 EMIT(0x5E); 2330 emit_sse_operand(dst, src); 2331 } 2332 2333 void Assembler::rcpps(XMMRegister dst, Operand src) { 2334 EnsureSpace ensure_space(this); 2335 EMIT(0x0F); 2336 EMIT(0x53); 2337 emit_sse_operand(dst, src); 2338 } 2339 2340 void Assembler::rsqrtps(XMMRegister dst, Operand src) { 2341 EnsureSpace ensure_space(this); 2342 EMIT(0x0F); 2343 EMIT(0x52); 2344 emit_sse_operand(dst, src); 2345 } 2346 2347 void Assembler::minps(XMMRegister dst, Operand src) { 2348 EnsureSpace ensure_space(this); 2349 EMIT(0x0F); 2350 EMIT(0x5D); 2351 emit_sse_operand(dst, src); 2352 } 2353 2354 void Assembler::maxps(XMMRegister dst, Operand src) { 2355 EnsureSpace ensure_space(this); 2356 EMIT(0x0F); 2357 EMIT(0x5F); 2358 emit_sse_operand(dst, src); 2359 } 2360 2361 void Assembler::cmpps(XMMRegister dst, Operand src, int8_t cmp) { 2362 EnsureSpace ensure_space(this); 2363 EMIT(0x0F); 2364 EMIT(0xC2); 2365 emit_sse_operand(dst, src); 2366 EMIT(cmp); 2367 } 2368 2369 void Assembler::sqrtsd(XMMRegister dst, Operand src) { 2370 EnsureSpace ensure_space(this); 2371 EMIT(0xF2); 2372 EMIT(0x0F); 2373 EMIT(0x51); 2374 emit_sse_operand(dst, src); 2375 } 2376 2377 void Assembler::haddps(XMMRegister dst, Operand src) { 2378 DCHECK(IsEnabled(SSE3)); 2379 EnsureSpace ensure_space(this); 2380 EMIT(0xF2); 2381 EMIT(0x0F); 2382 EMIT(0x7C); 2383 emit_sse_operand(dst, src); 2384 } 2385 2386 void Assembler::andpd(XMMRegister dst, Operand src) { 2387 EnsureSpace ensure_space(this); 2388 EMIT(0x66); 2389 EMIT(0x0F); 2390 EMIT(0x54); 2391 emit_sse_operand(dst, src); 2392 } 2393 2394 void Assembler::orpd(XMMRegister dst, Operand src) { 2395 EnsureSpace ensure_space(this); 2396 EMIT(0x66); 2397 EMIT(0x0F); 2398 EMIT(0x56); 2399 emit_sse_operand(dst, src); 2400 } 2401 2402 void Assembler::ucomisd(XMMRegister dst, Operand src) { 2403 EnsureSpace ensure_space(this); 2404 EMIT(0x66); 2405 EMIT(0x0F); 2406 EMIT(0x2E); 2407 emit_sse_operand(dst, src); 2408 } 2409 2410 2411 void Assembler::roundss(XMMRegister dst, XMMRegister src, RoundingMode mode) { 2412 DCHECK(IsEnabled(SSE4_1)); 2413 EnsureSpace ensure_space(this); 2414 EMIT(0x66); 2415 EMIT(0x0F); 2416 EMIT(0x3A); 2417 EMIT(0x0A); 2418 emit_sse_operand(dst, src); 2419 // Mask precision exeption. 2420 EMIT(static_cast<byte>(mode) | 0x8); 2421 } 2422 2423 2424 void Assembler::roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode) { 2425 DCHECK(IsEnabled(SSE4_1)); 2426 EnsureSpace ensure_space(this); 2427 EMIT(0x66); 2428 EMIT(0x0F); 2429 EMIT(0x3A); 2430 EMIT(0x0B); 2431 emit_sse_operand(dst, src); 2432 // Mask precision exeption. 2433 EMIT(static_cast<byte>(mode) | 0x8); 2434 } 2435 2436 2437 void Assembler::movmskpd(Register dst, XMMRegister src) { 2438 EnsureSpace ensure_space(this); 2439 EMIT(0x66); 2440 EMIT(0x0F); 2441 EMIT(0x50); 2442 emit_sse_operand(dst, src); 2443 } 2444 2445 2446 void Assembler::movmskps(Register dst, XMMRegister src) { 2447 EnsureSpace ensure_space(this); 2448 EMIT(0x0F); 2449 EMIT(0x50); 2450 emit_sse_operand(dst, src); 2451 } 2452 2453 void Assembler::maxsd(XMMRegister dst, Operand src) { 2454 EnsureSpace ensure_space(this); 2455 EMIT(0xF2); 2456 EMIT(0x0F); 2457 EMIT(0x5F); 2458 emit_sse_operand(dst, src); 2459 } 2460 2461 void Assembler::minsd(XMMRegister dst, Operand src) { 2462 EnsureSpace ensure_space(this); 2463 EMIT(0xF2); 2464 EMIT(0x0F); 2465 EMIT(0x5D); 2466 emit_sse_operand(dst, src); 2467 } 2468 2469 2470 void Assembler::cmpltsd(XMMRegister dst, XMMRegister src) { 2471 EnsureSpace ensure_space(this); 2472 EMIT(0xF2); 2473 EMIT(0x0F); 2474 EMIT(0xC2); 2475 emit_sse_operand(dst, src); 2476 EMIT(1); // LT == 1 2477 } 2478 2479 2480 void Assembler::movaps(XMMRegister dst, XMMRegister src) { 2481 EnsureSpace ensure_space(this); 2482 EMIT(0x0F); 2483 EMIT(0x28); 2484 emit_sse_operand(dst, src); 2485 } 2486 2487 void Assembler::movups(XMMRegister dst, XMMRegister src) { 2488 EnsureSpace ensure_space(this); 2489 EMIT(0x0F); 2490 EMIT(0x10); 2491 emit_sse_operand(dst, src); 2492 } 2493 2494 void Assembler::movups(XMMRegister dst, Operand src) { 2495 EnsureSpace ensure_space(this); 2496 EMIT(0x0F); 2497 EMIT(0x10); 2498 emit_sse_operand(dst, src); 2499 } 2500 2501 void Assembler::movups(Operand dst, XMMRegister src) { 2502 EnsureSpace ensure_space(this); 2503 EMIT(0x0F); 2504 EMIT(0x11); 2505 emit_sse_operand(src, dst); 2506 } 2507 2508 void Assembler::shufps(XMMRegister dst, XMMRegister src, byte imm8) { 2509 DCHECK(is_uint8(imm8)); 2510 EnsureSpace ensure_space(this); 2511 EMIT(0x0F); 2512 EMIT(0xC6); 2513 emit_sse_operand(dst, src); 2514 EMIT(imm8); 2515 } 2516 2517 void Assembler::movdqa(Operand dst, XMMRegister src) { 2518 EnsureSpace ensure_space(this); 2519 EMIT(0x66); 2520 EMIT(0x0F); 2521 EMIT(0x7F); 2522 emit_sse_operand(src, dst); 2523 } 2524 2525 void Assembler::movdqa(XMMRegister dst, Operand src) { 2526 EnsureSpace ensure_space(this); 2527 EMIT(0x66); 2528 EMIT(0x0F); 2529 EMIT(0x6F); 2530 emit_sse_operand(dst, src); 2531 } 2532 2533 void Assembler::movdqu(Operand dst, XMMRegister src) { 2534 EnsureSpace ensure_space(this); 2535 EMIT(0xF3); 2536 EMIT(0x0F); 2537 EMIT(0x7F); 2538 emit_sse_operand(src, dst); 2539 } 2540 2541 void Assembler::movdqu(XMMRegister dst, Operand src) { 2542 EnsureSpace ensure_space(this); 2543 EMIT(0xF3); 2544 EMIT(0x0F); 2545 EMIT(0x6F); 2546 emit_sse_operand(dst, src); 2547 } 2548 2549 void Assembler::prefetch(Operand src, int level) { 2550 DCHECK(is_uint2(level)); 2551 EnsureSpace ensure_space(this); 2552 EMIT(0x0F); 2553 EMIT(0x18); 2554 // Emit hint number in Reg position of RegR/M. 2555 XMMRegister code = XMMRegister::from_code(level); 2556 emit_sse_operand(code, src); 2557 } 2558 2559 void Assembler::movsd(Operand dst, XMMRegister src) { 2560 EnsureSpace ensure_space(this); 2561 EMIT(0xF2); // double 2562 EMIT(0x0F); 2563 EMIT(0x11); // store 2564 emit_sse_operand(src, dst); 2565 } 2566 2567 void Assembler::movsd(XMMRegister dst, Operand src) { 2568 EnsureSpace ensure_space(this); 2569 EMIT(0xF2); // double 2570 EMIT(0x0F); 2571 EMIT(0x10); // load 2572 emit_sse_operand(dst, src); 2573 } 2574 2575 void Assembler::movss(Operand dst, XMMRegister src) { 2576 EnsureSpace ensure_space(this); 2577 EMIT(0xF3); // float 2578 EMIT(0x0F); 2579 EMIT(0x11); // store 2580 emit_sse_operand(src, dst); 2581 } 2582 2583 void Assembler::movss(XMMRegister dst, Operand src) { 2584 EnsureSpace ensure_space(this); 2585 EMIT(0xF3); // float 2586 EMIT(0x0F); 2587 EMIT(0x10); // load 2588 emit_sse_operand(dst, src); 2589 } 2590 2591 void Assembler::movd(XMMRegister dst, Operand src) { 2592 EnsureSpace ensure_space(this); 2593 EMIT(0x66); 2594 EMIT(0x0F); 2595 EMIT(0x6E); 2596 emit_sse_operand(dst, src); 2597 } 2598 2599 void Assembler::movd(Operand dst, XMMRegister src) { 2600 EnsureSpace ensure_space(this); 2601 EMIT(0x66); 2602 EMIT(0x0F); 2603 EMIT(0x7E); 2604 emit_sse_operand(src, dst); 2605 } 2606 2607 2608 void Assembler::extractps(Register dst, XMMRegister src, byte imm8) { 2609 DCHECK(IsEnabled(SSE4_1)); 2610 DCHECK(is_uint8(imm8)); 2611 EnsureSpace ensure_space(this); 2612 EMIT(0x66); 2613 EMIT(0x0F); 2614 EMIT(0x3A); 2615 EMIT(0x17); 2616 emit_sse_operand(src, dst); 2617 EMIT(imm8); 2618 } 2619 2620 void Assembler::psllw(XMMRegister reg, int8_t shift) { 2621 EnsureSpace ensure_space(this); 2622 EMIT(0x66); 2623 EMIT(0x0F); 2624 EMIT(0x71); 2625 emit_sse_operand(esi, reg); // esi == 6 2626 EMIT(shift); 2627 } 2628 2629 void Assembler::pslld(XMMRegister reg, int8_t shift) { 2630 EnsureSpace ensure_space(this); 2631 EMIT(0x66); 2632 EMIT(0x0F); 2633 EMIT(0x72); 2634 emit_sse_operand(esi, reg); // esi == 6 2635 EMIT(shift); 2636 } 2637 2638 void Assembler::psrlw(XMMRegister reg, int8_t shift) { 2639 EnsureSpace ensure_space(this); 2640 EMIT(0x66); 2641 EMIT(0x0F); 2642 EMIT(0x71); 2643 emit_sse_operand(edx, reg); // edx == 2 2644 EMIT(shift); 2645 } 2646 2647 void Assembler::psrld(XMMRegister reg, int8_t shift) { 2648 EnsureSpace ensure_space(this); 2649 EMIT(0x66); 2650 EMIT(0x0F); 2651 EMIT(0x72); 2652 emit_sse_operand(edx, reg); // edx == 2 2653 EMIT(shift); 2654 } 2655 2656 void Assembler::psraw(XMMRegister reg, int8_t shift) { 2657 EnsureSpace ensure_space(this); 2658 EMIT(0x66); 2659 EMIT(0x0F); 2660 EMIT(0x71); 2661 emit_sse_operand(esp, reg); // esp == 4 2662 EMIT(shift); 2663 } 2664 2665 void Assembler::psrad(XMMRegister reg, int8_t shift) { 2666 EnsureSpace ensure_space(this); 2667 EMIT(0x66); 2668 EMIT(0x0F); 2669 EMIT(0x72); 2670 emit_sse_operand(esp, reg); // esp == 4 2671 EMIT(shift); 2672 } 2673 2674 void Assembler::psllq(XMMRegister reg, int8_t shift) { 2675 EnsureSpace ensure_space(this); 2676 EMIT(0x66); 2677 EMIT(0x0F); 2678 EMIT(0x73); 2679 emit_sse_operand(esi, reg); // esi == 6 2680 EMIT(shift); 2681 } 2682 2683 2684 void Assembler::psllq(XMMRegister dst, XMMRegister src) { 2685 EnsureSpace ensure_space(this); 2686 EMIT(0x66); 2687 EMIT(0x0F); 2688 EMIT(0xF3); 2689 emit_sse_operand(dst, src); 2690 } 2691 2692 2693 void Assembler::psrlq(XMMRegister reg, int8_t shift) { 2694 EnsureSpace ensure_space(this); 2695 EMIT(0x66); 2696 EMIT(0x0F); 2697 EMIT(0x73); 2698 emit_sse_operand(edx, reg); // edx == 2 2699 EMIT(shift); 2700 } 2701 2702 2703 void Assembler::psrlq(XMMRegister dst, XMMRegister src) { 2704 EnsureSpace ensure_space(this); 2705 EMIT(0x66); 2706 EMIT(0x0F); 2707 EMIT(0xD3); 2708 emit_sse_operand(dst, src); 2709 } 2710 2711 void Assembler::pshufhw(XMMRegister dst, Operand src, uint8_t shuffle) { 2712 EnsureSpace ensure_space(this); 2713 EMIT(0xF3); 2714 EMIT(0x0F); 2715 EMIT(0x70); 2716 emit_sse_operand(dst, src); 2717 EMIT(shuffle); 2718 } 2719 2720 void Assembler::pshuflw(XMMRegister dst, Operand src, uint8_t shuffle) { 2721 EnsureSpace ensure_space(this); 2722 EMIT(0xF2); 2723 EMIT(0x0F); 2724 EMIT(0x70); 2725 emit_sse_operand(dst, src); 2726 EMIT(shuffle); 2727 } 2728 2729 void Assembler::pshufd(XMMRegister dst, Operand src, uint8_t shuffle) { 2730 EnsureSpace ensure_space(this); 2731 EMIT(0x66); 2732 EMIT(0x0F); 2733 EMIT(0x70); 2734 emit_sse_operand(dst, src); 2735 EMIT(shuffle); 2736 } 2737 2738 void Assembler::pblendw(XMMRegister dst, Operand src, uint8_t mask) { 2739 DCHECK(IsEnabled(SSE4_1)); 2740 EnsureSpace ensure_space(this); 2741 EMIT(0x66); 2742 EMIT(0x0F); 2743 EMIT(0x3A); 2744 EMIT(0x0E); 2745 emit_sse_operand(dst, src); 2746 EMIT(mask); 2747 } 2748 2749 void Assembler::palignr(XMMRegister dst, Operand src, uint8_t mask) { 2750 DCHECK(IsEnabled(SSSE3)); 2751 EnsureSpace ensure_space(this); 2752 EMIT(0x66); 2753 EMIT(0x0F); 2754 EMIT(0x3A); 2755 EMIT(0x0F); 2756 emit_sse_operand(dst, src); 2757 EMIT(mask); 2758 } 2759 2760 void Assembler::pextrb(Operand dst, XMMRegister src, int8_t offset) { 2761 DCHECK(IsEnabled(SSE4_1)); 2762 EnsureSpace ensure_space(this); 2763 EMIT(0x66); 2764 EMIT(0x0F); 2765 EMIT(0x3A); 2766 EMIT(0x14); 2767 emit_sse_operand(src, dst); 2768 EMIT(offset); 2769 } 2770 2771 void Assembler::pextrw(Operand dst, XMMRegister src, int8_t offset) { 2772 DCHECK(IsEnabled(SSE4_1)); 2773 EnsureSpace ensure_space(this); 2774 EMIT(0x66); 2775 EMIT(0x0F); 2776 EMIT(0x3A); 2777 EMIT(0x15); 2778 emit_sse_operand(src, dst); 2779 EMIT(offset); 2780 } 2781 2782 void Assembler::pextrd(Operand dst, XMMRegister src, int8_t offset) { 2783 DCHECK(IsEnabled(SSE4_1)); 2784 EnsureSpace ensure_space(this); 2785 EMIT(0x66); 2786 EMIT(0x0F); 2787 EMIT(0x3A); 2788 EMIT(0x16); 2789 emit_sse_operand(src, dst); 2790 EMIT(offset); 2791 } 2792 2793 void Assembler::insertps(XMMRegister dst, Operand src, int8_t offset) { 2794 DCHECK(IsEnabled(SSE4_1)); 2795 EnsureSpace ensure_space(this); 2796 EMIT(0x66); 2797 EMIT(0x0F); 2798 EMIT(0x3A); 2799 EMIT(0x21); 2800 emit_sse_operand(dst, src); 2801 EMIT(offset); 2802 } 2803 2804 void Assembler::pinsrb(XMMRegister dst, Operand src, int8_t offset) { 2805 DCHECK(IsEnabled(SSE4_1)); 2806 EnsureSpace ensure_space(this); 2807 EMIT(0x66); 2808 EMIT(0x0F); 2809 EMIT(0x3A); 2810 EMIT(0x20); 2811 emit_sse_operand(dst, src); 2812 EMIT(offset); 2813 } 2814 2815 void Assembler::pinsrw(XMMRegister dst, Operand src, int8_t offset) { 2816 DCHECK(is_uint8(offset)); 2817 EnsureSpace ensure_space(this); 2818 EMIT(0x66); 2819 EMIT(0x0F); 2820 EMIT(0xC4); 2821 emit_sse_operand(dst, src); 2822 EMIT(offset); 2823 } 2824 2825 void Assembler::pinsrd(XMMRegister dst, Operand src, int8_t offset) { 2826 DCHECK(IsEnabled(SSE4_1)); 2827 EnsureSpace ensure_space(this); 2828 EMIT(0x66); 2829 EMIT(0x0F); 2830 EMIT(0x3A); 2831 EMIT(0x22); 2832 emit_sse_operand(dst, src); 2833 EMIT(offset); 2834 } 2835 2836 void Assembler::addss(XMMRegister dst, Operand src) { 2837 EnsureSpace ensure_space(this); 2838 EMIT(0xF3); 2839 EMIT(0x0F); 2840 EMIT(0x58); 2841 emit_sse_operand(dst, src); 2842 } 2843 2844 void Assembler::subss(XMMRegister dst, Operand src) { 2845 EnsureSpace ensure_space(this); 2846 EMIT(0xF3); 2847 EMIT(0x0F); 2848 EMIT(0x5C); 2849 emit_sse_operand(dst, src); 2850 } 2851 2852 void Assembler::mulss(XMMRegister dst, Operand src) { 2853 EnsureSpace ensure_space(this); 2854 EMIT(0xF3); 2855 EMIT(0x0F); 2856 EMIT(0x59); 2857 emit_sse_operand(dst, src); 2858 } 2859 2860 void Assembler::divss(XMMRegister dst, Operand src) { 2861 EnsureSpace ensure_space(this); 2862 EMIT(0xF3); 2863 EMIT(0x0F); 2864 EMIT(0x5E); 2865 emit_sse_operand(dst, src); 2866 } 2867 2868 void Assembler::sqrtss(XMMRegister dst, Operand src) { 2869 EnsureSpace ensure_space(this); 2870 EMIT(0xF3); 2871 EMIT(0x0F); 2872 EMIT(0x51); 2873 emit_sse_operand(dst, src); 2874 } 2875 2876 void Assembler::ucomiss(XMMRegister dst, Operand src) { 2877 EnsureSpace ensure_space(this); 2878 EMIT(0x0F); 2879 EMIT(0x2E); 2880 emit_sse_operand(dst, src); 2881 } 2882 2883 void Assembler::maxss(XMMRegister dst, Operand src) { 2884 EnsureSpace ensure_space(this); 2885 EMIT(0xF3); 2886 EMIT(0x0F); 2887 EMIT(0x5F); 2888 emit_sse_operand(dst, src); 2889 } 2890 2891 void Assembler::minss(XMMRegister dst, Operand src) { 2892 EnsureSpace ensure_space(this); 2893 EMIT(0xF3); 2894 EMIT(0x0F); 2895 EMIT(0x5D); 2896 emit_sse_operand(dst, src); 2897 } 2898 2899 2900 // AVX instructions 2901 void Assembler::vfmasd(byte op, XMMRegister dst, XMMRegister src1, 2902 Operand src2) { 2903 DCHECK(IsEnabled(FMA3)); 2904 EnsureSpace ensure_space(this); 2905 emit_vex_prefix(src1, kLIG, k66, k0F38, kW1); 2906 EMIT(op); 2907 emit_sse_operand(dst, src2); 2908 } 2909 2910 void Assembler::vfmass(byte op, XMMRegister dst, XMMRegister src1, 2911 Operand src2) { 2912 DCHECK(IsEnabled(FMA3)); 2913 EnsureSpace ensure_space(this); 2914 emit_vex_prefix(src1, kLIG, k66, k0F38, kW0); 2915 EMIT(op); 2916 emit_sse_operand(dst, src2); 2917 } 2918 2919 void Assembler::vsd(byte op, XMMRegister dst, XMMRegister src1, Operand src2) { 2920 vinstr(op, dst, src1, src2, kF2, k0F, kWIG); 2921 } 2922 2923 void Assembler::vss(byte op, XMMRegister dst, XMMRegister src1, Operand src2) { 2924 vinstr(op, dst, src1, src2, kF3, k0F, kWIG); 2925 } 2926 2927 void Assembler::vps(byte op, XMMRegister dst, XMMRegister src1, Operand src2) { 2928 vinstr(op, dst, src1, src2, kNone, k0F, kWIG); 2929 } 2930 2931 void Assembler::vpd(byte op, XMMRegister dst, XMMRegister src1, Operand src2) { 2932 vinstr(op, dst, src1, src2, k66, k0F, kWIG); 2933 } 2934 2935 void Assembler::vcmpps(XMMRegister dst, XMMRegister src1, Operand src2, 2936 int8_t cmp) { 2937 vps(0xC2, dst, src1, src2); 2938 EMIT(cmp); 2939 } 2940 2941 void Assembler::vshufps(XMMRegister dst, XMMRegister src1, Operand src2, 2942 byte imm8) { 2943 DCHECK(is_uint8(imm8)); 2944 vps(0xC6, dst, src1, src2); 2945 EMIT(imm8); 2946 } 2947 2948 void Assembler::vpsllw(XMMRegister dst, XMMRegister src, int8_t imm8) { 2949 XMMRegister iop = XMMRegister::from_code(6); 2950 vinstr(0x71, iop, dst, Operand(src), k66, k0F, kWIG); 2951 EMIT(imm8); 2952 } 2953 2954 void Assembler::vpslld(XMMRegister dst, XMMRegister src, int8_t imm8) { 2955 XMMRegister iop = XMMRegister::from_code(6); 2956 vinstr(0x72, iop, dst, Operand(src), k66, k0F, kWIG); 2957 EMIT(imm8); 2958 } 2959 2960 void Assembler::vpsrlw(XMMRegister dst, XMMRegister src, int8_t imm8) { 2961 XMMRegister iop = XMMRegister::from_code(2); 2962 vinstr(0x71, iop, dst, Operand(src), k66, k0F, kWIG); 2963 EMIT(imm8); 2964 } 2965 2966 void Assembler::vpsrld(XMMRegister dst, XMMRegister src, int8_t imm8) { 2967 XMMRegister iop = XMMRegister::from_code(2); 2968 vinstr(0x72, iop, dst, Operand(src), k66, k0F, kWIG); 2969 EMIT(imm8); 2970 } 2971 2972 void Assembler::vpsraw(XMMRegister dst, XMMRegister src, int8_t imm8) { 2973 XMMRegister iop = XMMRegister::from_code(4); 2974 vinstr(0x71, iop, dst, Operand(src), k66, k0F, kWIG); 2975 EMIT(imm8); 2976 } 2977 2978 void Assembler::vpsrad(XMMRegister dst, XMMRegister src, int8_t imm8) { 2979 XMMRegister iop = XMMRegister::from_code(4); 2980 vinstr(0x72, iop, dst, Operand(src), k66, k0F, kWIG); 2981 EMIT(imm8); 2982 } 2983 2984 void Assembler::vpshufhw(XMMRegister dst, Operand src, uint8_t shuffle) { 2985 vinstr(0x70, dst, xmm0, src, kF3, k0F, kWIG); 2986 EMIT(shuffle); 2987 } 2988 2989 void Assembler::vpshuflw(XMMRegister dst, Operand src, uint8_t shuffle) { 2990 vinstr(0x70, dst, xmm0, src, kF2, k0F, kWIG); 2991 EMIT(shuffle); 2992 } 2993 2994 void Assembler::vpshufd(XMMRegister dst, Operand src, uint8_t shuffle) { 2995 vinstr(0x70, dst, xmm0, src, k66, k0F, kWIG); 2996 EMIT(shuffle); 2997 } 2998 2999 void Assembler::vpblendw(XMMRegister dst, XMMRegister src1, Operand src2, 3000 uint8_t mask) { 3001 vinstr(0x0E, dst, src1, src2, k66, k0F3A, kWIG); 3002 EMIT(mask); 3003 } 3004 3005 void Assembler::vpalignr(XMMRegister dst, XMMRegister src1, Operand src2, 3006 uint8_t mask) { 3007 vinstr(0x0F, dst, src1, src2, k66, k0F3A, kWIG); 3008 EMIT(mask); 3009 } 3010 3011 void Assembler::vpextrb(Operand dst, XMMRegister src, int8_t offset) { 3012 vinstr(0x14, src, xmm0, dst, k66, k0F3A, kWIG); 3013 EMIT(offset); 3014 } 3015 3016 void Assembler::vpextrw(Operand dst, XMMRegister src, int8_t offset) { 3017 vinstr(0x15, src, xmm0, dst, k66, k0F3A, kWIG); 3018 EMIT(offset); 3019 } 3020 3021 void Assembler::vpextrd(Operand dst, XMMRegister src, int8_t offset) { 3022 vinstr(0x16, src, xmm0, dst, k66, k0F3A, kWIG); 3023 EMIT(offset); 3024 } 3025 3026 void Assembler::vinsertps(XMMRegister dst, XMMRegister src1, Operand src2, 3027 int8_t offset) { 3028 vinstr(0x21, dst, src1, src2, k66, k0F3A, kWIG); 3029 EMIT(offset); 3030 } 3031 3032 void Assembler::vpinsrb(XMMRegister dst, XMMRegister src1, Operand src2, 3033 int8_t offset) { 3034 vinstr(0x20, dst, src1, src2, k66, k0F3A, kWIG); 3035 EMIT(offset); 3036 } 3037 3038 void Assembler::vpinsrw(XMMRegister dst, XMMRegister src1, Operand src2, 3039 int8_t offset) { 3040 vinstr(0xC4, dst, src1, src2, k66, k0F, kWIG); 3041 EMIT(offset); 3042 } 3043 3044 void Assembler::vpinsrd(XMMRegister dst, XMMRegister src1, Operand src2, 3045 int8_t offset) { 3046 vinstr(0x22, dst, src1, src2, k66, k0F3A, kWIG); 3047 EMIT(offset); 3048 } 3049 3050 void Assembler::bmi1(byte op, Register reg, Register vreg, Operand rm) { 3051 DCHECK(IsEnabled(BMI1)); 3052 EnsureSpace ensure_space(this); 3053 emit_vex_prefix(vreg, kLZ, kNone, k0F38, kW0); 3054 EMIT(op); 3055 emit_operand(reg, rm); 3056 } 3057 3058 void Assembler::tzcnt(Register dst, Operand src) { 3059 DCHECK(IsEnabled(BMI1)); 3060 EnsureSpace ensure_space(this); 3061 EMIT(0xF3); 3062 EMIT(0x0F); 3063 EMIT(0xBC); 3064 emit_operand(dst, src); 3065 } 3066 3067 void Assembler::lzcnt(Register dst, Operand src) { 3068 DCHECK(IsEnabled(LZCNT)); 3069 EnsureSpace ensure_space(this); 3070 EMIT(0xF3); 3071 EMIT(0x0F); 3072 EMIT(0xBD); 3073 emit_operand(dst, src); 3074 } 3075 3076 void Assembler::popcnt(Register dst, Operand src) { 3077 DCHECK(IsEnabled(POPCNT)); 3078 EnsureSpace ensure_space(this); 3079 EMIT(0xF3); 3080 EMIT(0x0F); 3081 EMIT(0xB8); 3082 emit_operand(dst, src); 3083 } 3084 3085 void Assembler::bmi2(SIMDPrefix pp, byte op, Register reg, Register vreg, 3086 Operand rm) { 3087 DCHECK(IsEnabled(BMI2)); 3088 EnsureSpace ensure_space(this); 3089 emit_vex_prefix(vreg, kLZ, pp, k0F38, kW0); 3090 EMIT(op); 3091 emit_operand(reg, rm); 3092 } 3093 3094 void Assembler::rorx(Register dst, Operand src, byte imm8) { 3095 DCHECK(IsEnabled(BMI2)); 3096 DCHECK(is_uint8(imm8)); 3097 Register vreg = Register::from_code<0>(); // VEX.vvvv unused 3098 EnsureSpace ensure_space(this); 3099 emit_vex_prefix(vreg, kLZ, kF2, k0F3A, kW0); 3100 EMIT(0xF0); 3101 emit_operand(dst, src); 3102 EMIT(imm8); 3103 } 3104 3105 void Assembler::sse2_instr(XMMRegister dst, Operand src, byte prefix, 3106 byte escape, byte opcode) { 3107 EnsureSpace ensure_space(this); 3108 EMIT(prefix); 3109 EMIT(escape); 3110 EMIT(opcode); 3111 emit_sse_operand(dst, src); 3112 } 3113 3114 void Assembler::ssse3_instr(XMMRegister dst, Operand src, byte prefix, 3115 byte escape1, byte escape2, byte opcode) { 3116 DCHECK(IsEnabled(SSSE3)); 3117 EnsureSpace ensure_space(this); 3118 EMIT(prefix); 3119 EMIT(escape1); 3120 EMIT(escape2); 3121 EMIT(opcode); 3122 emit_sse_operand(dst, src); 3123 } 3124 3125 void Assembler::sse4_instr(XMMRegister dst, Operand src, byte prefix, 3126 byte escape1, byte escape2, byte opcode) { 3127 DCHECK(IsEnabled(SSE4_1)); 3128 EnsureSpace ensure_space(this); 3129 EMIT(prefix); 3130 EMIT(escape1); 3131 EMIT(escape2); 3132 EMIT(opcode); 3133 emit_sse_operand(dst, src); 3134 } 3135 3136 void Assembler::vinstr(byte op, XMMRegister dst, XMMRegister src1, Operand src2, 3137 SIMDPrefix pp, LeadingOpcode m, VexW w) { 3138 DCHECK(IsEnabled(AVX)); 3139 EnsureSpace ensure_space(this); 3140 emit_vex_prefix(src1, kL128, pp, m, w); 3141 EMIT(op); 3142 emit_sse_operand(dst, src2); 3143 } 3144 3145 void Assembler::emit_sse_operand(XMMRegister reg, Operand adr) { 3146 Register ireg = Register::from_code(reg.code()); 3147 emit_operand(ireg, adr); 3148 } 3149 3150 3151 void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) { 3152 EMIT(0xC0 | dst.code() << 3 | src.code()); 3153 } 3154 3155 3156 void Assembler::emit_sse_operand(Register dst, XMMRegister src) { 3157 EMIT(0xC0 | dst.code() << 3 | src.code()); 3158 } 3159 3160 3161 void Assembler::emit_sse_operand(XMMRegister dst, Register src) { 3162 EMIT(0xC0 | (dst.code() << 3) | src.code()); 3163 } 3164 3165 3166 void Assembler::emit_vex_prefix(XMMRegister vreg, VectorLength l, SIMDPrefix pp, 3167 LeadingOpcode mm, VexW w) { 3168 if (mm != k0F || w != kW0) { 3169 EMIT(0xC4); 3170 // Change RXB from "110" to "111" to align with gdb disassembler. 3171 EMIT(0xE0 | mm); 3172 EMIT(w | ((~vreg.code() & 0xF) << 3) | l | pp); 3173 } else { 3174 EMIT(0xC5); 3175 EMIT(((~vreg.code()) << 3) | l | pp); 3176 } 3177 } 3178 3179 3180 void Assembler::emit_vex_prefix(Register vreg, VectorLength l, SIMDPrefix pp, 3181 LeadingOpcode mm, VexW w) { 3182 XMMRegister ivreg = XMMRegister::from_code(vreg.code()); 3183 emit_vex_prefix(ivreg, l, pp, mm, w); 3184 } 3185 3186 3187 void Assembler::GrowBuffer() { 3188 DCHECK(buffer_overflow()); 3189 if (!own_buffer_) FATAL("external code buffer is too small"); 3190 3191 // Compute new buffer size. 3192 CodeDesc desc; // the new buffer 3193 desc.buffer_size = 2 * buffer_size_; 3194 3195 // Some internal data structures overflow for very large buffers, 3196 // they must ensure that kMaximalBufferSize is not too large. 3197 if (desc.buffer_size > kMaximalBufferSize) { 3198 V8::FatalProcessOutOfMemory(nullptr, "Assembler::GrowBuffer"); 3199 } 3200 3201 // Set up new buffer. 3202 desc.buffer = NewArray<byte>(desc.buffer_size); 3203 desc.origin = this; 3204 desc.instr_size = pc_offset(); 3205 desc.reloc_size = (buffer_ + buffer_size_) - (reloc_info_writer.pos()); 3206 3207 // Clear the buffer in debug mode. Use 'int3' instructions to make 3208 // sure to get into problems if we ever run uninitialized code. 3209 #ifdef DEBUG 3210 ZapCode(reinterpret_cast<Address>(desc.buffer), desc.buffer_size); 3211 #endif 3212 3213 // Copy the data. 3214 int pc_delta = desc.buffer - buffer_; 3215 int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_); 3216 MemMove(desc.buffer, buffer_, desc.instr_size); 3217 MemMove(rc_delta + reloc_info_writer.pos(), reloc_info_writer.pos(), 3218 desc.reloc_size); 3219 3220 // Switch buffers. 3221 DeleteArray(buffer_); 3222 buffer_ = desc.buffer; 3223 buffer_size_ = desc.buffer_size; 3224 pc_ += pc_delta; 3225 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, 3226 reloc_info_writer.last_pc() + pc_delta); 3227 3228 // Relocate internal references. 3229 for (auto pos : internal_reference_positions_) { 3230 int32_t* p = reinterpret_cast<int32_t*>(buffer_ + pos); 3231 *p += pc_delta; 3232 } 3233 3234 // Relocate pc-relative references. 3235 int mode_mask = RelocInfo::ModeMask(RelocInfo::JS_TO_WASM_CALL) | 3236 RelocInfo::ModeMask(RelocInfo::OFF_HEAP_TARGET); 3237 DCHECK_EQ(mode_mask, RelocInfo::kApplyMask & mode_mask); 3238 for (RelocIterator it(desc, mode_mask); !it.done(); it.next()) { 3239 it.rinfo()->apply(pc_delta); 3240 } 3241 3242 DCHECK(!buffer_overflow()); 3243 } 3244 3245 3246 void Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) { 3247 DCHECK(is_uint8(op1) && is_uint8(op2)); // wrong opcode 3248 DCHECK(is_uint8(imm8)); 3249 DCHECK_EQ(op1 & 0x01, 0); // should be 8bit operation 3250 EMIT(op1); 3251 EMIT(op2 | dst.code()); 3252 EMIT(imm8); 3253 } 3254 3255 3256 void Assembler::emit_arith(int sel, Operand dst, const Immediate& x) { 3257 DCHECK((0 <= sel) && (sel <= 7)); 3258 Register ireg = Register::from_code(sel); 3259 if (x.is_int8()) { 3260 EMIT(0x83); // using a sign-extended 8-bit immediate. 3261 emit_operand(ireg, dst); 3262 EMIT(x.immediate() & 0xFF); 3263 } else if (dst.is_reg(eax)) { 3264 EMIT((sel << 3) | 0x05); // short form if the destination is eax. 3265 emit(x); 3266 } else { 3267 EMIT(0x81); // using a literal 32-bit immediate. 3268 emit_operand(ireg, dst); 3269 emit(x); 3270 } 3271 } 3272 3273 void Assembler::emit_operand(Register reg, Operand adr) { 3274 emit_operand(reg.code(), adr); 3275 } 3276 3277 void Assembler::emit_operand(XMMRegister reg, Operand adr) { 3278 Register ireg = Register::from_code(reg.code()); 3279 emit_operand(ireg, adr); 3280 } 3281 3282 void Assembler::emit_operand(int code, Operand adr) { 3283 // Isolate-independent code may not embed relocatable addresses. 3284 DCHECK(!options().isolate_independent_code || 3285 adr.rmode_ != RelocInfo::CODE_TARGET); 3286 DCHECK(!options().isolate_independent_code || 3287 adr.rmode_ != RelocInfo::EMBEDDED_OBJECT); 3288 // TODO(jgruber,v8:6666): Enable once kRootRegister exists. 3289 // DCHECK(!options().isolate_independent_code || 3290 // adr.rmode_ != RelocInfo::EXTERNAL_REFERENCE); 3291 3292 const unsigned length = adr.len_; 3293 DCHECK_GT(length, 0); 3294 3295 // Emit updated ModRM byte containing the given register. 3296 pc_[0] = (adr.buf_[0] & ~0x38) | (code << 3); 3297 3298 // Emit the rest of the encoded operand. 3299 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i]; 3300 pc_ += length; 3301 3302 // Emit relocation information if necessary. 3303 if (length >= sizeof(int32_t) && !RelocInfo::IsNone(adr.rmode_)) { 3304 pc_ -= sizeof(int32_t); // pc_ must be *at* disp32 3305 RecordRelocInfo(adr.rmode_); 3306 if (adr.rmode_ == RelocInfo::INTERNAL_REFERENCE) { // Fixup for labels 3307 emit_label(*reinterpret_cast<Label**>(pc_)); 3308 } else { 3309 pc_ += sizeof(int32_t); 3310 } 3311 } 3312 } 3313 3314 3315 void Assembler::emit_label(Label* label) { 3316 if (label->is_bound()) { 3317 internal_reference_positions_.push_back(pc_offset()); 3318 emit(reinterpret_cast<uint32_t>(buffer_ + label->pos())); 3319 } else { 3320 emit_disp(label, Displacement::CODE_ABSOLUTE); 3321 } 3322 } 3323 3324 3325 void Assembler::emit_farith(int b1, int b2, int i) { 3326 DCHECK(is_uint8(b1) && is_uint8(b2)); // wrong opcode 3327 DCHECK(0 <= i && i < 8); // illegal stack offset 3328 EMIT(b1); 3329 EMIT(b2 + i); 3330 } 3331 3332 3333 void Assembler::db(uint8_t data) { 3334 EnsureSpace ensure_space(this); 3335 EMIT(data); 3336 } 3337 3338 3339 void Assembler::dd(uint32_t data) { 3340 EnsureSpace ensure_space(this); 3341 emit(data); 3342 } 3343 3344 3345 void Assembler::dq(uint64_t data) { 3346 EnsureSpace ensure_space(this); 3347 emit_q(data); 3348 } 3349 3350 3351 void Assembler::dd(Label* label) { 3352 EnsureSpace ensure_space(this); 3353 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE); 3354 emit_label(label); 3355 } 3356 3357 3358 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { 3359 DCHECK(!RelocInfo::IsNone(rmode)); 3360 if (options().disable_reloc_info_for_patching) return; 3361 // Don't record external references unless the heap will be serialized. 3362 if (RelocInfo::IsOnlyForSerializer(rmode) && 3363 !options().record_reloc_info_for_serialization && !emit_debug_code()) { 3364 return; 3365 } 3366 RelocInfo rinfo(reinterpret_cast<Address>(pc_), rmode, data, nullptr); 3367 reloc_info_writer.Write(&rinfo); 3368 } 3369 3370 3371 } // namespace internal 3372 } // namespace v8 3373 3374 #endif // V8_TARGET_ARCH_IA32 3375