blob: 2847ff2569c2d967de06334e74182dedb16e1520 [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 const char* ToString();
121 bool IsAllocatable() const;
122 bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
123 bool is(Register reg) const { return reg_code == reg.reg_code; }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100124 int code() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000125 DCHECK(is_valid());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000126 return reg_code;
Steve Blocka7e24c12009-10-30 11:49:00 +0000127 }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100128 int bit() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000129 DCHECK(is_valid());
130 return 1 << reg_code;
Steve Blocka7e24c12009-10-30 11:49:00 +0000131 }
132
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000133 bool is_byte_register() const { return reg_code <= 3; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000134 // Return the high bit of the register code as a 0 or 1. Used often
135 // when constructing the REX prefix byte.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000136 int high_bit() const { return reg_code >> 3; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000137 // Return the 3 low bits of the register code. Used when encoding registers
138 // in modR/M, SIB, and opcode bytes.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000139 int low_bits() const { return reg_code & 0x7; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000140
Andrei Popescu31002712010-02-23 13:46:05 +0000141 // Unfortunately we can't make this private in a struct when initializing
142 // by assignment.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000143 int reg_code;
Steve Blocka7e24c12009-10-30 11:49:00 +0000144};
145
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100146
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000147#define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R};
148GENERAL_REGISTERS(DECLARE_REGISTER)
149#undef DECLARE_REGISTER
150const Register no_reg = {Register::kCode_no_reg};
151
Steve Blocka7e24c12009-10-30 11:49:00 +0000152
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000153#ifdef _WIN64
154 // Windows calling convention
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000155const Register arg_reg_1 = {Register::kCode_rcx};
156const Register arg_reg_2 = {Register::kCode_rdx};
157const Register arg_reg_3 = {Register::kCode_r8};
158const Register arg_reg_4 = {Register::kCode_r9};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000159#else
160 // AMD64 calling convention
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000161const Register arg_reg_1 = {Register::kCode_rdi};
162const Register arg_reg_2 = {Register::kCode_rsi};
163const Register arg_reg_3 = {Register::kCode_rdx};
164const Register arg_reg_4 = {Register::kCode_rcx};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000165#endif // _WIN64
Steve Blocka7e24c12009-10-30 11:49:00 +0000166
Ben Murdochb0fe1622011-05-05 13:52:32 +0100167
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000168#define DOUBLE_REGISTERS(V) \
169 V(xmm0) \
170 V(xmm1) \
171 V(xmm2) \
172 V(xmm3) \
173 V(xmm4) \
174 V(xmm5) \
175 V(xmm6) \
176 V(xmm7) \
177 V(xmm8) \
178 V(xmm9) \
179 V(xmm10) \
180 V(xmm11) \
181 V(xmm12) \
182 V(xmm13) \
183 V(xmm14) \
184 V(xmm15)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400185
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000186#define ALLOCATABLE_DOUBLE_REGISTERS(V) \
187 V(xmm1) \
188 V(xmm2) \
189 V(xmm3) \
190 V(xmm4) \
191 V(xmm5) \
192 V(xmm6) \
193 V(xmm7) \
194 V(xmm8) \
195 V(xmm9) \
196 V(xmm10) \
197 V(xmm11) \
198 V(xmm12) \
199 V(xmm13) \
200 V(xmm14) \
201 V(xmm15)
Ben Murdochb0fe1622011-05-05 13:52:32 +0100202
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000203
204struct DoubleRegister {
205 enum Code {
206#define REGISTER_CODE(R) kCode_##R,
207 DOUBLE_REGISTERS(REGISTER_CODE)
208#undef REGISTER_CODE
209 kAfterLast,
210 kCode_no_reg = -1
211 };
212
213 static const int kMaxNumRegisters = Code::kAfterLast;
214
215 static DoubleRegister from_code(int code) {
216 DoubleRegister result = {code};
Ben Murdochb8e0da22011-05-16 14:20:40 +0100217 return result;
218 }
219
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000220 const char* ToString();
221 bool IsAllocatable() const;
222 bool is_valid() const { return 0 <= reg_code && reg_code < kMaxNumRegisters; }
223 bool is(DoubleRegister reg) const { return reg_code == reg.reg_code; }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100224 int code() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000225 DCHECK(is_valid());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000226 return reg_code;
Steve Blocka7e24c12009-10-30 11:49:00 +0000227 }
228
229 // Return the high bit of the register code as a 0 or 1. Used often
230 // when constructing the REX prefix byte.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000231 int high_bit() const { return reg_code >> 3; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000232 // Return the 3 low bits of the register code. Used when encoding registers
233 // in modR/M, SIB, and opcode bytes.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000234 int low_bits() const { return reg_code & 0x7; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000235
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000236 // Unfortunately we can't make this private in a struct when initializing
237 // by assignment.
238 int reg_code;
Steve Blocka7e24c12009-10-30 11:49:00 +0000239};
240
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000241
242#define DECLARE_REGISTER(R) \
243 const DoubleRegister R = {DoubleRegister::kCode_##R};
244DOUBLE_REGISTERS(DECLARE_REGISTER)
245#undef DECLARE_REGISTER
246const DoubleRegister no_double_reg = {DoubleRegister::kCode_no_reg};
Steve Blocka7e24c12009-10-30 11:49:00 +0000247
Ben Murdochb0fe1622011-05-05 13:52:32 +0100248
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000249typedef DoubleRegister XMMRegister;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100250
Ben Murdoch097c5b22016-05-18 11:27:45 +0100251typedef DoubleRegister Simd128Register;
252
Steve Blocka7e24c12009-10-30 11:49:00 +0000253enum Condition {
254 // any value < 0 is considered no_condition
255 no_condition = -1,
256
257 overflow = 0,
258 no_overflow = 1,
259 below = 2,
260 above_equal = 3,
261 equal = 4,
262 not_equal = 5,
263 below_equal = 6,
264 above = 7,
265 negative = 8,
266 positive = 9,
267 parity_even = 10,
268 parity_odd = 11,
269 less = 12,
270 greater_equal = 13,
271 less_equal = 14,
272 greater = 15,
273
Steve Block3ce2e202009-11-05 08:53:23 +0000274 // Fake conditions that are handled by the
275 // opcodes using them.
276 always = 16,
277 never = 17,
Steve Blocka7e24c12009-10-30 11:49:00 +0000278 // aliases
279 carry = below,
280 not_carry = above_equal,
281 zero = equal,
282 not_zero = not_equal,
283 sign = negative,
Steve Block3ce2e202009-11-05 08:53:23 +0000284 not_sign = positive,
285 last_condition = greater
Steve Blocka7e24c12009-10-30 11:49:00 +0000286};
287
288
289// Returns the equivalent of !cc.
290// Negation of the default no_condition (-1) results in a non-default
291// no_condition value (-2). As long as tests for no_condition check
292// for condition < 0, this will work as expected.
Kristian Monsen9dcf7e22010-06-28 14:14:28 +0100293inline Condition NegateCondition(Condition cc) {
294 return static_cast<Condition>(cc ^ 1);
295}
296
Steve Blocka7e24c12009-10-30 11:49:00 +0000297
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000298// Commute a condition such that {a cond b == b cond' a}.
299inline Condition CommuteCondition(Condition cc) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000300 switch (cc) {
301 case below:
302 return above;
303 case above:
304 return below;
305 case above_equal:
306 return below_equal;
307 case below_equal:
308 return above_equal;
309 case less:
310 return greater;
311 case greater:
312 return less;
313 case greater_equal:
314 return less_equal;
315 case less_equal:
316 return greater_equal;
317 default:
318 return cc;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000319 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000320}
321
Kristian Monsen9dcf7e22010-06-28 14:14:28 +0100322
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000323enum RoundingMode {
324 kRoundToNearest = 0x0,
325 kRoundDown = 0x1,
326 kRoundUp = 0x2,
327 kRoundToZero = 0x3
328};
329
330
Steve Blocka7e24c12009-10-30 11:49:00 +0000331// -----------------------------------------------------------------------------
332// Machine instruction Immediates
333
334class Immediate BASE_EMBEDDED {
335 public:
336 explicit Immediate(int32_t value) : value_(value) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000337 explicit Immediate(Smi* value) {
338 DCHECK(SmiValuesAre31Bits()); // Only available for 31-bit SMI.
339 value_ = static_cast<int32_t>(reinterpret_cast<intptr_t>(value));
340 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000341
342 private:
343 int32_t value_;
344
345 friend class Assembler;
346};
347
348
349// -----------------------------------------------------------------------------
350// Machine instruction Operands
351
352enum ScaleFactor {
353 times_1 = 0,
354 times_2 = 1,
355 times_4 = 2,
356 times_8 = 3,
357 times_int_size = times_4,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000358 times_pointer_size = (kPointerSize == 8) ? times_8 : times_4
Steve Blocka7e24c12009-10-30 11:49:00 +0000359};
360
361
362class Operand BASE_EMBEDDED {
363 public:
364 // [base + disp/r]
365 Operand(Register base, int32_t disp);
366
367 // [base + index*scale + disp/r]
368 Operand(Register base,
369 Register index,
370 ScaleFactor scale,
371 int32_t disp);
372
373 // [index*scale + disp/r]
374 Operand(Register index,
375 ScaleFactor scale,
376 int32_t disp);
377
Leon Clarkef7060e22010-06-03 12:02:55 +0100378 // Offset from existing memory operand.
379 // Offset is added to existing displacement as 32-bit signed values and
380 // this must not overflow.
381 Operand(const Operand& base, int32_t offset);
382
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000383 // [rip + disp/r]
384 explicit Operand(Label* label);
385
Steve Block1e0659c2011-05-24 12:43:12 +0100386 // Checks whether either base or index register is the given register.
387 // Does not check the "reg" part of the Operand.
388 bool AddressUsesRegister(Register reg) const;
389
Steve Block44f0eee2011-05-26 01:26:41 +0100390 // Queries related to the size of the generated instruction.
391 // Whether the generated instruction will have a REX prefix.
392 bool requires_rex() const { return rex_ != 0; }
393 // Size of the ModR/M, SIB and displacement parts of the generated
394 // instruction.
395 int operand_size() const { return len_; }
396
Steve Blocka7e24c12009-10-30 11:49:00 +0000397 private:
398 byte rex_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000399 byte buf_[9];
Steve Block1e0659c2011-05-24 12:43:12 +0100400 // The number of bytes of buf_ in use.
401 byte len_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000402
403 // Set the ModR/M byte without an encoded 'reg' register. The
404 // register is encoded later as part of the emit_operand operation.
405 // set_modrm can be called before or after set_sib and set_disp*.
406 inline void set_modrm(int mod, Register rm);
407
408 // Set the SIB byte if one is needed. Sets the length to 2 rather than 1.
409 inline void set_sib(ScaleFactor scale, Register index, Register base);
410
411 // Adds operand displacement fields (offsets added to the memory address).
412 // Needs to be called after set_sib, not before it.
413 inline void set_disp8(int disp);
414 inline void set_disp32(int disp);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000415 inline void set_disp64(int64_t disp); // for labels.
Steve Blocka7e24c12009-10-30 11:49:00 +0000416
417 friend class Assembler;
418};
419
420
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000421#define ASSEMBLER_INSTRUCTION_LIST(V) \
422 V(add) \
423 V(and) \
424 V(cmp) \
425 V(dec) \
426 V(idiv) \
427 V(div) \
428 V(imul) \
429 V(inc) \
430 V(lea) \
431 V(mov) \
432 V(movzxb) \
433 V(movzxw) \
434 V(neg) \
435 V(not) \
436 V(or) \
437 V(repmovs) \
438 V(sbb) \
439 V(sub) \
440 V(test) \
441 V(xchg) \
442 V(xor)
Steve Block44f0eee2011-05-26 01:26:41 +0100443
Ben Murdoch8b112d22011-06-08 16:22:53 +0100444
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000445// Shift instructions on operands/registers with kPointerSize, kInt32Size and
446// kInt64Size.
447#define SHIFT_INSTRUCTION_LIST(V) \
448 V(rol, 0x0) \
449 V(ror, 0x1) \
450 V(rcl, 0x2) \
451 V(rcr, 0x3) \
452 V(shl, 0x4) \
453 V(shr, 0x5) \
454 V(sar, 0x7) \
Steve Blocka7e24c12009-10-30 11:49:00 +0000455
456
Steve Block44f0eee2011-05-26 01:26:41 +0100457class Assembler : public AssemblerBase {
Steve Blocka7e24c12009-10-30 11:49:00 +0000458 private:
459 // We check before assembling an instruction that there is sufficient
460 // space to write an instruction and its relocation information.
461 // The relocation writer's position must be kGap bytes above the end of
462 // the generated instructions. This leaves enough space for the
463 // longest possible x64 instruction, 15 bytes, and the longest possible
464 // relocation information encoding, RelocInfoWriter::kMaxLength == 16.
465 // (There is a 15 byte limit on x64 instruction length that rules out some
466 // otherwise valid instructions.)
467 // This allows for a single, fast space check per instruction.
468 static const int kGap = 32;
469
470 public:
471 // Create an assembler. Instructions and relocation information are emitted
472 // into a buffer, with the instructions starting from the beginning and the
473 // relocation information starting from the end of the buffer. See CodeDesc
474 // for a detailed comment on the layout (globals.h).
475 //
476 // If the provided buffer is NULL, the assembler allocates and grows its own
477 // buffer, and buffer_size determines the initial buffer size. The buffer is
478 // owned by the assembler and deallocated upon destruction of the assembler.
479 //
480 // If the provided buffer is not NULL, the assembler uses the provided buffer
481 // for code generation and assumes its size to be buffer_size. If the buffer
482 // is too small, a fatal error occurs. No deallocation of the buffer is done
483 // upon destruction of the assembler.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100484 Assembler(Isolate* isolate, void* buffer, int buffer_size);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000485 virtual ~Assembler() { }
Steve Block44f0eee2011-05-26 01:26:41 +0100486
Steve Blocka7e24c12009-10-30 11:49:00 +0000487 // GetCode emits any pending (non-emitted) code and fills the descriptor
488 // desc. GetCode() is idempotent; it returns the same result if no other
489 // Assembler functions are invoked in between GetCode() calls.
490 void GetCode(CodeDesc* desc);
491
Steve Block3ce2e202009-11-05 08:53:23 +0000492 // Read/Modify the code target in the relative branch/call instruction at pc.
493 // On the x64 architecture, we use relative jumps with a 32-bit displacement
494 // to jump to other Code objects in the Code space in the heap.
495 // Jumps to C functions are done indirectly through a 64-bit register holding
496 // the absolute address of the target.
497 // These functions convert between absolute Addresses of Code objects and
498 // the relative displacements stored in the code.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000499 static inline Address target_address_at(Address pc, Address constant_pool);
500 static inline void set_target_address_at(
501 Isolate* isolate, Address pc, Address constant_pool, Address target,
502 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000503 static inline Address target_address_at(Address pc, Code* code) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000504 Address constant_pool = code ? code->constant_pool() : NULL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000505 return target_address_at(pc, constant_pool);
506 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000507 static inline void set_target_address_at(
508 Isolate* isolate, Address pc, Code* code, Address target,
509 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED) {
510 Address constant_pool = code ? code->constant_pool() : NULL;
511 set_target_address_at(isolate, pc, constant_pool, target,
512 icache_flush_mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000513 }
514
515 // Return the code target address at a call site from the return address
516 // of that call in the instruction stream.
517 static inline Address target_address_from_return_address(Address pc);
518
Steve Blockd0582a62009-12-15 09:54:21 +0000519 // This sets the branch destination (which is in the instruction on x64).
520 // This is for calls and branches within generated code.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100521 inline static void deserialization_set_special_target_at(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000522 Isolate* isolate, Address instruction_payload, Code* code,
523 Address target) {
524 set_target_address_at(isolate, instruction_payload, code, target);
Steve Blockd0582a62009-12-15 09:54:21 +0000525 }
526
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000527 // This sets the internal reference at the pc.
528 inline static void deserialization_set_target_internal_reference_at(
529 Isolate* isolate, Address pc, Address target,
530 RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
531
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000532 static inline RelocInfo::Mode RelocInfoNone() {
533 if (kPointerSize == kInt64Size) {
534 return RelocInfo::NONE64;
535 } else {
536 DCHECK(kPointerSize == kInt32Size);
537 return RelocInfo::NONE32;
538 }
Steve Blockd0582a62009-12-15 09:54:21 +0000539 }
540
Steve Block3ce2e202009-11-05 08:53:23 +0000541 inline Handle<Object> code_target_object_handle_at(Address pc);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000542 inline Address runtime_entry_at(Address pc);
Steve Blockd0582a62009-12-15 09:54:21 +0000543 // Number of bytes taken up by the branch target in the code.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100544 static const int kSpecialTargetSize = 4; // Use 32-bit displacement.
Steve Blocka7e24c12009-10-30 11:49:00 +0000545 // Distance between the address of the code target in the call instruction
Steve Block3ce2e202009-11-05 08:53:23 +0000546 // and the return address pushed on the stack.
547 static const int kCallTargetAddressOffset = 4; // Use 32-bit displacement.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000548 // The length of call(kScratchRegister).
549 static const int kCallScratchRegisterInstructionLength = 3;
550 // The length of call(Immediate32).
Steve Block1e0659c2011-05-24 12:43:12 +0100551 static const int kShortCallInstructionLength = 5;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000552 // The length of movq(kScratchRegister, address).
553 static const int kMoveAddressIntoScratchRegisterInstructionLength =
554 2 + kPointerSize;
555 // The length of movq(kScratchRegister, address) and call(kScratchRegister).
556 static const int kCallSequenceLength =
557 kMoveAddressIntoScratchRegisterInstructionLength +
558 kCallScratchRegisterInstructionLength;
Steve Blockd0582a62009-12-15 09:54:21 +0000559
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000560 // The debug break slot must be able to contain an indirect call sequence.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000561 static const int kDebugBreakSlotLength = kCallSequenceLength;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000562 // Distance between start of patched debug break slot and the emitted address
563 // to jump to.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000564 static const int kPatchDebugBreakSlotAddressOffset =
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000565 kMoveAddressIntoScratchRegisterInstructionLength - kPointerSize;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100566
Steve Block9fac8402011-05-12 15:51:54 +0100567 // One byte opcode for test eax,0xXXXXXXXX.
568 static const byte kTestEaxByte = 0xA9;
Steve Block1e0659c2011-05-24 12:43:12 +0100569 // One byte opcode for test al, 0xXX.
570 static const byte kTestAlByte = 0xA8;
571 // One byte opcode for nop.
572 static const byte kNopByte = 0x90;
573
574 // One byte prefix for a short conditional jump.
575 static const byte kJccShortPrefix = 0x70;
576 static const byte kJncShortOpcode = kJccShortPrefix | not_carry;
577 static const byte kJcShortOpcode = kJccShortPrefix | carry;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000578 static const byte kJnzShortOpcode = kJccShortPrefix | not_zero;
579 static const byte kJzShortOpcode = kJccShortPrefix | zero;
Steve Block1e0659c2011-05-24 12:43:12 +0100580
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000581 // VEX prefix encodings.
582 enum SIMDPrefix { kNone = 0x0, k66 = 0x1, kF3 = 0x2, kF2 = 0x3 };
583 enum VectorLength { kL128 = 0x0, kL256 = 0x4, kLIG = kL128, kLZ = kL128 };
584 enum VexW { kW0 = 0x0, kW1 = 0x80, kWIG = kW0 };
585 enum LeadingOpcode { k0F = 0x1, k0F38 = 0x2, k0F3A = 0x3 };
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100586
Steve Blocka7e24c12009-10-30 11:49:00 +0000587 // ---------------------------------------------------------------------------
588 // Code generation
589 //
590 // Function names correspond one-to-one to x64 instruction mnemonics.
591 // Unless specified otherwise, instructions operate on 64-bit operands.
592 //
593 // If we need versions of an assembly instruction that operate on different
594 // width arguments, we add a single-letter suffix specifying the width.
595 // This is done for the following instructions: mov, cmp, inc, dec,
596 // add, sub, and test.
597 // There are no versions of these instructions without the suffix.
598 // - Instructions on 8-bit (byte) operands/registers have a trailing 'b'.
599 // - Instructions on 16-bit (word) operands/registers have a trailing 'w'.
600 // - Instructions on 32-bit (doubleword) operands/registers use 'l'.
601 // - Instructions on 64-bit (quadword) operands/registers use 'q'.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000602 // - Instructions on operands/registers with pointer size use 'p'.
603
604 STATIC_ASSERT(kPointerSize == kInt64Size || kPointerSize == kInt32Size);
605
606#define DECLARE_INSTRUCTION(instruction) \
607 template<class P1> \
608 void instruction##p(P1 p1) { \
609 emit_##instruction(p1, kPointerSize); \
610 } \
611 \
612 template<class P1> \
613 void instruction##l(P1 p1) { \
614 emit_##instruction(p1, kInt32Size); \
615 } \
616 \
617 template<class P1> \
618 void instruction##q(P1 p1) { \
619 emit_##instruction(p1, kInt64Size); \
620 } \
621 \
622 template<class P1, class P2> \
623 void instruction##p(P1 p1, P2 p2) { \
624 emit_##instruction(p1, p2, kPointerSize); \
625 } \
626 \
627 template<class P1, class P2> \
628 void instruction##l(P1 p1, P2 p2) { \
629 emit_##instruction(p1, p2, kInt32Size); \
630 } \
631 \
632 template<class P1, class P2> \
633 void instruction##q(P1 p1, P2 p2) { \
634 emit_##instruction(p1, p2, kInt64Size); \
635 } \
636 \
637 template<class P1, class P2, class P3> \
638 void instruction##p(P1 p1, P2 p2, P3 p3) { \
639 emit_##instruction(p1, p2, p3, kPointerSize); \
640 } \
641 \
642 template<class P1, class P2, class P3> \
643 void instruction##l(P1 p1, P2 p2, P3 p3) { \
644 emit_##instruction(p1, p2, p3, kInt32Size); \
645 } \
646 \
647 template<class P1, class P2, class P3> \
648 void instruction##q(P1 p1, P2 p2, P3 p3) { \
649 emit_##instruction(p1, p2, p3, kInt64Size); \
650 }
651 ASSEMBLER_INSTRUCTION_LIST(DECLARE_INSTRUCTION)
652#undef DECLARE_INSTRUCTION
Steve Blocka7e24c12009-10-30 11:49:00 +0000653
654 // Insert the smallest number of nop instructions
655 // possible to align the pc offset to a multiple
Steve Block1e0659c2011-05-24 12:43:12 +0100656 // of m, where m must be a power of 2.
Steve Blocka7e24c12009-10-30 11:49:00 +0000657 void Align(int m);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000658 // Insert the smallest number of zero bytes possible to align the pc offset
659 // to a mulitple of m. m must be a power of 2 (>= 2).
660 void DataAlign(int m);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100661 void Nop(int bytes = 1);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +0100662 // Aligns code to something that's optimal for a jump target for the platform.
663 void CodeTargetAlign();
Steve Blocka7e24c12009-10-30 11:49:00 +0000664
665 // Stack
666 void pushfq();
667 void popfq();
668
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000669 void pushq(Immediate value);
Steve Block1e0659c2011-05-24 12:43:12 +0100670 // Push a 32 bit integer, and guarantee that it is actually pushed as a
671 // 32 bit value, the normal push will optimize the 8 bit case.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000672 void pushq_imm32(int32_t imm32);
673 void pushq(Register src);
674 void pushq(const Operand& src);
Steve Blocka7e24c12009-10-30 11:49:00 +0000675
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000676 void popq(Register dst);
677 void popq(const Operand& dst);
Steve Blocka7e24c12009-10-30 11:49:00 +0000678
679 void enter(Immediate size);
680 void leave();
681
682 // Moves
683 void movb(Register dst, const Operand& src);
684 void movb(Register dst, Immediate imm);
685 void movb(const Operand& dst, Register src);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000686 void movb(const Operand& dst, Immediate imm);
Steve Blocka7e24c12009-10-30 11:49:00 +0000687
Steve Block3ce2e202009-11-05 08:53:23 +0000688 // Move the low 16 bits of a 64-bit register value to a 16-bit
689 // memory location.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000690 void movw(Register dst, const Operand& src);
Steve Block3ce2e202009-11-05 08:53:23 +0000691 void movw(const Operand& dst, Register src);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000692 void movw(const Operand& dst, Immediate imm);
Steve Block3ce2e202009-11-05 08:53:23 +0000693
Steve Blocka7e24c12009-10-30 11:49:00 +0000694 // Move the offset of the label location relative to the current
695 // position (after the move) to the destination.
696 void movl(const Operand& dst, Label* src);
697
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000698 // Loads a pointer into a register with a relocation mode.
699 void movp(Register dst, void* ptr, RelocInfo::Mode rmode);
Steve Blocka7e24c12009-10-30 11:49:00 +0000700
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000701 // Loads a 64-bit immediate into a register.
702 void movq(Register dst, int64_t value);
703 void movq(Register dst, uint64_t value);
704
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400705 void movsxbl(Register dst, Register src);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000706 void movsxbl(Register dst, const Operand& src);
Steve Block3ce2e202009-11-05 08:53:23 +0000707 void movsxbq(Register dst, const Operand& src);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400708 void movsxwl(Register dst, Register src);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000709 void movsxwl(Register dst, const Operand& src);
Steve Block3ce2e202009-11-05 08:53:23 +0000710 void movsxwq(Register dst, const Operand& src);
Steve Blocka7e24c12009-10-30 11:49:00 +0000711 void movsxlq(Register dst, Register src);
712 void movsxlq(Register dst, const Operand& src);
Steve Blocka7e24c12009-10-30 11:49:00 +0000713
Leon Clarked91b9f72010-01-27 17:25:45 +0000714 // Repeated moves.
715
716 void repmovsb();
717 void repmovsw();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000718 void repmovsp() { emit_repmovs(kPointerSize); }
719 void repmovsl() { emit_repmovs(kInt32Size); }
720 void repmovsq() { emit_repmovs(kInt64Size); }
Leon Clarked91b9f72010-01-27 17:25:45 +0000721
Steve Block44f0eee2011-05-26 01:26:41 +0100722 // Instruction to load from an immediate 64-bit pointer into RAX.
Steve Blocka7e24c12009-10-30 11:49:00 +0000723 void load_rax(void* ptr, RelocInfo::Mode rmode);
724 void load_rax(ExternalReference ext);
725
726 // Conditional moves.
727 void cmovq(Condition cc, Register dst, Register src);
728 void cmovq(Condition cc, Register dst, const Operand& src);
729 void cmovl(Condition cc, Register dst, Register src);
730 void cmovl(Condition cc, Register dst, const Operand& src);
731
Steve Blocka7e24c12009-10-30 11:49:00 +0000732 void cmpb(Register dst, Immediate src) {
733 immediate_arithmetic_op_8(0x7, dst, src);
734 }
735
736 void cmpb_al(Immediate src);
737
738 void cmpb(Register dst, Register src) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000739 arithmetic_op_8(0x3A, dst, src);
Steve Blocka7e24c12009-10-30 11:49:00 +0000740 }
741
742 void cmpb(Register dst, const Operand& src) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000743 arithmetic_op_8(0x3A, dst, src);
Steve Blocka7e24c12009-10-30 11:49:00 +0000744 }
745
746 void cmpb(const Operand& dst, Register src) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000747 arithmetic_op_8(0x38, src, dst);
Steve Blocka7e24c12009-10-30 11:49:00 +0000748 }
749
750 void cmpb(const Operand& dst, Immediate src) {
751 immediate_arithmetic_op_8(0x7, dst, src);
752 }
753
754 void cmpw(const Operand& dst, Immediate src) {
755 immediate_arithmetic_op_16(0x7, dst, src);
756 }
757
758 void cmpw(Register dst, Immediate src) {
759 immediate_arithmetic_op_16(0x7, dst, src);
760 }
761
762 void cmpw(Register dst, const Operand& src) {
763 arithmetic_op_16(0x3B, dst, src);
764 }
765
766 void cmpw(Register dst, Register src) {
767 arithmetic_op_16(0x3B, dst, src);
768 }
769
770 void cmpw(const Operand& dst, Register src) {
771 arithmetic_op_16(0x39, src, dst);
772 }
773
Leon Clarke4515c472010-02-03 11:58:03 +0000774 void andb(Register dst, Immediate src) {
775 immediate_arithmetic_op_8(0x4, dst, src);
776 }
Steve Block3ce2e202009-11-05 08:53:23 +0000777
Steve Block3ce2e202009-11-05 08:53:23 +0000778 void decb(Register dst);
779 void decb(const Operand& dst);
Steve Blocka7e24c12009-10-30 11:49:00 +0000780
781 // Sign-extends rax into rdx:rax.
782 void cqo();
783 // Sign-extends eax into edx:eax.
784 void cdq();
785
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400786 // Multiply eax by src, put the result in edx:eax.
787 void mull(Register src);
788 void mull(const Operand& src);
Steve Blocka7e24c12009-10-30 11:49:00 +0000789 // Multiply rax by src, put the result in rdx:rax.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400790 void mulq(Register src);
Steve Blocka7e24c12009-10-30 11:49:00 +0000791
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400792#define DECLARE_SHIFT_INSTRUCTION(instruction, subcode) \
793 void instruction##p(Register dst, Immediate imm8) { \
794 shift(dst, imm8, subcode, kPointerSize); \
795 } \
796 \
797 void instruction##l(Register dst, Immediate imm8) { \
798 shift(dst, imm8, subcode, kInt32Size); \
799 } \
800 \
801 void instruction##q(Register dst, Immediate imm8) { \
802 shift(dst, imm8, subcode, kInt64Size); \
803 } \
804 \
805 void instruction##p(Operand dst, Immediate imm8) { \
806 shift(dst, imm8, subcode, kPointerSize); \
807 } \
808 \
809 void instruction##l(Operand dst, Immediate imm8) { \
810 shift(dst, imm8, subcode, kInt32Size); \
811 } \
812 \
813 void instruction##q(Operand dst, Immediate imm8) { \
814 shift(dst, imm8, subcode, kInt64Size); \
815 } \
816 \
817 void instruction##p_cl(Register dst) { shift(dst, subcode, kPointerSize); } \
818 \
819 void instruction##l_cl(Register dst) { shift(dst, subcode, kInt32Size); } \
820 \
821 void instruction##q_cl(Register dst) { shift(dst, subcode, kInt64Size); } \
822 \
823 void instruction##p_cl(Operand dst) { shift(dst, subcode, kPointerSize); } \
824 \
825 void instruction##l_cl(Operand dst) { shift(dst, subcode, kInt32Size); } \
826 \
827 void instruction##q_cl(Operand dst) { shift(dst, subcode, kInt64Size); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000828 SHIFT_INSTRUCTION_LIST(DECLARE_SHIFT_INSTRUCTION)
829#undef DECLARE_SHIFT_INSTRUCTION
Steve Blocka7e24c12009-10-30 11:49:00 +0000830
831 // Shifts dst:src left by cl bits, affecting only dst.
832 void shld(Register dst, Register src);
833
834 // Shifts src:dst right by cl bits, affecting only dst.
835 void shrd(Register dst, Register src);
836
Steve Blocka7e24c12009-10-30 11:49:00 +0000837 void store_rax(void* dst, RelocInfo::Mode mode);
838 void store_rax(ExternalReference ref);
839
Steve Blocka7e24c12009-10-30 11:49:00 +0000840 void subb(Register dst, Immediate src) {
841 immediate_arithmetic_op_8(0x5, dst, src);
842 }
843
Steve Block3ce2e202009-11-05 08:53:23 +0000844 void testb(Register dst, Register src);
Steve Blocka7e24c12009-10-30 11:49:00 +0000845 void testb(Register reg, Immediate mask);
846 void testb(const Operand& op, Immediate mask);
Leon Clarkee46be812010-01-19 14:06:41 +0000847 void testb(const Operand& op, Register reg);
Steve Blocka7e24c12009-10-30 11:49:00 +0000848
849 // Bit operations.
850 void bt(const Operand& dst, Register src);
851 void bts(const Operand& dst, Register src);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000852 void bsrq(Register dst, Register src);
853 void bsrq(Register dst, const Operand& src);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000854 void bsrl(Register dst, Register src);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000855 void bsrl(Register dst, const Operand& src);
856 void bsfq(Register dst, Register src);
857 void bsfq(Register dst, const Operand& src);
858 void bsfl(Register dst, Register src);
859 void bsfl(Register dst, const Operand& src);
Steve Blocka7e24c12009-10-30 11:49:00 +0000860
861 // Miscellaneous
Steve Block3ce2e202009-11-05 08:53:23 +0000862 void clc();
Steve Block44f0eee2011-05-26 01:26:41 +0100863 void cld();
Steve Blocka7e24c12009-10-30 11:49:00 +0000864 void cpuid();
865 void hlt();
866 void int3();
867 void nop();
Steve Blocka7e24c12009-10-30 11:49:00 +0000868 void ret(int imm16);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000869 void ud2();
Steve Blocka7e24c12009-10-30 11:49:00 +0000870 void setcc(Condition cc, Register reg);
871
872 // Label operations & relative jumps (PPUM Appendix D)
873 //
874 // Takes a branch opcode (cc) and a label (L) and generates
875 // either a backward branch or a forward branch and links it
876 // to the label fixup chain. Usage:
877 //
878 // Label L; // unbound label
879 // j(cc, &L); // forward branch to unbound label
880 // bind(&L); // bind label to the current pc
881 // j(cc, &L); // backward branch to bound label
882 // bind(&L); // illegal: a label may be bound only once
883 //
884 // Note: The same Label can be used for forward and backward branches
885 // but it may be bound only once.
886
887 void bind(Label* L); // binds an unbound label L to the current code position
888
889 // Calls
890 // Call near relative 32-bit displacement, relative to next instruction.
891 void call(Label* L);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000892 void call(Address entry, RelocInfo::Mode rmode);
Ben Murdoch257744e2011-11-30 15:57:28 +0000893 void call(Handle<Code> target,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000894 RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000895 TypeFeedbackId ast_id = TypeFeedbackId::None());
Steve Blocka7e24c12009-10-30 11:49:00 +0000896
Steve Block1e0659c2011-05-24 12:43:12 +0100897 // Calls directly to the given address using a relative offset.
898 // Should only ever be used in Code objects for calls within the
899 // same Code object. Should not be used when generating new code (use labels),
900 // but only when patching existing code.
901 void call(Address target);
902
Steve Blocka7e24c12009-10-30 11:49:00 +0000903 // Call near absolute indirect, address in register
904 void call(Register adr);
905
Steve Blocka7e24c12009-10-30 11:49:00 +0000906 // Jumps
907 // Jump short or near relative.
Steve Block3ce2e202009-11-05 08:53:23 +0000908 // Use a 32-bit signed displacement.
Ben Murdoch257744e2011-11-30 15:57:28 +0000909 // Unconditional jump to L
910 void jmp(Label* L, Label::Distance distance = Label::kFar);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000911 void jmp(Address entry, RelocInfo::Mode rmode);
Steve Block3ce2e202009-11-05 08:53:23 +0000912 void jmp(Handle<Code> target, RelocInfo::Mode rmode);
Steve Blocka7e24c12009-10-30 11:49:00 +0000913
914 // Jump near absolute indirect (r64)
915 void jmp(Register adr);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000916 void jmp(const Operand& src);
Steve Blocka7e24c12009-10-30 11:49:00 +0000917
Steve Blocka7e24c12009-10-30 11:49:00 +0000918 // Conditional jumps
Ben Murdoch257744e2011-11-30 15:57:28 +0000919 void j(Condition cc,
920 Label* L,
921 Label::Distance distance = Label::kFar);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000922 void j(Condition cc, Address entry, RelocInfo::Mode rmode);
Steve Block3ce2e202009-11-05 08:53:23 +0000923 void j(Condition cc, Handle<Code> target, RelocInfo::Mode rmode);
Steve Blocka7e24c12009-10-30 11:49:00 +0000924
925 // Floating-point operations
926 void fld(int i);
927
928 void fld1();
929 void fldz();
Steve Block6ded16b2010-05-10 14:33:55 +0100930 void fldpi();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100931 void fldln2();
Steve Blocka7e24c12009-10-30 11:49:00 +0000932
933 void fld_s(const Operand& adr);
934 void fld_d(const Operand& adr);
935
936 void fstp_s(const Operand& adr);
937 void fstp_d(const Operand& adr);
Steve Block3ce2e202009-11-05 08:53:23 +0000938 void fstp(int index);
Steve Blocka7e24c12009-10-30 11:49:00 +0000939
940 void fild_s(const Operand& adr);
941 void fild_d(const Operand& adr);
942
943 void fist_s(const Operand& adr);
944
945 void fistp_s(const Operand& adr);
946 void fistp_d(const Operand& adr);
947
948 void fisttp_s(const Operand& adr);
Leon Clarked91b9f72010-01-27 17:25:45 +0000949 void fisttp_d(const Operand& adr);
Steve Blocka7e24c12009-10-30 11:49:00 +0000950
951 void fabs();
952 void fchs();
953
954 void fadd(int i);
955 void fsub(int i);
956 void fmul(int i);
957 void fdiv(int i);
958
959 void fisub_s(const Operand& adr);
960
961 void faddp(int i = 1);
962 void fsubp(int i = 1);
963 void fsubrp(int i = 1);
964 void fmulp(int i = 1);
965 void fdivp(int i = 1);
966 void fprem();
967 void fprem1();
968
969 void fxch(int i = 1);
970 void fincstp();
971 void ffree(int i = 0);
972
973 void ftst();
974 void fucomp(int i);
975 void fucompp();
Steve Block3ce2e202009-11-05 08:53:23 +0000976 void fucomi(int i);
977 void fucomip();
978
Steve Blocka7e24c12009-10-30 11:49:00 +0000979 void fcompp();
980 void fnstsw_ax();
981 void fwait();
982 void fnclex();
983
984 void fsin();
985 void fcos();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100986 void fptan();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100987 void fyl2x();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100988 void f2xm1();
989 void fscale();
990 void fninit();
Steve Blocka7e24c12009-10-30 11:49:00 +0000991
992 void frndint();
993
994 void sahf();
995
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000996 // SSE instructions
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400997 void addss(XMMRegister dst, XMMRegister src);
998 void addss(XMMRegister dst, const Operand& src);
999 void subss(XMMRegister dst, XMMRegister src);
1000 void subss(XMMRegister dst, const Operand& src);
1001 void mulss(XMMRegister dst, XMMRegister src);
1002 void mulss(XMMRegister dst, const Operand& src);
1003 void divss(XMMRegister dst, XMMRegister src);
1004 void divss(XMMRegister dst, const Operand& src);
1005
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001006 void maxss(XMMRegister dst, XMMRegister src);
1007 void maxss(XMMRegister dst, const Operand& src);
1008 void minss(XMMRegister dst, XMMRegister src);
1009 void minss(XMMRegister dst, const Operand& src);
1010
1011 void sqrtss(XMMRegister dst, XMMRegister src);
1012 void sqrtss(XMMRegister dst, const Operand& src);
1013
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001014 void ucomiss(XMMRegister dst, XMMRegister src);
1015 void ucomiss(XMMRegister dst, const Operand& src);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001016 void movaps(XMMRegister dst, XMMRegister src);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001017
1018 // Don't use this unless it's important to keep the
1019 // top half of the destination register unchanged.
1020 // Use movaps when moving float values and movd for integer
1021 // values in xmm registers.
1022 void movss(XMMRegister dst, XMMRegister src);
1023
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001024 void movss(XMMRegister dst, const Operand& src);
1025 void movss(const Operand& dst, XMMRegister src);
1026 void shufps(XMMRegister dst, XMMRegister src, byte imm8);
1027
1028 void cvttss2si(Register dst, const Operand& src);
1029 void cvttss2si(Register dst, XMMRegister src);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001030 void cvtlsi2ss(XMMRegister dst, const Operand& src);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001031 void cvtlsi2ss(XMMRegister dst, Register src);
1032
1033 void andps(XMMRegister dst, XMMRegister src);
1034 void andps(XMMRegister dst, const Operand& src);
1035 void orps(XMMRegister dst, XMMRegister src);
1036 void orps(XMMRegister dst, const Operand& src);
1037 void xorps(XMMRegister dst, XMMRegister src);
1038 void xorps(XMMRegister dst, const Operand& src);
1039
1040 void addps(XMMRegister dst, XMMRegister src);
1041 void addps(XMMRegister dst, const Operand& src);
1042 void subps(XMMRegister dst, XMMRegister src);
1043 void subps(XMMRegister dst, const Operand& src);
1044 void mulps(XMMRegister dst, XMMRegister src);
1045 void mulps(XMMRegister dst, const Operand& src);
1046 void divps(XMMRegister dst, XMMRegister src);
1047 void divps(XMMRegister dst, const Operand& src);
1048
1049 void movmskps(Register dst, XMMRegister src);
1050
Steve Blocka7e24c12009-10-30 11:49:00 +00001051 // SSE2 instructions
Steve Block6ded16b2010-05-10 14:33:55 +01001052 void movd(XMMRegister dst, Register src);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001053 void movd(XMMRegister dst, const Operand& src);
Steve Block6ded16b2010-05-10 14:33:55 +01001054 void movd(Register dst, XMMRegister src);
1055 void movq(XMMRegister dst, Register src);
1056 void movq(Register dst, XMMRegister src);
Ben Murdoch257744e2011-11-30 15:57:28 +00001057 void movq(XMMRegister dst, XMMRegister src);
Steve Block6ded16b2010-05-10 14:33:55 +01001058
Ben Murdoch257744e2011-11-30 15:57:28 +00001059 // Don't use this unless it's important to keep the
1060 // top half of the destination register unchanged.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001061 // Use movapd when moving double values and movq for integer
Ben Murdoch257744e2011-11-30 15:57:28 +00001062 // values in xmm registers.
Steve Block053d10c2011-06-13 19:13:29 +01001063 void movsd(XMMRegister dst, XMMRegister src);
Ben Murdoch257744e2011-11-30 15:57:28 +00001064
1065 void movsd(const Operand& dst, XMMRegister src);
Steve Block6ded16b2010-05-10 14:33:55 +01001066 void movsd(XMMRegister dst, const Operand& src);
Steve Blocka7e24c12009-10-30 11:49:00 +00001067
Steve Block1e0659c2011-05-24 12:43:12 +01001068 void movdqa(const Operand& dst, XMMRegister src);
1069 void movdqa(XMMRegister dst, const Operand& src);
1070
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001071 void movdqu(const Operand& dst, XMMRegister src);
1072 void movdqu(XMMRegister dst, const Operand& src);
1073
Ben Murdoch257744e2011-11-30 15:57:28 +00001074 void movapd(XMMRegister dst, XMMRegister src);
Ben Murdoch257744e2011-11-30 15:57:28 +00001075
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001076 void psllq(XMMRegister reg, byte imm8);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001077 void psrlq(XMMRegister reg, byte imm8);
1078 void pslld(XMMRegister reg, byte imm8);
1079 void psrld(XMMRegister reg, byte imm8);
Steve Block8defd9f2010-07-08 12:39:36 +01001080
Steve Blocka7e24c12009-10-30 11:49:00 +00001081 void cvttsd2si(Register dst, const Operand& src);
Steve Block1e0659c2011-05-24 12:43:12 +01001082 void cvttsd2si(Register dst, XMMRegister src);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001083 void cvttss2siq(Register dst, XMMRegister src);
1084 void cvttss2siq(Register dst, const Operand& src);
Kristian Monsen25f61362010-05-21 11:50:48 +01001085 void cvttsd2siq(Register dst, XMMRegister src);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001086 void cvttsd2siq(Register dst, const Operand& src);
Steve Blocka7e24c12009-10-30 11:49:00 +00001087
1088 void cvtlsi2sd(XMMRegister dst, const Operand& src);
1089 void cvtlsi2sd(XMMRegister dst, Register src);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001090
1091 void cvtqsi2ss(XMMRegister dst, const Operand& src);
1092 void cvtqsi2ss(XMMRegister dst, Register src);
1093
Steve Blocka7e24c12009-10-30 11:49:00 +00001094 void cvtqsi2sd(XMMRegister dst, const Operand& src);
1095 void cvtqsi2sd(XMMRegister dst, Register src);
1096
Steve Block8defd9f2010-07-08 12:39:36 +01001097
Steve Block6ded16b2010-05-10 14:33:55 +01001098 void cvtss2sd(XMMRegister dst, XMMRegister src);
Steve Block8defd9f2010-07-08 12:39:36 +01001099 void cvtss2sd(XMMRegister dst, const Operand& src);
1100 void cvtsd2ss(XMMRegister dst, XMMRegister src);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001101 void cvtsd2ss(XMMRegister dst, const Operand& src);
Steve Block8defd9f2010-07-08 12:39:36 +01001102
1103 void cvtsd2si(Register dst, XMMRegister src);
1104 void cvtsd2siq(Register dst, XMMRegister src);
Steve Block6ded16b2010-05-10 14:33:55 +01001105
Steve Blocka7e24c12009-10-30 11:49:00 +00001106 void addsd(XMMRegister dst, XMMRegister src);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001107 void addsd(XMMRegister dst, const Operand& src);
Steve Blocka7e24c12009-10-30 11:49:00 +00001108 void subsd(XMMRegister dst, XMMRegister src);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001109 void subsd(XMMRegister dst, const Operand& src);
Steve Blocka7e24c12009-10-30 11:49:00 +00001110 void mulsd(XMMRegister dst, XMMRegister src);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001111 void mulsd(XMMRegister dst, const Operand& src);
Steve Blocka7e24c12009-10-30 11:49:00 +00001112 void divsd(XMMRegister dst, XMMRegister src);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001113 void divsd(XMMRegister dst, const Operand& src);
Steve Blocka7e24c12009-10-30 11:49:00 +00001114
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001115 void maxsd(XMMRegister dst, XMMRegister src);
1116 void maxsd(XMMRegister dst, const Operand& src);
1117 void minsd(XMMRegister dst, XMMRegister src);
1118 void minsd(XMMRegister dst, const Operand& src);
1119
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001120 void andpd(XMMRegister dst, XMMRegister src);
1121 void orpd(XMMRegister dst, XMMRegister src);
Andrei Popescu402d9372010-02-26 13:31:12 +00001122 void xorpd(XMMRegister dst, XMMRegister src);
Steve Block6ded16b2010-05-10 14:33:55 +01001123 void sqrtsd(XMMRegister dst, XMMRegister src);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001124 void sqrtsd(XMMRegister dst, const Operand& src);
Andrei Popescu402d9372010-02-26 13:31:12 +00001125
Andrei Popescu402d9372010-02-26 13:31:12 +00001126 void ucomisd(XMMRegister dst, XMMRegister src);
Steve Block8defd9f2010-07-08 12:39:36 +01001127 void ucomisd(XMMRegister dst, const Operand& src);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001128 void cmpltsd(XMMRegister dst, XMMRegister src);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001129 void pcmpeqd(XMMRegister dst, XMMRegister src);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001130
1131 void movmskpd(Register dst, XMMRegister src);
1132
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001133 void punpckldq(XMMRegister dst, XMMRegister src);
1134 void punpckhdq(XMMRegister dst, XMMRegister src);
1135
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001136 // SSE 4.1 instruction
1137 void extractps(Register dst, XMMRegister src, byte imm8);
Steve Blocka7e24c12009-10-30 11:49:00 +00001138
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001139 void pextrd(Register dst, XMMRegister src, int8_t imm8);
Ben Murdoch257744e2011-11-30 15:57:28 +00001140
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001141 void pinsrd(XMMRegister dst, Register src, int8_t imm8);
1142 void pinsrd(XMMRegister dst, const Operand& src, int8_t imm8);
1143
1144 void roundss(XMMRegister dst, XMMRegister src, RoundingMode mode);
Ben Murdoch257744e2011-11-30 15:57:28 +00001145 void roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode);
1146
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001147 // AVX instruction
1148 void vfmadd132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1149 vfmasd(0x99, dst, src1, src2);
1150 }
1151 void vfmadd213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1152 vfmasd(0xa9, dst, src1, src2);
1153 }
1154 void vfmadd231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1155 vfmasd(0xb9, dst, src1, src2);
1156 }
1157 void vfmadd132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1158 vfmasd(0x99, dst, src1, src2);
1159 }
1160 void vfmadd213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1161 vfmasd(0xa9, dst, src1, src2);
1162 }
1163 void vfmadd231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1164 vfmasd(0xb9, dst, src1, src2);
1165 }
1166 void vfmsub132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1167 vfmasd(0x9b, dst, src1, src2);
1168 }
1169 void vfmsub213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1170 vfmasd(0xab, dst, src1, src2);
1171 }
1172 void vfmsub231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1173 vfmasd(0xbb, dst, src1, src2);
1174 }
1175 void vfmsub132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1176 vfmasd(0x9b, dst, src1, src2);
1177 }
1178 void vfmsub213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1179 vfmasd(0xab, dst, src1, src2);
1180 }
1181 void vfmsub231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1182 vfmasd(0xbb, dst, src1, src2);
1183 }
1184 void vfnmadd132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1185 vfmasd(0x9d, dst, src1, src2);
1186 }
1187 void vfnmadd213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1188 vfmasd(0xad, dst, src1, src2);
1189 }
1190 void vfnmadd231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1191 vfmasd(0xbd, dst, src1, src2);
1192 }
1193 void vfnmadd132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1194 vfmasd(0x9d, dst, src1, src2);
1195 }
1196 void vfnmadd213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1197 vfmasd(0xad, dst, src1, src2);
1198 }
1199 void vfnmadd231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1200 vfmasd(0xbd, dst, src1, src2);
1201 }
1202 void vfnmsub132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1203 vfmasd(0x9f, dst, src1, src2);
1204 }
1205 void vfnmsub213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1206 vfmasd(0xaf, dst, src1, src2);
1207 }
1208 void vfnmsub231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1209 vfmasd(0xbf, dst, src1, src2);
1210 }
1211 void vfnmsub132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1212 vfmasd(0x9f, dst, src1, src2);
1213 }
1214 void vfnmsub213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1215 vfmasd(0xaf, dst, src1, src2);
1216 }
1217 void vfnmsub231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1218 vfmasd(0xbf, dst, src1, src2);
1219 }
1220 void vfmasd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
1221 void vfmasd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
1222
1223 void vfmadd132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1224 vfmass(0x99, dst, src1, src2);
1225 }
1226 void vfmadd213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1227 vfmass(0xa9, dst, src1, src2);
1228 }
1229 void vfmadd231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1230 vfmass(0xb9, dst, src1, src2);
1231 }
1232 void vfmadd132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1233 vfmass(0x99, dst, src1, src2);
1234 }
1235 void vfmadd213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1236 vfmass(0xa9, dst, src1, src2);
1237 }
1238 void vfmadd231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1239 vfmass(0xb9, dst, src1, src2);
1240 }
1241 void vfmsub132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1242 vfmass(0x9b, dst, src1, src2);
1243 }
1244 void vfmsub213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1245 vfmass(0xab, dst, src1, src2);
1246 }
1247 void vfmsub231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1248 vfmass(0xbb, dst, src1, src2);
1249 }
1250 void vfmsub132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1251 vfmass(0x9b, dst, src1, src2);
1252 }
1253 void vfmsub213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1254 vfmass(0xab, dst, src1, src2);
1255 }
1256 void vfmsub231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1257 vfmass(0xbb, dst, src1, src2);
1258 }
1259 void vfnmadd132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1260 vfmass(0x9d, dst, src1, src2);
1261 }
1262 void vfnmadd213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1263 vfmass(0xad, dst, src1, src2);
1264 }
1265 void vfnmadd231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1266 vfmass(0xbd, dst, src1, src2);
1267 }
1268 void vfnmadd132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1269 vfmass(0x9d, dst, src1, src2);
1270 }
1271 void vfnmadd213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1272 vfmass(0xad, dst, src1, src2);
1273 }
1274 void vfnmadd231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1275 vfmass(0xbd, dst, src1, src2);
1276 }
1277 void vfnmsub132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1278 vfmass(0x9f, dst, src1, src2);
1279 }
1280 void vfnmsub213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1281 vfmass(0xaf, dst, src1, src2);
1282 }
1283 void vfnmsub231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1284 vfmass(0xbf, dst, src1, src2);
1285 }
1286 void vfnmsub132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1287 vfmass(0x9f, dst, src1, src2);
1288 }
1289 void vfnmsub213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1290 vfmass(0xaf, dst, src1, src2);
1291 }
1292 void vfnmsub231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1293 vfmass(0xbf, dst, src1, src2);
1294 }
1295 void vfmass(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
1296 void vfmass(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
1297
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001298 void vmovd(XMMRegister dst, Register src);
1299 void vmovd(XMMRegister dst, const Operand& src);
1300 void vmovd(Register dst, XMMRegister src);
1301 void vmovq(XMMRegister dst, Register src);
1302 void vmovq(XMMRegister dst, const Operand& src);
1303 void vmovq(Register dst, XMMRegister src);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001304
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001305 void vmovsd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1306 vsd(0x10, dst, src1, src2);
1307 }
1308 void vmovsd(XMMRegister dst, const Operand& src) {
1309 vsd(0x10, dst, xmm0, src);
1310 }
1311 void vmovsd(const Operand& dst, XMMRegister src) {
1312 vsd(0x11, src, xmm0, dst);
1313 }
1314
1315#define AVX_SP_3(instr, opcode) \
1316 AVX_S_3(instr, opcode) \
1317 AVX_P_3(instr, opcode)
1318
1319#define AVX_S_3(instr, opcode) \
1320 AVX_3(instr##ss, opcode, vss) \
1321 AVX_3(instr##sd, opcode, vsd)
1322
1323#define AVX_P_3(instr, opcode) \
1324 AVX_3(instr##ps, opcode, vps) \
1325 AVX_3(instr##pd, opcode, vpd)
1326
1327#define AVX_3(instr, opcode, impl) \
1328 void instr(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \
1329 impl(opcode, dst, src1, src2); \
1330 } \
1331 void instr(XMMRegister dst, XMMRegister src1, const Operand& src2) { \
1332 impl(opcode, dst, src1, src2); \
1333 }
1334
1335 AVX_SP_3(vsqrt, 0x51);
1336 AVX_SP_3(vadd, 0x58);
1337 AVX_SP_3(vsub, 0x5c);
1338 AVX_SP_3(vmul, 0x59);
1339 AVX_SP_3(vdiv, 0x5e);
1340 AVX_SP_3(vmin, 0x5d);
1341 AVX_SP_3(vmax, 0x5f);
1342 AVX_P_3(vand, 0x54);
1343 AVX_P_3(vor, 0x56);
1344 AVX_P_3(vxor, 0x57);
1345 AVX_3(vpcmpeqd, 0x76, vpd);
1346 AVX_3(vcvtsd2ss, 0x5a, vsd);
1347
1348#undef AVX_3
1349#undef AVX_S_3
1350#undef AVX_P_3
1351#undef AVX_SP_3
1352
1353 void vpsrlq(XMMRegister dst, XMMRegister src, byte imm8) {
1354 XMMRegister iop = {2};
1355 vpd(0x73, iop, dst, src);
1356 emit(imm8);
1357 }
1358 void vpsllq(XMMRegister dst, XMMRegister src, byte imm8) {
1359 XMMRegister iop = {6};
1360 vpd(0x73, iop, dst, src);
1361 emit(imm8);
1362 }
1363 void vcvtss2sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1364 vsd(0x5a, dst, src1, src2, kF3, k0F, kWIG);
1365 }
1366 void vcvtss2sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1367 vsd(0x5a, dst, src1, src2, kF3, k0F, kWIG);
1368 }
1369 void vcvtlsi2sd(XMMRegister dst, XMMRegister src1, Register src2) {
1370 XMMRegister isrc2 = {src2.code()};
1371 vsd(0x2a, dst, src1, isrc2, kF2, k0F, kW0);
1372 }
1373 void vcvtlsi2sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1374 vsd(0x2a, dst, src1, src2, kF2, k0F, kW0);
1375 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001376 void vcvtlsi2ss(XMMRegister dst, XMMRegister src1, Register src2) {
1377 XMMRegister isrc2 = {src2.code()};
1378 vsd(0x2a, dst, src1, isrc2, kF3, k0F, kW0);
1379 }
1380 void vcvtlsi2ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1381 vsd(0x2a, dst, src1, src2, kF3, k0F, kW0);
1382 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001383 void vcvtqsi2ss(XMMRegister dst, XMMRegister src1, Register src2) {
1384 XMMRegister isrc2 = {src2.code()};
1385 vsd(0x2a, dst, src1, isrc2, kF3, k0F, kW1);
1386 }
1387 void vcvtqsi2ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1388 vsd(0x2a, dst, src1, src2, kF3, k0F, kW1);
1389 }
1390 void vcvtqsi2sd(XMMRegister dst, XMMRegister src1, Register src2) {
1391 XMMRegister isrc2 = {src2.code()};
1392 vsd(0x2a, dst, src1, isrc2, kF2, k0F, kW1);
1393 }
1394 void vcvtqsi2sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1395 vsd(0x2a, dst, src1, src2, kF2, k0F, kW1);
1396 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001397 void vcvttss2si(Register dst, XMMRegister src) {
1398 XMMRegister idst = {dst.code()};
1399 vsd(0x2c, idst, xmm0, src, kF3, k0F, kW0);
1400 }
1401 void vcvttss2si(Register dst, const Operand& src) {
1402 XMMRegister idst = {dst.code()};
1403 vsd(0x2c, idst, xmm0, src, kF3, k0F, kW0);
1404 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001405 void vcvttsd2si(Register dst, XMMRegister src) {
1406 XMMRegister idst = {dst.code()};
1407 vsd(0x2c, idst, xmm0, src, kF2, k0F, kW0);
1408 }
1409 void vcvttsd2si(Register dst, const Operand& src) {
1410 XMMRegister idst = {dst.code()};
1411 vsd(0x2c, idst, xmm0, src, kF2, k0F, kW0);
1412 }
1413 void vcvttss2siq(Register dst, XMMRegister src) {
1414 XMMRegister idst = {dst.code()};
1415 vsd(0x2c, idst, xmm0, src, kF3, k0F, kW1);
1416 }
1417 void vcvttss2siq(Register dst, const Operand& src) {
1418 XMMRegister idst = {dst.code()};
1419 vsd(0x2c, idst, xmm0, src, kF3, k0F, kW1);
1420 }
1421 void vcvttsd2siq(Register dst, XMMRegister src) {
1422 XMMRegister idst = {dst.code()};
1423 vsd(0x2c, idst, xmm0, src, kF2, k0F, kW1);
1424 }
1425 void vcvttsd2siq(Register dst, const Operand& src) {
1426 XMMRegister idst = {dst.code()};
1427 vsd(0x2c, idst, xmm0, src, kF2, k0F, kW1);
1428 }
1429 void vcvtsd2si(Register dst, XMMRegister src) {
1430 XMMRegister idst = {dst.code()};
1431 vsd(0x2d, idst, xmm0, src, kF2, k0F, kW0);
1432 }
1433 void vucomisd(XMMRegister dst, XMMRegister src) {
1434 vsd(0x2e, dst, xmm0, src, k66, k0F, kWIG);
1435 }
1436 void vucomisd(XMMRegister dst, const Operand& src) {
1437 vsd(0x2e, dst, xmm0, src, k66, k0F, kWIG);
1438 }
1439 void vroundss(XMMRegister dst, XMMRegister src1, XMMRegister src2,
1440 RoundingMode mode) {
1441 vsd(0x0a, dst, src1, src2, k66, k0F3A, kWIG);
1442 emit(static_cast<byte>(mode) | 0x8); // Mask precision exception.
1443 }
1444 void vroundsd(XMMRegister dst, XMMRegister src1, XMMRegister src2,
1445 RoundingMode mode) {
1446 vsd(0x0b, dst, src1, src2, k66, k0F3A, kWIG);
1447 emit(static_cast<byte>(mode) | 0x8); // Mask precision exception.
1448 }
1449
1450 void vsd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1451 vsd(op, dst, src1, src2, kF2, k0F, kWIG);
1452 }
1453 void vsd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2) {
1454 vsd(op, dst, src1, src2, kF2, k0F, kWIG);
1455 }
1456 void vsd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2,
1457 SIMDPrefix pp, LeadingOpcode m, VexW w);
1458 void vsd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2,
1459 SIMDPrefix pp, LeadingOpcode m, VexW w);
1460
1461 void vmovss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1462 vss(0x10, dst, src1, src2);
1463 }
1464 void vmovss(XMMRegister dst, const Operand& src) {
1465 vss(0x10, dst, xmm0, src);
1466 }
1467 void vmovss(const Operand& dst, XMMRegister src) {
1468 vss(0x11, src, xmm0, dst);
1469 }
1470 void vucomiss(XMMRegister dst, XMMRegister src);
1471 void vucomiss(XMMRegister dst, const Operand& src);
1472 void vss(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
1473 void vss(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
1474
1475 void vmovaps(XMMRegister dst, XMMRegister src) { vps(0x28, dst, xmm0, src); }
1476 void vmovapd(XMMRegister dst, XMMRegister src) { vpd(0x28, dst, xmm0, src); }
1477 void vmovmskpd(Register dst, XMMRegister src) {
1478 XMMRegister idst = {dst.code()};
1479 vpd(0x50, idst, xmm0, src);
1480 }
1481
1482 void vps(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
1483 void vps(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
1484 void vpd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
1485 void vpd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
1486
1487 // BMI instruction
1488 void andnq(Register dst, Register src1, Register src2) {
1489 bmi1q(0xf2, dst, src1, src2);
1490 }
1491 void andnq(Register dst, Register src1, const Operand& src2) {
1492 bmi1q(0xf2, dst, src1, src2);
1493 }
1494 void andnl(Register dst, Register src1, Register src2) {
1495 bmi1l(0xf2, dst, src1, src2);
1496 }
1497 void andnl(Register dst, Register src1, const Operand& src2) {
1498 bmi1l(0xf2, dst, src1, src2);
1499 }
1500 void bextrq(Register dst, Register src1, Register src2) {
1501 bmi1q(0xf7, dst, src2, src1);
1502 }
1503 void bextrq(Register dst, const Operand& src1, Register src2) {
1504 bmi1q(0xf7, dst, src2, src1);
1505 }
1506 void bextrl(Register dst, Register src1, Register src2) {
1507 bmi1l(0xf7, dst, src2, src1);
1508 }
1509 void bextrl(Register dst, const Operand& src1, Register src2) {
1510 bmi1l(0xf7, dst, src2, src1);
1511 }
1512 void blsiq(Register dst, Register src) {
1513 Register ireg = {3};
1514 bmi1q(0xf3, ireg, dst, src);
1515 }
1516 void blsiq(Register dst, const Operand& src) {
1517 Register ireg = {3};
1518 bmi1q(0xf3, ireg, dst, src);
1519 }
1520 void blsil(Register dst, Register src) {
1521 Register ireg = {3};
1522 bmi1l(0xf3, ireg, dst, src);
1523 }
1524 void blsil(Register dst, const Operand& src) {
1525 Register ireg = {3};
1526 bmi1l(0xf3, ireg, dst, src);
1527 }
1528 void blsmskq(Register dst, Register src) {
1529 Register ireg = {2};
1530 bmi1q(0xf3, ireg, dst, src);
1531 }
1532 void blsmskq(Register dst, const Operand& src) {
1533 Register ireg = {2};
1534 bmi1q(0xf3, ireg, dst, src);
1535 }
1536 void blsmskl(Register dst, Register src) {
1537 Register ireg = {2};
1538 bmi1l(0xf3, ireg, dst, src);
1539 }
1540 void blsmskl(Register dst, const Operand& src) {
1541 Register ireg = {2};
1542 bmi1l(0xf3, ireg, dst, src);
1543 }
1544 void blsrq(Register dst, Register src) {
1545 Register ireg = {1};
1546 bmi1q(0xf3, ireg, dst, src);
1547 }
1548 void blsrq(Register dst, const Operand& src) {
1549 Register ireg = {1};
1550 bmi1q(0xf3, ireg, dst, src);
1551 }
1552 void blsrl(Register dst, Register src) {
1553 Register ireg = {1};
1554 bmi1l(0xf3, ireg, dst, src);
1555 }
1556 void blsrl(Register dst, const Operand& src) {
1557 Register ireg = {1};
1558 bmi1l(0xf3, ireg, dst, src);
1559 }
1560 void tzcntq(Register dst, Register src);
1561 void tzcntq(Register dst, const Operand& src);
1562 void tzcntl(Register dst, Register src);
1563 void tzcntl(Register dst, const Operand& src);
1564
1565 void lzcntq(Register dst, Register src);
1566 void lzcntq(Register dst, const Operand& src);
1567 void lzcntl(Register dst, Register src);
1568 void lzcntl(Register dst, const Operand& src);
1569
1570 void popcntq(Register dst, Register src);
1571 void popcntq(Register dst, const Operand& src);
1572 void popcntl(Register dst, Register src);
1573 void popcntl(Register dst, const Operand& src);
1574
1575 void bzhiq(Register dst, Register src1, Register src2) {
1576 bmi2q(kNone, 0xf5, dst, src2, src1);
1577 }
1578 void bzhiq(Register dst, const Operand& src1, Register src2) {
1579 bmi2q(kNone, 0xf5, dst, src2, src1);
1580 }
1581 void bzhil(Register dst, Register src1, Register src2) {
1582 bmi2l(kNone, 0xf5, dst, src2, src1);
1583 }
1584 void bzhil(Register dst, const Operand& src1, Register src2) {
1585 bmi2l(kNone, 0xf5, dst, src2, src1);
1586 }
1587 void mulxq(Register dst1, Register dst2, Register src) {
1588 bmi2q(kF2, 0xf6, dst1, dst2, src);
1589 }
1590 void mulxq(Register dst1, Register dst2, const Operand& src) {
1591 bmi2q(kF2, 0xf6, dst1, dst2, src);
1592 }
1593 void mulxl(Register dst1, Register dst2, Register src) {
1594 bmi2l(kF2, 0xf6, dst1, dst2, src);
1595 }
1596 void mulxl(Register dst1, Register dst2, const Operand& src) {
1597 bmi2l(kF2, 0xf6, dst1, dst2, src);
1598 }
1599 void pdepq(Register dst, Register src1, Register src2) {
1600 bmi2q(kF2, 0xf5, dst, src1, src2);
1601 }
1602 void pdepq(Register dst, Register src1, const Operand& src2) {
1603 bmi2q(kF2, 0xf5, dst, src1, src2);
1604 }
1605 void pdepl(Register dst, Register src1, Register src2) {
1606 bmi2l(kF2, 0xf5, dst, src1, src2);
1607 }
1608 void pdepl(Register dst, Register src1, const Operand& src2) {
1609 bmi2l(kF2, 0xf5, dst, src1, src2);
1610 }
1611 void pextq(Register dst, Register src1, Register src2) {
1612 bmi2q(kF3, 0xf5, dst, src1, src2);
1613 }
1614 void pextq(Register dst, Register src1, const Operand& src2) {
1615 bmi2q(kF3, 0xf5, dst, src1, src2);
1616 }
1617 void pextl(Register dst, Register src1, Register src2) {
1618 bmi2l(kF3, 0xf5, dst, src1, src2);
1619 }
1620 void pextl(Register dst, Register src1, const Operand& src2) {
1621 bmi2l(kF3, 0xf5, dst, src1, src2);
1622 }
1623 void sarxq(Register dst, Register src1, Register src2) {
1624 bmi2q(kF3, 0xf7, dst, src2, src1);
1625 }
1626 void sarxq(Register dst, const Operand& src1, Register src2) {
1627 bmi2q(kF3, 0xf7, dst, src2, src1);
1628 }
1629 void sarxl(Register dst, Register src1, Register src2) {
1630 bmi2l(kF3, 0xf7, dst, src2, src1);
1631 }
1632 void sarxl(Register dst, const Operand& src1, Register src2) {
1633 bmi2l(kF3, 0xf7, dst, src2, src1);
1634 }
1635 void shlxq(Register dst, Register src1, Register src2) {
1636 bmi2q(k66, 0xf7, dst, src2, src1);
1637 }
1638 void shlxq(Register dst, const Operand& src1, Register src2) {
1639 bmi2q(k66, 0xf7, dst, src2, src1);
1640 }
1641 void shlxl(Register dst, Register src1, Register src2) {
1642 bmi2l(k66, 0xf7, dst, src2, src1);
1643 }
1644 void shlxl(Register dst, const Operand& src1, Register src2) {
1645 bmi2l(k66, 0xf7, dst, src2, src1);
1646 }
1647 void shrxq(Register dst, Register src1, Register src2) {
1648 bmi2q(kF2, 0xf7, dst, src2, src1);
1649 }
1650 void shrxq(Register dst, const Operand& src1, Register src2) {
1651 bmi2q(kF2, 0xf7, dst, src2, src1);
1652 }
1653 void shrxl(Register dst, Register src1, Register src2) {
1654 bmi2l(kF2, 0xf7, dst, src2, src1);
1655 }
1656 void shrxl(Register dst, const Operand& src1, Register src2) {
1657 bmi2l(kF2, 0xf7, dst, src2, src1);
1658 }
1659 void rorxq(Register dst, Register src, byte imm8);
1660 void rorxq(Register dst, const Operand& src, byte imm8);
1661 void rorxl(Register dst, Register src, byte imm8);
1662 void rorxl(Register dst, const Operand& src, byte imm8);
Steve Blocka7e24c12009-10-30 11:49:00 +00001663
1664 // Check the code size generated from label to here.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001665 int SizeOfCodeGeneratedSince(Label* label) {
1666 return pc_offset() - label->pos();
1667 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001668
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001669 // Mark generator continuation.
1670 void RecordGeneratorContinuation();
Steve Blocka7e24c12009-10-30 11:49:00 +00001671
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001672 // Mark address of a debug break slot.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001673 void RecordDebugBreakSlot(RelocInfo::Mode mode);
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001674
Steve Blocka7e24c12009-10-30 11:49:00 +00001675 // Record a comment relocation entry that can be used by a disassembler.
Ben Murdochb0fe1622011-05-05 13:52:32 +01001676 // Use --code-comments to enable.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001677 void RecordComment(const char* msg);
Steve Blocka7e24c12009-10-30 11:49:00 +00001678
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001679 // Record a deoptimization reason that can be used by a log or cpu profiler.
1680 // Use --trace-deopt to enable.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001681 void RecordDeoptReason(const int reason, int raw_position);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001682
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001683 void PatchConstantPoolAccessInstruction(int pc_offset, int offset,
1684 ConstantPoolEntry::Access access,
1685 ConstantPoolEntry::Type type) {
1686 // No embedded constant pool support.
1687 UNREACHABLE();
1688 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001689
Ben Murdochb0fe1622011-05-05 13:52:32 +01001690 // Writes a single word of data in the code stream.
1691 // Used for inline tables, e.g., jump-tables.
Ben Murdochb8e0da22011-05-16 14:20:40 +01001692 void db(uint8_t data);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001693 void dd(uint32_t data);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001694 void dq(uint64_t data);
1695 void dp(uintptr_t data) { dq(data); }
1696 void dq(Label* label);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001697
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001698 PositionsRecorder* positions_recorder() { return &positions_recorder_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001699
1700 // Check if there is less than kGap bytes available in the buffer.
1701 // If this is the case, we need to grow the buffer before emitting
1702 // an instruction or relocation information.
1703 inline bool buffer_overflow() const {
1704 return pc_ >= reloc_info_writer.pos() - kGap;
1705 }
1706
1707 // Get the number of bytes available in the buffer.
Steve Blockd0582a62009-12-15 09:54:21 +00001708 inline int available_space() const {
1709 return static_cast<int>(reloc_info_writer.pos() - pc_);
1710 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001711
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001712 static bool IsNop(Address addr);
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001713
Steve Blocka7e24c12009-10-30 11:49:00 +00001714 // Avoid overflows for displacements etc.
1715 static const int kMaximalBufferSize = 512*MB;
Steve Blocka7e24c12009-10-30 11:49:00 +00001716
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001717 byte byte_at(int pos) { return buffer_[pos]; }
1718 void set_byte_at(int pos, byte value) { buffer_[pos] = value; }
1719
Steve Block44f0eee2011-05-26 01:26:41 +01001720 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001721 // Call near indirect
1722 void call(const Operand& operand);
1723
Steve Blocka7e24c12009-10-30 11:49:00 +00001724 private:
1725 byte* addr_at(int pos) { return buffer_ + pos; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001726 uint32_t long_at(int pos) {
1727 return *reinterpret_cast<uint32_t*>(addr_at(pos));
1728 }
1729 void long_at_put(int pos, uint32_t x) {
1730 *reinterpret_cast<uint32_t*>(addr_at(pos)) = x;
1731 }
1732
1733 // code emission
1734 void GrowBuffer();
1735
1736 void emit(byte x) { *pc_++ = x; }
1737 inline void emitl(uint32_t x);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001738 inline void emitp(void* x, RelocInfo::Mode rmode);
1739 inline void emitq(uint64_t x);
Steve Blocka7e24c12009-10-30 11:49:00 +00001740 inline void emitw(uint16_t x);
Ben Murdoch257744e2011-11-30 15:57:28 +00001741 inline void emit_code_target(Handle<Code> target,
1742 RelocInfo::Mode rmode,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001743 TypeFeedbackId ast_id = TypeFeedbackId::None());
1744 inline void emit_runtime_entry(Address entry, RelocInfo::Mode rmode);
Steve Blocka7e24c12009-10-30 11:49:00 +00001745 void emit(Immediate x) { emitl(x.value_); }
1746
1747 // Emits a REX prefix that encodes a 64-bit operand size and
1748 // the top bit of both register codes.
1749 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
1750 // REX.W is set.
Steve Blocka7e24c12009-10-30 11:49:00 +00001751 inline void emit_rex_64(XMMRegister reg, Register rm_reg);
Steve Block6ded16b2010-05-10 14:33:55 +01001752 inline void emit_rex_64(Register reg, XMMRegister rm_reg);
1753 inline void emit_rex_64(Register reg, Register rm_reg);
Steve Blocka7e24c12009-10-30 11:49:00 +00001754
1755 // Emits a REX prefix that encodes a 64-bit operand size and
1756 // the top bit of the destination, index, and base register codes.
1757 // The high bit of reg is used for REX.R, the high bit of op's base
1758 // register is used for REX.B, and the high bit of op's index register
1759 // is used for REX.X. REX.W is set.
1760 inline void emit_rex_64(Register reg, const Operand& op);
1761 inline void emit_rex_64(XMMRegister reg, const Operand& op);
1762
1763 // Emits a REX prefix that encodes a 64-bit operand size and
1764 // the top bit of the register code.
1765 // The high bit of register is used for REX.B.
1766 // REX.W is set and REX.R and REX.X are clear.
1767 inline void emit_rex_64(Register rm_reg);
1768
1769 // Emits a REX prefix that encodes a 64-bit operand size and
1770 // the top bit of the index and base register codes.
1771 // The high bit of op's base register is used for REX.B, and the high
1772 // bit of op's index register is used for REX.X.
1773 // REX.W is set and REX.R clear.
1774 inline void emit_rex_64(const Operand& op);
1775
1776 // Emit a REX prefix that only sets REX.W to choose a 64-bit operand size.
1777 void emit_rex_64() { emit(0x48); }
1778
1779 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
1780 // REX.W is clear.
1781 inline void emit_rex_32(Register reg, Register rm_reg);
1782
1783 // The high bit of reg is used for REX.R, the high bit of op's base
1784 // register is used for REX.B, and the high bit of op's index register
1785 // is used for REX.X. REX.W is cleared.
1786 inline void emit_rex_32(Register reg, const Operand& op);
1787
1788 // High bit of rm_reg goes to REX.B.
1789 // REX.W, REX.R and REX.X are clear.
1790 inline void emit_rex_32(Register rm_reg);
1791
1792 // High bit of base goes to REX.B and high bit of index to REX.X.
1793 // REX.W and REX.R are clear.
1794 inline void emit_rex_32(const Operand& op);
1795
1796 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
1797 // REX.W is cleared. If no REX bits are set, no byte is emitted.
1798 inline void emit_optional_rex_32(Register reg, Register rm_reg);
1799
1800 // The high bit of reg is used for REX.R, the high bit of op's base
1801 // register is used for REX.B, and the high bit of op's index register
1802 // is used for REX.X. REX.W is cleared. If no REX bits are set, nothing
1803 // is emitted.
1804 inline void emit_optional_rex_32(Register reg, const Operand& op);
1805
1806 // As for emit_optional_rex_32(Register, Register), except that
1807 // the registers are XMM registers.
1808 inline void emit_optional_rex_32(XMMRegister reg, XMMRegister base);
1809
1810 // As for emit_optional_rex_32(Register, Register), except that
Steve Block6ded16b2010-05-10 14:33:55 +01001811 // one of the registers is an XMM registers.
Steve Blocka7e24c12009-10-30 11:49:00 +00001812 inline void emit_optional_rex_32(XMMRegister reg, Register base);
1813
Steve Block6ded16b2010-05-10 14:33:55 +01001814 // As for emit_optional_rex_32(Register, Register), except that
1815 // one of the registers is an XMM registers.
1816 inline void emit_optional_rex_32(Register reg, XMMRegister base);
1817
Steve Blocka7e24c12009-10-30 11:49:00 +00001818 // As for emit_optional_rex_32(Register, const Operand&), except that
1819 // the register is an XMM register.
1820 inline void emit_optional_rex_32(XMMRegister reg, const Operand& op);
1821
1822 // Optionally do as emit_rex_32(Register) if the register number has
1823 // the high bit set.
1824 inline void emit_optional_rex_32(Register rm_reg);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001825 inline void emit_optional_rex_32(XMMRegister rm_reg);
Steve Blocka7e24c12009-10-30 11:49:00 +00001826
1827 // Optionally do as emit_rex_32(const Operand&) if the operand register
1828 // numbers have a high bit set.
1829 inline void emit_optional_rex_32(const Operand& op);
1830
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001831 void emit_rex(int size) {
1832 if (size == kInt64Size) {
1833 emit_rex_64();
1834 } else {
1835 DCHECK(size == kInt32Size);
1836 }
1837 }
1838
1839 template<class P1>
1840 void emit_rex(P1 p1, int size) {
1841 if (size == kInt64Size) {
1842 emit_rex_64(p1);
1843 } else {
1844 DCHECK(size == kInt32Size);
1845 emit_optional_rex_32(p1);
1846 }
1847 }
1848
1849 template<class P1, class P2>
1850 void emit_rex(P1 p1, P2 p2, int size) {
1851 if (size == kInt64Size) {
1852 emit_rex_64(p1, p2);
1853 } else {
1854 DCHECK(size == kInt32Size);
1855 emit_optional_rex_32(p1, p2);
1856 }
1857 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001858
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001859 // Emit vex prefix
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001860 void emit_vex2_byte0() { emit(0xc5); }
1861 inline void emit_vex2_byte1(XMMRegister reg, XMMRegister v, VectorLength l,
1862 SIMDPrefix pp);
1863 void emit_vex3_byte0() { emit(0xc4); }
1864 inline void emit_vex3_byte1(XMMRegister reg, XMMRegister rm, LeadingOpcode m);
1865 inline void emit_vex3_byte1(XMMRegister reg, const Operand& rm,
1866 LeadingOpcode m);
1867 inline void emit_vex3_byte2(VexW w, XMMRegister v, VectorLength l,
1868 SIMDPrefix pp);
1869 inline void emit_vex_prefix(XMMRegister reg, XMMRegister v, XMMRegister rm,
1870 VectorLength l, SIMDPrefix pp, LeadingOpcode m,
1871 VexW w);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001872 inline void emit_vex_prefix(Register reg, Register v, Register rm,
1873 VectorLength l, SIMDPrefix pp, LeadingOpcode m,
1874 VexW w);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001875 inline void emit_vex_prefix(XMMRegister reg, XMMRegister v, const Operand& rm,
1876 VectorLength l, SIMDPrefix pp, LeadingOpcode m,
1877 VexW w);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001878 inline void emit_vex_prefix(Register reg, Register v, const Operand& rm,
1879 VectorLength l, SIMDPrefix pp, LeadingOpcode m,
1880 VexW w);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001881
Steve Blocka7e24c12009-10-30 11:49:00 +00001882 // Emit the ModR/M byte, and optionally the SIB byte and
1883 // 1- or 4-byte offset for a memory operand. Also encodes
1884 // the second operand of the operation, a register or operation
1885 // subcode, into the reg field of the ModR/M byte.
1886 void emit_operand(Register reg, const Operand& adr) {
1887 emit_operand(reg.low_bits(), adr);
1888 }
1889
1890 // Emit the ModR/M byte, and optionally the SIB byte and
1891 // 1- or 4-byte offset for a memory operand. Also used to encode
1892 // a three-bit opcode extension into the ModR/M byte.
1893 void emit_operand(int rm, const Operand& adr);
1894
1895 // Emit a ModR/M byte with registers coded in the reg and rm_reg fields.
1896 void emit_modrm(Register reg, Register rm_reg) {
1897 emit(0xC0 | reg.low_bits() << 3 | rm_reg.low_bits());
1898 }
1899
1900 // Emit a ModR/M byte with an operation subcode in the reg field and
1901 // a register in the rm_reg field.
1902 void emit_modrm(int code, Register rm_reg) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001903 DCHECK(is_uint3(code));
Steve Blocka7e24c12009-10-30 11:49:00 +00001904 emit(0xC0 | code << 3 | rm_reg.low_bits());
1905 }
1906
1907 // Emit the code-object-relative offset of the label's position
1908 inline void emit_code_relative_offset(Label* label);
1909
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001910 // The first argument is the reg field, the second argument is the r/m field.
1911 void emit_sse_operand(XMMRegister dst, XMMRegister src);
1912 void emit_sse_operand(XMMRegister reg, const Operand& adr);
1913 void emit_sse_operand(Register reg, const Operand& adr);
1914 void emit_sse_operand(XMMRegister dst, Register src);
1915 void emit_sse_operand(Register dst, XMMRegister src);
1916
Steve Blocka7e24c12009-10-30 11:49:00 +00001917 // Emit machine code for one of the operations ADD, ADC, SUB, SBC,
1918 // AND, OR, XOR, or CMP. The encodings of these operations are all
1919 // similar, differing just in the opcode or in the reg field of the
1920 // ModR/M byte.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001921 void arithmetic_op_8(byte opcode, Register reg, Register rm_reg);
1922 void arithmetic_op_8(byte opcode, Register reg, const Operand& rm_reg);
Steve Blocka7e24c12009-10-30 11:49:00 +00001923 void arithmetic_op_16(byte opcode, Register reg, Register rm_reg);
1924 void arithmetic_op_16(byte opcode, Register reg, const Operand& rm_reg);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001925 // Operate on operands/registers with pointer size, 32-bit or 64-bit size.
1926 void arithmetic_op(byte opcode, Register reg, Register rm_reg, int size);
1927 void arithmetic_op(byte opcode,
1928 Register reg,
1929 const Operand& rm_reg,
1930 int size);
Steve Blocka7e24c12009-10-30 11:49:00 +00001931 // Operate on a byte in memory or register.
1932 void immediate_arithmetic_op_8(byte subcode,
1933 Register dst,
1934 Immediate src);
1935 void immediate_arithmetic_op_8(byte subcode,
1936 const Operand& dst,
1937 Immediate src);
1938 // Operate on a word in memory or register.
1939 void immediate_arithmetic_op_16(byte subcode,
1940 Register dst,
1941 Immediate src);
1942 void immediate_arithmetic_op_16(byte subcode,
1943 const Operand& dst,
1944 Immediate src);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001945 // Operate on operands/registers with pointer size, 32-bit or 64-bit size.
1946 void immediate_arithmetic_op(byte subcode,
1947 Register dst,
1948 Immediate src,
1949 int size);
1950 void immediate_arithmetic_op(byte subcode,
1951 const Operand& dst,
1952 Immediate src,
1953 int size);
Steve Blocka7e24c12009-10-30 11:49:00 +00001954
1955 // Emit machine code for a shift operation.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001956 void shift(Operand dst, Immediate shift_amount, int subcode, int size);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001957 void shift(Register dst, Immediate shift_amount, int subcode, int size);
Steve Blocka7e24c12009-10-30 11:49:00 +00001958 // Shift dst by cl % 64 bits.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001959 void shift(Register dst, int subcode, int size);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001960 void shift(Operand dst, int subcode, int size);
Steve Blocka7e24c12009-10-30 11:49:00 +00001961
1962 void emit_farith(int b1, int b2, int i);
1963
1964 // labels
1965 // void print(Label* L);
1966 void bind_to(Label* L, int pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00001967
1968 // record reloc info for current pc_
1969 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
1970
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001971 // Arithmetics
1972 void emit_add(Register dst, Register src, int size) {
1973 arithmetic_op(0x03, dst, src, size);
1974 }
1975
1976 void emit_add(Register dst, Immediate src, int size) {
1977 immediate_arithmetic_op(0x0, dst, src, size);
1978 }
1979
1980 void emit_add(Register dst, const Operand& src, int size) {
1981 arithmetic_op(0x03, dst, src, size);
1982 }
1983
1984 void emit_add(const Operand& dst, Register src, int size) {
1985 arithmetic_op(0x1, src, dst, size);
1986 }
1987
1988 void emit_add(const Operand& dst, Immediate src, int size) {
1989 immediate_arithmetic_op(0x0, dst, src, size);
1990 }
1991
1992 void emit_and(Register dst, Register src, int size) {
1993 arithmetic_op(0x23, dst, src, size);
1994 }
1995
1996 void emit_and(Register dst, const Operand& src, int size) {
1997 arithmetic_op(0x23, dst, src, size);
1998 }
1999
2000 void emit_and(const Operand& dst, Register src, int size) {
2001 arithmetic_op(0x21, src, dst, size);
2002 }
2003
2004 void emit_and(Register dst, Immediate src, int size) {
2005 immediate_arithmetic_op(0x4, dst, src, size);
2006 }
2007
2008 void emit_and(const Operand& dst, Immediate src, int size) {
2009 immediate_arithmetic_op(0x4, dst, src, size);
2010 }
2011
2012 void emit_cmp(Register dst, Register src, int size) {
2013 arithmetic_op(0x3B, dst, src, size);
2014 }
2015
2016 void emit_cmp(Register dst, const Operand& src, int size) {
2017 arithmetic_op(0x3B, dst, src, size);
2018 }
2019
2020 void emit_cmp(const Operand& dst, Register src, int size) {
2021 arithmetic_op(0x39, src, dst, size);
2022 }
2023
2024 void emit_cmp(Register dst, Immediate src, int size) {
2025 immediate_arithmetic_op(0x7, dst, src, size);
2026 }
2027
2028 void emit_cmp(const Operand& dst, Immediate src, int size) {
2029 immediate_arithmetic_op(0x7, dst, src, size);
2030 }
2031
2032 void emit_dec(Register dst, int size);
2033 void emit_dec(const Operand& dst, int size);
2034
2035 // Divide rdx:rax by src. Quotient in rax, remainder in rdx when size is 64.
2036 // Divide edx:eax by lower 32 bits of src. Quotient in eax, remainder in edx
2037 // when size is 32.
2038 void emit_idiv(Register src, int size);
2039 void emit_div(Register src, int size);
2040
2041 // Signed multiply instructions.
2042 // rdx:rax = rax * src when size is 64 or edx:eax = eax * src when size is 32.
2043 void emit_imul(Register src, int size);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002044 void emit_imul(const Operand& src, int size);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002045 void emit_imul(Register dst, Register src, int size);
2046 void emit_imul(Register dst, const Operand& src, int size);
2047 void emit_imul(Register dst, Register src, Immediate imm, int size);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002048 void emit_imul(Register dst, const Operand& src, Immediate imm, int size);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002049
2050 void emit_inc(Register dst, int size);
2051 void emit_inc(const Operand& dst, int size);
2052
2053 void emit_lea(Register dst, const Operand& src, int size);
2054
2055 void emit_mov(Register dst, const Operand& src, int size);
2056 void emit_mov(Register dst, Register src, int size);
2057 void emit_mov(const Operand& dst, Register src, int size);
2058 void emit_mov(Register dst, Immediate value, int size);
2059 void emit_mov(const Operand& dst, Immediate value, int size);
2060
2061 void emit_movzxb(Register dst, const Operand& src, int size);
2062 void emit_movzxb(Register dst, Register src, int size);
2063 void emit_movzxw(Register dst, const Operand& src, int size);
2064 void emit_movzxw(Register dst, Register src, int size);
2065
2066 void emit_neg(Register dst, int size);
2067 void emit_neg(const Operand& dst, int size);
2068
2069 void emit_not(Register dst, int size);
2070 void emit_not(const Operand& dst, int size);
2071
2072 void emit_or(Register dst, Register src, int size) {
2073 arithmetic_op(0x0B, dst, src, size);
2074 }
2075
2076 void emit_or(Register dst, const Operand& src, int size) {
2077 arithmetic_op(0x0B, dst, src, size);
2078 }
2079
2080 void emit_or(const Operand& dst, Register src, int size) {
2081 arithmetic_op(0x9, src, dst, size);
2082 }
2083
2084 void emit_or(Register dst, Immediate src, int size) {
2085 immediate_arithmetic_op(0x1, dst, src, size);
2086 }
2087
2088 void emit_or(const Operand& dst, Immediate src, int size) {
2089 immediate_arithmetic_op(0x1, dst, src, size);
2090 }
2091
2092 void emit_repmovs(int size);
2093
2094 void emit_sbb(Register dst, Register src, int size) {
2095 arithmetic_op(0x1b, dst, src, size);
2096 }
2097
2098 void emit_sub(Register dst, Register src, int size) {
2099 arithmetic_op(0x2B, dst, src, size);
2100 }
2101
2102 void emit_sub(Register dst, Immediate src, int size) {
2103 immediate_arithmetic_op(0x5, dst, src, size);
2104 }
2105
2106 void emit_sub(Register dst, const Operand& src, int size) {
2107 arithmetic_op(0x2B, dst, src, size);
2108 }
2109
2110 void emit_sub(const Operand& dst, Register src, int size) {
2111 arithmetic_op(0x29, src, dst, size);
2112 }
2113
2114 void emit_sub(const Operand& dst, Immediate src, int size) {
2115 immediate_arithmetic_op(0x5, dst, src, size);
2116 }
2117
2118 void emit_test(Register dst, Register src, int size);
2119 void emit_test(Register reg, Immediate mask, int size);
2120 void emit_test(const Operand& op, Register reg, int size);
2121 void emit_test(const Operand& op, Immediate mask, int size);
2122 void emit_test(Register reg, const Operand& op, int size) {
2123 return emit_test(op, reg, size);
2124 }
2125
2126 void emit_xchg(Register dst, Register src, int size);
2127 void emit_xchg(Register dst, const Operand& src, int size);
2128
2129 void emit_xor(Register dst, Register src, int size) {
2130 if (size == kInt64Size && dst.code() == src.code()) {
2131 // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
2132 // there is no need to make this a 64 bit operation.
2133 arithmetic_op(0x33, dst, src, kInt32Size);
2134 } else {
2135 arithmetic_op(0x33, dst, src, size);
2136 }
2137 }
2138
2139 void emit_xor(Register dst, const Operand& src, int size) {
2140 arithmetic_op(0x33, dst, src, size);
2141 }
2142
2143 void emit_xor(Register dst, Immediate src, int size) {
2144 immediate_arithmetic_op(0x6, dst, src, size);
2145 }
2146
2147 void emit_xor(const Operand& dst, Immediate src, int size) {
2148 immediate_arithmetic_op(0x6, dst, src, size);
2149 }
2150
2151 void emit_xor(const Operand& dst, Register src, int size) {
2152 arithmetic_op(0x31, src, dst, size);
2153 }
2154
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002155 // Most BMI instructions are similiar.
2156 void bmi1q(byte op, Register reg, Register vreg, Register rm);
2157 void bmi1q(byte op, Register reg, Register vreg, const Operand& rm);
2158 void bmi1l(byte op, Register reg, Register vreg, Register rm);
2159 void bmi1l(byte op, Register reg, Register vreg, const Operand& rm);
2160 void bmi2q(SIMDPrefix pp, byte op, Register reg, Register vreg, Register rm);
2161 void bmi2q(SIMDPrefix pp, byte op, Register reg, Register vreg,
2162 const Operand& rm);
2163 void bmi2l(SIMDPrefix pp, byte op, Register reg, Register vreg, Register rm);
2164 void bmi2l(SIMDPrefix pp, byte op, Register reg, Register vreg,
2165 const Operand& rm);
2166
Steve Blocka7e24c12009-10-30 11:49:00 +00002167 friend class CodePatcher;
2168 friend class EnsureSpace;
2169 friend class RegExpMacroAssemblerX64;
2170
Steve Blocka7e24c12009-10-30 11:49:00 +00002171 // code generation
Steve Blocka7e24c12009-10-30 11:49:00 +00002172 RelocInfoWriter reloc_info_writer;
2173
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002174 // Internal reference positions, required for (potential) patching in
2175 // GrowBuffer(); contains only those internal references whose labels
2176 // are already bound.
2177 std::deque<int> internal_reference_positions_;
2178
Steve Block3ce2e202009-11-05 08:53:23 +00002179 List< Handle<Code> > code_targets_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002180
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08002181 PositionsRecorder positions_recorder_;
2182 friend class PositionsRecorder;
Steve Blocka7e24c12009-10-30 11:49:00 +00002183};
2184
2185
2186// Helper class that ensures that there is enough space for generating
2187// instructions and relocation information. The constructor makes
2188// sure that there is enough space and (in debug mode) the destructor
2189// checks that we did not generate too much.
2190class EnsureSpace BASE_EMBEDDED {
2191 public:
2192 explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) {
2193 if (assembler_->buffer_overflow()) assembler_->GrowBuffer();
2194#ifdef DEBUG
2195 space_before_ = assembler_->available_space();
2196#endif
2197 }
2198
2199#ifdef DEBUG
2200 ~EnsureSpace() {
2201 int bytes_generated = space_before_ - assembler_->available_space();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002202 DCHECK(bytes_generated < assembler_->kGap);
Steve Blocka7e24c12009-10-30 11:49:00 +00002203 }
2204#endif
2205
2206 private:
2207 Assembler* assembler_;
2208#ifdef DEBUG
2209 int space_before_;
2210#endif
2211};
2212
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002213} // namespace internal
2214} // namespace v8
Steve Blocka7e24c12009-10-30 11:49:00 +00002215
2216#endif // V8_X64_ASSEMBLER_X64_H_