assembler-x64.h 43.1 KB
Newer Older
1 2 3
// Copyright (c) 1994-2006 Sun Microsystems Inc.
// All Rights Reserved.
//
4 5 6 7
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
8 9 10 11 12 13
// - Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// - Redistribution in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
14
//
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
// - Neither the name of Sun Microsystems or the names of contributors may
// be used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// The original source code covered by the above license above has been
// modified significantly by Google Inc.
// Copyright 2006-2009 the V8 project authors. All rights reserved.

// A lightweight X64 Assembler.
36

37 38 39
#ifndef V8_X64_ASSEMBLER_X64_H_
#define V8_X64_ASSEMBLER_X64_H_

40 41
#include "serialize.h"

42 43
namespace v8 {
namespace internal {
44

45 46 47 48
// Utility functions

// Test whether a 64-bit value is in a specific range.
static inline bool is_uint32(int64_t x) {
lrn@chromium.org's avatar
lrn@chromium.org committed
49
  static const int64_t kUInt32Mask = V8_INT64_C(0xffffffff);
50
  return x == (x & kUInt32Mask);
51 52 53
}

static inline bool is_int32(int64_t x) {
lrn@chromium.org's avatar
lrn@chromium.org committed
54
  static const int64_t kMinIntValue = V8_INT64_C(-0x80000000);
55
  return is_uint32(x - kMinIntValue);
lrn@chromium.org's avatar
lrn@chromium.org committed
56 57 58 59 60 61 62 63 64 65
}

static inline bool uint_is_int32(uint64_t x) {
  static const uint64_t kMaxIntValue = V8_UINT64_C(0x80000000);
  return x < kMaxIntValue;
}

static inline bool is_uint32(uint64_t x) {
  static const uint64_t kMaxUIntValue = V8_UINT64_C(0x100000000);
  return x < kMaxUIntValue;
66 67
}

68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
// CPU Registers.
//
// 1) We would prefer to use an enum, but enum values are assignment-
// compatible with int, which has caused code-generation bugs.
//
// 2) We would prefer to use a class instead of a struct but we don't like
// the register initialization to depend on the particular initialization
// order (which appears to be different on OS X, Linux, and Windows for the
// installed versions of C++ we tried). Using a struct permits C-style
// "initialization". Also, the Register objects cannot be const as this
// forces initialization stubs in MSVC, making us dependent on initialization
// order.
//
// 3) By not using an enum, we are possibly preventing the compiler from
// doing certain constant folds, which may significantly reduce the
// code generated for some assembly instructions (because they boil down
// to a few constants). If this is a problem, we could change the code
// such that we use an enum in optimized mode, and the struct in debug
// mode. This way we get the compile-time error checking in debug mode
// and best performance in optimized code.
//

90
struct Register {
91
  static Register toRegister(int code) {
92
    Register r = { code };
93 94
    return r;
  }
95
  bool is_valid() const  { return 0 <= code_ && code_ < 16; }
96 97 98 99 100 101
  bool is(Register reg) const  { return code_ == reg.code_; }
  int code() const  {
    ASSERT(is_valid());
    return code_;
  }
  int bit() const  {
102
    return 1 << code_;
103 104
  }

105 106 107 108 109 110 111 112 113 114 115
  // Return the high bit of the register code as a 0 or 1.  Used often
  // when constructing the REX prefix byte.
  int high_bit() const {
    return code_ >> 3;
  }
  // Return the 3 low bits of the register code.  Used when encoding registers
  // in modR/M, SIB, and opcode bytes.
  int low_bits() const {
    return code_ & 0x7;
  }

116 117
  // Unfortunately we can't make this private in a struct when initializing
  // by assignment.
118 119 120
  int code_;
};

121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
const Register rax = { 0 };
const Register rcx = { 1 };
const Register rdx = { 2 };
const Register rbx = { 3 };
const Register rsp = { 4 };
const Register rbp = { 5 };
const Register rsi = { 6 };
const Register rdi = { 7 };
const Register r8 = { 8 };
const Register r9 = { 9 };
const Register r10 = { 10 };
const Register r11 = { 11 };
const Register r12 = { 12 };
const Register r13 = { 13 };
const Register r14 = { 14 };
const Register r15 = { 15 };
const Register no_reg = { -1 };
138 139


140
struct XMMRegister {
141
  bool is_valid() const  { return 0 <= code_ && code_ < 16; }
142 143 144 145 146
  int code() const  {
    ASSERT(is_valid());
    return code_;
  }

147 148 149 150 151 152 153 154 155 156 157
  // Return the high bit of the register code as a 0 or 1.  Used often
  // when constructing the REX prefix byte.
  int high_bit() const {
    return code_ >> 3;
  }
  // Return the 3 low bits of the register code.  Used when encoding registers
  // in modR/M, SIB, and opcode bytes.
  int low_bits() const {
    return code_ & 0x7;
  }

158 159 160
  int code_;
};

161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
const XMMRegister xmm0 = { 0 };
const XMMRegister xmm1 = { 1 };
const XMMRegister xmm2 = { 2 };
const XMMRegister xmm3 = { 3 };
const XMMRegister xmm4 = { 4 };
const XMMRegister xmm5 = { 5 };
const XMMRegister xmm6 = { 6 };
const XMMRegister xmm7 = { 7 };
const XMMRegister xmm8 = { 8 };
const XMMRegister xmm9 = { 9 };
const XMMRegister xmm10 = { 10 };
const XMMRegister xmm11 = { 11 };
const XMMRegister xmm12 = { 12 };
const XMMRegister xmm13 = { 13 };
const XMMRegister xmm14 = { 14 };
const XMMRegister xmm15 = { 15 };
177

178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
enum Condition {
  // any value < 0 is considered no_condition
  no_condition  = -1,

