~evarlast/ubuntu/utopic/mongodb/upstart-workaround-debian-bug-718702

« back to all changes in this revision

Viewing changes to src/third_party/v8/src/x64/assembler-x64.h

  • Committer: Package Import Robot
  • Author(s): James Page, James Page, Robie Basak
  • Date: 2013-05-29 17:44:42 UTC
  • mfrom: (44.1.7 sid)
  • Revision ID: package-import@ubuntu.com-20130529174442-z0a4qmoww4y0t458
Tags: 1:2.4.3-1ubuntu1
[ James Page ]
* Merge from Debian unstable, remaining changes:
  - Enable SSL support:
    + d/control: Add libssl-dev to BD's.
    + d/rules: Enabled --ssl option.
    + d/mongodb.conf: Add example SSL configuration options.
  - d/mongodb-server.mongodb.upstart: Add upstart configuration.
  - d/rules: Don't strip binaries during scons build for Ubuntu.
  - d/control: Add armhf to target archs.
  - d/p/SConscript.client.patch: fixup install of client libraries.
  - d/p/0010-install-libs-to-usr-lib-not-usr-lib64-Closes-588557.patch:
    Install libraries to lib not lib64.
* Dropped changes:
  - d/p/arm-support.patch: Included in Debian.
  - d/p/double-alignment.patch: Included in Debian.
  - d/rules,control: Debian also builds with avaliable system libraries
    now.
* Fix FTBFS due to gcc and boost upgrades in saucy:
  - d/p/0008-ignore-unused-local-typedefs.patch: Add -Wno-unused-typedefs
    to unbreak building with g++-4.8.
  - d/p/0009-boost-1.53.patch: Fixup signed/unsigned casting issue.

[ Robie Basak ]
* d/p/0011-Use-a-signed-char-to-store-BSONType-enumerations.patch: Fixup
  build failure on ARM due to missing signed'ness of char cast.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 2012 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
 
 
42
namespace v8 {
 
43
namespace internal {
 
44
 
 
45
// Utility functions
 
46
 
 
47
// Test whether a 64-bit value is in a specific range.
 
48
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
 
 
53
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
 
 
58
inline bool uint_is_int32(uint64_t x) {
 
59
  static const uint64_t kMaxInt32 = V8_UINT64_C(0x7fffffff);
 
60
  return x <= kMaxInt32;
 
61
}
 
62
 
 
63
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
 
 
90
struct Register {
 
91
  // The non-allocatable registers are:
 
92
  //  rsp - stack pointer
 
93
  //  rbp - frame pointer
 
94
  //  rsi - context register
 
95
  //  r10 - fixed scratch register
 
96
  //  r12 - smi constant register
 
97
  //  r13 - root register
 
98
  static const int kNumRegisters = 16;
 
99
  static const int kNumAllocatableRegisters = 10;
 
100
 
 
101
  static int ToAllocationIndex(Register reg) {
 
102
    return kAllocationIndexByRegisterCode[reg.code()];
 
103
  }
 
104
 
 
105
  static Register FromAllocationIndex(int index) {
 
106
    ASSERT(index >= 0 && index < kNumAllocatableRegisters);
 
107
    Register result = { kRegisterCodeByAllocationIndex[index] };
 
108
    return result;
 
109
  }
 
110
 
 
111
  static const char* AllocationIndexToString(int index) {
 
112
    ASSERT(index >= 0 && index < kNumAllocatableRegisters);
 
113
    const char* const names[] = {
 
114
      "rax",
 
115
      "rbx",
 
116
      "rdx",
 
117
      "rcx",
 
118
      "rdi",
 
119
      "r8",
 
120
      "r9",
 
121
      "r11",
 
122
      "r14",
 
123
      "r15"
 
124
    };
 
125
    return names[index];
 
126
  }
 
127
 
 
128
  static Register from_code(int code) {
 
129
    Register r = { code };
 
130
    return r;
 
131
  }
 
132
  bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; }
 
133
  bool is(Register reg) const { return code_ == reg.code_; }
 
134
  // rax, rbx, rcx and rdx are byte registers, the rest are not.
 
135
  bool is_byte_register() const { return code_ <= 3; }
 
136
  int code() const {
 
137
    ASSERT(is_valid());
 
138
    return code_;
 
139
  }
 
140
  int bit() const {
 
141
    return 1 << code_;
 
142
  }
 
143
 
 
144
  // Return the high bit of the register code as a 0 or 1.  Used often
 
145
  // when constructing the REX prefix byte.
 
146
  int high_bit() const {
 
147
    return code_ >> 3;
 
148
  }
 
149
  // Return the 3 low bits of the register code.  Used when encoding registers
 
150
  // in modR/M, SIB, and opcode bytes.
 
151
  int low_bits() const {
 
152
    return code_ & 0x7;
 
153
  }
 
154
 
 
155
  // Unfortunately we can't make this private in a struct when initializing
 
156
  // by assignment.
 
157
  int code_;
 
158
 
 
159
 private:
 
160
  static const int kRegisterCodeByAllocationIndex[kNumAllocatableRegisters];
 
161
  static const int kAllocationIndexByRegisterCode[kNumRegisters];
 
162
};
 
163
 
 
164
const int kRegister_rax_Code = 0;
 
165
const int kRegister_rcx_Code = 1;
 
166
const int kRegister_rdx_Code = 2;
 
167
const int kRegister_rbx_Code = 3;
 
168
const int kRegister_rsp_Code = 4;
 
169
const int kRegister_rbp_Code = 5;
 
170
const int kRegister_rsi_Code = 6;
 
171
const int kRegister_rdi_Code = 7;
 
172
const int kRegister_r8_Code = 8;
 
173
const int kRegister_r9_Code = 9;
 
174
const int kRegister_r10_Code = 10;
 
175
const int kRegister_r11_Code = 11;
 
176
const int kRegister_r12_Code = 12;
 
177
const int kRegister_r13_Code = 13;
 
178
const int kRegister_r14_Code = 14;
 
179
const int kRegister_r15_Code = 15;
 
180
const int kRegister_no_reg_Code = -1;
 
181
 
 
182
const Register rax = { kRegister_rax_Code };
 
183
const Register rcx = { kRegister_rcx_Code };
 
184
const Register rdx = { kRegister_rdx_Code };
 
185
const Register rbx = { kRegister_rbx_Code };
 
186
const Register rsp = { kRegister_rsp_Code };
 
187
const Register rbp = { kRegister_rbp_Code };
 
188
const Register rsi = { kRegister_rsi_Code };
 
189
const Register rdi = { kRegister_rdi_Code };
 
190
const Register r8 = { kRegister_r8_Code };
 
191
const Register r9 = { kRegister_r9_Code };
 
192
const Register r10 = { kRegister_r10_Code };
 
193
const Register r11 = { kRegister_r11_Code };
 
194
const Register r12 = { kRegister_r12_Code };
 
195
const Register r13 = { kRegister_r13_Code };
 
196
const Register r14 = { kRegister_r14_Code };
 
197
const Register r15 = { kRegister_r15_Code };
 
198
const Register no_reg = { kRegister_no_reg_Code };
 
199
 
 
200
 
 
201
struct XMMRegister {
 
202
  static const int kNumRegisters = 16;
 
203
  static const int kNumAllocatableRegisters = 15;
 
204
 
 
205
  static int ToAllocationIndex(XMMRegister reg) {
 
206
    ASSERT(reg.code() != 0);
 
207
    return reg.code() - 1;
 
208
  }
 
209
 
 
210
  static XMMRegister FromAllocationIndex(int index) {
 
211
    ASSERT(0 <= index && index < kNumAllocatableRegisters);
 
212
    XMMRegister result = { index + 1 };
 
213
    return result;
 
214
  }
 
215
 
 
216
  static const char* AllocationIndexToString(int index) {
 
217
    ASSERT(index >= 0 && index < kNumAllocatableRegisters);
 
218
    const char* const names[] = {
 
219
      "xmm1",
 
220
      "xmm2",
 
221
      "xmm3",
 
222
      "xmm4",
 
223
      "xmm5",
 
224
      "xmm6",
 
225
      "xmm7",
 
226
      "xmm8",
 
227
      "xmm9",
 
228
      "xmm10",
 
229
      "xmm11",
 
230
      "xmm12",
 
231
      "xmm13",
 
232
      "xmm14",
 
233
      "xmm15"
 
234
    };
 
235
    return names[index];
 
236
  }
 
237
 
 
238
  static XMMRegister from_code(int code) {
 
239
    ASSERT(code >= 0);
 
240
    ASSERT(code < kNumRegisters);
 
241
    XMMRegister r = { code };
 
242
    return r;
 
243
  }
 
244
  bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; }
 
245
  bool is(XMMRegister reg) const { return code_ == reg.code_; }
 
246
  int code() const {
 
247
    ASSERT(is_valid());
 
248
    return code_;
 
249
  }
 
250
 
 
251
  // Return the high bit of the register code as a 0 or 1.  Used often
 
252
  // when constructing the REX prefix byte.
 
253
  int high_bit() const {
 
254
    return code_ >> 3;
 
255
  }
 
256
  // Return the 3 low bits of the register code.  Used when encoding registers
 
257
  // in modR/M, SIB, and opcode bytes.
 
258
  int low_bits() const {
 
259
    return code_ & 0x7;
 
260
  }
 
261
 
 
262
  int code_;
 
263
};
 
