1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/v8.h"
6
7 #if V8_TARGET_ARCH_X64
8
9 #include "src/base/bits.h"
10 #include "src/macro-assembler.h"
11 #include "src/serialize.h"
12
13 namespace v8 {
14 namespace internal {
15
16 // -----------------------------------------------------------------------------
17 // Implementation of CpuFeatures
18
ProbeImpl(bool cross_compile)19 void CpuFeatures::ProbeImpl(bool cross_compile) {
20 base::CPU cpu;
21 CHECK(cpu.has_sse2()); // SSE2 support is mandatory.
22 CHECK(cpu.has_cmov()); // CMOV support is mandatory.
23
24 // Only use statically determined features for cross compile (snapshot).
25 if (cross_compile) return;
26
27 if (cpu.has_sse41() && FLAG_enable_sse4_1) supported_ |= 1u << SSE4_1;
28 if (cpu.has_sse3() && FLAG_enable_sse3) supported_ |= 1u << SSE3;
29 // SAHF is not generally available in long mode.
30 if (cpu.has_sahf() && FLAG_enable_sahf) supported_|= 1u << SAHF;
31 }
32
33
PrintTarget()34 void CpuFeatures::PrintTarget() { }
PrintFeatures()35 void CpuFeatures::PrintFeatures() { }
36
37
38 // -----------------------------------------------------------------------------
39 // Implementation of RelocInfo
40
41 // Patch the code at the current PC with a call to the target address.
42 // Additional guard int3 instructions can be added if required.
PatchCodeWithCall(Address target,int guard_bytes)43 void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) {
44 int code_size = Assembler::kCallSequenceLength + guard_bytes;
45
46 // Create a code patcher.
47 CodePatcher patcher(pc_, code_size);
48
49 // Add a label for checking the size of the code used for returning.
50 #ifdef DEBUG
51 Label check_codesize;
52 patcher.masm()->bind(&check_codesize);
53 #endif
54
55 // Patch the code.
56 patcher.masm()->movp(kScratchRegister, reinterpret_cast<void*>(target),
57 Assembler::RelocInfoNone());
58 patcher.masm()->call(kScratchRegister);
59
60 // Check that the size of the code generated is as expected.
61 DCHECK_EQ(Assembler::kCallSequenceLength,
62 patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize));
63
64 // Add the requested number of int3 instructions after the call.
65 for (int i = 0; i < guard_bytes; i++) {
66 patcher.masm()->int3();
67 }
68 }
69
70
PatchCode(byte * instructions,int instruction_count)71 void RelocInfo::PatchCode(byte* instructions, int instruction_count) {
72 // Patch the code at the current address with the supplied instructions.
73 for (int i = 0; i < instruction_count; i++) {
74 *(pc_ + i) = *(instructions + i);
75 }
76
77 // Indicate that code has changed.
78 CpuFeatures::FlushICache(pc_, instruction_count);
79 }
80
81
82 // -----------------------------------------------------------------------------
83 // Register constants.
84
85 const int
86 Register::kRegisterCodeByAllocationIndex[kMaxNumAllocatableRegisters] = {
87 // rax, rbx, rdx, rcx, rsi, rdi, r8, r9, r11, r14, r15
88 0, 3, 2, 1, 6, 7, 8, 9, 11, 14, 15
89 };
90
91 const int Register::kAllocationIndexByRegisterCode[kNumRegisters] = {
92 0, 3, 2, 1, -1, -1, 4, 5, 6, 7, -1, 8, -1, -1, 9, 10
93 };
94
95
96 // -----------------------------------------------------------------------------
97 // Implementation of Operand
98
Operand(Register base,int32_t disp)99 Operand::Operand(Register base, int32_t disp) : rex_(0) {
100 len_ = 1;
101 if (base.is(rsp) || base.is(r12)) {
102 // SIB byte is needed to encode (rsp + offset) or (r12 + offset).
103 set_sib(times_1, rsp, base);
104 }
105
106 if (disp == 0 && !base.is(rbp) && !base.is(r13)) {
107 set_modrm(0, base);
108 } else if (is_int8(disp)) {
109 set_modrm(1, base);
110 set_disp8(disp);
111 } else {
112 set_modrm(2, base);
113 set_disp32(disp);
114 }
115 }
116
117
Operand(Register base,Register index,ScaleFactor scale,int32_t disp)118 Operand::Operand(Register base,
119 Register index,
120 ScaleFactor scale,
121 int32_t disp) : rex_(0) {
122 DCHECK(!index.is(rsp));
123 len_ = 1;
124 set_sib(scale, index, base);
125 if (disp == 0 && !base.is(rbp) && !base.is(r13)) {
126 // This call to set_modrm doesn't overwrite the REX.B (or REX.X) bits
127 // possibly set by set_sib.
128 set_modrm(0, rsp);
129 } else if (is_int8(disp)) {
130 set_modrm(1, rsp);
131 set_disp8(disp);
132 } else {
133 set_modrm(2, rsp);
134 set_disp32(disp);
135 }
136 }
137
138
Operand(Register index,ScaleFactor scale,int32_t disp)139 Operand::Operand(Register index,
140 ScaleFactor scale,
141 int32_t disp) : rex_(0) {
142 DCHECK(!index.is(rsp));
143 len_ = 1;
144 set_modrm(0, rsp);
145 set_sib(scale, index, rbp);
146 set_disp32(disp);
147 }
148
149
Operand(const Operand & operand,int32_t offset)150 Operand::Operand(const Operand& operand, int32_t offset) {
151 DCHECK(operand.len_ >= 1);
152 // Operand encodes REX ModR/M [SIB] [Disp].
153 byte modrm = operand.buf_[0];
154 DCHECK(modrm < 0xC0); // Disallow mode 3 (register target).
155 bool has_sib = ((modrm & 0x07) == 0x04);
156 byte mode = modrm & 0xC0;
157 int disp_offset = has_sib ? 2 : 1;
158 int base_reg = (has_sib ? operand.buf_[1] : modrm) & 0x07;
159 // Mode 0 with rbp/r13 as ModR/M or SIB base register always has a 32-bit
160 // displacement.
161 bool is_baseless = (mode == 0) && (base_reg == 0x05); // No base or RIP base.
162 int32_t disp_value = 0;
163 if (mode == 0x80 || is_baseless) {
164 // Mode 2 or mode 0 with rbp/r13 as base: Word displacement.
165 disp_value = *bit_cast<const int32_t*>(&operand.buf_[disp_offset]);
166 } else if (mode == 0x40) {
167 // Mode 1: Byte displacement.
168 disp_value = static_cast<signed char>(operand.buf_[disp_offset]);
169 }
170
171 // Write new operand with same registers, but with modified displacement.
172 DCHECK(offset >= 0 ? disp_value + offset > disp_value
173 : disp_value + offset < disp_value); // No overflow.
174 disp_value += offset;
175 rex_ = operand.rex_;
176 if (!is_int8(disp_value) || is_baseless) {
177 // Need 32 bits of displacement, mode 2 or mode 1 with register rbp/r13.
178 buf_[0] = (modrm & 0x3f) | (is_baseless ? 0x00 : 0x80);
179 len_ = disp_offset + 4;
180 Memory::int32_at(&buf_[disp_offset]) = disp_value;
181 } else if (disp_value != 0 || (base_reg == 0x05)) {
182 // Need 8 bits of displacement.
183 buf_[0] = (modrm & 0x3f) | 0x40; // Mode 1.
184 len_ = disp_offset + 1;
185 buf_[disp_offset] = static_cast<byte>(disp_value);
186 } else {
187 // Need no displacement.
188 buf_[0] = (modrm & 0x3f); // Mode 0.
189 len_ = disp_offset;
190 }
191 if (has_sib) {
192 buf_[1] = operand.buf_[1];
193 }
194 }
195
196
AddressUsesRegister(Register reg) const197 bool Operand::AddressUsesRegister(Register reg) const {
198 int code = reg.code();
199 DCHECK((buf_[0] & 0xC0) != 0xC0); // Always a memory operand.
200 // Start with only low three bits of base register. Initial decoding doesn't
201 // distinguish on the REX.B bit.
202 int base_code = buf_[0] & 0x07;
203 if (base_code == rsp.code()) {
204 // SIB byte present in buf_[1].
205 // Check the index register from the SIB byte + REX.X prefix.
206 int index_code = ((buf_[1] >> 3) & 0x07) | ((rex_ & 0x02) << 2);
207 // Index code (including REX.X) of 0x04 (rsp) means no index register.
208 if (index_code != rsp.code() && index_code == code) return true;
209 // Add REX.B to get the full base register code.
210 base_code = (buf_[1] & 0x07) | ((rex_ & 0x01) << 3);
211 // A base register of 0x05 (rbp) with mod = 0 means no base register.
212 if (base_code == rbp.code() && ((buf_[0] & 0xC0) == 0)) return false;
213 return code == base_code;
214 } else {
215 // A base register with low bits of 0x05 (rbp or r13) and mod = 0 means
216 // no base register.
217 if (base_code == rbp.code() && ((buf_[0] & 0xC0) == 0)) return false;
218 base_code |= ((rex_ & 0x01) << 3);
219 return code == base_code;
220 }
221 }
222
223
224 // -----------------------------------------------------------------------------
225 // Implementation of Assembler.
226
227 #ifdef GENERATED_CODE_COVERAGE
228 static void InitCoverageLog();
229 #endif
230
Assembler(Isolate * isolate,void * buffer,int buffer_size)231 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
232 : AssemblerBase(isolate, buffer, buffer_size),
233 code_targets_(100),
234 positions_recorder_(this) {
235 // Clear the buffer in debug mode unless it was provided by the
236 // caller in which case we can't be sure it's okay to overwrite
237 // existing code in it.
238 #ifdef DEBUG
239 if (own_buffer_) {
240 memset(buffer_, 0xCC, buffer_size_); // int3
241 }
242 #endif
243
244 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
245
246
247 #ifdef GENERATED_CODE_COVERAGE
248 InitCoverageLog();
249 #endif
250 }
251
252
GetCode(CodeDesc * desc)253 void Assembler::GetCode(CodeDesc* desc) {
254 // Finalize code (at this point overflow() may be true, but the gap ensures
255 // that we are still not overlapping instructions and relocation info).
256 DCHECK(pc_ <= reloc_info_writer.pos()); // No overlap.
257 // Set up code descriptor.
258 desc->buffer = buffer_;
259 desc->buffer_size = buffer_size_;
260 desc->instr_size = pc_offset();
261 DCHECK(desc->instr_size > 0); // Zero-size code objects upset the system.
262 desc->reloc_size =
263 static_cast<int>((buffer_ + buffer_size_) - reloc_info_writer.pos());
264 desc->origin = this;
265 }
266
267
Align(int m)268 void Assembler::Align(int m) {
269 DCHECK(base::bits::IsPowerOfTwo32(m));
270 int delta = (m - (pc_offset() & (m - 1))) & (m - 1);
271 Nop(delta);
272 }
273
274
CodeTargetAlign()275 void Assembler::CodeTargetAlign() {
276 Align(16); // Preferred alignment of jump targets on x64.
277 }
278
279
IsNop(Address addr)280 bool Assembler::IsNop(Address addr) {
281 Address a = addr;
282 while (*a == 0x66) a++;
283 if (*a == 0x90) return true;
284 if (a[0] == 0xf && a[1] == 0x1f) return true;
285 return false;
286 }
287
288
bind_to(Label * L,int pos)289 void Assembler::bind_to(Label* L, int pos) {
290 DCHECK(!L->is_bound()); // Label may only be bound once.
291 DCHECK(0 <= pos && pos <= pc_offset()); // Position must be valid.
292 if (L->is_linked()) {
293 int current = L->pos();
294 int next = long_at(current);
295 while (next != current) {
296 // Relative address, relative to point after address.
297 int imm32 = pos - (current + sizeof(int32_t));
298 long_at_put(current, imm32);
299 current = next;
300 next = long_at(next);
301 }
302 // Fix up last fixup on linked list.
303 int last_imm32 = pos - (current + sizeof(int32_t));
304 long_at_put(current, last_imm32);
305 }
306 while (L->is_near_linked()) {
307 int fixup_pos = L->near_link_pos();
308 int offset_to_next =
309 static_cast<int>(*reinterpret_cast<int8_t*>(addr_at(fixup_pos)));
310 DCHECK(offset_to_next <= 0);
311 int disp = pos - (fixup_pos + sizeof(int8_t));
312 CHECK(is_int8(disp));
313 set_byte_at(fixup_pos, disp);
314 if (offset_to_next < 0) {
315 L->link_to(fixup_pos + offset_to_next, Label::kNear);
316 } else {
317 L->UnuseNear();
318 }
319 }
320 L->bind_to(pos);
321 }
322
323
bind(Label * L)324 void Assembler::bind(Label* L) {
325 bind_to(L, pc_offset());
326 }
327
328
GrowBuffer()329 void Assembler::GrowBuffer() {
330 DCHECK(buffer_overflow());
331 if (!own_buffer_) FATAL("external code buffer is too small");
332
333 // Compute new buffer size.
334 CodeDesc desc; // the new buffer
335 desc.buffer_size = 2 * buffer_size_;
336
337 // Some internal data structures overflow for very large buffers,
338 // they must ensure that kMaximalBufferSize is not too large.
339 if ((desc.buffer_size > kMaximalBufferSize) ||
340 (desc.buffer_size > isolate()->heap()->MaxOldGenerationSize())) {
341 V8::FatalProcessOutOfMemory("Assembler::GrowBuffer");
342 }
343
344 // Set up new buffer.
345 desc.buffer = NewArray<byte>(desc.buffer_size);
346 desc.instr_size = pc_offset();
347 desc.reloc_size =
348 static_cast<int>((buffer_ + buffer_size_) - (reloc_info_writer.pos()));
349
350 // Clear the buffer in debug mode. Use 'int3' instructions to make
351 // sure to get into problems if we ever run uninitialized code.
352 #ifdef DEBUG
353 memset(desc.buffer, 0xCC, desc.buffer_size);
354 #endif
355
356 // Copy the data.
357 intptr_t pc_delta = desc.buffer - buffer_;
358 intptr_t rc_delta = (desc.buffer + desc.buffer_size) -
359 (buffer_ + buffer_size_);
360 MemMove(desc.buffer, buffer_, desc.instr_size);
361 MemMove(rc_delta + reloc_info_writer.pos(), reloc_info_writer.pos(),
362 desc.reloc_size);
363
364 // Switch buffers.
365 DeleteArray(buffer_);
366 buffer_ = desc.buffer;
367 buffer_size_ = desc.buffer_size;
368 pc_ += pc_delta;
369 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
370 reloc_info_writer.last_pc() + pc_delta);
371
372 // Relocate runtime entries.
373 for (RelocIterator it(desc); !it.done(); it.next()) {
374 RelocInfo::Mode rmode = it.rinfo()->rmode();
375 if (rmode == RelocInfo::INTERNAL_REFERENCE) {
376 intptr_t* p = reinterpret_cast<intptr_t*>(it.rinfo()->pc());
377 if (*p != 0) { // 0 means uninitialized.
378 *p += pc_delta;
379 }
380 }
381 }
382
383 DCHECK(!buffer_overflow());
384 }
385
386
emit_operand(int code,const Operand & adr)387 void Assembler::emit_operand(int code, const Operand& adr) {
388 DCHECK(is_uint3(code));
389 const unsigned length = adr.len_;
390 DCHECK(length > 0);
391
392 // Emit updated ModR/M byte containing the given register.
393 DCHECK((adr.buf_[0] & 0x38) == 0);
394 pc_[0] = adr.buf_[0] | code << 3;
395
396 // Emit the rest of the encoded operand.
397 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i];
398 pc_ += length;
399 }
400
401
402 // Assembler Instruction implementations.
403
arithmetic_op(byte opcode,Register reg,const Operand & op,int size)404 void Assembler::arithmetic_op(byte opcode,
405 Register reg,
406 const Operand& op,
407 int size) {
408 EnsureSpace ensure_space(this);
409 emit_rex(reg, op, size);
410 emit(opcode);
411 emit_operand(reg, op);
412 }
413
414
arithmetic_op(byte opcode,Register reg,Register rm_reg,int size)415 void Assembler::arithmetic_op(byte opcode,
416 Register reg,
417 Register rm_reg,
418 int size) {
419 EnsureSpace ensure_space(this);
420 DCHECK((opcode & 0xC6) == 2);
421 if (rm_reg.low_bits() == 4) { // Forces SIB byte.
422 // Swap reg and rm_reg and change opcode operand order.
423 emit_rex(rm_reg, reg, size);
424 emit(opcode ^ 0x02);
425 emit_modrm(rm_reg, reg);
426 } else {
427 emit_rex(reg, rm_reg, size);
428 emit(opcode);
429 emit_modrm(reg, rm_reg);
430 }
431 }
432
433
arithmetic_op_16(byte opcode,Register reg,Register rm_reg)434 void Assembler::arithmetic_op_16(byte opcode, Register reg, Register rm_reg) {
435 EnsureSpace ensure_space(this);
436 DCHECK((opcode & 0xC6) == 2);
437 if (rm_reg.low_bits() == 4) { // Forces SIB byte.
438 // Swap reg and rm_reg and change opcode operand order.
439 emit(0x66);
440 emit_optional_rex_32(rm_reg, reg);
441 emit(opcode ^ 0x02);
442 emit_modrm(rm_reg, reg);
443 } else {
444 emit(0x66);
445 emit_optional_rex_32(reg, rm_reg);
446 emit(opcode);
447 emit_modrm(reg, rm_reg);
448 }
449 }
450
451
arithmetic_op_16(byte opcode,Register reg,const Operand & rm_reg)452 void Assembler::arithmetic_op_16(byte opcode,
453 Register reg,
454 const Operand& rm_reg) {
455 EnsureSpace ensure_space(this);
456 emit(0x66);
457 emit_optional_rex_32(reg, rm_reg);
458 emit(opcode);
459 emit_operand(reg, rm_reg);
460 }
461
462
arithmetic_op_8(byte opcode,Register reg,const Operand & op)463 void Assembler::arithmetic_op_8(byte opcode, Register reg, const Operand& op) {
464 EnsureSpace ensure_space(this);
465 if (!reg.is_byte_register()) {
466 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
467 emit_rex_32(reg);
468 }
469 emit(opcode);
470 emit_operand(reg, op);
471 }
472
473
arithmetic_op_8(byte opcode,Register reg,Register rm_reg)474 void Assembler::arithmetic_op_8(byte opcode, Register reg, Register rm_reg) {
475 EnsureSpace ensure_space(this);
476 DCHECK((opcode & 0xC6) == 2);
477 if (rm_reg.low_bits() == 4) { // Forces SIB byte.
478 // Swap reg and rm_reg and change opcode operand order.
479 if (!rm_reg.is_byte_register() || !reg.is_byte_register()) {
480 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
481 emit_rex_32(rm_reg, reg);
482 }
483 emit(opcode ^ 0x02);
484 emit_modrm(rm_reg, reg);
485 } else {
486 if (!reg.is_byte_register() || !rm_reg.is_byte_register()) {
487 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
488 emit_rex_32(reg, rm_reg);
489 }
490 emit(opcode);
491 emit_modrm(reg, rm_reg);
492 }
493 }
494
495
immediate_arithmetic_op(byte subcode,Register dst,Immediate src,int size)496 void Assembler::immediate_arithmetic_op(byte subcode,
497 Register dst,
498 Immediate src,
499 int size) {
500 EnsureSpace ensure_space(this);
501 emit_rex(dst, size);
502 if (is_int8(src.value_)) {
503 emit(0x83);
504 emit_modrm(subcode, dst);
505 emit(src.value_);
506 } else if (dst.is(rax)) {
507 emit(0x05 | (subcode << 3));
508 emitl(src.value_);
509 } else {
510 emit(0x81);
511 emit_modrm(subcode, dst);
512 emitl(src.value_);
513 }
514 }
515
immediate_arithmetic_op(byte subcode,const Operand & dst,Immediate src,int size)516 void Assembler::immediate_arithmetic_op(byte subcode,
517 const Operand& dst,
518 Immediate src,
519 int size) {
520 EnsureSpace ensure_space(this);
521 emit_rex(dst, size);
522 if (is_int8(src.value_)) {
523 emit(0x83);
524 emit_operand(subcode, dst);
525 emit(src.value_);
526 } else {
527 emit(0x81);
528 emit_operand(subcode, dst);
529 emitl(src.value_);
530 }
531 }
532
533
immediate_arithmetic_op_16(byte subcode,Register dst,Immediate src)534 void Assembler::immediate_arithmetic_op_16(byte subcode,
535 Register dst,
536 Immediate src) {
537 EnsureSpace ensure_space(this);
538 emit(0x66); // Operand size override prefix.
539 emit_optional_rex_32(dst);
540 if (is_int8(src.value_)) {
541 emit(0x83);
542 emit_modrm(subcode, dst);
543 emit(src.value_);
544 } else if (dst.is(rax)) {
545 emit(0x05 | (subcode << 3));
546 emitw(src.value_);
547 } else {
548 emit(0x81);
549 emit_modrm(subcode, dst);
550 emitw(src.value_);
551 }
552 }
553
554
immediate_arithmetic_op_16(byte subcode,const Operand & dst,Immediate src)555 void Assembler::immediate_arithmetic_op_16(byte subcode,
556 const Operand& dst,
557 Immediate src) {
558 EnsureSpace ensure_space(this);
559 emit(0x66); // Operand size override prefix.
560 emit_optional_rex_32(dst);
561 if (is_int8(src.value_)) {
562 emit(0x83);
563 emit_operand(subcode, dst);
564 emit(src.value_);
565 } else {
566 emit(0x81);
567 emit_operand(subcode, dst);
568 emitw(src.value_);
569 }
570 }
571
572
immediate_arithmetic_op_8(byte subcode,const Operand & dst,Immediate src)573 void Assembler::immediate_arithmetic_op_8(byte subcode,
574 const Operand& dst,
575 Immediate src) {
576 EnsureSpace ensure_space(this);
577 emit_optional_rex_32(dst);
578 DCHECK(is_int8(src.value_) || is_uint8(src.value_));
579 emit(0x80);
580 emit_operand(subcode, dst);
581 emit(src.value_);
582 }
583
584
immediate_arithmetic_op_8(byte subcode,Register dst,Immediate src)585 void Assembler::immediate_arithmetic_op_8(byte subcode,
586 Register dst,
587 Immediate src) {
588 EnsureSpace ensure_space(this);
589 if (!dst.is_byte_register()) {
590 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
591 emit_rex_32(dst);
592 }
593 DCHECK(is_int8(src.value_) || is_uint8(src.value_));
594 emit(0x80);
595 emit_modrm(subcode, dst);
596 emit(src.value_);
597 }
598
599
shift(Register dst,Immediate shift_amount,int subcode,int size)600 void Assembler::shift(Register dst,
601 Immediate shift_amount,
602 int subcode,
603 int size) {
604 EnsureSpace ensure_space(this);
605 DCHECK(size == kInt64Size ? is_uint6(shift_amount.value_)
606 : is_uint5(shift_amount.value_));
607 if (shift_amount.value_ == 1) {
608 emit_rex(dst, size);
609 emit(0xD1);
610 emit_modrm(subcode, dst);
611 } else {
612 emit_rex(dst, size);
613 emit(0xC1);
614 emit_modrm(subcode, dst);
615 emit(shift_amount.value_);
616 }
617 }
618
619
shift(Register dst,int subcode,int size)620 void Assembler::shift(Register dst, int subcode, int size) {
621 EnsureSpace ensure_space(this);
622 emit_rex(dst, size);
623 emit(0xD3);
624 emit_modrm(subcode, dst);
625 }
626
627
bt(const Operand & dst,Register src)628 void Assembler::bt(const Operand& dst, Register src) {
629 EnsureSpace ensure_space(this);
630 emit_rex_64(src, dst);
631 emit(0x0F);
632 emit(0xA3);
633 emit_operand(src, dst);
634 }
635
636
bts(const Operand & dst,Register src)637 void Assembler::bts(const Operand& dst, Register src) {
638 EnsureSpace ensure_space(this);
639 emit_rex_64(src, dst);
640 emit(0x0F);
641 emit(0xAB);
642 emit_operand(src, dst);
643 }
644
645
bsrl(Register dst,Register src)646 void Assembler::bsrl(Register dst, Register src) {
647 EnsureSpace ensure_space(this);
648 emit_optional_rex_32(dst, src);
649 emit(0x0F);
650 emit(0xBD);
651 emit_modrm(dst, src);
652 }
653
654
call(Label * L)655 void Assembler::call(Label* L) {
656 positions_recorder()->WriteRecordedPositions();
657 EnsureSpace ensure_space(this);
658 // 1110 1000 #32-bit disp.
659 emit(0xE8);
660 if (L->is_bound()) {
661 int offset = L->pos() - pc_offset() - sizeof(int32_t);
662 DCHECK(offset <= 0);
663 emitl(offset);
664 } else if (L->is_linked()) {
665 emitl(L->pos());
666 L->link_to(pc_offset() - sizeof(int32_t));
667 } else {
668 DCHECK(L->is_unused());
669 int32_t current = pc_offset();
670 emitl(current);
671 L->link_to(current);
672 }
673 }
674
675
call(Address entry,RelocInfo::Mode rmode)676 void Assembler::call(Address entry, RelocInfo::Mode rmode) {
677 DCHECK(RelocInfo::IsRuntimeEntry(rmode));
678 positions_recorder()->WriteRecordedPositions();
679 EnsureSpace ensure_space(this);
680 // 1110 1000 #32-bit disp.
681 emit(0xE8);
682 emit_runtime_entry(entry, rmode);
683 }
684
685
call(Handle<Code> target,RelocInfo::Mode rmode,TypeFeedbackId ast_id)686 void Assembler::call(Handle<Code> target,
687 RelocInfo::Mode rmode,
688 TypeFeedbackId ast_id) {
689 positions_recorder()->WriteRecordedPositions();
690 EnsureSpace ensure_space(this);
691 // 1110 1000 #32-bit disp.
692 emit(0xE8);
693 emit_code_target(target, rmode, ast_id);
694 }
695
696
call(Register adr)697 void Assembler::call(Register adr) {
698 positions_recorder()->WriteRecordedPositions();
699 EnsureSpace ensure_space(this);
700 // Opcode: FF /2 r64.
701 emit_optional_rex_32(adr);
702 emit(0xFF);
703 emit_modrm(0x2, adr);
704 }
705
706
call(const Operand & op)707 void Assembler::call(const Operand& op) {
708 positions_recorder()->WriteRecordedPositions();
709 EnsureSpace ensure_space(this);
710 // Opcode: FF /2 m64.
711 emit_optional_rex_32(op);
712 emit(0xFF);
713 emit_operand(0x2, op);
714 }
715
716
717 // Calls directly to the given address using a relative offset.
718 // Should only ever be used in Code objects for calls within the
719 // same Code object. Should not be used when generating new code (use labels),
720 // but only when patching existing code.
call(Address target)721 void Assembler::call(Address target) {
722 positions_recorder()->WriteRecordedPositions();
723 EnsureSpace ensure_space(this);
724 // 1110 1000 #32-bit disp.
725 emit(0xE8);
726 Address source = pc_ + 4;
727 intptr_t displacement = target - source;
728 DCHECK(is_int32(displacement));
729 emitl(static_cast<int32_t>(displacement));
730 }
731
732
clc()733 void Assembler::clc() {
734 EnsureSpace ensure_space(this);
735 emit(0xF8);
736 }
737
738
cld()739 void Assembler::cld() {
740 EnsureSpace ensure_space(this);
741 emit(0xFC);
742 }
743
744
cdq()745 void Assembler::cdq() {
746 EnsureSpace ensure_space(this);
747 emit(0x99);
748 }
749
750
cmovq(Condition cc,Register dst,Register src)751 void Assembler::cmovq(Condition cc, Register dst, Register src) {
752 if (cc == always) {
753 movq(dst, src);
754 } else if (cc == never) {
755 return;
756 }
757 // No need to check CpuInfo for CMOV support, it's a required part of the
758 // 64-bit architecture.
759 DCHECK(cc >= 0); // Use mov for unconditional moves.
760 EnsureSpace ensure_space(this);
761 // Opcode: REX.W 0f 40 + cc /r.
762 emit_rex_64(dst, src);
763 emit(0x0f);
764 emit(0x40 + cc);
765 emit_modrm(dst, src);
766 }
767
768
cmovq(Condition cc,Register dst,const Operand & src)769 void Assembler::cmovq(Condition cc, Register dst, const Operand& src) {
770 if (cc == always) {
771 movq(dst, src);
772 } else if (cc == never) {
773 return;
774 }
775 DCHECK(cc >= 0);
776 EnsureSpace ensure_space(this);
777 // Opcode: REX.W 0f 40 + cc /r.
778 emit_rex_64(dst, src);
779 emit(0x0f);
780 emit(0x40 + cc);
781 emit_operand(dst, src);
782 }
783
784
cmovl(Condition cc,Register dst,Register src)785 void Assembler::cmovl(Condition cc, Register dst, Register src) {
786 if (cc == always) {
787 movl(dst, src);
788 } else if (cc == never) {
789 return;
790 }
791 DCHECK(cc >= 0);
792 EnsureSpace ensure_space(this);
793 // Opcode: 0f 40 + cc /r.
794 emit_optional_rex_32(dst, src);
795 emit(0x0f);
796 emit(0x40 + cc);
797 emit_modrm(dst, src);
798 }
799
800
cmovl(Condition cc,Register dst,const Operand & src)801 void Assembler::cmovl(Condition cc, Register dst, const Operand& src) {
802 if (cc == always) {
803 movl(dst, src);
804 } else if (cc == never) {
805 return;
806 }
807 DCHECK(cc >= 0);
808 EnsureSpace ensure_space(this);
809 // Opcode: 0f 40 + cc /r.
810 emit_optional_rex_32(dst, src);
811 emit(0x0f);
812 emit(0x40 + cc);
813 emit_operand(dst, src);
814 }
815
816
cmpb_al(Immediate imm8)817 void Assembler::cmpb_al(Immediate imm8) {
818 DCHECK(is_int8(imm8.value_) || is_uint8(imm8.value_));
819 EnsureSpace ensure_space(this);
820 emit(0x3c);
821 emit(imm8.value_);
822 }
823
824
cpuid()825 void Assembler::cpuid() {
826 EnsureSpace ensure_space(this);
827 emit(0x0F);
828 emit(0xA2);
829 }
830
831
cqo()832 void Assembler::cqo() {
833 EnsureSpace ensure_space(this);
834 emit_rex_64();
835 emit(0x99);
836 }
837
838
emit_dec(Register dst,int size)839 void Assembler::emit_dec(Register dst, int size) {
840 EnsureSpace ensure_space(this);
841 emit_rex(dst, size);
842 emit(0xFF);
843 emit_modrm(0x1, dst);
844 }
845
846
emit_dec(const Operand & dst,int size)847 void Assembler::emit_dec(const Operand& dst, int size) {
848 EnsureSpace ensure_space(this);
849 emit_rex(dst, size);
850 emit(0xFF);
851 emit_operand(1, dst);
852 }
853
854
decb(Register dst)855 void Assembler::decb(Register dst) {
856 EnsureSpace ensure_space(this);
857 if (!dst.is_byte_register()) {
858 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
859 emit_rex_32(dst);
860 }
861 emit(0xFE);
862 emit_modrm(0x1, dst);
863 }
864
865
decb(const Operand & dst)866 void Assembler::decb(const Operand& dst) {
867 EnsureSpace ensure_space(this);
868 emit_optional_rex_32(dst);
869 emit(0xFE);
870 emit_operand(1, dst);
871 }
872
873
enter(Immediate size)874 void Assembler::enter(Immediate size) {
875 EnsureSpace ensure_space(this);
876 emit(0xC8);
877 emitw(size.value_); // 16 bit operand, always.
878 emit(0);
879 }
880
881
hlt()882 void Assembler::hlt() {
883 EnsureSpace ensure_space(this);
884 emit(0xF4);
885 }
886
887
emit_idiv(Register src,int size)888 void Assembler::emit_idiv(Register src, int size) {
889 EnsureSpace ensure_space(this);
890 emit_rex(src, size);
891 emit(0xF7);
892 emit_modrm(0x7, src);
893 }
894
895
emit_div(Register src,int size)896 void Assembler::emit_div(Register src, int size) {
897 EnsureSpace ensure_space(this);
898 emit_rex(src, size);
899 emit(0xF7);
900 emit_modrm(0x6, src);
901 }
902
903
emit_imul(Register src,int size)904 void Assembler::emit_imul(Register src, int size) {
905 EnsureSpace ensure_space(this);
906 emit_rex(src, size);
907 emit(0xF7);
908 emit_modrm(0x5, src);
909 }
910
911
emit_imul(Register dst,Register src,int size)912 void Assembler::emit_imul(Register dst, Register src, int size) {
913 EnsureSpace ensure_space(this);
914 emit_rex(dst, src, size);
915 emit(0x0F);
916 emit(0xAF);
917 emit_modrm(dst, src);
918 }
919
920
emit_imul(Register dst,const Operand & src,int size)921 void Assembler::emit_imul(Register dst, const Operand& src, int size) {
922 EnsureSpace ensure_space(this);
923 emit_rex(dst, src, size);
924 emit(0x0F);
925 emit(0xAF);
926 emit_operand(dst, src);
927 }
928
929
emit_imul(Register dst,Register src,Immediate imm,int size)930 void Assembler::emit_imul(Register dst, Register src, Immediate imm, int size) {
931 EnsureSpace ensure_space(this);
932 emit_rex(dst, src, size);
933 if (is_int8(imm.value_)) {
934 emit(0x6B);
935 emit_modrm(dst, src);
936 emit(imm.value_);
937 } else {
938 emit(0x69);
939 emit_modrm(dst, src);
940 emitl(imm.value_);
941 }
942 }
943
944
emit_inc(Register dst,int size)945 void Assembler::emit_inc(Register dst, int size) {
946 EnsureSpace ensure_space(this);
947 emit_rex(dst, size);
948 emit(0xFF);
949 emit_modrm(0x0, dst);
950 }
951
952
emit_inc(const Operand & dst,int size)953 void Assembler::emit_inc(const Operand& dst, int size) {
954 EnsureSpace ensure_space(this);
955 emit_rex(dst, size);
956 emit(0xFF);
957 emit_operand(0, dst);
958 }
959
960
int3()961 void Assembler::int3() {
962 EnsureSpace ensure_space(this);
963 emit(0xCC);
964 }
965
966
j(Condition cc,Label * L,Label::Distance distance)967 void Assembler::j(Condition cc, Label* L, Label::Distance distance) {
968 if (cc == always) {
969 jmp(L);
970 return;
971 } else if (cc == never) {
972 return;
973 }
974 EnsureSpace ensure_space(this);
975 DCHECK(is_uint4(cc));
976 if (L->is_bound()) {
977 const int short_size = 2;
978 const int long_size = 6;
979 int offs = L->pos() - pc_offset();
980 DCHECK(offs <= 0);
981 // Determine whether we can use 1-byte offsets for backwards branches,
982 // which have a max range of 128 bytes.
983
984 // We also need to check predictable_code_size() flag here, because on x64,
985 // when the full code generator recompiles code for debugging, some places
986 // need to be padded out to a certain size. The debugger is keeping track of
987 // how often it did this so that it can adjust return addresses on the
988 // stack, but if the size of jump instructions can also change, that's not
989 // enough and the calculated offsets would be incorrect.
990 if (is_int8(offs - short_size) && !predictable_code_size()) {
991 // 0111 tttn #8-bit disp.
992 emit(0x70 | cc);
993 emit((offs - short_size) & 0xFF);
994 } else {
995 // 0000 1111 1000 tttn #32-bit disp.
996 emit(0x0F);
997 emit(0x80 | cc);
998 emitl(offs - long_size);
999 }
1000 } else if (distance == Label::kNear) {
1001 // 0111 tttn #8-bit disp
1002 emit(0x70 | cc);
1003 byte disp = 0x00;
1004 if (L->is_near_linked()) {
1005 int offset = L->near_link_pos() - pc_offset();
1006 DCHECK(is_int8(offset));
1007 disp = static_cast<byte>(offset & 0xFF);
1008 }
1009 L->link_to(pc_offset(), Label::kNear);
1010 emit(disp);
1011 } else if (L->is_linked()) {
1012 // 0000 1111 1000 tttn #32-bit disp.
1013 emit(0x0F);
1014 emit(0x80 | cc);
1015 emitl(L->pos());
1016 L->link_to(pc_offset() - sizeof(int32_t));
1017 } else {
1018 DCHECK(L->is_unused());
1019 emit(0x0F);
1020 emit(0x80 | cc);
1021 int32_t current = pc_offset();
1022 emitl(current);
1023 L->link_to(current);
1024 }
1025 }
1026
1027
j(Condition cc,Address entry,RelocInfo::Mode rmode)1028 void Assembler::j(Condition cc, Address entry, RelocInfo::Mode rmode) {
1029 DCHECK(RelocInfo::IsRuntimeEntry(rmode));
1030 EnsureSpace ensure_space(this);
1031 DCHECK(is_uint4(cc));
1032 emit(0x0F);
1033 emit(0x80 | cc);
1034 emit_runtime_entry(entry, rmode);
1035 }
1036
1037
j(Condition cc,Handle<Code> target,RelocInfo::Mode rmode)1038 void Assembler::j(Condition cc,
1039 Handle<Code> target,
1040 RelocInfo::Mode rmode) {
1041 EnsureSpace ensure_space(this);
1042 DCHECK(is_uint4(cc));
1043 // 0000 1111 1000 tttn #32-bit disp.
1044 emit(0x0F);
1045 emit(0x80 | cc);
1046 emit_code_target(target, rmode);
1047 }
1048
1049
jmp(Label * L,Label::Distance distance)1050 void Assembler::jmp(Label* L, Label::Distance distance) {
1051 EnsureSpace ensure_space(this);
1052 const int short_size = sizeof(int8_t);
1053 const int long_size = sizeof(int32_t);
1054 if (L->is_bound()) {
1055 int offs = L->pos() - pc_offset() - 1;
1056 DCHECK(offs <= 0);
1057 if (is_int8(offs - short_size) && !predictable_code_size()) {
1058 // 1110 1011 #8-bit disp.
1059 emit(0xEB);
1060 emit((offs - short_size) & 0xFF);
1061 } else {
1062 // 1110 1001 #32-bit disp.
1063 emit(0xE9);
1064 emitl(offs - long_size);
1065 }
1066 } else if (distance == Label::kNear) {
1067 emit(0xEB);
1068 byte disp = 0x00;
1069 if (L->is_near_linked()) {
1070 int offset = L->near_link_pos() - pc_offset();
1071 DCHECK(is_int8(offset));
1072 disp = static_cast<byte>(offset & 0xFF);
1073 }
1074 L->link_to(pc_offset(), Label::kNear);
1075 emit(disp);
1076 } else if (L->is_linked()) {
1077 // 1110 1001 #32-bit disp.
1078 emit(0xE9);
1079 emitl(L->pos());
1080 L->link_to(pc_offset() - long_size);
1081 } else {
1082 // 1110 1001 #32-bit disp.
1083 DCHECK(L->is_unused());
1084 emit(0xE9);
1085 int32_t current = pc_offset();
1086 emitl(current);
1087 L->link_to(current);
1088 }
1089 }
1090
1091
jmp(Handle<Code> target,RelocInfo::Mode rmode)1092 void Assembler::jmp(Handle<Code> target, RelocInfo::Mode rmode) {
1093 EnsureSpace ensure_space(this);
1094 // 1110 1001 #32-bit disp.
1095 emit(0xE9);
1096 emit_code_target(target, rmode);
1097 }
1098
1099
jmp(Address entry,RelocInfo::Mode rmode)1100 void Assembler::jmp(Address entry, RelocInfo::Mode rmode) {
1101 DCHECK(RelocInfo::IsRuntimeEntry(rmode));
1102 EnsureSpace ensure_space(this);
1103 DCHECK(RelocInfo::IsRuntimeEntry(rmode));
1104 emit(0xE9);
1105 emit_runtime_entry(entry, rmode);
1106 }
1107
1108
jmp(Register target)1109 void Assembler::jmp(Register target) {
1110 EnsureSpace ensure_space(this);
1111 // Opcode FF/4 r64.
1112 emit_optional_rex_32(target);
1113 emit(0xFF);
1114 emit_modrm(0x4, target);
1115 }
1116
1117
jmp(const Operand & src)1118 void Assembler::jmp(const Operand& src) {
1119 EnsureSpace ensure_space(this);
1120 // Opcode FF/4 m64.
1121 emit_optional_rex_32(src);
1122 emit(0xFF);
1123 emit_operand(0x4, src);
1124 }
1125
1126
emit_lea(Register dst,const Operand & src,int size)1127 void Assembler::emit_lea(Register dst, const Operand& src, int size) {
1128 EnsureSpace ensure_space(this);
1129 emit_rex(dst, src, size);
1130 emit(0x8D);
1131 emit_operand(dst, src);
1132 }
1133
1134
load_rax(void * value,RelocInfo::Mode mode)1135 void Assembler::load_rax(void* value, RelocInfo::Mode mode) {
1136 EnsureSpace ensure_space(this);
1137 if (kPointerSize == kInt64Size) {
1138 emit(0x48); // REX.W
1139 emit(0xA1);
1140 emitp(value, mode);
1141 } else {
1142 DCHECK(kPointerSize == kInt32Size);
1143 emit(0xA1);
1144 emitp(value, mode);
1145 // In 64-bit mode, need to zero extend the operand to 8 bytes.
1146 // See 2.2.1.4 in Intel64 and IA32 Architectures Software
1147 // Developer's Manual Volume 2.
1148 emitl(0);
1149 }
1150 }
1151
1152
load_rax(ExternalReference ref)1153 void Assembler::load_rax(ExternalReference ref) {
1154 load_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE);
1155 }
1156
1157
leave()1158 void Assembler::leave() {
1159 EnsureSpace ensure_space(this);
1160 emit(0xC9);
1161 }
1162
1163
movb(Register dst,const Operand & src)1164 void Assembler::movb(Register dst, const Operand& src) {
1165 EnsureSpace ensure_space(this);
1166 if (!dst.is_byte_register()) {
1167 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1168 emit_rex_32(dst, src);
1169 } else {
1170 emit_optional_rex_32(dst, src);
1171 }
1172 emit(0x8A);
1173 emit_operand(dst, src);
1174 }
1175
1176
movb(Register dst,Immediate imm)1177 void Assembler::movb(Register dst, Immediate imm) {
1178 EnsureSpace ensure_space(this);
1179 if (!dst.is_byte_register()) {
1180 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1181 emit_rex_32(dst);
1182 }
1183 emit(0xB0 + dst.low_bits());
1184 emit(imm.value_);
1185 }
1186
1187
movb(const Operand & dst,Register src)1188 void Assembler::movb(const Operand& dst, Register src) {
1189 EnsureSpace ensure_space(this);
1190 if (!src.is_byte_register()) {
1191 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1192 emit_rex_32(src, dst);
1193 } else {
1194 emit_optional_rex_32(src, dst);
1195 }
1196 emit(0x88);
1197 emit_operand(src, dst);
1198 }
1199
1200
movb(const Operand & dst,Immediate imm)1201 void Assembler::movb(const Operand& dst, Immediate imm) {
1202 EnsureSpace ensure_space(this);
1203 emit_optional_rex_32(dst);
1204 emit(0xC6);
1205 emit_operand(0x0, dst);
1206 emit(static_cast<byte>(imm.value_));
1207 }
1208
1209
movw(Register dst,const Operand & src)1210 void Assembler::movw(Register dst, const Operand& src) {
1211 EnsureSpace ensure_space(this);
1212 emit(0x66);
1213 emit_optional_rex_32(dst, src);
1214 emit(0x8B);
1215 emit_operand(dst, src);
1216 }
1217
1218
movw(const Operand & dst,Register src)1219 void Assembler::movw(const Operand& dst, Register src) {
1220 EnsureSpace ensure_space(this);
1221 emit(0x66);
1222 emit_optional_rex_32(src, dst);
1223 emit(0x89);
1224 emit_operand(src, dst);
1225 }
1226
1227
movw(const Operand & dst,Immediate imm)1228 void Assembler::movw(const Operand& dst, Immediate imm) {
1229 EnsureSpace ensure_space(this);
1230 emit(0x66);
1231 emit_optional_rex_32(dst);
1232 emit(0xC7);
1233 emit_operand(0x0, dst);
1234 emit(static_cast<byte>(imm.value_ & 0xff));
1235 emit(static_cast<byte>(imm.value_ >> 8));
1236 }
1237
1238
emit_mov(Register dst,const Operand & src,int size)1239 void Assembler::emit_mov(Register dst, const Operand& src, int size) {
1240 EnsureSpace ensure_space(this);
1241 emit_rex(dst, src, size);
1242 emit(0x8B);
1243 emit_operand(dst, src);
1244 }
1245
1246
emit_mov(Register dst,Register src,int size)1247 void Assembler::emit_mov(Register dst, Register src, int size) {
1248 EnsureSpace ensure_space(this);
1249 if (src.low_bits() == 4) {
1250 emit_rex(src, dst, size);
1251 emit(0x89);
1252 emit_modrm(src, dst);
1253 } else {
1254 emit_rex(dst, src, size);
1255 emit(0x8B);
1256 emit_modrm(dst, src);
1257 }
1258 }
1259
1260
emit_mov(const Operand & dst,Register src,int size)1261 void Assembler::emit_mov(const Operand& dst, Register src, int size) {
1262 EnsureSpace ensure_space(this);
1263 emit_rex(src, dst, size);
1264 emit(0x89);
1265 emit_operand(src, dst);
1266 }
1267
1268
emit_mov(Register dst,Immediate value,int size)1269 void Assembler::emit_mov(Register dst, Immediate value, int size) {
1270 EnsureSpace ensure_space(this);
1271 emit_rex(dst, size);
1272 if (size == kInt64Size) {
1273 emit(0xC7);
1274 emit_modrm(0x0, dst);
1275 } else {
1276 DCHECK(size == kInt32Size);
1277 emit(0xB8 + dst.low_bits());
1278 }
1279 emit(value);
1280 }
1281
1282
emit_mov(const Operand & dst,Immediate value,int size)1283 void Assembler::emit_mov(const Operand& dst, Immediate value, int size) {
1284 EnsureSpace ensure_space(this);
1285 emit_rex(dst, size);
1286 emit(0xC7);
1287 emit_operand(0x0, dst);
1288 emit(value);
1289 }
1290
1291
movp(Register dst,void * value,RelocInfo::Mode rmode)1292 void Assembler::movp(Register dst, void* value, RelocInfo::Mode rmode) {
1293 EnsureSpace ensure_space(this);
1294 emit_rex(dst, kPointerSize);
1295 emit(0xB8 | dst.low_bits());
1296 emitp(value, rmode);
1297 }
1298
1299
movq(Register dst,int64_t value)1300 void Assembler::movq(Register dst, int64_t value) {
1301 EnsureSpace ensure_space(this);
1302 emit_rex_64(dst);
1303 emit(0xB8 | dst.low_bits());
1304 emitq(value);
1305 }
1306
1307
movq(Register dst,uint64_t value)1308 void Assembler::movq(Register dst, uint64_t value) {
1309 movq(dst, static_cast<int64_t>(value));
1310 }
1311
1312
1313 // Loads the ip-relative location of the src label into the target location
1314 // (as a 32-bit offset sign extended to 64-bit).
movl(const Operand & dst,Label * src)1315 void Assembler::movl(const Operand& dst, Label* src) {
1316 EnsureSpace ensure_space(this);
1317 emit_optional_rex_32(dst);
1318 emit(0xC7);
1319 emit_operand(0, dst);
1320 if (src->is_bound()) {
1321 int offset = src->pos() - pc_offset() - sizeof(int32_t);
1322 DCHECK(offset <= 0);
1323 emitl(offset);
1324 } else if (src->is_linked()) {
1325 emitl(src->pos());
1326 src->link_to(pc_offset() - sizeof(int32_t));
1327 } else {
1328 DCHECK(src->is_unused());
1329 int32_t current = pc_offset();
1330 emitl(current);
1331 src->link_to(current);
1332 }
1333 }
1334
1335
movsxbl(Register dst,const Operand & src)1336 void Assembler::movsxbl(Register dst, const Operand& src) {
1337 EnsureSpace ensure_space(this);
1338 emit_optional_rex_32(dst, src);
1339 emit(0x0F);
1340 emit(0xBE);
1341 emit_operand(dst, src);
1342 }
1343
1344
movsxbq(Register dst,const Operand & src)1345 void Assembler::movsxbq(Register dst, const Operand& src) {
1346 EnsureSpace ensure_space(this);
1347 emit_rex_64(dst, src);
1348 emit(0x0F);
1349 emit(0xBE);
1350 emit_operand(dst, src);
1351 }
1352
1353
movsxwl(Register dst,const Operand & src)1354 void Assembler::movsxwl(Register dst, const Operand& src) {
1355 EnsureSpace ensure_space(this);
1356 emit_optional_rex_32(dst, src);
1357 emit(0x0F);
1358 emit(0xBF);
1359 emit_operand(dst, src);
1360 }
1361
1362
movsxwq(Register dst,const Operand & src)1363 void Assembler::movsxwq(Register dst, const Operand& src) {
1364 EnsureSpace ensure_space(this);
1365 emit_rex_64(dst, src);
1366 emit(0x0F);
1367 emit(0xBF);
1368 emit_operand(dst, src);
1369 }
1370
1371
movsxlq(Register dst,Register src)1372 void Assembler::movsxlq(Register dst, Register src) {
1373 EnsureSpace ensure_space(this);
1374 emit_rex_64(dst, src);
1375 emit(0x63);
1376 emit_modrm(dst, src);
1377 }
1378
1379
movsxlq(Register dst,const Operand & src)1380 void Assembler::movsxlq(Register dst, const Operand& src) {
1381 EnsureSpace ensure_space(this);
1382 emit_rex_64(dst, src);
1383 emit(0x63);
1384 emit_operand(dst, src);
1385 }
1386
1387
emit_movzxb(Register dst,const Operand & src,int size)1388 void Assembler::emit_movzxb(Register dst, const Operand& src, int size) {
1389 EnsureSpace ensure_space(this);
1390 // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
1391 // there is no need to make this a 64 bit operation.
1392 emit_optional_rex_32(dst, src);
1393 emit(0x0F);
1394 emit(0xB6);
1395 emit_operand(dst, src);
1396 }
1397
1398
emit_movzxb(Register dst,Register src,int size)1399 void Assembler::emit_movzxb(Register dst, Register src, int size) {
1400 EnsureSpace ensure_space(this);
1401 // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
1402 // there is no need to make this a 64 bit operation.
1403 if (!src.is_byte_register()) {
1404 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1405 emit_rex_32(dst, src);
1406 } else {
1407 emit_optional_rex_32(dst, src);
1408 }
1409 emit(0x0F);
1410 emit(0xB6);
1411 emit_modrm(dst, src);
1412 }
1413
1414
emit_movzxw(Register dst,const Operand & src,int size)1415 void Assembler::emit_movzxw(Register dst, const Operand& src, int size) {
1416 EnsureSpace ensure_space(this);
1417 // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
1418 // there is no need to make this a 64 bit operation.
1419 emit_optional_rex_32(dst, src);
1420 emit(0x0F);
1421 emit(0xB7);
1422 emit_operand(dst, src);
1423 }
1424
1425
emit_movzxw(Register dst,Register src,int size)1426 void Assembler::emit_movzxw(Register dst, Register src, int size) {
1427 EnsureSpace ensure_space(this);
1428 // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
1429 // there is no need to make this a 64 bit operation.
1430 emit_optional_rex_32(dst, src);
1431 emit(0x0F);
1432 emit(0xB7);
1433 emit_modrm(dst, src);
1434 }
1435
1436
repmovsb()1437 void Assembler::repmovsb() {
1438 EnsureSpace ensure_space(this);
1439 emit(0xF3);
1440 emit(0xA4);
1441 }
1442
1443
repmovsw()1444 void Assembler::repmovsw() {
1445 EnsureSpace ensure_space(this);
1446 emit(0x66); // Operand size override.
1447 emit(0xF3);
1448 emit(0xA4);
1449 }
1450
1451
emit_repmovs(int size)1452 void Assembler::emit_repmovs(int size) {
1453 EnsureSpace ensure_space(this);
1454 emit(0xF3);
1455 emit_rex(size);
1456 emit(0xA5);
1457 }
1458
1459
mul(Register src)1460 void Assembler::mul(Register src) {
1461 EnsureSpace ensure_space(this);
1462 emit_rex_64(src);
1463 emit(0xF7);
1464 emit_modrm(0x4, src);
1465 }
1466
1467
emit_neg(Register dst,int size)1468 void Assembler::emit_neg(Register dst, int size) {
1469 EnsureSpace ensure_space(this);
1470 emit_rex(dst, size);
1471 emit(0xF7);
1472 emit_modrm(0x3, dst);
1473 }
1474
1475
emit_neg(const Operand & dst,int size)1476 void Assembler::emit_neg(const Operand& dst, int size) {
1477 EnsureSpace ensure_space(this);
1478 emit_rex_64(dst);
1479 emit(0xF7);
1480 emit_operand(3, dst);
1481 }
1482
1483
nop()1484 void Assembler::nop() {
1485 EnsureSpace ensure_space(this);
1486 emit(0x90);
1487 }
1488
1489
emit_not(Register dst,int size)1490 void Assembler::emit_not(Register dst, int size) {
1491 EnsureSpace ensure_space(this);
1492 emit_rex(dst, size);
1493 emit(0xF7);
1494 emit_modrm(0x2, dst);
1495 }
1496
1497
emit_not(const Operand & dst,int size)1498 void Assembler::emit_not(const Operand& dst, int size) {
1499 EnsureSpace ensure_space(this);
1500 emit_rex(dst, size);
1501 emit(0xF7);
1502 emit_operand(2, dst);
1503 }
1504
1505
Nop(int n)1506 void Assembler::Nop(int n) {
1507 // The recommended muti-byte sequences of NOP instructions from the Intel 64
1508 // and IA-32 Architectures Software Developer's Manual.
1509 //
1510 // Length Assembly Byte Sequence
1511 // 2 bytes 66 NOP 66 90H
1512 // 3 bytes NOP DWORD ptr [EAX] 0F 1F 00H
1513 // 4 bytes NOP DWORD ptr [EAX + 00H] 0F 1F 40 00H
1514 // 5 bytes NOP DWORD ptr [EAX + EAX*1 + 00H] 0F 1F 44 00 00H
1515 // 6 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00H] 66 0F 1F 44 00 00H
1516 // 7 bytes NOP DWORD ptr [EAX + 00000000H] 0F 1F 80 00 00 00 00H
1517 // 8 bytes NOP DWORD ptr [EAX + EAX*1 + 00000000H] 0F 1F 84 00 00 00 00 00H
1518 // 9 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 66 0F 1F 84 00 00 00 00
1519 // 00000000H] 00H
1520
1521 EnsureSpace ensure_space(this);
1522 while (n > 0) {
1523 switch (n) {
1524 case 2:
1525 emit(0x66);
1526 case 1:
1527 emit(0x90);
1528 return;
1529 case 3:
1530 emit(0x0f);
1531 emit(0x1f);
1532 emit(0x00);
1533 return;
1534 case 4:
1535 emit(0x0f);
1536 emit(0x1f);
1537 emit(0x40);
1538 emit(0x00);
1539 return;
1540 case 6:
1541 emit(0x66);
1542 case 5:
1543 emit(0x0f);
1544 emit(0x1f);
1545 emit(0x44);
1546 emit(0x00);
1547 emit(0x00);
1548 return;
1549 case 7:
1550 emit(0x0f);
1551 emit(0x1f);
1552 emit(0x80);
1553 emit(0x00);
1554 emit(0x00);
1555 emit(0x00);
1556 emit(0x00);
1557 return;
1558 default:
1559 case 11:
1560 emit(0x66);
1561 n--;
1562 case 10:
1563 emit(0x66);
1564 n--;
1565 case 9:
1566 emit(0x66);
1567 n--;
1568 case 8:
1569 emit(0x0f);
1570 emit(0x1f);
1571 emit(0x84);
1572 emit(0x00);
1573 emit(0x00);
1574 emit(0x00);
1575 emit(0x00);
1576 emit(0x00);
1577 n -= 8;
1578 }
1579 }
1580 }
1581
1582
popq(Register dst)1583 void Assembler::popq(Register dst) {
1584 EnsureSpace ensure_space(this);
1585 emit_optional_rex_32(dst);
1586 emit(0x58 | dst.low_bits());
1587 }
1588
1589
popq(const Operand & dst)1590 void Assembler::popq(const Operand& dst) {
1591 EnsureSpace ensure_space(this);
1592 emit_optional_rex_32(dst);
1593 emit(0x8F);
1594 emit_operand(0, dst);
1595 }
1596
1597
popfq()1598 void Assembler::popfq() {
1599 EnsureSpace ensure_space(this);
1600 emit(0x9D);
1601 }
1602
1603
pushq(Register src)1604 void Assembler::pushq(Register src) {
1605 EnsureSpace ensure_space(this);
1606 emit_optional_rex_32(src);
1607 emit(0x50 | src.low_bits());
1608 }
1609
1610
pushq(const Operand & src)1611 void Assembler::pushq(const Operand& src) {
1612 EnsureSpace ensure_space(this);
1613 emit_optional_rex_32(src);
1614 emit(0xFF);
1615 emit_operand(6, src);
1616 }
1617
1618
pushq(Immediate value)1619 void Assembler::pushq(Immediate value) {
1620 EnsureSpace ensure_space(this);
1621 if (is_int8(value.value_)) {
1622 emit(0x6A);
1623 emit(value.value_); // Emit low byte of value.
1624 } else {
1625 emit(0x68);
1626 emitl(value.value_);
1627 }
1628 }
1629
1630
pushq_imm32(int32_t imm32)1631 void Assembler::pushq_imm32(int32_t imm32) {
1632 EnsureSpace ensure_space(this);
1633 emit(0x68);
1634 emitl(imm32);
1635 }
1636
1637
pushfq()1638 void Assembler::pushfq() {
1639 EnsureSpace ensure_space(this);
1640 emit(0x9C);
1641 }
1642
1643
ret(int imm16)1644 void Assembler::ret(int imm16) {
1645 EnsureSpace ensure_space(this);
1646 DCHECK(is_uint16(imm16));
1647 if (imm16 == 0) {
1648 emit(0xC3);
1649 } else {
1650 emit(0xC2);
1651 emit(imm16 & 0xFF);
1652 emit((imm16 >> 8) & 0xFF);
1653 }
1654 }
1655
1656
setcc(Condition cc,Register reg)1657 void Assembler::setcc(Condition cc, Register reg) {
1658 if (cc > last_condition) {
1659 movb(reg, Immediate(cc == always ? 1 : 0));
1660 return;
1661 }
1662 EnsureSpace ensure_space(this);
1663 DCHECK(is_uint4(cc));
1664 if (!reg.is_byte_register()) {
1665 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1666 emit_rex_32(reg);
1667 }
1668 emit(0x0F);
1669 emit(0x90 | cc);
1670 emit_modrm(0x0, reg);
1671 }
1672
1673
shld(Register dst,Register src)1674 void Assembler::shld(Register dst, Register src) {
1675 EnsureSpace ensure_space(this);
1676 emit_rex_64(src, dst);
1677 emit(0x0F);
1678 emit(0xA5);
1679 emit_modrm(src, dst);
1680 }
1681
1682
shrd(Register dst,Register src)1683 void Assembler::shrd(Register dst, Register src) {
1684 EnsureSpace ensure_space(this);
1685 emit_rex_64(src, dst);
1686 emit(0x0F);
1687 emit(0xAD);
1688 emit_modrm(src, dst);
1689 }
1690
1691
emit_xchg(Register dst,Register src,int size)1692 void Assembler::emit_xchg(Register dst, Register src, int size) {
1693 EnsureSpace ensure_space(this);
1694 if (src.is(rax) || dst.is(rax)) { // Single-byte encoding
1695 Register other = src.is(rax) ? dst : src;
1696 emit_rex(other, size);
1697 emit(0x90 | other.low_bits());
1698 } else if (dst.low_bits() == 4) {
1699 emit_rex(dst, src, size);
1700 emit(0x87);
1701 emit_modrm(dst, src);
1702 } else {
1703 emit_rex(src, dst, size);
1704 emit(0x87);
1705 emit_modrm(src, dst);
1706 }
1707 }
1708
1709
emit_xchg(Register dst,const Operand & src,int size)1710 void Assembler::emit_xchg(Register dst, const Operand& src, int size) {
1711 EnsureSpace ensure_space(this);
1712 emit_rex(dst, src, size);
1713 emit(0x87);
1714 emit_operand(dst, src);
1715 }
1716
1717
store_rax(void * dst,RelocInfo::Mode mode)1718 void Assembler::store_rax(void* dst, RelocInfo::Mode mode) {
1719 EnsureSpace ensure_space(this);
1720 if (kPointerSize == kInt64Size) {
1721 emit(0x48); // REX.W
1722 emit(0xA3);
1723 emitp(dst, mode);
1724 } else {
1725 DCHECK(kPointerSize == kInt32Size);
1726 emit(0xA3);
1727 emitp(dst, mode);
1728 // In 64-bit mode, need to zero extend the operand to 8 bytes.
1729 // See 2.2.1.4 in Intel64 and IA32 Architectures Software
1730 // Developer's Manual Volume 2.
1731 emitl(0);
1732 }
1733 }
1734
1735
store_rax(ExternalReference ref)1736 void Assembler::store_rax(ExternalReference ref) {
1737 store_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE);
1738 }
1739
1740
testb(Register dst,Register src)1741 void Assembler::testb(Register dst, Register src) {
1742 EnsureSpace ensure_space(this);
1743 if (src.low_bits() == 4) {
1744 emit_rex_32(src, dst);
1745 emit(0x84);
1746 emit_modrm(src, dst);
1747 } else {
1748 if (!dst.is_byte_register() || !src.is_byte_register()) {
1749 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1750 emit_rex_32(dst, src);
1751 }
1752 emit(0x84);
1753 emit_modrm(dst, src);
1754 }
1755 }
1756
1757
testb(Register reg,Immediate mask)1758 void Assembler::testb(Register reg, Immediate mask) {
1759 DCHECK(is_int8(mask.value_) || is_uint8(mask.value_));
1760 EnsureSpace ensure_space(this);
1761 if (reg.is(rax)) {
1762 emit(0xA8);
1763 emit(mask.value_); // Low byte emitted.
1764 } else {
1765 if (!reg.is_byte_register()) {
1766 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1767 emit_rex_32(reg);
1768 }
1769 emit(0xF6);
1770 emit_modrm(0x0, reg);
1771 emit(mask.value_); // Low byte emitted.
1772 }
1773 }
1774
1775
testb(const Operand & op,Immediate mask)1776 void Assembler::testb(const Operand& op, Immediate mask) {
1777 DCHECK(is_int8(mask.value_) || is_uint8(mask.value_));
1778 EnsureSpace ensure_space(this);
1779 emit_optional_rex_32(rax, op);
1780 emit(0xF6);
1781 emit_operand(rax, op); // Operation code 0
1782 emit(mask.value_); // Low byte emitted.
1783 }
1784
1785
testb(const Operand & op,Register reg)1786 void Assembler::testb(const Operand& op, Register reg) {
1787 EnsureSpace ensure_space(this);
1788 if (!reg.is_byte_register()) {
1789 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1790 emit_rex_32(reg, op);
1791 } else {
1792 emit_optional_rex_32(reg, op);
1793 }
1794 emit(0x84);
1795 emit_operand(reg, op);
1796 }
1797
1798
emit_test(Register dst,Register src,int size)1799 void Assembler::emit_test(Register dst, Register src, int size) {
1800 EnsureSpace ensure_space(this);
1801 if (src.low_bits() == 4) {
1802 emit_rex(src, dst, size);
1803 emit(0x85);
1804 emit_modrm(src, dst);
1805 } else {
1806 emit_rex(dst, src, size);
1807 emit(0x85);
1808 emit_modrm(dst, src);
1809 }
1810 }
1811
1812
emit_test(Register reg,Immediate mask,int size)1813 void Assembler::emit_test(Register reg, Immediate mask, int size) {
1814 // testl with a mask that fits in the low byte is exactly testb.
1815 if (is_uint8(mask.value_)) {
1816 testb(reg, mask);
1817 return;
1818 }
1819 EnsureSpace ensure_space(this);
1820 if (reg.is(rax)) {
1821 emit_rex(rax, size);
1822 emit(0xA9);
1823 emit(mask);
1824 } else {
1825 emit_rex(reg, size);
1826 emit(0xF7);
1827 emit_modrm(0x0, reg);
1828 emit(mask);
1829 }
1830 }
1831
1832
emit_test(const Operand & op,Immediate mask,int size)1833 void Assembler::emit_test(const Operand& op, Immediate mask, int size) {
1834 // testl with a mask that fits in the low byte is exactly testb.
1835 if (is_uint8(mask.value_)) {
1836 testb(op, mask);
1837 return;
1838 }
1839 EnsureSpace ensure_space(this);
1840 emit_rex(rax, op, size);
1841 emit(0xF7);
1842 emit_operand(rax, op); // Operation code 0
1843 emit(mask);
1844 }
1845
1846
emit_test(const Operand & op,Register reg,int size)1847 void Assembler::emit_test(const Operand& op, Register reg, int size) {
1848 EnsureSpace ensure_space(this);
1849 emit_rex(reg, op, size);
1850 emit(0x85);
1851 emit_operand(reg, op);
1852 }
1853
1854
1855 // FPU instructions.
1856
1857
fld(int i)1858 void Assembler::fld(int i) {
1859 EnsureSpace ensure_space(this);
1860 emit_farith(0xD9, 0xC0, i);
1861 }
1862
1863
fld1()1864 void Assembler::fld1() {
1865 EnsureSpace ensure_space(this);
1866 emit(0xD9);
1867 emit(0xE8);
1868 }
1869
1870
fldz()1871 void Assembler::fldz() {
1872 EnsureSpace ensure_space(this);
1873 emit(0xD9);
1874 emit(0xEE);
1875 }
1876
1877
fldpi()1878 void Assembler::fldpi() {
1879 EnsureSpace ensure_space(this);
1880 emit(0xD9);
1881 emit(0xEB);
1882 }
1883
1884
fldln2()1885 void Assembler::fldln2() {
1886 EnsureSpace ensure_space(this);
1887 emit(0xD9);
1888 emit(0xED);
1889 }
1890
1891
fld_s(const Operand & adr)1892 void Assembler::fld_s(const Operand& adr) {
1893 EnsureSpace ensure_space(this);
1894 emit_optional_rex_32(adr);
1895 emit(0xD9);
1896 emit_operand(0, adr);
1897 }
1898
1899
fld_d(const Operand & adr)1900 void Assembler::fld_d(const Operand& adr) {
1901 EnsureSpace ensure_space(this);
1902 emit_optional_rex_32(adr);
1903 emit(0xDD);
1904 emit_operand(0, adr);
1905 }
1906
1907
fstp_s(const Operand & adr)1908 void Assembler::fstp_s(const Operand& adr) {
1909 EnsureSpace ensure_space(this);
1910 emit_optional_rex_32(adr);
1911 emit(0xD9);
1912 emit_operand(3, adr);
1913 }
1914
1915
fstp_d(const Operand & adr)1916 void Assembler::fstp_d(const Operand& adr) {
1917 EnsureSpace ensure_space(this);
1918 emit_optional_rex_32(adr);
1919 emit(0xDD);
1920 emit_operand(3, adr);
1921 }
1922
1923
fstp(int index)1924 void Assembler::fstp(int index) {
1925 DCHECK(is_uint3(index));
1926 EnsureSpace ensure_space(this);
1927 emit_farith(0xDD, 0xD8, index);
1928 }
1929
1930
fild_s(const Operand & adr)1931 void Assembler::fild_s(const Operand& adr) {
1932 EnsureSpace ensure_space(this);
1933 emit_optional_rex_32(adr);
1934 emit(0xDB);
1935 emit_operand(0, adr);
1936 }
1937
1938
fild_d(const Operand & adr)1939 void Assembler::fild_d(const Operand& adr) {
1940 EnsureSpace ensure_space(this);
1941 emit_optional_rex_32(adr);
1942 emit(0xDF);
1943 emit_operand(5, adr);
1944 }
1945
1946
fistp_s(const Operand & adr)1947 void Assembler::fistp_s(const Operand& adr) {
1948 EnsureSpace ensure_space(this);
1949 emit_optional_rex_32(adr);
1950 emit(0xDB);
1951 emit_operand(3, adr);
1952 }
1953
1954
fisttp_s(const Operand & adr)1955 void Assembler::fisttp_s(const Operand& adr) {
1956 DCHECK(IsEnabled(SSE3));
1957 EnsureSpace ensure_space(this);
1958 emit_optional_rex_32(adr);
1959 emit(0xDB);
1960 emit_operand(1, adr);
1961 }
1962
1963
fisttp_d(const Operand & adr)1964 void Assembler::fisttp_d(const Operand& adr) {
1965 DCHECK(IsEnabled(SSE3));
1966 EnsureSpace ensure_space(this);
1967 emit_optional_rex_32(adr);
1968 emit(0xDD);
1969 emit_operand(1, adr);
1970 }
1971
1972
fist_s(const Operand & adr)1973 void Assembler::fist_s(const Operand& adr) {
1974 EnsureSpace ensure_space(this);
1975 emit_optional_rex_32(adr);
1976 emit(0xDB);
1977 emit_operand(2, adr);
1978 }
1979
1980
fistp_d(const Operand & adr)1981 void Assembler::fistp_d(const Operand& adr) {
1982 EnsureSpace ensure_space(this);
1983 emit_optional_rex_32(adr);
1984 emit(0xDF);
1985 emit_operand(7, adr);
1986 }
1987
1988
fabs()1989 void Assembler::fabs() {
1990 EnsureSpace ensure_space(this);
1991 emit(0xD9);
1992 emit(0xE1);
1993 }
1994
1995
fchs()1996 void Assembler::fchs() {
1997 EnsureSpace ensure_space(this);
1998 emit(0xD9);
1999 emit(0xE0);
2000 }
2001
2002
fcos()2003 void Assembler::fcos() {
2004 EnsureSpace ensure_space(this);
2005 emit(0xD9);
2006 emit(0xFF);
2007 }
2008
2009
fsin()2010 void Assembler::fsin() {
2011 EnsureSpace ensure_space(this);
2012 emit(0xD9);
2013 emit(0xFE);
2014 }
2015
2016
fptan()2017 void Assembler::fptan() {
2018 EnsureSpace ensure_space(this);
2019 emit(0xD9);
2020 emit(0xF2);
2021 }
2022
2023
fyl2x()2024 void Assembler::fyl2x() {
2025 EnsureSpace ensure_space(this);
2026 emit(0xD9);
2027 emit(0xF1);
2028 }
2029
2030
f2xm1()2031 void Assembler::f2xm1() {
2032 EnsureSpace ensure_space(this);
2033 emit(0xD9);
2034 emit(0xF0);
2035 }
2036
2037
fscale()2038 void Assembler::fscale() {
2039 EnsureSpace ensure_space(this);
2040 emit(0xD9);
2041 emit(0xFD);
2042 }
2043
2044
fninit()2045 void Assembler::fninit() {
2046 EnsureSpace ensure_space(this);
2047 emit(0xDB);
2048 emit(0xE3);
2049 }
2050
2051
fadd(int i)2052 void Assembler::fadd(int i) {
2053 EnsureSpace ensure_space(this);
2054 emit_farith(0xDC, 0xC0, i);
2055 }
2056
2057
fsub(int i)2058 void Assembler::fsub(int i) {
2059 EnsureSpace ensure_space(this);
2060 emit_farith(0xDC, 0xE8, i);
2061 }
2062
2063
fisub_s(const Operand & adr)2064 void Assembler::fisub_s(const Operand& adr) {
2065 EnsureSpace ensure_space(this);
2066 emit_optional_rex_32(adr);
2067 emit(0xDA);
2068 emit_operand(4, adr);
2069 }
2070
2071
fmul(int i)2072 void Assembler::fmul(int i) {
2073 EnsureSpace ensure_space(this);
2074 emit_farith(0xDC, 0xC8, i);
2075 }
2076
2077
fdiv(int i)2078 void Assembler::fdiv(int i) {
2079 EnsureSpace ensure_space(this);
2080 emit_farith(0xDC, 0xF8, i);
2081 }
2082
2083
faddp(int i)2084 void Assembler::faddp(int i) {
2085 EnsureSpace ensure_space(this);
2086 emit_farith(0xDE, 0xC0, i);
2087 }
2088
2089
fsubp(int i)2090 void Assembler::fsubp(int i) {
2091 EnsureSpace ensure_space(this);
2092 emit_farith(0xDE, 0xE8, i);
2093 }
2094
2095
fsubrp(int i)2096 void Assembler::fsubrp(int i) {
2097 EnsureSpace ensure_space(this);
2098 emit_farith(0xDE, 0xE0, i);
2099 }
2100
2101
fmulp(int i)2102 void Assembler::fmulp(int i) {
2103 EnsureSpace ensure_space(this);
2104 emit_farith(0xDE, 0xC8, i);
2105 }
2106
2107
fdivp(int i)2108 void Assembler::fdivp(int i) {
2109 EnsureSpace ensure_space(this);
2110 emit_farith(0xDE, 0xF8, i);
2111 }
2112
2113
fprem()2114 void Assembler::fprem() {
2115 EnsureSpace ensure_space(this);
2116 emit(0xD9);
2117 emit(0xF8);
2118 }
2119
2120
fprem1()2121 void Assembler::fprem1() {
2122 EnsureSpace ensure_space(this);
2123 emit(0xD9);
2124 emit(0xF5);
2125 }
2126
2127
fxch(int i)2128 void Assembler::fxch(int i) {
2129 EnsureSpace ensure_space(this);
2130 emit_farith(0xD9, 0xC8, i);
2131 }
2132
2133
fincstp()2134 void Assembler::fincstp() {
2135 EnsureSpace ensure_space(this);
2136 emit(0xD9);
2137 emit(0xF7);
2138 }
2139
2140
ffree(int i)2141 void Assembler::ffree(int i) {
2142 EnsureSpace ensure_space(this);
2143 emit_farith(0xDD, 0xC0, i);
2144 }
2145
2146
ftst()2147 void Assembler::ftst() {
2148 EnsureSpace ensure_space(this);
2149 emit(0xD9);
2150 emit(0xE4);
2151 }
2152
2153
fucomp(int i)2154 void Assembler::fucomp(int i) {
2155 EnsureSpace ensure_space(this);
2156 emit_farith(0xDD, 0xE8, i);
2157 }
2158
2159
fucompp()2160 void Assembler::fucompp() {
2161 EnsureSpace ensure_space(this);
2162 emit(0xDA);
2163 emit(0xE9);
2164 }
2165
2166
fucomi(int i)2167 void Assembler::fucomi(int i) {
2168 EnsureSpace ensure_space(this);
2169 emit(0xDB);
2170 emit(0xE8 + i);
2171 }
2172
2173
fucomip()2174 void Assembler::fucomip() {
2175 EnsureSpace ensure_space(this);
2176 emit(0xDF);
2177 emit(0xE9);
2178 }
2179
2180
fcompp()2181 void Assembler::fcompp() {
2182 EnsureSpace ensure_space(this);
2183 emit(0xDE);
2184 emit(0xD9);
2185 }
2186
2187
fnstsw_ax()2188 void Assembler::fnstsw_ax() {
2189 EnsureSpace ensure_space(this);
2190 emit(0xDF);
2191 emit(0xE0);
2192 }
2193
2194
fwait()2195 void Assembler::fwait() {
2196 EnsureSpace ensure_space(this);
2197 emit(0x9B);
2198 }
2199
2200
frndint()2201 void Assembler::frndint() {
2202 EnsureSpace ensure_space(this);
2203 emit(0xD9);
2204 emit(0xFC);
2205 }
2206
2207
fnclex()2208 void Assembler::fnclex() {
2209 EnsureSpace ensure_space(this);
2210 emit(0xDB);
2211 emit(0xE2);
2212 }
2213
2214
sahf()2215 void Assembler::sahf() {
2216 // TODO(X64): Test for presence. Not all 64-bit intel CPU's have sahf
2217 // in 64-bit mode. Test CpuID.
2218 DCHECK(IsEnabled(SAHF));
2219 EnsureSpace ensure_space(this);
2220 emit(0x9E);
2221 }
2222
2223
emit_farith(int b1,int b2,int i)2224 void Assembler::emit_farith(int b1, int b2, int i) {
2225 DCHECK(is_uint8(b1) && is_uint8(b2)); // wrong opcode
2226 DCHECK(is_uint3(i)); // illegal stack offset
2227 emit(b1);
2228 emit(b2 + i);
2229 }
2230
2231
2232 // SSE operations.
2233
andps(XMMRegister dst,XMMRegister src)2234 void Assembler::andps(XMMRegister dst, XMMRegister src) {
2235 EnsureSpace ensure_space(this);
2236 emit_optional_rex_32(dst, src);
2237 emit(0x0F);
2238 emit(0x54);
2239 emit_sse_operand(dst, src);
2240 }
2241
2242
andps(XMMRegister dst,const Operand & src)2243 void Assembler::andps(XMMRegister dst, const Operand& src) {
2244 EnsureSpace ensure_space(this);
2245 emit_optional_rex_32(dst, src);
2246 emit(0x0F);
2247 emit(0x54);
2248 emit_sse_operand(dst, src);
2249 }
2250
2251
orps(XMMRegister dst,XMMRegister src)2252 void Assembler::orps(XMMRegister dst, XMMRegister src) {
2253 EnsureSpace ensure_space(this);
2254 emit_optional_rex_32(dst, src);
2255 emit(0x0F);
2256 emit(0x56);
2257 emit_sse_operand(dst, src);
2258 }
2259
2260
orps(XMMRegister dst,const Operand & src)2261 void Assembler::orps(XMMRegister dst, const Operand& src) {
2262 EnsureSpace ensure_space(this);
2263 emit_optional_rex_32(dst, src);
2264 emit(0x0F);
2265 emit(0x56);
2266 emit_sse_operand(dst, src);
2267 }
2268
2269
xorps(XMMRegister dst,XMMRegister src)2270 void Assembler::xorps(XMMRegister dst, XMMRegister src) {
2271 EnsureSpace ensure_space(this);
2272 emit_optional_rex_32(dst, src);
2273 emit(0x0F);
2274 emit(0x57);
2275 emit_sse_operand(dst, src);
2276 }
2277
2278
xorps(XMMRegister dst,const Operand & src)2279 void Assembler::xorps(XMMRegister dst, const Operand& src) {
2280 EnsureSpace ensure_space(this);
2281 emit_optional_rex_32(dst, src);
2282 emit(0x0F);
2283 emit(0x57);
2284 emit_sse_operand(dst, src);
2285 }
2286
2287
addps(XMMRegister dst,XMMRegister src)2288 void Assembler::addps(XMMRegister dst, XMMRegister src) {
2289 EnsureSpace ensure_space(this);
2290 emit_optional_rex_32(dst, src);
2291 emit(0x0F);
2292 emit(0x58);
2293 emit_sse_operand(dst, src);
2294 }
2295
2296
addps(XMMRegister dst,const Operand & src)2297 void Assembler::addps(XMMRegister dst, const Operand& src) {
2298 EnsureSpace ensure_space(this);
2299 emit_optional_rex_32(dst, src);
2300 emit(0x0F);
2301 emit(0x58);
2302 emit_sse_operand(dst, src);
2303 }
2304
2305
subps(XMMRegister dst,XMMRegister src)2306 void Assembler::subps(XMMRegister dst, XMMRegister src) {
2307 EnsureSpace ensure_space(this);
2308 emit_optional_rex_32(dst, src);
2309 emit(0x0F);
2310 emit(0x5C);
2311 emit_sse_operand(dst, src);
2312 }
2313
2314
subps(XMMRegister dst,const Operand & src)2315 void Assembler::subps(XMMRegister dst, const Operand& src) {
2316 EnsureSpace ensure_space(this);
2317 emit_optional_rex_32(dst, src);
2318 emit(0x0F);
2319 emit(0x5C);
2320 emit_sse_operand(dst, src);
2321 }
2322
2323
mulps(XMMRegister dst,XMMRegister src)2324 void Assembler::mulps(XMMRegister dst, XMMRegister src) {
2325 EnsureSpace ensure_space(this);
2326 emit_optional_rex_32(dst, src);
2327 emit(0x0F);
2328 emit(0x59);
2329 emit_sse_operand(dst, src);
2330 }
2331
2332
mulps(XMMRegister dst,const Operand & src)2333 void Assembler::mulps(XMMRegister dst, const Operand& src) {
2334 EnsureSpace ensure_space(this);
2335 emit_optional_rex_32(dst, src);
2336 emit(0x0F);
2337 emit(0x59);
2338 emit_sse_operand(dst, src);
2339 }
2340
2341
divps(XMMRegister dst,XMMRegister src)2342 void Assembler::divps(XMMRegister dst, XMMRegister src) {
2343 EnsureSpace ensure_space(this);
2344 emit_optional_rex_32(dst, src);
2345 emit(0x0F);
2346 emit(0x5E);
2347 emit_sse_operand(dst, src);
2348 }
2349
2350
divps(XMMRegister dst,const Operand & src)2351 void Assembler::divps(XMMRegister dst, const Operand& src) {
2352 EnsureSpace ensure_space(this);
2353 emit_optional_rex_32(dst, src);
2354 emit(0x0F);
2355 emit(0x5E);
2356 emit_sse_operand(dst, src);
2357 }
2358
2359
2360 // SSE 2 operations.
2361
movd(XMMRegister dst,Register src)2362 void Assembler::movd(XMMRegister dst, Register src) {
2363 EnsureSpace ensure_space(this);
2364 emit(0x66);
2365 emit_optional_rex_32(dst, src);
2366 emit(0x0F);
2367 emit(0x6E);
2368 emit_sse_operand(dst, src);
2369 }
2370
2371
movd(Register dst,XMMRegister src)2372 void Assembler::movd(Register dst, XMMRegister src) {
2373 EnsureSpace ensure_space(this);
2374 emit(0x66);
2375 emit_optional_rex_32(src, dst);
2376 emit(0x0F);
2377 emit(0x7E);
2378 emit_sse_operand(src, dst);
2379 }
2380
2381
movq(XMMRegister dst,Register src)2382 void Assembler::movq(XMMRegister dst, Register src) {
2383 EnsureSpace ensure_space(this);
2384 emit(0x66);
2385 emit_rex_64(dst, src);
2386 emit(0x0F);
2387 emit(0x6E);
2388 emit_sse_operand(dst, src);
2389 }
2390
2391
movq(Register dst,XMMRegister src)2392 void Assembler::movq(Register dst, XMMRegister src) {
2393 EnsureSpace ensure_space(this);
2394 emit(0x66);
2395 emit_rex_64(src, dst);
2396 emit(0x0F);
2397 emit(0x7E);
2398 emit_sse_operand(src, dst);
2399 }
2400
2401
movq(XMMRegister dst,XMMRegister src)2402 void Assembler::movq(XMMRegister dst, XMMRegister src) {
2403 EnsureSpace ensure_space(this);
2404 if (dst.low_bits() == 4) {
2405 // Avoid unnecessary SIB byte.
2406 emit(0xf3);
2407 emit_optional_rex_32(dst, src);
2408 emit(0x0F);
2409 emit(0x7e);
2410 emit_sse_operand(dst, src);
2411 } else {
2412 emit(0x66);
2413 emit_optional_rex_32(src, dst);
2414 emit(0x0F);
2415 emit(0xD6);
2416 emit_sse_operand(src, dst);
2417 }
2418 }
2419
2420
movdqa(const Operand & dst,XMMRegister src)2421 void Assembler::movdqa(const Operand& dst, XMMRegister src) {
2422 EnsureSpace ensure_space(this);
2423 emit(0x66);
2424 emit_rex_64(src, dst);
2425 emit(0x0F);
2426 emit(0x7F);
2427 emit_sse_operand(src, dst);
2428 }
2429
2430
movdqa(XMMRegister dst,const Operand & src)2431 void Assembler::movdqa(XMMRegister dst, const Operand& src) {
2432 EnsureSpace ensure_space(this);
2433 emit(0x66);
2434 emit_rex_64(dst, src);
2435 emit(0x0F);
2436 emit(0x6F);
2437 emit_sse_operand(dst, src);
2438 }
2439
2440
movdqu(const Operand & dst,XMMRegister src)2441 void Assembler::movdqu(const Operand& dst, XMMRegister src) {
2442 EnsureSpace ensure_space(this);
2443 emit(0xF3);
2444 emit_rex_64(src, dst);
2445 emit(0x0F);
2446 emit(0x7F);
2447 emit_sse_operand(src, dst);
2448 }
2449
2450
movdqu(XMMRegister dst,const Operand & src)2451 void Assembler::movdqu(XMMRegister dst, const Operand& src) {
2452 EnsureSpace ensure_space(this);
2453 emit(0xF3);
2454 emit_rex_64(dst, src);
2455 emit(0x0F);
2456 emit(0x6F);
2457 emit_sse_operand(dst, src);
2458 }
2459
2460
extractps(Register dst,XMMRegister src,byte imm8)2461 void Assembler::extractps(Register dst, XMMRegister src, byte imm8) {
2462 DCHECK(IsEnabled(SSE4_1));
2463 DCHECK(is_uint8(imm8));
2464 EnsureSpace ensure_space(this);
2465 emit(0x66);
2466 emit_optional_rex_32(src, dst);
2467 emit(0x0F);
2468 emit(0x3A);
2469 emit(0x17);
2470 emit_sse_operand(src, dst);
2471 emit(imm8);
2472 }
2473
2474
movsd(const Operand & dst,XMMRegister src)2475 void Assembler::movsd(const Operand& dst, XMMRegister src) {
2476 EnsureSpace ensure_space(this);
2477 emit(0xF2); // double
2478 emit_optional_rex_32(src, dst);
2479 emit(0x0F);
2480 emit(0x11); // store
2481 emit_sse_operand(src, dst);
2482 }
2483
2484
movsd(XMMRegister dst,XMMRegister src)2485 void Assembler::movsd(XMMRegister dst, XMMRegister src) {
2486 EnsureSpace ensure_space(this);
2487 emit(0xF2); // double
2488 emit_optional_rex_32(dst, src);
2489 emit(0x0F);
2490 emit(0x10); // load
2491 emit_sse_operand(dst, src);
2492 }
2493
2494
movsd(XMMRegister dst,const Operand & src)2495 void Assembler::movsd(XMMRegister dst, const Operand& src) {
2496 EnsureSpace ensure_space(this);
2497 emit(0xF2); // double
2498 emit_optional_rex_32(dst, src);
2499 emit(0x0F);
2500 emit(0x10); // load
2501 emit_sse_operand(dst, src);
2502 }
2503
2504
movaps(XMMRegister dst,XMMRegister src)2505 void Assembler::movaps(XMMRegister dst, XMMRegister src) {
2506 EnsureSpace ensure_space(this);
2507 if (src.low_bits() == 4) {
2508 // Try to avoid an unnecessary SIB byte.
2509 emit_optional_rex_32(src, dst);
2510 emit(0x0F);
2511 emit(0x29);
2512 emit_sse_operand(src, dst);
2513 } else {
2514 emit_optional_rex_32(dst, src);
2515 emit(0x0F);
2516 emit(0x28);
2517 emit_sse_operand(dst, src);
2518 }
2519 }
2520
2521
shufps(XMMRegister dst,XMMRegister src,byte imm8)2522 void Assembler::shufps(XMMRegister dst, XMMRegister src, byte imm8) {
2523 DCHECK(is_uint8(imm8));
2524 EnsureSpace ensure_space(this);
2525 emit_optional_rex_32(src, dst);
2526 emit(0x0F);
2527 emit(0xC6);
2528 emit_sse_operand(dst, src);
2529 emit(imm8);
2530 }
2531
2532
movapd(XMMRegister dst,XMMRegister src)2533 void Assembler::movapd(XMMRegister dst, XMMRegister src) {
2534 EnsureSpace ensure_space(this);
2535 if (src.low_bits() == 4) {
2536 // Try to avoid an unnecessary SIB byte.
2537 emit(0x66);
2538 emit_optional_rex_32(src, dst);
2539 emit(0x0F);
2540 emit(0x29);
2541 emit_sse_operand(src, dst);
2542 } else {
2543 emit(0x66);
2544 emit_optional_rex_32(dst, src);
2545 emit(0x0F);
2546 emit(0x28);
2547 emit_sse_operand(dst, src);
2548 }
2549 }
2550
2551
movss(XMMRegister dst,const Operand & src)2552 void Assembler::movss(XMMRegister dst, const Operand& src) {
2553 EnsureSpace ensure_space(this);
2554 emit(0xF3); // single
2555 emit_optional_rex_32(dst, src);
2556 emit(0x0F);
2557 emit(0x10); // load
2558 emit_sse_operand(dst, src);
2559 }
2560
2561
movss(const Operand & src,XMMRegister dst)2562 void Assembler::movss(const Operand& src, XMMRegister dst) {
2563 EnsureSpace ensure_space(this);
2564 emit(0xF3); // single
2565 emit_optional_rex_32(dst, src);
2566 emit(0x0F);
2567 emit(0x11); // store
2568 emit_sse_operand(dst, src);
2569 }
2570
2571
psllq(XMMRegister reg,byte imm8)2572 void Assembler::psllq(XMMRegister reg, byte imm8) {
2573 EnsureSpace ensure_space(this);
2574 emit(0x66);
2575 emit(0x0F);
2576 emit(0x73);
2577 emit_sse_operand(rsi, reg); // rsi == 6
2578 emit(imm8);
2579 }
2580
2581
cvttss2si(Register dst,const Operand & src)2582 void Assembler::cvttss2si(Register dst, const Operand& src) {
2583 EnsureSpace ensure_space(this);
2584 emit(0xF3);
2585 emit_optional_rex_32(dst, src);
2586 emit(0x0F);
2587 emit(0x2C);
2588 emit_operand(dst, src);
2589 }
2590
2591
cvttss2si(Register dst,XMMRegister src)2592 void Assembler::cvttss2si(Register dst, XMMRegister src) {
2593 EnsureSpace ensure_space(this);
2594 emit(0xF3);
2595 emit_optional_rex_32(dst, src);
2596 emit(0x0F);
2597 emit(0x2C);
2598 emit_sse_operand(dst, src);
2599 }
2600
2601
cvttsd2si(Register dst,const Operand & src)2602 void Assembler::cvttsd2si(Register dst, const Operand& src) {
2603 EnsureSpace ensure_space(this);
2604 emit(0xF2);
2605 emit_optional_rex_32(dst, src);
2606 emit(0x0F);
2607 emit(0x2C);
2608 emit_operand(dst, src);
2609 }
2610
2611
cvttsd2si(Register dst,XMMRegister src)2612 void Assembler::cvttsd2si(Register dst, XMMRegister src) {
2613 EnsureSpace ensure_space(this);
2614 emit(0xF2);
2615 emit_optional_rex_32(dst, src);
2616 emit(0x0F);
2617 emit(0x2C);
2618 emit_sse_operand(dst, src);
2619 }
2620
2621
cvttsd2siq(Register dst,XMMRegister src)2622 void Assembler::cvttsd2siq(Register dst, XMMRegister src) {
2623 EnsureSpace ensure_space(this);
2624 emit(0xF2);
2625 emit_rex_64(dst, src);
2626 emit(0x0F);
2627 emit(0x2C);
2628 emit_sse_operand(dst, src);
2629 }
2630
2631
cvttsd2siq(Register dst,const Operand & src)2632 void Assembler::cvttsd2siq(Register dst, const Operand& src) {
2633 EnsureSpace ensure_space(this);
2634 emit(0xF2);
2635 emit_rex_64(dst, src);
2636 emit(0x0F);
2637 emit(0x2C);
2638 emit_sse_operand(dst, src);
2639 }
2640
2641
cvtlsi2sd(XMMRegister dst,const Operand & src)2642 void Assembler::cvtlsi2sd(XMMRegister dst, const Operand& src) {
2643 EnsureSpace ensure_space(this);
2644 emit(0xF2);
2645 emit_optional_rex_32(dst, src);
2646 emit(0x0F);
2647 emit(0x2A);
2648 emit_sse_operand(dst, src);
2649 }
2650
2651
cvtlsi2sd(XMMRegister dst,Register src)2652 void Assembler::cvtlsi2sd(XMMRegister dst, Register src) {
2653 EnsureSpace ensure_space(this);
2654 emit(0xF2);
2655 emit_optional_rex_32(dst, src);
2656 emit(0x0F);
2657 emit(0x2A);
2658 emit_sse_operand(dst, src);
2659 }
2660
2661
cvtlsi2ss(XMMRegister dst,Register src)2662 void Assembler::cvtlsi2ss(XMMRegister dst, Register src) {
2663 EnsureSpace ensure_space(this);
2664 emit(0xF3);
2665 emit_optional_rex_32(dst, src);
2666 emit(0x0F);
2667 emit(0x2A);
2668 emit_sse_operand(dst, src);
2669 }
2670
2671
cvtqsi2sd(XMMRegister dst,Register src)2672 void Assembler::cvtqsi2sd(XMMRegister dst, Register src) {
2673 EnsureSpace ensure_space(this);
2674 emit(0xF2);
2675 emit_rex_64(dst, src);
2676 emit(0x0F);
2677 emit(0x2A);
2678 emit_sse_operand(dst, src);
2679 }
2680
2681
cvtss2sd(XMMRegister dst,XMMRegister src)2682 void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) {
2683 EnsureSpace ensure_space(this);
2684 emit(0xF3);
2685 emit_optional_rex_32(dst, src);
2686 emit(0x0F);
2687 emit(0x5A);
2688 emit_sse_operand(dst, src);
2689 }
2690
2691
cvtss2sd(XMMRegister dst,const Operand & src)2692 void Assembler::cvtss2sd(XMMRegister dst, const Operand& src) {
2693 EnsureSpace ensure_space(this);
2694 emit(0xF3);
2695 emit_optional_rex_32(dst, src);
2696 emit(0x0F);
2697 emit(0x5A);
2698 emit_sse_operand(dst, src);
2699 }
2700
2701
cvtsd2ss(XMMRegister dst,XMMRegister src)2702 void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) {
2703 EnsureSpace ensure_space(this);
2704 emit(0xF2);
2705 emit_optional_rex_32(dst, src);
2706 emit(0x0F);
2707 emit(0x5A);
2708 emit_sse_operand(dst, src);
2709 }
2710
2711
cvtsd2si(Register dst,XMMRegister src)2712 void Assembler::cvtsd2si(Register dst, XMMRegister src) {
2713 EnsureSpace ensure_space(this);
2714 emit(0xF2);
2715 emit_optional_rex_32(dst, src);
2716 emit(0x0F);
2717 emit(0x2D);
2718 emit_sse_operand(dst, src);
2719 }
2720
2721
cvtsd2siq(Register dst,XMMRegister src)2722 void Assembler::cvtsd2siq(Register dst, XMMRegister src) {
2723 EnsureSpace ensure_space(this);
2724 emit(0xF2);
2725 emit_rex_64(dst, src);
2726 emit(0x0F);
2727 emit(0x2D);
2728 emit_sse_operand(dst, src);
2729 }
2730
2731
addsd(XMMRegister dst,XMMRegister src)2732 void Assembler::addsd(XMMRegister dst, XMMRegister src) {
2733 EnsureSpace ensure_space(this);
2734 emit(0xF2);
2735 emit_optional_rex_32(dst, src);
2736 emit(0x0F);
2737 emit(0x58);
2738 emit_sse_operand(dst, src);
2739 }
2740
2741
addsd(XMMRegister dst,const Operand & src)2742 void Assembler::addsd(XMMRegister dst, const Operand& src) {
2743 EnsureSpace ensure_space(this);
2744 emit(0xF2);
2745 emit_optional_rex_32(dst, src);
2746 emit(0x0F);
2747 emit(0x58);
2748 emit_sse_operand(dst, src);
2749 }
2750
2751
mulsd(XMMRegister dst,XMMRegister src)2752 void Assembler::mulsd(XMMRegister dst, XMMRegister src) {
2753 EnsureSpace ensure_space(this);
2754 emit(0xF2);
2755 emit_optional_rex_32(dst, src);
2756 emit(0x0F);
2757 emit(0x59);
2758 emit_sse_operand(dst, src);
2759 }
2760
2761
mulsd(XMMRegister dst,const Operand & src)2762 void Assembler::mulsd(XMMRegister dst, const Operand& src) {
2763 EnsureSpace ensure_space(this);
2764 emit(0xF2);
2765 emit_optional_rex_32(dst, src);
2766 emit(0x0F);
2767 emit(0x59);
2768 emit_sse_operand(dst, src);
2769 }
2770
2771
subsd(XMMRegister dst,XMMRegister src)2772 void Assembler::subsd(XMMRegister dst, XMMRegister src) {
2773 EnsureSpace ensure_space(this);
2774 emit(0xF2);
2775 emit_optional_rex_32(dst, src);
2776 emit(0x0F);
2777 emit(0x5C);
2778 emit_sse_operand(dst, src);
2779 }
2780
2781
divsd(XMMRegister dst,XMMRegister src)2782 void Assembler::divsd(XMMRegister dst, XMMRegister src) {
2783 EnsureSpace ensure_space(this);
2784 emit(0xF2);
2785 emit_optional_rex_32(dst, src);
2786 emit(0x0F);
2787 emit(0x5E);
2788 emit_sse_operand(dst, src);
2789 }
2790
2791
andpd(XMMRegister dst,XMMRegister src)2792 void Assembler::andpd(XMMRegister dst, XMMRegister src) {
2793 EnsureSpace ensure_space(this);
2794 emit(0x66);
2795 emit_optional_rex_32(dst, src);
2796 emit(0x0F);
2797 emit(0x54);
2798 emit_sse_operand(dst, src);
2799 }
2800
2801
orpd(XMMRegister dst,XMMRegister src)2802 void Assembler::orpd(XMMRegister dst, XMMRegister src) {
2803 EnsureSpace ensure_space(this);
2804 emit(0x66);
2805 emit_optional_rex_32(dst, src);
2806 emit(0x0F);
2807 emit(0x56);
2808 emit_sse_operand(dst, src);
2809 }
2810
2811
xorpd(XMMRegister dst,XMMRegister src)2812 void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
2813 EnsureSpace ensure_space(this);
2814 emit(0x66);
2815 emit_optional_rex_32(dst, src);
2816 emit(0x0F);
2817 emit(0x57);
2818 emit_sse_operand(dst, src);
2819 }
2820
2821
sqrtsd(XMMRegister dst,XMMRegister src)2822 void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) {
2823 EnsureSpace ensure_space(this);
2824 emit(0xF2);
2825 emit_optional_rex_32(dst, src);
2826 emit(0x0F);
2827 emit(0x51);
2828 emit_sse_operand(dst, src);
2829 }
2830
2831
sqrtsd(XMMRegister dst,const Operand & src)2832 void Assembler::sqrtsd(XMMRegister dst, const Operand& src) {
2833 EnsureSpace ensure_space(this);
2834 emit(0xF2);
2835 emit_optional_rex_32(dst, src);
2836 emit(0x0F);
2837 emit(0x51);
2838 emit_sse_operand(dst, src);
2839 }
2840
2841
ucomisd(XMMRegister dst,XMMRegister src)2842 void Assembler::ucomisd(XMMRegister dst, XMMRegister src) {
2843 EnsureSpace ensure_space(this);
2844 emit(0x66);
2845 emit_optional_rex_32(dst, src);
2846 emit(0x0f);
2847 emit(0x2e);
2848 emit_sse_operand(dst, src);
2849 }
2850
2851
ucomisd(XMMRegister dst,const Operand & src)2852 void Assembler::ucomisd(XMMRegister dst, const Operand& src) {
2853 EnsureSpace ensure_space(this);
2854 emit(0x66);
2855 emit_optional_rex_32(dst, src);
2856 emit(0x0f);
2857 emit(0x2e);
2858 emit_sse_operand(dst, src);
2859 }
2860
2861
cmpltsd(XMMRegister dst,XMMRegister src)2862 void Assembler::cmpltsd(XMMRegister dst, XMMRegister src) {
2863 EnsureSpace ensure_space(this);
2864 emit(0xF2);
2865 emit_optional_rex_32(dst, src);
2866 emit(0x0F);
2867 emit(0xC2);
2868 emit_sse_operand(dst, src);
2869 emit(0x01); // LT == 1
2870 }
2871
2872
roundsd(XMMRegister dst,XMMRegister src,Assembler::RoundingMode mode)2873 void Assembler::roundsd(XMMRegister dst, XMMRegister src,
2874 Assembler::RoundingMode mode) {
2875 DCHECK(IsEnabled(SSE4_1));
2876 EnsureSpace ensure_space(this);
2877 emit(0x66);
2878 emit_optional_rex_32(dst, src);
2879 emit(0x0f);
2880 emit(0x3a);
2881 emit(0x0b);
2882 emit_sse_operand(dst, src);
2883 // Mask precision exeption.
2884 emit(static_cast<byte>(mode) | 0x8);
2885 }
2886
2887
movmskpd(Register dst,XMMRegister src)2888 void Assembler::movmskpd(Register dst, XMMRegister src) {
2889 EnsureSpace ensure_space(this);
2890 emit(0x66);
2891 emit_optional_rex_32(dst, src);
2892 emit(0x0f);
2893 emit(0x50);
2894 emit_sse_operand(dst, src);
2895 }
2896
2897
movmskps(Register dst,XMMRegister src)2898 void Assembler::movmskps(Register dst, XMMRegister src) {
2899 EnsureSpace ensure_space(this);
2900 emit_optional_rex_32(dst, src);
2901 emit(0x0f);
2902 emit(0x50);
2903 emit_sse_operand(dst, src);
2904 }
2905
2906
emit_sse_operand(XMMRegister reg,const Operand & adr)2907 void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) {
2908 Register ireg = { reg.code() };
2909 emit_operand(ireg, adr);
2910 }
2911
2912
emit_sse_operand(Register reg,const Operand & adr)2913 void Assembler::emit_sse_operand(Register reg, const Operand& adr) {
2914 Register ireg = {reg.code()};
2915 emit_operand(ireg, adr);
2916 }
2917
2918
emit_sse_operand(XMMRegister dst,XMMRegister src)2919 void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) {
2920 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
2921 }
2922
2923
emit_sse_operand(XMMRegister dst,Register src)2924 void Assembler::emit_sse_operand(XMMRegister dst, Register src) {
2925 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
2926 }
2927
2928
emit_sse_operand(Register dst,XMMRegister src)2929 void Assembler::emit_sse_operand(Register dst, XMMRegister src) {
2930 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
2931 }
2932
2933
db(uint8_t data)2934 void Assembler::db(uint8_t data) {
2935 EnsureSpace ensure_space(this);
2936 emit(data);
2937 }
2938
2939
dd(uint32_t data)2940 void Assembler::dd(uint32_t data) {
2941 EnsureSpace ensure_space(this);
2942 emitl(data);
2943 }
2944
2945
2946 // Relocation information implementations.
2947
RecordRelocInfo(RelocInfo::Mode rmode,intptr_t data)2948 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
2949 DCHECK(!RelocInfo::IsNone(rmode));
2950 // Don't record external references unless the heap will be serialized.
2951 if (rmode == RelocInfo::EXTERNAL_REFERENCE &&
2952 !serializer_enabled() && !emit_debug_code()) {
2953 return;
2954 } else if (rmode == RelocInfo::CODE_AGE_SEQUENCE) {
2955 // Don't record psuedo relocation info for code age sequence mode.
2956 return;
2957 }
2958 RelocInfo rinfo(pc_, rmode, data, NULL);
2959 reloc_info_writer.Write(&rinfo);
2960 }
2961
2962
RecordJSReturn()2963 void Assembler::RecordJSReturn() {
2964 positions_recorder()->WriteRecordedPositions();
2965 EnsureSpace ensure_space(this);
2966 RecordRelocInfo(RelocInfo::JS_RETURN);
2967 }
2968
2969
RecordDebugBreakSlot()2970 void Assembler::RecordDebugBreakSlot() {
2971 positions_recorder()->WriteRecordedPositions();
2972 EnsureSpace ensure_space(this);
2973 RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
2974 }
2975
2976
RecordComment(const char * msg,bool force)2977 void Assembler::RecordComment(const char* msg, bool force) {
2978 if (FLAG_code_comments || force) {
2979 EnsureSpace ensure_space(this);
2980 RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg));
2981 }
2982 }
2983
2984
NewConstantPool(Isolate * isolate)2985 Handle<ConstantPoolArray> Assembler::NewConstantPool(Isolate* isolate) {
2986 // No out-of-line constant pool support.
2987 DCHECK(!FLAG_enable_ool_constant_pool);
2988 return isolate->factory()->empty_constant_pool_array();
2989 }
2990
2991
PopulateConstantPool(ConstantPoolArray * constant_pool)2992 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
2993 // No out-of-line constant pool support.
2994 DCHECK(!FLAG_enable_ool_constant_pool);
2995 return;
2996 }
2997
2998
2999 const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask |
3000 1 << RelocInfo::RUNTIME_ENTRY |
3001 1 << RelocInfo::INTERNAL_REFERENCE |
3002 1 << RelocInfo::CODE_AGE_SEQUENCE;
3003
3004
IsCodedSpecially()3005 bool RelocInfo::IsCodedSpecially() {
3006 // The deserializer needs to know whether a pointer is specially coded. Being
3007 // specially coded on x64 means that it is a relative 32 bit address, as used
3008 // by branch instructions.
3009 return (1 << rmode_) & kApplyMask;
3010 }
3011
3012
IsInConstantPool()3013 bool RelocInfo::IsInConstantPool() {
3014 return false;
3015 }
3016
3017
3018 } } // namespace v8::internal
3019
3020 #endif // V8_TARGET_ARCH_X64
3021