  overflow      =  0,
  no_overflow   =  1,
  below         =  2,
  above_equal   =  3,
  equal         =  4,
  not_equal     =  5,
  below_equal   =  6,
  above         =  7,
  negative      =  8,
  positive      =  9,
  parity_even   = 10,
  parity_odd    = 11,
  less          = 12,
  greater_equal = 13,
  less_equal    = 14,
  greater       = 15,

199 200 201 202
  // Fake conditions that are handled by the
  // opcodes using them.
  always        = 16,
  never         = 17,
203 204 205 206 207 208
  // aliases
  carry         = below,
  not_carry     = above_equal,
  zero          = equal,
  not_zero      = not_equal,
  sign          = negative,
209 210
  not_sign      = positive,
  last_condition = greater
211 212
};

213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243

// Returns the equivalent of !cc.
// Negation of the default no_condition (-1) results in a non-default
// no_condition value (-2). As long as tests for no_condition check
// for condition < 0, this will work as expected.
inline Condition NegateCondition(Condition cc);

// Corresponds to transposing the operands of a comparison.
inline Condition ReverseCondition(Condition cc) {
  switch (cc) {
    case below:
      return above;
    case above:
      return below;
    case above_equal:
      return below_equal;
    case below_equal:
      return above_equal;
    case less:
      return greater;
    case greater:
      return less;
    case greater_equal:
      return less_equal;
    case less_equal:
      return greater_equal;
    default:
      return cc;
  };
}

244 245 246 247 248 249
enum Hint {
  no_hint = 0,
  not_taken = 0x2e,
  taken = 0x3e
};

250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
// The result of negating a hint is as if the corresponding condition
// were negated by NegateCondition.  That is, no_hint is mapped to
// itself and not_taken and taken are mapped to each other.
inline Hint NegateHint(Hint hint) {
  return (hint == no_hint)
      ? no_hint
      : ((hint == not_taken) ? taken : not_taken);
}


// -----------------------------------------------------------------------------
// Machine instruction Immediates

class Immediate BASE_EMBEDDED {
 public:
265
  explicit Immediate(int32_t value) : value_(value) {}
266 267

 private:
268
  int32_t value_;
269 270 271 272 273 274 275 276 277

  friend class Assembler;
};


// -----------------------------------------------------------------------------
// Machine instruction Operands

enum ScaleFactor {
278 279 280 281 282 283
  times_1 = 0,
  times_2 = 1,
  times_4 = 2,
  times_8 = 3,
  times_int_size = times_4,
  times_pointer_size = times_8
284 285 286 287 288 289
};


class Operand BASE_EMBEDDED {
 public:
  // [base + disp/r]
290
  Operand(Register base, int32_t disp);
291 292

  // [base + index*scale + disp/r]
293 294 295 296
  Operand(Register base,
          Register index,
          ScaleFactor scale,
          int32_t disp);
297 298

  // [index*scale + disp/r]
299 300 301
  Operand(Register index,
          ScaleFactor scale,
          int32_t disp);
302 303 304 305 306 307 308 309

 private:
  byte rex_;
  byte buf_[10];
  // The number of bytes in buf_.
  unsigned int len_;
  RelocInfo::Mode rmode_;

310
  // Set the ModR/M byte without an encoded 'reg' register. The
311
  // register is encoded later as part of the emit_operand operation.
312
  // set_modrm can be called before or after set_sib and set_disp*.
313 314
  inline void set_modrm(int mod, Register rm);

315
  // Set the SIB byte if one is needed. Sets the length to 2 rather than 1.
316 317
  inline void set_sib(ScaleFactor scale, Register index, Register base);

318 319 320 321
  // Adds operand displacement fields (offsets added to the memory address).
  // Needs to be called after set_sib, not before it.
  inline void set_disp8(int disp);
  inline void set_disp32(int disp);
322

323
  friend class Assembler;
324 325 326 327 328 329
};


// CpuFeatures keeps track of which features are supported by the target CPU.
// Supported features must be enabled by a Scope before use.
// Example:
330 331 332
//   if (CpuFeatures::IsSupported(SSE3)) {
//     CpuFeatures::Scope fscope(SSE3);
//     // Generate SSE3 floating point code.
333
//   } else {
334
//     // Generate standard x87 or SSE2 floating point code.
335 336 337 338 339 340 341
//   }
class CpuFeatures : public AllStatic {
 public:
  // Detect features of the target CPU. Set safe defaults if the serializer
  // is enabled (snapshots must be portable).
  static void Probe();
  // Check whether a feature is supported by the target CPU.
342
  static bool IsSupported(CpuFeature f) {
343 344 345 346 347
    if (f == SSE2 && !FLAG_enable_sse2) return false;
    if (f == SSE3 && !FLAG_enable_sse3) return false;
    if (f == CMOV && !FLAG_enable_cmov) return false;
    if (f == RDTSC && !FLAG_enable_rdtsc) return false;
    if (f == SAHF && !FLAG_enable_sahf) return false;
348
    return (supported_ & (V8_UINT64_C(1) << f)) != 0;
349 350
  }
  // Check whether a feature is currently enabled.
351
  static bool IsEnabled(CpuFeature f) {
352
    return (enabled_ & (V8_UINT64_C(1) << f)) != 0;
353 354 355 356 357
  }
  // Enable a specified feature within a scope.
  class Scope BASE_EMBEDDED {
#ifdef DEBUG
   public:
358 359
    explicit Scope(CpuFeature f) {
      uint64_t mask = (V8_UINT64_C(1) << f);
360
      ASSERT(CpuFeatures::IsSupported(f));
361
      ASSERT(!Serializer::enabled() || (found_by_runtime_probing_ & mask) == 0);
362
      old_enabled_ = CpuFeatures::enabled_;
363
      CpuFeatures::enabled_ |= mask;
364 365 366 367 368 369
    }
    ~Scope() { CpuFeatures::enabled_ = old_enabled_; }
   private:
    uint64_t old_enabled_;
#else
   public:
370
    explicit Scope(CpuFeature f) {}
371 372 373
#endif
  };
 private:
374 375
  // Safe defaults include SSE2 and CMOV for X64. It is always available, if
  // anyone checks, but they shouldn't need to check.
376
  static const uint64_t kDefaultCpuFeatures = (1 << SSE2 | 1 << CMOV);
377 378
  static uint64_t supported_;
  static uint64_t enabled_;
379
  static uint64_t found_by_runtime_probing_;
380 381 382 383 384
};


class Assembler : public Malloced {
 private:
385 386 387
  // We check before assembling an instruction that there is sufficient
  // space to write an instruction and its relocation information.
  // The relocation writer's position must be kGap bytes above the end of
388
  // the generated instructions. This leaves enough space for the
389 390 391 392 393
  // longest possible x64 instruction, 15 bytes, and the longest possible
  // relocation information encoding, RelocInfoWriter::kMaxLength == 16.
  // (There is a 15 byte limit on x64 instruction length that rules out some
  // otherwise valid instructions.)
  // This allows for a single, fast space check per instruction.
394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417
  static const int kGap = 32;