264
 
 
265
const XMMRegister xmm0 = { 0 };
 
266
const XMMRegister xmm1 = { 1 };
 
267
const XMMRegister xmm2 = { 2 };
 
268
const XMMRegister xmm3 = { 3 };
 
269
const XMMRegister xmm4 = { 4 };
 
270
const XMMRegister xmm5 = { 5 };
 
271
const XMMRegister xmm6 = { 6 };
 
272
const XMMRegister xmm7 = { 7 };
 
273
const XMMRegister xmm8 = { 8 };
 
274
const XMMRegister xmm9 = { 9 };
 
275
const XMMRegister xmm10 = { 10 };
 
276
const XMMRegister xmm11 = { 11 };
 
277
const XMMRegister xmm12 = { 12 };
 
278
const XMMRegister xmm13 = { 13 };
 
279
const XMMRegister xmm14 = { 14 };
 
280
const XMMRegister xmm15 = { 15 };
 
281
 
 
282
 
 
283
typedef XMMRegister DoubleRegister;
 
284
 
 
285
 
 
286
enum Condition {
 
287
  // any value < 0 is considered no_condition
 
288
  no_condition  = -1,
 
289
 
 
290
  overflow      =  0,
 
291
  no_overflow   =  1,
 
292
  below         =  2,
 
293
  above_equal   =  3,
 
294
  equal         =  4,
 
295
  not_equal     =  5,
 
296
  below_equal   =  6,
 
297
  above         =  7,
 
298
  negative      =  8,
 
299
  positive      =  9,
 
300
  parity_even   = 10,
 
301
  parity_odd    = 11,
 
302
  less          = 12,
 
303
  greater_equal = 13,
 
304
  less_equal    = 14,
 
305
  greater       = 15,
 
306
 
 
307
  // Fake conditions that are handled by the
 
308
  // opcodes using them.
 
309
  always        = 16,
 
310
  never         = 17,
 
311
  // aliases
 
312
  carry         = below,
 
313
  not_carry     = above_equal,
 
314
  zero          = equal,
 
315
  not_zero      = not_equal,
 
316
  sign          = negative,
 
317
  not_sign      = positive,
 
318
  last_condition = greater
 
319
};
 
320
 
 
321
 
 
322
// Returns the equivalent of !cc.
 
323
// Negation of the default no_condition (-1) results in a non-default
 
324
// no_condition value (-2). As long as tests for no_condition check
 
325
// for condition < 0, this will work as expected.
 
326
inline Condition NegateCondition(Condition cc) {
 
327
  return static_cast<Condition>(cc ^ 1);
 
328
}
 
329
 
 
330
 
 
331
// Corresponds to transposing the operands of a comparison.
 
332
inline Condition ReverseCondition(Condition cc) {
 
333
  switch (cc) {
 
334
    case below:
 
335
      return above;
 
336
    case above:
 
337
      return below;
 
338
    case above_equal:
 
339
      return below_equal;
 
340
    case below_equal:
 
341
      return above_equal;
 
342
    case less:
 
343
      return greater;
 
344
    case greater:
 
345
      return less;
 
346
    case greater_equal:
 
347
      return less_equal;
 
348
    case less_equal:
 
349
      return greater_equal;
 
350
    default:
 
351
      return cc;
 
352
  };
 
353
}
 
354
 
 
355
 
 
356
// -----------------------------------------------------------------------------
 
357
// Machine instruction Immediates
 
358
 
 
359
class Immediate BASE_EMBEDDED {
 
360
 public:
 
361
  explicit Immediate(int32_t value) : value_(value) {}
 
362
 
 
363
 private:
 
364
  int32_t value_;
 
365
 
 
366
  friend class Assembler;
 
367
};
 
368
 
 
369
 
 
370
// -----------------------------------------------------------------------------
 
371
// Machine instruction Operands
 
372
 
 
373
enum ScaleFactor {
 
374
  times_1 = 0,
 
375
  times_2 = 1,
 
376
  times_4 = 2,
 
377
  times_8 = 3,
 
378
  times_int_size = times_4,
 
379
  times_pointer_size = times_8
 
380
};
 
381
 
 
382
 
 
383
class Operand BASE_EMBEDDED {
 
384
 public:
 
385
  // [base + disp/r]
 
386
  Operand(Register base, int32_t disp);
 
387
 
 
388
  // [base + index*scale + disp/r]
 
389
  Operand(Register base,
 
390
          Register index,
 
391
          ScaleFactor scale,
 
392
          int32_t disp);
 
393
 
 
394
  // [index*scale + disp/r]
 
395
  Operand(Register index,
 
396
          ScaleFactor scale,
 
397
          int32_t disp);
 
398
 
 
399
  // Offset from existing memory operand.
 
400
  // Offset is added to existing displacement as 32-bit signed values and
 
401
  // this must not overflow.
 
402
  Operand(const Operand& base, int32_t offset);
 
403
 
 
404
  // Checks whether either base or index register is the given register.
 
405
  // Does not check the "reg" part of the Operand.
 
406
  bool AddressUsesRegister(Register reg) const;
 
407
 
 
408
  // Queries related to the size of the generated instruction.
 
409
  // Whether the generated instruction will have a REX prefix.
 
410
  bool requires_rex() const { return rex_ != 0; }
 
411
  // Size of the ModR/M, SIB and displacement parts of the generated
 
412
  // instruction.
 
413
  int operand_size() const { return len_; }
 
414
 
 
415
 private:
 
416
  byte rex_;
 
417
  byte buf_[6];
 
418
  // The number of bytes of buf_ in use.
 
419
  byte len_;
 
420
 
 
421
  // Set the ModR/M byte without an encoded 'reg' register. The
 
422
  // register is encoded later as part of the emit_operand operation.
 
423
  // set_modrm can be called before or after set_sib and set_disp*.
 
424
  inline void set_modrm(int mod, Register rm);
 
425
 
 
426
  // Set the SIB byte if one is needed. Sets the length to 2 rather than 1.
 
427
  inline void set_sib(ScaleFactor scale, Register index, Register base);
 
428
 
 
429
  // Adds operand displacement fields (offsets added to the memory address).
 
430
  // Needs to be called after set_sib, not before it.
 
431
  inline void set_disp8(int disp);
 
432
  inline void set_disp32(int disp);
 
433
 
 
434
  friend class Assembler;
 
435
};
 
436
 
 
437
 
 
438
// CpuFeatures keeps track of which features are supported by the target CPU.
 
439
// Supported features must be enabled by a Scope before use.
 
440
// Example:
 
441
//   if (CpuFeatures::IsSupported(SSE3)) {
 
442
//     CpuFeatures::Scope fscope(SSE3);
 
443
//     // Generate SSE3 floating point code.
 
444
//   } else {
 
445
//     // Generate standard x87 or SSE2 floating point code.
 
446
//   }
 
447
class CpuFeatures : public AllStatic {
 
448
 public:
 
449
  // Detect features of the target CPU. Set safe defaults if the serializer
 
450
  // is enabled (snapshots must be portable).
 
451
  static void Probe();
 
452
 
 
453
  // Check whether a feature is supported by the target CPU.
 
454
  static bool IsSupported(CpuFeature f) {
 
455
    ASSERT(initialized_);
 
456
    if (f == SSE2 && !FLAG_enable_sse2) return false;
 
457
    if (f == SSE3 && !FLAG_enable_sse3) return false;
 
458
    if (f == SSE4_1 && !FLAG_enable_sse4_1) return false;
 
459
    if (f == CMOV && !FLAG_enable_cmov) return false;
 
460
    if (f == RDTSC && !FLAG_enable_rdtsc) return false;
 
461
    if (f == SAHF && !FLAG_enable_sahf) return false;
 
462
    return (supported_ & (V8_UINT64_C(1) << f)) != 0;
 
463
  }
 
464
 
 
465
#ifdef DEBUG
 
466
  // Check whether a feature is currently enabled.
 
467
  static bool IsEnabled(CpuFeature f) {
 
468
    ASSERT(initialized_);
 
469
    Isolate* isolate = Isolate::UncheckedCurrent();
 
470
    if (isolate == NULL) {
 
471
      // When no isolate is available, work as if we're running in
 
472
      // release mode.
 
473
      return IsSupported(f);
 
474
    }
 
475
    uint64_t enabled = isolate->enabled_cpu_features();
 
476
    return (enabled & (V8_UINT64_C(1) << f)) != 0;
 
477
  }
 
478
#endif
 
479
 
 
480
  // Enable a specified feature within a scope.
 
481
  class Scope BASE_EMBEDDED {
 
482
#ifdef DEBUG
 
483
 
 
484
   public:
 
485
    explicit Scope(CpuFeature f) {
 
486
      uint64_t mask = V8_UINT64_C(1) << f;
 
487
      ASSERT(CpuFeatures::IsSupported(f));
 
488
      ASSERT(!Serializer::enabled() ||
 
489
             (CpuFeatures::found_by_runtime_probing_ & mask) == 0);
 
490
      isolate_ = Isolate::UncheckedCurrent();
 
491
      old_enabled_ = 0;
 
492
      if (isolate_ != NULL) {
 
493
        old_enabled_ = isolate_->enabled_cpu_features();
 
494
        isolate_->set_enabled_cpu_features(old_enabled_ | mask);
 
495
      }
 
496
    }
 
497
    ~Scope() {
 
498
      ASSERT_EQ(Isolate::UncheckedCurrent(), isolate_);
 
499
      if (isolate_ != NULL) {
 
500
        isolate_->set_enabled_cpu_features(old_enabled_);
 
501
      }
 
502
    }
 
503
 
 
504
   private:
 
505
    Isolate* isolate_;
 
506
    uint64_t old_enabled_;
 
507
#else
 
508
 
 
509
   public:
 
510
    explicit Scope(CpuFeature f) {}
 
511
#endif
 
512
  };
 
513
 
 
514
 private:
 
515
  // Safe defaults include SSE2 and CMOV for X64. It is always available, if
 
516
  // anyone checks, but they shouldn't need to check.
 
517
  // The required user mode extensions in X64 are (from AMD64 ABI Table A.1):
 
518
  //   fpu, tsc, cx8, cmov, mmx, sse, sse2, fxsr, syscall
 
519
  static const uint64_t kDefaultCpuFeatures = (1 << SSE2 | 1 << CMOV);
 
520
 
 
521
#ifdef DEBUG
 
522
  static bool initialized_;
 
523
#endif
 
524
  static uint64_t supported_;
 
525
  static uint64_t found_by_runtime_probing_;
 
526
 
 
527
  DISALLOW_COPY_AND_ASSIGN(CpuFeatures);
 
528
};
 
