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 |