blob: a7759c32e16a6300a5501174593c6330d9a3e89a [file] [log] [blame]
Steve Blocka7e24c12009-10-30 11:49:00 +00001// 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.
Ben Murdoch3ef787d2012-04-12 10:51:47 +010033// Copyright 2012 the V8 project authors. All rights reserved.
Steve Blocka7e24c12009-10-30 11:49:00 +000034
35// A lightweight X64 Assembler.
36
37#ifndef V8_X64_ASSEMBLER_X64_H_
38#define V8_X64_ASSEMBLER_X64_H_
39
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000040#include <deque>
41
42#include "src/assembler.h"
Steve Blockd0582a62009-12-15 09:54:21 +000043
Steve Blocka7e24c12009-10-30 11:49:00 +000044namespace v8 {
45namespace internal {
46
47// Utility functions
48
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000049#define GENERAL_REGISTERS(V) \
50 V(rax) \
51 V(rcx) \
52 V(rdx) \
53 V(rbx) \
54 V(rsp) \
55 V(rbp) \
56 V(rsi) \
57 V(rdi) \
58 V(r8) \
59 V(r9) \
60 V(r10) \
61 V(r11) \
62 V(r12) \
63 V(r13) \
64 V(r14) \
65 V(r15)
66
67#define ALLOCATABLE_GENERAL_REGISTERS(V) \
68 V(rax) \
69 V(rbx) \
70 V(rdx) \
71 V(rcx) \
72 V(rsi) \
73 V(rdi) \
74 V(r8) \
75 V(r9) \
76 V(r11) \
77 V(r12) \
78 V(r14) \
79 V(r15)
80
81
Steve Blocka7e24c12009-10-30 11:49:00 +000082// CPU Registers.
83//
84// 1) We would prefer to use an enum, but enum values are assignment-
85// compatible with int, which has caused code-generation bugs.
86//
87// 2) We would prefer to use a class instead of a struct but we don't like
88// the register initialization to depend on the particular initialization
89// order (which appears to be different on OS X, Linux, and Windows for the
90// installed versions of C++ we tried). Using a struct permits C-style
91// "initialization". Also, the Register objects cannot be const as this
92// forces initialization stubs in MSVC, making us dependent on initialization
93// order.
94//
95// 3) By not using an enum, we are possibly preventing the compiler from
96// doing certain constant folds, which may significantly reduce the
97// code generated for some assembly instructions (because they boil down
98// to a few constants). If this is a problem, we could change the code
99// such that we use an enum in optimized mode, and the struct in debug
100// mode. This way we get the compile-time error checking in debug mode
101// and best performance in optimized code.
102//
Steve Blocka7e24c12009-10-30 11:49:00 +0000103struct Register {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000104 enum Code {
105#define REGISTER_CODE(R) kCode_##R,
106 GENERAL_REGISTERS(REGISTER_CODE)
107#undef REGISTER_CODE
108 kAfterLast,
109 kCode_no_reg = -1
110 };
Ben Murdochb0fe1622011-05-05 13:52:32 +0100111
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000112 static const int kNumRegisters = Code::kAfterLast;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100113
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000114 static Register from_code(int code) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000115 DCHECK(code >= 0);
116 DCHECK(code < kNumRegisters);
117 Register r = {code};
Steve Blocka7e24c12009-10-30 11:49:00 +0000118 return r;
119 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000120 bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
121 bool is(Register reg) const { return reg_code == reg.reg_code; }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100122 int code() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000123 DCHECK(is_valid());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000124 return reg_code;
Steve Blocka7e24c12009-10-30 11:49:00 +0000125 }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100126 int bit() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000127 DCHECK(is_valid());
128 return 1 << reg_code;
Steve Blocka7e24c12009-10-30 11:49:00 +0000129 }
130
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000131 bool is_byte_register() const { return reg_code <= 3; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000132 // Return the high bit of the register code as a 0 or 1. Used often
133 // when constructing the REX prefix byte.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000134 int high_bit() const { return reg_code >> 3; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000135 // Return the 3 low bits of the register code. Used when encoding registers
136 // in modR/M, SIB, and opcode bytes.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000137 int low_bits() const { return reg_code & 0x7; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000138
Andrei Popescu31002712010-02-23 13:46:05 +0000139 // Unfortunately we can't make this private in a struct when initializing
140 // by assignment.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000141 int reg_code;
Steve Blocka7e24c12009-10-30 11:49:00 +0000142};
143
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100144
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000145#define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R};
146GENERAL_REGISTERS(DECLARE_REGISTER)
147#undef DECLARE_REGISTER
148const Register no_reg = {Register::kCode_no_reg};
149
Steve Blocka7e24c12009-10-30 11:49:00 +0000150
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000151#ifdef _WIN64
152 // Windows calling convention
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000153const Register arg_reg_1 = {Register::kCode_rcx};
154const Register arg_reg_2 = {Register::kCode_rdx};
155const Register arg_reg_3 = {Register::kCode_r8};
156const Register arg_reg_4 = {Register::kCode_r9};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000157#else
158 // AMD64 calling convention
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000159const Register arg_reg_1 = {Register::kCode_rdi};
160const Register arg_reg_2 = {Register::kCode_rsi};
161const Register arg_reg_3 = {Register::kCode_rdx};
162const Register arg_reg_4 = {Register::kCode_rcx};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000163#endif // _WIN64
Steve Blocka7e24c12009-10-30 11:49:00 +0000164
Ben Murdochb0fe1622011-05-05 13:52:32 +0100165
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000166#define DOUBLE_REGISTERS(V) \
167 V(xmm0) \
168 V(xmm1) \
169 V(xmm2) \
170 V(xmm3) \
171 V(xmm4) \
172 V(xmm5) \
173 V(xmm6) \
174 V(xmm7) \
175 V(xmm8) \
176 V(xmm9) \
177 V(xmm10) \
178 V(xmm11) \
179 V(xmm12) \
180 V(xmm13) \
181 V(xmm14) \
182 V(xmm15)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400183
Ben Murdochc5610432016-08-08 18:44:38 +0100184#define FLOAT_REGISTERS DOUBLE_REGISTERS
185
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000186#define ALLOCATABLE_DOUBLE_REGISTERS(V) \
Ben Murdoch61f157c2016-09-16 13:49:30 +0100187 V(xmm0) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000188 V(xmm1) \
189 V(xmm2) \
190 V(xmm3) \
191 V(xmm4) \
192 V(xmm5) \
193 V(xmm6) \
194 V(xmm7) \
195 V(xmm8) \
196 V(xmm9) \
197 V(xmm10) \
198 V(xmm11) \
199 V(xmm12) \
200 V(xmm13) \
Ben Murdoch61f157c2016-09-16 13:49:30 +0100201 V(xmm14)
202
203static const bool kSimpleFPAliasing = true;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100204
Ben Murdochc5610432016-08-08 18:44:38 +0100205struct XMMRegister {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000206 enum Code {
207#define REGISTER_CODE(R) kCode_##R,
208 DOUBLE_REGISTERS(REGISTER_CODE)
209#undef REGISTER_CODE
210 kAfterLast,
211 kCode_no_reg = -1
212 };
213
214 static const int kMaxNumRegisters = Code::kAfterLast;
215
Ben Murdochc5610432016-08-08 18:44:38 +0100216 static XMMRegister from_code(int code) {
217 XMMRegister result = {code};
Ben Murdochb8e0da22011-05-16 14:20:40 +0100218 return result;
219 }
220
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000221 bool is_valid() const { return 0 <= reg_code && reg_code < kMaxNumRegisters; }
Ben Murdochc5610432016-08-08 18:44:38 +0100222 bool is(XMMRegister reg) const { return reg_code == reg.reg_code; }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100223 int code() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000224 DCHECK(is_valid());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000225 return reg_code;
Steve Blocka7e24c12009-10-30 11:49:00 +0000226 }
227
228 // Return the high bit of the register code as a 0 or 1. Used often
229 // when constructing the REX prefix byte.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000230 int high_bit() const { return reg_code >> 3; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000231 // Return the 3 low bits of the register code. Used when encoding registers
232 // in modR/M, SIB, and opcode bytes.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000233 int low_bits() const { return reg_code & 0x7; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000234
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000235 // Unfortunately we can't make this private in a struct when initializing
236 // by assignment.
237 int reg_code;
Steve Blocka7e24c12009-10-30 11:49:00 +0000238};
239
Ben Murdochc5610432016-08-08 18:44:38 +0100240typedef XMMRegister FloatRegister;
241
242typedef XMMRegister DoubleRegister;
243
244typedef XMMRegister Simd128Register;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000245
246#define DECLARE_REGISTER(R) \
247 const DoubleRegister R = {DoubleRegister::kCode_##R};
248DOUBLE_REGISTERS(DECLARE_REGISTER)
249#undef DECLARE_REGISTER
250const DoubleRegister no_double_reg = {DoubleRegister::kCode_no_reg};
Steve Blocka7e24c12009-10-30 11:49:00 +0000251
252enum Condition {
253 // any value < 0 is considered no_condition
254 no_condition = -1,
255
256 overflow = 0,
257 no_overflow = 1,
258 below = 2,
259 above_equal = 3,
260 equal = 4,
261 not_equal = 5,
262 below_equal = 6,
263 above = 7,
264 negative = 8,
265 positive = 9,
266 parity_even = 10,
267 parity_odd = 11,
268 less = 12,
269 greater_equal = 13,
270 less_equal = 14,
271 greater = 15,
272
Steve Block3ce2e202009-11-05 08:53:23 +0000273 // Fake conditions that are handled by the
274 // opcodes using them.
275 always = 16,
276 never = 17,
Steve Blocka7e24c12009-10-30 11:49:00 +0000277 // aliases
278 carry = below,
279 not_carry = above_equal,
280 zero = equal,
281 not_zero = not_equal,
282 sign = negative,
Steve Block3ce2e202009-11-05 08:53:23 +0000283 not_sign = positive,
284 last_condition = greater
Steve Blocka7e24c12009-10-30 11:49:00 +0000285};
286
287
288// Returns the equivalent of !cc.
289// Negation of the default no_condition (-1) results in a non-default
290// no_condition value (-2). As long as tests for no_condition check
291// for condition < 0, this will work as expected.
Kristian Monsen9dcf7e22010-06-28 14:14:28 +0100292inline Condition NegateCondition(Condition cc) {
293 return static_cast<Condition>(cc ^ 1);
294}
295
Steve Blocka7e24c12009-10-30 11:49:00 +0000296
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000297// Commute a condition such that {a cond b == b cond' a}.
298inline Condition CommuteCondition(Condition cc) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000299 switch (cc) {
300 case below:
301 return above;
302 case above:
303 return below;
304 case above_equal:
305 return below_equal;
306 case below_equal:
307 return above_equal;
308 case less:
309 return greater;
310 case greater:
311 return less;
312 case greater_equal:
313 return less_equal;
314 case less_equal:
315 return greater_equal;
316 default:
317 return cc;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000318 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000319}
320
Kristian Monsen9dcf7e22010-06-28 14:14:28 +0100321
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000322enum RoundingMode {
323 kRoundToNearest = 0x0,
324 kRoundDown = 0x1,
325 kRoundUp = 0x2,
326 kRoundToZero = 0x3
327};
328
329
Steve Blocka7e24c12009-10-30 11:49:00 +0000330// -----------------------------------------------------------------------------
331// Machine instruction Immediates
332
333class Immediate BASE_EMBEDDED {
334 public:
335 explicit Immediate(int32_t value) : value_(value) {}
Ben Murdochc5610432016-08-08 18:44:38 +0100336 explicit Immediate(int32_t value, RelocInfo::Mode rmode)
337 : value_(value), rmode_(rmode) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000338 explicit Immediate(Smi* value) {
339 DCHECK(SmiValuesAre31Bits()); // Only available for 31-bit SMI.
340 value_ = static_cast<int32_t>(reinterpret_cast<intptr_t>(value));
341 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000342
343 private:
344 int32_t value_;
Ben Murdochc5610432016-08-08 18:44:38 +0100345 RelocInfo::Mode rmode_ = RelocInfo::NONE32;
Steve Blocka7e24c12009-10-30 11:49:00 +0000346
347 friend class Assembler;
348};
349
350
351// -----------------------------------------------------------------------------
352// Machine instruction Operands
353
354enum ScaleFactor {
355 times_1 = 0,
356 times_2 = 1,
357 times_4 = 2,
358 times_8 = 3,
359 times_int_size = times_4,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000360 times_pointer_size = (kPointerSize == 8) ? times_8 : times_4
Steve Blocka7e24c12009-10-30 11:49:00 +0000361};
362
363
364class Operand BASE_EMBEDDED {
365 public:
366 // [base + disp/r]
367 Operand(Register base, int32_t disp);
368
369 // [base + index*scale + disp/r]
370 Operand(Register base,
371 Register index,
372 ScaleFactor scale,
373 int32_t disp);
374
375 // [index*scale + disp/r]
376 Operand(Register index,
377 ScaleFactor scale,
378 int32_t disp);
379
Leon Clarkef7060e22010-06-03 12:02:55 +0100380 // Offset from existing memory operand.
381 // Offset is added to existing displacement as 32-bit signed values and
382 // this must not overflow.
383 Operand(const Operand& base, int32_t offset);
384
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000385 // [rip + disp/r]
386 explicit Operand(Label* label);
387
Steve Block1e0659c2011-05-24 12:43:12 +0100388 // Checks whether either base or index register is the given register.
389 // Does not check the "reg" part of the Operand.
390 bool AddressUsesRegister(Register reg) const;
391
Steve Block44f0eee2011-05-26 01:26:41 +0100392 // Queries related to the size of the generated instruction.
393 // Whether the generated instruction will have a REX prefix.
394 bool requires_rex() const { return rex_ != 0; }
395 // Size of the ModR/M, SIB and displacement parts of the generated
396 // instruction.
397 int operand_size() const { return len_; }
398
Steve Blocka7e24c12009-10-30 11:49:00 +0000399 private:
400 byte rex_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000401 byte buf_[9];
Steve Block1e0659c2011-05-24 12:43:12 +0100402 // The number of bytes of buf_ in use.
403 byte len_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000404
405 // Set the ModR/M byte without an encoded 'reg' register. The
406 // register is encoded later as part of the emit_operand operation.
407 // set_modrm can be called before or after set_sib and set_disp*.
408 inline void set_modrm(int mod, Register rm);
409
410 // Set the SIB byte if one is needed. Sets the length to 2 rather than 1.
411 inline void set_sib(ScaleFactor scale, Register index, Register base);
412
413 // Adds operand displacement fields (offsets added to the memory address).
414 // Needs to be called after set_sib, not before it.
415 inline void set_disp8(int disp);
416 inline void set_disp32(int disp);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000417 inline void set_disp64(int64_t disp); // for labels.
Steve Blocka7e24c12009-10-30 11:49:00 +0000418
419 friend class Assembler;
420};
421
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000422#define ASSEMBLER_INSTRUCTION_LIST(V) \
423 V(add) \
424 V(and) \
425 V(cmp) \
Ben Murdoch61f157c2016-09-16 13:49:30 +0100426 V(cmpxchg) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000427 V(dec) \
428 V(idiv) \
429 V(div) \
430 V(imul) \
431 V(inc) \
432 V(lea) \
433 V(mov) \
434 V(movzxb) \
435 V(movzxw) \
436 V(neg) \
437 V(not) \
438 V(or) \
439 V(repmovs) \
440 V(sbb) \
441 V(sub) \
442 V(test) \
443 V(xchg) \
444 V(xor)
Steve Block44f0eee2011-05-26 01:26:41 +0100445
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000446// Shift instructions on operands/registers with kPointerSize, kInt32Size and
447// kInt64Size.
448#define SHIFT_INSTRUCTION_LIST(V) \
449 V(rol, 0x0) \
450 V(ror, 0x1) \
451 V(rcl, 0x2) \
452 V(rcr, 0x3) \
453 V(shl, 0x4) \
454 V(shr, 0x5) \
455 V(sar, 0x7) \
Steve Blocka7e24c12009-10-30 11:49:00 +0000456
457
Steve Block44f0eee2011-05-26 01:26:41 +0100458class Assembler : public AssemblerBase {
Steve Blocka7e24c12009-10-30 11:49:00 +0000459 private:
460 // We check before assembling an instruction that there is sufficient
461 // space to write an instruction and its relocation information.
462 // The relocation writer's position must be kGap bytes above the end of
463 // the generated instructions. This leaves enough space for the
464 // longest possible x64 instruction, 15 bytes, and the longest possible
465 // relocation information encoding, RelocInfoWriter::kMaxLength == 16.
466 // (There is a 15 byte limit on x64 instruction length that rules out some
467 // otherwise valid instructions.)
468 // This allows for a single, fast space check per instruction.
469 static const int kGap = 32;
470
471 public:
472 // Create an assembler. Instructions and relocation information are emitted
473 // into a buffer, with the instructions starting from the beginning and the
474 // relocation information starting from the end of the buffer. See CodeDesc
475 // for a detailed comment on the layout (globals.h).
476 //
477 // If the provided buffer is NULL, the assembler allocates and grows its own
478 // buffer, and buffer_size determines the initial buffer size. The buffer is
479 // owned by the assembler and deallocated upon destruction of the assembler.
480 //
481 // If the provided buffer is not NULL, the assembler uses the provided buffer
482 // for code generation and assumes its size to be buffer_size. If the buffer
483 // is too small, a fatal error occurs. No deallocation of the buffer is done
484 // upon destruction of the assembler.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100485 Assembler(Isolate* isolate, void* buffer, int buffer_size);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000486 virtual ~Assembler() { }
Steve Block44f0eee2011-05-26 01:26:41 +0100487
Steve Blocka7e24c12009-10-30 11:49:00 +0000488 // GetCode emits any pending (non-emitted) code and fills the descriptor
489 // desc. GetCode() is idempotent; it returns the same result if no other
490 // Assembler functions are invoked in between GetCode() calls.
491 void GetCode(CodeDesc* desc);
492
Steve Block3ce2e202009-11-05 08:53:23 +0000493 // Read/Modify the code target in the relative branch/call instruction at pc.
494 // On the x64 architecture, we use relative jumps with a 32-bit displacement
495 // to jump to other Code objects in the Code space in the heap.
496 // Jumps to C functions are done indirectly through a 64-bit register holding
497 // the absolute address of the target.
498 // These functions convert between absolute Addresses of Code objects and
499 // the relative displacements stored in the code.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000500 static inline Address target_address_at(Address pc, Address constant_pool);
501 static inline void set_target_address_at(
502 Isolate* isolate, Address pc, Address constant_pool, Address target,
503 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000504 static inline Address target_address_at(Address pc, Code* code) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000505 Address constant_pool = code ? code->constant_pool() : NULL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000506 return target_address_at(pc, constant_pool);
507 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000508 static inline void set_target_address_at(
509 Isolate* isolate, Address pc, Code* code, Address target,
510 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED) {
511 Address constant_pool = code ? code->constant_pool() : NULL;
512 set_target_address_at(isolate, pc, constant_pool, target,
513 icache_flush_mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000514 }
515
516 // Return the code target address at a call site from the return address
517 // of that call in the instruction stream.
518 static inline Address target_address_from_return_address(Address pc);
519
Steve Blockd0582a62009-12-15 09:54:21 +0000520 // This sets the branch destination (which is in the instruction on x64).
521 // This is for calls and branches within generated code.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100522 inline static void deserialization_set_special_target_at(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000523 Isolate* isolate, Address instruction_payload, Code* code,
524 Address target) {
525 set_target_address_at(isolate, instruction_payload, code, target);
Steve Blockd0582a62009-12-15 09:54:21 +0000526 }
527
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000528 // This sets the internal reference at the pc.
529 inline static void deserialization_set_target_internal_reference_at(
530 Isolate* isolate, Address pc, Address target,
531 RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
532
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000533 static inline RelocInfo::Mode RelocInfoNone() {
534 if (kPointerSize == kInt64Size) {
535 return RelocInfo::NONE64;
536 } else {
537 DCHECK(kPointerSize == kInt32Size);
538 return RelocInfo::NONE32;
539 }
Steve Blockd0582a62009-12-15 09:54:21 +0000540 }
541
Steve Block3ce2e202009-11-05 08:53:23 +0000542 inline Handle<Object> code_target_object_handle_at(Address pc);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000543 inline Address runtime_entry_at(Address pc);
Steve Blockd0582a62009-12-15 09:54:21 +0000544 // Number of bytes taken up by the branch target in the code.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100545 static const int kSpecialTargetSize = 4; // Use 32-bit displacement.
Steve Blocka7e24c12009-10-30 11:49:00 +0000546 // Distance between the address of the code target in the call instruction
Steve Block3ce2e202009-11-05 08:53:23 +0000547 // and the return address pushed on the stack.
548 static const int kCallTargetAddressOffset = 4; // Use 32-bit displacement.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000549 // The length of call(kScratchRegister).
550 static const int kCallScratchRegisterInstructionLength = 3;
551 // The length of call(Immediate32).
Steve Block1e0659c2011-05-24 12:43:12 +0100552 static const int kShortCallInstructionLength = 5;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000553 // The length of movq(kScratchRegister, address).
554 static const int kMoveAddressIntoScratchRegisterInstructionLength =
555 2 + kPointerSize;
556 // The length of movq(kScratchRegister, address) and call(kScratchRegister).
557 static const int kCallSequenceLength =
558 kMoveAddressIntoScratchRegisterInstructionLength +
559 kCallScratchRegisterInstructionLength;
Steve Blockd0582a62009-12-15 09:54:21 +0000560
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000561 // The debug break slot must be able to contain an indirect call sequence.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000562 static const int kDebugBreakSlotLength = kCallSequenceLength;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000563 // Distance between start of patched debug break slot and the emitted address
564 // to jump to.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000565 static const int kPatchDebugBreakSlotAddressOffset =
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000566 kMoveAddressIntoScratchRegisterInstructionLength - kPointerSize;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100567
Steve Block9fac8402011-05-12 15:51:54 +0100568 // One byte opcode for test eax,0xXXXXXXXX.
569 static const byte kTestEaxByte = 0xA9;
Steve Block1e0659c2011-05-24 12:43:12 +0100570 // One byte opcode for test al, 0xXX.
571 static const byte kTestAlByte = 0xA8;
572 // One byte opcode for nop.
573 static const byte kNopByte = 0x90;
574
575 // One byte prefix for a short conditional jump.
576 static const byte kJccShortPrefix = 0x70;
577 static const byte kJncShortOpcode = kJccShortPrefix | not_carry;
578 static const byte kJcShortOpcode = kJccShortPrefix | carry;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000579 static const byte kJnzShortOpcode = kJccShortPrefix | not_zero;
580 static const byte kJzShortOpcode = kJccShortPrefix | zero;
Steve Block1e0659c2011-05-24 12:43:12 +0100581
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000582 // VEX prefix encodings.
583 enum SIMDPrefix { kNone = 0x0, k66 = 0x1, kF3 = 0x2, kF2 = 0x3 };
584 enum VectorLength { kL128 = 0x0, kL256 = 0x4, kLIG = kL128, kLZ = kL128 };
585 enum VexW { kW0 = 0x0, kW1 = 0x80, kWIG = kW0 };
586 enum LeadingOpcode { k0F = 0x1, k0F38 = 0x2, k0F3A = 0x3 };
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100587
Steve Blocka7e24c12009-10-30 11:49:00 +0000588 // ---------------------------------------------------------------------------
589 // Code generation
590 //
591 // Function names correspond one-to-one to x64 instruction mnemonics.
592 // Unless specified otherwise, instructions operate on 64-bit operands.
593 //
594 // If we need versions of an assembly instruction that operate on different
595 // width arguments, we add a single-letter suffix specifying the width.
596 // This is done for the following instructions: mov, cmp, inc, dec,
597 // add, sub, and test.
598 // There are no versions of these instructions without the suffix.
599 // - Instructions on 8-bit (byte) operands/registers have a trailing 'b'.
600 // - Instructions on 16-bit (word) operands/registers have a trailing 'w'.
601 // - Instructions on 32-bit (doubleword) operands/registers use 'l'.
602 // - Instructions on 64-bit (quadword) operands/registers use 'q'.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000603 // - Instructions on operands/registers with pointer size use 'p'.
604
605 STATIC_ASSERT(kPointerSize == kInt64Size || kPointerSize == kInt32Size);
606
607#define DECLARE_INSTRUCTION(instruction) \
608 template<class P1> \
609 void instruction##p(P1 p1) { \
610 emit_##instruction(p1, kPointerSize); \
611 } \
612 \
613 template<class P1> \
614 void instruction##l(P1 p1) { \
615 emit_##instruction(p1, kInt32Size); \
616 } \
617 \
618 template<class P1> \
619 void instruction##q(P1 p1) { \
620 emit_##instruction(p1, kInt64Size); \
621 } \
622 \
623 template<class P1, class P2> \
624 void instruction##p(P1 p1, P2 p2) { \
625 emit_##instruction(p1, p2, kPointerSize); \
626 } \
627 \
628 template<class P1, class P2> \
629 void instruction##l(P1 p1, P2 p2) { \
630 emit_##instruction(p1, p2, kInt32Size); \
631 } \
632 \
633 template<class P1, class P2> \
634 void instruction##q(P1 p1, P2 p2) { \
635 emit_##instruction(p1, p2, kInt64Size); \
636 } \
637 \
638 template<class P1, class P2, class P3> \
639 void instruction##p(P1 p1, P2 p2, P3 p3) { \
640 emit_##instruction(p1, p2, p3, kPointerSize); \
641 } \
642 \
643 template<class P1, class P2, class P3> \
644 void instruction##l(P1 p1, P2 p2, P3 p3) { \
645 emit_##instruction(p1, p2, p3, kInt32Size); \
646 } \
647 \
648 template<class P1, class P2, class P3> \
649 void instruction##q(P1 p1, P2 p2, P3 p3) { \
650 emit_##instruction(p1, p2, p3, kInt64Size); \
651 }
652 ASSEMBLER_INSTRUCTION_LIST(DECLARE_INSTRUCTION)
653#undef DECLARE_INSTRUCTION
Steve Blocka7e24c12009-10-30 11:49:00 +0000654
655 // Insert the smallest number of nop instructions
656 // possible to align the pc offset to a multiple
Steve Block1e0659c2011-05-24 12:43:12 +0100657 // of m, where m must be a power of 2.
Steve Blocka7e24c12009-10-30 11:49:00 +0000658 void Align(int m);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000659 // Insert the smallest number of zero bytes possible to align the pc offset
660 // to a mulitple of m. m must be a power of 2 (>= 2).
661 void DataAlign(int m);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100662 void Nop(int bytes = 1);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +0100663 // Aligns code to something that's optimal for a jump target for the platform.
664 void CodeTargetAlign();
Steve Blocka7e24c12009-10-30 11:49:00 +0000665
666 // Stack
667 void pushfq();
668 void popfq();
669
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000670 void pushq(Immediate value);
Steve Block1e0659c2011-05-24 12:43:12 +0100671 // Push a 32 bit integer, and guarantee that it is actually pushed as a
672 // 32 bit value, the normal push will optimize the 8 bit case.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000673 void pushq_imm32(int32_t imm32);
674 void pushq(Register src);
675 void pushq(const Operand& src);
Steve Blocka7e24c12009-10-30 11:49:00 +0000676
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000677 void popq(Register dst);
678 void popq(const Operand& dst);
Steve Blocka7e24c12009-10-30 11:49:00 +0000679
680 void enter(Immediate size);
681 void leave();
682
683 // Moves
684 void movb(Register dst, const Operand& src);
685 void movb(Register dst, Immediate imm);
686 void movb(const Operand& dst, Register src);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000687 void movb(const Operand& dst, Immediate imm);
Steve Blocka7e24c12009-10-30 11:49:00 +0000688
Steve Block3ce2e202009-11-05 08:53:23 +0000689 // Move the low 16 bits of a 64-bit register value to a 16-bit
690 // memory location.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000691 void movw(Register dst, const Operand& src);
Steve Block3ce2e202009-11-05 08:53:23 +0000692 void movw(const Operand& dst, Register src);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000693 void movw(const Operand& dst, Immediate imm);
Steve Block3ce2e202009-11-05 08:53:23 +0000694
Steve Blocka7e24c12009-10-30 11:49:00 +0000695 // Move the offset of the label location relative to the current
696 // position (after the move) to the destination.
697 void movl(const Operand& dst, Label* src);
698
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000699 // Loads a pointer into a register with a relocation mode.
700 void movp(Register dst, void* ptr, RelocInfo::Mode rmode);
Steve Blocka7e24c12009-10-30 11:49:00 +0000701
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000702 // Loads a 64-bit immediate into a register.
Ben Murdochda12d292016-06-02 14:46:10 +0100703 void movq(Register dst, int64_t value,
704 RelocInfo::Mode rmode = RelocInfo::NONE64);
705 void movq(Register dst, uint64_t value,
706 RelocInfo::Mode rmode = RelocInfo::NONE64);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000707
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400708 void movsxbl(Register dst, Register src);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000709 void movsxbl(Register dst, const Operand& src);
Steve Block3ce2e202009-11-05 08:53:23 +0000710 void movsxbq(Register dst, const Operand& src);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400711 void movsxwl(Register dst, Register src);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000712 void movsxwl(Register dst, const Operand& src);
Steve Block3ce2e202009-11-05 08:53:23 +0000713 void movsxwq(Register dst, const Operand& src);
Steve Blocka7e24c12009-10-30 11:49:00 +0000714 void movsxlq(Register dst, Register src);
715 void movsxlq(Register dst, const Operand& src);
Steve Blocka7e24c12009-10-30 11:49:00 +0000716
Leon Clarked91b9f72010-01-27 17:25:45 +0000717 // Repeated moves.
718
719 void repmovsb();
720 void repmovsw();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000721 void repmovsp() { emit_repmovs(kPointerSize); }
722 void repmovsl() { emit_repmovs(kInt32Size); }
723 void repmovsq() { emit_repmovs(kInt64Size); }
Leon Clarked91b9f72010-01-27 17:25:45 +0000724
Steve Block44f0eee2011-05-26 01:26:41 +0100725 // Instruction to load from an immediate 64-bit pointer into RAX.
Steve Blocka7e24c12009-10-30 11:49:00 +0000726 void load_rax(void* ptr, RelocInfo::Mode rmode);
727 void load_rax(ExternalReference ext);
728
729 // Conditional moves.
730 void cmovq(Condition cc, Register dst, Register src);
731 void cmovq(Condition cc, Register dst, const Operand& src);
732 void cmovl(Condition cc, Register dst, Register src);
733 void cmovl(Condition cc, Register dst, const Operand& src);
734
Steve Blocka7e24c12009-10-30 11:49:00 +0000735 void cmpb(Register dst, Immediate src) {
736 immediate_arithmetic_op_8(0x7, dst, src);
737 }
738
739 void cmpb_al(Immediate src);
740
741 void cmpb(Register dst, Register src) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000742 arithmetic_op_8(0x3A, dst, src);
Steve Blocka7e24c12009-10-30 11:49:00 +0000743 }
744
745 void cmpb(Register dst, const Operand& src) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000746 arithmetic_op_8(0x3A, dst, src);
Steve Blocka7e24c12009-10-30 11:49:00 +0000747 }
748
749 void cmpb(const Operand& dst, Register src) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000750 arithmetic_op_8(0x38, src, dst);
Steve Blocka7e24c12009-10-30 11:49:00 +0000751 }
752
753 void cmpb(const Operand& dst, Immediate src) {
754 immediate_arithmetic_op_8(0x7, dst, src);
755 }
756
757 void cmpw(const Operand& dst, Immediate src) {
758 immediate_arithmetic_op_16(0x7, dst, src);
759 }
760
761 void cmpw(Register dst, Immediate src) {
762 immediate_arithmetic_op_16(0x7, dst, src);
763 }
764
765 void cmpw(Register dst, const Operand& src) {
766 arithmetic_op_16(0x3B, dst, src);
767 }
768
769 void cmpw(Register dst, Register src) {
770 arithmetic_op_16(0x3B, dst, src);
771 }
772
773 void cmpw(const Operand& dst, Register src) {
774 arithmetic_op_16(0x39, src, dst);
775 }
776
Ben Murdochda12d292016-06-02 14:46:10 +0100777 void testb(Register reg, const Operand& op) { testb(op, reg); }
778
779 void testw(Register reg, const Operand& op) { testw(op, reg); }
780
Leon Clarke4515c472010-02-03 11:58:03 +0000781 void andb(Register dst, Immediate src) {
782 immediate_arithmetic_op_8(0x4, dst, src);
783 }
Steve Block3ce2e202009-11-05 08:53:23 +0000784
Steve Block3ce2e202009-11-05 08:53:23 +0000785 void decb(Register dst);
786 void decb(const Operand& dst);
Steve Blocka7e24c12009-10-30 11:49:00 +0000787
Ben Murdoch61f157c2016-09-16 13:49:30 +0100788 // Lock prefix.
789 void lock();
790
Ben Murdochc5610432016-08-08 18:44:38 +0100791 void xchgb(Register reg, const Operand& op);
792 void xchgw(Register reg, const Operand& op);
793
Ben Murdoch61f157c2016-09-16 13:49:30 +0100794 void cmpxchgb(const Operand& dst, Register src);
795 void cmpxchgw(const Operand& dst, Register src);
796
Steve Blocka7e24c12009-10-30 11:49:00 +0000797 // Sign-extends rax into rdx:rax.
798 void cqo();
799 // Sign-extends eax into edx:eax.
800 void cdq();
801
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400802 // Multiply eax by src, put the result in edx:eax.
803 void mull(Register src);
804 void mull(const Operand& src);
Steve Blocka7e24c12009-10-30 11:49:00 +0000805 // Multiply rax by src, put the result in rdx:rax.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400806 void mulq(Register src);
Steve Blocka7e24c12009-10-30 11:49:00 +0000807
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400808#define DECLARE_SHIFT_INSTRUCTION(instruction, subcode) \
809 void instruction##p(Register dst, Immediate imm8) { \
810 shift(dst, imm8, subcode, kPointerSize); \
811 } \
812 \
813 void instruction##l(Register dst, Immediate imm8) { \
814 shift(dst, imm8, subcode, kInt32Size); \
815 } \
816 \
817 void instruction##q(Register dst, Immediate imm8) { \
818 shift(dst, imm8, subcode, kInt64Size); \
819 } \
820 \
821 void instruction##p(Operand dst, Immediate imm8) { \
822 shift(dst, imm8, subcode, kPointerSize); \
823 } \
824 \
825 void instruction##l(Operand dst, Immediate imm8) { \
826 shift(dst, imm8, subcode, kInt32Size); \
827 } \
828 \
829 void instruction##q(Operand dst, Immediate imm8) { \
830 shift(dst, imm8, subcode, kInt64Size); \
831 } \
832 \
833 void instruction##p_cl(Register dst) { shift(dst, subcode, kPointerSize); } \
834 \
835 void instruction##l_cl(Register dst) { shift(dst, subcode, kInt32Size); } \
836 \
837 void instruction##q_cl(Register dst) { shift(dst, subcode, kInt64Size); } \
838 \
839 void instruction##p_cl(Operand dst) { shift(dst, subcode, kPointerSize); } \
840 \
841 void instruction##l_cl(Operand dst) { shift(dst, subcode, kInt32Size); } \
842 \
843 void instruction##q_cl(Operand dst) { shift(dst, subcode, kInt64Size); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000844 SHIFT_INSTRUCTION_LIST(DECLARE_SHIFT_INSTRUCTION)
845#undef DECLARE_SHIFT_INSTRUCTION
Steve Blocka7e24c12009-10-30 11:49:00 +0000846
847 // Shifts dst:src left by cl bits, affecting only dst.
848 void shld(Register dst, Register src);
849
850 // Shifts src:dst right by cl bits, affecting only dst.
851 void shrd(Register dst, Register src);
852
Steve Blocka7e24c12009-10-30 11:49:00 +0000853 void store_rax(void* dst, RelocInfo::Mode mode);
854 void store_rax(ExternalReference ref);
855
Steve Blocka7e24c12009-10-30 11:49:00 +0000856 void subb(Register dst, Immediate src) {
857 immediate_arithmetic_op_8(0x5, dst, src);
858 }
859
Steve Block3ce2e202009-11-05 08:53:23 +0000860 void testb(Register dst, Register src);
Steve Blocka7e24c12009-10-30 11:49:00 +0000861 void testb(Register reg, Immediate mask);
862 void testb(const Operand& op, Immediate mask);
Leon Clarkee46be812010-01-19 14:06:41 +0000863 void testb(const Operand& op, Register reg);
Steve Blocka7e24c12009-10-30 11:49:00 +0000864
Ben Murdochda12d292016-06-02 14:46:10 +0100865 void testw(Register dst, Register src);
866 void testw(Register reg, Immediate mask);
867 void testw(const Operand& op, Immediate mask);
868 void testw(const Operand& op, Register reg);
869
Steve Blocka7e24c12009-10-30 11:49:00 +0000870 // Bit operations.
871 void bt(const Operand& dst, Register src);
872 void bts(const Operand& dst, Register src);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000873 void bsrq(Register dst, Register src);
874 void bsrq(Register dst, const Operand& src);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000875 void bsrl(Register dst, Register src);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000876 void bsrl(Register dst, const Operand& src);
877 void bsfq(Register dst, Register src);
878 void bsfq(Register dst, const Operand& src);
879 void bsfl(Register dst, Register src);
880 void bsfl(Register dst, const Operand& src);
Steve Blocka7e24c12009-10-30 11:49:00 +0000881
882 // Miscellaneous
Steve Block3ce2e202009-11-05 08:53:23 +0000883 void clc();
Steve Block44f0eee2011-05-26 01:26:41 +0100884 void cld();
Steve Blocka7e24c12009-10-30 11:49:00 +0000885 void cpuid();
886 void hlt();
887 void int3();
888 void nop();
Steve Blocka7e24c12009-10-30 11:49:00 +0000889 void ret(int imm16);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000890 void ud2();
Steve Blocka7e24c12009-10-30 11:49:00 +0000891 void setcc(Condition cc, Register reg);
892
893 // Label operations & relative jumps (PPUM Appendix D)
894 //
895 // Takes a branch opcode (cc) and a label (L) and generates
896 // either a backward branch or a forward branch and links it
897 // to the label fixup chain. Usage:
898 //
899 // Label L; // unbound label
900 // j(cc, &L); // forward branch to unbound label
901 // bind(&L); // bind label to the current pc
902 // j(cc, &L); // backward branch to bound label
903 // bind(&L); // illegal: a label may be bound only once
904 //
905 // Note: The same Label can be used for forward and backward branches
906 // but it may be bound only once.
907
908 void bind(Label* L); // binds an unbound label L to the current code position
909
910 // Calls
911 // Call near relative 32-bit displacement, relative to next instruction.
912 void call(Label* L);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000913 void call(Address entry, RelocInfo::Mode rmode);
Ben Murdoch257744e2011-11-30 15:57:28 +0000914 void call(Handle<Code> target,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000915 RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000916 TypeFeedbackId ast_id = TypeFeedbackId::None());
Steve Blocka7e24c12009-10-30 11:49:00 +0000917
Steve Block1e0659c2011-05-24 12:43:12 +0100918 // Calls directly to the given address using a relative offset.
919 // Should only ever be used in Code objects for calls within the
920 // same Code object. Should not be used when generating new code (use labels),
921 // but only when patching existing code.
922 void call(Address target);
923
Steve Blocka7e24c12009-10-30 11:49:00 +0000924 // Call near absolute indirect, address in register
925 void call(Register adr);
926
Steve Blocka7e24c12009-10-30 11:49:00 +0000927 // Jumps
928 // Jump short or near relative.
Steve Block3ce2e202009-11-05 08:53:23 +0000929 // Use a 32-bit signed displacement.
Ben Murdoch257744e2011-11-30 15:57:28 +0000930 // Unconditional jump to L
931 void jmp(Label* L, Label::Distance distance = Label::kFar);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000932 void jmp(Address entry, RelocInfo::Mode rmode);
Steve Block3ce2e202009-11-05 08:53:23 +0000933 void jmp(Handle<Code> target, RelocInfo::Mode rmode);
Steve Blocka7e24c12009-10-30 11:49:00 +0000934
935 // Jump near absolute indirect (r64)
936 void jmp(Register adr);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000937 void jmp(const Operand& src);
Steve Blocka7e24c12009-10-30 11:49:00 +0000938
Steve Blocka7e24c12009-10-30 11:49:00 +0000939 // Conditional jumps
Ben Murdoch257744e2011-11-30 15:57:28 +0000940 void j(Condition cc,
941 Label* L,
942 Label::Distance distance = Label::kFar);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000943 void j(Condition cc, Address entry, RelocInfo::Mode rmode);
Steve Block3ce2e202009-11-05 08:53:23 +0000944 void j(Condition cc, Handle<Code> target, RelocInfo::Mode rmode);
Steve Blocka7e24c12009-10-30 11:49:00 +0000945
946 // Floating-point operations
947 void fld(int i);
948
949 void fld1();
950 void fldz();
Steve Block6ded16b2010-05-10 14:33:55 +0100951 void fldpi();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100952 void fldln2();
Steve Blocka7e24c12009-10-30 11:49:00 +0000953
954 void fld_s(const Operand& adr);
955 void fld_d(const Operand& adr);
956
957 void fstp_s(const Operand& adr);
958 void fstp_d(const Operand& adr);
Steve Block3ce2e202009-11-05 08:53:23 +0000959 void fstp(int index);
Steve Blocka7e24c12009-10-30 11:49:00 +0000960
961 void fild_s(const Operand& adr);
962 void fild_d(const Operand& adr);
963
964 void fist_s(const Operand& adr);
965
966 void fistp_s(const Operand& adr);
967 void fistp_d(const Operand& adr);
968
969 void fisttp_s(const Operand& adr);
Leon Clarked91b9f72010-01-27 17:25:45 +0000970 void fisttp_d(const Operand& adr);
Steve Blocka7e24c12009-10-30 11:49:00 +0000971
972 void fabs();
973 void fchs();
974
975 void fadd(int i);
976 void fsub(int i);
977 void fmul(int i);
978 void fdiv(int i);
979
980 void fisub_s(const Operand& adr);
981
982 void faddp(int i = 1);
983 void fsubp(int i = 1);
984 void fsubrp(int i = 1);
985 void fmulp(int i = 1);
986 void fdivp(int i = 1);
987 void fprem();
988 void fprem1();
989
990 void fxch(int i = 1);
991 void fincstp();
992 void ffree(int i = 0);
993
994 void ftst();
995 void fucomp(int i);
996 void fucompp();
Steve Block3ce2e202009-11-05 08:53:23 +0000997 void fucomi(int i);
998 void fucomip();
999
Steve Blocka7e24c12009-10-30 11:49:00 +00001000 void fcompp();
1001 void fnstsw_ax();
1002 void fwait();
1003 void fnclex();
1004
1005 void fsin();
1006 void fcos();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001007 void fptan();
Ben Murdochb0fe1622011-05-05 13:52:32 +01001008 void fyl2x();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001009 void f2xm1();
1010 void fscale();
1011 void fninit();
Steve Blocka7e24c12009-10-30 11:49:00 +00001012
1013 void frndint();
1014
1015 void sahf();
1016
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001017 // SSE instructions
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001018 void addss(XMMRegister dst, XMMRegister src);
1019 void addss(XMMRegister dst, const Operand& src);
1020 void subss(XMMRegister dst, XMMRegister src);
1021 void subss(XMMRegister dst, const Operand& src);
1022 void mulss(XMMRegister dst, XMMRegister src);
1023 void mulss(XMMRegister dst, const Operand& src);
1024 void divss(XMMRegister dst, XMMRegister src);
1025 void divss(XMMRegister dst, const Operand& src);
1026
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001027 void maxss(XMMRegister dst, XMMRegister src);
1028 void maxss(XMMRegister dst, const Operand& src);
1029 void minss(XMMRegister dst, XMMRegister src);
1030 void minss(XMMRegister dst, const Operand& src);
1031
1032 void sqrtss(XMMRegister dst, XMMRegister src);
1033 void sqrtss(XMMRegister dst, const Operand& src);
1034
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001035 void ucomiss(XMMRegister dst, XMMRegister src);
1036 void ucomiss(XMMRegister dst, const Operand& src);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001037 void movaps(XMMRegister dst, XMMRegister src);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001038
1039 // Don't use this unless it's important to keep the
1040 // top half of the destination register unchanged.
1041 // Use movaps when moving float values and movd for integer
1042 // values in xmm registers.
1043 void movss(XMMRegister dst, XMMRegister src);
1044
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001045 void movss(XMMRegister dst, const Operand& src);
1046 void movss(const Operand& dst, XMMRegister src);
1047 void shufps(XMMRegister dst, XMMRegister src, byte imm8);
1048
1049 void cvttss2si(Register dst, const Operand& src);
1050 void cvttss2si(Register dst, XMMRegister src);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001051 void cvtlsi2ss(XMMRegister dst, const Operand& src);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001052 void cvtlsi2ss(XMMRegister dst, Register src);
1053
1054 void andps(XMMRegister dst, XMMRegister src);
1055 void andps(XMMRegister dst, const Operand& src);
1056 void orps(XMMRegister dst, XMMRegister src);
1057 void orps(XMMRegister dst, const Operand& src);
1058 void xorps(XMMRegister dst, XMMRegister src);
1059 void xorps(XMMRegister dst, const Operand& src);
1060
1061 void addps(XMMRegister dst, XMMRegister src);
1062 void addps(XMMRegister dst, const Operand& src);
1063 void subps(XMMRegister dst, XMMRegister src);
1064 void subps(XMMRegister dst, const Operand& src);
1065 void mulps(XMMRegister dst, XMMRegister src);
1066 void mulps(XMMRegister dst, const Operand& src);
1067 void divps(XMMRegister dst, XMMRegister src);
1068 void divps(XMMRegister dst, const Operand& src);
1069
1070 void movmskps(Register dst, XMMRegister src);
1071
Steve Blocka7e24c12009-10-30 11:49:00 +00001072 // SSE2 instructions
Steve Block6ded16b2010-05-10 14:33:55 +01001073 void movd(XMMRegister dst, Register src);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001074 void movd(XMMRegister dst, const Operand& src);
Steve Block6ded16b2010-05-10 14:33:55 +01001075 void movd(Register dst, XMMRegister src);
1076 void movq(XMMRegister dst, Register src);
1077 void movq(Register dst, XMMRegister src);
Ben Murdoch257744e2011-11-30 15:57:28 +00001078 void movq(XMMRegister dst, XMMRegister src);
Steve Block6ded16b2010-05-10 14:33:55 +01001079
Ben Murdoch257744e2011-11-30 15:57:28 +00001080 // Don't use this unless it's important to keep the
1081 // top half of the destination register unchanged.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001082 // Use movapd when moving double values and movq for integer
Ben Murdoch257744e2011-11-30 15:57:28 +00001083 // values in xmm registers.
Steve Block053d10c2011-06-13 19:13:29 +01001084 void movsd(XMMRegister dst, XMMRegister src);
Ben Murdoch257744e2011-11-30 15:57:28 +00001085
1086 void movsd(const Operand& dst, XMMRegister src);
Steve Block6ded16b2010-05-10 14:33:55 +01001087 void movsd(XMMRegister dst, const Operand& src);
Steve Blocka7e24c12009-10-30 11:49:00 +00001088
Steve Block1e0659c2011-05-24 12:43:12 +01001089 void movdqa(const Operand& dst, XMMRegister src);
1090 void movdqa(XMMRegister dst, const Operand& src);
1091
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001092 void movdqu(const Operand& dst, XMMRegister src);
1093 void movdqu(XMMRegister dst, const Operand& src);
1094
Ben Murdoch257744e2011-11-30 15:57:28 +00001095 void movapd(XMMRegister dst, XMMRegister src);
Ben Murdoch257744e2011-11-30 15:57:28 +00001096
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001097 void psllq(XMMRegister reg, byte imm8);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001098 void psrlq(XMMRegister reg, byte imm8);
1099 void pslld(XMMRegister reg, byte imm8);
1100 void psrld(XMMRegister reg, byte imm8);
Steve Block8defd9f2010-07-08 12:39:36 +01001101
Steve Blocka7e24c12009-10-30 11:49:00 +00001102 void cvttsd2si(Register dst, const Operand& src);
Steve Block1e0659c2011-05-24 12:43:12 +01001103 void cvttsd2si(Register dst, XMMRegister src);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001104 void cvttss2siq(Register dst, XMMRegister src);
1105 void cvttss2siq(Register dst, const Operand& src);
Kristian Monsen25f61362010-05-21 11:50:48 +01001106 void cvttsd2siq(Register dst, XMMRegister src);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001107 void cvttsd2siq(Register dst, const Operand& src);
Steve Blocka7e24c12009-10-30 11:49:00 +00001108
1109 void cvtlsi2sd(XMMRegister dst, const Operand& src);
1110 void cvtlsi2sd(XMMRegister dst, Register src);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001111
1112 void cvtqsi2ss(XMMRegister dst, const Operand& src);
1113 void cvtqsi2ss(XMMRegister dst, Register src);
1114
Steve Blocka7e24c12009-10-30 11:49:00 +00001115 void cvtqsi2sd(XMMRegister dst, const Operand& src);
1116 void cvtqsi2sd(XMMRegister dst, Register src);
1117
Steve Block8defd9f2010-07-08 12:39:36 +01001118
Steve Block6ded16b2010-05-10 14:33:55 +01001119 void cvtss2sd(XMMRegister dst, XMMRegister src);
Steve Block8defd9f2010-07-08 12:39:36 +01001120 void cvtss2sd(XMMRegister dst, const Operand& src);
1121 void cvtsd2ss(XMMRegister dst, XMMRegister src);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001122 void cvtsd2ss(XMMRegister dst, const Operand& src);
Steve Block8defd9f2010-07-08 12:39:36 +01001123
1124 void cvtsd2si(Register dst, XMMRegister src);
1125 void cvtsd2siq(Register dst, XMMRegister src);
Steve Block6ded16b2010-05-10 14:33:55 +01001126
Steve Blocka7e24c12009-10-30 11:49:00 +00001127 void addsd(XMMRegister dst, XMMRegister src);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001128 void addsd(XMMRegister dst, const Operand& src);
Steve Blocka7e24c12009-10-30 11:49:00 +00001129 void subsd(XMMRegister dst, XMMRegister src);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001130 void subsd(XMMRegister dst, const Operand& src);
Steve Blocka7e24c12009-10-30 11:49:00 +00001131 void mulsd(XMMRegister dst, XMMRegister src);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001132 void mulsd(XMMRegister dst, const Operand& src);
Steve Blocka7e24c12009-10-30 11:49:00 +00001133 void divsd(XMMRegister dst, XMMRegister src);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001134 void divsd(XMMRegister dst, const Operand& src);
Steve Blocka7e24c12009-10-30 11:49:00 +00001135
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001136 void maxsd(XMMRegister dst, XMMRegister src);
1137 void maxsd(XMMRegister dst, const Operand& src);
1138 void minsd(XMMRegister dst, XMMRegister src);
1139 void minsd(XMMRegister dst, const Operand& src);
1140
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001141 void andpd(XMMRegister dst, XMMRegister src);
1142 void orpd(XMMRegister dst, XMMRegister src);
Andrei Popescu402d9372010-02-26 13:31:12 +00001143 void xorpd(XMMRegister dst, XMMRegister src);
Steve Block6ded16b2010-05-10 14:33:55 +01001144 void sqrtsd(XMMRegister dst, XMMRegister src);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001145 void sqrtsd(XMMRegister dst, const Operand& src);
Andrei Popescu402d9372010-02-26 13:31:12 +00001146
Andrei Popescu402d9372010-02-26 13:31:12 +00001147 void ucomisd(XMMRegister dst, XMMRegister src);
Steve Block8defd9f2010-07-08 12:39:36 +01001148 void ucomisd(XMMRegister dst, const Operand& src);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001149 void cmpltsd(XMMRegister dst, XMMRegister src);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001150 void pcmpeqd(XMMRegister dst, XMMRegister src);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001151
1152 void movmskpd(Register dst, XMMRegister src);
1153
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001154 void punpckldq(XMMRegister dst, XMMRegister src);
Ben Murdoch61f157c2016-09-16 13:49:30 +01001155 void punpckldq(XMMRegister dst, const Operand& src);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001156 void punpckhdq(XMMRegister dst, XMMRegister src);
1157
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001158 // SSE 4.1 instruction
Ben Murdoch61f157c2016-09-16 13:49:30 +01001159 void insertps(XMMRegister dst, XMMRegister src, byte imm8);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001160 void extractps(Register dst, XMMRegister src, byte imm8);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001161 void pextrd(Register dst, XMMRegister src, int8_t imm8);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001162 void pinsrd(XMMRegister dst, Register src, int8_t imm8);
1163 void pinsrd(XMMRegister dst, const Operand& src, int8_t imm8);
1164
1165 void roundss(XMMRegister dst, XMMRegister src, RoundingMode mode);
Ben Murdoch257744e2011-11-30 15:57:28 +00001166 void roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode);
1167
Ben Murdoch61f157c2016-09-16 13:49:30 +01001168 void cmpps(XMMRegister dst, XMMRegister src, int8_t cmp);
1169 void cmpeqps(XMMRegister dst, XMMRegister src);
1170 void cmpltps(XMMRegister dst, XMMRegister src);
1171 void cmpleps(XMMRegister dst, XMMRegister src);
1172 void cmpneqps(XMMRegister dst, XMMRegister src);
1173 void cmpnltps(XMMRegister dst, XMMRegister src);
1174 void cmpnleps(XMMRegister dst, XMMRegister src);
1175
1176 void minps(XMMRegister dst, XMMRegister src);
1177 void minps(XMMRegister dst, const Operand& src);
1178 void maxps(XMMRegister dst, XMMRegister src);
1179 void maxps(XMMRegister dst, const Operand& src);
1180 void rcpps(XMMRegister dst, XMMRegister src);
1181 void rcpps(XMMRegister dst, const Operand& src);
1182 void rsqrtps(XMMRegister dst, XMMRegister src);
1183 void rsqrtps(XMMRegister dst, const Operand& src);
1184 void sqrtps(XMMRegister dst, XMMRegister src);
1185 void sqrtps(XMMRegister dst, const Operand& src);
1186 void movups(XMMRegister dst, XMMRegister src);
1187 void movups(XMMRegister dst, const Operand& src);
1188 void movups(const Operand& dst, XMMRegister src);
1189 void paddd(XMMRegister dst, XMMRegister src);
1190 void paddd(XMMRegister dst, const Operand& src);
1191 void psubd(XMMRegister dst, XMMRegister src);
1192 void psubd(XMMRegister dst, const Operand& src);
1193 void pmulld(XMMRegister dst, XMMRegister src);
1194 void pmulld(XMMRegister dst, const Operand& src);
1195 void pmuludq(XMMRegister dst, XMMRegister src);
1196 void pmuludq(XMMRegister dst, const Operand& src);
1197 void psrldq(XMMRegister dst, uint8_t shift);
1198 void pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle);
1199 void cvtps2dq(XMMRegister dst, XMMRegister src);
1200 void cvtps2dq(XMMRegister dst, const Operand& src);
1201 void cvtdq2ps(XMMRegister dst, XMMRegister src);
1202 void cvtdq2ps(XMMRegister dst, const Operand& src);
1203
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001204 // AVX instruction
1205 void vfmadd132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1206 vfmasd(0x99, dst, src1, src2);
1207 }
1208 void vfmadd213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1209 vfmasd(0xa9, dst, src1, src2);
1210 }
1211 void vfmadd231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1212 vfmasd(0xb9, dst, src1, src2);
1213 }
1214 void vfmadd132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1215 vfmasd(0x99, dst, src1, src2);
1216 }
1217 void vfmadd213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1218 vfmasd(0xa9, dst, src1, src2);
1219 }
1220 void vfmadd231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1221 vfmasd(0xb9, dst, src1, src2);
1222 }
1223 void vfmsub132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1224 vfmasd(0x9b, dst, src1, src2);
1225 }
1226 void vfmsub213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1227 vfmasd(0xab, dst, src1, src2);
1228 }
1229 void vfmsub231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1230 vfmasd(0xbb, dst, src1, src2);
1231 }
1232 void vfmsub132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1233 vfmasd(0x9b, dst, src1, src2);
1234 }
1235 void vfmsub213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1236 vfmasd(0xab, dst, src1, src2);
1237 }
1238 void vfmsub231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1239 vfmasd(0xbb, dst, src1, src2);
1240 }
1241 void vfnmadd132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1242 vfmasd(0x9d, dst, src1, src2);
1243 }
1244 void vfnmadd213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1245 vfmasd(0xad, dst, src1, src2);
1246 }
1247 void vfnmadd231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1248 vfmasd(0xbd, dst, src1, src2);
1249 }
1250 void vfnmadd132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1251 vfmasd(0x9d, dst, src1, src2);
1252 }
1253 void vfnmadd213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1254 vfmasd(0xad, dst, src1, src2);
1255 }
1256 void vfnmadd231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1257 vfmasd(0xbd, dst, src1, src2);
1258 }
1259 void vfnmsub132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1260 vfmasd(0x9f, dst, src1, src2);
1261 }
1262 void vfnmsub213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1263 vfmasd(0xaf, dst, src1, src2);
1264 }
1265 void vfnmsub231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1266 vfmasd(0xbf, dst, src1, src2);
1267 }
1268 void vfnmsub132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1269 vfmasd(0x9f, dst, src1, src2);
1270 }
1271 void vfnmsub213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1272 vfmasd(0xaf, dst, src1, src2);
1273 }
1274 void vfnmsub231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1275 vfmasd(0xbf, dst, src1, src2);
1276 }
1277 void vfmasd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
1278 void vfmasd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
1279
1280 void vfmadd132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1281 vfmass(0x99, dst, src1, src2);
1282 }
1283 void vfmadd213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1284 vfmass(0xa9, dst, src1, src2);
1285 }
1286 void vfmadd231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1287 vfmass(0xb9, dst, src1, src2);
1288 }
1289 void vfmadd132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1290 vfmass(0x99, dst, src1, src2);
1291 }
1292 void vfmadd213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1293 vfmass(0xa9, dst, src1, src2);
1294 }
1295 void vfmadd231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1296 vfmass(0xb9, dst, src1, src2);
1297 }
1298 void vfmsub132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1299 vfmass(0x9b, dst, src1, src2);
1300 }
1301 void vfmsub213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1302 vfmass(0xab, dst, src1, src2);
1303 }
1304 void vfmsub231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1305 vfmass(0xbb, dst, src1, src2);
1306 }
1307 void vfmsub132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1308 vfmass(0x9b, dst, src1, src2);
1309 }
1310 void vfmsub213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1311 vfmass(0xab, dst, src1, src2);
1312 }
1313 void vfmsub231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1314 vfmass(0xbb, dst, src1, src2);
1315 }
1316 void vfnmadd132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1317 vfmass(0x9d, dst, src1, src2);
1318 }
1319 void vfnmadd213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1320 vfmass(0xad, dst, src1, src2);
1321 }
1322 void vfnmadd231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1323 vfmass(0xbd, dst, src1, src2);
1324 }
1325 void vfnmadd132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1326 vfmass(0x9d, dst, src1, src2);
1327 }
1328 void vfnmadd213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1329 vfmass(0xad, dst, src1, src2);
1330 }
1331 void vfnmadd231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1332 vfmass(0xbd, dst, src1, src2);
1333 }
1334 void vfnmsub132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1335 vfmass(0x9f, dst, src1, src2);
1336 }
1337 void vfnmsub213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1338 vfmass(0xaf, dst, src1, src2);
1339 }
1340 void vfnmsub231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1341 vfmass(0xbf, dst, src1, src2);
1342 }
1343 void vfnmsub132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1344 vfmass(0x9f, dst, src1, src2);
1345 }
1346 void vfnmsub213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1347 vfmass(0xaf, dst, src1, src2);
1348 }
1349 void vfnmsub231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1350 vfmass(0xbf, dst, src1, src2);
1351 }
1352 void vfmass(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
1353 void vfmass(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
1354
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001355 void vmovd(XMMRegister dst, Register src);
1356 void vmovd(XMMRegister dst, const Operand& src);
1357 void vmovd(Register dst, XMMRegister src);
1358 void vmovq(XMMRegister dst, Register src);
1359 void vmovq(XMMRegister dst, const Operand& src);
1360 void vmovq(Register dst, XMMRegister src);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001361
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001362 void vmovsd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1363 vsd(0x10, dst, src1, src2);
1364 }
1365 void vmovsd(XMMRegister dst, const Operand& src) {
1366 vsd(0x10, dst, xmm0, src);
1367 }
1368 void vmovsd(const Operand& dst, XMMRegister src) {
1369 vsd(0x11, src, xmm0, dst);
1370 }
1371
1372#define AVX_SP_3(instr, opcode) \
1373 AVX_S_3(instr, opcode) \
1374 AVX_P_3(instr, opcode)
1375
1376#define AVX_S_3(instr, opcode) \
1377 AVX_3(instr##ss, opcode, vss) \
1378 AVX_3(instr##sd, opcode, vsd)
1379
1380#define AVX_P_3(instr, opcode) \
1381 AVX_3(instr##ps, opcode, vps) \
1382 AVX_3(instr##pd, opcode, vpd)
1383
1384#define AVX_3(instr, opcode, impl) \
1385 void instr(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \
1386 impl(opcode, dst, src1, src2); \
1387 } \
1388 void instr(XMMRegister dst, XMMRegister src1, const Operand& src2) { \
1389 impl(opcode, dst, src1, src2); \
1390 }
1391
1392 AVX_SP_3(vsqrt, 0x51);
1393 AVX_SP_3(vadd, 0x58);
1394 AVX_SP_3(vsub, 0x5c);
1395 AVX_SP_3(vmul, 0x59);
1396 AVX_SP_3(vdiv, 0x5e);
1397 AVX_SP_3(vmin, 0x5d);
1398 AVX_SP_3(vmax, 0x5f);
1399 AVX_P_3(vand, 0x54);
1400 AVX_P_3(vor, 0x56);
1401 AVX_P_3(vxor, 0x57);
1402 AVX_3(vpcmpeqd, 0x76, vpd);
1403 AVX_3(vcvtsd2ss, 0x5a, vsd);
1404
1405#undef AVX_3
1406#undef AVX_S_3
1407#undef AVX_P_3
1408#undef AVX_SP_3
1409
1410 void vpsrlq(XMMRegister dst, XMMRegister src, byte imm8) {
1411 XMMRegister iop = {2};
1412 vpd(0x73, iop, dst, src);
1413 emit(imm8);
1414 }
1415 void vpsllq(XMMRegister dst, XMMRegister src, byte imm8) {
1416 XMMRegister iop = {6};
1417 vpd(0x73, iop, dst, src);
1418 emit(imm8);
1419 }
1420 void vcvtss2sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1421 vsd(0x5a, dst, src1, src2, kF3, k0F, kWIG);
1422 }
1423 void vcvtss2sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1424 vsd(0x5a, dst, src1, src2, kF3, k0F, kWIG);
1425 }
1426 void vcvtlsi2sd(XMMRegister dst, XMMRegister src1, Register src2) {
1427 XMMRegister isrc2 = {src2.code()};
1428 vsd(0x2a, dst, src1, isrc2, kF2, k0F, kW0);
1429 }
1430 void vcvtlsi2sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1431 vsd(0x2a, dst, src1, src2, kF2, k0F, kW0);
1432 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001433 void vcvtlsi2ss(XMMRegister dst, XMMRegister src1, Register src2) {
1434 XMMRegister isrc2 = {src2.code()};
1435 vsd(0x2a, dst, src1, isrc2, kF3, k0F, kW0);
1436 }
1437 void vcvtlsi2ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1438 vsd(0x2a, dst, src1, src2, kF3, k0F, kW0);
1439 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001440 void vcvtqsi2ss(XMMRegister dst, XMMRegister src1, Register src2) {
1441 XMMRegister isrc2 = {src2.code()};
1442 vsd(0x2a, dst, src1, isrc2, kF3, k0F, kW1);
1443 }
1444 void vcvtqsi2ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1445 vsd(0x2a, dst, src1, src2, kF3, k0F, kW1);
1446 }
1447 void vcvtqsi2sd(XMMRegister dst, XMMRegister src1, Register src2) {
1448 XMMRegister isrc2 = {src2.code()};
1449 vsd(0x2a, dst, src1, isrc2, kF2, k0F, kW1);
1450 }
1451 void vcvtqsi2sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1452 vsd(0x2a, dst, src1, src2, kF2, k0F, kW1);
1453 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001454 void vcvttss2si(Register dst, XMMRegister src) {
1455 XMMRegister idst = {dst.code()};
1456 vsd(0x2c, idst, xmm0, src, kF3, k0F, kW0);
1457 }
1458 void vcvttss2si(Register dst, const Operand& src) {
1459 XMMRegister idst = {dst.code()};
1460 vsd(0x2c, idst, xmm0, src, kF3, k0F, kW0);
1461 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001462 void vcvttsd2si(Register dst, XMMRegister src) {
1463 XMMRegister idst = {dst.code()};
1464 vsd(0x2c, idst, xmm0, src, kF2, k0F, kW0);
1465 }
1466 void vcvttsd2si(Register dst, const Operand& src) {
1467 XMMRegister idst = {dst.code()};
1468 vsd(0x2c, idst, xmm0, src, kF2, k0F, kW0);
1469 }
1470 void vcvttss2siq(Register dst, XMMRegister src) {
1471 XMMRegister idst = {dst.code()};
1472 vsd(0x2c, idst, xmm0, src, kF3, k0F, kW1);
1473 }
1474 void vcvttss2siq(Register dst, const Operand& src) {
1475 XMMRegister idst = {dst.code()};
1476 vsd(0x2c, idst, xmm0, src, kF3, k0F, kW1);
1477 }
1478 void vcvttsd2siq(Register dst, XMMRegister src) {
1479 XMMRegister idst = {dst.code()};
1480 vsd(0x2c, idst, xmm0, src, kF2, k0F, kW1);
1481 }
1482 void vcvttsd2siq(Register dst, const Operand& src) {
1483 XMMRegister idst = {dst.code()};
1484 vsd(0x2c, idst, xmm0, src, kF2, k0F, kW1);
1485 }
1486 void vcvtsd2si(Register dst, XMMRegister src) {
1487 XMMRegister idst = {dst.code()};
1488 vsd(0x2d, idst, xmm0, src, kF2, k0F, kW0);
1489 }
1490 void vucomisd(XMMRegister dst, XMMRegister src) {
1491 vsd(0x2e, dst, xmm0, src, k66, k0F, kWIG);
1492 }
1493 void vucomisd(XMMRegister dst, const Operand& src) {
1494 vsd(0x2e, dst, xmm0, src, k66, k0F, kWIG);
1495 }
1496 void vroundss(XMMRegister dst, XMMRegister src1, XMMRegister src2,
1497 RoundingMode mode) {
1498 vsd(0x0a, dst, src1, src2, k66, k0F3A, kWIG);
1499 emit(static_cast<byte>(mode) | 0x8); // Mask precision exception.
1500 }
1501 void vroundsd(XMMRegister dst, XMMRegister src1, XMMRegister src2,
1502 RoundingMode mode) {
1503 vsd(0x0b, dst, src1, src2, k66, k0F3A, kWIG);
1504 emit(static_cast<byte>(mode) | 0x8); // Mask precision exception.
1505 }
1506
1507 void vsd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1508 vsd(op, dst, src1, src2, kF2, k0F, kWIG);
1509 }
1510 void vsd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2) {
1511 vsd(op, dst, src1, src2, kF2, k0F, kWIG);
1512 }
1513 void vsd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2,
1514 SIMDPrefix pp, LeadingOpcode m, VexW w);
1515 void vsd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2,
1516 SIMDPrefix pp, LeadingOpcode m, VexW w);
1517
1518 void vmovss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1519 vss(0x10, dst, src1, src2);
1520 }
1521 void vmovss(XMMRegister dst, const Operand& src) {
1522 vss(0x10, dst, xmm0, src);
1523 }
1524 void vmovss(const Operand& dst, XMMRegister src) {
1525 vss(0x11, src, xmm0, dst);
1526 }
1527 void vucomiss(XMMRegister dst, XMMRegister src);
1528 void vucomiss(XMMRegister dst, const Operand& src);
1529 void vss(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
1530 void vss(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
1531
1532 void vmovaps(XMMRegister dst, XMMRegister src) { vps(0x28, dst, xmm0, src); }
1533 void vmovapd(XMMRegister dst, XMMRegister src) { vpd(0x28, dst, xmm0, src); }
1534 void vmovmskpd(Register dst, XMMRegister src) {
1535 XMMRegister idst = {dst.code()};
1536 vpd(0x50, idst, xmm0, src);
1537 }
1538
1539 void vps(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
1540 void vps(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
1541 void vpd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
1542 void vpd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
1543
1544 // BMI instruction
1545 void andnq(Register dst, Register src1, Register src2) {
1546 bmi1q(0xf2, dst, src1, src2);
1547 }
1548 void andnq(Register dst, Register src1, const Operand& src2) {
1549 bmi1q(0xf2, dst, src1, src2);
1550 }
1551 void andnl(Register dst, Register src1, Register src2) {
1552 bmi1l(0xf2, dst, src1, src2);
1553 }
1554 void andnl(Register dst, Register src1, const Operand& src2) {
1555 bmi1l(0xf2, dst, src1, src2);
1556 }
1557 void bextrq(Register dst, Register src1, Register src2) {
1558 bmi1q(0xf7, dst, src2, src1);
1559 }
1560 void bextrq(Register dst, const Operand& src1, Register src2) {
1561 bmi1q(0xf7, dst, src2, src1);
1562 }
1563 void bextrl(Register dst, Register src1, Register src2) {
1564 bmi1l(0xf7, dst, src2, src1);
1565 }
1566 void bextrl(Register dst, const Operand& src1, Register src2) {
1567 bmi1l(0xf7, dst, src2, src1);
1568 }
1569 void blsiq(Register dst, Register src) {
1570 Register ireg = {3};
1571 bmi1q(0xf3, ireg, dst, src);
1572 }
1573 void blsiq(Register dst, const Operand& src) {
1574 Register ireg = {3};
1575 bmi1q(0xf3, ireg, dst, src);
1576 }
1577 void blsil(Register dst, Register src) {
1578 Register ireg = {3};
1579 bmi1l(0xf3, ireg, dst, src);
1580 }
1581 void blsil(Register dst, const Operand& src) {
1582 Register ireg = {3};
1583 bmi1l(0xf3, ireg, dst, src);
1584 }
1585 void blsmskq(Register dst, Register src) {
1586 Register ireg = {2};
1587 bmi1q(0xf3, ireg, dst, src);
1588 }
1589 void blsmskq(Register dst, const Operand& src) {
1590 Register ireg = {2};
1591 bmi1q(0xf3, ireg, dst, src);
1592 }
1593 void blsmskl(Register dst, Register src) {
1594 Register ireg = {2};
1595 bmi1l(0xf3, ireg, dst, src);
1596 }
1597 void blsmskl(Register dst, const Operand& src) {
1598 Register ireg = {2};
1599 bmi1l(0xf3, ireg, dst, src);
1600 }
1601 void blsrq(Register dst, Register src) {
1602 Register ireg = {1};
1603 bmi1q(0xf3, ireg, dst, src);
1604 }
1605 void blsrq(Register dst, const Operand& src) {
1606 Register ireg = {1};
1607 bmi1q(0xf3, ireg, dst, src);
1608 }
1609 void blsrl(Register dst, Register src) {
1610 Register ireg = {1};
1611 bmi1l(0xf3, ireg, dst, src);
1612 }
1613 void blsrl(Register dst, const Operand& src) {
1614 Register ireg = {1};
1615 bmi1l(0xf3, ireg, dst, src);
1616 }
1617 void tzcntq(Register dst, Register src);
1618 void tzcntq(Register dst, const Operand& src);
1619 void tzcntl(Register dst, Register src);
1620 void tzcntl(Register dst, const Operand& src);
1621
1622 void lzcntq(Register dst, Register src);
1623 void lzcntq(Register dst, const Operand& src);
1624 void lzcntl(Register dst, Register src);
1625 void lzcntl(Register dst, const Operand& src);
1626
1627 void popcntq(Register dst, Register src);
1628 void popcntq(Register dst, const Operand& src);
1629 void popcntl(Register dst, Register src);
1630 void popcntl(Register dst, const Operand& src);
1631
1632 void bzhiq(Register dst, Register src1, Register src2) {
1633 bmi2q(kNone, 0xf5, dst, src2, src1);
1634 }
1635 void bzhiq(Register dst, const Operand& src1, Register src2) {
1636 bmi2q(kNone, 0xf5, dst, src2, src1);
1637 }
1638 void bzhil(Register dst, Register src1, Register src2) {
1639 bmi2l(kNone, 0xf5, dst, src2, src1);
1640 }
1641 void bzhil(Register dst, const Operand& src1, Register src2) {
1642 bmi2l(kNone, 0xf5, dst, src2, src1);
1643 }
1644 void mulxq(Register dst1, Register dst2, Register src) {
1645 bmi2q(kF2, 0xf6, dst1, dst2, src);
1646 }
1647 void mulxq(Register dst1, Register dst2, const Operand& src) {
1648 bmi2q(kF2, 0xf6, dst1, dst2, src);
1649 }
1650 void mulxl(Register dst1, Register dst2, Register src) {
1651 bmi2l(kF2, 0xf6, dst1, dst2, src);
1652 }
1653 void mulxl(Register dst1, Register dst2, const Operand& src) {
1654 bmi2l(kF2, 0xf6, dst1, dst2, src);
1655 }
1656 void pdepq(Register dst, Register src1, Register src2) {
1657 bmi2q(kF2, 0xf5, dst, src1, src2);
1658 }
1659 void pdepq(Register dst, Register src1, const Operand& src2) {
1660 bmi2q(kF2, 0xf5, dst, src1, src2);
1661 }
1662 void pdepl(Register dst, Register src1, Register src2) {
1663 bmi2l(kF2, 0xf5, dst, src1, src2);
1664 }
1665 void pdepl(Register dst, Register src1, const Operand& src2) {
1666 bmi2l(kF2, 0xf5, dst, src1, src2);
1667 }
1668 void pextq(Register dst, Register src1, Register src2) {
1669 bmi2q(kF3, 0xf5, dst, src1, src2);
1670 }
1671 void pextq(Register dst, Register src1, const Operand& src2) {
1672 bmi2q(kF3, 0xf5, dst, src1, src2);
1673 }
1674 void pextl(Register dst, Register src1, Register src2) {
1675 bmi2l(kF3, 0xf5, dst, src1, src2);
1676 }
1677 void pextl(Register dst, Register src1, const Operand& src2) {
1678 bmi2l(kF3, 0xf5, dst, src1, src2);
1679 }
1680 void sarxq(Register dst, Register src1, Register src2) {
1681 bmi2q(kF3, 0xf7, dst, src2, src1);
1682 }
1683 void sarxq(Register dst, const Operand& src1, Register src2) {
1684 bmi2q(kF3, 0xf7, dst, src2, src1);
1685 }
1686 void sarxl(Register dst, Register src1, Register src2) {
1687 bmi2l(kF3, 0xf7, dst, src2, src1);
1688 }
1689 void sarxl(Register dst, const Operand& src1, Register src2) {
1690 bmi2l(kF3, 0xf7, dst, src2, src1);
1691 }
1692 void shlxq(Register dst, Register src1, Register src2) {
1693 bmi2q(k66, 0xf7, dst, src2, src1);
1694 }
1695 void shlxq(Register dst, const Operand& src1, Register src2) {
1696 bmi2q(k66, 0xf7, dst, src2, src1);
1697 }
1698 void shlxl(Register dst, Register src1, Register src2) {
1699 bmi2l(k66, 0xf7, dst, src2, src1);
1700 }
1701 void shlxl(Register dst, const Operand& src1, Register src2) {
1702 bmi2l(k66, 0xf7, dst, src2, src1);
1703 }
1704 void shrxq(Register dst, Register src1, Register src2) {
1705 bmi2q(kF2, 0xf7, dst, src2, src1);
1706 }
1707 void shrxq(Register dst, const Operand& src1, Register src2) {
1708 bmi2q(kF2, 0xf7, dst, src2, src1);
1709 }
1710 void shrxl(Register dst, Register src1, Register src2) {
1711 bmi2l(kF2, 0xf7, dst, src2, src1);
1712 }
1713 void shrxl(Register dst, const Operand& src1, Register src2) {
1714 bmi2l(kF2, 0xf7, dst, src2, src1);
1715 }
1716 void rorxq(Register dst, Register src, byte imm8);
1717 void rorxq(Register dst, const Operand& src, byte imm8);
1718 void rorxl(Register dst, Register src, byte imm8);
1719 void rorxl(Register dst, const Operand& src, byte imm8);
Steve Blocka7e24c12009-10-30 11:49:00 +00001720
1721 // Check the code size generated from label to here.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001722 int SizeOfCodeGeneratedSince(Label* label) {
1723 return pc_offset() - label->pos();
1724 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001725
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001726 // Mark generator continuation.
1727 void RecordGeneratorContinuation();
Steve Blocka7e24c12009-10-30 11:49:00 +00001728
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001729 // Mark address of a debug break slot.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001730 void RecordDebugBreakSlot(RelocInfo::Mode mode);
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001731
Steve Blocka7e24c12009-10-30 11:49:00 +00001732 // Record a comment relocation entry that can be used by a disassembler.
Ben Murdochb0fe1622011-05-05 13:52:32 +01001733 // Use --code-comments to enable.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001734 void RecordComment(const char* msg);
Steve Blocka7e24c12009-10-30 11:49:00 +00001735
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001736 // Record a deoptimization reason that can be used by a log or cpu profiler.
1737 // Use --trace-deopt to enable.
Ben Murdochc5610432016-08-08 18:44:38 +01001738 void RecordDeoptReason(const int reason, int raw_position, int id);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001739
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001740 void PatchConstantPoolAccessInstruction(int pc_offset, int offset,
1741 ConstantPoolEntry::Access access,
1742 ConstantPoolEntry::Type type) {
1743 // No embedded constant pool support.
1744 UNREACHABLE();
1745 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001746
Ben Murdochb0fe1622011-05-05 13:52:32 +01001747 // Writes a single word of data in the code stream.
1748 // Used for inline tables, e.g., jump-tables.
Ben Murdochb8e0da22011-05-16 14:20:40 +01001749 void db(uint8_t data);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001750 void dd(uint32_t data);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001751 void dq(uint64_t data);
1752 void dp(uintptr_t data) { dq(data); }
1753 void dq(Label* label);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001754
Ben Murdochda12d292016-06-02 14:46:10 +01001755 AssemblerPositionsRecorder* positions_recorder() {
1756 return &positions_recorder_;
1757 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001758
1759 // Check if there is less than kGap bytes available in the buffer.
1760 // If this is the case, we need to grow the buffer before emitting
1761 // an instruction or relocation information.
1762 inline bool buffer_overflow() const {
1763 return pc_ >= reloc_info_writer.pos() - kGap;
1764 }
1765
1766 // Get the number of bytes available in the buffer.
Steve Blockd0582a62009-12-15 09:54:21 +00001767 inline int available_space() const {
1768 return static_cast<int>(reloc_info_writer.pos() - pc_);
1769 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001770
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001771 static bool IsNop(Address addr);
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001772
Steve Blocka7e24c12009-10-30 11:49:00 +00001773 // Avoid overflows for displacements etc.
1774 static const int kMaximalBufferSize = 512*MB;
Steve Blocka7e24c12009-10-30 11:49:00 +00001775
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001776 byte byte_at(int pos) { return buffer_[pos]; }
1777 void set_byte_at(int pos, byte value) { buffer_[pos] = value; }
1778
Steve Block44f0eee2011-05-26 01:26:41 +01001779 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001780 // Call near indirect
1781 void call(const Operand& operand);
1782
Steve Blocka7e24c12009-10-30 11:49:00 +00001783 private:
1784 byte* addr_at(int pos) { return buffer_ + pos; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001785 uint32_t long_at(int pos) {
1786 return *reinterpret_cast<uint32_t*>(addr_at(pos));
1787 }
1788 void long_at_put(int pos, uint32_t x) {
1789 *reinterpret_cast<uint32_t*>(addr_at(pos)) = x;
1790 }
1791
1792 // code emission
1793 void GrowBuffer();
1794
1795 void emit(byte x) { *pc_++ = x; }
1796 inline void emitl(uint32_t x);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001797 inline void emitp(void* x, RelocInfo::Mode rmode);
1798 inline void emitq(uint64_t x);
Steve Blocka7e24c12009-10-30 11:49:00 +00001799 inline void emitw(uint16_t x);
Ben Murdoch257744e2011-11-30 15:57:28 +00001800 inline void emit_code_target(Handle<Code> target,
1801 RelocInfo::Mode rmode,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001802 TypeFeedbackId ast_id = TypeFeedbackId::None());
1803 inline void emit_runtime_entry(Address entry, RelocInfo::Mode rmode);
Ben Murdochc5610432016-08-08 18:44:38 +01001804 void emit(Immediate x) {
1805 if (!RelocInfo::IsNone(x.rmode_)) {
1806 RecordRelocInfo(x.rmode_);
1807 }
1808 emitl(x.value_);
1809 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001810
1811 // Emits a REX prefix that encodes a 64-bit operand size and
1812 // the top bit of both register codes.
1813 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
1814 // REX.W is set.
Steve Blocka7e24c12009-10-30 11:49:00 +00001815 inline void emit_rex_64(XMMRegister reg, Register rm_reg);
Steve Block6ded16b2010-05-10 14:33:55 +01001816 inline void emit_rex_64(Register reg, XMMRegister rm_reg);
1817 inline void emit_rex_64(Register reg, Register rm_reg);
Steve Blocka7e24c12009-10-30 11:49:00 +00001818
1819 // Emits a REX prefix that encodes a 64-bit operand size and
1820 // the top bit of the destination, index, and base register codes.
1821 // The high bit of reg is used for REX.R, the high bit of op's base
1822 // register is used for REX.B, and the high bit of op's index register
1823 // is used for REX.X. REX.W is set.
1824 inline void emit_rex_64(Register reg, const Operand& op);
1825 inline void emit_rex_64(XMMRegister reg, const Operand& op);
1826
1827 // Emits a REX prefix that encodes a 64-bit operand size and
1828 // the top bit of the register code.
1829 // The high bit of register is used for REX.B.
1830 // REX.W is set and REX.R and REX.X are clear.
1831 inline void emit_rex_64(Register rm_reg);
1832
1833 // Emits a REX prefix that encodes a 64-bit operand size and
1834 // the top bit of the index and base register codes.
1835 // The high bit of op's base register is used for REX.B, and the high
1836 // bit of op's index register is used for REX.X.
1837 // REX.W is set and REX.R clear.
1838 inline void emit_rex_64(const Operand& op);
1839
1840 // Emit a REX prefix that only sets REX.W to choose a 64-bit operand size.
1841 void emit_rex_64() { emit(0x48); }
1842
1843 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
1844 // REX.W is clear.
1845 inline void emit_rex_32(Register reg, Register rm_reg);
1846
1847 // The high bit of reg is used for REX.R, the high bit of op's base
1848 // register is used for REX.B, and the high bit of op's index register
1849 // is used for REX.X. REX.W is cleared.
1850 inline void emit_rex_32(Register reg, const Operand& op);
1851
1852 // High bit of rm_reg goes to REX.B.
1853 // REX.W, REX.R and REX.X are clear.
1854 inline void emit_rex_32(Register rm_reg);
1855
1856 // High bit of base goes to REX.B and high bit of index to REX.X.
1857 // REX.W and REX.R are clear.
1858 inline void emit_rex_32(const Operand& op);
1859
1860 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
1861 // REX.W is cleared. If no REX bits are set, no byte is emitted.
1862 inline void emit_optional_rex_32(Register reg, Register rm_reg);
1863
1864 // The high bit of reg is used for REX.R, the high bit of op's base
1865 // register is used for REX.B, and the high bit of op's index register
1866 // is used for REX.X. REX.W is cleared. If no REX bits are set, nothing
1867 // is emitted.
1868 inline void emit_optional_rex_32(Register reg, const Operand& op);
1869
1870 // As for emit_optional_rex_32(Register, Register), except that
1871 // the registers are XMM registers.
1872 inline void emit_optional_rex_32(XMMRegister reg, XMMRegister base);
1873
1874 // As for emit_optional_rex_32(Register, Register), except that
Steve Block6ded16b2010-05-10 14:33:55 +01001875 // one of the registers is an XMM registers.
Steve Blocka7e24c12009-10-30 11:49:00 +00001876 inline void emit_optional_rex_32(XMMRegister reg, Register base);
1877
Steve Block6ded16b2010-05-10 14:33:55 +01001878 // As for emit_optional_rex_32(Register, Register), except that
1879 // one of the registers is an XMM registers.
1880 inline void emit_optional_rex_32(Register reg, XMMRegister base);
1881
Steve Blocka7e24c12009-10-30 11:49:00 +00001882 // As for emit_optional_rex_32(Register, const Operand&), except that
1883 // the register is an XMM register.
1884 inline void emit_optional_rex_32(XMMRegister reg, const Operand& op);
1885
1886 // Optionally do as emit_rex_32(Register) if the register number has
1887 // the high bit set.
1888 inline void emit_optional_rex_32(Register rm_reg);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001889 inline void emit_optional_rex_32(XMMRegister rm_reg);
Steve Blocka7e24c12009-10-30 11:49:00 +00001890
1891 // Optionally do as emit_rex_32(const Operand&) if the operand register
1892 // numbers have a high bit set.
1893 inline void emit_optional_rex_32(const Operand& op);
1894
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001895 void emit_rex(int size) {
1896 if (size == kInt64Size) {
1897 emit_rex_64();
1898 } else {
1899 DCHECK(size == kInt32Size);
1900 }
1901 }
1902
1903 template<class P1>
1904 void emit_rex(P1 p1, int size) {
1905 if (size == kInt64Size) {
1906 emit_rex_64(p1);
1907 } else {
1908 DCHECK(size == kInt32Size);
1909 emit_optional_rex_32(p1);
1910 }
1911 }
1912
1913 template<class P1, class P2>
1914 void emit_rex(P1 p1, P2 p2, int size) {
1915 if (size == kInt64Size) {
1916 emit_rex_64(p1, p2);
1917 } else {
1918 DCHECK(size == kInt32Size);
1919 emit_optional_rex_32(p1, p2);
1920 }
1921 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001922
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001923 // Emit vex prefix
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001924 void emit_vex2_byte0() { emit(0xc5); }
1925 inline void emit_vex2_byte1(XMMRegister reg, XMMRegister v, VectorLength l,
1926 SIMDPrefix pp);
1927 void emit_vex3_byte0() { emit(0xc4); }
1928 inline void emit_vex3_byte1(XMMRegister reg, XMMRegister rm, LeadingOpcode m);
1929 inline void emit_vex3_byte1(XMMRegister reg, const Operand& rm,
1930 LeadingOpcode m);
1931 inline void emit_vex3_byte2(VexW w, XMMRegister v, VectorLength l,
1932 SIMDPrefix pp);
1933 inline void emit_vex_prefix(XMMRegister reg, XMMRegister v, XMMRegister rm,
1934 VectorLength l, SIMDPrefix pp, LeadingOpcode m,
1935 VexW w);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001936 inline void emit_vex_prefix(Register reg, Register v, Register rm,
1937 VectorLength l, SIMDPrefix pp, LeadingOpcode m,
1938 VexW w);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001939 inline void emit_vex_prefix(XMMRegister reg, XMMRegister v, const Operand& rm,
1940 VectorLength l, SIMDPrefix pp, LeadingOpcode m,
1941 VexW w);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001942 inline void emit_vex_prefix(Register reg, Register v, const Operand& rm,
1943 VectorLength l, SIMDPrefix pp, LeadingOpcode m,
1944 VexW w);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001945
Steve Blocka7e24c12009-10-30 11:49:00 +00001946 // Emit the ModR/M byte, and optionally the SIB byte and
1947 // 1- or 4-byte offset for a memory operand. Also encodes
1948 // the second operand of the operation, a register or operation
1949 // subcode, into the reg field of the ModR/M byte.
1950 void emit_operand(Register reg, const Operand& adr) {
1951 emit_operand(reg.low_bits(), adr);
1952 }
1953
1954 // Emit the ModR/M byte, and optionally the SIB byte and
1955 // 1- or 4-byte offset for a memory operand. Also used to encode
1956 // a three-bit opcode extension into the ModR/M byte.
1957 void emit_operand(int rm, const Operand& adr);
1958
1959 // Emit a ModR/M byte with registers coded in the reg and rm_reg fields.
1960 void emit_modrm(Register reg, Register rm_reg) {
1961 emit(0xC0 | reg.low_bits() << 3 | rm_reg.low_bits());
1962 }
1963
1964 // Emit a ModR/M byte with an operation subcode in the reg field and
1965 // a register in the rm_reg field.
1966 void emit_modrm(int code, Register rm_reg) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001967 DCHECK(is_uint3(code));
Steve Blocka7e24c12009-10-30 11:49:00 +00001968 emit(0xC0 | code << 3 | rm_reg.low_bits());
1969 }
1970
1971 // Emit the code-object-relative offset of the label's position
1972 inline void emit_code_relative_offset(Label* label);
1973
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001974 // The first argument is the reg field, the second argument is the r/m field.
1975 void emit_sse_operand(XMMRegister dst, XMMRegister src);
1976 void emit_sse_operand(XMMRegister reg, const Operand& adr);
1977 void emit_sse_operand(Register reg, const Operand& adr);
1978 void emit_sse_operand(XMMRegister dst, Register src);
1979 void emit_sse_operand(Register dst, XMMRegister src);
Ben Murdoch61f157c2016-09-16 13:49:30 +01001980 void emit_sse_operand(XMMRegister dst);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001981
Steve Blocka7e24c12009-10-30 11:49:00 +00001982 // Emit machine code for one of the operations ADD, ADC, SUB, SBC,
1983 // AND, OR, XOR, or CMP. The encodings of these operations are all
1984 // similar, differing just in the opcode or in the reg field of the
1985 // ModR/M byte.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001986 void arithmetic_op_8(byte opcode, Register reg, Register rm_reg);
1987 void arithmetic_op_8(byte opcode, Register reg, const Operand& rm_reg);
Steve Blocka7e24c12009-10-30 11:49:00 +00001988 void arithmetic_op_16(byte opcode, Register reg, Register rm_reg);
1989 void arithmetic_op_16(byte opcode, Register reg, const Operand& rm_reg);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001990 // Operate on operands/registers with pointer size, 32-bit or 64-bit size.
1991 void arithmetic_op(byte opcode, Register reg, Register rm_reg, int size);
1992 void arithmetic_op(byte opcode,
1993 Register reg,
1994 const Operand& rm_reg,
1995 int size);
Steve Blocka7e24c12009-10-30 11:49:00 +00001996 // Operate on a byte in memory or register.
1997 void immediate_arithmetic_op_8(byte subcode,
1998 Register dst,
1999 Immediate src);
2000 void immediate_arithmetic_op_8(byte subcode,
2001 const Operand& dst,
2002 Immediate src);
2003 // Operate on a word in memory or register.
2004 void immediate_arithmetic_op_16(byte subcode,
2005 Register dst,
2006 Immediate src);
2007 void immediate_arithmetic_op_16(byte subcode,
2008 const Operand& dst,
2009 Immediate src);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002010 // Operate on operands/registers with pointer size, 32-bit or 64-bit size.
2011 void immediate_arithmetic_op(byte subcode,
2012 Register dst,
2013 Immediate src,
2014 int size);
2015 void immediate_arithmetic_op(byte subcode,
2016 const Operand& dst,
2017 Immediate src,
2018 int size);
Steve Blocka7e24c12009-10-30 11:49:00 +00002019
2020 // Emit machine code for a shift operation.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002021 void shift(Operand dst, Immediate shift_amount, int subcode, int size);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002022 void shift(Register dst, Immediate shift_amount, int subcode, int size);
Steve Blocka7e24c12009-10-30 11:49:00 +00002023 // Shift dst by cl % 64 bits.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002024 void shift(Register dst, int subcode, int size);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002025 void shift(Operand dst, int subcode, int size);
Steve Blocka7e24c12009-10-30 11:49:00 +00002026
2027 void emit_farith(int b1, int b2, int i);
2028
2029 // labels
2030 // void print(Label* L);
2031 void bind_to(Label* L, int pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00002032
2033 // record reloc info for current pc_
2034 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
2035
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002036 // Arithmetics
2037 void emit_add(Register dst, Register src, int size) {
2038 arithmetic_op(0x03, dst, src, size);
2039 }
2040
2041 void emit_add(Register dst, Immediate src, int size) {
2042 immediate_arithmetic_op(0x0, dst, src, size);
2043 }
2044
2045 void emit_add(Register dst, const Operand& src, int size) {
2046 arithmetic_op(0x03, dst, src, size);
2047 }
2048
2049 void emit_add(const Operand& dst, Register src, int size) {
2050 arithmetic_op(0x1, src, dst, size);
2051 }
2052
2053 void emit_add(const Operand& dst, Immediate src, int size) {
2054 immediate_arithmetic_op(0x0, dst, src, size);
2055 }
2056
2057 void emit_and(Register dst, Register src, int size) {
2058 arithmetic_op(0x23, dst, src, size);
2059 }
2060
2061 void emit_and(Register dst, const Operand& src, int size) {
2062 arithmetic_op(0x23, dst, src, size);
2063 }
2064
2065 void emit_and(const Operand& dst, Register src, int size) {
2066 arithmetic_op(0x21, src, dst, size);
2067 }
2068
2069 void emit_and(Register dst, Immediate src, int size) {
2070 immediate_arithmetic_op(0x4, dst, src, size);
2071 }
2072
2073 void emit_and(const Operand& dst, Immediate src, int size) {
2074 immediate_arithmetic_op(0x4, dst, src, size);
2075 }
2076
2077 void emit_cmp(Register dst, Register src, int size) {
2078 arithmetic_op(0x3B, dst, src, size);
2079 }
2080
2081 void emit_cmp(Register dst, const Operand& src, int size) {
2082 arithmetic_op(0x3B, dst, src, size);
2083 }
2084
2085 void emit_cmp(const Operand& dst, Register src, int size) {
2086 arithmetic_op(0x39, src, dst, size);
2087 }
2088
2089 void emit_cmp(Register dst, Immediate src, int size) {
2090 immediate_arithmetic_op(0x7, dst, src, size);
2091 }
2092
2093 void emit_cmp(const Operand& dst, Immediate src, int size) {
2094 immediate_arithmetic_op(0x7, dst, src, size);
2095 }
2096
Ben Murdoch61f157c2016-09-16 13:49:30 +01002097 // Compare {al,ax,eax,rax} with src. If equal, set ZF and write dst into
2098 // src. Otherwise clear ZF and write src into {al,ax,eax,rax}. This
2099 // operation is only atomic if prefixed by the lock instruction.
2100 void emit_cmpxchg(const Operand& dst, Register src, int size);
2101
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002102 void emit_dec(Register dst, int size);
2103 void emit_dec(const Operand& dst, int size);
2104
2105 // Divide rdx:rax by src. Quotient in rax, remainder in rdx when size is 64.
2106 // Divide edx:eax by lower 32 bits of src. Quotient in eax, remainder in edx
2107 // when size is 32.
2108 void emit_idiv(Register src, int size);
2109 void emit_div(Register src, int size);
2110
2111 // Signed multiply instructions.
2112 // rdx:rax = rax * src when size is 64 or edx:eax = eax * src when size is 32.
2113 void emit_imul(Register src, int size);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002114 void emit_imul(const Operand& src, int size);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002115 void emit_imul(Register dst, Register src, int size);
2116 void emit_imul(Register dst, const Operand& src, int size);
2117 void emit_imul(Register dst, Register src, Immediate imm, int size);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002118 void emit_imul(Register dst, const Operand& src, Immediate imm, int size);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002119
2120 void emit_inc(Register dst, int size);
2121 void emit_inc(const Operand& dst, int size);
2122
2123 void emit_lea(Register dst, const Operand& src, int size);
2124
2125 void emit_mov(Register dst, const Operand& src, int size);
2126 void emit_mov(Register dst, Register src, int size);
2127 void emit_mov(const Operand& dst, Register src, int size);
2128 void emit_mov(Register dst, Immediate value, int size);
2129 void emit_mov(const Operand& dst, Immediate value, int size);
2130
2131 void emit_movzxb(Register dst, const Operand& src, int size);
2132 void emit_movzxb(Register dst, Register src, int size);
2133 void emit_movzxw(Register dst, const Operand& src, int size);
2134 void emit_movzxw(Register dst, Register src, int size);
2135
2136 void emit_neg(Register dst, int size);
2137 void emit_neg(const Operand& dst, int size);
2138
2139 void emit_not(Register dst, int size);
2140 void emit_not(const Operand& dst, int size);
2141
2142 void emit_or(Register dst, Register src, int size) {
2143 arithmetic_op(0x0B, dst, src, size);
2144 }
2145
2146 void emit_or(Register dst, const Operand& src, int size) {
2147 arithmetic_op(0x0B, dst, src, size);
2148 }
2149
2150 void emit_or(const Operand& dst, Register src, int size) {
2151 arithmetic_op(0x9, src, dst, size);
2152 }
2153
2154 void emit_or(Register dst, Immediate src, int size) {
2155 immediate_arithmetic_op(0x1, dst, src, size);
2156 }
2157
2158 void emit_or(const Operand& dst, Immediate src, int size) {
2159 immediate_arithmetic_op(0x1, dst, src, size);
2160 }
2161
2162 void emit_repmovs(int size);
2163
2164 void emit_sbb(Register dst, Register src, int size) {
2165 arithmetic_op(0x1b, dst, src, size);
2166 }
2167
2168 void emit_sub(Register dst, Register src, int size) {
2169 arithmetic_op(0x2B, dst, src, size);
2170 }
2171
2172 void emit_sub(Register dst, Immediate src, int size) {
2173 immediate_arithmetic_op(0x5, dst, src, size);
2174 }
2175
2176 void emit_sub(Register dst, const Operand& src, int size) {
2177 arithmetic_op(0x2B, dst, src, size);
2178 }
2179
2180 void emit_sub(const Operand& dst, Register src, int size) {
2181 arithmetic_op(0x29, src, dst, size);
2182 }
2183
2184 void emit_sub(const Operand& dst, Immediate src, int size) {
2185 immediate_arithmetic_op(0x5, dst, src, size);
2186 }
2187
2188 void emit_test(Register dst, Register src, int size);
2189 void emit_test(Register reg, Immediate mask, int size);
2190 void emit_test(const Operand& op, Register reg, int size);
2191 void emit_test(const Operand& op, Immediate mask, int size);
2192 void emit_test(Register reg, const Operand& op, int size) {
2193 return emit_test(op, reg, size);
2194 }
2195
2196 void emit_xchg(Register dst, Register src, int size);
2197 void emit_xchg(Register dst, const Operand& src, int size);
2198
2199 void emit_xor(Register dst, Register src, int size) {
2200 if (size == kInt64Size && dst.code() == src.code()) {
2201 // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
2202 // there is no need to make this a 64 bit operation.
2203 arithmetic_op(0x33, dst, src, kInt32Size);
2204 } else {
2205 arithmetic_op(0x33, dst, src, size);
2206 }
2207 }
2208
2209 void emit_xor(Register dst, const Operand& src, int size) {
2210 arithmetic_op(0x33, dst, src, size);
2211 }
2212
2213 void emit_xor(Register dst, Immediate src, int size) {
2214 immediate_arithmetic_op(0x6, dst, src, size);
2215 }
2216
2217 void emit_xor(const Operand& dst, Immediate src, int size) {
2218 immediate_arithmetic_op(0x6, dst, src, size);
2219 }
2220
2221 void emit_xor(const Operand& dst, Register src, int size) {
2222 arithmetic_op(0x31, src, dst, size);
2223 }
2224
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002225 // Most BMI instructions are similiar.
2226 void bmi1q(byte op, Register reg, Register vreg, Register rm);
2227 void bmi1q(byte op, Register reg, Register vreg, const Operand& rm);
2228 void bmi1l(byte op, Register reg, Register vreg, Register rm);
2229 void bmi1l(byte op, Register reg, Register vreg, const Operand& rm);
2230 void bmi2q(SIMDPrefix pp, byte op, Register reg, Register vreg, Register rm);
2231 void bmi2q(SIMDPrefix pp, byte op, Register reg, Register vreg,
2232 const Operand& rm);
2233 void bmi2l(SIMDPrefix pp, byte op, Register reg, Register vreg, Register rm);
2234 void bmi2l(SIMDPrefix pp, byte op, Register reg, Register vreg,
2235 const Operand& rm);
2236
Steve Blocka7e24c12009-10-30 11:49:00 +00002237 friend class CodePatcher;
2238 friend class EnsureSpace;
2239 friend class RegExpMacroAssemblerX64;
2240
Steve Blocka7e24c12009-10-30 11:49:00 +00002241 // code generation
Steve Blocka7e24c12009-10-30 11:49:00 +00002242 RelocInfoWriter reloc_info_writer;
2243
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002244 // Internal reference positions, required for (potential) patching in
2245 // GrowBuffer(); contains only those internal references whose labels
2246 // are already bound.
2247 std::deque<int> internal_reference_positions_;
2248
Steve Block3ce2e202009-11-05 08:53:23 +00002249 List< Handle<Code> > code_targets_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002250
Ben Murdochda12d292016-06-02 14:46:10 +01002251 AssemblerPositionsRecorder positions_recorder_;
2252 friend class AssemblerPositionsRecorder;
Steve Blocka7e24c12009-10-30 11:49:00 +00002253};
2254
2255
2256// Helper class that ensures that there is enough space for generating
2257// instructions and relocation information. The constructor makes
2258// sure that there is enough space and (in debug mode) the destructor
2259// checks that we did not generate too much.
2260class EnsureSpace BASE_EMBEDDED {
2261 public:
2262 explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) {
2263 if (assembler_->buffer_overflow()) assembler_->GrowBuffer();
2264#ifdef DEBUG
2265 space_before_ = assembler_->available_space();
2266#endif
2267 }
2268
2269#ifdef DEBUG
2270 ~EnsureSpace() {
2271 int bytes_generated = space_before_ - assembler_->available_space();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002272 DCHECK(bytes_generated < assembler_->kGap);
Steve Blocka7e24c12009-10-30 11:49:00 +00002273 }
2274#endif
2275
2276 private:
2277 Assembler* assembler_;
2278#ifdef DEBUG
2279 int space_before_;
2280#endif
2281};
2282
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002283} // namespace internal
2284} // namespace v8
Steve Blocka7e24c12009-10-30 11:49:00 +00002285
2286#endif // V8_X64_ASSEMBLER_X64_H_