529
 
 
530
 
 
531
class Assembler : public AssemblerBase {
 
532
 private:
 
533
  // We check before assembling an instruction that there is sufficient
 
534
  // space to write an instruction and its relocation information.
 
535
  // The relocation writer's position must be kGap bytes above the end of
 
536
  // the generated instructions. This leaves enough space for the
 
537
  // longest possible x64 instruction, 15 bytes, and the longest possible
 
538
  // relocation information encoding, RelocInfoWriter::kMaxLength == 16.
 
539
  // (There is a 15 byte limit on x64 instruction length that rules out some
 
540
  // otherwise valid instructions.)
 
541
  // This allows for a single, fast space check per instruction.
 
542
  static const int kGap = 32;
 
543
 
 
544
 public:
 
545
  // Create an assembler. Instructions and relocation information are emitted
 
546
  // into a buffer, with the instructions starting from the beginning and the
 
547
  // relocation information starting from the end of the buffer. See CodeDesc
 
548
  // for a detailed comment on the layout (globals.h).
 
549
  //
 
550
  // If the provided buffer is NULL, the assembler allocates and grows its own
 
551
  // buffer, and buffer_size determines the initial buffer size. The buffer is
 
552
  // owned by the assembler and deallocated upon destruction of the assembler.
 
553
  //
 
554
  // If the provided buffer is not NULL, the assembler uses the provided buffer
 
555
  // for code generation and assumes its size to be buffer_size. If the buffer
 
556
  // is too small, a fatal error occurs. No deallocation of the buffer is done
 
557
  // upon destruction of the assembler.
 
558
  Assembler(Isolate* isolate, void* buffer, int buffer_size);
 
559
  ~Assembler();
 
560
 
 
561
  // Overrides the default provided by FLAG_debug_code.
 
562
  void set_emit_debug_code(bool value) { emit_debug_code_ = value; }
 
563
 
 
564
  // Avoids using instructions that vary in size in unpredictable ways between
 
565
  // the snapshot and the running VM.  This is needed by the full compiler so
 
566
  // that it can recompile code with debug support and fix the PC.
 
567
  void set_predictable_code_size(bool value) { predictable_code_size_ = value; }
 
568
 
 
569
  // GetCode emits any pending (non-emitted) code and fills the descriptor
 
570
  // desc. GetCode() is idempotent; it returns the same result if no other
 
571
  // Assembler functions are invoked in between GetCode() calls.
 
572
  void GetCode(CodeDesc* desc);
 
573
 
 
574
  // Read/Modify the code target in the relative branch/call instruction at pc.
 
575
  // On the x64 architecture, we use relative jumps with a 32-bit displacement
 
576
  // to jump to other Code objects in the Code space in the heap.
 
577
  // Jumps to C functions are done indirectly through a 64-bit register holding
 
578
  // the absolute address of the target.
 
579
  // These functions convert between absolute Addresses of Code objects and
 
580
  // the relative displacements stored in the code.
 
581
  static inline Address target_address_at(Address pc);
 
582
  static inline void set_target_address_at(Address pc, Address target);
 
583
 
 
584
  // This sets the branch destination (which is in the instruction on x64).
 
585
  // This is for calls and branches within generated code.
 
586
  inline static void deserialization_set_special_target_at(
 
587
      Address instruction_payload, Address target) {
 
588
    set_target_address_at(instruction_payload, target);
 
589
  }
 
590
 
 
591
  // This sets the branch destination (which is a load instruction on x64).
 
592
  // This is for calls and branches to runtime code.
 
593
  inline static void set_external_target_at(Address instruction_payload,
 
594
                                            Address target) {
 
595
    *reinterpret_cast<Address*>(instruction_payload) = target;
 
596
  }
 
597
 
 
598
  inline Handle<Object> code_target_object_handle_at(Address pc);
 
599
  // Number of bytes taken up by the branch target in the code.
 
600
  static const int kSpecialTargetSize = 4;  // Use 32-bit displacement.
 
601
  // Distance between the address of the code target in the call instruction
 
602
  // and the return address pushed on the stack.
 
603
  static const int kCallTargetAddressOffset = 4;  // Use 32-bit displacement.
 
604
  // Distance between the start of the JS return sequence and where the
 
605
  // 32-bit displacement of a near call would be, relative to the pushed
 
606
  // return address.  TODO: Use return sequence length instead.
 
607
  // Should equal Debug::kX64JSReturnSequenceLength - kCallTargetAddressOffset;
 
608
  static const int kPatchReturnSequenceAddressOffset = 13 - 4;
 
609
  // Distance between start of patched debug break slot and where the
 
610
  // 32-bit displacement of a near call would be, relative to the pushed
 
611
  // return address.  TODO: Use return sequence length instead.
 
612
  // Should equal Debug::kX64JSReturnSequenceLength - kCallTargetAddressOffset;
 
613
  static const int kPatchDebugBreakSlotAddressOffset = 13 - 4;
 
614
  // TODO(X64): Rename this, removing the "Real", after changing the above.
 
615
  static const int kRealPatchReturnSequenceAddressOffset = 2;
 
616
 
 
617
  // Some x64 JS code is padded with int3 to make it large
 
618
  // enough to hold an instruction when the debugger patches it.
 
619
  static const int kJumpInstructionLength = 13;
 
620
  static const int kCallInstructionLength = 13;
 
621
  static const int kJSReturnSequenceLength = 13;
 
622
  static const int kShortCallInstructionLength = 5;
 
623
 
 
624
  // The debug break slot must be able to contain a call instruction.
 
625
  static const int kDebugBreakSlotLength = kCallInstructionLength;
 
626
 
 
627
  // One byte opcode for test eax,0xXXXXXXXX.
 
628
  static const byte kTestEaxByte = 0xA9;
 
629
  // One byte opcode for test al, 0xXX.
 
630
  static const byte kTestAlByte = 0xA8;
 
631
  // One byte opcode for nop.
 
632
  static const byte kNopByte = 0x90;
 
633
 
 
634
  // One byte prefix for a short conditional jump.
 
635
  static const byte kJccShortPrefix = 0x70;
 
636
  static const byte kJncShortOpcode = kJccShortPrefix | not_carry;
 
637
  static const byte kJcShortOpcode = kJccShortPrefix | carry;
 
638
  static const byte kJnzShortOpcode = kJccShortPrefix | not_zero;
 
639
  static const byte kJzShortOpcode = kJccShortPrefix | zero;
 
640
 
 
641
 
 
642
  // ---------------------------------------------------------------------------
 
643
  // Code generation
 
644
  //
 
645
  // Function names correspond one-to-one to x64 instruction mnemonics.
 
646
  // Unless specified otherwise, instructions operate on 64-bit operands.
 
647
  //
 
648
  // If we need versions of an assembly instruction that operate on different
 
649
  // width arguments, we add a single-letter suffix specifying the width.
 
650
  // This is done for the following instructions: mov, cmp, inc, dec,
 
651
  // add, sub, and test.
 
652
  // There are no versions of these instructions without the suffix.
 
653
  // - Instructions on 8-bit (byte) operands/registers have a trailing 'b'.
 
654
  // - Instructions on 16-bit (word) operands/registers have a trailing 'w'.
 
655
  // - Instructions on 32-bit (doubleword) operands/registers use 'l'.
 
656
  // - Instructions on 64-bit (quadword) operands/registers use 'q'.
 
657
  //
 
658
  // Some mnemonics, such as "and", are the same as C++ keywords.
 
659
  // Naming conflicts with C++ keywords are resolved by adding a trailing '_'.
 
660
 
 
661
  // Insert the smallest number of nop instructions
 
662
  // possible to align the pc offset to a multiple
 
663
  // of m, where m must be a power of 2.
 
664
  void Align(int m);
 
665
  void Nop(int bytes = 1);
 
666
  // Aligns code to something that's optimal for a jump target for the platform.
 
667
  void CodeTargetAlign();
 
668
 
 
669
  // Stack
 
670
  void pushfq();
 
671
  void popfq();
 
672
 
 
673
  void push(Immediate value);
 
674
  // Push a 32 bit integer, and guarantee that it is actually pushed as a
 
675
  // 32 bit value, the normal push will optimize the 8 bit case.
 
676
  void push_imm32(int32_t imm32);
 
677
  void push(Register src);
 
678
  void push(const Operand& src);
 
679
 
 
680
  void pop(Register dst);
 
681
  void pop(const Operand& dst);
 
682
 
 
683
  void enter(Immediate size);
 
684
  void leave();
 
685
 
 
686
  // Moves
 
687
  void movb(Register dst, const Operand& src);
 
688
  void movb(Register dst, Immediate imm);
 
689
  void movb(const Operand& dst, Register src);
 
690
 
 
691
  // Move the low 16 bits of a 64-bit register value to a 16-bit
 
692
  // memory location.
 
693
  void movw(const Operand& dst, Register src);
 
694
 
 
695
  void movl(Register dst, Register src);
 
696
  void movl(Register dst, const Operand& src);
 
697
  void movl(const Operand& dst, Register src);
 
698
  void movl(const Operand& dst, Immediate imm);
 
699
  // Load a 32-bit immediate value, zero-extended to 64 bits.
 
700
  void movl(Register dst, Immediate imm32);
 
701
 
 
702
  // Move 64 bit register value to 64-bit memory location.
 
703
  void movq(const Operand& dst, Register src);
 
704
  // Move 64 bit memory location to 64-bit register value.
 
705
  void movq(Register dst, const Operand& src);
 
706
  void movq(Register dst, Register src);
 
707
  // Sign extends immediate 32-bit value to 64 bits.
 
708
  void movq(Register dst, Immediate x);
 
709
  // Move the offset of the label location relative to the current
 
710
  // position (after the move) to the destination.
 
711
  void movl(const Operand& dst, Label* src);
 
712
 
 
713
  // Move sign extended immediate to memory location.
 
714
  void movq(const Operand& dst, Immediate value);
 
715
  // Instructions to load a 64-bit immediate into a register.
 
716
  // All 64-bit immediates must have a relocation mode.
 
717
  void movq(Register dst, void* ptr, RelocInfo::Mode rmode);
 
718
  void movq(Register dst, int64_t value, RelocInfo::Mode rmode);
 
719
  void movq(Register dst, const char* s, RelocInfo::Mode rmode);
 
720
  // Moves the address of the external reference into the register.
 
721
  void movq(Register dst, ExternalReference ext);
 
722
  void movq(Register dst, Handle<Object> handle, RelocInfo::Mode rmode);
 
723
 
 
724
  void movsxbq(Register dst, const Operand& src);
 
725
  void movsxwq(Register dst, const Operand& src);
 
726
  void movsxlq(Register dst, Register src);
 
727
  void movsxlq(Register dst, const Operand& src);
 
728
  void movzxbq(Register dst, const Operand& src);
 
729
  void movzxbl(Register dst, const Operand& src);
 
730
  void movzxwq(Register dst, const Operand& src);
 
731
  void movzxwl(Register dst, const Operand& src);
 
732
 
 
733
  // Repeated moves.
 
734
 
 
735
  void repmovsb();
 
736
  void repmovsw();
 
737
  void repmovsl();
 
738
  void repmovsq();
 
739
 
 
740
  // Instruction to load from an immediate 64-bit pointer into RAX.
 
741
  void load_rax(void* ptr, RelocInfo::Mode rmode);
 
742
  void load_rax(ExternalReference ext);
 
743
 
 
744
  // Conditional moves.
 
745
  void cmovq(Condition cc, Register dst, Register src);
 
746
  void cmovq(Condition cc, Register dst, const Operand& src);
 
747
  void cmovl(Condition cc, Register dst, Register src);
 
748
  void cmovl(Condition cc, Register dst, const Operand& src);
 
749
 
 
750
  // Exchange two registers
 
751
  void xchg(Register dst, Register src);
 
752
 
 
753
  // Arithmetics
 
754
  void addl(Register dst, Register src) {
 
755
    arithmetic_op_32(0x03, dst, src);
 
756
  }
 
757
 
 
758
  void addl(Register dst, Immediate src) {
 
759
    immediate_arithmetic_op_32(0x0, dst, src);
 
760
  }
 
761
 
 
762
  void addl(Register dst, const Operand& src) {
 
763
    arithmetic_op_32(0x03, dst, src);
 
764
  }
 
765
 
 
766
  void addl(const Operand& dst, Immediate src) {
 
767
    immediate_arithmetic_op_32(0x0, dst, src);
 
768
  }
 
769
 
 
770
  void addl(const Operand& dst, Register src) {
 
771
    arithmetic_op_32(0x01, src, dst);
 
772
  }
 
773
 
 
774
  void addq(Register dst, Register src) {
 
775
    arithmetic_op(0x03, dst, src);
 
776
  }
 
777
 
 
778
  void addq(Register dst, const Operand& src) {
 
779
    arithmetic_op(0x03, dst, src);
 
780
  }
 
781
 
 
782
  void addq(const Operand& dst, Register src) {
 
783
    arithmetic_op(0x01, src, dst);
 
784
  }
 
785
 
 
786
  void addq(Register dst, Immediate src) {
 
787
    immediate_arithmetic_op(0x0, dst, src);
 
788
  }
 
789
 
 
790
  void addq(const Operand& dst, Immediate src) {
 
791
    immediate_arithmetic_op(0x0, dst, src);
 
792
  }
 
793
 
 
794
  void sbbl(Register dst, Register src) {
 
795
    arithmetic_op_32(0x1b, dst, src);
 
796
  }
 
797
 
 
798
  void sbbq(Register dst, Register src) {
 
799
    arithmetic_op(0x1b, dst, src);
 
800
  }
 
801
 
 
802
  void cmpb(Register dst, Immediate src) {
 
803
    immediate_arithmetic_op_8(0x7, dst, src);
 
804
  }
 
805
 
 
806
  void cmpb_al(Immediate src);
 
807
 
 
808
  void cmpb(Register dst, Register src) {
 
809
    arithmetic_op(0x3A, dst, src);
 
810
  }
 
811
 
 
812
  void cmpb(Register dst, const Operand& src) {
 
813
    arithmetic_op(0x3A, dst, src);
 
814
  }
 
815
 
 
816
  void cmpb(const Operand& dst, Register src) {
 
817
    arithmetic_op(0x38, src, dst);
 
818
  }
 
819
 
 
820
  void cmpb(const Operand& dst, Immediate src) {
 
821
    immediate_arithmetic_op_8(0x7, dst, src);
 
822
  }
 
823
 
 
824
  void cmpw(const Operand& dst, Immediate src) {
 
825
    immediate_arithmetic_op_16(0x7, dst, src);
 
826
  }
 
827
 
 
828
  void cmpw(Register dst, Immediate src) {
 
829
    immediate_arithmetic_op_16(0x7, dst, src);
 
830
  }
 
831
 
 
832
  void cmpw(Register dst, const Operand& src) {
 
833
    arithmetic_op_16(0x3B, dst, src);
 
834
  }
 
835
 
 
836
  void cmpw(Register dst, Register src) {
 
837
    arithmetic_op_16(0x3B, dst, src);
 
838
  }
 
839
 
 
840
  void cmpw(const Operand& dst, Register src) {
 
841
    arithmetic_op_16(0x39, src, dst);
 
842
  }
 
843
 
 
844
  void cmpl(Register dst, Register src) {
 
845
    arithmetic_op_32(0x3B, dst, src);
 
846
  }
 
847
 
 
848
  void cmpl(Register dst, const Operand& src) {
 
849
    arithmetic_op_32(0x3B, dst, src);
 
850
  }
 
851
 
 
852
  void cmpl(const Operand& dst, Register src) {
 
853
    arithmetic_op_32(0x39, src, dst);
 
854
  }
 
855
 
 
856
  void cmpl(Register dst, Immediate src) {
 
857
    immediate_arithmetic_op_32(0x7, dst, src);
 
858
  }
 
859
 
 
860
  void cmpl(const Operand& dst, Immediate src) {
 
861
    immediate_arithmetic_op_32(0x7, dst, src);
 
862
  }
 
863
 
 
864
  void cmpq(Register dst, Register src) {
 
865
    arithmetic_op(0x3B, dst, src);
 
866
  }
 
867
 
 
868
  void cmpq(Register dst, const Operand& src) {
 
869
    arithmetic_op(0x3B, dst, src);
 
870
  }
 
871
 
 
872
  void cmpq(const Operand& dst, Register src) {
 
873
    arithmetic_op(0x39, src, dst);
 
874
  }
 
875
 
 
876
  void cmpq(Register dst, Immediate src) {
 
877
    immediate_arithmetic_op(0x7, dst, src);
 
878
  }
 
879
 
 
880
  void cmpq(const Operand& dst, Immediate src) {
 
881
    immediate_arithmetic_op(0x7, dst, src);
 
882
  }
 
883
 
 
884
  void and_(Register dst, Register src) {
 
885
    arithmetic_op(0x23, dst, src);
 
886
  }
 
887
 
 
888
  void and_(Register dst, const Operand& src) {
 
889
    arithmetic_op(0x23, dst, src);
 
890
  }
 
891
 
 
892
  void and_(const Operand& dst, Register src) {
 
893
    arithmetic_op(0x21, src, dst);
 
894
  }
 
895
 
 
896
  void and_(Register dst, Immediate src) {
 
897
    immediate_arithmetic_op(0x4, dst, src);
 
898
  }
 
899
 
 
900
  void and_(const Operand& dst, Immediate src) {
 
901
    immediate_arithmetic_op(0x4, dst, src);
 
902
  }
 
903
 
 
904
  void andl(Register dst, Immediate src) {
 
905
    immediate_arithmetic_op_32(0x4, dst, src);
 
906
  }
 
907
 
 
908
  void andl(Register dst, Register src) {
 
909
    arithmetic_op_32(0x23, dst, src);
 
910
  }
 
911
 
 
912
  void andl(Register dst, const Operand& src) {
 
913
    arithmetic_op_32(0x23, dst, src);
 
914
  }
 
915
 
 
916
  void andb(Register dst, Immediate src) {
 
917
    immediate_arithmetic_op_8(0x4, dst, src);
 
918
  }
 
919
 
 
920
  void decq(Register dst);
 
921
  void decq(const Operand& dst);
 
922
  void decl(Register dst);
 
923
  void decl(const Operand& dst);
 
924
  void decb(Register dst);
 
925
  void decb(const Operand& dst);
 
926
 
 
927
  // Sign-extends rax into rdx:rax.
 
928
  void cqo();
 
929
  // Sign-extends eax into edx:eax.
 
930
  void cdq();
 
931
 
 
932
  // Divide rdx:rax by src.  Quotient in rax, remainder in rdx.
 
933
  void idivq(Register src);
 
934
  // Divide edx:eax by lower 32 bits of src.  Quotient in eax, rem. in edx.
 
935
  void idivl(Register src);
 
936
 
 
937
  // Signed multiply instructions.
 
938
  void imul(Register src);                               // rdx:rax = rax * src.
 
939
  void imul(Register dst, Register src);                 // dst = dst * src.
 
940
  void imul(Register dst, const Operand& src);           // dst = dst * src.
 
941
  void imul(Register dst, Register src, Immediate imm);  // dst = src * imm.
 
942
  // Signed 32-bit multiply instructions.
 
943
  void imull(Register dst, Register src);                 // dst = dst * src.
 
944
  void imull(Register dst, const Operand& src);           // dst = dst * src.
 
945
  void imull(Register dst, Register src, Immediate imm);  // dst = src * imm.
 
946
 
 
947
  void incq(Register dst);
 
948
  void incq(const Operand& dst);
 
949
  void incl(Register dst);
 
950
  void incl(const Operand& dst);
 
951
 
 
952
  void lea(Register dst, const Operand& src);
 
953
  void leal(Register dst, const Operand& src);
 
954
 
 
955
  // Multiply rax by src, put the result in rdx:rax.
 
956
  void mul(Register src);
 
957
 
 
958
  void neg(Register dst);
 
959
  void neg(const Operand& dst);
 
960
  void negl(Register dst);
 
961
 
 
962
  void not_(Register dst);
 
963
  void not_(const Operand& dst);
 
964
  void notl(Register dst);
 
965
 
 
966
  void or_(Register dst, Register src) {
 
967
    arithmetic_op(0x0B, dst, src);
 
968
  }
 
969
 
 
970
  void orl(Register dst, Register src) {
 
971
    arithmetic_op_32(0x0B, dst, src);
 
972
  }
 
973
 
 
974
  void or_(Register dst, const Operand& src) {
 
975
    arithmetic_op(0x0B, dst, src);
 
976
  }
 
977
 
 
978
  void orl(Register dst, const Operand& src) {
 
979
    arithmetic_op_32(0x0B, dst, src);
 
980
  }
 
981
 
 
982
  void or_(const Operand& dst, Register src) {
 
983
    arithmetic_op(0x09, src, dst);
 
984
  }
 
985
 
 
986
  void or_(Register dst, Immediate src) {
 
987
    immediate_arithmetic_op(0x1, dst, src);
 
988
  }
 
989
 
 
990
  void orl(Register dst, Immediate src) {
 
991
    immediate_arithmetic_op_32(0x1, dst, src);
 
992
  }
 
993
 
 
994
  void or_(const Operand& dst, Immediate src) {
 
995
    immediate_arithmetic_op(0x1, dst, src);
 
996
  }
 
997
 
 
998
  void orl(const Operand& dst, Immediate src) {
 
999
    immediate_arithmetic_op_32(0x1, dst, src);
 
1000
  }
 
1001
 
 
1002
 
 
1003
  void rcl(Register dst, Immediate imm8) {
 
1004
    shift(dst, imm8, 0x2);
 
1005
  }
 
1006
 
 
1007
  void rol(Register dst, Immediate imm8) {
 
1008
    shift(dst, imm8, 0x0);
 
1009
  }
 
1010
 
 
1011
  void rcr(Register dst, Immediate imm8) {
 
1012
    shift(dst, imm8, 0x3);
 
1013
  }
 
1014
 
 
1015
  void ror(Register dst, Immediate imm8) {
 
1016
    shift(dst, imm8, 0x1);
 
1017
  }
 
1018
 
 
1019
  // Shifts dst:src left by cl bits, affecting only dst.
 
1020
  void shld(Register dst, Register src);
 
1021
 
 
1022
  // Shifts src:dst right by cl bits, affecting only dst.
 
1023
  void shrd(Register dst, Register src);
 
1024
 
 
1025
  // Shifts dst right, duplicating sign bit, by shift_amount bits.
 
1026
  // Shifting by 1 is handled efficiently.
 
1027
  void sar(Register dst, Immediate shift_amount) {
 
1028
    shift(dst, shift_amount, 0x7);
 
1029
  }
 
1030
 
 
1031
  // Shifts dst right, duplicating sign bit, by shift_amount bits.
 
1032
  // Shifting by 1 is handled efficiently.
 
1033
  void sarl(Register dst, Immediate shift_amount) {
 
1034
    shift_32(dst, shift_amount, 0x7);
 
1035
  }
 
1036
 
 
1037
  // Shifts dst right, duplicating sign bit, by cl % 64 bits.
 
1038
  void sar_cl(Register dst) {
 
1039
    shift(dst, 0x7);
 
1040
  }
 
1041
 
 
1042
  // Shifts dst right, duplicating sign bit, by cl % 64 bits.
 
1043
  void sarl_cl(Register dst) {
 
1044
    shift_32(dst, 0x7);
 
1045
  }
 
1046
 
 
1047
  void shl(Register dst, Immediate shift_amount) {
 
1048
    shift(dst, shift_amount, 0x4);
 
1049
  }
 
1050
 
 
1051
  void shl_cl(Register dst) {
 
1052
    shift(dst, 0x4);
 
1053
  }
 
1054
 
 
1055
  void shll_cl(Register dst) {
 
1056
    shift_32(dst, 0x4);
 
1057
  }
 
1058
 
 
1059
  void shll(Register dst, Immediate shift_amount) {
 
1060
    shift_32(dst, shift_amount, 0x4);
 
1061
  }
 
1062
 
 
1063
  void shr(Register dst, Immediate shift_amount) {
 
1064
    shift(dst, shift_amount, 0x5);
 
1065
  }
 
1066
 
 
1067
  void shr_cl(Register dst) {
 
1068
    shift(dst, 0x5);
 
1069
  }
 
1070
 
 
1071
  void shrl_cl(Register dst) {
 
1072
    shift_32(dst, 0x5);
 
1073
  }
 
1074
 
 
1075
  void shrl(Register dst, Immediate shift_amount) {
 
1076
    shift_32(dst, shift_amount, 0x5);
 
1077
  }
 
1078
 
 
1079
  void store_rax(void* dst, RelocInfo::Mode mode);
 
1080
  void store_rax(ExternalReference ref);
 
1081
 
 
1082
  void subq(Register dst, Register src) {
 
1083
    arithmetic_op(0x2B, dst, src);
 
1084
  }
 
1085
 
 
1086
  void subq(Register dst, const Operand& src) {
 
1087
    arithmetic_op(0x2B, dst, src);
 
1088
  }
 
1089
 
 
1090
  void subq(const Operand& dst, Register src) {
 
1091
    arithmetic_op(0x29, src, dst);
 
1092
  }
 
1093
 
 
1094
  void subq(Register dst, Immediate src) {
 
1095
    immediate_arithmetic_op(0x5, dst, src);
 
1096
  }
 
1097
 
 
1098
  void subq(const Operand& dst, Immediate src) {
 
1099
    immediate_arithmetic_op(0x5, dst, src);
 
1100
  }
 
1101
 
 
1102
  void subl(Register dst, Register src) {
 
1103
    arithmetic_op_32(0x2B, dst, src);
 
1104
  }
 
1105
 
 
1106
  void subl(Register dst, const Operand& src) {
 
1107
    arithmetic_op_32(0x2B, dst, src);
 
1108
  }
 
1109
 
 
1110
  void subl(const Operand& dst, Immediate src) {
 
1111
    immediate_arithmetic_op_32(0x5, dst, src);
 
1112
  }
 
1113
 
 
1114
  void subl(Register dst, Immediate src) {
 
1115
    immediate_arithmetic_op_32(0x5, dst, src);
 
1116
  }
 
1117
 
 
1118
  void subb(Register dst, Immediate src) {
 
1119
    immediate_arithmetic_op_8(0x5, dst, src);
 
1120
  }
 
1121
 
 
1122
  void testb(Register dst, Register src);
 
1123
  void testb(Register reg, Immediate mask);
 
1124
  void testb(const Operand& op, Immediate mask);
 
1125
  void testb(const Operand& op, Register reg);
 
1126
  void testl(Register dst, Register src);
 
1127
  void testl(Register reg, Immediate mask);
 
1128
  void testl(const Operand& op, Immediate mask);
 
1129
  void testq(const Operand& op, Register reg);
 
1130
  void testq(Register dst, Register src);
 
1131
  void testq(Register dst, Immediate mask);
 
1132
 
 
1133
  void xor_(Register dst, Register src) {
 
1134
    if (dst.code() == src.code()) {
 
1135
      arithmetic_op_32(0x33, dst, src);
 
1136
    } else {
 
1137
      arithmetic_op(0x33, dst, src);
 
1138
    }
 
1139
  }
 
1140
 
 
1141
  void xorl(Register dst, Register src) {
 
1142
    arithmetic_op_32(0x33, dst, src);
 
1143
  }
 
1144
 
 
1145
  void xorl(Register dst, const Operand& src) {
 
1146
    arithmetic_op_32(0x33, dst, src);
 
1147
  }
 
1148
 
 
1149
  void xorl(Register dst, Immediate src) {
 
1150
    immediate_arithmetic_op_32(0x6, dst, src);
 
1151
  }
 
1152
 
 
1153
  void xorl(const Operand& dst, Immediate src) {
 
1154
    immediate_arithmetic_op_32(0x6, dst, src);
 
1155
  }
 
1156
 
 
1157
  void xor_(Register dst, const Operand& src) {
 
1158
    arithmetic_op(0x33, dst, src);
 
1159
  }
 
1160
 
 
1161
  void xor_(const Operand& dst, Register src) {
 
1162
    arithmetic_op(0x31, src, dst);
 
1163
  }
 
1164
 
 
1165
  void xor_(Register dst, Immediate src) {
 
1166
    immediate_arithmetic_op(0x6, dst, src);
 
1167
  }
 
1168
 
 
1169
  void xor_(const Operand& dst, Immediate src) {
 
1170
    immediate_arithmetic_op(0x6, dst, src);
 
1171
  }
 
1172
 
 
1173
  // Bit operations.
 
1174
  void bt(const Operand& dst, Register src);
 
1175
  void bts(const Operand& dst, Register src);
 
1176
 
 
1177
  // Miscellaneous
 
1178
  void clc();
 
1179
  void cld();
 
1180
  void cpuid();
 
1181
  void hlt();
 
1182
  void int3();
 
1183
  void nop();
 
1184
  void rdtsc();
 
1185
  void ret(int imm16);
 
1186
  void setcc(Condition cc, Register reg);
 
1187
 
 
1188
  // Label operations & relative jumps (PPUM Appendix D)
 
1189
  //
 
1190
  // Takes a branch opcode (cc) and a label (L) and generates
 
1191
  // either a backward branch or a forward branch and links it
 
1192
  // to the label fixup chain. Usage:
 
1193
  //
 
1194
  // Label L;    // unbound label
 
1195
  // j(cc, &L);  // forward branch to unbound label
 
1196
  // bind(&L);   // bind label to the current pc
 
1197
  // j(cc, &L);  // backward branch to bound label
 
1198
  // bind(&L);   // illegal: a label may be bound only once
 
1199
  //
 
1200
  // Note: The same Label can be used for forward and backward branches
 
1201
  // but it may be bound only once.
 
1202
 
 
1203
  void bind(Label* L);  // binds an unbound label L to the current code position
 
1204
 
 
1205
  // Calls
 
1206
  // Call near relative 32-bit displacement, relative to next instruction.
 
1207
  void call(Label* L);
 
1208
  void call(Handle<Code> target,
 
1209
            RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
 
1210
            unsigned ast_id = kNoASTId);
 
1211
 
 
1212
  // Calls directly to the given address using a relative offset.
 
1213
  // Should only ever be used in Code objects for calls within the
 
1214
  // same Code object. Should not be used when generating new code (use labels),
 
1215
  // but only when patching existing code.
 
1216
  void call(Address target);
 
1217
 
 
1218
  // Call near absolute indirect, address in register
 
1219
  void call(Register adr);
 
1220
 
 
1221
  // Call near indirect
 
1222
  void call(const Operand& operand);
 
1223
 
 
1224
  // Jumps
 
1225
  // Jump short or near relative.
 
1226
  // Use a 32-bit signed displacement.
 
1227
  // Unconditional jump to L
 
1228
  void jmp(Label* L, Label::Distance distance = Label::kFar);
 
1229
  void jmp(Handle<Code> target, RelocInfo::Mode rmode);
 
1230
 
 
1231
  // Jump near absolute indirect (r64)
 
1232
  void jmp(Register adr);
 
1233
 
 
1234
  // Jump near absolute indirect (m64)
 
1235
  void jmp(const Operand& src);
 
1236
 
 
1237
  // Conditional jumps
 
1238
  void j(Condition cc,
 
1239
         Label* L,
 
1240
         Label::Distance distance = Label::kFar);
 
1241
  void j(Condition cc, Handle<Code> target, RelocInfo::Mode rmode);
 
1242
 
 
1243
  // Floating-point operations
 
1244
  void fld(int i);
 
1245
 
 
1246
  void fld1();
 
1247
  void fldz();
 
1248
  void fldpi();
 
1249
  void fldln2();
 
1250
 
 
1251
  void fld_s(const Operand& adr);
 
1252
  void fld_d(const Operand& adr);
 
1253
 
 
1254
  void fstp_s(const Operand& adr);
 
1255
  void fstp_d(const Operand& adr);
 
1256
  void fstp(int index);
 
1257
 
 
1258
  void fild_s(const Operand& adr);
 
1259
  void fild_d(const Operand& adr);
 
1260
 
 
1261
  void fist_s(const Operand& adr);
 
1262
 
 
1263
  void fistp_s(const Operand& adr);
 
1264
  void fistp_d(const Operand& adr);
 
1265
 
 
1266
  void fisttp_s(const Operand& adr);
 
1267
  void fisttp_d(const Operand& adr);
 
1268
 
 
1269
  void fabs();
 
1270
  void fchs();
 
1271
 
 
1272
  void fadd(int i);
 
1273
  void fsub(int i);
 
1274
  void fmul(int i);
 
1275
  void fdiv(int i);
 
1276
 
 
1277
  void fisub_s(const Operand& adr);
 
1278
 
 
1279
  void faddp(int i = 1);
 
1280
  void fsubp(int i = 1);
 
1281
  void fsubrp(int i = 1);
 
1282
  void fmulp(int i = 1);
 
1283
  void fdivp(int i = 1);
 
1284
  void fprem();
 
1285
  void fprem1();
 
1286
 
 
1287
  void fxch(int i = 1);
 
1288
  void fincstp();
 
1289
  void ffree(int i = 0);
 
1290
 
 
1291
  void ftst();
 
1292
  void fucomp(int i);
 
1293
  void fucompp();
 
1294
  void fucomi(int i);
 
1295
  void fucomip();
 
1296
 
 
1297
  void fcompp();
 
1298
  void fnstsw_ax();
 
1299
  void fwait();
 
1300
  void fnclex();
 
1301
 
 
1302
  void fsin();
 
1303
  void fcos();
 
1304
  void fptan();
 
1305
  void fyl2x();
 
1306
  void f2xm1();
 
1307
  void fscale();
 
1308
  void fninit();
 
1309
 
 
1310
  void frndint();
 
1311
 
 
1312
  void sahf();
 
1313
 
 
1314
  // SSE2 instructions
 
1315
  void movd(XMMRegister dst, Register src);
 
1316
  void movd(Register dst, XMMRegister src);
 
1317
  void movq(XMMRegister dst, Register src);
 
1318
  void movq(Register dst, XMMRegister src);
 
1319
  void movq(XMMRegister dst, XMMRegister src);
 
1320
  void extractps(Register dst, XMMRegister src, byte imm8);
 
1321
 
 
1322
  // Don't use this unless it's important to keep the
 
1323
  // top half of the destination register unchanged.
 
1324
  // Used movaps when moving double values and movq for integer
 
1325
  // values in xmm registers.
 
1326
  void movsd(XMMRegister dst, XMMRegister src);
 
1327
 
 
1328
  void movsd(const Operand& dst, XMMRegister src);
 
1329
  void movsd(XMMRegister dst, const Operand& src);
 
1330
 
 
1331
  void movdqa(const Operand& dst, XMMRegister src);
 
1332
  void movdqa(XMMRegister dst, const Operand& src);
 
1333
 
 
1334
  void movapd(XMMRegister dst, XMMRegister src);
 
1335
  void movaps(XMMRegister dst, XMMRegister src);
 
1336
 
 
1337
  void movss(XMMRegister dst, const Operand& src);
 
1338
  void movss(const Operand& dst, XMMRegister src);
 
1339
 
 
1340
  void cvttss2si(Register dst, const Operand& src);
 
1341
  void cvttss2si(Register dst, XMMRegister src);
 
1342
  void cvttsd2si(Register dst, const Operand& src);
 
1343
  void cvttsd2si(Register dst, XMMRegister src);
 
1344
  void cvttsd2siq(Register dst, XMMRegister src);
 
1345
 
 
1346
  void cvtlsi2sd(XMMRegister dst, const Operand& src);
 
1347
  void cvtlsi2sd(XMMRegister dst, Register src);
 
1348
  void cvtqsi2sd(XMMRegister dst, const Operand& src);
 
1349
  void cvtqsi2sd(XMMRegister dst, Register src);
 
1350
 
 
1351
  void cvtlsi2ss(XMMRegister dst, Register src);
 
1352
 
 
1353
  void cvtss2sd(XMMRegister dst, XMMRegister src);
 
1354
  void cvtss2sd(XMMRegister dst, const Operand& src);
 
1355
  void cvtsd2ss(XMMRegister dst, XMMRegister src);
 
1356
 
 
1357
  void cvtsd2si(Register dst, XMMRegister src);
 
1358
  void cvtsd2siq(Register dst, XMMRegister src);
 
1359
 
 
1360
  void addsd(XMMRegister dst, XMMRegister src);
 
1361
  void subsd(XMMRegister dst, XMMRegister src);
 
1362
  void mulsd(XMMRegister dst, XMMRegister src);
 
1363
  void divsd(XMMRegister dst, XMMRegister src);
 
1364
 
 
1365
  void andpd(XMMRegister dst, XMMRegister src);
 
1366
  void orpd(XMMRegister dst, XMMRegister src);
 
1367
  void xorpd(XMMRegister dst, XMMRegister src);
 
1368
  void xorps(XMMRegister dst, XMMRegister src);
 
1369
  void sqrtsd(XMMRegister dst, XMMRegister src);
 
1370
 
 
1371
  void ucomisd(XMMRegister dst, XMMRegister src);
 
1372
  void ucomisd(XMMRegister dst, const Operand& src);
 
1373
 
 
1374
  enum RoundingMode {
 
1375
    kRoundToNearest = 0x0,
 
1376
    kRoundDown      = 0x1,
 
1377
    kRoundUp        = 0x2,
 
1378
    kRoundToZero    = 0x3
 
1379
  };
 
1380
 
 
1381
  void roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode);
 
