• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #include "v8.h"
29 
30 #include "macro-assembler.h"
31 #include "serialize.h"
32 
33 namespace v8 {
34 namespace internal {
35 
36 // -----------------------------------------------------------------------------
37 // Implementation of CpuFeatures
38 
39 // The required user mode extensions in X64 are (from AMD64 ABI Table A.1):
40 //   fpu, tsc, cx8, cmov, mmx, sse, sse2, fxsr, syscall
41 uint64_t CpuFeatures::supported_ = kDefaultCpuFeatures;
42 uint64_t CpuFeatures::enabled_ = 0;
43 uint64_t CpuFeatures::found_by_runtime_probing_ = 0;
44 
Probe()45 void CpuFeatures::Probe()  {
46   ASSERT(Heap::HasBeenSetup());
47   ASSERT(supported_ == kDefaultCpuFeatures);
48   if (Serializer::enabled()) {
49     supported_ |= OS::CpuFeaturesImpliedByPlatform();
50     return;  // No features if we might serialize.
51   }
52 
53   Assembler assm(NULL, 0);
54   Label cpuid, done;
55 #define __ assm.
56   // Save old rsp, since we are going to modify the stack.
57   __ push(rbp);
58   __ pushfq();
59   __ push(rcx);
60   __ push(rbx);
61   __ movq(rbp, rsp);
62 
63   // If we can modify bit 21 of the EFLAGS register, then CPUID is supported.
64   __ pushfq();
65   __ pop(rax);
66   __ movq(rdx, rax);
67   __ xor_(rax, Immediate(0x200000));  // Flip bit 21.
68   __ push(rax);
69   __ popfq();
70   __ pushfq();
71   __ pop(rax);
72   __ xor_(rax, rdx);  // Different if CPUID is supported.
73   __ j(not_zero, &cpuid);
74 
75   // CPUID not supported. Clear the supported features in edx:eax.
76   __ xor_(rax, rax);
77   __ jmp(&done);
78 
79   // Invoke CPUID with 1 in eax to get feature information in
80   // ecx:edx. Temporarily enable CPUID support because we know it's
81   // safe here.
82   __ bind(&cpuid);
83   __ movq(rax, Immediate(1));
84   supported_ = kDefaultCpuFeatures | (1 << CPUID);
85   { Scope fscope(CPUID);
86     __ cpuid();
87     // Move the result from ecx:edx to rdi.
88     __ movl(rdi, rdx);  // Zero-extended to 64 bits.
89     __ shl(rcx, Immediate(32));
90     __ or_(rdi, rcx);
91 
92     // Get the sahf supported flag, from CPUID(0x80000001)
93     __ movq(rax, 0x80000001, RelocInfo::NONE);
94     __ cpuid();
95   }
96   supported_ = kDefaultCpuFeatures;
97 
98   // Put the CPU flags in rax.
99   // rax = (rcx & 1) | (rdi & ~1) | (1 << CPUID).
100   __ movl(rax, Immediate(1));
101   __ and_(rcx, rax);  // Bit 0 is set if SAHF instruction supported.
102   __ not_(rax);
103   __ and_(rax, rdi);
104   __ or_(rax, rcx);
105   __ or_(rax, Immediate(1 << CPUID));
106 
107   // Done.
108   __ bind(&done);
109   __ movq(rsp, rbp);
110   __ pop(rbx);
111   __ pop(rcx);
112   __ popfq();
113   __ pop(rbp);
114   __ ret(0);
115 #undef __
116 
117   CodeDesc desc;
118   assm.GetCode(&desc);
119   Object* code =
120       Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB), NULL);
121   if (!code->IsCode()) return;
122   LOG(CodeCreateEvent(Logger::BUILTIN_TAG,
123                       Code::cast(code), "CpuFeatures::Probe"));
124   typedef uint64_t (*F0)();
125   F0 probe = FUNCTION_CAST<F0>(Code::cast(code)->entry());
126   supported_ = probe();
127   found_by_runtime_probing_ = supported_;
128   found_by_runtime_probing_ &= ~kDefaultCpuFeatures;
129   uint64_t os_guarantees = OS::CpuFeaturesImpliedByPlatform();
130   supported_ |= os_guarantees;
131   found_by_runtime_probing_ &= ~os_guarantees;
132   // SSE2 and CMOV must be available on an X64 CPU.
133   ASSERT(IsSupported(CPUID));
134   ASSERT(IsSupported(SSE2));
135   ASSERT(IsSupported(CMOV));
136 }
137 
138 
139 // -----------------------------------------------------------------------------
140 // Implementation of RelocInfo
141 
142 // Patch the code at the current PC with a call to the target address.
143 // Additional guard int3 instructions can be added if required.
PatchCodeWithCall(Address target,int guard_bytes)144 void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) {
145   // Load register with immediate 64 and call through a register instructions
146   // takes up 13 bytes and int3 takes up one byte.
147   static const int kCallCodeSize = 13;
148   int code_size = kCallCodeSize + guard_bytes;
149 
150   // Create a code patcher.
151   CodePatcher patcher(pc_, code_size);
152 
153   // Add a label for checking the size of the code used for returning.
154 #ifdef DEBUG
155   Label check_codesize;
156   patcher.masm()->bind(&check_codesize);
157 #endif
158 
159   // Patch the code.
160   patcher.masm()->movq(r10, target, RelocInfo::NONE);
161   patcher.masm()->call(r10);
162 
163   // Check that the size of the code generated is as expected.
164   ASSERT_EQ(kCallCodeSize,
165             patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize));
166 
167   // Add the requested number of int3 instructions after the call.
168   for (int i = 0; i < guard_bytes; i++) {
169     patcher.masm()->int3();
170   }
171 }
172 
173 
PatchCode(byte * instructions,int instruction_count)174 void RelocInfo::PatchCode(byte* instructions, int instruction_count) {
175   // Patch the code at the current address with the supplied instructions.
176   for (int i = 0; i < instruction_count; i++) {
177     *(pc_ + i) = *(instructions + i);
178   }
179 
180   // Indicate that code has changed.
181   CPU::FlushICache(pc_, instruction_count);
182 }
183 
184 // -----------------------------------------------------------------------------
185 // Implementation of Operand
186 
Operand(Register base,int32_t disp)187 Operand::Operand(Register base, int32_t disp) : rex_(0) {
188   len_ = 1;
189   if (base.is(rsp) || base.is(r12)) {
190     // SIB byte is needed to encode (rsp + offset) or (r12 + offset).
191     set_sib(times_1, rsp, base);
192   }
193 
194   if (disp == 0 && !base.is(rbp) && !base.is(r13)) {
195     set_modrm(0, base);
196   } else if (is_int8(disp)) {
197     set_modrm(1, base);
198     set_disp8(disp);
199   } else {
200     set_modrm(2, base);
201     set_disp32(disp);
202   }
203 }
204 
205 
Operand(Register base,Register index,ScaleFactor scale,int32_t disp)206 Operand::Operand(Register base,
207                  Register index,
208                  ScaleFactor scale,
209                  int32_t disp) : rex_(0) {
210   ASSERT(!index.is(rsp));
211   len_ = 1;
212   set_sib(scale, index, base);
213   if (disp == 0 && !base.is(rbp) && !base.is(r13)) {
214     // This call to set_modrm doesn't overwrite the REX.B (or REX.X) bits
215     // possibly set by set_sib.
216     set_modrm(0, rsp);
217   } else if (is_int8(disp)) {
218     set_modrm(1, rsp);
219     set_disp8(disp);
220   } else {
221     set_modrm(2, rsp);
222     set_disp32(disp);
223   }
224 }
225 
226 
Operand(Register index,ScaleFactor scale,int32_t disp)227 Operand::Operand(Register index,
228                  ScaleFactor scale,
229                  int32_t disp) : rex_(0) {
230   ASSERT(!index.is(rsp));
231   len_ = 1;
232   set_modrm(0, rsp);
233   set_sib(scale, index, rbp);
234   set_disp32(disp);
235 }
236 
237 
238 // -----------------------------------------------------------------------------
239 // Implementation of Assembler.
240 
241 #ifdef GENERATED_CODE_COVERAGE
242 static void InitCoverageLog();
243 #endif
244 
245 byte* Assembler::spare_buffer_ = NULL;
246 
Assembler(void * buffer,int buffer_size)247 Assembler::Assembler(void* buffer, int buffer_size)
248     : code_targets_(100) {
249   if (buffer == NULL) {
250     // Do our own buffer management.
251     if (buffer_size <= kMinimalBufferSize) {
252       buffer_size = kMinimalBufferSize;
253 
254       if (spare_buffer_ != NULL) {
255         buffer = spare_buffer_;
256         spare_buffer_ = NULL;
257       }
258     }
259     if (buffer == NULL) {
260       buffer_ = NewArray<byte>(buffer_size);
261     } else {
262       buffer_ = static_cast<byte*>(buffer);
263     }
264     buffer_size_ = buffer_size;
265     own_buffer_ = true;
266   } else {
267     // Use externally provided buffer instead.
268     ASSERT(buffer_size > 0);
269     buffer_ = static_cast<byte*>(buffer);
270     buffer_size_ = buffer_size;
271     own_buffer_ = false;
272   }
273 
274   // Clear the buffer in debug mode unless it was provided by the
275   // caller in which case we can't be sure it's okay to overwrite
276   // existing code in it.
277 #ifdef DEBUG
278   if (own_buffer_) {
279     memset(buffer_, 0xCC, buffer_size);  // int3
280   }
281 #endif
282 
283   // Setup buffer pointers.
284   ASSERT(buffer_ != NULL);
285   pc_ = buffer_;
286   reloc_info_writer.Reposition(buffer_ + buffer_size, pc_);
287 
288   last_pc_ = NULL;
289   current_statement_position_ = RelocInfo::kNoPosition;
290   current_position_ = RelocInfo::kNoPosition;
291   written_statement_position_ = current_statement_position_;
292   written_position_ = current_position_;
293 #ifdef GENERATED_CODE_COVERAGE
294   InitCoverageLog();
295 #endif
296 }
297 
298 
~Assembler()299 Assembler::~Assembler() {
300   if (own_buffer_) {
301     if (spare_buffer_ == NULL && buffer_size_ == kMinimalBufferSize) {
302       spare_buffer_ = buffer_;
303     } else {
304       DeleteArray(buffer_);
305     }
306   }
307 }
308 
309 
GetCode(CodeDesc * desc)310 void Assembler::GetCode(CodeDesc* desc) {
311   // Finalize code (at this point overflow() may be true, but the gap ensures
312   // that we are still not overlapping instructions and relocation info).
313   ASSERT(pc_ <= reloc_info_writer.pos());  // No overlap.
314   // Setup code descriptor.
315   desc->buffer = buffer_;
316   desc->buffer_size = buffer_size_;
317   desc->instr_size = pc_offset();
318   ASSERT(desc->instr_size > 0);  // Zero-size code objects upset the system.
319   desc->reloc_size =
320       static_cast<int>((buffer_ + buffer_size_) - reloc_info_writer.pos());
321   desc->origin = this;
322 
323   Counters::reloc_info_size.Increment(desc->reloc_size);
324 }
325 
326 
Align(int m)327 void Assembler::Align(int m) {
328   ASSERT(IsPowerOf2(m));
329   while ((pc_offset() & (m - 1)) != 0) {
330     nop();
331   }
332 }
333 
334 
bind_to(Label * L,int pos)335 void Assembler::bind_to(Label* L, int pos) {
336   ASSERT(!L->is_bound());  // Label may only be bound once.
337   last_pc_ = NULL;
338   ASSERT(0 <= pos && pos <= pc_offset());  // Position must be valid.
339   if (L->is_linked()) {
340     int current = L->pos();
341     int next = long_at(current);
342     while (next != current) {
343       // Relative address, relative to point after address.
344       int imm32 = pos - (current + sizeof(int32_t));
345       long_at_put(current, imm32);
346       current = next;
347       next = long_at(next);
348     }
349     // Fix up last fixup on linked list.
350     int last_imm32 = pos - (current + sizeof(int32_t));
351     long_at_put(current, last_imm32);
352   }
353   L->bind_to(pos);
354 }
355 
356 
bind(Label * L)357 void Assembler::bind(Label* L) {
358   bind_to(L, pc_offset());
359 }
360 
361 
GrowBuffer()362 void Assembler::GrowBuffer() {
363   ASSERT(buffer_overflow());
364   if (!own_buffer_) FATAL("external code buffer is too small");
365 
366   // Compute new buffer size.
367   CodeDesc desc;  // the new buffer
368   if (buffer_size_ < 4*KB) {
369     desc.buffer_size = 4*KB;
370   } else {
371     desc.buffer_size = 2*buffer_size_;
372   }
373   // Some internal data structures overflow for very large buffers,
374   // they must ensure that kMaximalBufferSize is not too large.
375   if ((desc.buffer_size > kMaximalBufferSize) ||
376       (desc.buffer_size > Heap::MaxOldGenerationSize())) {
377     V8::FatalProcessOutOfMemory("Assembler::GrowBuffer");
378   }
379 
380   // Setup new buffer.
381   desc.buffer = NewArray<byte>(desc.buffer_size);
382   desc.instr_size = pc_offset();
383   desc.reloc_size =
384       static_cast<int>((buffer_ + buffer_size_) - (reloc_info_writer.pos()));
385 
386   // Clear the buffer in debug mode. Use 'int3' instructions to make
387   // sure to get into problems if we ever run uninitialized code.
388 #ifdef DEBUG
389   memset(desc.buffer, 0xCC, desc.buffer_size);
390 #endif
391 
392   // Copy the data.
393   intptr_t pc_delta = desc.buffer - buffer_;
394   intptr_t rc_delta = (desc.buffer + desc.buffer_size) -
395       (buffer_ + buffer_size_);
396   memmove(desc.buffer, buffer_, desc.instr_size);
397   memmove(rc_delta + reloc_info_writer.pos(),
398           reloc_info_writer.pos(), desc.reloc_size);
399 
400   // Switch buffers.
401   if (spare_buffer_ == NULL && buffer_size_ == kMinimalBufferSize) {
402     spare_buffer_ = buffer_;
403   } else {
404     DeleteArray(buffer_);
405   }
406   buffer_ = desc.buffer;
407   buffer_size_ = desc.buffer_size;
408   pc_ += pc_delta;
409   if (last_pc_ != NULL) {
410     last_pc_ += pc_delta;
411   }
412   reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
413                                reloc_info_writer.last_pc() + pc_delta);
414 
415   // Relocate runtime entries.
416   for (RelocIterator it(desc); !it.done(); it.next()) {
417     RelocInfo::Mode rmode = it.rinfo()->rmode();
418     if (rmode == RelocInfo::INTERNAL_REFERENCE) {
419       intptr_t* p = reinterpret_cast<intptr_t*>(it.rinfo()->pc());
420       if (*p != 0) {  // 0 means uninitialized.
421         *p += pc_delta;
422       }
423     }
424   }
425 
426   ASSERT(!buffer_overflow());
427 }
428 
429 
emit_operand(int code,const Operand & adr)430 void Assembler::emit_operand(int code, const Operand& adr) {
431   ASSERT(is_uint3(code));
432   const unsigned length = adr.len_;
433   ASSERT(length > 0);
434 
435   // Emit updated ModR/M byte containing the given register.
436   ASSERT((adr.buf_[0] & 0x38) == 0);
437   pc_[0] = adr.buf_[0] | code << 3;
438 
439   // Emit the rest of the encoded operand.
440   for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i];
441   pc_ += length;
442 }
443 
444 
445 // Assembler Instruction implementations.
446 
arithmetic_op(byte opcode,Register reg,const Operand & op)447 void Assembler::arithmetic_op(byte opcode, Register reg, const Operand& op) {
448   EnsureSpace ensure_space(this);
449   last_pc_ = pc_;
450   emit_rex_64(reg, op);
451   emit(opcode);
452   emit_operand(reg, op);
453 }
454 
455 
arithmetic_op(byte opcode,Register reg,Register rm_reg)456 void Assembler::arithmetic_op(byte opcode, Register reg, Register rm_reg) {
457   EnsureSpace ensure_space(this);
458   last_pc_ = pc_;
459   emit_rex_64(reg, rm_reg);
460   emit(opcode);
461   emit_modrm(reg, rm_reg);
462 }
463 
464 
arithmetic_op_16(byte opcode,Register reg,Register rm_reg)465 void Assembler::arithmetic_op_16(byte opcode, Register reg, Register rm_reg) {
466   EnsureSpace ensure_space(this);
467   last_pc_ = pc_;
468   emit(0x66);
469   emit_optional_rex_32(reg, rm_reg);
470   emit(opcode);
471   emit_modrm(reg, rm_reg);
472 }
473 
474 
arithmetic_op_16(byte opcode,Register reg,const Operand & rm_reg)475 void Assembler::arithmetic_op_16(byte opcode,
476                                  Register reg,
477                                  const Operand& rm_reg) {
478   EnsureSpace ensure_space(this);
479   last_pc_ = pc_;
480   emit(0x66);
481   emit_optional_rex_32(reg, rm_reg);
482   emit(opcode);
483   emit_operand(reg, rm_reg);
484 }
485 
486 
arithmetic_op_32(byte opcode,Register reg,Register rm_reg)487 void Assembler::arithmetic_op_32(byte opcode, Register reg, Register rm_reg) {
488   EnsureSpace ensure_space(this);
489   last_pc_ = pc_;
490   emit_optional_rex_32(reg, rm_reg);
491   emit(opcode);
492   emit_modrm(reg, rm_reg);
493 }
494 
495 
arithmetic_op_32(byte opcode,Register reg,const Operand & rm_reg)496 void Assembler::arithmetic_op_32(byte opcode,
497                                  Register reg,
498                                  const Operand& rm_reg) {
499   EnsureSpace ensure_space(this);
500   last_pc_ = pc_;
501   emit_optional_rex_32(reg, rm_reg);
502   emit(opcode);
503   emit_operand(reg, rm_reg);
504 }
505 
506 
immediate_arithmetic_op(byte subcode,Register dst,Immediate src)507 void Assembler::immediate_arithmetic_op(byte subcode,
508                                         Register dst,
509                                         Immediate src) {
510   EnsureSpace ensure_space(this);
511   last_pc_ = pc_;
512   emit_rex_64(dst);
513   if (is_int8(src.value_)) {
514     emit(0x83);
515     emit_modrm(subcode, dst);
516     emit(src.value_);
517   } else if (dst.is(rax)) {
518     emit(0x05 | (subcode << 3));
519     emitl(src.value_);
520   } else {
521     emit(0x81);
522     emit_modrm(subcode, dst);
523     emitl(src.value_);
524   }
525 }
526 
immediate_arithmetic_op(byte subcode,const Operand & dst,Immediate src)527 void Assembler::immediate_arithmetic_op(byte subcode,
528                                         const Operand& dst,
529                                         Immediate src) {
530   EnsureSpace ensure_space(this);
531   last_pc_ = pc_;
532   emit_rex_64(dst);
533   if (is_int8(src.value_)) {
534     emit(0x83);
535     emit_operand(subcode, dst);
536     emit(src.value_);
537   } else {
538     emit(0x81);
539     emit_operand(subcode, dst);
540     emitl(src.value_);
541   }
542 }
543 
544 
immediate_arithmetic_op_16(byte subcode,Register dst,Immediate src)545 void Assembler::immediate_arithmetic_op_16(byte subcode,
546                                            Register dst,
547                                            Immediate src) {
548   EnsureSpace ensure_space(this);
549   last_pc_ = pc_;
550   emit(0x66);  // Operand size override prefix.
551   emit_optional_rex_32(dst);
552   if (is_int8(src.value_)) {
553     emit(0x83);
554     emit_modrm(subcode, dst);
555     emit(src.value_);
556   } else if (dst.is(rax)) {
557     emit(0x05 | (subcode << 3));
558     emitw(src.value_);
559   } else {
560     emit(0x81);
561     emit_modrm(subcode, dst);
562     emitw(src.value_);
563   }
564 }
565 
566 
immediate_arithmetic_op_16(byte subcode,const Operand & dst,Immediate src)567 void Assembler::immediate_arithmetic_op_16(byte subcode,
568                                            const Operand& dst,
569                                            Immediate src) {
570   EnsureSpace ensure_space(this);
571   last_pc_ = pc_;
572   emit(0x66);  // Operand size override prefix.
573   emit_optional_rex_32(dst);
574   if (is_int8(src.value_)) {
575     emit(0x83);
576     emit_operand(subcode, dst);
577     emit(src.value_);
578   } else {
579     emit(0x81);
580     emit_operand(subcode, dst);
581     emitw(src.value_);
582   }
583 }
584 
585 
immediate_arithmetic_op_32(byte subcode,Register dst,Immediate src)586 void Assembler::immediate_arithmetic_op_32(byte subcode,
587                                            Register dst,
588                                            Immediate src) {
589   EnsureSpace ensure_space(this);
590   last_pc_ = pc_;
591   emit_optional_rex_32(dst);
592   if (is_int8(src.value_)) {
593     emit(0x83);
594     emit_modrm(subcode, dst);
595     emit(src.value_);
596   } else if (dst.is(rax)) {
597     emit(0x05 | (subcode << 3));
598     emitl(src.value_);
599   } else {
600     emit(0x81);
601     emit_modrm(subcode, dst);
602     emitl(src.value_);
603   }
604 }
605 
606 
immediate_arithmetic_op_32(byte subcode,const Operand & dst,Immediate src)607 void Assembler::immediate_arithmetic_op_32(byte subcode,
608                                            const Operand& dst,
609                                            Immediate src) {
610   EnsureSpace ensure_space(this);
611   last_pc_ = pc_;
612   emit_optional_rex_32(dst);
613   if (is_int8(src.value_)) {
614     emit(0x83);
615     emit_operand(subcode, dst);
616     emit(src.value_);
617   } else {
618     emit(0x81);
619     emit_operand(subcode, dst);
620     emitl(src.value_);
621   }
622 }
623 
624 
immediate_arithmetic_op_8(byte subcode,const Operand & dst,Immediate src)625 void Assembler::immediate_arithmetic_op_8(byte subcode,
626                                           const Operand& dst,
627                                           Immediate src) {
628   EnsureSpace ensure_space(this);
629   last_pc_ = pc_;
630   emit_optional_rex_32(dst);
631   ASSERT(is_int8(src.value_) || is_uint8(src.value_));
632   emit(0x80);
633   emit_operand(subcode, dst);
634   emit(src.value_);
635 }
636 
637 
immediate_arithmetic_op_8(byte subcode,Register dst,Immediate src)638 void Assembler::immediate_arithmetic_op_8(byte subcode,
639                                           Register dst,
640                                           Immediate src) {
641   EnsureSpace ensure_space(this);
642   last_pc_ = pc_;
643   if (dst.code() > 3) {
644     // Use 64-bit mode byte registers.
645     emit_rex_64(dst);
646   }
647   ASSERT(is_int8(src.value_) || is_uint8(src.value_));
648   emit(0x80);
649   emit_modrm(subcode, dst);
650   emit(src.value_);
651 }
652 
653 
shift(Register dst,Immediate shift_amount,int subcode)654 void Assembler::shift(Register dst, Immediate shift_amount, int subcode) {
655   EnsureSpace ensure_space(this);
656   last_pc_ = pc_;
657   ASSERT(is_uint6(shift_amount.value_));  // illegal shift count
658   if (shift_amount.value_ == 1) {
659     emit_rex_64(dst);
660     emit(0xD1);
661     emit_modrm(subcode, dst);
662   } else {
663     emit_rex_64(dst);
664     emit(0xC1);
665     emit_modrm(subcode, dst);
666     emit(shift_amount.value_);
667   }
668 }
669 
670 
shift(Register dst,int subcode)671 void Assembler::shift(Register dst, int subcode) {
672   EnsureSpace ensure_space(this);
673   last_pc_ = pc_;
674   emit_rex_64(dst);
675   emit(0xD3);
676   emit_modrm(subcode, dst);
677 }
678 
679 
shift_32(Register dst,int subcode)680 void Assembler::shift_32(Register dst, int subcode) {
681   EnsureSpace ensure_space(this);
682   last_pc_ = pc_;
683   emit_optional_rex_32(dst);
684   emit(0xD3);
685   emit_modrm(subcode, dst);
686 }
687 
688 
shift_32(Register dst,Immediate shift_amount,int subcode)689 void Assembler::shift_32(Register dst, Immediate shift_amount, int subcode) {
690   EnsureSpace ensure_space(this);
691   last_pc_ = pc_;
692   ASSERT(is_uint5(shift_amount.value_));  // illegal shift count
693   if (shift_amount.value_ == 1) {
694     emit_optional_rex_32(dst);
695     emit(0xD1);
696     emit_modrm(subcode, dst);
697   } else {
698     emit_optional_rex_32(dst);
699     emit(0xC1);
700     emit_modrm(subcode, dst);
701     emit(shift_amount.value_);
702   }
703 }
704 
705 
bt(const Operand & dst,Register src)706 void Assembler::bt(const Operand& dst, Register src) {
707   EnsureSpace ensure_space(this);
708   last_pc_ = pc_;
709   emit_rex_64(src, dst);
710   emit(0x0F);
711   emit(0xA3);
712   emit_operand(src, dst);
713 }
714 
715 
bts(const Operand & dst,Register src)716 void Assembler::bts(const Operand& dst, Register src) {
717   EnsureSpace ensure_space(this);
718   last_pc_ = pc_;
719   emit_rex_64(src, dst);
720   emit(0x0F);
721   emit(0xAB);
722   emit_operand(src, dst);
723 }
724 
725 
call(Label * L)726 void Assembler::call(Label* L) {
727   EnsureSpace ensure_space(this);
728   last_pc_ = pc_;
729   // 1110 1000 #32-bit disp.
730   emit(0xE8);
731   if (L->is_bound()) {
732     int offset = L->pos() - pc_offset() - sizeof(int32_t);
733     ASSERT(offset <= 0);
734     emitl(offset);
735   } else if (L->is_linked()) {
736     emitl(L->pos());
737     L->link_to(pc_offset() - sizeof(int32_t));
738   } else {
739     ASSERT(L->is_unused());
740     int32_t current = pc_offset();
741     emitl(current);
742     L->link_to(current);
743   }
744 }
745 
746 
call(Handle<Code> target,RelocInfo::Mode rmode)747 void Assembler::call(Handle<Code> target, RelocInfo::Mode rmode) {
748   EnsureSpace ensure_space(this);
749   last_pc_ = pc_;
750   // 1110 1000 #32-bit disp.
751   emit(0xE8);
752   emit_code_target(target, rmode);
753 }
754 
755 
call(Register adr)756 void Assembler::call(Register adr) {
757   EnsureSpace ensure_space(this);
758   last_pc_ = pc_;
759   // Opcode: FF /2 r64.
760   if (adr.high_bit()) {
761     emit_rex_64(adr);
762   }
763   emit(0xFF);
764   emit_modrm(0x2, adr);
765 }
766 
767 
call(const Operand & op)768 void Assembler::call(const Operand& op) {
769   EnsureSpace ensure_space(this);
770   last_pc_ = pc_;
771   // Opcode: FF /2 m64.
772   emit_rex_64(op);
773   emit(0xFF);
774   emit_operand(2, op);
775 }
776 
777 
clc()778 void Assembler::clc() {
779   EnsureSpace ensure_space(this);
780   last_pc_ = pc_;
781   emit(0xF8);
782 }
783 
cdq()784 void Assembler::cdq() {
785   EnsureSpace ensure_space(this);
786   last_pc_ = pc_;
787   emit(0x99);
788 }
789 
790 
cmovq(Condition cc,Register dst,Register src)791 void Assembler::cmovq(Condition cc, Register dst, Register src) {
792   if (cc == always) {
793     movq(dst, src);
794   } else if (cc == never) {
795     return;
796   }
797   // No need to check CpuInfo for CMOV support, it's a required part of the
798   // 64-bit architecture.
799   ASSERT(cc >= 0);  // Use mov for unconditional moves.
800   EnsureSpace ensure_space(this);
801   last_pc_ = pc_;
802   // Opcode: REX.W 0f 40 + cc /r.
803   emit_rex_64(dst, src);
804   emit(0x0f);
805   emit(0x40 + cc);
806   emit_modrm(dst, src);
807 }
808 
809 
cmovq(Condition cc,Register dst,const Operand & src)810 void Assembler::cmovq(Condition cc, Register dst, const Operand& src) {
811   if (cc == always) {
812     movq(dst, src);
813   } else if (cc == never) {
814     return;
815   }
816   ASSERT(cc >= 0);
817   EnsureSpace ensure_space(this);
818   last_pc_ = pc_;
819   // Opcode: REX.W 0f 40 + cc /r.
820   emit_rex_64(dst, src);
821   emit(0x0f);
822   emit(0x40 + cc);
823   emit_operand(dst, src);
824 }
825 
826 
cmovl(Condition cc,Register dst,Register src)827 void Assembler::cmovl(Condition cc, Register dst, Register src) {
828   if (cc == always) {
829     movl(dst, src);
830   } else if (cc == never) {
831     return;
832   }
833   ASSERT(cc >= 0);
834   EnsureSpace ensure_space(this);
835   last_pc_ = pc_;
836   // Opcode: 0f 40 + cc /r.
837   emit_optional_rex_32(dst, src);
838   emit(0x0f);
839   emit(0x40 + cc);
840   emit_modrm(dst, src);
841 }
842 
843 
cmovl(Condition cc,Register dst,const Operand & src)844 void Assembler::cmovl(Condition cc, Register dst, const Operand& src) {
845   if (cc == always) {
846     movl(dst, src);
847   } else if (cc == never) {
848     return;
849   }
850   ASSERT(cc >= 0);
851   EnsureSpace ensure_space(this);
852   last_pc_ = pc_;
853   // Opcode: 0f 40 + cc /r.
854   emit_optional_rex_32(dst, src);
855   emit(0x0f);
856   emit(0x40 + cc);
857   emit_operand(dst, src);
858 }
859 
860 
cmpb_al(Immediate imm8)861 void Assembler::cmpb_al(Immediate imm8) {
862   ASSERT(is_int8(imm8.value_) || is_uint8(imm8.value_));
863   EnsureSpace ensure_space(this);
864   last_pc_ = pc_;
865   emit(0x3c);
866   emit(imm8.value_);
867 }
868 
869 
cpuid()870 void Assembler::cpuid() {
871   ASSERT(CpuFeatures::IsEnabled(CPUID));
872   EnsureSpace ensure_space(this);
873   last_pc_ = pc_;
874   emit(0x0F);
875   emit(0xA2);
876 }
877 
878 
cqo()879 void Assembler::cqo() {
880   EnsureSpace ensure_space(this);
881   last_pc_ = pc_;
882   emit_rex_64();
883   emit(0x99);
884 }
885 
886 
decq(Register dst)887 void Assembler::decq(Register dst) {
888   EnsureSpace ensure_space(this);
889   last_pc_ = pc_;
890   emit_rex_64(dst);
891   emit(0xFF);
892   emit_modrm(0x1, dst);
893 }
894 
895 
decq(const Operand & dst)896 void Assembler::decq(const Operand& dst) {
897   EnsureSpace ensure_space(this);
898   last_pc_ = pc_;
899   emit_rex_64(dst);
900   emit(0xFF);
901   emit_operand(1, dst);
902 }
903 
904 
decl(Register dst)905 void Assembler::decl(Register dst) {
906   EnsureSpace ensure_space(this);
907   last_pc_ = pc_;
908   emit_optional_rex_32(dst);
909   emit(0xFF);
910   emit_modrm(0x1, dst);
911 }
912 
913 
decl(const Operand & dst)914 void Assembler::decl(const Operand& dst) {
915   EnsureSpace ensure_space(this);
916   last_pc_ = pc_;
917   emit_optional_rex_32(dst);
918   emit(0xFF);
919   emit_operand(1, dst);
920 }
921 
922 
decb(Register dst)923 void Assembler::decb(Register dst) {
924   EnsureSpace ensure_space(this);
925   last_pc_ = pc_;
926   if (dst.code() > 3) {
927     // Register is not one of al, bl, cl, dl.  Its encoding needs REX.
928     emit_rex_32(dst);
929   }
930   emit(0xFE);
931   emit_modrm(0x1, dst);
932 }
933 
934 
decb(const Operand & dst)935 void Assembler::decb(const Operand& dst) {
936   EnsureSpace ensure_space(this);
937   last_pc_ = pc_;
938   emit_optional_rex_32(dst);
939   emit(0xFE);
940   emit_operand(1, dst);
941 }
942 
943 
enter(Immediate size)944 void Assembler::enter(Immediate size) {
945   EnsureSpace ensure_space(this);
946   last_pc_ = pc_;
947   emit(0xC8);
948   emitw(size.value_);  // 16 bit operand, always.
949   emit(0);
950 }
951 
952 
hlt()953 void Assembler::hlt() {
954   EnsureSpace ensure_space(this);
955   last_pc_ = pc_;
956   emit(0xF4);
957 }
958 
959 
idivq(Register src)960 void Assembler::idivq(Register src) {
961   EnsureSpace ensure_space(this);
962   last_pc_ = pc_;
963   emit_rex_64(src);
964   emit(0xF7);
965   emit_modrm(0x7, src);
966 }
967 
968 
idivl(Register src)969 void Assembler::idivl(Register src) {
970   EnsureSpace ensure_space(this);
971   last_pc_ = pc_;
972   emit_optional_rex_32(src);
973   emit(0xF7);
974   emit_modrm(0x7, src);
975 }
976 
977 
imul(Register src)978 void Assembler::imul(Register src) {
979   EnsureSpace ensure_space(this);
980   last_pc_ = pc_;
981   emit_rex_64(src);
982   emit(0xF7);
983   emit_modrm(0x5, src);
984 }
985 
986 
imul(Register dst,Register src)987 void Assembler::imul(Register dst, Register src) {
988   EnsureSpace ensure_space(this);
989   last_pc_ = pc_;
990   emit_rex_64(dst, src);
991   emit(0x0F);
992   emit(0xAF);
993   emit_modrm(dst, src);
994 }
995 
996 
imul(Register dst,const Operand & src)997 void Assembler::imul(Register dst, const Operand& src) {
998   EnsureSpace ensure_space(this);
999   last_pc_ = pc_;
1000   emit_rex_64(dst, src);
1001   emit(0x0F);
1002   emit(0xAF);
1003   emit_operand(dst, src);
1004 }
1005 
1006 
imul(Register dst,Register src,Immediate imm)1007 void Assembler::imul(Register dst, Register src, Immediate imm) {
1008   EnsureSpace ensure_space(this);
1009   last_pc_ = pc_;
1010   emit_rex_64(dst, src);
1011   if (is_int8(imm.value_)) {
1012     emit(0x6B);
1013     emit_modrm(dst, src);
1014     emit(imm.value_);
1015   } else {
1016     emit(0x69);
1017     emit_modrm(dst, src);
1018     emitl(imm.value_);
1019   }
1020 }
1021 
1022 
imull(Register dst,Register src)1023 void Assembler::imull(Register dst, Register src) {
1024   EnsureSpace ensure_space(this);
1025   last_pc_ = pc_;
1026   emit_optional_rex_32(dst, src);
1027   emit(0x0F);
1028   emit(0xAF);
1029   emit_modrm(dst, src);
1030 }
1031 
1032 
incq(Register dst)1033 void Assembler::incq(Register dst) {
1034   EnsureSpace ensure_space(this);
1035   last_pc_ = pc_;
1036   emit_rex_64(dst);
1037   emit(0xFF);
1038   emit_modrm(0x0, dst);
1039 }
1040 
1041 
incq(const Operand & dst)1042 void Assembler::incq(const Operand& dst) {
1043   EnsureSpace ensure_space(this);
1044   last_pc_ = pc_;
1045   emit_rex_64(dst);
1046   emit(0xFF);
1047   emit_operand(0, dst);
1048 }
1049 
1050 
incl(const Operand & dst)1051 void Assembler::incl(const Operand& dst) {
1052   EnsureSpace ensure_space(this);
1053   last_pc_ = pc_;
1054   emit_optional_rex_32(dst);
1055   emit(0xFF);
1056   emit_operand(0, dst);
1057 }
1058 
1059 
int3()1060 void Assembler::int3() {
1061   EnsureSpace ensure_space(this);
1062   last_pc_ = pc_;
1063   emit(0xCC);
1064 }
1065 
1066 
j(Condition cc,Label * L)1067 void Assembler::j(Condition cc, Label* L) {
1068   if (cc == always) {
1069     jmp(L);
1070     return;
1071   } else if (cc == never) {
1072     return;
1073   }
1074   EnsureSpace ensure_space(this);
1075   last_pc_ = pc_;
1076   ASSERT(is_uint4(cc));
1077   if (L->is_bound()) {
1078     const int short_size = 2;
1079     const int long_size  = 6;
1080     int offs = L->pos() - pc_offset();
1081     ASSERT(offs <= 0);
1082     if (is_int8(offs - short_size)) {
1083       // 0111 tttn #8-bit disp.
1084       emit(0x70 | cc);
1085       emit((offs - short_size) & 0xFF);
1086     } else {
1087       // 0000 1111 1000 tttn #32-bit disp.
1088       emit(0x0F);
1089       emit(0x80 | cc);
1090       emitl(offs - long_size);
1091     }
1092   } else if (L->is_linked()) {
1093     // 0000 1111 1000 tttn #32-bit disp.
1094     emit(0x0F);
1095     emit(0x80 | cc);
1096     emitl(L->pos());
1097     L->link_to(pc_offset() - sizeof(int32_t));
1098   } else {
1099     ASSERT(L->is_unused());
1100     emit(0x0F);
1101     emit(0x80 | cc);
1102     int32_t current = pc_offset();
1103     emitl(current);
1104     L->link_to(current);
1105   }
1106 }
1107 
1108 
j(Condition cc,Handle<Code> target,RelocInfo::Mode rmode)1109 void Assembler::j(Condition cc,
1110                   Handle<Code> target,
1111                   RelocInfo::Mode rmode) {
1112   EnsureSpace ensure_space(this);
1113   last_pc_ = pc_;
1114   ASSERT(is_uint4(cc));
1115   // 0000 1111 1000 tttn #32-bit disp.
1116   emit(0x0F);
1117   emit(0x80 | cc);
1118   emit_code_target(target, rmode);
1119 }
1120 
1121 
jmp(Label * L)1122 void Assembler::jmp(Label* L) {
1123   EnsureSpace ensure_space(this);
1124   last_pc_ = pc_;
1125   if (L->is_bound()) {
1126     int offs = L->pos() - pc_offset() - 1;
1127     ASSERT(offs <= 0);
1128     if (is_int8(offs - sizeof(int8_t))) {
1129       // 1110 1011 #8-bit disp.
1130       emit(0xEB);
1131       emit((offs - sizeof(int8_t)) & 0xFF);
1132     } else {
1133       // 1110 1001 #32-bit disp.
1134       emit(0xE9);
1135       emitl(offs - sizeof(int32_t));
1136     }
1137   } else  if (L->is_linked()) {
1138     // 1110 1001 #32-bit disp.
1139     emit(0xE9);
1140     emitl(L->pos());
1141     L->link_to(pc_offset() - sizeof(int32_t));
1142   } else {
1143     // 1110 1001 #32-bit disp.
1144     ASSERT(L->is_unused());
1145     emit(0xE9);
1146     int32_t current = pc_offset();
1147     emitl(current);
1148     L->link_to(current);
1149   }
1150 }
1151 
1152 
jmp(Handle<Code> target,RelocInfo::Mode rmode)1153 void Assembler::jmp(Handle<Code> target, RelocInfo::Mode rmode) {
1154   EnsureSpace ensure_space(this);
1155   last_pc_ = pc_;
1156   // 1110 1001 #32-bit disp.
1157   emit(0xE9);
1158   emit_code_target(target, rmode);
1159 }
1160 
1161 
jmp(Register target)1162 void Assembler::jmp(Register target) {
1163   EnsureSpace ensure_space(this);
1164   last_pc_ = pc_;
1165   // Opcode FF/4 r64.
1166   if (target.high_bit()) {
1167     emit_rex_64(target);
1168   }
1169   emit(0xFF);
1170   emit_modrm(0x4, target);
1171 }
1172 
1173 
jmp(const Operand & src)1174 void Assembler::jmp(const Operand& src) {
1175   EnsureSpace ensure_space(this);
1176   last_pc_ = pc_;
1177   // Opcode FF/4 m64.
1178   emit_optional_rex_32(src);
1179   emit(0xFF);
1180   emit_operand(0x4, src);
1181 }
1182 
1183 
lea(Register dst,const Operand & src)1184 void Assembler::lea(Register dst, const Operand& src) {
1185   EnsureSpace ensure_space(this);
1186   last_pc_ = pc_;
1187   emit_rex_64(dst, src);
1188   emit(0x8D);
1189   emit_operand(dst, src);
1190 }
1191 
1192 
load_rax(void * value,RelocInfo::Mode mode)1193 void Assembler::load_rax(void* value, RelocInfo::Mode mode) {
1194   EnsureSpace ensure_space(this);
1195   last_pc_ = pc_;
1196   emit(0x48);  // REX.W
1197   emit(0xA1);
1198   emitq(reinterpret_cast<uintptr_t>(value), mode);
1199 }
1200 
1201 
load_rax(ExternalReference ref)1202 void Assembler::load_rax(ExternalReference ref) {
1203   load_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE);
1204 }
1205 
1206 
leave()1207 void Assembler::leave() {
1208   EnsureSpace ensure_space(this);
1209   last_pc_ = pc_;
1210   emit(0xC9);
1211 }
1212 
1213 
movb(Register dst,const Operand & src)1214 void Assembler::movb(Register dst, const Operand& src) {
1215   EnsureSpace ensure_space(this);
1216   last_pc_ = pc_;
1217   emit_rex_32(dst, src);
1218   emit(0x8A);
1219   emit_operand(dst, src);
1220 }
1221 
movb(Register dst,Immediate imm)1222 void Assembler::movb(Register dst, Immediate imm) {
1223   EnsureSpace ensure_space(this);
1224   last_pc_ = pc_;
1225   emit_rex_32(dst);
1226   emit(0xC6);
1227   emit_modrm(0x0, dst);
1228   emit(imm.value_);
1229 }
1230 
movb(const Operand & dst,Register src)1231 void Assembler::movb(const Operand& dst, Register src) {
1232   EnsureSpace ensure_space(this);
1233   last_pc_ = pc_;
1234   emit_rex_32(src, dst);
1235   emit(0x88);
1236   emit_operand(src, dst);
1237 }
1238 
movw(const Operand & dst,Register src)1239 void Assembler::movw(const Operand& dst, Register src) {
1240   EnsureSpace ensure_space(this);
1241   last_pc_ = pc_;
1242   emit(0x66);
1243   emit_optional_rex_32(src, dst);
1244   emit(0x89);
1245   emit_operand(src, dst);
1246 }
1247 
movl(Register dst,const Operand & src)1248 void Assembler::movl(Register dst, const Operand& src) {
1249   EnsureSpace ensure_space(this);
1250   last_pc_ = pc_;
1251   emit_optional_rex_32(dst, src);
1252   emit(0x8B);
1253   emit_operand(dst, src);
1254 }
1255 
1256 
movl(Register dst,Register src)1257 void Assembler::movl(Register dst, Register src) {
1258   EnsureSpace ensure_space(this);
1259   last_pc_ = pc_;
1260   emit_optional_rex_32(dst, src);
1261   emit(0x8B);
1262   emit_modrm(dst, src);
1263 }
1264 
1265 
movl(const Operand & dst,Register src)1266 void Assembler::movl(const Operand& dst, Register src) {
1267   EnsureSpace ensure_space(this);
1268   last_pc_ = pc_;
1269   emit_optional_rex_32(src, dst);
1270   emit(0x89);
1271   emit_operand(src, dst);
1272 }
1273 
1274 
movl(const Operand & dst,Immediate value)1275 void Assembler::movl(const Operand& dst, Immediate value) {
1276   EnsureSpace ensure_space(this);
1277   last_pc_ = pc_;
1278   emit_optional_rex_32(dst);
1279   emit(0xC7);
1280   emit_operand(0x0, dst);
1281   emit(value);  // Only 32-bit immediates are possible, not 8-bit immediates.
1282 }
1283 
1284 
movl(Register dst,Immediate value)1285 void Assembler::movl(Register dst, Immediate value) {
1286   EnsureSpace ensure_space(this);
1287   last_pc_ = pc_;
1288   emit_optional_rex_32(dst);
1289   emit(0xC7);
1290   emit_modrm(0x0, dst);
1291   emit(value);  // Only 32-bit immediates are possible, not 8-bit immediates.
1292 }
1293 
1294 
movq(Register dst,const Operand & src)1295 void Assembler::movq(Register dst, const Operand& src) {
1296   EnsureSpace ensure_space(this);
1297   last_pc_ = pc_;
1298   emit_rex_64(dst, src);
1299   emit(0x8B);
1300   emit_operand(dst, src);
1301 }
1302 
1303 
movq(Register dst,Register src)1304 void Assembler::movq(Register dst, Register src) {
1305   EnsureSpace ensure_space(this);
1306   last_pc_ = pc_;
1307   emit_rex_64(dst, src);
1308   emit(0x8B);
1309   emit_modrm(dst, src);
1310 }
1311 
1312 
movq(Register dst,Immediate value)1313 void Assembler::movq(Register dst, Immediate value) {
1314   EnsureSpace ensure_space(this);
1315   last_pc_ = pc_;
1316   emit_rex_64(dst);
1317   emit(0xC7);
1318   emit_modrm(0x0, dst);
1319   emit(value);  // Only 32-bit immediates are possible, not 8-bit immediates.
1320 }
1321 
1322 
movq(const Operand & dst,Register src)1323 void Assembler::movq(const Operand& dst, Register src) {
1324   EnsureSpace ensure_space(this);
1325   last_pc_ = pc_;
1326   emit_rex_64(src, dst);
1327   emit(0x89);
1328   emit_operand(src, dst);
1329 }
1330 
1331 
movq(Register dst,void * value,RelocInfo::Mode rmode)1332 void Assembler::movq(Register dst, void* value, RelocInfo::Mode rmode) {
1333   // This method must not be used with heap object references. The stored
1334   // address is not GC safe. Use the handle version instead.
1335   ASSERT(rmode > RelocInfo::LAST_GCED_ENUM);
1336   EnsureSpace ensure_space(this);
1337   last_pc_ = pc_;
1338   emit_rex_64(dst);
1339   emit(0xB8 | dst.low_bits());
1340   emitq(reinterpret_cast<uintptr_t>(value), rmode);
1341 }
1342 
1343 
movq(Register dst,int64_t value,RelocInfo::Mode rmode)1344 void Assembler::movq(Register dst, int64_t value, RelocInfo::Mode rmode) {
1345   // Non-relocatable values might not need a 64-bit representation.
1346   if (rmode == RelocInfo::NONE) {
1347     // Sadly, there is no zero or sign extending move for 8-bit immediates.
1348     if (is_int32(value)) {
1349       movq(dst, Immediate(static_cast<int32_t>(value)));
1350       return;
1351     } else if (is_uint32(value)) {
1352       movl(dst, Immediate(static_cast<int32_t>(value)));
1353       return;
1354     }
1355     // Value cannot be represented by 32 bits, so do a full 64 bit immediate
1356     // value.
1357   }
1358   EnsureSpace ensure_space(this);
1359   last_pc_ = pc_;
1360   emit_rex_64(dst);
1361   emit(0xB8 | dst.low_bits());
1362   emitq(value, rmode);
1363 }
1364 
1365 
movq(Register dst,ExternalReference ref)1366 void Assembler::movq(Register dst, ExternalReference ref) {
1367   EnsureSpace ensure_space(this);
1368   last_pc_ = pc_;
1369   emit_rex_64(dst);
1370   emit(0xB8 | dst.low_bits());
1371   emitq(reinterpret_cast<uintptr_t>(ref.address()),
1372         RelocInfo::EXTERNAL_REFERENCE);
1373 }
1374 
1375 
movq(const Operand & dst,Immediate value)1376 void Assembler::movq(const Operand& dst, Immediate value) {
1377   EnsureSpace ensure_space(this);
1378   last_pc_ = pc_;
1379   emit_rex_64(dst);
1380   emit(0xC7);
1381   emit_operand(0, dst);
1382   emit(value);
1383 }
1384 
1385 
1386 // Loads the ip-relative location of the src label into the target location
1387 // (as a 32-bit offset sign extended to 64-bit).
movl(const Operand & dst,Label * src)1388 void Assembler::movl(const Operand& dst, Label* src) {
1389   EnsureSpace ensure_space(this);
1390   last_pc_ = pc_;
1391   emit_optional_rex_32(dst);
1392   emit(0xC7);
1393   emit_operand(0, dst);
1394   if (src->is_bound()) {
1395     int offset = src->pos() - pc_offset() - sizeof(int32_t);
1396     ASSERT(offset <= 0);
1397     emitl(offset);
1398   } else if (src->is_linked()) {
1399     emitl(src->pos());
1400     src->link_to(pc_offset() - sizeof(int32_t));
1401   } else {
1402     ASSERT(src->is_unused());
1403     int32_t current = pc_offset();
1404     emitl(current);
1405     src->link_to(current);
1406   }
1407 }
1408 
1409 
movq(Register dst,Handle<Object> value,RelocInfo::Mode mode)1410 void Assembler::movq(Register dst, Handle<Object> value, RelocInfo::Mode mode) {
1411   // If there is no relocation info, emit the value of the handle efficiently
1412   // (possibly using less that 8 bytes for the value).
1413   if (mode == RelocInfo::NONE) {
1414     // There is no possible reason to store a heap pointer without relocation
1415     // info, so it must be a smi.
1416     ASSERT(value->IsSmi());
1417     movq(dst, reinterpret_cast<int64_t>(*value), RelocInfo::NONE);
1418   } else {
1419     EnsureSpace ensure_space(this);
1420     last_pc_ = pc_;
1421     ASSERT(value->IsHeapObject());
1422     ASSERT(!Heap::InNewSpace(*value));
1423     emit_rex_64(dst);
1424     emit(0xB8 | dst.low_bits());
1425     emitq(reinterpret_cast<uintptr_t>(value.location()), mode);
1426   }
1427 }
1428 
1429 
movsxbq(Register dst,const Operand & src)1430 void Assembler::movsxbq(Register dst, const Operand& src) {
1431   EnsureSpace ensure_space(this);
1432   last_pc_ = pc_;
1433   emit_rex_32(dst, src);
1434   emit(0x0F);
1435   emit(0xBE);
1436   emit_operand(dst, src);
1437 }
1438 
1439 
movsxwq(Register dst,const Operand & src)1440 void Assembler::movsxwq(Register dst, const Operand& src) {
1441   EnsureSpace ensure_space(this);
1442   last_pc_ = pc_;
1443   emit_rex_64(dst, src);
1444   emit(0x0F);
1445   emit(0xBF);
1446   emit_operand(dst, src);
1447 }
1448 
1449 
movsxlq(Register dst,Register src)1450 void Assembler::movsxlq(Register dst, Register src) {
1451   EnsureSpace ensure_space(this);
1452   last_pc_ = pc_;
1453   emit_rex_64(dst, src);
1454   emit(0x63);
1455   emit_modrm(dst, src);
1456 }
1457 
1458 
movsxlq(Register dst,const Operand & src)1459 void Assembler::movsxlq(Register dst, const Operand& src) {
1460   EnsureSpace ensure_space(this);
1461   last_pc_ = pc_;
1462   emit_rex_64(dst, src);
1463   emit(0x63);
1464   emit_operand(dst, src);
1465 }
1466 
1467 
movzxbq(Register dst,const Operand & src)1468 void Assembler::movzxbq(Register dst, const Operand& src) {
1469   EnsureSpace ensure_space(this);
1470   last_pc_ = pc_;
1471   emit_rex_64(dst, src);
1472   emit(0x0F);
1473   emit(0xB6);
1474   emit_operand(dst, src);
1475 }
1476 
1477 
movzxbl(Register dst,const Operand & src)1478 void Assembler::movzxbl(Register dst, const Operand& src) {
1479   EnsureSpace ensure_space(this);
1480   last_pc_ = pc_;
1481   emit_optional_rex_32(dst, src);
1482   emit(0x0F);
1483   emit(0xB6);
1484   emit_operand(dst, src);
1485 }
1486 
1487 
movzxwq(Register dst,const Operand & src)1488 void Assembler::movzxwq(Register dst, const Operand& src) {
1489   EnsureSpace ensure_space(this);
1490   last_pc_ = pc_;
1491   emit_rex_64(dst, src);
1492   emit(0x0F);
1493   emit(0xB7);
1494   emit_operand(dst, src);
1495 }
1496 
1497 
movzxwl(Register dst,const Operand & src)1498 void Assembler::movzxwl(Register dst, const Operand& src) {
1499   EnsureSpace ensure_space(this);
1500   last_pc_ = pc_;
1501   emit_optional_rex_32(dst, src);
1502   emit(0x0F);
1503   emit(0xB7);
1504   emit_operand(dst, src);
1505 }
1506 
1507 
repmovsb()1508 void Assembler::repmovsb() {
1509   EnsureSpace ensure_space(this);
1510   last_pc_ = pc_;
1511   emit(0xF3);
1512   emit(0xA4);
1513 }
1514 
1515 
repmovsw()1516 void Assembler::repmovsw() {
1517   EnsureSpace ensure_space(this);
1518   last_pc_ = pc_;
1519   emit(0x66);  // Operand size override.
1520   emit(0xF3);
1521   emit(0xA4);
1522 }
1523 
1524 
repmovsl()1525 void Assembler::repmovsl() {
1526   EnsureSpace ensure_space(this);
1527   last_pc_ = pc_;
1528   emit(0xF3);
1529   emit(0xA5);
1530 }
1531 
1532 
repmovsq()1533 void Assembler::repmovsq() {
1534   EnsureSpace ensure_space(this);
1535   last_pc_ = pc_;
1536   emit(0xF3);
1537   emit_rex_64();
1538   emit(0xA5);
1539 }
1540 
1541 
mul(Register src)1542 void Assembler::mul(Register src) {
1543   EnsureSpace ensure_space(this);
1544   last_pc_ = pc_;
1545   emit_rex_64(src);
1546   emit(0xF7);
1547   emit_modrm(0x4, src);
1548 }
1549 
1550 
neg(Register dst)1551 void Assembler::neg(Register dst) {
1552   EnsureSpace ensure_space(this);
1553   last_pc_ = pc_;
1554   emit_rex_64(dst);
1555   emit(0xF7);
1556   emit_modrm(0x3, dst);
1557 }
1558 
1559 
negl(Register dst)1560 void Assembler::negl(Register dst) {
1561   EnsureSpace ensure_space(this);
1562   last_pc_ = pc_;
1563   emit_optional_rex_32(dst);
1564   emit(0xF7);
1565   emit_modrm(0x3, dst);
1566 }
1567 
1568 
neg(const Operand & dst)1569 void Assembler::neg(const Operand& dst) {
1570   EnsureSpace ensure_space(this);
1571   last_pc_ = pc_;
1572   emit_rex_64(dst);
1573   emit(0xF7);
1574   emit_operand(3, dst);
1575 }
1576 
1577 
nop()1578 void Assembler::nop() {
1579   EnsureSpace ensure_space(this);
1580   last_pc_ = pc_;
1581   emit(0x90);
1582 }
1583 
1584 
not_(Register dst)1585 void Assembler::not_(Register dst) {
1586   EnsureSpace ensure_space(this);
1587   last_pc_ = pc_;
1588   emit_rex_64(dst);
1589   emit(0xF7);
1590   emit_modrm(0x2, dst);
1591 }
1592 
1593 
not_(const Operand & dst)1594 void Assembler::not_(const Operand& dst) {
1595   EnsureSpace ensure_space(this);
1596   last_pc_ = pc_;
1597   emit_rex_64(dst);
1598   emit(0xF7);
1599   emit_operand(2, dst);
1600 }
1601 
1602 
nop(int n)1603 void Assembler::nop(int n) {
1604   // The recommended muti-byte sequences of NOP instructions from the Intel 64
1605   // and IA-32 Architectures Software Developer's Manual.
1606   //
1607   // Length   Assembly                                Byte Sequence
1608   // 2 bytes  66 NOP                                  66 90H
1609   // 3 bytes  NOP DWORD ptr [EAX]                     0F 1F 00H
1610   // 4 bytes  NOP DWORD ptr [EAX + 00H]               0F 1F 40 00H
1611   // 5 bytes  NOP DWORD ptr [EAX + EAX*1 + 00H]       0F 1F 44 00 00H
1612   // 6 bytes  66 NOP DWORD ptr [EAX + EAX*1 + 00H]    66 0F 1F 44 00 00H
1613   // 7 bytes  NOP DWORD ptr [EAX + 00000000H]         0F 1F 80 00 00 00 00H
1614   // 8 bytes  NOP DWORD ptr [EAX + EAX*1 + 00000000H] 0F 1F 84 00 00 00 00 00H
1615   // 9 bytes  66 NOP DWORD ptr [EAX + EAX*1 +         66 0F 1F 84 00 00 00 00
1616   //          00000000H]                              00H
1617 
1618   ASSERT(1 <= n);
1619   ASSERT(n <= 9);
1620   EnsureSpace ensure_space(this);
1621   last_pc_ = pc_;
1622   switch (n) {
1623   case 1:
1624     emit(0x90);
1625     return;
1626   case 2:
1627     emit(0x66);
1628     emit(0x90);
1629     return;
1630   case 3:
1631     emit(0x0f);
1632     emit(0x1f);
1633     emit(0x00);
1634     return;
1635   case 4:
1636     emit(0x0f);
1637     emit(0x1f);
1638     emit(0x40);
1639     emit(0x00);
1640     return;
1641   case 5:
1642     emit(0x0f);
1643     emit(0x1f);
1644     emit(0x44);
1645     emit(0x00);
1646     emit(0x00);
1647     return;
1648   case 6:
1649     emit(0x66);
1650     emit(0x0f);
1651     emit(0x1f);
1652     emit(0x44);
1653     emit(0x00);
1654     emit(0x00);
1655     return;
1656   case 7:
1657     emit(0x0f);
1658     emit(0x1f);
1659     emit(0x80);
1660     emit(0x00);
1661     emit(0x00);
1662     emit(0x00);
1663     emit(0x00);
1664     return;
1665   case 8:
1666     emit(0x0f);
1667     emit(0x1f);
1668     emit(0x84);
1669     emit(0x00);
1670     emit(0x00);
1671     emit(0x00);
1672     emit(0x00);
1673     emit(0x00);
1674     return;
1675   case 9:
1676     emit(0x66);
1677     emit(0x0f);
1678     emit(0x1f);
1679     emit(0x84);
1680     emit(0x00);
1681     emit(0x00);
1682     emit(0x00);
1683     emit(0x00);
1684     emit(0x00);
1685     return;
1686   }
1687 }
1688 
1689 
pop(Register dst)1690 void Assembler::pop(Register dst) {
1691   EnsureSpace ensure_space(this);
1692   last_pc_ = pc_;
1693   if (dst.high_bit()) {
1694     emit_rex_64(dst);
1695   }
1696   emit(0x58 | dst.low_bits());
1697 }
1698 
1699 
pop(const Operand & dst)1700 void Assembler::pop(const Operand& dst) {
1701   EnsureSpace ensure_space(this);
1702   last_pc_ = pc_;
1703   emit_rex_64(dst);  // Could be omitted in some cases.
1704   emit(0x8F);
1705   emit_operand(0, dst);
1706 }
1707 
1708 
popfq()1709 void Assembler::popfq() {
1710   EnsureSpace ensure_space(this);
1711   last_pc_ = pc_;
1712   emit(0x9D);
1713 }
1714 
1715 
push(Register src)1716 void Assembler::push(Register src) {
1717   EnsureSpace ensure_space(this);
1718   last_pc_ = pc_;
1719   if (src.high_bit()) {
1720     emit_rex_64(src);
1721   }
1722   emit(0x50 | src.low_bits());
1723 }
1724 
1725 
push(const Operand & src)1726 void Assembler::push(const Operand& src) {
1727   EnsureSpace ensure_space(this);
1728   last_pc_ = pc_;
1729   emit_rex_64(src);  // Could be omitted in some cases.
1730   emit(0xFF);
1731   emit_operand(6, src);
1732 }
1733 
1734 
push(Immediate value)1735 void Assembler::push(Immediate value) {
1736   EnsureSpace ensure_space(this);
1737   last_pc_ = pc_;
1738   if (is_int8(value.value_)) {
1739     emit(0x6A);
1740     emit(value.value_);  // Emit low byte of value.
1741   } else {
1742     emit(0x68);
1743     emitl(value.value_);
1744   }
1745 }
1746 
1747 
pushfq()1748 void Assembler::pushfq() {
1749   EnsureSpace ensure_space(this);
1750   last_pc_ = pc_;
1751   emit(0x9C);
1752 }
1753 
1754 
rdtsc()1755 void Assembler::rdtsc() {
1756   EnsureSpace ensure_space(this);
1757   last_pc_ = pc_;
1758   emit(0x0F);
1759   emit(0x31);
1760 }
1761 
1762 
ret(int imm16)1763 void Assembler::ret(int imm16) {
1764   EnsureSpace ensure_space(this);
1765   last_pc_ = pc_;
1766   ASSERT(is_uint16(imm16));
1767   if (imm16 == 0) {
1768     emit(0xC3);
1769   } else {
1770     emit(0xC2);
1771     emit(imm16 & 0xFF);
1772     emit((imm16 >> 8) & 0xFF);
1773   }
1774 }
1775 
1776 
setcc(Condition cc,Register reg)1777 void Assembler::setcc(Condition cc, Register reg) {
1778   if (cc > last_condition) {
1779     movb(reg, Immediate(cc == always ? 1 : 0));
1780     return;
1781   }
1782   EnsureSpace ensure_space(this);
1783   last_pc_ = pc_;
1784   ASSERT(is_uint4(cc));
1785   if (reg.code() > 3) {  // Use x64 byte registers, where different.
1786     emit_rex_32(reg);
1787   }
1788   emit(0x0F);
1789   emit(0x90 | cc);
1790   emit_modrm(0x0, reg);
1791 }
1792 
1793 
shld(Register dst,Register src)1794 void Assembler::shld(Register dst, Register src) {
1795   EnsureSpace ensure_space(this);
1796   last_pc_ = pc_;
1797   emit_rex_64(src, dst);
1798   emit(0x0F);
1799   emit(0xA5);
1800   emit_modrm(src, dst);
1801 }
1802 
1803 
shrd(Register dst,Register src)1804 void Assembler::shrd(Register dst, Register src) {
1805   EnsureSpace ensure_space(this);
1806   last_pc_ = pc_;
1807   emit_rex_64(src, dst);
1808   emit(0x0F);
1809   emit(0xAD);
1810   emit_modrm(src, dst);
1811 }
1812 
1813 
xchg(Register dst,Register src)1814 void Assembler::xchg(Register dst, Register src) {
1815   EnsureSpace ensure_space(this);
1816   last_pc_ = pc_;
1817   if (src.is(rax) || dst.is(rax)) {  // Single-byte encoding
1818     Register other = src.is(rax) ? dst : src;
1819     emit_rex_64(other);
1820     emit(0x90 | other.low_bits());
1821   } else {
1822     emit_rex_64(src, dst);
1823     emit(0x87);
1824     emit_modrm(src, dst);
1825   }
1826 }
1827 
1828 
store_rax(void * dst,RelocInfo::Mode mode)1829 void Assembler::store_rax(void* dst, RelocInfo::Mode mode) {
1830   EnsureSpace ensure_space(this);
1831   last_pc_ = pc_;
1832   emit(0x48);  // REX.W
1833   emit(0xA3);
1834   emitq(reinterpret_cast<uintptr_t>(dst), mode);
1835 }
1836 
1837 
store_rax(ExternalReference ref)1838 void Assembler::store_rax(ExternalReference ref) {
1839   store_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE);
1840 }
1841 
1842 
testb(Register dst,Register src)1843 void Assembler::testb(Register dst, Register src) {
1844   EnsureSpace ensure_space(this);
1845   last_pc_ = pc_;
1846   if (dst.code() > 3 || src.code() > 3) {
1847     // Register is not one of al, bl, cl, dl.  Its encoding needs REX.
1848     emit_rex_32(dst, src);
1849   }
1850   emit(0x84);
1851   emit_modrm(dst, src);
1852 }
1853 
1854 
testb(Register reg,Immediate mask)1855 void Assembler::testb(Register reg, Immediate mask) {
1856   ASSERT(is_int8(mask.value_) || is_uint8(mask.value_));
1857   EnsureSpace ensure_space(this);
1858   last_pc_ = pc_;
1859   if (reg.is(rax)) {
1860     emit(0xA8);
1861     emit(mask.value_);  // Low byte emitted.
1862   } else {
1863     if (reg.code() > 3) {
1864       // Register is not one of al, bl, cl, dl.  Its encoding needs REX.
1865       emit_rex_32(reg);
1866     }
1867     emit(0xF6);
1868     emit_modrm(0x0, reg);
1869     emit(mask.value_);  // Low byte emitted.
1870   }
1871 }
1872 
1873 
testb(const Operand & op,Immediate mask)1874 void Assembler::testb(const Operand& op, Immediate mask) {
1875   ASSERT(is_int8(mask.value_) || is_uint8(mask.value_));
1876   EnsureSpace ensure_space(this);
1877   last_pc_ = pc_;
1878   emit_optional_rex_32(rax, op);
1879   emit(0xF6);
1880   emit_operand(rax, op);  // Operation code 0
1881   emit(mask.value_);  // Low byte emitted.
1882 }
1883 
1884 
testb(const Operand & op,Register reg)1885 void Assembler::testb(const Operand& op, Register reg) {
1886   EnsureSpace ensure_space(this);
1887   last_pc_ = pc_;
1888   if (reg.code() > 3) {
1889     // Register is not one of al, bl, cl, dl.  Its encoding needs REX.
1890     emit_rex_32(reg, op);
1891   } else {
1892     emit_optional_rex_32(reg, op);
1893   }
1894   emit(0x84);
1895   emit_operand(reg, op);
1896 }
1897 
1898 
testl(Register dst,Register src)1899 void Assembler::testl(Register dst, Register src) {
1900   EnsureSpace ensure_space(this);
1901   last_pc_ = pc_;
1902   emit_optional_rex_32(dst, src);
1903   emit(0x85);
1904   emit_modrm(dst, src);
1905 }
1906 
1907 
testl(Register reg,Immediate mask)1908 void Assembler::testl(Register reg, Immediate mask) {
1909   // testl with a mask that fits in the low byte is exactly testb.
1910   if (is_uint8(mask.value_)) {
1911     testb(reg, mask);
1912     return;
1913   }
1914   EnsureSpace ensure_space(this);
1915   last_pc_ = pc_;
1916   if (reg.is(rax)) {
1917     emit(0xA9);
1918     emit(mask);
1919   } else {
1920     emit_optional_rex_32(rax, reg);
1921     emit(0xF7);
1922     emit_modrm(0x0, reg);
1923     emit(mask);
1924   }
1925 }
1926 
1927 
testl(const Operand & op,Immediate mask)1928 void Assembler::testl(const Operand& op, Immediate mask) {
1929   // testl with a mask that fits in the low byte is exactly testb.
1930   if (is_uint8(mask.value_)) {
1931     testb(op, mask);
1932     return;
1933   }
1934   EnsureSpace ensure_space(this);
1935   last_pc_ = pc_;
1936   emit_optional_rex_32(rax, op);
1937   emit(0xF7);
1938   emit_operand(rax, op);  // Operation code 0
1939   emit(mask);
1940 }
1941 
1942 
testq(const Operand & op,Register reg)1943 void Assembler::testq(const Operand& op, Register reg) {
1944   EnsureSpace ensure_space(this);
1945   last_pc_ = pc_;
1946   emit_rex_64(reg, op);
1947   emit(0x85);
1948   emit_operand(reg, op);
1949 }
1950 
1951 
testq(Register dst,Register src)1952 void Assembler::testq(Register dst, Register src) {
1953   EnsureSpace ensure_space(this);
1954   last_pc_ = pc_;
1955   emit_rex_64(dst, src);
1956   emit(0x85);
1957   emit_modrm(dst, src);
1958 }
1959 
1960 
testq(Register dst,Immediate mask)1961 void Assembler::testq(Register dst, Immediate mask) {
1962   EnsureSpace ensure_space(this);
1963   last_pc_ = pc_;
1964   if (dst.is(rax)) {
1965     emit_rex_64();
1966     emit(0xA9);
1967     emit(mask);
1968   } else {
1969     emit_rex_64(dst);
1970     emit(0xF7);
1971     emit_modrm(0, dst);
1972     emit(mask);
1973   }
1974 }
1975 
1976 
1977 // FPU instructions.
1978 
1979 
fld(int i)1980 void Assembler::fld(int i) {
1981   EnsureSpace ensure_space(this);
1982   last_pc_ = pc_;
1983   emit_farith(0xD9, 0xC0, i);
1984 }
1985 
1986 
fld1()1987 void Assembler::fld1() {
1988   EnsureSpace ensure_space(this);
1989   last_pc_ = pc_;
1990   emit(0xD9);
1991   emit(0xE8);
1992 }
1993 
1994 
fldz()1995 void Assembler::fldz() {
1996   EnsureSpace ensure_space(this);
1997   last_pc_ = pc_;
1998   emit(0xD9);
1999   emit(0xEE);
2000 }
2001 
2002 
fld_s(const Operand & adr)2003 void Assembler::fld_s(const Operand& adr) {
2004   EnsureSpace ensure_space(this);
2005   last_pc_ = pc_;
2006   emit_optional_rex_32(adr);
2007   emit(0xD9);
2008   emit_operand(0, adr);
2009 }
2010 
2011 
fld_d(const Operand & adr)2012 void Assembler::fld_d(const Operand& adr) {
2013   EnsureSpace ensure_space(this);
2014   last_pc_ = pc_;
2015   emit_optional_rex_32(adr);
2016   emit(0xDD);
2017   emit_operand(0, adr);
2018 }
2019 
2020 
fstp_s(const Operand & adr)2021 void Assembler::fstp_s(const Operand& adr) {
2022   EnsureSpace ensure_space(this);
2023   last_pc_ = pc_;
2024   emit_optional_rex_32(adr);
2025   emit(0xD9);
2026   emit_operand(3, adr);
2027 }
2028 
2029 
fstp_d(const Operand & adr)2030 void Assembler::fstp_d(const Operand& adr) {
2031   EnsureSpace ensure_space(this);
2032   last_pc_ = pc_;
2033   emit_optional_rex_32(adr);
2034   emit(0xDD);
2035   emit_operand(3, adr);
2036 }
2037 
2038 
fstp(int index)2039 void Assembler::fstp(int index) {
2040   ASSERT(is_uint3(index));
2041   EnsureSpace ensure_space(this);
2042   last_pc_ = pc_;
2043   emit_farith(0xDD, 0xD8, index);
2044 }
2045 
2046 
fild_s(const Operand & adr)2047 void Assembler::fild_s(const Operand& adr) {
2048   EnsureSpace ensure_space(this);
2049   last_pc_ = pc_;
2050   emit_optional_rex_32(adr);
2051   emit(0xDB);
2052   emit_operand(0, adr);
2053 }
2054 
2055 
fild_d(const Operand & adr)2056 void Assembler::fild_d(const Operand& adr) {
2057   EnsureSpace ensure_space(this);
2058   last_pc_ = pc_;
2059   emit_optional_rex_32(adr);
2060   emit(0xDF);
2061   emit_operand(5, adr);
2062 }
2063 
2064 
fistp_s(const Operand & adr)2065 void Assembler::fistp_s(const Operand& adr) {
2066   EnsureSpace ensure_space(this);
2067   last_pc_ = pc_;
2068   emit_optional_rex_32(adr);
2069   emit(0xDB);
2070   emit_operand(3, adr);
2071 }
2072 
2073 
fisttp_s(const Operand & adr)2074 void Assembler::fisttp_s(const Operand& adr) {
2075   ASSERT(CpuFeatures::IsEnabled(SSE3));
2076   EnsureSpace ensure_space(this);
2077   last_pc_ = pc_;
2078   emit_optional_rex_32(adr);
2079   emit(0xDB);
2080   emit_operand(1, adr);
2081 }
2082 
2083 
fisttp_d(const Operand & adr)2084 void Assembler::fisttp_d(const Operand& adr) {
2085   ASSERT(CpuFeatures::IsEnabled(SSE3));
2086   EnsureSpace ensure_space(this);
2087   last_pc_ = pc_;
2088   emit_optional_rex_32(adr);
2089   emit(0xDD);
2090   emit_operand(1, adr);
2091 }
2092 
2093 
fist_s(const Operand & adr)2094 void Assembler::fist_s(const Operand& adr) {
2095   EnsureSpace ensure_space(this);
2096   last_pc_ = pc_;
2097   emit_optional_rex_32(adr);
2098   emit(0xDB);
2099   emit_operand(2, adr);
2100 }
2101 
2102 
fistp_d(const Operand & adr)2103 void Assembler::fistp_d(const Operand& adr) {
2104   EnsureSpace ensure_space(this);
2105   last_pc_ = pc_;
2106   emit_optional_rex_32(adr);
2107   emit(0xDF);
2108   emit_operand(7, adr);
2109 }
2110 
2111 
fabs()2112 void Assembler::fabs() {
2113   EnsureSpace ensure_space(this);
2114   last_pc_ = pc_;
2115   emit(0xD9);
2116   emit(0xE1);
2117 }
2118 
2119 
fchs()2120 void Assembler::fchs() {
2121   EnsureSpace ensure_space(this);
2122   last_pc_ = pc_;
2123   emit(0xD9);
2124   emit(0xE0);
2125 }
2126 
2127 
fcos()2128 void Assembler::fcos() {
2129   EnsureSpace ensure_space(this);
2130   last_pc_ = pc_;
2131   emit(0xD9);
2132   emit(0xFF);
2133 }
2134 
2135 
fsin()2136 void Assembler::fsin() {
2137   EnsureSpace ensure_space(this);
2138   last_pc_ = pc_;
2139   emit(0xD9);
2140   emit(0xFE);
2141 }
2142 
2143 
fadd(int i)2144 void Assembler::fadd(int i) {
2145   EnsureSpace ensure_space(this);
2146   last_pc_ = pc_;
2147   emit_farith(0xDC, 0xC0, i);
2148 }
2149 
2150 
fsub(int i)2151 void Assembler::fsub(int i) {
2152   EnsureSpace ensure_space(this);
2153   last_pc_ = pc_;
2154   emit_farith(0xDC, 0xE8, i);
2155 }
2156 
2157 
fisub_s(const Operand & adr)2158 void Assembler::fisub_s(const Operand& adr) {
2159   EnsureSpace ensure_space(this);
2160   last_pc_ = pc_;
2161   emit_optional_rex_32(adr);
2162   emit(0xDA);
2163   emit_operand(4, adr);
2164 }
2165 
2166 
fmul(int i)2167 void Assembler::fmul(int i) {
2168   EnsureSpace ensure_space(this);
2169   last_pc_ = pc_;
2170   emit_farith(0xDC, 0xC8, i);
2171 }
2172 
2173 
fdiv(int i)2174 void Assembler::fdiv(int i) {
2175   EnsureSpace ensure_space(this);
2176   last_pc_ = pc_;
2177   emit_farith(0xDC, 0xF8, i);
2178 }
2179 
2180 
faddp(int i)2181 void Assembler::faddp(int i) {
2182   EnsureSpace ensure_space(this);
2183   last_pc_ = pc_;
2184   emit_farith(0xDE, 0xC0, i);
2185 }
2186 
2187 
fsubp(int i)2188 void Assembler::fsubp(int i) {
2189   EnsureSpace ensure_space(this);
2190   last_pc_ = pc_;
2191   emit_farith(0xDE, 0xE8, i);
2192 }
2193 
2194 
fsubrp(int i)2195 void Assembler::fsubrp(int i) {
2196   EnsureSpace ensure_space(this);
2197   last_pc_ = pc_;
2198   emit_farith(0xDE, 0xE0, i);
2199 }
2200 
2201 
fmulp(int i)2202 void Assembler::fmulp(int i) {
2203   EnsureSpace ensure_space(this);
2204   last_pc_ = pc_;
2205   emit_farith(0xDE, 0xC8, i);
2206 }
2207 
2208 
fdivp(int i)2209 void Assembler::fdivp(int i) {
2210   EnsureSpace ensure_space(this);
2211   last_pc_ = pc_;
2212   emit_farith(0xDE, 0xF8, i);
2213 }
2214 
2215 
fprem()2216 void Assembler::fprem() {
2217   EnsureSpace ensure_space(this);
2218   last_pc_ = pc_;
2219   emit(0xD9);
2220   emit(0xF8);
2221 }
2222 
2223 
fprem1()2224 void Assembler::fprem1() {
2225   EnsureSpace ensure_space(this);
2226   last_pc_ = pc_;
2227   emit(0xD9);
2228   emit(0xF5);
2229 }
2230 
2231 
fxch(int i)2232 void Assembler::fxch(int i) {
2233   EnsureSpace ensure_space(this);
2234   last_pc_ = pc_;
2235   emit_farith(0xD9, 0xC8, i);
2236 }
2237 
2238 
fincstp()2239 void Assembler::fincstp() {
2240   EnsureSpace ensure_space(this);
2241   last_pc_ = pc_;
2242   emit(0xD9);
2243   emit(0xF7);
2244 }
2245 
2246 
ffree(int i)2247 void Assembler::ffree(int i) {
2248   EnsureSpace ensure_space(this);
2249   last_pc_ = pc_;
2250   emit_farith(0xDD, 0xC0, i);
2251 }
2252 
2253 
ftst()2254 void Assembler::ftst() {
2255   EnsureSpace ensure_space(this);
2256   last_pc_ = pc_;
2257   emit(0xD9);
2258   emit(0xE4);
2259 }
2260 
2261 
fucomp(int i)2262 void Assembler::fucomp(int i) {
2263   EnsureSpace ensure_space(this);
2264   last_pc_ = pc_;
2265   emit_farith(0xDD, 0xE8, i);
2266 }
2267 
2268 
fucompp()2269 void Assembler::fucompp() {
2270   EnsureSpace ensure_space(this);
2271   last_pc_ = pc_;
2272   emit(0xDA);
2273   emit(0xE9);
2274 }
2275 
2276 
fucomi(int i)2277 void Assembler::fucomi(int i) {
2278   EnsureSpace ensure_space(this);
2279   last_pc_ = pc_;
2280   emit(0xDB);
2281   emit(0xE8 + i);
2282 }
2283 
2284 
fucomip()2285 void Assembler::fucomip() {
2286   EnsureSpace ensure_space(this);
2287   last_pc_ = pc_;
2288   emit(0xDF);
2289   emit(0xE9);
2290 }
2291 
2292 
fcompp()2293 void Assembler::fcompp() {
2294   EnsureSpace ensure_space(this);
2295   last_pc_ = pc_;
2296   emit(0xDE);
2297   emit(0xD9);
2298 }
2299 
2300 
fnstsw_ax()2301 void Assembler::fnstsw_ax() {
2302   EnsureSpace ensure_space(this);
2303   last_pc_ = pc_;
2304   emit(0xDF);
2305   emit(0xE0);
2306 }
2307 
2308 
fwait()2309 void Assembler::fwait() {
2310   EnsureSpace ensure_space(this);
2311   last_pc_ = pc_;
2312   emit(0x9B);
2313 }
2314 
2315 
frndint()2316 void Assembler::frndint() {
2317   EnsureSpace ensure_space(this);
2318   last_pc_ = pc_;
2319   emit(0xD9);
2320   emit(0xFC);
2321 }
2322 
2323 
fnclex()2324 void Assembler::fnclex() {
2325   EnsureSpace ensure_space(this);
2326   last_pc_ = pc_;
2327   emit(0xDB);
2328   emit(0xE2);
2329 }
2330 
2331 
sahf()2332 void Assembler::sahf() {
2333   // TODO(X64): Test for presence. Not all 64-bit intel CPU's have sahf
2334   // in 64-bit mode. Test CpuID.
2335   EnsureSpace ensure_space(this);
2336   last_pc_ = pc_;
2337   emit(0x9E);
2338 }
2339 
2340 
emit_farith(int b1,int b2,int i)2341 void Assembler::emit_farith(int b1, int b2, int i) {
2342   ASSERT(is_uint8(b1) && is_uint8(b2));  // wrong opcode
2343   ASSERT(is_uint3(i));  // illegal stack offset
2344   emit(b1);
2345   emit(b2 + i);
2346 }
2347 
2348 // SSE 2 operations.
2349 
movsd(const Operand & dst,XMMRegister src)2350 void Assembler::movsd(const Operand& dst, XMMRegister src) {
2351   EnsureSpace ensure_space(this);
2352   last_pc_ = pc_;
2353   emit(0xF2);  // double
2354   emit_optional_rex_32(src, dst);
2355   emit(0x0F);
2356   emit(0x11);  // store
2357   emit_sse_operand(src, dst);
2358 }
2359 
2360 
movsd(XMMRegister dst,XMMRegister src)2361 void Assembler::movsd(XMMRegister dst, XMMRegister src) {
2362   EnsureSpace ensure_space(this);
2363   last_pc_ = pc_;
2364   emit(0xF2);  // double
2365   emit_optional_rex_32(dst, src);
2366   emit(0x0F);
2367   emit(0x10);  // load
2368   emit_sse_operand(dst, src);
2369 }
2370 
2371 
movsd(XMMRegister dst,const Operand & src)2372 void Assembler::movsd(XMMRegister dst, const Operand& src) {
2373   EnsureSpace ensure_space(this);
2374   last_pc_ = pc_;
2375   emit(0xF2);  // double
2376   emit_optional_rex_32(dst, src);
2377   emit(0x0F);
2378   emit(0x10);  // load
2379   emit_sse_operand(dst, src);
2380 }
2381 
2382 
cvttss2si(Register dst,const Operand & src)2383 void Assembler::cvttss2si(Register dst, const Operand& src) {
2384   EnsureSpace ensure_space(this);
2385   last_pc_ = pc_;
2386   emit(0xF3);
2387   emit_optional_rex_32(dst, src);
2388   emit(0x0F);
2389   emit(0x2C);
2390   emit_operand(dst, src);
2391 }
2392 
2393 
cvttsd2si(Register dst,const Operand & src)2394 void Assembler::cvttsd2si(Register dst, const Operand& src) {
2395   EnsureSpace ensure_space(this);
2396   last_pc_ = pc_;
2397   emit(0xF2);
2398   emit_optional_rex_32(dst, src);
2399   emit(0x0F);
2400   emit(0x2C);
2401   emit_operand(dst, src);
2402 }
2403 
2404 
cvtlsi2sd(XMMRegister dst,const Operand & src)2405 void Assembler::cvtlsi2sd(XMMRegister dst, const Operand& src) {
2406   EnsureSpace ensure_space(this);
2407   last_pc_ = pc_;
2408   emit(0xF2);
2409   emit_optional_rex_32(dst, src);
2410   emit(0x0F);
2411   emit(0x2A);
2412   emit_sse_operand(dst, src);
2413 }
2414 
2415 
cvtlsi2sd(XMMRegister dst,Register src)2416 void Assembler::cvtlsi2sd(XMMRegister dst, Register src) {
2417   EnsureSpace ensure_space(this);
2418   last_pc_ = pc_;
2419   emit(0xF2);
2420   emit_optional_rex_32(dst, src);
2421   emit(0x0F);
2422   emit(0x2A);
2423   emit_sse_operand(dst, src);
2424 }
2425 
2426 
cvtqsi2sd(XMMRegister dst,Register src)2427 void Assembler::cvtqsi2sd(XMMRegister dst, Register src) {
2428   EnsureSpace ensure_space(this);
2429   last_pc_ = pc_;
2430   emit(0xF2);
2431   emit_rex_64(dst, src);
2432   emit(0x0F);
2433   emit(0x2A);
2434   emit_sse_operand(dst, src);
2435 }
2436 
2437 
addsd(XMMRegister dst,XMMRegister src)2438 void Assembler::addsd(XMMRegister dst, XMMRegister src) {
2439   EnsureSpace ensure_space(this);
2440   last_pc_ = pc_;
2441   emit(0xF2);
2442   emit_optional_rex_32(dst, src);
2443   emit(0x0F);
2444   emit(0x58);
2445   emit_sse_operand(dst, src);
2446 }
2447 
2448 
mulsd(XMMRegister dst,XMMRegister src)2449 void Assembler::mulsd(XMMRegister dst, XMMRegister src) {
2450   EnsureSpace ensure_space(this);
2451   last_pc_ = pc_;
2452   emit(0xF2);
2453   emit_optional_rex_32(dst, src);
2454   emit(0x0F);
2455   emit(0x59);
2456   emit_sse_operand(dst, src);
2457 }
2458 
2459 
subsd(XMMRegister dst,XMMRegister src)2460 void Assembler::subsd(XMMRegister dst, XMMRegister src) {
2461   EnsureSpace ensure_space(this);
2462   last_pc_ = pc_;
2463   emit(0xF2);
2464   emit_optional_rex_32(dst, src);
2465   emit(0x0F);
2466   emit(0x5C);
2467   emit_sse_operand(dst, src);
2468 }
2469 
2470 
divsd(XMMRegister dst,XMMRegister src)2471 void Assembler::divsd(XMMRegister dst, XMMRegister src) {
2472   EnsureSpace ensure_space(this);
2473   last_pc_ = pc_;
2474   emit(0xF2);
2475   emit_optional_rex_32(dst, src);
2476   emit(0x0F);
2477   emit(0x5E);
2478   emit_sse_operand(dst, src);
2479 }
2480 
2481 
xorpd(XMMRegister dst,XMMRegister src)2482 void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
2483   EnsureSpace ensure_space(this);
2484   last_pc_ = pc_;
2485   emit(0x66);
2486   emit_optional_rex_32(dst, src);
2487   emit(0x0f);
2488   emit(0x57);
2489   emit_sse_operand(dst, src);
2490 }
2491 
2492 
comisd(XMMRegister dst,XMMRegister src)2493 void Assembler::comisd(XMMRegister dst, XMMRegister src) {
2494   EnsureSpace ensure_space(this);
2495   last_pc_ = pc_;
2496   emit(0x66);
2497   emit_optional_rex_32(dst, src);
2498   emit(0x0f);
2499   emit(0x2f);
2500   emit_sse_operand(dst, src);
2501 }
2502 
2503 
ucomisd(XMMRegister dst,XMMRegister src)2504 void Assembler::ucomisd(XMMRegister dst, XMMRegister src) {
2505   EnsureSpace ensure_space(this);
2506   last_pc_ = pc_;
2507   emit(0x66);
2508   emit_optional_rex_32(dst, src);
2509   emit(0x0f);
2510   emit(0x2e);
2511   emit_sse_operand(dst, src);
2512 }
2513 
2514 
emit_sse_operand(XMMRegister reg,const Operand & adr)2515 void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) {
2516   Register ireg = { reg.code() };
2517   emit_operand(ireg, adr);
2518 }
2519 
2520 
emit_sse_operand(XMMRegister dst,XMMRegister src)2521 void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) {
2522   emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
2523 }
2524 
emit_sse_operand(XMMRegister dst,Register src)2525 void Assembler::emit_sse_operand(XMMRegister dst, Register src) {
2526   emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
2527 }
2528 
2529 
2530 // Relocation information implementations.
2531 
RecordRelocInfo(RelocInfo::Mode rmode,intptr_t data)2532 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
2533   ASSERT(rmode != RelocInfo::NONE);
2534   // Don't record external references unless the heap will be serialized.
2535   if (rmode == RelocInfo::EXTERNAL_REFERENCE &&
2536       !Serializer::enabled() &&
2537       !FLAG_debug_code) {
2538     return;
2539   }
2540   RelocInfo rinfo(pc_, rmode, data);
2541   reloc_info_writer.Write(&rinfo);
2542 }
2543 
RecordJSReturn()2544 void Assembler::RecordJSReturn() {
2545   WriteRecordedPositions();
2546   EnsureSpace ensure_space(this);
2547   RecordRelocInfo(RelocInfo::JS_RETURN);
2548 }
2549 
2550 
RecordComment(const char * msg)2551 void Assembler::RecordComment(const char* msg) {
2552   if (FLAG_debug_code) {
2553     EnsureSpace ensure_space(this);
2554     RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg));
2555   }
2556 }
2557 
2558 
RecordPosition(int pos)2559 void Assembler::RecordPosition(int pos) {
2560   ASSERT(pos != RelocInfo::kNoPosition);
2561   ASSERT(pos >= 0);
2562   current_position_ = pos;
2563 }
2564 
2565 
RecordStatementPosition(int pos)2566 void Assembler::RecordStatementPosition(int pos) {
2567   ASSERT(pos != RelocInfo::kNoPosition);
2568   ASSERT(pos >= 0);
2569   current_statement_position_ = pos;
2570 }
2571 
2572 
WriteRecordedPositions()2573 void Assembler::WriteRecordedPositions() {
2574   // Write the statement position if it is different from what was written last
2575   // time.
2576   if (current_statement_position_ != written_statement_position_) {
2577     EnsureSpace ensure_space(this);
2578     RecordRelocInfo(RelocInfo::STATEMENT_POSITION, current_statement_position_);
2579     written_statement_position_ = current_statement_position_;
2580   }
2581 
2582   // Write the position if it is different from what was written last time and
2583   // also different from the written statement position.
2584   if (current_position_ != written_position_ &&
2585       current_position_ != written_statement_position_) {
2586     EnsureSpace ensure_space(this);
2587     RecordRelocInfo(RelocInfo::POSITION, current_position_);
2588     written_position_ = current_position_;
2589   }
2590 }
2591 
2592 
2593 const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask |
2594                                   1 << RelocInfo::INTERNAL_REFERENCE |
2595                                   1 << RelocInfo::JS_RETURN;
2596 
2597 } }  // namespace v8::internal
2598