 public:
  // Create an assembler. Instructions and relocation information are emitted
  // into a buffer, with the instructions starting from the beginning and the
  // relocation information starting from the end of the buffer. See CodeDesc
  // for a detailed comment on the layout (globals.h).
  //
  // If the provided buffer is NULL, the assembler allocates and grows its own
  // buffer, and buffer_size determines the initial buffer size. The buffer is
  // owned by the assembler and deallocated upon destruction of the assembler.
  //
  // If the provided buffer is not NULL, the assembler uses the provided buffer
  // for code generation and assumes its size to be buffer_size. If the buffer
  // is too small, a fatal error occurs. No deallocation of the buffer is done
  // upon destruction of the assembler.
  Assembler(void* buffer, int buffer_size);
  ~Assembler();

  // GetCode emits any pending (non-emitted) code and fills the descriptor
  // desc. GetCode() is idempotent; it returns the same result if no other
  // Assembler functions are invoked in between GetCode() calls.
  void GetCode(CodeDesc* desc);

418 419 420 421 422 423 424
  // Read/Modify the code target in the relative branch/call instruction at pc.
  // On the x64 architecture, we use relative jumps with a 32-bit displacement
  // to jump to other Code objects in the Code space in the heap.
  // Jumps to C functions are done indirectly through a 64-bit register holding
  // the absolute address of the target.
  // These functions convert between absolute Addresses of Code objects and
  // the relative displacements stored in the code.
425 426
  static inline Address target_address_at(Address pc);
  static inline void set_target_address_at(Address pc, Address target);
427

428
  // This sets the branch destination (which is in the instruction on x64).
429
  // This is for calls and branches within generated code.
430 431 432 433
  inline static void set_target_at(Address instruction_payload,
                                   Address target) {
    set_target_address_at(instruction_payload, target);
  }
434 435 436 437 438 439 440 441

  // This sets the branch destination (which is a load instruction on x64).
  // This is for calls and branches to runtime code.
  inline static void set_external_target_at(Address instruction_payload,
                                            Address target) {
    *reinterpret_cast<Address*>(instruction_payload) = target;
  }

442
  inline Handle<Object> code_target_object_handle_at(Address pc);
443
  // Number of bytes taken up by the branch target in the code.
444 445
  static const int kCallTargetSize = 4;      // Use 32-bit displacement.
  static const int kExternalTargetSize = 8;  // Use 64-bit absolute.
446
  // Distance between the address of the code target in the call instruction
447 448 449 450 451 452 453 454 455
  // and the return address pushed on the stack.
  static const int kCallTargetAddressOffset = 4;  // Use 32-bit displacement.
  // Distance between the start of the JS return sequence and where the
  // 32-bit displacement of a near call would be, relative to the pushed
  // return address.  TODO: Use return sequence length instead.
  // Should equal Debug::kX64JSReturnSequenceLength - kCallTargetAddressOffset;
  static const int kPatchReturnSequenceAddressOffset = 13 - 4;
  // TODO(X64): Rename this, removing the "Real", after changing the above.
  static const int kRealPatchReturnSequenceAddressOffset = 2;
456 457 458 459 460 461

  // The x64 JS return sequence is padded with int3 to make it large
  // enough to hold a call instruction when the debugger patches it.
  static const int kCallInstructionLength = 13;
  static const int kJSReturnSequenceLength = 13;

462 463 464
  // ---------------------------------------------------------------------------
  // Code generation
  //
465 466 467 468 469
  // Function names correspond one-to-one to x64 instruction mnemonics.
  // Unless specified otherwise, instructions operate on 64-bit operands.
  //
  // If we need versions of an assembly instruction that operate on different
  // width arguments, we add a single-letter suffix specifying the width.
470 471
  // This is done for the following instructions: mov, cmp, inc, dec,
  // add, sub, and test.
472 473 474 475 476 477 478 479
  // There are no versions of these instructions without the suffix.
  // - Instructions on 8-bit (byte) operands/registers have a trailing 'b'.
  // - Instructions on 16-bit (word) operands/registers have a trailing 'w'.
  // - Instructions on 32-bit (doubleword) operands/registers use 'l'.
  // - Instructions on 64-bit (quadword) operands/registers use 'q'.
  //
  // Some mnemonics, such as "and", are the same as C++ keywords.
  // Naming conflicts with C++ keywords are resolved by adding a trailing '_'.
480 481 482 483 484 485 486

  // Insert the smallest number of nop instructions
  // possible to align the pc offset to a multiple
  // of m. m must be a power of 2.
  void Align(int m);

  // Stack
487 488
  void pushfq();
  void popfq();
489

490
  void push(Immediate value);
491 492 493 494 495 496 497
  void push(Register src);
  void push(const Operand& src);
  void push(Label* label, RelocInfo::Mode relocation_mode);

  void pop(Register dst);
  void pop(const Operand& dst);

498
  void enter(Immediate size);
499 500 501
  void leave();

  // Moves
502
  void movb(Register dst, const Operand& src);
503
  void movb(Register dst, Immediate imm);
504 505
  void movb(const Operand& dst, Register src);

506 507 508 509
  // Move the low 16 bits of a 64-bit register value to a 16-bit
  // memory location.
  void movw(const Operand& dst, Register src);

510 511 512
  void movl(Register dst, Register src);
  void movl(Register dst, const Operand& src);
  void movl(const Operand& dst, Register src);
513
  void movl(const Operand& dst, Immediate imm);
514 515
  // Load a 32-bit immediate value, zero-extended to 64 bits.
  void movl(Register dst, Immediate imm32);
516

517 518 519
  // Move 64 bit register value to 64-bit memory location.
  void movq(const Operand& dst, Register src);
  // Move 64 bit memory location to 64-bit register value.
520
  void movq(Register dst, const Operand& src);
521
  void movq(Register dst, Register src);
522 523
  // Sign extends immediate 32-bit value to 64 bits.
  void movq(Register dst, Immediate x);
524 525 526
  // Move the offset of the label location relative to the current
  // position (after the move) to the destination.
  void movl(const Operand& dst, Label* src);
527

528 529
  // Move sign extended immediate to memory location.
  void movq(const Operand& dst, Immediate value);
530 531 532 533 534
  // New x64 instructions to load a 64-bit immediate into a register.
  // All 64-bit immediates must have a relocation mode.
  void movq(Register dst, void* ptr, RelocInfo::Mode rmode);
  void movq(Register dst, int64_t value, RelocInfo::Mode rmode);
  void movq(Register dst, const char* s, RelocInfo::Mode rmode);
lrn@chromium.org's avatar
lrn@chromium.org committed
535 536
  // Moves the address of the external reference into the register.
  void movq(Register dst, ExternalReference ext);
537 538
  void movq(Register dst, Handle<Object> handle, RelocInfo::Mode rmode);

539 540
  void movsxbq(Register dst, const Operand& src);
  void movsxwq(Register dst, const Operand& src);
541
  void movsxlq(Register dst, Register src);
542
  void movsxlq(Register dst, const Operand& src);
543
  void movzxbq(Register dst, const Operand& src);
544
  void movzxbl(Register dst, const Operand& src);
545
  void movzxwq(Register dst, const Operand& src);
546
  void movzxwl(Register dst, const Operand& src);
547

548 549 550 551 552 553 554
  // Repeated moves.