1382
 
 
1383
  void movmskpd(Register dst, XMMRegister src);
 
1384
 
 
1385
  // The first argument is the reg field, the second argument is the r/m field.
 
1386
  void emit_sse_operand(XMMRegister dst, XMMRegister src);
 
1387
  void emit_sse_operand(XMMRegister reg, const Operand& adr);
 
1388
  void emit_sse_operand(XMMRegister dst, Register src);
 
1389
  void emit_sse_operand(Register dst, XMMRegister src);
 
1390
 
 
1391
  // Debugging
 
1392
  void Print();
 
1393
 
 
1394
  // Check the code size generated from label to here.
 
1395
  int SizeOfCodeGeneratedSince(Label* label) {
 
1396
    return pc_offset() - label->pos();
 
1397
  }
 
1398
 
 
1399
  // Mark address of the ExitJSFrame code.
 
1400
  void RecordJSReturn();
 
1401
 
 
1402
  // Mark address of a debug break slot.
 
1403
  void RecordDebugBreakSlot();
 
1404
 
 
1405
  // Record a comment relocation entry that can be used by a disassembler.
 
1406
  // Use --code-comments to enable.
 
1407
  void RecordComment(const char* msg, bool force = false);
 
1408
 
 
1409
  // Writes a single word of data in the code stream.
 
