30 #if defined(V8_TARGET_ARCH_X64)
43 bool CpuFeatures::initialized_ =
false;
45 uint64_t CpuFeatures::supported_ = CpuFeatures::kDefaultCpuFeatures;
46 uint64_t CpuFeatures::found_by_runtime_probing_ = 0;
50 ASSERT(supported_ == CpuFeatures::kDefaultCpuFeatures);
54 supported_ = kDefaultCpuFeatures;
60 const int kBufferSize = 4 *
KB;
61 VirtualMemory* memory =
new VirtualMemory(kBufferSize);
62 if (!memory->IsReserved()) {
66 ASSERT(memory->size() >=
static_cast<size_t>(kBufferSize));
67 if (!memory->Commit(memory->address(), kBufferSize,
true)) {
72 Assembler assm(
NULL, memory->
address(), kBufferSize);
86 __ xor_(
rax, Immediate(0x200000));
102 __ movl(
rax, Immediate(1));
103 supported_ = kDefaultCpuFeatures | (1 <<
CPUID);
104 { Scope fscope(
CPUID);
108 __ shl(
rcx, Immediate(32));
115 supported_ = kDefaultCpuFeatures;
119 __ movl(
rax, Immediate(1));
136 typedef uint64_t (*
F0)();
137 F0 probe = FUNCTION_CAST<F0>(
reinterpret_cast<Address>(memory->address()));
138 supported_ = probe();
139 found_by_runtime_probing_ = supported_;
140 found_by_runtime_probing_ &= ~kDefaultCpuFeatures;
142 supported_ |= os_guarantees;
143 found_by_runtime_probing_ &= ~os_guarantees;
158 void RelocInfo::PatchCodeWithCall(
Address target,
int guard_bytes) {
161 static const int kCallCodeSize = 13;
162 int code_size = kCallCodeSize + guard_bytes;
165 CodePatcher patcher(pc_, code_size);
169 Label check_codesize;
170 patcher.masm()->bind(&check_codesize);
175 patcher.masm()->call(
r10);
179 patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize));
182 for (
int i = 0; i < guard_bytes; i++) {
183 patcher.masm()->int3();
190 for (
int i = 0; i < instruction_count; i++) {
191 *(pc_ + i) = *(instructions + i);
202 const int Register::kRegisterCodeByAllocationIndex[kNumAllocatableRegisters] = {
204 0, 3, 2, 1, 7, 8, 9, 11, 14, 15
207 const int Register::kAllocationIndexByRegisterCode[
kNumRegisters] = {
208 0, 3, 2, 1, -1, -1, -1, 4, 5, 6, -1, 7, -1, -1, 8, 9
215 Operand::Operand(Register base,
int32_t disp) : rex_(0) {
217 if (base.is(
rsp) || base.is(
r12)) {
222 if (disp == 0 && !base.is(
rbp) && !base.is(
r13)) {
234 Operand::Operand(Register base,
240 set_sib(scale, index, base);
241 if (disp == 0 && !base.is(
rbp) && !base.is(
r13)) {
255 Operand::Operand(Register index,
261 set_sib(scale, index,
rbp);
266 Operand::Operand(
const Operand& operand,
int32_t offset) {
267 ASSERT(operand.len_ >= 1);
269 byte modrm = operand.buf_[0];
271 bool has_sib = ((modrm & 0x07) == 0x04);
272 byte mode = modrm & 0xC0;
273 int disp_offset = has_sib ? 2 : 1;
274 int base_reg = (has_sib ? operand.buf_[1] : modrm) & 0x07;
277 bool is_baseless = (mode == 0) && (base_reg == 0x05);
279 if (mode == 0x80 || is_baseless) {
281 disp_value = *BitCast<const int32_t*>(&operand.buf_[disp_offset]);
282 }
else if (mode == 0x40) {
284 disp_value =
static_cast<signed char>(operand.buf_[disp_offset]);
288 ASSERT(offset >= 0 ? disp_value + offset > disp_value
289 : disp_value + offset < disp_value);
290 disp_value += offset;
292 if (!
is_int8(disp_value) || is_baseless) {
294 buf_[0] = (modrm & 0x3f) | (is_baseless ? 0x00 : 0x80);
295 len_ = disp_offset + 4;
297 }
else if (disp_value != 0 || (base_reg == 0x05)) {
299 buf_[0] = (modrm & 0x3f) | 0x40;
300 len_ = disp_offset + 1;
301 buf_[disp_offset] =
static_cast<byte>(disp_value);
304 buf_[0] = (modrm & 0x3f);
308 buf_[1] = operand.buf_[1];
313 bool Operand::AddressUsesRegister(Register reg)
const {
314 int code = reg.code();
315 ASSERT((buf_[0] & 0xC0) != 0xC0);
318 int base_code = buf_[0] & 0x07;
322 int index_code = ((buf_[1] >> 3) & 0x07) | ((rex_ & 0x02) << 2);
324 if (index_code !=
rsp.
code() && index_code == code)
return true;
326 base_code = (buf_[1] & 0x07) | ((rex_ & 0x01) << 3);
328 if (base_code ==
rbp.
code() && ((buf_[0] & 0xC0) == 0))
return false;
329 return code == base_code;
333 if (base_code ==
rbp.
code() && ((buf_[0] & 0xC0) == 0))
return false;
334 base_code |= ((rex_ & 0x01) << 3);
335 return code == base_code;
343 #ifdef GENERATED_CODE_COVERAGE
344 static void InitCoverageLog();
348 : AssemblerBase(arg_isolate),
350 positions_recorder_(this),
351 emit_debug_code_(FLAG_debug_code) {
352 if (buffer ==
NULL) {
358 buffer =
isolate()->assembler_spare_buffer();
362 if (buffer ==
NULL) {
363 buffer_ = NewArray<byte>(buffer_size);
365 buffer_ =
static_cast<byte*
>(buffer);
367 buffer_size_ = buffer_size;
372 buffer_ =
static_cast<byte*
>(buffer);
373 buffer_size_ = buffer_size;
382 memset(buffer_, 0xCC, buffer_size);
389 reloc_info_writer.Reposition(buffer_ + buffer_size, pc_);
392 #ifdef GENERATED_CODE_COVERAGE
403 isolate()->set_assembler_spare_buffer(buffer_);
414 ASSERT(pc_ <= reloc_info_writer.pos());
416 desc->buffer = buffer_;
417 desc->buffer_size = buffer_size_;
419 ASSERT(desc->instr_size > 0);
421 static_cast<int>((buffer_ + buffer_size_) - reloc_info_writer.pos());
428 int delta = (m - (
pc_offset() & (m - 1))) & (m - 1);
440 while (*a == 0x66) a++;
441 if (*a == 0x90)
return true;
442 if (a[0] == 0xf && a[1] == 0x1f)
return true;
447 void Assembler::bind_to(Label*
L,
int pos) {
450 if (L->is_linked()) {
451 int current = L->pos();
452 int next = long_at(current);
453 while (next != current) {
455 int imm32 = pos - (current +
sizeof(
int32_t));
456 long_at_put(current, imm32);
458 next = long_at(next);
461 int last_imm32 = pos - (current +
sizeof(
int32_t));
462 long_at_put(current, last_imm32);
464 while (L->is_near_linked()) {
465 int fixup_pos = L->near_link_pos();
467 static_cast<int>(*
reinterpret_cast<int8_t*
>(
addr_at(fixup_pos)));
468 ASSERT(offset_to_next <= 0);
469 int disp = pos - (fixup_pos +
sizeof(int8_t));
472 if (offset_to_next < 0) {
473 L->link_to(fixup_pos + offset_to_next, Label::kNear);
487 void Assembler::GrowBuffer() {
489 if (!own_buffer_)
FATAL(
"external code buffer is too small");
493 if (buffer_size_ < 4*
KB) {
494 desc.buffer_size = 4*
KB;
496 desc.buffer_size = 2*buffer_size_;
501 (desc.buffer_size >
HEAP->MaxOldGenerationSize())) {
506 desc.buffer = NewArray<byte>(desc.buffer_size);
509 static_cast<int>((buffer_ + buffer_size_) - (reloc_info_writer.pos()));
514 memset(desc.buffer, 0xCC, desc.buffer_size);
518 intptr_t pc_delta = desc.buffer - buffer_;
519 intptr_t rc_delta = (desc.buffer + desc.buffer_size) -
520 (buffer_ + buffer_size_);
521 memmove(desc.buffer, buffer_, desc.instr_size);
522 memmove(rc_delta + reloc_info_writer.pos(),
523 reloc_info_writer.pos(), desc.reloc_size);
529 isolate()->set_assembler_spare_buffer(buffer_);
533 buffer_ = desc.buffer;
534 buffer_size_ = desc.buffer_size;
536 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
537 reloc_info_writer.last_pc() + pc_delta);
540 for (RelocIterator it(desc); !it.done(); it.next()) {
541 RelocInfo::Mode rmode = it.rinfo()->rmode();
542 if (rmode == RelocInfo::INTERNAL_REFERENCE) {
543 intptr_t* p =
reinterpret_cast<intptr_t*
>(it.rinfo()->pc());
554 void Assembler::emit_operand(
int code,
const Operand& adr) {
556 const unsigned length = adr.len_;
560 ASSERT((adr.buf_[0] & 0x38) == 0);
561 pc_[0] = adr.buf_[0] | code << 3;
564 for (
unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i];
571 void Assembler::arithmetic_op(
byte opcode, Register reg,
const Operand& op) {
573 emit_rex_64(reg, op);
575 emit_operand(reg, op);
579 void Assembler::arithmetic_op(
byte opcode, Register reg, Register rm_reg) {
581 ASSERT((opcode & 0xC6) == 2);
582 if (rm_reg.low_bits() == 4) {
584 emit_rex_64(rm_reg, reg);
586 emit_modrm(rm_reg, reg);
588 emit_rex_64(reg, rm_reg);
590 emit_modrm(reg, rm_reg);
595 void Assembler::arithmetic_op_16(
byte opcode, Register reg, Register rm_reg) {
597 ASSERT((opcode & 0xC6) == 2);
598 if (rm_reg.low_bits() == 4) {
601 emit_optional_rex_32(rm_reg, reg);
603 emit_modrm(rm_reg, reg);
606 emit_optional_rex_32(reg, rm_reg);
608 emit_modrm(reg, rm_reg);
613 void Assembler::arithmetic_op_16(
byte opcode,
615 const Operand& rm_reg) {
618 emit_optional_rex_32(reg, rm_reg);
620 emit_operand(reg, rm_reg);
624 void Assembler::arithmetic_op_32(
byte opcode, Register reg, Register rm_reg) {
626 ASSERT((opcode & 0xC6) == 2);
627 if (rm_reg.low_bits() == 4) {
629 emit_optional_rex_32(rm_reg, reg);
631 emit_modrm(rm_reg, reg);
633 emit_optional_rex_32(reg, rm_reg);
635 emit_modrm(reg, rm_reg);
640 void Assembler::arithmetic_op_32(
byte opcode,
642 const Operand& rm_reg) {
644 emit_optional_rex_32(reg, rm_reg);
646 emit_operand(reg, rm_reg);
650 void Assembler::immediate_arithmetic_op(
byte subcode,
657 emit_modrm(subcode, dst);
659 }
else if (dst.is(
rax)) {
660 emit(0x05 | (subcode << 3));
664 emit_modrm(subcode, dst);
669 void Assembler::immediate_arithmetic_op(
byte subcode,
676 emit_operand(subcode, dst);
680 emit_operand(subcode, dst);
686 void Assembler::immediate_arithmetic_op_16(
byte subcode,
691 emit_optional_rex_32(dst);
694 emit_modrm(subcode, dst);
696 }
else if (dst.is(
rax)) {
697 emit(0x05 | (subcode << 3));
701 emit_modrm(subcode, dst);
707 void Assembler::immediate_arithmetic_op_16(
byte subcode,
712 emit_optional_rex_32(dst);
715 emit_operand(subcode, dst);
719 emit_operand(subcode, dst);
725 void Assembler::immediate_arithmetic_op_32(
byte subcode,
729 emit_optional_rex_32(dst);
732 emit_modrm(subcode, dst);
734 }
else if (dst.is(
rax)) {
735 emit(0x05 | (subcode << 3));
739 emit_modrm(subcode, dst);
745 void Assembler::immediate_arithmetic_op_32(
byte subcode,
749 emit_optional_rex_32(dst);
752 emit_operand(subcode, dst);
756 emit_operand(subcode, dst);
762 void Assembler::immediate_arithmetic_op_8(
byte subcode,
766 emit_optional_rex_32(dst);
769 emit_operand(subcode, dst);
774 void Assembler::immediate_arithmetic_op_8(
byte subcode,
778 if (!dst.is_byte_register()) {
784 emit_modrm(subcode, dst);
789 void Assembler::shift(Register dst, Immediate shift_amount,
int subcode) {
792 if (shift_amount.value_ == 1) {
795 emit_modrm(subcode, dst);
799 emit_modrm(subcode, dst);
800 emit(shift_amount.value_);
805 void Assembler::shift(Register dst,
int subcode) {
809 emit_modrm(subcode, dst);
813 void Assembler::shift_32(Register dst,
int subcode) {
815 emit_optional_rex_32(dst);
817 emit_modrm(subcode, dst);
821 void Assembler::shift_32(Register dst, Immediate shift_amount,
int subcode) {
824 if (shift_amount.value_ == 1) {
825 emit_optional_rex_32(dst);
827 emit_modrm(subcode, dst);
829 emit_optional_rex_32(dst);
831 emit_modrm(subcode, dst);
832 emit(shift_amount.value_);
839 emit_rex_64(src, dst);
842 emit_operand(src, dst);
848 emit_rex_64(src, dst);
851 emit_operand(src, dst);
864 }
else if (L->is_linked()) {
877 RelocInfo::Mode rmode,
883 emit_code_target(target, rmode, ast_id);
891 emit_optional_rex_32(adr);
893 emit_modrm(0x2, adr);
901 emit_optional_rex_32(op);
903 emit_operand(0x2, op);
917 intptr_t displacement = target - source;
919 emitl(static_cast<int32_t>(displacement));
942 }
else if (cc ==
never) {
950 emit_rex_64(dst, src);
953 emit_modrm(dst, src);
960 }
else if (cc ==
never) {
966 emit_rex_64(dst, src);
969 emit_operand(dst, src);
976 }
else if (cc ==
never) {
982 emit_optional_rex_32(dst, src);
985 emit_modrm(dst, src);
992 }
else if (cc ==
never) {
998 emit_optional_rex_32(dst, src);
1001 emit_operand(dst, src);
1032 emit_modrm(0x1, dst);
1040 emit_operand(1, dst);
1046 emit_optional_rex_32(dst);
1048 emit_modrm(0x1, dst);
1054 emit_optional_rex_32(dst);
1056 emit_operand(1, dst);
1062 if (!dst.is_byte_register()) {
1067 emit_modrm(0x1, dst);
1073 emit_optional_rex_32(dst);
1075 emit_operand(1, dst);
1097 emit_modrm(0x7, src);
1103 emit_optional_rex_32(src);
1105 emit_modrm(0x7, src);
1113 emit_modrm(0x5, src);
1119 emit_rex_64(dst, src);
1122 emit_modrm(dst, src);
1128 emit_rex_64(dst, src);
1131 emit_operand(dst, src);
1137 emit_rex_64(dst, src);
1140 emit_modrm(dst, src);
1144 emit_modrm(dst, src);
1152 emit_optional_rex_32(dst, src);
1155 emit_modrm(dst, src);
1161 emit_optional_rex_32(dst, src);
1164 emit_operand(dst, src);
1170 emit_optional_rex_32(dst, src);
1173 emit_modrm(dst, src);
1177 emit_modrm(dst, src);
1187 emit_modrm(0x0, dst);
1195 emit_operand(0, dst);
1201 emit_optional_rex_32(dst);
1203 emit_operand(0, dst);
1209 emit_optional_rex_32(dst);
1225 }
else if (cc ==
never) {
1230 if (L->is_bound()) {
1231 const int short_size = 2;
1232 const int long_size = 6;
1235 if (
is_int8(offs - short_size)) {
1238 emit((offs - short_size) & 0xFF);
1243 emitl(offs - long_size);
1245 }
else if (distance == Label::kNear) {
1249 if (L->is_near_linked()) {
1250 int offset = L->near_link_pos() -
pc_offset();
1252 disp =
static_cast<byte>(offset & 0xFF);
1256 }
else if (L->is_linked()) {
1268 L->link_to(current);
1274 Handle<Code> target,
1275 RelocInfo::Mode rmode) {
1281 emit_code_target(target, rmode);
1287 const int short_size =
sizeof(int8_t);
1288 const int long_size =
sizeof(
int32_t);
1289 if (L->is_bound()) {
1292 if (
is_int8(offs - short_size)) {
1295 emit((offs - short_size) & 0xFF);
1299 emitl(offs - long_size);
1301 }
else if (distance == Label::kNear) {
1304 if (L->is_near_linked()) {
1305 int offset = L->near_link_pos() -
pc_offset();
1307 disp =
static_cast<byte>(offset & 0xFF);
1311 }
else if (L->is_linked()) {
1322 L->link_to(current);
1327 void Assembler::jmp(Handle<Code> target, RelocInfo::Mode rmode) {
1331 emit_code_target(target, rmode);
1338 emit_optional_rex_32(target);
1340 emit_modrm(0x4, target);
1347 emit_optional_rex_32(src);
1349 emit_operand(0x4, src);
1355 emit_rex_64(dst, src);
1357 emit_operand(dst, src);
1363 emit_optional_rex_32(dst, src);
1365 emit_operand(dst, src);
1373 emitq(reinterpret_cast<uintptr_t>(value), mode);
1378 load_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE);
1390 if (!dst.is_byte_register()) {
1392 emit_rex_32(dst, src);
1394 emit_optional_rex_32(dst, src);
1397 emit_operand(dst, src);
1403 if (!dst.is_byte_register()) {
1406 emit(0xB0 + dst.low_bits());
1413 if (!src.is_byte_register()) {
1414 emit_rex_32(src, dst);
1416 emit_optional_rex_32(src, dst);
1419 emit_operand(src, dst);
1426 emit_optional_rex_32(src, dst);
1428 emit_operand(src, dst);
1434 emit_optional_rex_32(dst, src);
1436 emit_operand(dst, src);
1442 if (src.low_bits() == 4) {
1443 emit_optional_rex_32(src, dst);
1445 emit_modrm(src, dst);
1447 emit_optional_rex_32(dst, src);
1449 emit_modrm(dst, src);
1456 emit_optional_rex_32(src, dst);
1458 emit_operand(src, dst);
1464 emit_optional_rex_32(dst);
1466 emit_operand(0x0, dst);
1473 emit_optional_rex_32(dst);
1474 emit(0xB8 + dst.low_bits());
1481 emit_rex_64(dst, src);
1483 emit_operand(dst, src);
1489 if (src.low_bits() == 4) {
1490 emit_rex_64(src, dst);
1492 emit_modrm(src, dst);
1494 emit_rex_64(dst, src);
1496 emit_modrm(dst, src);
1505 emit_modrm(0x0, dst);
1512 emit_rex_64(src, dst);
1514 emit_operand(src, dst);
1518 void Assembler::movq(Register dst,
void* value, RelocInfo::Mode rmode) {
1521 ASSERT(rmode > RelocInfo::LAST_GCED_ENUM);
1524 emit(0xB8 | dst.low_bits());
1525 emitq(reinterpret_cast<uintptr_t>(value), rmode);
1529 void Assembler::movq(Register dst, int64_t value, RelocInfo::Mode rmode) {
1534 movq(dst, Immediate(static_cast<int32_t>(value)));
1537 movl(dst, Immediate(static_cast<int32_t>(value)));
1545 emit(0xB8 | dst.low_bits());
1546 emitq(value, rmode);
1551 int64_t value =
reinterpret_cast<int64_t
>(ref.address());
1552 movq(dst, value, RelocInfo::EXTERNAL_REFERENCE);
1560 emit_operand(0, dst);
1569 emit_optional_rex_32(dst);
1571 emit_operand(0, dst);
1572 if (src->is_bound()) {
1576 }
else if (src->is_linked()) {
1580 ASSERT(src->is_unused());
1583 src->link_to(current);
1588 void Assembler::movq(Register dst, Handle<Object> value, RelocInfo::Mode mode) {
1598 ASSERT(value->IsHeapObject());
1601 emit(0xB8 | dst.low_bits());
1602 emitq(reinterpret_cast<uintptr_t>(value.location()), mode);
1609 emit_rex_64(dst, src);
1612 emit_operand(dst, src);
1618 emit_rex_64(dst, src);
1621 emit_operand(dst, src);
1627 emit_rex_64(dst, src);
1629 emit_modrm(dst, src);
1635 emit_rex_64(dst, src);
1637 emit_operand(dst, src);
1645 emit_optional_rex_32(dst, src);
1648 emit_operand(dst, src);
1654 emit_optional_rex_32(dst, src);
1657 emit_operand(dst, src);
1663 emit_optional_rex_32(dst, src);
1666 emit_operand(dst, src);
1672 emit_optional_rex_32(dst, src);
1675 emit_operand(dst, src);
1713 emit_modrm(0x4, src);
1721 emit_modrm(0x3, dst);
1727 emit_optional_rex_32(dst);
1729 emit_modrm(0x3, dst);
1737 emit_operand(3, dst);
1751 emit_modrm(0x2, dst);
1759 emit_operand(2, dst);
1765 emit_optional_rex_32(dst);
1767 emit_modrm(0x2, dst);
1850 emit_optional_rex_32(dst);
1851 emit(0x58 | dst.low_bits());
1857 emit_optional_rex_32(dst);
1859 emit_operand(0, dst);
1871 emit_optional_rex_32(src);
1872 emit(0x50 | src.low_bits());
1878 emit_optional_rex_32(src);
1880 emit_operand(6, src);
1891 emitl(value.value_);
1924 emit((imm16 >> 8) & 0xFF);
1936 if (!reg.is_byte_register()) {
1941 emit_modrm(0x0, reg);
1947 emit_rex_64(src, dst);
1950 emit_modrm(src, dst);
1956 emit_rex_64(src, dst);
1959 emit_modrm(src, dst);
1965 if (src.is(
rax) || dst.is(
rax)) {
1966 Register other = src.is(
rax) ? dst : src;
1968 emit(0x90 | other.low_bits());
1969 }
else if (dst.low_bits() == 4) {
1970 emit_rex_64(dst, src);
1972 emit_modrm(dst, src);
1974 emit_rex_64(src, dst);
1976 emit_modrm(src, dst);
1985 emitq(reinterpret_cast<uintptr_t>(dst), mode);
1990 store_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE);
1996 if (src.low_bits() == 4) {
1997 emit_rex_32(src, dst);
1999 emit_modrm(src, dst);
2001 if (!dst.is_byte_register() || !src.is_byte_register()) {
2003 emit_rex_32(dst, src);
2006 emit_modrm(dst, src);
2018 if (!reg.is_byte_register()) {
2023 emit_modrm(0x0, reg);
2032 emit_optional_rex_32(
rax, op);
2034 emit_operand(
rax, op);
2041 if (!reg.is_byte_register()) {
2043 emit_rex_32(reg, op);
2045 emit_optional_rex_32(reg, op);
2048 emit_operand(reg, op);
2054 if (src.low_bits() == 4) {
2055 emit_optional_rex_32(src, dst);
2057 emit_modrm(src, dst);
2059 emit_optional_rex_32(dst, src);
2061 emit_modrm(dst, src);
2077 emit_optional_rex_32(
rax, reg);
2079 emit_modrm(0x0, reg);
2092 emit_optional_rex_32(
rax, op);
2094 emit_operand(
rax, op);
2101 emit_rex_64(reg, op);
2103 emit_operand(reg, op);
2109 if (src.low_bits() == 4) {
2110 emit_rex_64(src, dst);
2112 emit_modrm(src, dst);
2114 emit_rex_64(dst, src);
2116 emit_modrm(dst, src);
2141 emit_farith(0xD9, 0xC0, i);
2175 emit_optional_rex_32(adr);
2177 emit_operand(0, adr);
2183 emit_optional_rex_32(adr);
2185 emit_operand(0, adr);
2191 emit_optional_rex_32(adr);
2193 emit_operand(3, adr);
2199 emit_optional_rex_32(adr);
2201 emit_operand(3, adr);
2208 emit_farith(0xDD, 0xD8, index);
2214 emit_optional_rex_32(adr);
2216 emit_operand(0, adr);
2222 emit_optional_rex_32(adr);
2224 emit_operand(5, adr);
2230 emit_optional_rex_32(adr);
2232 emit_operand(3, adr);
2239 emit_optional_rex_32(adr);
2241 emit_operand(1, adr);
2248 emit_optional_rex_32(adr);
2250 emit_operand(1, adr);
2256 emit_optional_rex_32(adr);
2258 emit_operand(2, adr);
2264 emit_optional_rex_32(adr);
2266 emit_operand(7, adr);
2335 emit_farith(0xDC, 0xC0, i);
2341 emit_farith(0xDC, 0xE8, i);
2347 emit_optional_rex_32(adr);
2349 emit_operand(4, adr);
2355 emit_farith(0xDC, 0xC8, i);
2361 emit_farith(0xDC, 0xF8, i);
2367 emit_farith(0xDE, 0xC0, i);
2373 emit_farith(0xDE, 0xE8, i);
2379 emit_farith(0xDE, 0xE0, i);
2385 emit_farith(0xDE, 0xC8, i);
2391 emit_farith(0xDE, 0xF8, i);
2411 emit_farith(0xD9, 0xC8, i);
2424 emit_farith(0xDD, 0xC0, i);
2437 emit_farith(0xDD, 0xE8, i);
2504 void Assembler::emit_farith(
int b1,
int b2,
int i) {
2516 emit_optional_rex_32(dst, src);
2526 emit_optional_rex_32(src, dst);
2536 emit_rex_64(dst, src);
2546 emit_rex_64(src, dst);
2555 if (dst.low_bits() == 4) {
2558 emit_optional_rex_32(dst, src);
2564 emit_optional_rex_32(src, dst);
2574 emit_rex_64(src, dst);
2584 emit_rex_64(dst, src);
2596 emit_optional_rex_32(dst, src);
2608 emit_optional_rex_32(src, dst);
2618 emit_optional_rex_32(dst, src);
2628 emit_optional_rex_32(dst, src);
2637 if (src.low_bits() == 4) {
2639 emit_optional_rex_32(src, dst);
2644 emit_optional_rex_32(dst, src);
2654 if (src.low_bits() == 4) {
2657 emit_optional_rex_32(src, dst);
2663 emit_optional_rex_32(dst, src);
2674 emit_optional_rex_32(dst, src);
2684 emit_optional_rex_32(dst, src);
2694 emit_optional_rex_32(dst, src);
2697 emit_operand(dst, src);
2704 emit_optional_rex_32(dst, src);
2714 emit_optional_rex_32(dst, src);
2717 emit_operand(dst, src);
2724 emit_optional_rex_32(dst, src);
2734 emit_rex_64(dst, src);
2744 emit_optional_rex_32(dst, src);
2754 emit_optional_rex_32(dst, src);
2764 emit_optional_rex_32(dst, src);
2774 emit_rex_64(dst, src);
2784 emit_optional_rex_32(dst, src);
2794 emit_optional_rex_32(dst, src);
2804 emit_optional_rex_32(dst, src);
2814 emit_optional_rex_32(dst, src);
2824 emit_rex_64(dst, src);
2834 emit_optional_rex_32(dst, src);
2844 emit_optional_rex_32(dst, src);
2854 emit_optional_rex_32(dst, src);
2864 emit_optional_rex_32(dst, src);
2874 emit_optional_rex_32(dst, src);
2884 emit_optional_rex_32(dst, src);
2894 emit_optional_rex_32(dst, src);
2903 emit_optional_rex_32(dst, src);
2913 emit_optional_rex_32(dst, src);
2923 emit_optional_rex_32(dst, src);
2933 emit_optional_rex_32(dst, src);
2945 emit_optional_rex_32(dst, src);
2951 emit(static_cast<byte>(mode) | 0x8);
2958 emit_optional_rex_32(dst, src);
2966 Register ireg = { reg.code() };
2967 emit_operand(ireg, adr);
2972 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
2976 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
2980 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
2998 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
3001 if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
3012 reloc_info_writer.Write(&rinfo);
3018 RecordRelocInfo(RelocInfo::JS_RETURN);
3025 RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
3030 if (FLAG_code_comments || force) {
3032 RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg));
3037 const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask |
3038 1 << RelocInfo::INTERNAL_REFERENCE;
3041 bool RelocInfo::IsCodedSpecially() {
3045 return (1 << rmode_) & kApplyMask;
3050 #endif // V8_TARGET_ARCH_X64
void cvtlsi2ss(XMMRegister dst, Register src)
void movapd(XMMRegister dst, XMMRegister src)
static const int kMaximalBufferSize
Isolate * isolate() const
void load_rax(void *ptr, RelocInfo::Mode rmode)
void ucomisd(XMMRegister dst, XMMRegister src)
void cvttss2si(Register dst, const Operand &src)
void movzxbl(Register dst, const Operand &src)
void roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode)
bool buffer_overflow() const
void mulsd(XMMRegister dst, XMMRegister src)
void cvtsd2si(Register dst, XMMRegister src)
void orpd(XMMRegister dst, XMMRegister src)
void push(Register src, Condition cond=al)
void cvtss2sd(XMMRegister dst, XMMRegister src)
void sqrtsd(XMMRegister dst, XMMRegister src)
static bool IsSupported(CpuFeature f)
void andpd(XMMRegister dst, XMMRegister src)
void j(Condition cc, Label *L, Label::Distance distance=Label::kFar)
static const int kMinimalBufferSize
#define ASSERT(condition)
void cvtlsi2sd(XMMRegister dst, const Operand &src)
void movsxlq(Register dst, Register src)
void xorpd(XMMRegister dst, XMMRegister src)
void bt(const Operand &dst, Register src)
bool is_uint32(int64_t x)
void cmovl(Condition cc, Register dst, Register src)
void testb(Register dst, Register src)
void fistp_s(const Operand &adr)
void addsd(XMMRegister dst, XMMRegister src)
void fld_d(const Operand &adr)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 instructions(ARM only)") DEFINE_bool(enable_armv7
void imull(Register dst, Register src)
void cmpb_al(const Operand &op)
void xchg(Register dst, Register src)
void fild_s(const Operand &adr)
void enter(const Immediate &size)
void testl(Register dst, Register src)
void movzxbq(Register dst, const Operand &src)
void shld(Register dst, Register src)
void fisttp_d(const Operand &adr)
void movss(XMMRegister dst, const Operand &src)
void movb(Register dst, const Operand &src)
void set_byte_at(int pos, byte value)
void cvtsd2ss(XMMRegister dst, XMMRegister src)
void movsd(XMMRegister dst, XMMRegister src)
void GetCode(CodeDesc *desc)
void movdqa(XMMRegister dst, const Operand &src)
void movsxbq(Register dst, const Operand &src)
static void TooLateToEnableNow()
void movmskpd(Register dst, XMMRegister src)
void fisttp_s(const Operand &adr)
void movzxwq(Register dst, const Operand &src)
static int32_t & int32_at(Address addr)
void movzxwl(Register dst, const Operand &src)
void emit_sse_operand(XMMRegister reg, const Operand &adr)
void cvtqsi2sd(XMMRegister dst, const Operand &src)
void xorps(XMMRegister dst, XMMRegister src)
void setcc(Condition cc, Register reg)
void fld_s(const Operand &adr)
static bool IsNop(Instr instr, int type=NON_MARKING_NOP)
void RecordDebugBreakSlot()
void fstp_d(const Operand &adr)
void movw(Register reg, uint32_t immediate, Condition cond=al)
void store_rax(void *dst, RelocInfo::Mode mode)
void push_imm32(int32_t imm32)
void fistp_d(const Operand &adr)
void cvtsd2siq(Register dst, XMMRegister src)
void shrd(Register dst, Register src)
void movaps(XMMRegister dst, XMMRegister src)
void RecordComment(const char *msg)
void fstp_s(const Operand &adr)
void divsd(XMMRegister dst, XMMRegister src)
void lea(Register dst, const Operand &src)
void fild_d(const Operand &adr)
Assembler(Isolate *isolate, void *buffer, int buffer_size)
void movl(Register dst, Register src)
#define ASSERT_EQ(v1, v2)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
void testq(const Operand &op, Register reg)
void movd(XMMRegister dst, Register src)
PositionsRecorder * positions_recorder()
void fisub_s(const Operand &adr)
void extractps(Register dst, XMMRegister src, byte imm8)
static uint64_t CpuFeaturesImpliedByPlatform()
static void FlushICache(void *start, size_t size)
void fist_s(const Operand &adr)
void movsxwq(Register dst, const Operand &src)
void DeleteArray(T *array)
void bts(Register dst, Register src)
void cmovq(Condition cc, Register dst, Register src)
static void FatalProcessOutOfMemory(const char *location, bool take_snapshot=false)
bool emit_debug_code() const
void subsd(XMMRegister dst, XMMRegister src)
void cvttsd2siq(Register dst, XMMRegister src)
void movq(const Operand &dst, Register src)
void mul(Register dst, Register src1, Register src2, SBit s=LeaveCC, Condition cond=al)
void cvttsd2si(Register dst, const Operand &src)
void leal(Register dst, const Operand &src)