  void repmovsb();
  void repmovsw();
  void repmovsl();
  void repmovsq();

555 556
  // New x64 instruction to load from an immediate 64-bit pointer into RAX.
  void load_rax(void* ptr, RelocInfo::Mode rmode);
lrn@chromium.org's avatar
lrn@chromium.org committed
557
  void load_rax(ExternalReference ext);
558

559 560 561 562 563
  // Conditional moves.
  void cmovq(Condition cc, Register dst, Register src);
  void cmovq(Condition cc, Register dst, const Operand& src);
  void cmovl(Condition cc, Register dst, Register src);
  void cmovl(Condition cc, Register dst, const Operand& src);
564 565 566 567 568

  // Exchange two registers
  void xchg(Register dst, Register src);

  // Arithmetics
569
  void addl(Register dst, Register src) {
570 571 572 573 574
    if (dst.low_bits() == 4) {  // Forces SIB byte.
      arithmetic_op_32(0x01, src, dst);
    } else {
      arithmetic_op_32(0x03, dst, src);
    }
575 576
  }

577 578 579 580
  void addl(Register dst, Immediate src) {
    immediate_arithmetic_op_32(0x0, dst, src);
  }

581 582 583 584
  void addl(Register dst, const Operand& src) {
    arithmetic_op_32(0x03, dst, src);
  }

585 586 587 588
  void addl(const Operand& dst, Immediate src) {
    immediate_arithmetic_op_32(0x0, dst, src);
  }

589
  void addq(Register dst, Register src) {
590 591 592
    arithmetic_op(0x03, dst, src);
  }

593 594 595
  void addq(Register dst, const Operand& src) {
    arithmetic_op(0x03, dst, src);
  }
596

597
  void addq(const Operand& dst, Register src) {
598 599 600
    arithmetic_op(0x01, src, dst);
  }

601
  void addq(Register dst, Immediate src) {
602 603 604
    immediate_arithmetic_op(0x0, dst, src);
  }

605
  void addq(const Operand& dst, Immediate src) {
606 607 608
    immediate_arithmetic_op(0x0, dst, src);
  }

609 610 611 612
  void cmpb(Register dst, Immediate src) {
    immediate_arithmetic_op_8(0x7, dst, src);
  }

613 614 615 616 617 618 619 620 621 622 623 624 625 626
  void cmpb_al(Immediate src);

  void cmpb(Register dst, Register src) {
    arithmetic_op(0x3A, dst, src);
  }

  void cmpb(Register dst, const Operand& src) {
    arithmetic_op(0x3A, dst, src);
  }

  void cmpb(const Operand& dst, Register src) {
    arithmetic_op(0x38, src, dst);
  }

627 628 629 630
  void cmpb(const Operand& dst, Immediate src) {
    immediate_arithmetic_op_8(0x7, dst, src);
  }

631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650
  void cmpw(const Operand& dst, Immediate src) {
    immediate_arithmetic_op_16(0x7, dst, src);
  }

  void cmpw(Register dst, Immediate src) {
    immediate_arithmetic_op_16(0x7, dst, src);
  }

  void cmpw(Register dst, const Operand& src) {
    arithmetic_op_16(0x3B, dst, src);
  }

  void cmpw(Register dst, Register src) {
    arithmetic_op_16(0x3B, dst, src);
  }

  void cmpw(const Operand& dst, Register src) {
    arithmetic_op_16(0x39, src, dst);
  }

651 652 653 654
  void cmpl(Register dst, Register src) {
    arithmetic_op_32(0x3B, dst, src);
  }

655
  void cmpl(Register dst, const Operand& src) {
656
    arithmetic_op_32(0x3B, dst, src);
657 658 659
  }

  void cmpl(const Operand& dst, Register src) {
660
    arithmetic_op_32(0x39, src, dst);
661 662
  }

663 664 665 666
  void cmpl(Register dst, Immediate src) {
    immediate_arithmetic_op_32(0x7, dst, src);
  }

667 668 669 670
  void cmpl(const Operand& dst, Immediate src) {
    immediate_arithmetic_op_32(0x7, dst, src);
  }

671
  void cmpq(Register dst, Register src) {
672 673 674
    arithmetic_op(0x3B, dst, src);
  }

675
  void cmpq(Register dst, const Operand& src) {
676 677 678
    arithmetic_op(0x3B, dst, src);
  }

679
  void cmpq(const Operand& dst, Register src) {
680 681 682
    arithmetic_op(0x39, src, dst);
  }

683
  void cmpq(Register dst, Immediate src) {
684 685 686
    immediate_arithmetic_op(0x7, dst, src);
  }

687
  void cmpq(const Operand& dst, Immediate src) {
688 689
    immediate_arithmetic_op(0x7, dst, src);
  }
690

691 692 693 694 695 696 697 698 699 700 701 702 703 704 705
  void and_(Register dst, Register src) {
    arithmetic_op(0x23, dst, src);
  }

  void and_(Register dst, const Operand& src) {
    arithmetic_op(0x23, dst, src);
  }

  void and_(const Operand& dst, Register src) {
    arithmetic_op(0x21, src, dst);
  }