1410
  // Used for inline tables, e.g., jump-tables.
 
1411
  void db(uint8_t data);
 
1412
  void dd(uint32_t data);
 
1413
 
 
1414
  int pc_offset() const { return static_cast<int>(pc_ - buffer_); }
 
1415
 
 
1416
  PositionsRecorder* positions_recorder() { return &positions_recorder_; }
 
1417
 
 
1418
  // Check if there is less than kGap bytes available in the buffer.
 
1419
  // If this is the case, we need to grow the buffer before emitting
 
1420
  // an instruction or relocation information.
 
1421
  inline bool buffer_overflow() const {
 
1422
    return pc_ >= reloc_info_writer.pos() - kGap;
 
1423
  }
 
1424
 
 
1425
  // Get the number of bytes available in the buffer.
 
1426
  inline int available_space() const {
 
1427
    return static_cast<int>(reloc_info_writer.pos() - pc_);
 
1428
  }
 
1429
 
 
1430
  static bool IsNop(Address addr);
 
1431
 
 
1432
  // Avoid overflows for displacements etc.
 
1433
  static const int kMaximalBufferSize = 512*MB;
 
1434
  static const int kMinimalBufferSize = 4*KB;
 
1435
 
 
1436
  byte byte_at(int pos)  { return buffer_[pos]; }
 
