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

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

Issue 1131573006: ARM64: Enable shorten-64-to-32 warning (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 7 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/arm64/assembler-arm64.h ('k') | src/arm64/assembler-arm64-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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // 2 //
3 // Redistribution and use in source and binary forms, with or without 3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions are 4 // modification, are permitted provided that the following conditions are
5 // met: 5 // met:
6 // 6 //
7 // * Redistributions of source code must retain the above copyright 7 // * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer. 8 // notice, this list of conditions and the following disclaimer.
9 // * Redistributions in binary form must reproduce the above 9 // * Redistributions in binary form must reproduce the above
10 // copyright notice, this list of conditions and the following 10 // copyright notice, this list of conditions and the following
(...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 reloc_info_writer.Finish(); 573 reloc_info_writer.Finish();
574 // Emit constant pool if necessary. 574 // Emit constant pool if necessary.
575 CheckConstPool(true, false); 575 CheckConstPool(true, false);
576 DCHECK(constpool_.IsEmpty()); 576 DCHECK(constpool_.IsEmpty());
577 577
578 // Set up code descriptor. 578 // Set up code descriptor.
579 if (desc) { 579 if (desc) {
580 desc->buffer = reinterpret_cast<byte*>(buffer_); 580 desc->buffer = reinterpret_cast<byte*>(buffer_);
581 desc->buffer_size = buffer_size_; 581 desc->buffer_size = buffer_size_;
582 desc->instr_size = pc_offset(); 582 desc->instr_size = pc_offset();
583 desc->reloc_size = (reinterpret_cast<byte*>(buffer_) + buffer_size_) - 583 desc->reloc_size =
584 reloc_info_writer.pos(); 584 static_cast<int>((reinterpret_cast<byte*>(buffer_) + buffer_size_) -
585 reloc_info_writer.pos());
585 desc->origin = this; 586 desc->origin = this;
586 } 587 }
587 } 588 }
588 589
589 590
590 void Assembler::Align(int m) { 591 void Assembler::Align(int m) {
591 DCHECK(m >= 4 && base::bits::IsPowerOfTwo32(m)); 592 DCHECK(m >= 4 && base::bits::IsPowerOfTwo32(m));
592 while ((pc_offset() & (m - 1)) != 0) { 593 while ((pc_offset() & (m - 1)) != 0) {
593 nop(); 594 nop();
594 } 595 }
595 } 596 }
596 597
597 598
598 void Assembler::CheckLabelLinkChain(Label const * label) { 599 void Assembler::CheckLabelLinkChain(Label const * label) {
599 #ifdef DEBUG 600 #ifdef DEBUG
600 if (label->is_linked()) { 601 if (label->is_linked()) {
601 static const int kMaxLinksToCheck = 64; // Avoid O(n2) behaviour. 602 static const int kMaxLinksToCheck = 64; // Avoid O(n2) behaviour.
602 int links_checked = 0; 603 int links_checked = 0;
603 int linkoffset = label->pos(); 604 int64_t linkoffset = label->pos();
604 bool end_of_chain = false; 605 bool end_of_chain = false;
605 while (!end_of_chain) { 606 while (!end_of_chain) {
606 if (++links_checked > kMaxLinksToCheck) break; 607 if (++links_checked > kMaxLinksToCheck) break;
607 Instruction * link = InstructionAt(linkoffset); 608 Instruction * link = InstructionAt(linkoffset);
608 int linkpcoffset = link->ImmPCOffset(); 609 int64_t linkpcoffset = link->ImmPCOffset();
609 int prevlinkoffset = linkoffset + linkpcoffset; 610 int64_t prevlinkoffset = linkoffset + linkpcoffset;
610 611
611 end_of_chain = (linkoffset == prevlinkoffset); 612 end_of_chain = (linkoffset == prevlinkoffset);
612 linkoffset = linkoffset + linkpcoffset; 613 linkoffset = linkoffset + linkpcoffset;
613 } 614 }
614 } 615 }
615 #endif 616 #endif
616 } 617 }
617 618
618 619
619 void Assembler::RemoveBranchFromLabelLinkChain(Instruction* branch, 620 void Assembler::RemoveBranchFromLabelLinkChain(Instruction* branch,
(...skipping 18 matching lines...) Expand all
638 DCHECK(branch == link); 639 DCHECK(branch == link);
639 next_link = branch->ImmPCOffsetTarget(); 640 next_link = branch->ImmPCOffsetTarget();
640 641
641 if (branch == prev_link) { 642 if (branch == prev_link) {
642 // The branch is the first instruction in the chain. 643 // The branch is the first instruction in the chain.
643 if (branch == next_link) { 644 if (branch == next_link) {
644 // It is also the last instruction in the chain, so it is the only branch 645 // It is also the last instruction in the chain, so it is the only branch
645 // currently referring to this label. 646 // currently referring to this label.
646 label->Unuse(); 647 label->Unuse();
647 } else { 648 } else {
648 label->link_to(reinterpret_cast<byte*>(next_link) - buffer_); 649 label->link_to(
650 static_cast<int>(reinterpret_cast<byte*>(next_link) - buffer_));
649 } 651 }
650 652
651 } else if (branch == next_link) { 653 } else if (branch == next_link) {
652 // The branch is the last (but not also the first) instruction in the chain. 654 // The branch is the last (but not also the first) instruction in the chain.
653 prev_link->SetImmPCOffsetTarget(prev_link); 655 prev_link->SetImmPCOffsetTarget(prev_link);
654 656
655 } else { 657 } else {
656 // The branch is in the middle of the chain. 658 // The branch is in the middle of the chain.
657 if (prev_link->IsTargetInImmPCOffsetRange(next_link)) { 659 if (prev_link->IsTargetInImmPCOffsetRange(next_link)) {
658 prev_link->SetImmPCOffsetTarget(next_link); 660 prev_link->SetImmPCOffsetTarget(next_link);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
714 // |<------| link->ImmPCOffset() 716 // |<------| link->ImmPCOffset()
715 // |------>| prevlinkoffset = linkoffset + link->ImmPCOffset() 717 // |------>| prevlinkoffset = linkoffset + link->ImmPCOffset()
716 // 718 //
717 // On each iteration, the last link is updated and then removed from the 719 // On each iteration, the last link is updated and then removed from the
718 // chain until only one remains. At that point, the label is bound. 720 // chain until only one remains. At that point, the label is bound.
719 // 721 //
720 // If the label is not linked, no preparation is required before binding. 722 // If the label is not linked, no preparation is required before binding.
721 while (label->is_linked()) { 723 while (label->is_linked()) {
722 int linkoffset = label->pos(); 724 int linkoffset = label->pos();
723 Instruction* link = InstructionAt(linkoffset); 725 Instruction* link = InstructionAt(linkoffset);
724 int prevlinkoffset = linkoffset + link->ImmPCOffset(); 726 int prevlinkoffset = linkoffset + static_cast<int>(link->ImmPCOffset());
725 727
726 CheckLabelLinkChain(label); 728 CheckLabelLinkChain(label);
727 729
728 DCHECK(linkoffset >= 0); 730 DCHECK(linkoffset >= 0);
729 DCHECK(linkoffset < pc_offset()); 731 DCHECK(linkoffset < pc_offset());
730 DCHECK((linkoffset > prevlinkoffset) || 732 DCHECK((linkoffset > prevlinkoffset) ||
731 (linkoffset - prevlinkoffset == kStartOfLabelLinkChain)); 733 (linkoffset - prevlinkoffset == kStartOfLabelLinkChain));
732 DCHECK(prevlinkoffset >= 0); 734 DCHECK(prevlinkoffset >= 0);
733 735
734 // Update the link to point to the label. 736 // Update the link to point to the label.
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
804 void Assembler::DeleteUnresolvedBranchInfoForLabelTraverse(Label* label) { 806 void Assembler::DeleteUnresolvedBranchInfoForLabelTraverse(Label* label) {
805 DCHECK(label->is_linked()); 807 DCHECK(label->is_linked());
806 CheckLabelLinkChain(label); 808 CheckLabelLinkChain(label);
807 809
808 int link_offset = label->pos(); 810 int link_offset = label->pos();
809 int link_pcoffset; 811 int link_pcoffset;
810 bool end_of_chain = false; 812 bool end_of_chain = false;
811 813
812 while (!end_of_chain) { 814 while (!end_of_chain) {
813 Instruction * link = InstructionAt(link_offset); 815 Instruction * link = InstructionAt(link_offset);
814 link_pcoffset = link->ImmPCOffset(); 816 link_pcoffset = static_cast<int>(link->ImmPCOffset());
815 817
816 // ADR instructions are not handled by veneers. 818 // ADR instructions are not handled by veneers.
817 if (link->IsImmBranch()) { 819 if (link->IsImmBranch()) {
818 int max_reachable_pc = InstructionOffset(link) + 820 int max_reachable_pc =
819 Instruction::ImmBranchRange(link->BranchType()); 821 static_cast<int>(InstructionOffset(link) +
822 Instruction::ImmBranchRange(link->BranchType()));
820 typedef std::multimap<int, FarBranchInfo>::iterator unresolved_info_it; 823 typedef std::multimap<int, FarBranchInfo>::iterator unresolved_info_it;
821 std::pair<unresolved_info_it, unresolved_info_it> range; 824 std::pair<unresolved_info_it, unresolved_info_it> range;
822 range = unresolved_branches_.equal_range(max_reachable_pc); 825 range = unresolved_branches_.equal_range(max_reachable_pc);
823 unresolved_info_it it; 826 unresolved_info_it it;
824 for (it = range.first; it != range.second; ++it) { 827 for (it = range.first; it != range.second; ++it) {
825 if (it->second.pc_offset_ == link_offset) { 828 if (it->second.pc_offset_ == link_offset) {
826 unresolved_branches_.erase(it); 829 unresolved_branches_.erase(it);
827 break; 830 break;
828 } 831 }
829 } 832 }
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
902 int Assembler::ConstantPoolSizeAt(Instruction* instr) { 905 int Assembler::ConstantPoolSizeAt(Instruction* instr) {
903 #ifdef USE_SIMULATOR 906 #ifdef USE_SIMULATOR
904 // Assembler::debug() embeds constants directly into the instruction stream. 907 // Assembler::debug() embeds constants directly into the instruction stream.
905 // Although this is not a genuine constant pool, treat it like one to avoid 908 // Although this is not a genuine constant pool, treat it like one to avoid
906 // disassembling the constants. 909 // disassembling the constants.
907 if ((instr->Mask(ExceptionMask) == HLT) && 910 if ((instr->Mask(ExceptionMask) == HLT) &&
908 (instr->ImmException() == kImmExceptionIsDebug)) { 911 (instr->ImmException() == kImmExceptionIsDebug)) {
909 const char* message = 912 const char* message =
910 reinterpret_cast<const char*>( 913 reinterpret_cast<const char*>(
911 instr->InstructionAtOffset(kDebugMessageOffset)); 914 instr->InstructionAtOffset(kDebugMessageOffset));
912 int size = kDebugMessageOffset + strlen(message) + 1; 915 int size = static_cast<int>(kDebugMessageOffset + strlen(message) + 1);
913 return RoundUp(size, kInstructionSize) / kInstructionSize; 916 return RoundUp(size, kInstructionSize) / kInstructionSize;
914 } 917 }
915 // Same for printf support, see MacroAssembler::CallPrintf(). 918 // Same for printf support, see MacroAssembler::CallPrintf().
916 if ((instr->Mask(ExceptionMask) == HLT) && 919 if ((instr->Mask(ExceptionMask) == HLT) &&
917 (instr->ImmException() == kImmExceptionIsPrintf)) { 920 (instr->ImmException() == kImmExceptionIsPrintf)) {
918 return kPrintfLength / kInstructionSize; 921 return kPrintfLength / kInstructionSize;
919 } 922 }
920 #endif 923 #endif
921 if (IsConstantPoolAt(instr)) { 924 if (IsConstantPoolAt(instr)) {
922 return instr->ImmLLiteral(); 925 return instr->ImmLLiteral();
(...skipping 669 matching lines...) Expand 10 before | Expand all | Expand 10 after
1592 } 1595 }
1593 1596
1594 1597
1595 void Assembler::LoadStorePair(const CPURegister& rt, 1598 void Assembler::LoadStorePair(const CPURegister& rt,
1596 const CPURegister& rt2, 1599 const CPURegister& rt2,
1597 const MemOperand& addr, 1600 const MemOperand& addr,
1598 LoadStorePairOp op) { 1601 LoadStorePairOp op) {
1599 // 'rt' and 'rt2' can only be aliased for stores. 1602 // 'rt' and 'rt2' can only be aliased for stores.
1600 DCHECK(((op & LoadStorePairLBit) == 0) || !rt.Is(rt2)); 1603 DCHECK(((op & LoadStorePairLBit) == 0) || !rt.Is(rt2));
1601 DCHECK(AreSameSizeAndType(rt, rt2)); 1604 DCHECK(AreSameSizeAndType(rt, rt2));
1605 DCHECK(IsImmLSPair(addr.offset(), CalcLSPairDataSize(op)));
1606 int offset = static_cast<int>(addr.offset());
1602 1607
1603 Instr memop = op | Rt(rt) | Rt2(rt2) | RnSP(addr.base()) | 1608 Instr memop = op | Rt(rt) | Rt2(rt2) | RnSP(addr.base()) |
1604 ImmLSPair(addr.offset(), CalcLSPairDataSize(op)); 1609 ImmLSPair(offset, CalcLSPairDataSize(op));
1605 1610
1606 Instr addrmodeop; 1611 Instr addrmodeop;
1607 if (addr.IsImmediateOffset()) { 1612 if (addr.IsImmediateOffset()) {
1608 addrmodeop = LoadStorePairOffsetFixed; 1613 addrmodeop = LoadStorePairOffsetFixed;
1609 } else { 1614 } else {
1610 // Pre-index and post-index modes. 1615 // Pre-index and post-index modes.
1611 DCHECK(!rt.Is(addr.base())); 1616 DCHECK(!rt.Is(addr.base()));
1612 DCHECK(!rt2.Is(addr.base())); 1617 DCHECK(!rt2.Is(addr.base()));
1613 DCHECK(addr.offset() != 0); 1618 DCHECK(addr.offset() != 0);
1614 if (addr.IsPreIndex()) { 1619 if (addr.IsPreIndex()) {
(...skipping 23 matching lines...) Expand all
1638 } 1643 }
1639 1644
1640 1645
1641 void Assembler::LoadStorePairNonTemporal(const CPURegister& rt, 1646 void Assembler::LoadStorePairNonTemporal(const CPURegister& rt,
1642 const CPURegister& rt2, 1647 const CPURegister& rt2,
1643 const MemOperand& addr, 1648 const MemOperand& addr,
1644 LoadStorePairNonTemporalOp op) { 1649 LoadStorePairNonTemporalOp op) {
1645 DCHECK(!rt.Is(rt2)); 1650 DCHECK(!rt.Is(rt2));
1646 DCHECK(AreSameSizeAndType(rt, rt2)); 1651 DCHECK(AreSameSizeAndType(rt, rt2));
1647 DCHECK(addr.IsImmediateOffset()); 1652 DCHECK(addr.IsImmediateOffset());
1648
1649 LSDataSize size = CalcLSPairDataSize( 1653 LSDataSize size = CalcLSPairDataSize(
1650 static_cast<LoadStorePairOp>(op & LoadStorePairMask)); 1654 static_cast<LoadStorePairOp>(op & LoadStorePairMask));
1651 Emit(op | Rt(rt) | Rt2(rt2) | RnSP(addr.base()) | 1655 DCHECK(IsImmLSPair(addr.offset(), size));
1652 ImmLSPair(addr.offset(), size)); 1656 int offset = static_cast<int>(addr.offset());
1657 Emit(op | Rt(rt) | Rt2(rt2) | RnSP(addr.base()) | ImmLSPair(offset, size));
1653 } 1658 }
1654 1659
1655 1660
1656 // Memory instructions. 1661 // Memory instructions.
1657 void Assembler::ldrb(const Register& rt, const MemOperand& src) { 1662 void Assembler::ldrb(const Register& rt, const MemOperand& src) {
1658 LoadStore(rt, src, LDRB_w); 1663 LoadStore(rt, src, LDRB_w);
1659 } 1664 }
1660 1665
1661 1666
1662 void Assembler::strb(const Register& rt, const MemOperand& dst) { 1667 void Assembler::strb(const Register& rt, const MemOperand& dst) {
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after
2130 return (bit7 | bit6 | bit5_to_0) << ImmFP_offset; 2135 return (bit7 | bit6 | bit5_to_0) << ImmFP_offset;
2131 } 2136 }
2132 2137
2133 2138
2134 Instr Assembler::ImmFP64(double imm) { 2139 Instr Assembler::ImmFP64(double imm) {
2135 DCHECK(IsImmFP64(imm)); 2140 DCHECK(IsImmFP64(imm));
2136 // bits: aBbb.bbbb.bbcd.efgh.0000.0000.0000.0000 2141 // bits: aBbb.bbbb.bbcd.efgh.0000.0000.0000.0000
2137 // 0000.0000.0000.0000.0000.0000.0000.0000 2142 // 0000.0000.0000.0000.0000.0000.0000.0000
2138 uint64_t bits = double_to_rawbits(imm); 2143 uint64_t bits = double_to_rawbits(imm);
2139 // bit7: a000.0000 2144 // bit7: a000.0000
2140 uint32_t bit7 = ((bits >> 63) & 0x1) << 7; 2145 uint64_t bit7 = ((bits >> 63) & 0x1) << 7;
2141 // bit6: 0b00.0000 2146 // bit6: 0b00.0000
2142 uint32_t bit6 = ((bits >> 61) & 0x1) << 6; 2147 uint64_t bit6 = ((bits >> 61) & 0x1) << 6;
2143 // bit5_to_0: 00cd.efgh 2148 // bit5_to_0: 00cd.efgh
2144 uint32_t bit5_to_0 = (bits >> 48) & 0x3f; 2149 uint64_t bit5_to_0 = (bits >> 48) & 0x3f;
2145 2150
2146 return (bit7 | bit6 | bit5_to_0) << ImmFP_offset; 2151 return static_cast<Instr>((bit7 | bit6 | bit5_to_0) << ImmFP_offset);
2147 } 2152 }
2148 2153
2149 2154
2150 // Code generation helpers. 2155 // Code generation helpers.
2151 void Assembler::MoveWide(const Register& rd, 2156 void Assembler::MoveWide(const Register& rd,
2152 uint64_t imm, 2157 uint64_t imm,
2153 int shift, 2158 int shift,
2154 MoveWideImmediateOp mov_op) { 2159 MoveWideImmediateOp mov_op) {
2155 // Ignore the top 32 bits of an immediate if we're moving to a W register. 2160 // Ignore the top 32 bits of an immediate if we're moving to a W register.
2156 if (rd.Is32Bits()) { 2161 if (rd.Is32Bits()) {
(...skipping 24 matching lines...) Expand all
2181 shift = 2; 2186 shift = 2;
2182 } else if ((imm & ~(0xffffUL << 48)) == 0) { 2187 } else if ((imm & ~(0xffffUL << 48)) == 0) {
2183 DCHECK(rd.Is64Bits()); 2188 DCHECK(rd.Is64Bits());
2184 imm >>= 48; 2189 imm >>= 48;
2185 shift = 3; 2190 shift = 3;
2186 } 2191 }
2187 } 2192 }
2188 2193
2189 DCHECK(is_uint16(imm)); 2194 DCHECK(is_uint16(imm));
2190 2195
2191 Emit(SF(rd) | MoveWideImmediateFixed | mov_op | 2196 Emit(SF(rd) | MoveWideImmediateFixed | mov_op | Rd(rd) |
2192 Rd(rd) | ImmMoveWide(imm) | ShiftMoveWide(shift)); 2197 ImmMoveWide(static_cast<int>(imm)) | ShiftMoveWide(shift));
2193 } 2198 }
2194 2199
2195 2200
2196 void Assembler::AddSub(const Register& rd, 2201 void Assembler::AddSub(const Register& rd,
2197 const Register& rn, 2202 const Register& rn,
2198 const Operand& operand, 2203 const Operand& operand,
2199 FlagsUpdate S, 2204 FlagsUpdate S,
2200 AddSubOp op) { 2205 AddSubOp op) {
2201 DCHECK(rd.SizeInBits() == rn.SizeInBits()); 2206 DCHECK(rd.SizeInBits() == rn.SizeInBits());
2202 DCHECK(!operand.NeedsRelocation(this)); 2207 DCHECK(!operand.NeedsRelocation(this));
2203 if (operand.IsImmediate()) { 2208 if (operand.IsImmediate()) {
2204 int64_t immediate = operand.ImmediateValue(); 2209 int64_t immediate = operand.ImmediateValue();
2205 DCHECK(IsImmAddSub(immediate)); 2210 DCHECK(IsImmAddSub(immediate));
2206 Instr dest_reg = (S == SetFlags) ? Rd(rd) : RdSP(rd); 2211 Instr dest_reg = (S == SetFlags) ? Rd(rd) : RdSP(rd);
2207 Emit(SF(rd) | AddSubImmediateFixed | op | Flags(S) | 2212 Emit(SF(rd) | AddSubImmediateFixed | op | Flags(S) |
2208 ImmAddSub(immediate) | dest_reg | RnSP(rn)); 2213 ImmAddSub(static_cast<int>(immediate)) | dest_reg | RnSP(rn));
2209 } else if (operand.IsShiftedRegister()) { 2214 } else if (operand.IsShiftedRegister()) {
2210 DCHECK(operand.reg().SizeInBits() == rd.SizeInBits()); 2215 DCHECK(operand.reg().SizeInBits() == rd.SizeInBits());
2211 DCHECK(operand.shift() != ROR); 2216 DCHECK(operand.shift() != ROR);
2212 2217
2213 // For instructions of the form: 2218 // For instructions of the form:
2214 // add/sub wsp, <Wn>, <Wm> [, LSL #0-3 ] 2219 // add/sub wsp, <Wn>, <Wm> [, LSL #0-3 ]
2215 // add/sub <Wd>, wsp, <Wm> [, LSL #0-3 ] 2220 // add/sub <Wd>, wsp, <Wm> [, LSL #0-3 ]
2216 // add/sub wsp, wsp, <Wm> [, LSL #0-3 ] 2221 // add/sub wsp, wsp, <Wm> [, LSL #0-3 ]
2217 // adds/subs <Wd>, wsp, <Wm> [, LSL #0-3 ] 2222 // adds/subs <Wd>, wsp, <Wm> [, LSL #0-3 ]
2218 // or their 64-bit register equivalents, convert the operand from shifted to 2223 // or their 64-bit register equivalents, convert the operand from shifted to
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2252 2257
2253 void Assembler::brk(int code) { 2258 void Assembler::brk(int code) {
2254 DCHECK(is_uint16(code)); 2259 DCHECK(is_uint16(code));
2255 Emit(BRK | ImmException(code)); 2260 Emit(BRK | ImmException(code));
2256 } 2261 }
2257 2262
2258 2263
2259 void Assembler::EmitStringData(const char* string) { 2264 void Assembler::EmitStringData(const char* string) {
2260 size_t len = strlen(string) + 1; 2265 size_t len = strlen(string) + 1;
2261 DCHECK(RoundUp(len, kInstructionSize) <= static_cast<size_t>(kGap)); 2266 DCHECK(RoundUp(len, kInstructionSize) <= static_cast<size_t>(kGap));
2262 EmitData(string, len); 2267 EmitData(string, static_cast<int>(len));
2263 // Pad with NULL characters until pc_ is aligned. 2268 // Pad with NULL characters until pc_ is aligned.
2264 const char pad[] = {'\0', '\0', '\0', '\0'}; 2269 const char pad[] = {'\0', '\0', '\0', '\0'};
2265 STATIC_ASSERT(sizeof(pad) == kInstructionSize); 2270 STATIC_ASSERT(sizeof(pad) == kInstructionSize);
2266 EmitData(pad, RoundUp(pc_offset(), kInstructionSize) - pc_offset()); 2271 EmitData(pad, RoundUp(pc_offset(), kInstructionSize) - pc_offset());
2267 } 2272 }
2268 2273
2269 2274
2270 void Assembler::debug(const char* message, uint32_t code, Instr params) { 2275 void Assembler::debug(const char* message, uint32_t code, Instr params) {
2271 #ifdef USE_SIMULATOR 2276 #ifdef USE_SIMULATOR
2272 // Don't generate simulator specific code if we are building a snapshot, which 2277 // Don't generate simulator specific code if we are building a snapshot, which
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
2355 void Assembler::ConditionalCompare(const Register& rn, 2360 void Assembler::ConditionalCompare(const Register& rn,
2356 const Operand& operand, 2361 const Operand& operand,
2357 StatusFlags nzcv, 2362 StatusFlags nzcv,
2358 Condition cond, 2363 Condition cond,
2359 ConditionalCompareOp op) { 2364 ConditionalCompareOp op) {
2360 Instr ccmpop; 2365 Instr ccmpop;
2361 DCHECK(!operand.NeedsRelocation(this)); 2366 DCHECK(!operand.NeedsRelocation(this));
2362 if (operand.IsImmediate()) { 2367 if (operand.IsImmediate()) {
2363 int64_t immediate = operand.ImmediateValue(); 2368 int64_t immediate = operand.ImmediateValue();
2364 DCHECK(IsImmConditionalCompare(immediate)); 2369 DCHECK(IsImmConditionalCompare(immediate));
2365 ccmpop = ConditionalCompareImmediateFixed | op | ImmCondCmp(immediate); 2370 ccmpop = ConditionalCompareImmediateFixed | op |
2371 ImmCondCmp(static_cast<unsigned>(immediate));
2366 } else { 2372 } else {
2367 DCHECK(operand.IsShiftedRegister() && (operand.shift_amount() == 0)); 2373 DCHECK(operand.IsShiftedRegister() && (operand.shift_amount() == 0));
2368 ccmpop = ConditionalCompareRegisterFixed | op | Rm(operand.reg()); 2374 ccmpop = ConditionalCompareRegisterFixed | op | Rm(operand.reg());
2369 } 2375 }
2370 Emit(SF(rn) | ccmpop | Cond(cond) | Rn(rn) | Nzcv(nzcv)); 2376 Emit(SF(rn) | ccmpop | Cond(cond) | Rn(rn) | Nzcv(nzcv));
2371 } 2377 }
2372 2378
2373 2379
2374 void Assembler::DataProcessing1Source(const Register& rd, 2380 void Assembler::DataProcessing1Source(const Register& rd,
2375 const Register& rn, 2381 const Register& rn,
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
2495 2501
2496 bool Assembler::IsImmAddSub(int64_t immediate) { 2502 bool Assembler::IsImmAddSub(int64_t immediate) {
2497 return is_uint12(immediate) || 2503 return is_uint12(immediate) ||
2498 (is_uint12(immediate >> 12) && ((immediate & 0xfff) == 0)); 2504 (is_uint12(immediate >> 12) && ((immediate & 0xfff) == 0));
2499 } 2505 }
2500 2506
2501 void Assembler::LoadStore(const CPURegister& rt, 2507 void Assembler::LoadStore(const CPURegister& rt,
2502 const MemOperand& addr, 2508 const MemOperand& addr,
2503 LoadStoreOp op) { 2509 LoadStoreOp op) {
2504 Instr memop = op | Rt(rt) | RnSP(addr.base()); 2510 Instr memop = op | Rt(rt) | RnSP(addr.base());
2505 int64_t offset = addr.offset();
2506 2511
2507 if (addr.IsImmediateOffset()) { 2512 if (addr.IsImmediateOffset()) {
2508 LSDataSize size = CalcLSDataSize(op); 2513 LSDataSize size = CalcLSDataSize(op);
2509 if (IsImmLSScaled(offset, size)) { 2514 if (IsImmLSScaled(addr.offset(), size)) {
2515 int offset = static_cast<int>(addr.offset());
2510 // Use the scaled addressing mode. 2516 // Use the scaled addressing mode.
2511 Emit(LoadStoreUnsignedOffsetFixed | memop | 2517 Emit(LoadStoreUnsignedOffsetFixed | memop |
2512 ImmLSUnsigned(offset >> size)); 2518 ImmLSUnsigned(offset >> size));
2513 } else if (IsImmLSUnscaled(offset)) { 2519 } else if (IsImmLSUnscaled(addr.offset())) {
2520 int offset = static_cast<int>(addr.offset());
2514 // Use the unscaled addressing mode. 2521 // Use the unscaled addressing mode.
2515 Emit(LoadStoreUnscaledOffsetFixed | memop | ImmLS(offset)); 2522 Emit(LoadStoreUnscaledOffsetFixed | memop | ImmLS(offset));
2516 } else { 2523 } else {
2517 // This case is handled in the macro assembler. 2524 // This case is handled in the macro assembler.
2518 UNREACHABLE(); 2525 UNREACHABLE();
2519 } 2526 }
2520 } else if (addr.IsRegisterOffset()) { 2527 } else if (addr.IsRegisterOffset()) {
2521 Extend ext = addr.extend(); 2528 Extend ext = addr.extend();
2522 Shift shift = addr.shift(); 2529 Shift shift = addr.shift();
2523 unsigned shift_amount = addr.shift_amount(); 2530 unsigned shift_amount = addr.shift_amount();
2524 2531
2525 // LSL is encoded in the option field as UXTX. 2532 // LSL is encoded in the option field as UXTX.
2526 if (shift == LSL) { 2533 if (shift == LSL) {
2527 ext = UXTX; 2534 ext = UXTX;
2528 } 2535 }
2529 2536
2530 // Shifts are encoded in one bit, indicating a left shift by the memory 2537 // Shifts are encoded in one bit, indicating a left shift by the memory
2531 // access size. 2538 // access size.
2532 DCHECK((shift_amount == 0) || 2539 DCHECK((shift_amount == 0) ||
2533 (shift_amount == static_cast<unsigned>(CalcLSDataSize(op)))); 2540 (shift_amount == static_cast<unsigned>(CalcLSDataSize(op))));
2534 Emit(LoadStoreRegisterOffsetFixed | memop | Rm(addr.regoffset()) | 2541 Emit(LoadStoreRegisterOffsetFixed | memop | Rm(addr.regoffset()) |
2535 ExtendMode(ext) | ImmShiftLS((shift_amount > 0) ? 1 : 0)); 2542 ExtendMode(ext) | ImmShiftLS((shift_amount > 0) ? 1 : 0));
2536 } else { 2543 } else {
2537 // Pre-index and post-index modes. 2544 // Pre-index and post-index modes.
2538 DCHECK(!rt.Is(addr.base())); 2545 DCHECK(!rt.Is(addr.base()));
2539 if (IsImmLSUnscaled(offset)) { 2546 if (IsImmLSUnscaled(addr.offset())) {
2547 int offset = static_cast<int>(addr.offset());
2540 if (addr.IsPreIndex()) { 2548 if (addr.IsPreIndex()) {
2541 Emit(LoadStorePreIndexFixed | memop | ImmLS(offset)); 2549 Emit(LoadStorePreIndexFixed | memop | ImmLS(offset));
2542 } else { 2550 } else {
2543 DCHECK(addr.IsPostIndex()); 2551 DCHECK(addr.IsPostIndex());
2544 Emit(LoadStorePostIndexFixed | memop | ImmLS(offset)); 2552 Emit(LoadStorePostIndexFixed | memop | ImmLS(offset));
2545 } 2553 }
2546 } else { 2554 } else {
2547 // This case is handled in the macro assembler. 2555 // This case is handled in the macro assembler.
2548 UNREACHABLE(); 2556 UNREACHABLE();
2549 } 2557 }
(...skipping 11 matching lines...) Expand all
2561 return offset_is_size_multiple && is_uint12(offset >> size); 2569 return offset_is_size_multiple && is_uint12(offset >> size);
2562 } 2570 }
2563 2571
2564 2572
2565 bool Assembler::IsImmLSPair(int64_t offset, LSDataSize size) { 2573 bool Assembler::IsImmLSPair(int64_t offset, LSDataSize size) {
2566 bool offset_is_size_multiple = (((offset >> size) << size) == offset); 2574 bool offset_is_size_multiple = (((offset >> size) << size) == offset);
2567 return offset_is_size_multiple && is_int7(offset >> size); 2575 return offset_is_size_multiple && is_int7(offset >> size);
2568 } 2576 }
2569 2577
2570 2578
2579 bool Assembler::IsImmLLiteral(int64_t offset) {
2580 int inst_size = static_cast<int>(kInstructionSizeLog2);
2581 bool offset_is_inst_multiple =
2582 (((offset >> inst_size) << inst_size) == offset);
2583 return offset_is_inst_multiple && is_intn(offset, ImmLLiteral_width);
2584 }
2585
2586
2571 // Test if a given value can be encoded in the immediate field of a logical 2587 // Test if a given value can be encoded in the immediate field of a logical
2572 // instruction. 2588 // instruction.
2573 // If it can be encoded, the function returns true, and values pointed to by n, 2589 // If it can be encoded, the function returns true, and values pointed to by n,
2574 // imm_s and imm_r are updated with immediates encoded in the format required 2590 // imm_s and imm_r are updated with immediates encoded in the format required
2575 // by the corresponding fields in the logical instruction. 2591 // by the corresponding fields in the logical instruction.
2576 // If it can not be encoded, the function returns false, and the values pointed 2592 // If it can not be encoded, the function returns false, and the values pointed
2577 // to by n, imm_s and imm_r are undefined. 2593 // to by n, imm_s and imm_r are undefined.
2578 bool Assembler::IsImmLogical(uint64_t value, 2594 bool Assembler::IsImmLogical(uint64_t value,
2579 unsigned width, 2595 unsigned width,
2580 unsigned* n, 2596 unsigned* n,
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
2842 desc.buffer_size = buffer_size_ + 1 * MB; 2858 desc.buffer_size = buffer_size_ + 1 * MB;
2843 } 2859 }
2844 CHECK_GT(desc.buffer_size, 0); // No overflow. 2860 CHECK_GT(desc.buffer_size, 0); // No overflow.
2845 2861
2846 byte* buffer = reinterpret_cast<byte*>(buffer_); 2862 byte* buffer = reinterpret_cast<byte*>(buffer_);
2847 2863
2848 // Set up new buffer. 2864 // Set up new buffer.
2849 desc.buffer = NewArray<byte>(desc.buffer_size); 2865 desc.buffer = NewArray<byte>(desc.buffer_size);
2850 2866
2851 desc.instr_size = pc_offset(); 2867 desc.instr_size = pc_offset();
2852 desc.reloc_size = (buffer + buffer_size_) - reloc_info_writer.pos(); 2868 desc.reloc_size =
2869 static_cast<int>((buffer + buffer_size_) - reloc_info_writer.pos());
2853 2870
2854 // Copy the data. 2871 // Copy the data.
2855 intptr_t pc_delta = desc.buffer - buffer; 2872 intptr_t pc_delta = desc.buffer - buffer;
2856 intptr_t rc_delta = (desc.buffer + desc.buffer_size) - 2873 intptr_t rc_delta = (desc.buffer + desc.buffer_size) -
2857 (buffer + buffer_size_); 2874 (buffer + buffer_size_);
2858 memmove(desc.buffer, buffer, desc.instr_size); 2875 memmove(desc.buffer, buffer, desc.instr_size);
2859 memmove(reloc_info_writer.pos() + rc_delta, 2876 memmove(reloc_info_writer.pos() + rc_delta,
2860 reloc_info_writer.pos(), desc.reloc_size); 2877 reloc_info_writer.pos(), desc.reloc_size);
2861 2878
2862 // Switch buffers. 2879 // Switch buffers.
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
3058 #endif 3075 #endif
3059 3076
3060 it_to_delete = it++; 3077 it_to_delete = it++;
3061 unresolved_branches_.erase(it_to_delete); 3078 unresolved_branches_.erase(it_to_delete);
3062 } else { 3079 } else {
3063 ++it; 3080 ++it;
3064 } 3081 }
3065 } 3082 }
3066 3083
3067 // Record the veneer pool size. 3084 // Record the veneer pool size.
3068 int pool_size = SizeOfCodeGeneratedSince(&size_check); 3085 int pool_size = static_cast<int>(SizeOfCodeGeneratedSince(&size_check));
3069 RecordVeneerPool(veneer_pool_relocinfo_loc, pool_size); 3086 RecordVeneerPool(veneer_pool_relocinfo_loc, pool_size);
3070 3087
3071 if (unresolved_branches_.empty()) { 3088 if (unresolved_branches_.empty()) {
3072 next_veneer_pool_check_ = kMaxInt; 3089 next_veneer_pool_check_ = kMaxInt;
3073 } else { 3090 } else {
3074 next_veneer_pool_check_ = 3091 next_veneer_pool_check_ =
3075 unresolved_branches_first_limit() - kVeneerDistanceCheckMargin; 3092 unresolved_branches_first_limit() - kVeneerDistanceCheckMargin;
3076 } 3093 }
3077 3094
3078 bind(&end); 3095 bind(&end);
(...skipping 27 matching lines...) Expand all
3106 if (force_emit || ShouldEmitVeneers(margin)) { 3123 if (force_emit || ShouldEmitVeneers(margin)) {
3107 EmitVeneers(force_emit, require_jump, margin); 3124 EmitVeneers(force_emit, require_jump, margin);
3108 } else { 3125 } else {
3109 next_veneer_pool_check_ = 3126 next_veneer_pool_check_ =
3110 unresolved_branches_first_limit() - kVeneerDistanceCheckMargin; 3127 unresolved_branches_first_limit() - kVeneerDistanceCheckMargin;
3111 } 3128 }
3112 } 3129 }
3113 3130
3114 3131
3115 int Assembler::buffer_space() const { 3132 int Assembler::buffer_space() const {
3116 return reloc_info_writer.pos() - reinterpret_cast<byte*>(pc_); 3133 return static_cast<int>(reloc_info_writer.pos() -
3134 reinterpret_cast<byte*>(pc_));
3117 } 3135 }
3118 3136
3119 3137
3120 void Assembler::RecordConstPool(int size) { 3138 void Assembler::RecordConstPool(int size) {
3121 // We only need this for debugger support, to correctly compute offsets in the 3139 // We only need this for debugger support, to correctly compute offsets in the
3122 // code. 3140 // code.
3123 RecordRelocInfo(RelocInfo::CONST_POOL, static_cast<intptr_t>(size)); 3141 RecordRelocInfo(RelocInfo::CONST_POOL, static_cast<intptr_t>(size));
3124 } 3142 }
3125 3143
3126 3144
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
3167 movz(scratch, (target_offset >> 16) & 0xFFFF, 16); 3185 movz(scratch, (target_offset >> 16) & 0xFFFF, 16);
3168 movk(scratch, (target_offset >> 32) & 0xFFFF, 32); 3186 movk(scratch, (target_offset >> 32) & 0xFFFF, 32);
3169 DCHECK((target_offset >> 48) == 0); 3187 DCHECK((target_offset >> 48) == 0);
3170 add(rd, rd, scratch); 3188 add(rd, rd, scratch);
3171 } 3189 }
3172 3190
3173 3191
3174 } } // namespace v8::internal 3192 } } // namespace v8::internal
3175 3193
3176 #endif // V8_TARGET_ARCH_ARM64 3194 #endif // V8_TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « src/arm64/assembler-arm64.h ('k') | src/arm64/assembler-arm64-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698