  void and_(Register dst, Immediate src) {
    immediate_arithmetic_op(0x4, dst, src);
  }
706

707 708 709
  void and_(const Operand& dst, Immediate src) {
    immediate_arithmetic_op(0x4, dst, src);
  }
710

711 712 713 714
  void andl(Register dst, Immediate src) {
    immediate_arithmetic_op_32(0x4, dst, src);
  }

715 716 717 718
  void andl(Register dst, Register src) {
    arithmetic_op_32(0x23, dst, src);
  }

719 720 721
  void andb(Register dst, Immediate src) {
    immediate_arithmetic_op_8(0x4, dst, src);
  }
722

723 724
  void decq(Register dst);
  void decq(const Operand& dst);
725
  void decl(Register dst);
726
  void decl(const Operand& dst);
727 728
  void decb(Register dst);
  void decb(const Operand& dst);
729

730 731
  // Sign-extends rax into rdx:rax.
  void cqo();
732 733
  // Sign-extends eax into edx:eax.
  void cdq();
734

735
  // Divide rdx:rax by src.  Quotient in rax, remainder in rdx.
736 737 738
  void idivq(Register src);
  // Divide edx:eax by lower 32 bits of src.  Quotient in eax, rem. in edx.
  void idivl(Register src);
739

740 741 742 743 744
  // Signed multiply instructions.
  void imul(Register src);                               // rdx:rax = rax * src.
  void imul(Register dst, Register src);                 // dst = dst * src.
  void imul(Register dst, const Operand& src);           // dst = dst * src.
  void imul(Register dst, Register src, Immediate imm);  // dst = src * imm.
745
  // Signed 32-bit multiply instructions.
746 747
  void imull(Register dst, Register src);                 // dst = dst * src.
  void imull(Register dst, Register src, Immediate imm);  // dst = src * imm.
748

749 750 751
  void incq(Register dst);
  void incq(const Operand& dst);
  void incl(const Operand& dst);
752 753

  void lea(Register dst, const Operand& src);
754
  void leal(Register dst, const Operand& src);
755

756
  // Multiply rax by src, put the result in rdx:rax.
757 758 759
  void mul(Register src);

  void neg(Register dst);
760
  void neg(const Operand& dst);
761
  void negl(Register dst);
762 763

  void not_(Register dst);
764
  void not_(const Operand& dst);
765
  void notl(Register dst);
766

767 768 769 770
  void or_(Register dst, Register src) {
    arithmetic_op(0x0B, dst, src);
  }

771 772 773 774
  void orl(Register dst, Register src) {
    arithmetic_op_32(0x0B, dst, src);
  }

775 776 777 778 779 780 781 782 783 784 785 786
  void or_(Register dst, const Operand& src) {
    arithmetic_op(0x0B, dst, src);
  }

  void or_(const Operand& dst, Register src) {
    arithmetic_op(0x09, src, dst);
  }

  void or_(Register dst, Immediate src) {
    immediate_arithmetic_op(0x1, dst, src);
  }

787 788 789 790
  void orl(Register dst, Immediate src) {
    immediate_arithmetic_op_32(0x1, dst, src);
  }

791 792 793 794
  void or_(const Operand& dst, Immediate src) {
    immediate_arithmetic_op(0x1, dst, src);
  }

795 796 797 798
  void orl(const Operand& dst, Immediate src) {
    immediate_arithmetic_op_32(0x1, dst, src);
  }

799

800 801 802 803 804 805 806 807 808 809 810 811 812 813 814
  void rcl(Register dst, Immediate imm8) {
    shift(dst, imm8, 0x2);
  }

  void rol(Register dst, Immediate imm8) {
    shift(dst, imm8, 0x0);
  }

  void rcr(Register dst, Immediate imm8) {
    shift(dst, imm8, 0x3);
  }

  void ror(Register dst, Immediate imm8) {
    shift(dst, imm8, 0x1);
  }
815

816 817
  // Shifts dst:src left by cl bits, affecting only dst.
  void shld(Register dst, Register src);
818

819 820
  // Shifts src:dst right by cl bits, affecting only dst.
  void shrd(Register dst, Register src);
821

822 823 824 825 826 827
  // Shifts dst right, duplicating sign bit, by shift_amount bits.
  // Shifting by 1 is handled efficiently.
  void sar(Register dst, Immediate shift_amount) {
    shift(dst, shift_amount, 0x7);
  }

828 829 830 831 832 833
  // Shifts dst right, duplicating sign bit, by shift_amount bits.
  // Shifting by 1 is handled efficiently.
  void sarl(Register dst, Immediate shift_amount) {
    shift_32(dst, shift_amount, 0x7);
  }

834
  // Shifts dst right, duplicating sign bit, by cl % 64 bits.
835
  void sar_cl(Register dst) {
836 837 838
    shift(dst, 0x7);
  }

839
  // Shifts dst right, duplicating sign bit, by cl % 64 bits.
840
  void sarl_cl(Register dst) {
841 842 843
    shift_32(dst, 0x7);
  }

844 845 846 847
  void shl(Register dst, Immediate shift_amount) {
    shift(dst, shift_amount, 0x4);
  }

848
  void shl_cl(Register dst) {
849 850 851
    shift(dst, 0x4);
  }

852
  void shll_cl(Register dst) {
853 854 855
    shift_32(dst, 0x4);
  }

856 857 858 859
  void shll(Register dst, Immediate shift_amount) {
    shift_32(dst, shift_amount, 0x4);
  }

860 861 862 863
  void shr(Register dst, Immediate shift_amount) {
    shift(dst, shift_amount, 0x5);
  }

864
  void shr_cl(Register dst) {
865 866
    shift(dst, 0x5);
  }
867

868
  void shrl_cl(Register dst) {
869 870 871
    shift_32(dst, 0x5);
  }

872 873 874 875
  void shrl(Register dst, Immediate shift_amount) {
    shift_32(dst, shift_amount, 0x5);
  }

lrn@chromium.org's avatar
lrn@chromium.org committed
876 877 878
  void store_rax(void* dst, RelocInfo::Mode mode);
  void store_rax(ExternalReference ref);

879
  void subq(Register dst, Register src) {
880 881 882
    arithmetic_op(0x2B, dst, src);
  }

883
  void subq(Register dst, const Operand& src) {
884 885 886
    arithmetic_op(0x2B, dst, src);
  }

887
  void subq(const Operand& dst, Register src) {
888 889 890
    arithmetic_op(0x29, src, dst);
  }

891
  void subq(Register dst, Immediate src) {
892 893 894
    immediate_arithmetic_op(0x5, dst, src);
  }

895
  void subq(const Operand& dst, Immediate src) {
896 897 898
    immediate_arithmetic_op(0x5, dst, src);
  }

899 900 901 902
  void subl(Register dst, Register src) {
    arithmetic_op_32(0x2B, dst, src);
  }

903 904 905 906
  void subl(Register dst, const Operand& src) {
    arithmetic_op_32(0x2B, dst, src);
  }

907 908 909 910
  void subl(const Operand& dst, Immediate src) {
    immediate_arithmetic_op_32(0x5, dst, src);
  }

911 912 913 914
  void subl(Register dst, Immediate src) {
    immediate_arithmetic_op_32(0x5, dst, src);
  }

915 916 917 918
  void subb(Register dst, Immediate src) {
    immediate_arithmetic_op_8(0x5, dst, src);
  }

919
  void testb(Register dst, Register src);
920 921
  void testb(Register reg, Immediate mask);
  void testb(const Operand& op, Immediate mask);
922
  void testb(const Operand& op, Register reg);
923
  void testl(Register dst, Register src);
924 925
  void testl(Register reg, Immediate mask);
  void testl(const Operand& op, Immediate mask);
926 927
  void testq(const Operand& op, Register reg);
  void testq(Register dst, Register src);
928
  void testq(Register dst, Immediate mask);
929

930
  void xor_(Register dst, Register src) {
931 932 933 934 935
    if (dst.code() == src.code()) {
      arithmetic_op_32(0x33, dst, src);
    } else {
      arithmetic_op(0x33, dst, src);
    }
936 937
  }

938 939 940 941
  void xorl(Register dst, Register src) {
    arithmetic_op_32(0x33, dst, src);
  }

942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957
  void xor_(Register dst, const Operand& src) {
    arithmetic_op(0x33, dst, src);
  }