1437
  void set_byte_at(int pos, byte value) { buffer_[pos] = value; }
 
1438
 
 
1439
 protected:
 
1440
  bool emit_debug_code() const { return emit_debug_code_; }
 
1441
  bool predictable_code_size() const { return predictable_code_size_; }
 
1442
 
 
1443
 private:
 
1444
  byte* addr_at(int pos)  { return buffer_ + pos; }
 
1445
  uint32_t long_at(int pos)  {
 
1446
    return *reinterpret_cast<uint32_t*>(addr_at(pos));
 
1447
  }
 
1448
  void long_at_put(int pos, uint32_t x)  {
 
1449
    *reinterpret_cast<uint32_t*>(addr_at(pos)) = x;
 
1450
  }
 
1451
 
 
1452
  // code emission
 
1453
  void GrowBuffer();
 
1454
 
 
1455
  void emit(byte x) { *pc_++ = x; }
 
1456
  inline void emitl(uint32_t x);
 
1457
  inline void emitq(uint64_t x, RelocInfo::Mode rmode);
 
1458
  inline void emitw(uint16_t x);
 
1459
  inline void emit_code_target(Handle<Code> target,
 
1460
                               RelocInfo::Mode rmode,
 
1461
                               unsigned ast_id = kNoASTId);
 
