Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(252)

Side by Side Diff: src/ppc/assembler-ppc.cc

Issue 994533004: Contribution of PowerPC port (continuation of 422063005) - uplevel (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ppc/assembler-ppc.h ('k') | src/ppc/assembler-ppc-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. 1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
2 // All Rights Reserved. 2 // All Rights Reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions 5 // modification, are permitted provided that the following conditions
6 // are met: 6 // are met:
7 // 7 //
8 // - Redistributions of source code must retain the above copyright notice, 8 // - Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer. 9 // this list of conditions and the following disclaimer.
10 // 10 //
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 // We leave space (kMaxBlockTrampolineSectionSize) 210 // We leave space (kMaxBlockTrampolineSectionSize)
211 // for BlockTrampolinePoolScope buffer. 211 // for BlockTrampolinePoolScope buffer.
212 next_buffer_check_ = 212 next_buffer_check_ =
213 FLAG_force_long_branches ? kMaxInt : kMaxCondBranchReach - 213 FLAG_force_long_branches ? kMaxInt : kMaxCondBranchReach -
214 kMaxBlockTrampolineSectionSize; 214 kMaxBlockTrampolineSectionSize;
215 internal_trampoline_exception_ = false; 215 internal_trampoline_exception_ = false;
216 last_bound_pos_ = 0; 216 last_bound_pos_ = 0;
217 trampoline_emitted_ = FLAG_force_long_branches; 217 trampoline_emitted_ = FLAG_force_long_branches;
218 unbound_labels_count_ = 0; 218 unbound_labels_count_ = 0;
219 ClearRecordedAstId(); 219 ClearRecordedAstId();
220 relocations_.reserve(128);
220 } 221 }
221 222
222 223
223 void Assembler::GetCode(CodeDesc* desc) { 224 void Assembler::GetCode(CodeDesc* desc) {
224 reloc_info_writer.Finish(); 225 EmitRelocations();
225 226
226 // Set up code descriptor. 227 // Set up code descriptor.
227 desc->buffer = buffer_; 228 desc->buffer = buffer_;
228 desc->buffer_size = buffer_size_; 229 desc->buffer_size = buffer_size_;
229 desc->instr_size = pc_offset(); 230 desc->instr_size = pc_offset();
230 desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos(); 231 desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
231 desc->origin = this; 232 desc->origin = this;
232 } 233 }
233 234
234 235
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 // instruction using the label. 372 // instruction using the label.
372 373
373 374
374 // The link chain is terminated by a negative code position (must be aligned) 375 // The link chain is terminated by a negative code position (must be aligned)
375 const int kEndOfChain = -4; 376 const int kEndOfChain = -4;
376 377
377 378
378 // Dummy opcodes for unbound label mov instructions or jump table entries. 379 // Dummy opcodes for unbound label mov instructions or jump table entries.
379 enum { 380 enum {
380 kUnboundMovLabelOffsetOpcode = 0 << 26, 381 kUnboundMovLabelOffsetOpcode = 0 << 26,
381 kUnboundMovLabelAddrOpcode = 1 << 26, 382 kUnboundAddLabelOffsetOpcode = 1 << 26,
382 kUnboundJumpTableEntryOpcode = 2 << 26 383 kUnboundMovLabelAddrOpcode = 2 << 26,
384 kUnboundJumpTableEntryOpcode = 3 << 26
383 }; 385 };
384 386
385 387
386 int Assembler::target_at(int pos) { 388 int Assembler::target_at(int pos) {
387 Instr instr = instr_at(pos); 389 Instr instr = instr_at(pos);
388 // check which type of branch this is 16 or 26 bit offset 390 // check which type of branch this is 16 or 26 bit offset
389 int opcode = instr & kOpcodeMask; 391 int opcode = instr & kOpcodeMask;
390 int link; 392 int link;
391 switch (opcode) { 393 switch (opcode) {
392 case BX: 394 case BX:
393 link = SIGN_EXT_IMM26(instr & kImm26Mask); 395 link = SIGN_EXT_IMM26(instr & kImm26Mask);
394 link &= ~(kAAMask | kLKMask); // discard AA|LK bits if present 396 link &= ~(kAAMask | kLKMask); // discard AA|LK bits if present
395 break; 397 break;
396 case BCX: 398 case BCX:
397 link = SIGN_EXT_IMM16((instr & kImm16Mask)); 399 link = SIGN_EXT_IMM16((instr & kImm16Mask));
398 link &= ~(kAAMask | kLKMask); // discard AA|LK bits if present 400 link &= ~(kAAMask | kLKMask); // discard AA|LK bits if present
399 break; 401 break;
400 case kUnboundMovLabelOffsetOpcode: 402 case kUnboundMovLabelOffsetOpcode:
403 case kUnboundAddLabelOffsetOpcode:
401 case kUnboundMovLabelAddrOpcode: 404 case kUnboundMovLabelAddrOpcode:
402 case kUnboundJumpTableEntryOpcode: 405 case kUnboundJumpTableEntryOpcode:
403 link = SIGN_EXT_IMM26(instr & kImm26Mask); 406 link = SIGN_EXT_IMM26(instr & kImm26Mask);
404 link <<= 2; 407 link <<= 2;
405 break; 408 break;
406 default: 409 default:
407 DCHECK(false); 410 DCHECK(false);
408 return -1; 411 return -1;
409 } 412 }
410 413
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
447 case kUnboundMovLabelOffsetOpcode: { 450 case kUnboundMovLabelOffsetOpcode: {
448 // Load the position of the label relative to the generated code object 451 // Load the position of the label relative to the generated code object
449 // pointer in a register. 452 // pointer in a register.
450 Register dst = Register::from_code(instr_at(pos + kInstrSize)); 453 Register dst = Register::from_code(instr_at(pos + kInstrSize));
451 int32_t offset = target_pos + (Code::kHeaderSize - kHeapObjectTag); 454 int32_t offset = target_pos + (Code::kHeaderSize - kHeapObjectTag);
452 CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos), 2, 455 CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos), 2,
453 CodePatcher::DONT_FLUSH); 456 CodePatcher::DONT_FLUSH);
454 patcher.masm()->bitwise_mov32(dst, offset); 457 patcher.masm()->bitwise_mov32(dst, offset);
455 break; 458 break;
456 } 459 }
460 case kUnboundAddLabelOffsetOpcode: {
461 // dst = base + position + immediate
462 Instr operands = instr_at(pos + kInstrSize);
463 Register dst = Register::from_code((operands >> 21) & 0x1f);
464 Register base = Register::from_code((operands >> 16) & 0x1f);
465 int32_t offset = target_pos + SIGN_EXT_IMM16(operands & kImm16Mask);
466 CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos), 2,
467 CodePatcher::DONT_FLUSH);
468 patcher.masm()->bitwise_add32(dst, base, offset);
469 break;
470 }
457 case kUnboundMovLabelAddrOpcode: { 471 case kUnboundMovLabelAddrOpcode: {
458 // Load the address of the label in a register. 472 // Load the address of the label in a register.
459 Register dst = Register::from_code(instr_at(pos + kInstrSize)); 473 Register dst = Register::from_code(instr_at(pos + kInstrSize));
460 intptr_t addr = reinterpret_cast<uintptr_t>(buffer_ + target_pos);
461 CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos), 474 CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos),
462 kMovInstructions, CodePatcher::DONT_FLUSH); 475 kMovInstructions, CodePatcher::DONT_FLUSH);
463 AddBoundInternalReferenceLoad(pos); 476 // Keep internal references relative until EmitRelocations.
464 patcher.masm()->bitwise_mov(dst, addr); 477 patcher.masm()->bitwise_mov(dst, target_pos);
465 break; 478 break;
466 } 479 }
467 case kUnboundJumpTableEntryOpcode: { 480 case kUnboundJumpTableEntryOpcode: {
468 intptr_t addr = reinterpret_cast<uintptr_t>(buffer_ + target_pos);
469 CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos), 481 CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos),
470 kPointerSize / kInstrSize, CodePatcher::DONT_FLUSH); 482 kPointerSize / kInstrSize, CodePatcher::DONT_FLUSH);
471 AddBoundInternalReference(pos); 483 // Keep internal references relative until EmitRelocations.
472 patcher.masm()->emit_ptr(addr); 484 patcher.masm()->emit_ptr(target_pos);
473 break; 485 break;
474 } 486 }
475 default: 487 default:
476 DCHECK(false); 488 DCHECK(false);
477 break; 489 break;
478 } 490 }
479 } 491 }
480 492
481 493
482 int Assembler::max_reach_from(int pos) { 494 int Assembler::max_reach_from(int pos) {
483 Instr instr = instr_at(pos); 495 Instr instr = instr_at(pos);
484 int opcode = instr & kOpcodeMask; 496 int opcode = instr & kOpcodeMask;
485 497
486 // check which type of branch this is 16 or 26 bit offset 498 // check which type of branch this is 16 or 26 bit offset
487 switch (opcode) { 499 switch (opcode) {
488 case BX: 500 case BX:
489 return 26; 501 return 26;
490 case BCX: 502 case BCX:
491 return 16; 503 return 16;
492 case kUnboundMovLabelOffsetOpcode: 504 case kUnboundMovLabelOffsetOpcode:
505 case kUnboundAddLabelOffsetOpcode:
493 case kUnboundMovLabelAddrOpcode: 506 case kUnboundMovLabelAddrOpcode:
494 case kUnboundJumpTableEntryOpcode: 507 case kUnboundJumpTableEntryOpcode:
495 return 0; // no limit on reach 508 return 0; // no limit on reach
496 } 509 }
497 510
498 DCHECK(false); 511 DCHECK(false);
499 return 0; 512 return 0;
500 } 513 }
501 514
502 515
(...skipping 977 matching lines...) Expand 10 before | Expand all | Expand 10 after
1480 Label instructions; 1493 Label instructions;
1481 DCHECK(pc_offset() == 0); 1494 DCHECK(pc_offset() == 0);
1482 emit_label_addr(&instructions); 1495 emit_label_addr(&instructions);
1483 emit_ptr(0); 1496 emit_ptr(0);
1484 emit_ptr(0); 1497 emit_ptr(0);
1485 bind(&instructions); 1498 bind(&instructions);
1486 #endif 1499 #endif
1487 } 1500 }
1488 1501
1489 1502
1490 void Assembler::RelocateInternalReference(Address pc, intptr_t delta,
1491 Address code_start,
1492 RelocInfo::Mode rmode,
1493 ICacheFlushMode icache_flush_mode) {
1494 if (RelocInfo::IsInternalReference(rmode)) {
1495 // Jump table entry
1496 DCHECK(delta || code_start);
1497 uintptr_t* entry = reinterpret_cast<uintptr_t*>(pc);
1498 if (delta) {
1499 *entry += delta;
1500 } else {
1501 // remove when serializer properly supports internal references
1502 *entry = reinterpret_cast<uintptr_t>(code_start) + 3 * kPointerSize;
1503 }
1504 } else {
1505 // mov sequence
1506 DCHECK(delta || code_start);
1507 DCHECK(RelocInfo::IsInternalReferenceEncoded(rmode));
1508 ConstantPoolArray* constant_pool = NULL;
1509 Address addr;
1510 if (delta) {
1511 addr = target_address_at(pc, constant_pool) + delta;
1512 } else {
1513 // remove when serializer properly supports internal references
1514 addr = code_start;
1515 }
1516 set_target_address_at(pc, constant_pool, addr, icache_flush_mode);
1517 }
1518 }
1519
1520
1521 void Assembler::EnsureSpaceFor(int space_needed) { 1503 void Assembler::EnsureSpaceFor(int space_needed) {
1522 if (buffer_space() <= (kGap + space_needed)) { 1504 if (buffer_space() <= (kGap + space_needed)) {
1523 GrowBuffer(space_needed); 1505 GrowBuffer(space_needed);
1524 } 1506 }
1525 } 1507 }
1526 1508
1527 1509
1528 bool Operand::must_output_reloc_info(const Assembler* assembler) const { 1510 bool Operand::must_output_reloc_info(const Assembler* assembler) const {
1529 if (rmode_ == RelocInfo::EXTERNAL_REFERENCE) { 1511 if (rmode_ == RelocInfo::EXTERNAL_REFERENCE) {
1530 if (assembler != NULL && assembler->predictable_code_size()) return true; 1512 if (assembler != NULL && assembler->predictable_code_size()) return true;
1531 return assembler->serializer_enabled(); 1513 return assembler->serializer_enabled();
1532 } else if (RelocInfo::IsNone(rmode_)) { 1514 } else if (RelocInfo::IsNone(rmode_)) {
1533 return false; 1515 return false;
1534 } 1516 }
1535 return true; 1517 return true;
1536 } 1518 }
1537 1519
1538 1520
1539 // Primarily used for loading constants 1521 // Primarily used for loading constants
1540 // This should really move to be in macro-assembler as it 1522 // This should really move to be in macro-assembler as it
1541 // is really a pseudo instruction 1523 // is really a pseudo instruction
1542 // Some usages of this intend for a FIXED_SEQUENCE to be used 1524 // Some usages of this intend for a FIXED_SEQUENCE to be used
1543 // Todo - break this dependency so we can optimize mov() in general 1525 // Todo - break this dependency so we can optimize mov() in general
1544 // and only use the generic version when we require a fixed sequence 1526 // and only use the generic version when we require a fixed sequence
1545 void Assembler::mov(Register dst, const Operand& src) { 1527 void Assembler::mov(Register dst, const Operand& src) {
1546 intptr_t value = src.immediate(); 1528 intptr_t value = src.immediate();
1529 bool relocatable = src.must_output_reloc_info(this);
1547 bool canOptimize; 1530 bool canOptimize;
1548 RelocInfo rinfo(pc_, src.rmode_, value, NULL);
1549 1531
1550 canOptimize = !(src.must_output_reloc_info(this) || 1532 canOptimize =
1551 (is_trampoline_pool_blocked() && !is_int16(value))); 1533 !(relocatable || (is_trampoline_pool_blocked() && !is_int16(value)));
1552 1534
1553 if (canOptimize) { 1535 if (canOptimize) {
1554 if (is_int16(value)) { 1536 if (is_int16(value)) {
1555 li(dst, Operand(value)); 1537 li(dst, Operand(value));
1556 } else { 1538 } else {
1557 uint16_t u16; 1539 uint16_t u16;
1558 #if V8_TARGET_ARCH_PPC64 1540 #if V8_TARGET_ARCH_PPC64
1559 if (is_int32(value)) { 1541 if (is_int32(value)) {
1560 #endif 1542 #endif
1561 lis(dst, Operand(value >> 16)); 1543 lis(dst, Operand(value >> 16));
(...skipping 17 matching lines...) Expand all
1579 #endif 1561 #endif
1580 u16 = (value & 0xffff); 1562 u16 = (value & 0xffff);
1581 if (u16) { 1563 if (u16) {
1582 ori(dst, dst, Operand(u16)); 1564 ori(dst, dst, Operand(u16));
1583 } 1565 }
1584 } 1566 }
1585 return; 1567 return;
1586 } 1568 }
1587 1569
1588 DCHECK(!canOptimize); 1570 DCHECK(!canOptimize);
1589 if (src.must_output_reloc_info(this)) { 1571 if (relocatable) {
1590 RecordRelocInfo(rinfo); 1572 RecordRelocInfo(src.rmode_);
1591 } 1573 }
1592 bitwise_mov(dst, value); 1574 bitwise_mov(dst, value);
1593 } 1575 }
1594 1576
1595 1577
1596 void Assembler::bitwise_mov(Register dst, intptr_t value) { 1578 void Assembler::bitwise_mov(Register dst, intptr_t value) {
1597 BlockTrampolinePoolScope block_trampoline_pool(this); 1579 BlockTrampolinePoolScope block_trampoline_pool(this);
1598 #if V8_TARGET_ARCH_PPC64 1580 #if V8_TARGET_ARCH_PPC64
1599 int32_t hi_32 = static_cast<int32_t>(value >> 32); 1581 int32_t hi_32 = static_cast<int32_t>(value >> 32);
1600 int32_t lo_32 = static_cast<int32_t>(value); 1582 int32_t lo_32 = static_cast<int32_t>(value);
(...skipping 17 matching lines...) Expand all
1618 1600
1619 void Assembler::bitwise_mov32(Register dst, int32_t value) { 1601 void Assembler::bitwise_mov32(Register dst, int32_t value) {
1620 BlockTrampolinePoolScope block_trampoline_pool(this); 1602 BlockTrampolinePoolScope block_trampoline_pool(this);
1621 int hi_word = static_cast<int>(value >> 16); 1603 int hi_word = static_cast<int>(value >> 16);
1622 int lo_word = static_cast<int>(value & 0xffff); 1604 int lo_word = static_cast<int>(value & 0xffff);
1623 lis(dst, Operand(SIGN_EXT_IMM16(hi_word))); 1605 lis(dst, Operand(SIGN_EXT_IMM16(hi_word)));
1624 ori(dst, dst, Operand(lo_word)); 1606 ori(dst, dst, Operand(lo_word));
1625 } 1607 }
1626 1608
1627 1609
1610 void Assembler::bitwise_add32(Register dst, Register src, int32_t value) {
1611 BlockTrampolinePoolScope block_trampoline_pool(this);
1612 if (is_int16(value)) {
1613 addi(dst, src, Operand(value));
1614 nop();
1615 } else {
1616 int hi_word = static_cast<int>(value >> 16);
1617 int lo_word = static_cast<int>(value & 0xffff);
1618 if (lo_word & 0x8000) hi_word++;
1619 addis(dst, src, Operand(SIGN_EXT_IMM16(hi_word)));
1620 addic(dst, dst, Operand(SIGN_EXT_IMM16(lo_word)));
1621 }
1622 }
1623
1624
1628 void Assembler::mov_label_offset(Register dst, Label* label) { 1625 void Assembler::mov_label_offset(Register dst, Label* label) {
1629 int position = link(label); 1626 int position = link(label);
1630 if (label->is_bound()) { 1627 if (label->is_bound()) {
1631 // Load the position of the label relative to the generated code object. 1628 // Load the position of the label relative to the generated code object.
1632 mov(dst, Operand(position + Code::kHeaderSize - kHeapObjectTag)); 1629 mov(dst, Operand(position + Code::kHeaderSize - kHeapObjectTag));
1633 } else { 1630 } else {
1634 // Encode internal reference to unbound label. We use a dummy opcode 1631 // Encode internal reference to unbound label. We use a dummy opcode
1635 // such that it won't collide with any opcode that might appear in the 1632 // such that it won't collide with any opcode that might appear in the
1636 // label's chain. Encode the destination register in the 2nd instruction. 1633 // label's chain. Encode the destination register in the 2nd instruction.
1637 int link = position - pc_offset(); 1634 int link = position - pc_offset();
1638 DCHECK_EQ(0, link & 3); 1635 DCHECK_EQ(0, link & 3);
1639 link >>= 2; 1636 link >>= 2;
1640 DCHECK(is_int26(link)); 1637 DCHECK(is_int26(link));
1641 1638
1642 // When the label is bound, these instructions will be patched 1639 // When the label is bound, these instructions will be patched
1643 // with a 2 instruction mov sequence that will load the 1640 // with a 2 instruction mov sequence that will load the
1644 // destination register with the position of the label from the 1641 // destination register with the position of the label from the
1645 // beginning of the code. 1642 // beginning of the code.
1646 // 1643 //
1647 // target_at extracts the link and target_at_put patches the instructions. 1644 // target_at extracts the link and target_at_put patches the instructions.
1648 BlockTrampolinePoolScope block_trampoline_pool(this); 1645 BlockTrampolinePoolScope block_trampoline_pool(this);
1649 emit(kUnboundMovLabelOffsetOpcode | (link & kImm26Mask)); 1646 emit(kUnboundMovLabelOffsetOpcode | (link & kImm26Mask));
1650 emit(dst.code()); 1647 emit(dst.code());
1651 } 1648 }
1652 } 1649 }
1653 1650
1654 1651
1652 void Assembler::add_label_offset(Register dst, Register base, Label* label,
1653 int delta) {
1654 int position = link(label);
1655 if (label->is_bound()) {
1656 // dst = base + position + delta
1657 position += delta;
1658 bitwise_add32(dst, base, position);
1659 } else {
1660 // Encode internal reference to unbound label. We use a dummy opcode
1661 // such that it won't collide with any opcode that might appear in the
1662 // label's chain. Encode the operands in the 2nd instruction.
1663 int link = position - pc_offset();
1664 DCHECK_EQ(0, link & 3);
1665 link >>= 2;
1666 DCHECK(is_int26(link));
1667 DCHECK(is_int16(delta));
1668
1669 BlockTrampolinePoolScope block_trampoline_pool(this);
1670 emit(kUnboundAddLabelOffsetOpcode | (link & kImm26Mask));
1671 emit(dst.code() * B21 | base.code() * B16 | (delta & kImm16Mask));
1672 }
1673 }
1674
1675
1655 void Assembler::mov_label_addr(Register dst, Label* label) { 1676 void Assembler::mov_label_addr(Register dst, Label* label) {
1656 CheckBuffer(); 1677 CheckBuffer();
1657 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE_ENCODED); 1678 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE_ENCODED);
1658 int position = link(label); 1679 int position = link(label);
1659 if (label->is_bound()) { 1680 if (label->is_bound()) {
1660 // CheckBuffer() is called too frequently. This will pre-grow 1681 // Keep internal references relative until EmitRelocations.
1661 // the buffer if needed to avoid spliting the relocation and instructions 1682 bitwise_mov(dst, position);
1662 EnsureSpaceFor(kMovInstructions * kInstrSize);
1663
1664 intptr_t addr = reinterpret_cast<uintptr_t>(buffer_ + position);
1665 AddBoundInternalReferenceLoad(pc_offset());
1666 bitwise_mov(dst, addr);
1667 } else { 1683 } else {
1668 // Encode internal reference to unbound label. We use a dummy opcode 1684 // Encode internal reference to unbound label. We use a dummy opcode
1669 // such that it won't collide with any opcode that might appear in the 1685 // such that it won't collide with any opcode that might appear in the
1670 // label's chain. Encode the destination register in the 2nd instruction. 1686 // label's chain. Encode the destination register in the 2nd instruction.
1671 int link = position - pc_offset(); 1687 int link = position - pc_offset();
1672 DCHECK_EQ(0, link & 3); 1688 DCHECK_EQ(0, link & 3);
1673 link >>= 2; 1689 link >>= 2;
1674 DCHECK(is_int26(link)); 1690 DCHECK(is_int26(link));
1675 1691
1676 // When the label is bound, these instructions will be patched 1692 // When the label is bound, these instructions will be patched
1677 // with a multi-instruction mov sequence that will load the 1693 // with a multi-instruction mov sequence that will load the
1678 // destination register with the address of the label. 1694 // destination register with the address of the label.
1679 // 1695 //
1680 // target_at extracts the link and target_at_put patches the instructions. 1696 // target_at extracts the link and target_at_put patches the instructions.
1681 BlockTrampolinePoolScope block_trampoline_pool(this); 1697 BlockTrampolinePoolScope block_trampoline_pool(this);
1682 emit(kUnboundMovLabelAddrOpcode | (link & kImm26Mask)); 1698 emit(kUnboundMovLabelAddrOpcode | (link & kImm26Mask));
1683 emit(dst.code()); 1699 emit(dst.code());
1684 DCHECK(kMovInstructions >= 2); 1700 DCHECK(kMovInstructions >= 2);
1685 for (int i = 0; i < kMovInstructions - 2; i++) nop(); 1701 for (int i = 0; i < kMovInstructions - 2; i++) nop();
1686 } 1702 }
1687 } 1703 }
1688 1704
1689 1705
1690 void Assembler::emit_label_addr(Label* label) { 1706 void Assembler::emit_label_addr(Label* label) {
1691 CheckBuffer(); 1707 CheckBuffer();
1692 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE); 1708 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
1693 int position = link(label); 1709 int position = link(label);
1694 if (label->is_bound()) { 1710 if (label->is_bound()) {
1695 // CheckBuffer() is called too frequently. This will pre-grow 1711 // Keep internal references relative until EmitRelocations.
1696 // the buffer if needed to avoid spliting the relocation and entry. 1712 emit_ptr(position);
1697 EnsureSpaceFor(kPointerSize);
1698
1699 intptr_t addr = reinterpret_cast<uintptr_t>(buffer_ + position);
1700 AddBoundInternalReference(pc_offset());
1701 emit_ptr(addr);
1702 } else { 1713 } else {
1703 // Encode internal reference to unbound label. We use a dummy opcode 1714 // Encode internal reference to unbound label. We use a dummy opcode
1704 // such that it won't collide with any opcode that might appear in the 1715 // such that it won't collide with any opcode that might appear in the
1705 // label's chain. 1716 // label's chain.
1706 int link = position - pc_offset(); 1717 int link = position - pc_offset();
1707 DCHECK_EQ(0, link & 3); 1718 DCHECK_EQ(0, link & 3);
1708 link >>= 2; 1719 link >>= 2;
1709 DCHECK(is_int26(link)); 1720 DCHECK(is_int26(link));
1710 1721
1711 // When the label is bound, the instruction(s) will be patched 1722 // When the label is bound, the instruction(s) will be patched
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after
2211 desc.reloc_size); 2222 desc.reloc_size);
2212 2223
2213 // Switch buffers. 2224 // Switch buffers.
2214 DeleteArray(buffer_); 2225 DeleteArray(buffer_);
2215 buffer_ = desc.buffer; 2226 buffer_ = desc.buffer;
2216 buffer_size_ = desc.buffer_size; 2227 buffer_size_ = desc.buffer_size;
2217 pc_ += pc_delta; 2228 pc_ += pc_delta;
2218 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, 2229 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
2219 reloc_info_writer.last_pc() + pc_delta); 2230 reloc_info_writer.last_pc() + pc_delta);
2220 2231
2221 // Relocate internal references 2232 // Nothing else to do here since we keep all internal references and
2222 for (int pos : internal_reference_positions_) { 2233 // deferred relocation entries relative to the buffer (until
2223 RelocateInternalReference(buffer_ + pos, pc_delta, 0, 2234 // EmitRelocations).
2224 RelocInfo::INTERNAL_REFERENCE);
2225 }
2226 for (int pos : internal_reference_load_positions_) {
2227 RelocateInternalReference(buffer_ + pos, pc_delta, 0,
2228 RelocInfo::INTERNAL_REFERENCE_ENCODED);
2229 }
2230 } 2235 }
2231 2236
2232 2237
2233 void Assembler::db(uint8_t data) { 2238 void Assembler::db(uint8_t data) {
2234 CheckBuffer(); 2239 CheckBuffer();
2235 *reinterpret_cast<uint8_t*>(pc_) = data; 2240 *reinterpret_cast<uint8_t*>(pc_) = data;
2236 pc_ += sizeof(uint8_t); 2241 pc_ += sizeof(uint8_t);
2237 } 2242 }
2238 2243
2239 2244
2240 void Assembler::dd(uint32_t data) { 2245 void Assembler::dd(uint32_t data) {
2241 CheckBuffer(); 2246 CheckBuffer();
2242 *reinterpret_cast<uint32_t*>(pc_) = data; 2247 *reinterpret_cast<uint32_t*>(pc_) = data;
2243 pc_ += sizeof(uint32_t); 2248 pc_ += sizeof(uint32_t);
2244 } 2249 }
2245 2250
2246 2251
2247 void Assembler::emit_ptr(intptr_t data) { 2252 void Assembler::emit_ptr(intptr_t data) {
2248 CheckBuffer(); 2253 CheckBuffer();
2249 *reinterpret_cast<intptr_t*>(pc_) = data; 2254 *reinterpret_cast<intptr_t*>(pc_) = data;
2250 pc_ += sizeof(intptr_t); 2255 pc_ += sizeof(intptr_t);
2251 } 2256 }
2252 2257
2253 2258
2259 void Assembler::emit_double(double value) {
2260 CheckBuffer();
2261 *reinterpret_cast<double*>(pc_) = value;
2262 pc_ += sizeof(double);
2263 }
2264
2265
2254 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { 2266 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
2255 RelocInfo rinfo(pc_, rmode, data, NULL); 2267 DeferredRelocInfo rinfo(pc_offset(), rmode, data);
2256 RecordRelocInfo(rinfo); 2268 RecordRelocInfo(rinfo);
2257 } 2269 }
2258 2270
2259 2271
2260 void Assembler::RecordRelocInfo(const RelocInfo& rinfo) { 2272 void Assembler::RecordRelocInfo(const DeferredRelocInfo& rinfo) {
2261 if (rinfo.rmode() >= RelocInfo::JS_RETURN && 2273 if (rinfo.rmode() >= RelocInfo::JS_RETURN &&
2262 rinfo.rmode() <= RelocInfo::DEBUG_BREAK_SLOT) { 2274 rinfo.rmode() <= RelocInfo::DEBUG_BREAK_SLOT) {
2263 // Adjust code for new modes. 2275 // Adjust code for new modes.
2264 DCHECK(RelocInfo::IsDebugBreakSlot(rinfo.rmode()) || 2276 DCHECK(RelocInfo::IsDebugBreakSlot(rinfo.rmode()) ||
2265 RelocInfo::IsJSReturn(rinfo.rmode()) || 2277 RelocInfo::IsJSReturn(rinfo.rmode()) ||
2266 RelocInfo::IsComment(rinfo.rmode()) || 2278 RelocInfo::IsComment(rinfo.rmode()) ||
2267 RelocInfo::IsPosition(rinfo.rmode())); 2279 RelocInfo::IsPosition(rinfo.rmode()));
2268 } 2280 }
2269 if (!RelocInfo::IsNone(rinfo.rmode())) { 2281 if (!RelocInfo::IsNone(rinfo.rmode())) {
2270 // Don't record external references unless the heap will be serialized. 2282 // Don't record external references unless the heap will be serialized.
2271 if (rinfo.rmode() == RelocInfo::EXTERNAL_REFERENCE) { 2283 if (rinfo.rmode() == RelocInfo::EXTERNAL_REFERENCE) {
2272 if (!serializer_enabled() && !emit_debug_code()) { 2284 if (!serializer_enabled() && !emit_debug_code()) {
2273 return; 2285 return;
2274 } 2286 }
2275 } 2287 }
2276 DCHECK(buffer_space() >= kMaxRelocSize); // too late to grow buffer here
2277 if (rinfo.rmode() == RelocInfo::CODE_TARGET_WITH_ID) { 2288 if (rinfo.rmode() == RelocInfo::CODE_TARGET_WITH_ID) {
2278 RelocInfo reloc_info_with_ast_id(rinfo.pc(), rinfo.rmode(), 2289 DeferredRelocInfo reloc_info_with_ast_id(rinfo.position(), rinfo.rmode(),
2279 RecordedAstId().ToInt(), NULL); 2290 RecordedAstId().ToInt());
2280 ClearRecordedAstId(); 2291 ClearRecordedAstId();
2281 reloc_info_writer.Write(&reloc_info_with_ast_id); 2292 relocations_.push_back(reloc_info_with_ast_id);
2282 } else { 2293 } else {
2283 reloc_info_writer.Write(&rinfo); 2294 relocations_.push_back(rinfo);
2284 } 2295 }
2285 } 2296 }
2286 } 2297 }
2287 2298
2288 2299
2300 void Assembler::EmitRelocations() {
2301 EnsureSpaceFor(relocations_.size() * kMaxRelocSize);
2302
2303 for (std::vector<DeferredRelocInfo>::iterator it = relocations_.begin();
2304 it != relocations_.end(); it++) {
2305 RelocInfo::Mode rmode = it->rmode();
2306 RelocInfo rinfo(buffer_ + it->position(), rmode, it->data(), NULL);
2307
2308 // Fix up internal references now that they are guaranteed to be bound.
2309 if (RelocInfo::IsInternalReference(rmode) ||
2310 RelocInfo::IsInternalReferenceEncoded(rmode)) {
2311 intptr_t pos =
2312 reinterpret_cast<intptr_t>(rinfo.target_internal_reference());
2313 rinfo.set_target_internal_reference(buffer_ + pos);
2314 }
2315
2316 reloc_info_writer.Write(&rinfo);
2317 }
2318
2319 reloc_info_writer.Finish();
2320 }
2321
2322
2289 void Assembler::BlockTrampolinePoolFor(int instructions) { 2323 void Assembler::BlockTrampolinePoolFor(int instructions) {
2290 BlockTrampolinePoolBefore(pc_offset() + instructions * kInstrSize); 2324 BlockTrampolinePoolBefore(pc_offset() + instructions * kInstrSize);
2291 } 2325 }
2292 2326
2293 2327
2294 void Assembler::CheckTrampolinePool() { 2328 void Assembler::CheckTrampolinePool() {
2295 // Some small sequences of instructions must not be broken up by the 2329 // Some small sequences of instructions must not be broken up by the
2296 // insertion of a trampoline pool; such sequences are protected by setting 2330 // insertion of a trampoline pool; such sequences are protected by setting
2297 // either trampoline_pool_blocked_nesting_ or no_trampoline_pool_before_, 2331 // either trampoline_pool_blocked_nesting_ or no_trampoline_pool_before_,
2298 // which are both checked here. Also, recursive calls to CheckTrampolinePool 2332 // which are both checked here. Also, recursive calls to CheckTrampolinePool
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2346 } 2380 }
2347 2381
2348 2382
2349 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) { 2383 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
2350 DCHECK(!FLAG_enable_ool_constant_pool); 2384 DCHECK(!FLAG_enable_ool_constant_pool);
2351 } 2385 }
2352 } 2386 }
2353 } // namespace v8::internal 2387 } // namespace v8::internal
2354 2388
2355 #endif // V8_TARGET_ARCH_PPC 2389 #endif // V8_TARGET_ARCH_PPC
OLDNEW
« no previous file with comments | « src/ppc/assembler-ppc.h ('k') | src/ppc/assembler-ppc-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698