  void xor_(const Operand& dst, Register src) {
    arithmetic_op(0x31, src, dst);
  }

  void xor_(Register dst, Immediate src) {
    immediate_arithmetic_op(0x6, dst, src);
  }

  void xor_(const Operand& dst, Immediate src) {
    immediate_arithmetic_op(0x6, dst, src);
  }

958 959 960 961 962
  // Bit operations.
  void bt(const Operand& dst, Register src);
  void bts(const Operand& dst, Register src);

  // Miscellaneous
963
  void clc();
964
  void cpuid();
965 966 967
  void hlt();
  void int3();
  void nop();
968
  void nop(int n);
969 970
  void rdtsc();
  void ret(int imm16);
971
  void setcc(Condition cc, Register reg);
972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990

  // Label operations & relative jumps (PPUM Appendix D)
  //
  // Takes a branch opcode (cc) and a label (L) and generates
  // either a backward branch or a forward branch and links it
  // to the label fixup chain. Usage:
  //
  // Label L;    // unbound label
  // j(cc, &L);  // forward branch to unbound label
  // bind(&L);   // bind label to the current pc
  // j(cc, &L);  // backward branch to bound label
  // bind(&L);   // illegal: a label may be bound only once
  //
  // Note: The same Label can be used for forward and backward branches
  // but it may be bound only once.

  void bind(Label* L);  // binds an unbound label L to the current code position

  // Calls
991
  // Call near relative 32-bit displacement, relative to next instruction.
992
  void call(Label* L);
993
  void call(Handle<Code> target, RelocInfo::Mode rmode);
994 995 996

  // Call near absolute indirect, address in register
  void call(Register adr);
997

lrn@chromium.org's avatar
lrn@chromium.org committed
998 999 1000
  // Call near indirect
  void call(const Operand& operand);

1001
  // Jumps
1002
  // Jump short or near relative.
1003
  // Use a 32-bit signed displacement.
1004
  void jmp(Label* L);  // unconditional jump to L
1005
  void jmp(Handle<Code> target, RelocInfo::Mode rmode);
1006 1007 1008

  // Jump near absolute indirect (r64)
  void jmp(Register adr);
1009

1010 1011 1012
  // Jump near absolute indirect (m64)
  void jmp(const Operand& src);

1013
  // Conditional jumps
1014
  void j(Condition cc, Label* L);
1015
  void j(Condition cc, Handle<Code> target, RelocInfo::Mode rmode);
1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027

  // Floating-point operations
  void fld(int i);

  void fld1();
  void fldz();

  void fld_s(const Operand& adr);
  void fld_d(const Operand& adr);

  void fstp_s(const Operand& adr);
  void fstp_d(const Operand& adr);
1028
  void fstp(int index);
1029 1030 1031 1032 1033 1034 1035 1036 1037 1038

  void fild_s(const Operand& adr);
  void fild_d(const Operand& adr);

  void fist_s(const Operand& adr);

  void fistp_s(const Operand& adr);
  void fistp_d(const Operand& adr);

  void fisttp_s(const Operand& adr);
1039
  void fisttp_d(const Operand& adr);
1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065

  void fabs();
  void fchs();

  void fadd(int i);
  void fsub(int i);
  void fmul(int i);
  void fdiv(int i);

  void fisub_s(const Operand& adr);

  void faddp(int i = 1);
  void fsubp(int i = 1);
  void fsubrp(int i = 1);
  void fmulp(int i = 1);
  void fdivp(int i = 1);
  void fprem();
  void fprem1();

  void fxch(int i = 1);
  void fincstp();
  void ffree(int i = 0);

  void ftst();
  void fucomp(int i);
  void fucompp();
1066
  void fucomi(int i);
1067 1068
  void fucomip();

1069 1070 1071 1072 1073
  void fcompp();
  void fnstsw_ax();
  void fwait();
  void fnclex();

1074 1075 1076
  void fsin();
  void fcos();

1077 1078
  void frndint();

1079 1080 1081
  void sahf();

  // SSE2 instructions
1082 1083
  void movd(XMMRegister dst, Register src);

1084
  void movsd(const Operand& dst, XMMRegister src);
1085 1086
  void movsd(XMMRegister dst, XMMRegister src);
  void movsd(XMMRegister dst, const Operand& src);
1087

1088 1089 1090
  void cvttss2si(Register dst, const Operand& src);
  void cvttsd2si(Register dst, const Operand& src);

1091 1092 1093 1094
  void cvtlsi2sd(XMMRegister dst, const Operand& src);
  void cvtlsi2sd(XMMRegister dst, Register src);
  void cvtqsi2sd(XMMRegister dst, const Operand& src);
  void cvtqsi2sd(XMMRegister dst, Register src);
1095

1096 1097
  void cvtss2sd(XMMRegister dst, XMMRegister src);

1098 1099 1100 1101 1102
  void addsd(XMMRegister dst, XMMRegister src);
  void subsd(XMMRegister dst, XMMRegister src);
  void mulsd(XMMRegister dst, XMMRegister src);
  void divsd(XMMRegister dst, XMMRegister src);

1103 1104 1105 1106
  void xorpd(XMMRegister dst, XMMRegister src);

