assembler-x64.h revision 0d5e116f6aee03185f237311a943491bb079a768
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 are 6// 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 distribution. 14// 15// - Neither the name of Sun Microsystems or the names of contributors may 16// be used to endorse or promote products derived from this software without 17// specific prior written permission. 18// 19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 23// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31// The original source code covered by the above license above has been 32// modified significantly by Google Inc. 33// Copyright 2006-2009 the V8 project authors. All rights reserved. 34 35// A lightweight X64 Assembler. 36 37#ifndef V8_X64_ASSEMBLER_X64_H_ 38#define V8_X64_ASSEMBLER_X64_H_ 39 40#include "serialize.h" 41 42namespace v8 { 43namespace internal { 44 45// Utility functions 46 47// Test whether a 64-bit value is in a specific range. 48static inline bool is_uint32(int64_t x) { 49 static const uint64_t kMaxUInt32 = V8_UINT64_C(0xffffffff); 50 return static_cast<uint64_t>(x) <= kMaxUInt32; 51} 52 53static inline bool is_int32(int64_t x) { 54 static const int64_t kMinInt32 = -V8_INT64_C(0x80000000); 55 return is_uint32(x - kMinInt32); 56} 57 58static inline bool uint_is_int32(uint64_t x) { 59 static const uint64_t kMaxInt32 = V8_UINT64_C(0x7fffffff); 60 return x <= kMaxInt32; 61} 62 63static inline bool is_uint32(uint64_t x) { 64 static const uint64_t kMaxUInt32 = V8_UINT64_C(0xffffffff); 65 return x <= kMaxUInt32; 66} 67 68// CPU Registers. 69// 70// 1) We would prefer to use an enum, but enum values are assignment- 71// compatible with int, which has caused code-generation bugs. 72// 73// 2) We would prefer to use a class instead of a struct but we don't like 74// the register initialization to depend on the particular initialization 75// order (which appears to be different on OS X, Linux, and Windows for the 76// installed versions of C++ we tried). Using a struct permits C-style 77// "initialization". Also, the Register objects cannot be const as this 78// forces initialization stubs in MSVC, making us dependent on initialization 79// order. 80// 81// 3) By not using an enum, we are possibly preventing the compiler from 82// doing certain constant folds, which may significantly reduce the 83// code generated for some assembly instructions (because they boil down 84// to a few constants). If this is a problem, we could change the code 85// such that we use an enum in optimized mode, and the struct in debug 86// mode. This way we get the compile-time error checking in debug mode 87// and best performance in optimized code. 88// 89 90struct Register { 91 static Register toRegister(int code) { 92 Register r = { code }; 93 return r; 94 } 95 bool is_valid() const { return 0 <= code_ && code_ < 16; } 96 bool is(Register reg) const { return code_ == reg.code_; } 97 int code() const { 98 ASSERT(is_valid()); 99 return code_; 100 } 101 int bit() const { 102 return 1 << code_; 103 } 104 105 // Return the high bit of the register code as a 0 or 1. Used often 106 // when constructing the REX prefix byte. 107 int high_bit() const { 108 return code_ >> 3; 109 } 110 // Return the 3 low bits of the register code. Used when encoding registers 111 // in modR/M, SIB, and opcode bytes. 112 int low_bits() const { 113 return code_ & 0x7; 114 } 115 116 // Unfortunately we can't make this private in a struct when initializing 117 // by assignment. 118 int code_; 119}; 120 121const Register rax = { 0 }; 122const Register rcx = { 1 }; 123const Register rdx = { 2 }; 124const Register rbx = { 3 }; 125const Register rsp = { 4 }; 126const Register rbp = { 5 }; 127const Register rsi = { 6 }; 128const Register rdi = { 7 }; 129const Register r8 = { 8 }; 130const Register r9 = { 9 }; 131const Register r10 = { 10 }; 132const Register r11 = { 11 }; 133const Register r12 = { 12 }; 134const Register r13 = { 13 }; 135const Register r14 = { 14 }; 136const Register r15 = { 15 }; 137const Register no_reg = { -1 }; 138 139 140struct XMMRegister { 141 bool is_valid() const { return 0 <= code_ && code_ < 16; } 142 int code() const { 143 ASSERT(is_valid()); 144 return code_; 145 } 146 147 // Return the high bit of the register code as a 0 or 1. Used often 148 // when constructing the REX prefix byte. 149 int high_bit() const { 150 return code_ >> 3; 151 } 152 // Return the 3 low bits of the register code. Used when encoding registers 153 // in modR/M, SIB, and opcode bytes. 154 int low_bits() const { 155 return code_ & 0x7; 156 } 157 158 int code_; 159}; 160 161const XMMRegister xmm0 = { 0 }; 162const XMMRegister xmm1 = { 1 }; 163const XMMRegister xmm2 = { 2 }; 164const XMMRegister xmm3 = { 3 }; 165const XMMRegister xmm4 = { 4 }; 166const XMMRegister xmm5 = { 5 }; 167const XMMRegister xmm6 = { 6 }; 168const XMMRegister xmm7 = { 7 }; 169const XMMRegister xmm8 = { 8 }; 170const XMMRegister xmm9 = { 9 }; 171const XMMRegister xmm10 = { 10 }; 172const XMMRegister xmm11 = { 11 }; 173const XMMRegister xmm12 = { 12 }; 174const XMMRegister xmm13 = { 13 }; 175const XMMRegister xmm14 = { 14 }; 176const XMMRegister xmm15 = { 15 }; 177 178enum Condition { 179 // any value < 0 is considered no_condition 180 no_condition = -1, 181 182 overflow = 0, 183 no_overflow = 1, 184 below = 2, 185 above_equal = 3, 186 equal = 4, 187 not_equal = 5, 188 below_equal = 6, 189 above = 7, 190 negative = 8, 191 positive = 9, 192 parity_even = 10, 193 parity_odd = 11, 194 less = 12, 195 greater_equal = 13, 196 less_equal = 14, 197 greater = 15, 198 199 // Fake conditions that are handled by the 200 // opcodes using them. 201 always = 16, 202 never = 17, 203 // aliases 204 carry = below, 205 not_carry = above_equal, 206 zero = equal, 207 not_zero = not_equal, 208 sign = negative, 209 not_sign = positive, 210 last_condition = greater 211}; 212 213 214// Returns the equivalent of !cc. 215// Negation of the default no_condition (-1) results in a non-default 216// no_condition value (-2). As long as tests for no_condition check 217// for condition < 0, this will work as expected. 218inline Condition NegateCondition(Condition cc) { 219 return static_cast<Condition>(cc ^ 1); 220} 221 222 223// Corresponds to transposing the operands of a comparison. 224inline Condition ReverseCondition(Condition cc) { 225 switch (cc) { 226 case below: 227 return above; 228 case above: 229 return below; 230 case above_equal: 231 return below_equal; 232 case below_equal: 233 return above_equal; 234 case less: 235 return greater; 236 case greater: 237 return less; 238 case greater_equal: 239 return less_equal; 240 case less_equal: 241 return greater_equal; 242 default: 243 return cc; 244 }; 245} 246 247 248enum Hint { 249 no_hint = 0, 250 not_taken = 0x2e, 251 taken = 0x3e 252}; 253 254// The result of negating a hint is as if the corresponding condition 255// were negated by NegateCondition. That is, no_hint is mapped to 256// itself and not_taken and taken are mapped to each other. 257inline Hint NegateHint(Hint hint) { 258 return (hint == no_hint) 259 ? no_hint 260 : ((hint == not_taken) ? taken : not_taken); 261} 262 263 264// ----------------------------------------------------------------------------- 265// Machine instruction Immediates 266 267class Immediate BASE_EMBEDDED { 268 public: 269 explicit Immediate(int32_t value) : value_(value) {} 270 271 private: 272 int32_t value_; 273 274 friend class Assembler; 275}; 276 277 278// ----------------------------------------------------------------------------- 279// Machine instruction Operands 280 281enum ScaleFactor { 282 times_1 = 0, 283 times_2 = 1, 284 times_4 = 2, 285 times_8 = 3, 286 times_int_size = times_4, 287 times_pointer_size = times_8 288}; 289 290 291class Operand BASE_EMBEDDED { 292 public: 293 // [base + disp/r] 294 Operand(Register base, int32_t disp); 295 296 // [base + index*scale + disp/r] 297 Operand(Register base, 298 Register index, 299 ScaleFactor scale, 300 int32_t disp); 301 302 // [index*scale + disp/r] 303 Operand(Register index, 304 ScaleFactor scale, 305 int32_t disp); 306 307 // Offset from existing memory operand. 308 // Offset is added to existing displacement as 32-bit signed values and 309 // this must not overflow. 310 Operand(const Operand& base, int32_t offset); 311 312 private: 313 byte rex_; 314 byte buf_[6]; 315 // The number of bytes in buf_. 316 unsigned int len_; 317 318 // Set the ModR/M byte without an encoded 'reg' register. The 319 // register is encoded later as part of the emit_operand operation. 320 // set_modrm can be called before or after set_sib and set_disp*. 321 inline void set_modrm(int mod, Register rm); 322 323 // Set the SIB byte if one is needed. Sets the length to 2 rather than 1. 324 inline void set_sib(ScaleFactor scale, Register index, Register base); 325 326 // Adds operand displacement fields (offsets added to the memory address). 327 // Needs to be called after set_sib, not before it. 328 inline void set_disp8(int disp); 329 inline void set_disp32(int disp); 330 331 friend class Assembler; 332}; 333 334 335// CpuFeatures keeps track of which features are supported by the target CPU. 336// Supported features must be enabled by a Scope before use. 337// Example: 338// if (CpuFeatures::IsSupported(SSE3)) { 339// CpuFeatures::Scope fscope(SSE3); 340// // Generate SSE3 floating point code. 341// } else { 342// // Generate standard x87 or SSE2 floating point code. 343// } 344class CpuFeatures : public AllStatic { 345 public: 346 // Detect features of the target CPU. Set safe defaults if the serializer 347 // is enabled (snapshots must be portable). 348 static void Probe(); 349 // Check whether a feature is supported by the target CPU. 350 static bool IsSupported(CpuFeature f) { 351 if (f == SSE2 && !FLAG_enable_sse2) return false; 352 if (f == SSE3 && !FLAG_enable_sse3) return false; 353 if (f == CMOV && !FLAG_enable_cmov) return false; 354 if (f == RDTSC && !FLAG_enable_rdtsc) return false; 355 if (f == SAHF && !FLAG_enable_sahf) return false; 356 return (supported_ & (V8_UINT64_C(1) << f)) != 0; 357 } 358 // Check whether a feature is currently enabled. 359 static bool IsEnabled(CpuFeature f) { 360 return (enabled_ & (V8_UINT64_C(1) << f)) != 0; 361 } 362 // Enable a specified feature within a scope. 363 class Scope BASE_EMBEDDED { 364#ifdef DEBUG 365 public: 366 explicit Scope(CpuFeature f) { 367 uint64_t mask = (V8_UINT64_C(1) << f); 368 ASSERT(CpuFeatures::IsSupported(f)); 369 ASSERT(!Serializer::enabled() || (found_by_runtime_probing_ & mask) == 0); 370 old_enabled_ = CpuFeatures::enabled_; 371 CpuFeatures::enabled_ |= mask; 372 } 373 ~Scope() { CpuFeatures::enabled_ = old_enabled_; } 374 private: 375 uint64_t old_enabled_; 376#else 377 public: 378 explicit Scope(CpuFeature f) {} 379#endif 380 }; 381 private: 382 // Safe defaults include SSE2 and CMOV for X64. It is always available, if 383 // anyone checks, but they shouldn't need to check. 384 static const uint64_t kDefaultCpuFeatures = (1 << SSE2 | 1 << CMOV); 385 static uint64_t supported_; 386 static uint64_t enabled_; 387 static uint64_t found_by_runtime_probing_; 388}; 389 390 391class Assembler : public Malloced { 392 private: 393 // We check before assembling an instruction that there is sufficient 394 // space to write an instruction and its relocation information. 395 // The relocation writer's position must be kGap bytes above the end of 396 // the generated instructions. This leaves enough space for the 397 // longest possible x64 instruction, 15 bytes, and the longest possible 398 // relocation information encoding, RelocInfoWriter::kMaxLength == 16. 399 // (There is a 15 byte limit on x64 instruction length that rules out some 400 // otherwise valid instructions.) 401 // This allows for a single, fast space check per instruction. 402 static const int kGap = 32; 403 404 public: 405 // Create an assembler. Instructions and relocation information are emitted 406 // into a buffer, with the instructions starting from the beginning and the 407 // relocation information starting from the end of the buffer. See CodeDesc 408 // for a detailed comment on the layout (globals.h). 409 // 410 // If the provided buffer is NULL, the assembler allocates and grows its own 411 // buffer, and buffer_size determines the initial buffer size. The buffer is 412 // owned by the assembler and deallocated upon destruction of the assembler. 413 // 414 // If the provided buffer is not NULL, the assembler uses the provided buffer 415 // for code generation and assumes its size to be buffer_size. If the buffer 416 // is too small, a fatal error occurs. No deallocation of the buffer is done 417 // upon destruction of the assembler. 418 Assembler(void* buffer, int buffer_size); 419 ~Assembler(); 420 421 // GetCode emits any pending (non-emitted) code and fills the descriptor 422 // desc. GetCode() is idempotent; it returns the same result if no other 423 // Assembler functions are invoked in between GetCode() calls. 424 void GetCode(CodeDesc* desc); 425 426 // Read/Modify the code target in the relative branch/call instruction at pc. 427 // On the x64 architecture, we use relative jumps with a 32-bit displacement 428 // to jump to other Code objects in the Code space in the heap. 429 // Jumps to C functions are done indirectly through a 64-bit register holding 430 // the absolute address of the target. 431 // These functions convert between absolute Addresses of Code objects and 432 // the relative displacements stored in the code. 433 static inline Address target_address_at(Address pc); 434 static inline void set_target_address_at(Address pc, Address target); 435 436 // This sets the branch destination (which is in the instruction on x64). 437 // This is for calls and branches within generated code. 438 inline static void set_target_at(Address instruction_payload, 439 Address target) { 440 set_target_address_at(instruction_payload, target); 441 } 442 443 // This sets the branch destination (which is a load instruction on x64). 444 // This is for calls and branches to runtime code. 445 inline static void set_external_target_at(Address instruction_payload, 446 Address target) { 447 *reinterpret_cast<Address*>(instruction_payload) = target; 448 } 449 450 inline Handle<Object> code_target_object_handle_at(Address pc); 451 // Number of bytes taken up by the branch target in the code. 452 static const int kCallTargetSize = 4; // Use 32-bit displacement. 453 static const int kExternalTargetSize = 8; // Use 64-bit absolute. 454 // Distance between the address of the code target in the call instruction 455 // and the return address pushed on the stack. 456 static const int kCallTargetAddressOffset = 4; // Use 32-bit displacement. 457 // Distance between the start of the JS return sequence and where the 458 // 32-bit displacement of a near call would be, relative to the pushed 459 // return address. TODO: Use return sequence length instead. 460 // Should equal Debug::kX64JSReturnSequenceLength - kCallTargetAddressOffset; 461 static const int kPatchReturnSequenceAddressOffset = 13 - 4; 462 // Distance between start of patched debug break slot and where the 463 // 32-bit displacement of a near call would be, relative to the pushed 464 // return address. TODO: Use return sequence length instead. 465 // Should equal Debug::kX64JSReturnSequenceLength - kCallTargetAddressOffset; 466 static const int kPatchDebugBreakSlotAddressOffset = 13 - 4; 467 // TODO(X64): Rename this, removing the "Real", after changing the above. 468 static const int kRealPatchReturnSequenceAddressOffset = 2; 469 470 // The x64 JS return sequence is padded with int3 to make it large 471 // enough to hold a call instruction when the debugger patches it. 472 static const int kCallInstructionLength = 13; 473 static const int kJSReturnSequenceLength = 13; 474 475 // The debug break slot must be able to contain a call instruction. 476 static const int kDebugBreakSlotLength = kCallInstructionLength; 477 478 479 // --------------------------------------------------------------------------- 480 // Code generation 481 // 482 // Function names correspond one-to-one to x64 instruction mnemonics. 483 // Unless specified otherwise, instructions operate on 64-bit operands. 484 // 485 // If we need versions of an assembly instruction that operate on different 486 // width arguments, we add a single-letter suffix specifying the width. 487 // This is done for the following instructions: mov, cmp, inc, dec, 488 // add, sub, and test. 489 // There are no versions of these instructions without the suffix. 490 // - Instructions on 8-bit (byte) operands/registers have a trailing 'b'. 491 // - Instructions on 16-bit (word) operands/registers have a trailing 'w'. 492 // - Instructions on 32-bit (doubleword) operands/registers use 'l'. 493 // - Instructions on 64-bit (quadword) operands/registers use 'q'. 494 // 495 // Some mnemonics, such as "and", are the same as C++ keywords. 496 // Naming conflicts with C++ keywords are resolved by adding a trailing '_'. 497 498 // Insert the smallest number of nop instructions 499 // possible to align the pc offset to a multiple 500 // of m. m must be a power of 2. 501 void Align(int m); 502 // Aligns code to something that's optimal for a jump target for the platform. 503 void CodeTargetAlign(); 504 505 // Stack 506 void pushfq(); 507 void popfq(); 508 509 void push(Immediate value); 510 void push(Register src); 511 void push(const Operand& src); 512 513 void pop(Register dst); 514 void pop(const Operand& dst); 515 516 void enter(Immediate size); 517 void leave(); 518 519 // Moves 520 void movb(Register dst, const Operand& src); 521 void movb(Register dst, Immediate imm); 522 void movb(const Operand& dst, Register src); 523 524 // Move the low 16 bits of a 64-bit register value to a 16-bit 525 // memory location. 526 void movw(const Operand& dst, Register src); 527 528 void movl(Register dst, Register src); 529 void movl(Register dst, const Operand& src); 530 void movl(const Operand& dst, Register src); 531 void movl(const Operand& dst, Immediate imm); 532 // Load a 32-bit immediate value, zero-extended to 64 bits. 533 void movl(Register dst, Immediate imm32); 534 535 // Move 64 bit register value to 64-bit memory location. 536 void movq(const Operand& dst, Register src); 537 // Move 64 bit memory location to 64-bit register value. 538 void movq(Register dst, const Operand& src); 539 void movq(Register dst, Register src); 540 // Sign extends immediate 32-bit value to 64 bits. 541 void movq(Register dst, Immediate x); 542 // Move the offset of the label location relative to the current 543 // position (after the move) to the destination. 544 void movl(const Operand& dst, Label* src); 545 546 // Move sign extended immediate to memory location. 547 void movq(const Operand& dst, Immediate value); 548 // New x64 instructions to load a 64-bit immediate into a register. 549 // All 64-bit immediates must have a relocation mode. 550 void movq(Register dst, void* ptr, RelocInfo::Mode rmode); 551 void movq(Register dst, int64_t value, RelocInfo::Mode rmode); 552 void movq(Register dst, const char* s, RelocInfo::Mode rmode); 553 // Moves the address of the external reference into the register. 554 void movq(Register dst, ExternalReference ext); 555 void movq(Register dst, Handle<Object> handle, RelocInfo::Mode rmode); 556 557 void movsxbq(Register dst, const Operand& src); 558 void movsxwq(Register dst, const Operand& src); 559 void movsxlq(Register dst, Register src); 560 void movsxlq(Register dst, const Operand& src); 561 void movzxbq(Register dst, const Operand& src); 562 void movzxbl(Register dst, const Operand& src); 563 void movzxwq(Register dst, const Operand& src); 564 void movzxwl(Register dst, const Operand& src); 565 566 // Repeated moves. 567 568 void repmovsb(); 569 void repmovsw(); 570 void repmovsl(); 571 void repmovsq(); 572 573 // New x64 instruction to load from an immediate 64-bit pointer into RAX. 574 void load_rax(void* ptr, RelocInfo::Mode rmode); 575 void load_rax(ExternalReference ext); 576 577 // Conditional moves. 578 void cmovq(Condition cc, Register dst, Register src); 579 void cmovq(Condition cc, Register dst, const Operand& src); 580 void cmovl(Condition cc, Register dst, Register src); 581 void cmovl(Condition cc, Register dst, const Operand& src); 582 583 // Exchange two registers 584 void xchg(Register dst, Register src); 585 586 // Arithmetics 587 void addl(Register dst, Register src) { 588 arithmetic_op_32(0x03, dst, src); 589 } 590 591 void addl(Register dst, Immediate src) { 592 immediate_arithmetic_op_32(0x0, dst, src); 593 } 594 595 void addl(Register dst, const Operand& src) { 596 arithmetic_op_32(0x03, dst, src); 597 } 598 599 void addl(const Operand& dst, Immediate src) { 600 immediate_arithmetic_op_32(0x0, dst, src); 601 } 602 603 void addq(Register dst, Register src) { 604 arithmetic_op(0x03, dst, src); 605 } 606 607 void addq(Register dst, const Operand& src) { 608 arithmetic_op(0x03, dst, src); 609 } 610 611 void addq(const Operand& dst, Register src) { 612 arithmetic_op(0x01, src, dst); 613 } 614 615 void addq(Register dst, Immediate src) { 616 immediate_arithmetic_op(0x0, dst, src); 617 } 618 619 void addq(const Operand& dst, Immediate src) { 620 immediate_arithmetic_op(0x0, dst, src); 621 } 622 623 void sbbl(Register dst, Register src) { 624 arithmetic_op_32(0x1b, dst, src); 625 } 626 627 void cmpb(Register dst, Immediate src) { 628 immediate_arithmetic_op_8(0x7, dst, src); 629 } 630 631 void cmpb_al(Immediate src); 632 633 void cmpb(Register dst, Register src) { 634 arithmetic_op(0x3A, dst, src); 635 } 636 637 void cmpb(Register dst, const Operand& src) { 638 arithmetic_op(0x3A, dst, src); 639 } 640 641 void cmpb(const Operand& dst, Register src) { 642 arithmetic_op(0x38, src, dst); 643 } 644 645 void cmpb(const Operand& dst, Immediate src) { 646 immediate_arithmetic_op_8(0x7, dst, src); 647 } 648 649 void cmpw(const Operand& dst, Immediate src) { 650 immediate_arithmetic_op_16(0x7, dst, src); 651 } 652 653 void cmpw(Register dst, Immediate src) { 654 immediate_arithmetic_op_16(0x7, dst, src); 655 } 656 657 void cmpw(Register dst, const Operand& src) { 658 arithmetic_op_16(0x3B, dst, src); 659 } 660 661 void cmpw(Register dst, Register src) { 662 arithmetic_op_16(0x3B, dst, src); 663 } 664 665 void cmpw(const Operand& dst, Register src) { 666 arithmetic_op_16(0x39, src, dst); 667 } 668 669 void cmpl(Register dst, Register src) { 670 arithmetic_op_32(0x3B, dst, src); 671 } 672 673 void cmpl(Register dst, const Operand& src) { 674 arithmetic_op_32(0x3B, dst, src); 675 } 676 677 void cmpl(const Operand& dst, Register src) { 678 arithmetic_op_32(0x39, src, dst); 679 } 680 681 void cmpl(Register dst, Immediate src) { 682 immediate_arithmetic_op_32(0x7, dst, src); 683 } 684 685 void cmpl(const Operand& dst, Immediate src) { 686 immediate_arithmetic_op_32(0x7, dst, src); 687 } 688 689 void cmpq(Register dst, Register src) { 690 arithmetic_op(0x3B, dst, src); 691 } 692 693 void cmpq(Register dst, const Operand& src) { 694 arithmetic_op(0x3B, dst, src); 695 } 696 697 void cmpq(const Operand& dst, Register src) { 698 arithmetic_op(0x39, src, dst); 699 } 700 701 void cmpq(Register dst, Immediate src) { 702 immediate_arithmetic_op(0x7, dst, src); 703 } 704 705 void cmpq(const Operand& dst, Immediate src) { 706 immediate_arithmetic_op(0x7, dst, src); 707 } 708 709 void and_(Register dst, Register src) { 710 arithmetic_op(0x23, dst, src); 711 } 712 713 void and_(Register dst, const Operand& src) { 714 arithmetic_op(0x23, dst, src); 715 } 716 717 void and_(const Operand& dst, Register src) { 718 arithmetic_op(0x21, src, dst); 719 } 720 721 void and_(Register dst, Immediate src) { 722 immediate_arithmetic_op(0x4, dst, src); 723 } 724 725 void and_(const Operand& dst, Immediate src) { 726 immediate_arithmetic_op(0x4, dst, src); 727 } 728 729 void andl(Register dst, Immediate src) { 730 immediate_arithmetic_op_32(0x4, dst, src); 731 } 732 733 void andl(Register dst, Register src) { 734 arithmetic_op_32(0x23, dst, src); 735 } 736 737 void andb(Register dst, Immediate src) { 738 immediate_arithmetic_op_8(0x4, dst, src); 739 } 740 741 void decq(Register dst); 742 void decq(const Operand& dst); 743 void decl(Register dst); 744 void decl(const Operand& dst); 745 void decb(Register dst); 746 void decb(const Operand& dst); 747 748 // Sign-extends rax into rdx:rax. 749 void cqo(); 750 // Sign-extends eax into edx:eax. 751 void cdq(); 752 753 // Divide rdx:rax by src. Quotient in rax, remainder in rdx. 754 void idivq(Register src); 755 // Divide edx:eax by lower 32 bits of src. Quotient in eax, rem. in edx. 756 void idivl(Register src); 757 758 // Signed multiply instructions. 759 void imul(Register src); // rdx:rax = rax * src. 760 void imul(Register dst, Register src); // dst = dst * src. 761 void imul(Register dst, const Operand& src); // dst = dst * src. 762 void imul(Register dst, Register src, Immediate imm); // dst = src * imm. 763 // Signed 32-bit multiply instructions. 764 void imull(Register dst, Register src); // dst = dst * src. 765 void imull(Register dst, Register src, Immediate imm); // dst = src * imm. 766 767 void incq(Register dst); 768 void incq(const Operand& dst); 769 void incl(Register dst); 770 void incl(const Operand& dst); 771 772 void lea(Register dst, const Operand& src); 773 void leal(Register dst, const Operand& src); 774 775 // Multiply rax by src, put the result in rdx:rax. 776 void mul(Register src); 777 778 void neg(Register dst); 779 void neg(const Operand& dst); 780 void negl(Register dst); 781 782 void not_(Register dst); 783 void not_(const Operand& dst); 784 void notl(Register dst); 785 786 void or_(Register dst, Register src) { 787 arithmetic_op(0x0B, dst, src); 788 } 789 790 void orl(Register dst, Register src) { 791 arithmetic_op_32(0x0B, dst, src); 792 } 793 794 void or_(Register dst, const Operand& src) { 795 arithmetic_op(0x0B, dst, src); 796 } 797 798 void or_(const Operand& dst, Register src) { 799 arithmetic_op(0x09, src, dst); 800 } 801 802 void or_(Register dst, Immediate src) { 803 immediate_arithmetic_op(0x1, dst, src); 804 } 805 806 void orl(Register dst, Immediate src) { 807 immediate_arithmetic_op_32(0x1, dst, src); 808 } 809 810 void or_(const Operand& dst, Immediate src) { 811 immediate_arithmetic_op(0x1, dst, src); 812 } 813 814 void orl(const Operand& dst, Immediate src) { 815 immediate_arithmetic_op_32(0x1, dst, src); 816 } 817 818 819 void rcl(Register dst, Immediate imm8) { 820 shift(dst, imm8, 0x2); 821 } 822 823 void rol(Register dst, Immediate imm8) { 824 shift(dst, imm8, 0x0); 825 } 826 827 void rcr(Register dst, Immediate imm8) { 828 shift(dst, imm8, 0x3); 829 } 830 831 void ror(Register dst, Immediate imm8) { 832 shift(dst, imm8, 0x1); 833 } 834 835 // Shifts dst:src left by cl bits, affecting only dst. 836 void shld(Register dst, Register src); 837 838 // Shifts src:dst right by cl bits, affecting only dst. 839 void shrd(Register dst, Register src); 840 841 // Shifts dst right, duplicating sign bit, by shift_amount bits. 842 // Shifting by 1 is handled efficiently. 843 void sar(Register dst, Immediate shift_amount) { 844 shift(dst, shift_amount, 0x7); 845 } 846 847 // Shifts dst right, duplicating sign bit, by shift_amount bits. 848 // Shifting by 1 is handled efficiently. 849 void sarl(Register dst, Immediate shift_amount) { 850 shift_32(dst, shift_amount, 0x7); 851 } 852 853 // Shifts dst right, duplicating sign bit, by cl % 64 bits. 854 void sar_cl(Register dst) { 855 shift(dst, 0x7); 856 } 857 858 // Shifts dst right, duplicating sign bit, by cl % 64 bits. 859 void sarl_cl(Register dst) { 860 shift_32(dst, 0x7); 861 } 862 863 void shl(Register dst, Immediate shift_amount) { 864 shift(dst, shift_amount, 0x4); 865 } 866 867 void shl_cl(Register dst) { 868 shift(dst, 0x4); 869 } 870 871 void shll_cl(Register dst) { 872 shift_32(dst, 0x4); 873 } 874 875 void shll(Register dst, Immediate shift_amount) { 876 shift_32(dst, shift_amount, 0x4); 877 } 878 879 void shr(Register dst, Immediate shift_amount) { 880 shift(dst, shift_amount, 0x5); 881 } 882 883 void shr_cl(Register dst) { 884 shift(dst, 0x5); 885 } 886 887 void shrl_cl(Register dst) { 888 shift_32(dst, 0x5); 889 } 890 891 void shrl(Register dst, Immediate shift_amount) { 892 shift_32(dst, shift_amount, 0x5); 893 } 894 895 void store_rax(void* dst, RelocInfo::Mode mode); 896 void store_rax(ExternalReference ref); 897 898 void subq(Register dst, Register src) { 899 arithmetic_op(0x2B, dst, src); 900 } 901 902 void subq(Register dst, const Operand& src) { 903 arithmetic_op(0x2B, dst, src); 904 } 905 906 void subq(const Operand& dst, Register src) { 907 arithmetic_op(0x29, src, dst); 908 } 909 910 void subq(Register dst, Immediate src) { 911 immediate_arithmetic_op(0x5, dst, src); 912 } 913 914 void subq(const Operand& dst, Immediate src) { 915 immediate_arithmetic_op(0x5, dst, src); 916 } 917 918 void subl(Register dst, Register src) { 919 arithmetic_op_32(0x2B, dst, src); 920 } 921 922 void subl(Register dst, const Operand& src) { 923 arithmetic_op_32(0x2B, dst, src); 924 } 925 926 void subl(const Operand& dst, Immediate src) { 927 immediate_arithmetic_op_32(0x5, dst, src); 928 } 929 930 void subl(Register dst, Immediate src) { 931 immediate_arithmetic_op_32(0x5, dst, src); 932 } 933 934 void subb(Register dst, Immediate src) { 935 immediate_arithmetic_op_8(0x5, dst, src); 936 } 937 938 void testb(Register dst, Register src); 939 void testb(Register reg, Immediate mask); 940 void testb(const Operand& op, Immediate mask); 941 void testb(const Operand& op, Register reg); 942 void testl(Register dst, Register src); 943 void testl(Register reg, Immediate mask); 944 void testl(const Operand& op, Immediate mask); 945 void testq(const Operand& op, Register reg); 946 void testq(Register dst, Register src); 947 void testq(Register dst, Immediate mask); 948 949 void xor_(Register dst, Register src) { 950 if (dst.code() == src.code()) { 951 arithmetic_op_32(0x33, dst, src); 952 } else { 953 arithmetic_op(0x33, dst, src); 954 } 955 } 956 957 void xorl(Register dst, Register src) { 958 arithmetic_op_32(0x33, dst, src); 959 } 960 961 void xor_(Register dst, const Operand& src) { 962 arithmetic_op(0x33, dst, src); 963 } 964 965 void xor_(const Operand& dst, Register src) { 966 arithmetic_op(0x31, src, dst); 967 } 968 969 void xor_(Register dst, Immediate src) { 970 immediate_arithmetic_op(0x6, dst, src); 971 } 972 973 void xor_(const Operand& dst, Immediate src) { 974 immediate_arithmetic_op(0x6, dst, src); 975 } 976 977 // Bit operations. 978 void bt(const Operand& dst, Register src); 979 void bts(const Operand& dst, Register src); 980 981 // Miscellaneous 982 void clc(); 983 void cpuid(); 984 void hlt(); 985 void int3(); 986 void nop(); 987 void nop(int n); 988 void rdtsc(); 989 void ret(int imm16); 990 void setcc(Condition cc, Register reg); 991 992 // Label operations & relative jumps (PPUM Appendix D) 993 // 994 // Takes a branch opcode (cc) and a label (L) and generates 995 // either a backward branch or a forward branch and links it 996 // to the label fixup chain. Usage: 997 // 998 // Label L; // unbound label 999 // j(cc, &L); // forward branch to unbound label 1000 // bind(&L); // bind label to the current pc 1001 // j(cc, &L); // backward branch to bound label 1002 // bind(&L); // illegal: a label may be bound only once 1003 // 1004 // Note: The same Label can be used for forward and backward branches 1005 // but it may be bound only once. 1006 1007 void bind(Label* L); // binds an unbound label L to the current code position 1008 void bind(NearLabel* L); 1009 1010 // Calls 1011 // Call near relative 32-bit displacement, relative to next instruction. 1012 void call(Label* L); 1013 void call(Handle<Code> target, RelocInfo::Mode rmode); 1014 1015 // Call near absolute indirect, address in register 1016 void call(Register adr); 1017 1018 // Call near indirect 1019 void call(const Operand& operand); 1020 1021 // Jumps 1022 // Jump short or near relative. 1023 // Use a 32-bit signed displacement. 1024 void jmp(Label* L); // unconditional jump to L 1025 void jmp(Handle<Code> target, RelocInfo::Mode rmode); 1026 1027 // Jump near absolute indirect (r64) 1028 void jmp(Register adr); 1029 1030 // Jump near absolute indirect (m64) 1031 void jmp(const Operand& src); 1032 1033 // Short jump 1034 void jmp(NearLabel* L); 1035 1036 // Conditional jumps 1037 void j(Condition cc, Label* L); 1038 void j(Condition cc, Handle<Code> target, RelocInfo::Mode rmode); 1039 1040 // Conditional short jump 1041 void j(Condition cc, NearLabel* L, Hint hint = no_hint); 1042 1043 // Floating-point operations 1044 void fld(int i); 1045 1046 void fld1(); 1047 void fldz(); 1048 void fldpi(); 1049 1050 void fld_s(const Operand& adr); 1051 void fld_d(const Operand& adr); 1052 1053 void fstp_s(const Operand& adr); 1054 void fstp_d(const Operand& adr); 1055 void fstp(int index); 1056 1057 void fild_s(const Operand& adr); 1058 void fild_d(const Operand& adr); 1059 1060 void fist_s(const Operand& adr); 1061 1062 void fistp_s(const Operand& adr); 1063 void fistp_d(const Operand& adr); 1064 1065 void fisttp_s(const Operand& adr); 1066 void fisttp_d(const Operand& adr); 1067 1068 void fabs(); 1069 void fchs(); 1070 1071 void fadd(int i); 1072 void fsub(int i); 1073 void fmul(int i); 1074 void fdiv(int i); 1075 1076 void fisub_s(const Operand& adr); 1077 1078 void faddp(int i = 1); 1079 void fsubp(int i = 1); 1080 void fsubrp(int i = 1); 1081 void fmulp(int i = 1); 1082 void fdivp(int i = 1); 1083 void fprem(); 1084 void fprem1(); 1085 1086 void fxch(int i = 1); 1087 void fincstp(); 1088 void ffree(int i = 0); 1089 1090 void ftst(); 1091 void fucomp(int i); 1092 void fucompp(); 1093 void fucomi(int i); 1094 void fucomip(); 1095 1096 void fcompp(); 1097 void fnstsw_ax(); 1098 void fwait(); 1099 void fnclex(); 1100 1101 void fsin(); 1102 void fcos(); 1103 1104 void frndint(); 1105 1106 void sahf(); 1107 1108 // SSE2 instructions 1109 void movd(XMMRegister dst, Register src); 1110 void movd(Register dst, XMMRegister src); 1111 void movq(XMMRegister dst, Register src); 1112 void movq(Register dst, XMMRegister src); 1113 void extractps(Register dst, XMMRegister src, byte imm8); 1114 1115 void movsd(const Operand& dst, XMMRegister src); 1116 void movsd(XMMRegister dst, XMMRegister src); 1117 void movsd(XMMRegister dst, const Operand& src); 1118 1119 void movss(XMMRegister dst, const Operand& src); 1120 void movss(const Operand& dst, XMMRegister src); 1121 1122 void cvttss2si(Register dst, const Operand& src); 1123 void cvttsd2si(Register dst, const Operand& src); 1124 void cvttsd2siq(Register dst, XMMRegister src); 1125 1126 void cvtlsi2sd(XMMRegister dst, const Operand& src); 1127 void cvtlsi2sd(XMMRegister dst, Register src); 1128 void cvtqsi2sd(XMMRegister dst, const Operand& src); 1129 void cvtqsi2sd(XMMRegister dst, Register src); 1130 1131 void cvtlsi2ss(XMMRegister dst, Register src); 1132 1133 void cvtss2sd(XMMRegister dst, XMMRegister src); 1134 void cvtss2sd(XMMRegister dst, const Operand& src); 1135 void cvtsd2ss(XMMRegister dst, XMMRegister src); 1136 1137 void cvtsd2si(Register dst, XMMRegister src); 1138 void cvtsd2siq(Register dst, XMMRegister src); 1139 1140 void addsd(XMMRegister dst, XMMRegister src); 1141 void subsd(XMMRegister dst, XMMRegister src); 1142 void mulsd(XMMRegister dst, XMMRegister src); 1143 void divsd(XMMRegister dst, XMMRegister src); 1144 1145 void xorpd(XMMRegister dst, XMMRegister src); 1146 void sqrtsd(XMMRegister dst, XMMRegister src); 1147 1148 void ucomisd(XMMRegister dst, XMMRegister src); 1149 void ucomisd(XMMRegister dst, const Operand& src); 1150 1151 // The first argument is the reg field, the second argument is the r/m field. 1152 void emit_sse_operand(XMMRegister dst, XMMRegister src); 1153 void emit_sse_operand(XMMRegister reg, const Operand& adr); 1154 void emit_sse_operand(XMMRegister dst, Register src); 1155 void emit_sse_operand(Register dst, XMMRegister src); 1156 1157 // Use either movsd or movlpd. 1158 // void movdbl(XMMRegister dst, const Operand& src); 1159 // void movdbl(const Operand& dst, XMMRegister src); 1160 1161 // Debugging 1162 void Print(); 1163 1164 // Check the code size generated from label to here. 1165 int SizeOfCodeGeneratedSince(Label* l) { return pc_offset() - l->pos(); } 1166 1167 // Mark address of the ExitJSFrame code. 1168 void RecordJSReturn(); 1169 1170 // Mark address of a debug break slot. 1171 void RecordDebugBreakSlot(); 1172 1173 // Record a comment relocation entry that can be used by a disassembler. 1174 // Use --debug_code to enable. 1175 void RecordComment(const char* msg); 1176 1177 void RecordPosition(int pos); 1178 void RecordStatementPosition(int pos); 1179 bool WriteRecordedPositions(); 1180 1181 int pc_offset() const { return static_cast<int>(pc_ - buffer_); } 1182 int current_statement_position() const { return current_statement_position_; } 1183 int current_position() const { return current_position_; } 1184 1185 // Check if there is less than kGap bytes available in the buffer. 1186 // If this is the case, we need to grow the buffer before emitting 1187 // an instruction or relocation information. 1188 inline bool buffer_overflow() const { 1189 return pc_ >= reloc_info_writer.pos() - kGap; 1190 } 1191 1192 // Get the number of bytes available in the buffer. 1193 inline int available_space() const { 1194 return static_cast<int>(reloc_info_writer.pos() - pc_); 1195 } 1196 1197 static bool IsNop(Address addr) { return *addr == 0x90; } 1198 1199 // Avoid overflows for displacements etc. 1200 static const int kMaximalBufferSize = 512*MB; 1201 static const int kMinimalBufferSize = 4*KB; 1202 1203 private: 1204 byte* addr_at(int pos) { return buffer_ + pos; } 1205 byte byte_at(int pos) { return buffer_[pos]; } 1206 void set_byte_at(int pos, byte value) { buffer_[pos] = value; } 1207 uint32_t long_at(int pos) { 1208 return *reinterpret_cast<uint32_t*>(addr_at(pos)); 1209 } 1210 void long_at_put(int pos, uint32_t x) { 1211 *reinterpret_cast<uint32_t*>(addr_at(pos)) = x; 1212 } 1213 1214 // code emission 1215 void GrowBuffer(); 1216 1217 void emit(byte x) { *pc_++ = x; } 1218 inline void emitl(uint32_t x); 1219 inline void emitq(uint64_t x, RelocInfo::Mode rmode); 1220 inline void emitw(uint16_t x); 1221 inline void emit_code_target(Handle<Code> target, RelocInfo::Mode rmode); 1222 void emit(Immediate x) { emitl(x.value_); } 1223 1224 // Emits a REX prefix that encodes a 64-bit operand size and 1225 // the top bit of both register codes. 1226 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. 1227 // REX.W is set. 1228 inline void emit_rex_64(XMMRegister reg, Register rm_reg); 1229 inline void emit_rex_64(Register reg, XMMRegister rm_reg); 1230 inline void emit_rex_64(Register reg, Register rm_reg); 1231 1232 // Emits a REX prefix that encodes a 64-bit operand size and 1233 // the top bit of the destination, index, and base register codes. 1234 // The high bit of reg is used for REX.R, the high bit of op's base 1235 // register is used for REX.B, and the high bit of op's index register 1236 // is used for REX.X. REX.W is set. 1237 inline void emit_rex_64(Register reg, const Operand& op); 1238 inline void emit_rex_64(XMMRegister reg, const Operand& op); 1239 1240 // Emits a REX prefix that encodes a 64-bit operand size and 1241 // the top bit of the register code. 1242 // The high bit of register is used for REX.B. 1243 // REX.W is set and REX.R and REX.X are clear. 1244 inline void emit_rex_64(Register rm_reg); 1245 1246 // Emits a REX prefix that encodes a 64-bit operand size and 1247 // the top bit of the index and base register codes. 1248 // The high bit of op's base register is used for REX.B, and the high 1249 // bit of op's index register is used for REX.X. 1250 // REX.W is set and REX.R clear. 1251 inline void emit_rex_64(const Operand& op); 1252 1253 // Emit a REX prefix that only sets REX.W to choose a 64-bit operand size. 1254 void emit_rex_64() { emit(0x48); } 1255 1256 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. 1257 // REX.W is clear. 1258 inline void emit_rex_32(Register reg, Register rm_reg); 1259 1260 // The high bit of reg is used for REX.R, the high bit of op's base 1261 // register is used for REX.B, and the high bit of op's index register 1262 // is used for REX.X. REX.W is cleared. 1263 inline void emit_rex_32(Register reg, const Operand& op); 1264 1265 // High bit of rm_reg goes to REX.B. 1266 // REX.W, REX.R and REX.X are clear. 1267 inline void emit_rex_32(Register rm_reg); 1268 1269 // High bit of base goes to REX.B and high bit of index to REX.X. 1270 // REX.W and REX.R are clear. 1271 inline void emit_rex_32(const Operand& op); 1272 1273 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. 1274 // REX.W is cleared. If no REX bits are set, no byte is emitted. 1275 inline void emit_optional_rex_32(Register reg, Register rm_reg); 1276 1277 // The high bit of reg is used for REX.R, the high bit of op's base 1278 // register is used for REX.B, and the high bit of op's index register 1279 // is used for REX.X. REX.W is cleared. If no REX bits are set, nothing 1280 // is emitted. 1281 inline void emit_optional_rex_32(Register reg, const Operand& op); 1282 1283 // As for emit_optional_rex_32(Register, Register), except that 1284 // the registers are XMM registers. 1285 inline void emit_optional_rex_32(XMMRegister reg, XMMRegister base); 1286 1287 // As for emit_optional_rex_32(Register, Register), except that 1288 // one of the registers is an XMM registers. 1289 inline void emit_optional_rex_32(XMMRegister reg, Register base); 1290 1291 // As for emit_optional_rex_32(Register, Register), except that 1292 // one of the registers is an XMM registers. 1293 inline void emit_optional_rex_32(Register reg, XMMRegister base); 1294 1295 // As for emit_optional_rex_32(Register, const Operand&), except that 1296 // the register is an XMM register. 1297 inline void emit_optional_rex_32(XMMRegister reg, const Operand& op); 1298 1299 // Optionally do as emit_rex_32(Register) if the register number has 1300 // the high bit set. 1301 inline void emit_optional_rex_32(Register rm_reg); 1302 1303 // Optionally do as emit_rex_32(const Operand&) if the operand register 1304 // numbers have a high bit set. 1305 inline void emit_optional_rex_32(const Operand& op); 1306 1307 1308 // Emit the ModR/M byte, and optionally the SIB byte and 1309 // 1- or 4-byte offset for a memory operand. Also encodes 1310 // the second operand of the operation, a register or operation 1311 // subcode, into the reg field of the ModR/M byte. 1312 void emit_operand(Register reg, const Operand& adr) { 1313 emit_operand(reg.low_bits(), adr); 1314 } 1315 1316 // Emit the ModR/M byte, and optionally the SIB byte and 1317 // 1- or 4-byte offset for a memory operand. Also used to encode 1318 // a three-bit opcode extension into the ModR/M byte. 1319 void emit_operand(int rm, const Operand& adr); 1320 1321 // Emit a ModR/M byte with registers coded in the reg and rm_reg fields. 1322 void emit_modrm(Register reg, Register rm_reg) { 1323 emit(0xC0 | reg.low_bits() << 3 | rm_reg.low_bits()); 1324 } 1325 1326 // Emit a ModR/M byte with an operation subcode in the reg field and 1327 // a register in the rm_reg field. 1328 void emit_modrm(int code, Register rm_reg) { 1329 ASSERT(is_uint3(code)); 1330 emit(0xC0 | code << 3 | rm_reg.low_bits()); 1331 } 1332 1333 // Emit the code-object-relative offset of the label's position 1334 inline void emit_code_relative_offset(Label* label); 1335 1336 // Emit machine code for one of the operations ADD, ADC, SUB, SBC, 1337 // AND, OR, XOR, or CMP. The encodings of these operations are all 1338 // similar, differing just in the opcode or in the reg field of the 1339 // ModR/M byte. 1340 void arithmetic_op_16(byte opcode, Register reg, Register rm_reg); 1341 void arithmetic_op_16(byte opcode, Register reg, const Operand& rm_reg); 1342 void arithmetic_op_32(byte opcode, Register reg, Register rm_reg); 1343 void arithmetic_op_32(byte opcode, Register reg, const Operand& rm_reg); 1344 void arithmetic_op(byte opcode, Register reg, Register rm_reg); 1345 void arithmetic_op(byte opcode, Register reg, const Operand& rm_reg); 1346 void immediate_arithmetic_op(byte subcode, Register dst, Immediate src); 1347 void immediate_arithmetic_op(byte subcode, const Operand& dst, Immediate src); 1348 // Operate on a byte in memory or register. 1349 void immediate_arithmetic_op_8(byte subcode, 1350 Register dst, 1351 Immediate src); 1352 void immediate_arithmetic_op_8(byte subcode, 1353 const Operand& dst, 1354 Immediate src); 1355 // Operate on a word in memory or register. 1356 void immediate_arithmetic_op_16(byte subcode, 1357 Register dst, 1358 Immediate src); 1359 void immediate_arithmetic_op_16(byte subcode, 1360 const Operand& dst, 1361 Immediate src); 1362 // Operate on a 32-bit word in memory or register. 1363 void immediate_arithmetic_op_32(byte subcode, 1364 Register dst, 1365 Immediate src); 1366 void immediate_arithmetic_op_32(byte subcode, 1367 const Operand& dst, 1368 Immediate src); 1369 1370 // Emit machine code for a shift operation. 1371 void shift(Register dst, Immediate shift_amount, int subcode); 1372 void shift_32(Register dst, Immediate shift_amount, int subcode); 1373 // Shift dst by cl % 64 bits. 1374 void shift(Register dst, int subcode); 1375 void shift_32(Register dst, int subcode); 1376 1377 void emit_farith(int b1, int b2, int i); 1378 1379 // labels 1380 // void print(Label* L); 1381 void bind_to(Label* L, int pos); 1382 1383 // record reloc info for current pc_ 1384 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); 1385 1386 friend class CodePatcher; 1387 friend class EnsureSpace; 1388 friend class RegExpMacroAssemblerX64; 1389 1390 // Code buffer: 1391 // The buffer into which code and relocation info are generated. 1392 byte* buffer_; 1393 int buffer_size_; 1394 // True if the assembler owns the buffer, false if buffer is external. 1395 bool own_buffer_; 1396 // A previously allocated buffer of kMinimalBufferSize bytes, or NULL. 1397 static byte* spare_buffer_; 1398 1399 // code generation 1400 byte* pc_; // the program counter; moves forward 1401 RelocInfoWriter reloc_info_writer; 1402 1403 List< Handle<Code> > code_targets_; 1404 // push-pop elimination 1405 byte* last_pc_; 1406 1407 // source position information 1408 int current_statement_position_; 1409 int current_position_; 1410 int written_statement_position_; 1411 int written_position_; 1412}; 1413 1414 1415// Helper class that ensures that there is enough space for generating 1416// instructions and relocation information. The constructor makes 1417// sure that there is enough space and (in debug mode) the destructor 1418// checks that we did not generate too much. 1419class EnsureSpace BASE_EMBEDDED { 1420 public: 1421 explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) { 1422 if (assembler_->buffer_overflow()) assembler_->GrowBuffer(); 1423#ifdef DEBUG 1424 space_before_ = assembler_->available_space(); 1425#endif 1426 } 1427 1428#ifdef DEBUG 1429 ~EnsureSpace() { 1430 int bytes_generated = space_before_ - assembler_->available_space(); 1431 ASSERT(bytes_generated < assembler_->kGap); 1432 } 1433#endif 1434 1435 private: 1436 Assembler* assembler_; 1437#ifdef DEBUG 1438 int space_before_; 1439#endif 1440}; 1441 1442} } // namespace v8::internal 1443 1444#endif // V8_X64_ASSEMBLER_X64_H_ 1445