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