1462
  void emit(Immediate x) { emitl(x.value_); }
 
1463
 
 
1464
  // Emits a REX prefix that encodes a 64-bit operand size and
 
1465
  // the top bit of both register codes.
 
1466
  // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
 
1467
  // REX.W is set.
 
1468
  inline void emit_rex_64(XMMRegister reg, Register rm_reg);
 
1469
  inline void emit_rex_64(Register reg, XMMRegister rm_reg);
 
1470
  inline void emit_rex_64(Register reg, Register rm_reg);
 
1471
 
 
1472
  // Emits a REX prefix that encodes a 64-bit operand size and
 
1473
  // the top bit of the destination, index, and base register codes.
 
1474
  // The high bit of reg is used for REX.R, the high bit of op's base
 
1475
  // register is used for REX.B, and the high bit of op's index register
 
1476
  // is used for REX.X.  REX.W is set.
 
1477
  inline void emit_rex_64(Register reg, const Operand& op);
 
1478
  inline void emit_rex_64(XMMRegister reg, const Operand& op);
 
1479
 
 
1480
  // Emits a REX prefix that encodes a 64-bit operand size and
 
1481
  // the top bit of the register code.
 
1482
  // The high bit of register is used for REX.B.
 
1483
  // REX.W is set and REX.R and REX.X are clear.
 
1484
  inline void emit_rex_64(Register rm_reg);
 
1485
 
 
1486
  // Emits a REX prefix that encodes a 64-bit operand size and
 
1487
  // the top bit of the index and base register codes.
 
1488
  // The high bit of op's base register is used for REX.B, and the high
 
1489
  // bit of op's index register is used for REX.X.
 
1490
  // REX.W is set and REX.R clear.
 
1491
  inline void emit_rex_64(const Operand& op);
 
1492
 
 
1493
  // Emit a REX prefix that only sets REX.W to choose a 64-bit operand size.
 
1494
  void emit_rex_64() { emit(0x48); }
 
1495
 
 
1496
  // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
 
1497
  // REX.W is clear.
 
1498
  inline void emit_rex_32(Register reg, Register rm_reg);
 