  void comisd(XMMRegister dst, XMMRegister src);
  void ucomisd(XMMRegister dst, XMMRegister src);
1107

1108
  // The first argument is the reg field, the second argument is the r/m field.
1109 1110 1111 1112
  void emit_sse_operand(XMMRegister dst, XMMRegister src);
  void emit_sse_operand(XMMRegister reg, const Operand& adr);
  void emit_sse_operand(XMMRegister dst, Register src);

1113
  // Use either movsd or movlpd.
1114 1115
  // void movdbl(XMMRegister dst, const Operand& src);
  // void movdbl(const Operand& dst, XMMRegister src);
1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133

  // Debugging
  void Print();

  // Check the code size generated from label to here.
  int SizeOfCodeGeneratedSince(Label* l) { return pc_offset() - l->pos(); }

  // Mark address of the ExitJSFrame code.
  void RecordJSReturn();

  // Record a comment relocation entry that can be used by a disassembler.
  // Use --debug_code to enable.
  void RecordComment(const char* msg);

  void RecordPosition(int pos);
  void RecordStatementPosition(int pos);
  void WriteRecordedPositions();

1134
  int pc_offset() const  { return static_cast<int>(pc_ - buffer_); }
1135 1136 1137 1138 1139 1140
  int current_statement_position() const { return current_statement_position_; }
  int current_position() const  { return current_position_; }

  // Check if there is less than kGap bytes available in the buffer.
  // If this is the case, we need to grow the buffer before emitting
  // an instruction or relocation information.
1141 1142 1143
  inline bool buffer_overflow() const {
    return pc_ >= reloc_info_writer.pos() - kGap;
  }
1144 1145

  // Get the number of bytes available in the buffer.
1146 1147 1148
  inline int available_space() const {
    return static_cast<int>(reloc_info_writer.pos() - pc_);
  }
1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165

  // Avoid overflows for displacements etc.
  static const int kMaximalBufferSize = 512*MB;
  static const int kMinimalBufferSize = 4*KB;

 private:
  byte* addr_at(int pos)  { return buffer_ + pos; }
  byte byte_at(int pos)  { return buffer_[pos]; }
  uint32_t long_at(int pos)  {
    return *reinterpret_cast<uint32_t*>(addr_at(pos));
  }
  void long_at_put(int pos, uint32_t x)  {
    *reinterpret_cast<uint32_t*>(addr_at(pos)) = x;
  }

  // code emission
  void GrowBuffer();
1166 1167

  void emit(byte x) { *pc_++ = x; }
1168 1169
  inline void emitl(uint32_t x);
  inline void emitq(uint64_t x, RelocInfo::Mode rmode);
1170
  inline void emitw(uint16_t x);
1171
  inline void emit_code_target(Handle<Code> target, RelocInfo::Mode rmode);
1172
  void emit(Immediate x) { emitl(x.value_); }
1173

1174 1175
  // Emits a REX prefix that encodes a 64-bit operand size and
  // the top bit of both register codes.
1176 1177
  // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
  // REX.W is set.
1178
  inline void emit_rex_64(Register reg, Register rm_reg);
1179
  inline void emit_rex_64(XMMRegister reg, Register rm_reg);
1180 1181 1182

  // Emits a REX prefix that encodes a 64-bit operand size and
  // the top bit of the destination, index, and base register codes.
1183 1184 1185
  // The high bit of reg is used for REX.R, the high bit of op's base
  // register is used for REX.B, and the high bit of op's index register
  // is used for REX.X.  REX.W is set.
1186
  inline void emit_rex_64(Register reg, const Operand& op);
1187
  inline void emit_rex_64(XMMRegister reg, const Operand& op);
1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200

  // Emits a REX prefix that encodes a 64-bit operand size and
  // the top bit of the register code.
  // The high bit of register is used for REX.B.
  // REX.W is set and REX.R and REX.X are clear.
  inline void emit_rex_64(Register rm_reg);

  // Emits a REX prefix that encodes a 64-bit operand size and
  // the top bit of the index and base register codes.
  // The high bit of op's base register is used for REX.B, and the high
  // bit of op's index register is used for REX.X.
  // REX.W is set and REX.R clear.
  inline void emit_rex_64(const Operand& op);
1201

1202 1203 1204
  // Emit a REX prefix that only sets REX.W to choose a 64-bit operand size.
  void emit_rex_64() { emit(0x48); }

1205
  // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
1206
  // REX.W is clear.
1207 1208 1209 1210 1211 1212 1213
  inline void emit_rex_32(Register reg, Register rm_reg);

  // The high bit of reg is used for REX.R, the high bit of op's base
  // register is used for REX.B, and the high bit of op's index register
  // is used for REX.X.  REX.W is cleared.
  inline void emit_rex_32(Register reg, const Operand& op);

1214 1215 1216 1217 1218 1219
  // High bit of rm_reg goes to REX.B.
  // REX.W, REX.R and REX.X are clear.
  inline void emit_rex_32(Register rm_reg);

  // High bit of base goes to REX.B and high bit of index to REX.X.
  // REX.W and REX.R are clear.
1220
  inline void emit_rex_32(const Operand& op);
1221

1222 1223 1224 1225 1226 1227 1228 1229 1230
  // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
  // REX.W is cleared.  If no REX bits are set, no byte is emitted.
  inline void emit_optional_rex_32(Register reg, Register rm_reg);

  // The high bit of reg is used for REX.R, the high bit of op's base
  // register is used for REX.B, and the high bit of op's index register
  // is used for REX.X.  REX.W is cleared.  If no REX bits are set, nothing
  // is emitted.
  inline void emit_optional_rex_32(Register reg, const Operand& op);
1231

1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243
  // As for emit_optional_rex_32(Register, Register), except that
  // the registers are XMM registers.
  inline void emit_optional_rex_32(XMMRegister reg, XMMRegister base);

