| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
| 6 | 6 |
| 7 #include "src/compiler/code-generator-impl.h" | 7 #include "src/compiler/code-generator-impl.h" |
| 8 #include "src/compiler/gap-resolver.h" | 8 #include "src/compiler/gap-resolver.h" |
| 9 #include "src/compiler/node-matchers.h" | 9 #include "src/compiler/node-matchers.h" |
| 10 #include "src/compiler/osr.h" | 10 #include "src/compiler/osr.h" |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 150 OutOfLineLoadZero(CodeGenerator* gen, Register result) | 150 OutOfLineLoadZero(CodeGenerator* gen, Register result) |
| 151 : OutOfLineCode(gen), result_(result) {} | 151 : OutOfLineCode(gen), result_(result) {} |
| 152 | 152 |
| 153 void Generate() final { __ li(result_, Operand::Zero()); } | 153 void Generate() final { __ li(result_, Operand::Zero()); } |
| 154 | 154 |
| 155 private: | 155 private: |
| 156 Register const result_; | 156 Register const result_; |
| 157 }; | 157 }; |
| 158 | 158 |
| 159 | 159 |
| 160 class OutOfLineRecordWrite final : public OutOfLineCode { |
| 161 public: |
| 162 OutOfLineRecordWrite(CodeGenerator* gen, Register object, Register offset, |
| 163 Register value, Register scratch0, Register scratch1, |
| 164 RecordWriteMode mode) |
| 165 : OutOfLineCode(gen), |
| 166 object_(object), |
| 167 offset_(offset), |
| 168 value_(value), |
| 169 scratch0_(scratch0), |
| 170 scratch1_(scratch1), |
| 171 mode_(mode) {} |
| 172 |
| 173 void Generate() final { |
| 174 if (mode_ > RecordWriteMode::kValueIsPointer) { |
| 175 __ JumpIfSmi(value_, exit()); |
| 176 } |
| 177 if (mode_ > RecordWriteMode::kValueIsMap) { |
| 178 __ CheckPageFlag(value_, scratch0_, |
| 179 MemoryChunk::kPointersToHereAreInterestingMask, eq, |
| 180 exit()); |
| 181 } |
| 182 SaveFPRegsMode const save_fp_mode = |
| 183 frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs; |
| 184 // TODO(turbofan): Once we get frame elision working, we need to save |
| 185 // and restore lr properly here if the frame was elided. |
| 186 RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_, |
| 187 EMIT_REMEMBERED_SET, save_fp_mode); |
| 188 __ add(scratch1_, object_, offset_); |
| 189 __ CallStub(&stub); |
| 190 } |
| 191 |
| 192 private: |
| 193 Register const object_; |
| 194 Register const offset_; |
| 195 Register const value_; |
| 196 Register const scratch0_; |
| 197 Register const scratch1_; |
| 198 RecordWriteMode const mode_; |
| 199 }; |
| 200 |
| 201 |
| 160 Condition FlagsConditionToCondition(FlagsCondition condition) { | 202 Condition FlagsConditionToCondition(FlagsCondition condition) { |
| 161 switch (condition) { | 203 switch (condition) { |
| 162 case kEqual: | 204 case kEqual: |
| 163 return eq; | 205 return eq; |
| 164 case kNotEqual: | 206 case kNotEqual: |
| 165 return ne; | 207 return ne; |
| 166 case kSignedLessThan: | 208 case kSignedLessThan: |
| 167 case kUnsignedLessThan: | 209 case kUnsignedLessThan: |
| 168 return lt; | 210 return lt; |
| 169 case kSignedGreaterThanOrEqual: | 211 case kSignedGreaterThanOrEqual: |
| (...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 556 if (mode == kMode_MRI) { \ | 598 if (mode == kMode_MRI) { \ |
| 557 __ asm_instr(value, operand); \ | 599 __ asm_instr(value, operand); \ |
| 558 } else { \ | 600 } else { \ |
| 559 __ asm_instrx(value, operand); \ | 601 __ asm_instrx(value, operand); \ |
| 560 } \ | 602 } \ |
| 561 __ bind(&done); \ | 603 __ bind(&done); \ |
| 562 DCHECK_EQ(LeaveRC, i.OutputRCBit()); \ | 604 DCHECK_EQ(LeaveRC, i.OutputRCBit()); \ |
| 563 } while (0) | 605 } while (0) |
| 564 | 606 |
| 565 | 607 |
| 566 #define ASSEMBLE_STORE_WRITE_BARRIER() \ | |
| 567 do { \ | |
| 568 Register object = i.InputRegister(0); \ | |
| 569 Register index = i.InputRegister(1); \ | |
| 570 Register value = i.InputRegister(2); \ | |
| 571 __ add(index, object, index); \ | |
| 572 __ StoreP(value, MemOperand(index)); \ | |
| 573 SaveFPRegsMode mode = \ | |
| 574 frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs; \ | |
| 575 LinkRegisterStatus lr_status = kLRHasNotBeenSaved; \ | |
| 576 __ RecordWrite(object, index, value, lr_status, mode); \ | |
| 577 DCHECK_EQ(LeaveRC, i.OutputRCBit()); \ | |
| 578 } while (0) | |
| 579 | |
| 580 | |
| 581 void CodeGenerator::AssembleDeconstructActivationRecord() { | 608 void CodeGenerator::AssembleDeconstructActivationRecord() { |
| 582 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 609 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
| 583 int stack_slots = frame()->GetSpillSlotCount(); | 610 int stack_slots = frame()->GetSpillSlotCount(); |
| 584 if (descriptor->IsJSFunctionCall() || stack_slots > 0) { | 611 if (descriptor->IsJSFunctionCall() || stack_slots > 0) { |
| 585 __ LeaveFrame(StackFrame::MANUAL); | 612 __ LeaveFrame(StackFrame::MANUAL); |
| 586 } | 613 } |
| 587 } | 614 } |
| 588 | 615 |
| 589 | 616 |
| 590 // Assembles an instruction after register allocation, producing machine code. | 617 // Assembles an instruction after register allocation, producing machine code. |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 707 break; | 734 break; |
| 708 case kArchFramePointer: | 735 case kArchFramePointer: |
| 709 __ mr(i.OutputRegister(), fp); | 736 __ mr(i.OutputRegister(), fp); |
| 710 DCHECK_EQ(LeaveRC, i.OutputRCBit()); | 737 DCHECK_EQ(LeaveRC, i.OutputRCBit()); |
| 711 break; | 738 break; |
| 712 case kArchTruncateDoubleToI: | 739 case kArchTruncateDoubleToI: |
| 713 // TODO(mbrandy): move slow call to stub out of line. | 740 // TODO(mbrandy): move slow call to stub out of line. |
| 714 __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0)); | 741 __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0)); |
| 715 DCHECK_EQ(LeaveRC, i.OutputRCBit()); | 742 DCHECK_EQ(LeaveRC, i.OutputRCBit()); |
| 716 break; | 743 break; |
| 744 case kArchStoreWithWriteBarrier: { |
| 745 RecordWriteMode mode = |
| 746 static_cast<RecordWriteMode>(MiscField::decode(instr->opcode())); |
| 747 Register object = i.InputRegister(0); |
| 748 Register offset = i.InputRegister(1); |
| 749 Register value = i.InputRegister(2); |
| 750 Register scratch0 = i.TempRegister(0); |
| 751 Register scratch1 = i.TempRegister(1); |
| 752 auto ool = new (zone()) OutOfLineRecordWrite(this, object, offset, value, |
| 753 scratch0, scratch1, mode); |
| 754 __ StorePX(value, MemOperand(object, offset)); |
| 755 __ CheckPageFlag(object, scratch0, |
| 756 MemoryChunk::kPointersFromHereAreInterestingMask, ne, |
| 757 ool->entry()); |
| 758 __ bind(ool->exit()); |
| 759 break; |
| 760 } |
| 717 case kPPC_And: | 761 case kPPC_And: |
| 718 if (HasRegisterInput(instr, 1)) { | 762 if (HasRegisterInput(instr, 1)) { |
| 719 __ and_(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1), | 763 __ and_(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1), |
| 720 i.OutputRCBit()); | 764 i.OutputRCBit()); |
| 721 } else { | 765 } else { |
| 722 __ andi(i.OutputRegister(), i.InputRegister(0), i.InputImmediate(1)); | 766 __ andi(i.OutputRegister(), i.InputRegister(0), i.InputImmediate(1)); |
| 723 } | 767 } |
| 724 break; | 768 break; |
| 725 case kPPC_AndComplement: | 769 case kPPC_AndComplement: |
| 726 __ andc(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1), | 770 __ andc(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1), |
| (...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1148 case kPPC_StoreWord64: | 1192 case kPPC_StoreWord64: |
| 1149 ASSEMBLE_STORE_INTEGER(std, stdx); | 1193 ASSEMBLE_STORE_INTEGER(std, stdx); |
| 1150 break; | 1194 break; |
| 1151 #endif | 1195 #endif |
| 1152 case kPPC_StoreFloat32: | 1196 case kPPC_StoreFloat32: |
| 1153 ASSEMBLE_STORE_FLOAT32(); | 1197 ASSEMBLE_STORE_FLOAT32(); |
| 1154 break; | 1198 break; |
| 1155 case kPPC_StoreDouble: | 1199 case kPPC_StoreDouble: |
| 1156 ASSEMBLE_STORE_DOUBLE(); | 1200 ASSEMBLE_STORE_DOUBLE(); |
| 1157 break; | 1201 break; |
| 1158 case kPPC_StoreWriteBarrier: | |
| 1159 ASSEMBLE_STORE_WRITE_BARRIER(); | |
| 1160 break; | |
| 1161 case kCheckedLoadInt8: | 1202 case kCheckedLoadInt8: |
| 1162 ASSEMBLE_CHECKED_LOAD_INTEGER(lbz, lbzx); | 1203 ASSEMBLE_CHECKED_LOAD_INTEGER(lbz, lbzx); |
| 1163 __ extsb(i.OutputRegister(), i.OutputRegister()); | 1204 __ extsb(i.OutputRegister(), i.OutputRegister()); |
| 1164 break; | 1205 break; |
| 1165 case kCheckedLoadUint8: | 1206 case kCheckedLoadUint8: |
| 1166 ASSEMBLE_CHECKED_LOAD_INTEGER(lbz, lbzx); | 1207 ASSEMBLE_CHECKED_LOAD_INTEGER(lbz, lbzx); |
| 1167 break; | 1208 break; |
| 1168 case kCheckedLoadInt16: | 1209 case kCheckedLoadInt16: |
| 1169 ASSEMBLE_CHECKED_LOAD_INTEGER(lha, lhax); | 1210 ASSEMBLE_CHECKED_LOAD_INTEGER(lha, lhax); |
| 1170 break; | 1211 break; |
| (...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1658 padding_size -= v8::internal::Assembler::kInstrSize; | 1699 padding_size -= v8::internal::Assembler::kInstrSize; |
| 1659 } | 1700 } |
| 1660 } | 1701 } |
| 1661 } | 1702 } |
| 1662 | 1703 |
| 1663 #undef __ | 1704 #undef __ |
| 1664 | 1705 |
| 1665 } // namespace compiler | 1706 } // namespace compiler |
| 1666 } // namespace internal | 1707 } // namespace internal |
| 1667 } // namespace v8 | 1708 } // namespace v8 |
| OLD | NEW |