1499
 
 
1500
  // The high bit of reg is used for REX.R, the high bit of op's base
 
1501
  // register is used for REX.B, and the high bit of op's index register
 
1502
  // is used for REX.X.  REX.W is cleared.
 
1503
  inline void emit_rex_32(Register reg, const Operand& op);
 
1504
 
 
1505
  // High bit of rm_reg goes to REX.B.
 
1506
  // REX.W, REX.R and REX.X are clear.
 
1507
  inline void emit_rex_32(Register rm_reg);
 
1508
 
 
1509
  // High bit of base goes to REX.B and high bit of index to REX.X.
 
1510
  // REX.W and REX.R are clear.
 
1511
  inline void emit_rex_32(const Operand& op);
 
1512
 
 
1513
  // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
 
1514
  // REX.W is cleared.  If no REX bits are set, no byte is emitted.
 
1515
  inline void emit_optional_rex_32(Register reg, Register rm_reg);
 
1516
 
 
1517
  // The high bit of reg is used for REX.R, the high bit of op's base
 
1518
  // register is used for REX.B, and the high bit of op's index register
 
1519
  // is used for REX.X.  REX.W is cleared.  If no REX bits are set, nothing
 
1520
  // is emitted.
 
1521
  inline void emit_optional_rex_32(Register reg, const Operand& op);
 
1522
 
 
1523
  // As for emit_optional_rex_32(Register, Register), except that
 
1524
  // the registers are XMM registers.
 
1525
  inline void emit_optional_rex_32(XMMRegister reg, XMMRegister base);
 
1526
 
 
1527
  // As for emit_optional_rex_32(Register, Register), except that
 
1528
  // one of the registers is an XMM registers.
 
1529
  inline void emit_optional_rex_32(XMMRegister reg, Register base);
 
1530
 
 
1531
  // As for emit_optional_rex_32(Register, Register), except that
 
1532
  // one of the registers is an XMM registers.
 
1533
  inline void emit_optional_rex_32(Register reg, XMMRegister base);
 
1534
 
 
1535
  // As for emit_optional_rex_32(Register, const Operand&), except that
 
1536
  // the register is an XMM register.
 
1537
  inline void emit_optional_rex_32(XMMRegister reg, const Operand& op);
 
1538
 
 
1539
  // Optionally do as emit_rex_32(Register) if the register number has
 
1540
  // the high bit set.
 
1541
  inline void emit_optional_rex_32(Register rm_reg);
 
1542
 
 
1543
  // Optionally do as emit_rex_32(const Operand&) if the operand register
 
1544
  // numbers have a high bit set.
 
1545
  inline void emit_optional_rex_32(const Operand& op);
 
1546
 
 
1547
 
 
1548
  // Emit the ModR/M byte, and optionally the SIB byte and
 
1549
  // 1- or 4-byte offset for a memory operand.  Also encodes
 
1550
  // the second operand of the operation, a register or operation
 
1551
  // subcode, into the reg field of the ModR/M byte.
 
1552
  void emit_operand(Register reg, const Operand& adr) {
 
1553
    emit_operand(reg.low_bits(), adr);
 
1554
  }
 
1555
 
 
1556
  // Emit the ModR/M byte, and optionally the SIB byte and
 
1557
  // 1- or 4-byte offset for a memory operand.  Also used to encode
 
1558
  // a three-bit opcode extension into the ModR/M byte.
 
1559
  void emit_operand(int rm, const Operand& adr);
 
1560
 
 
1561
  // Emit a ModR/M byte with registers coded in the reg and rm_reg fields.
 
1562
  void emit_modrm(Register reg, Register rm_reg) {
 
1563
    emit(0xC0 | reg.low_bits() << 3 | rm_reg.low_bits());
 
1564
  }
 
1565
 
 
1566
  // Emit a ModR/M byte with an operation subcode in the reg field and
 
1567
  // a register in the rm_reg field.
 
1568
  void emit_modrm(int code, Register rm_reg) {
 
1569
    ASSERT(is_uint3(code));
 
1570
    emit(0xC0 | code << 3 | rm_reg.low_bits());
 
1571
  }
 
1572
 
 
1573
  // Emit the code-object-relative offset of the label's position
 
1574
  inline void emit_code_relative_offset(Label* label);
 
1575
 
 
1576
  // Emit machine code for one of the operations ADD, ADC, SUB, SBC,
 
1577
  // AND, OR, XOR, or CMP.  The encodings of these operations are all
 
1578
  // similar, differing just in the opcode or in the reg field of the
 
1579
  // ModR/M byte.
 
1580
  void arithmetic_op_16(byte opcode, Register reg, Register rm_reg);
 
1581
  void arithmetic_op_16(byte opcode, Register reg, const Operand& rm_reg);
 
1582
  void arithmetic_op_32(byte opcode, Register reg, Register rm_reg);
 
1583
  void arithmetic_op_32(byte opcode, Register reg, const Operand& rm_reg);
 
1584
  void arithmetic_op(byte opcode, Register reg, Register rm_reg);
 
1585
  void arithmetic_op(byte opcode, Register reg, const Operand& rm_reg);
 
1586
  void immediate_arithmetic_op(byte subcode, Register dst, Immediate src);
 
1587
  void immediate_arithmetic_op(byte subcode, const Operand& dst, Immediate src);
 
1588
  // Operate on a byte in memory or register.
 
1589
  void immediate_arithmetic_op_8(byte subcode,
 
1590
                                 Register dst,
 
1591
                                 Immediate src);
 
1592
  void immediate_arithmetic_op_8(byte subcode,
 
1593
                                 const Operand& dst,
 
1594
                                 Immediate src);
 
1595
  // Operate on a word in memory or register.
 
1596
  void immediate_arithmetic_op_16(byte subcode,
 
1597
                                  Register dst,
 
1598
                                  Immediate src);
 
1599
  void immediate_arithmetic_op_16(byte subcode,
 
1600
                                  const Operand& dst,
 
1601
                                  Immediate src);
 
1602
  // Operate on a 32-bit word in memory or register.
 
1603
  void immediate_arithmetic_op_32(byte subcode,
 
1604
                                  Register dst,
 
1605
                                  Immediate src);
 
1606
  void immediate_arithmetic_op_32(byte subcode,
 
1607
                                  const Operand& dst,
 
1608
                                  Immediate src);
 
1609
 
 
1610
  // Emit machine code for a shift operation.
 
1611
  void shift(Register dst, Immediate shift_amount, int subcode);
 
1612
  void shift_32(Register dst, Immediate shift_amount, int subcode);
 
1613
  // Shift dst by cl % 64 bits.
 
1614
  void shift(Register dst, int subcode);
 
1615
  void shift_32(Register dst, int subcode);
 
1616
 
 
1617
  void emit_farith(int b1, int b2, int i);
 
1618
 
 
1619
  // labels
 
1620
  // void print(Label* L);
 
1621
  void bind_to(Label* L, int pos);
 
1622
 
 
1623
  // record reloc info for current pc_
 
1624
  void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
 
1625
 
 
1626
  friend class CodePatcher;
 
1627
  friend class EnsureSpace;
 
1628
  friend class RegExpMacroAssemblerX64;
 
1629
 
 
1630
  // Code buffer:
 
1631
  // The buffer into which code and relocation info are generated.
 
1632
  byte* buffer_;
 
1633
  int buffer_size_;
 
1634
  // True if the assembler owns the buffer, false if buffer is external.
 
1635
  bool own_buffer_;
 
1636
 
 
1637
  // code generation
 
1638
  byte* pc_;  // the program counter; moves forward
 
1639
  RelocInfoWriter reloc_info_writer;
 
1640
 
 
1641
  List< Handle<Code> > code_targets_;
 
1642
 
 
1643
  PositionsRecorder positions_recorder_;
 
1644
 
 
1645
  bool emit_debug_code_;
 
1646
  bool predictable_code_size_;
 
1647
 
 
1648
  friend class PositionsRecorder;
 
1649
};
 
1650
 
 
1651
 
 
1652
// Helper class that ensures that there is enough space for generating
 
1653
// instructions and relocation information.  The constructor makes
 
1654
// sure that there is enough space and (in debug mode) the destructor
 
1655
// checks that we did not generate too much.
 
1656
class EnsureSpace BASE_EMBEDDED {
 
1657
 public:
 
1658
  explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) {
 
1659
    if (assembler_->buffer_overflow()) assembler_->GrowBuffer();
 
1660
#ifdef DEBUG
 
1661
    space_before_ = assembler_->available_space();
 
1662
#endif
 
1663
  }
 
1664
 
 
1665
#ifdef DEBUG
 
1666
  ~EnsureSpace() {
 
1667
    int bytes_generated = space_before_ - assembler_->available_space();
 
1668
    ASSERT(bytes_generated < assembler_->kGap);
 
1669
  }
 
1670
#endif
 
1671
 
 
1672
 private:
 
1673
  Assembler* assembler_;
 
1674
#ifdef DEBUG
 
1675
  int space_before_;
 
1676
#endif
 
1677
};
 
1678
 
 
1679
} }  // namespace v8::internal
 
1680
 
 
1681
#endif  // V8_X64_ASSEMBLER_X64_H_