  // As for emit_optional_rex_32(Register, Register), except that
  // the registers are XMM registers.
  inline void emit_optional_rex_32(XMMRegister reg, Register base);

  // As for emit_optional_rex_32(Register, const Operand&), except that
  // the register is an XMM register.
  inline void emit_optional_rex_32(XMMRegister reg, const Operand& op);

1244 1245 1246 1247 1248 1249 1250 1251 1252
  // Optionally do as emit_rex_32(Register) if the register number has
  // the high bit set.
  inline void emit_optional_rex_32(Register rm_reg);

  // Optionally do as emit_rex_32(const Operand&) if the operand register
  // numbers have a high bit set.
  inline void emit_optional_rex_32(const Operand& op);


1253
  // Emit the ModR/M byte, and optionally the SIB byte and
1254
  // 1- or 4-byte offset for a memory operand.  Also encodes
1255
  // the second operand of the operation, a register or operation
1256
  // subcode, into the reg field of the ModR/M byte.
1257
  void emit_operand(Register reg, const Operand& adr) {
1258
    emit_operand(reg.low_bits(), adr);
1259
  }
1260

1261
  // Emit the ModR/M byte, and optionally the SIB byte and
1262
  // 1- or 4-byte offset for a memory operand.  Also used to encode
1263
  // a three-bit opcode extension into the ModR/M byte.
1264 1265
  void emit_operand(int rm, const Operand& adr);

1266 1267
  // Emit a ModR/M byte with registers coded in the reg and rm_reg fields.
  void emit_modrm(Register reg, Register rm_reg) {
1268
    emit(0xC0 | reg.low_bits() << 3 | rm_reg.low_bits());
1269 1270 1271 1272 1273
  }

  // Emit a ModR/M byte with an operation subcode in the reg field and
  // a register in the rm_reg field.
  void emit_modrm(int code, Register rm_reg) {
1274 1275
    ASSERT(is_uint3(code));
    emit(0xC0 | code << 3 | rm_reg.low_bits());
1276 1277
  }

1278 1279 1280
  // Emit the code-object-relative offset of the label's position
  inline void emit_code_relative_offset(Label* label);

1281 1282 1283
  // Emit machine code for one of the operations ADD, ADC, SUB, SBC,
  // AND, OR, XOR, or CMP.  The encodings of these operations are all
  // similar, differing just in the opcode or in the reg field of the
1284
  // ModR/M byte.
1285 1286 1287
  void arithmetic_op_16(byte opcode, Register reg, Register rm_reg);
  void arithmetic_op_16(byte opcode, Register reg, const Operand& rm_reg);
  void arithmetic_op_32(byte opcode, Register reg, Register rm_reg);
1288
  void arithmetic_op_32(byte opcode, Register reg, const Operand& rm_reg);
1289
  void arithmetic_op(byte opcode, Register reg, Register rm_reg);
1290
  void arithmetic_op(byte opcode, Register reg, const Operand& rm_reg);
1291 1292
  void immediate_arithmetic_op(byte subcode, Register dst, Immediate src);
  void immediate_arithmetic_op(byte subcode, const Operand& dst, Immediate src);
1293
  // Operate on a byte in memory or register.
1294
  void immediate_arithmetic_op_8(byte subcode,
1295
                                 Register dst,
1296 1297
                                 Immediate src);
  void immediate_arithmetic_op_8(byte subcode,
1298
                                 const Operand& dst,
1299
                                 Immediate src);
1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314
  // Operate on a word in memory or register.
  void immediate_arithmetic_op_16(byte subcode,
                                  Register dst,
                                  Immediate src);
  void immediate_arithmetic_op_16(byte subcode,
                                  const Operand& dst,
                                  Immediate src);
  // Operate on a 32-bit word in memory or register.
  void immediate_arithmetic_op_32(byte subcode,
                                  Register dst,
                                  Immediate src);
  void immediate_arithmetic_op_32(byte subcode,
                                  const Operand& dst,
                                  Immediate src);

1315 1316
  // Emit machine code for a shift operation.
  void shift(Register dst, Immediate shift_amount, int subcode);
1317
  void shift_32(Register dst, Immediate shift_amount, int subcode);
1318 1319
  // Shift dst by cl % 64 bits.
  void shift(Register dst, int subcode);
1320
  void shift_32(Register dst, int subcode);
1321

1322
  void emit_farith(int b1, int b2, int i);
1323 1324

  // labels
1325
  // void print(Label* L);
1326 1327 1328 1329
  void bind_to(Label* L, int pos);
  void link_to(Label* L, Label* appendix);

  // record reloc info for current pc_
1330
  void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
1331 1332 1333

  friend class CodePatcher;
  friend class EnsureSpace;
1334
  friend class RegExpMacroAssemblerX64;
1335 1336 1337 1338 1339 1340 1341

  // Code buffer:
  // The buffer into which code and relocation info are generated.
  byte* buffer_;
  int buffer_size_;
  // True if the assembler owns the buffer, false if buffer is external.
  bool own_buffer_;
1342 1343
  // A previously allocated buffer of kMinimalBufferSize bytes, or NULL.
  static byte* spare_buffer_;
1344 1345 1346 1347 1348

  // code generation
  byte* pc_;  // the program counter; moves forward
  RelocInfoWriter reloc_info_writer;

1349
  List< Handle<Code> > code_targets_;
1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367
  // push-pop elimination
  byte* last_pc_;

  // source position information
  int current_statement_position_;
  int current_position_;
  int written_statement_position_;
  int written_position_;
};


// Helper class that ensures that there is enough space for generating
// instructions and relocation information.  The constructor makes
// sure that there is enough space and (in debug mode) the destructor
// checks that we did not generate too much.
class EnsureSpace BASE_EMBEDDED {
 public:
  explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) {
1368
    if (assembler_->buffer_overflow()) assembler_->GrowBuffer();
1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387
#ifdef DEBUG
    space_before_ = assembler_->available_space();
#endif
  }

#ifdef DEBUG
  ~EnsureSpace() {
    int bytes_generated = space_before_ - assembler_->available_space();
    ASSERT(bytes_generated < assembler_->kGap);
  }
#endif

 private:
  Assembler* assembler_;
#ifdef DEBUG
  int space_before_;
#endif
};

1388 1389 1390
} }  // namespace v8::internal

#endif  // V8_X64_ASSEMBLER_X64_H_