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/arm/macro-assembler-arm.h" | 7 #include "src/arm/macro-assembler-arm.h" |
8 #include "src/compiler/code-generator-impl.h" | 8 #include "src/compiler/code-generator-impl.h" |
9 #include "src/compiler/gap-resolver.h" | 9 #include "src/compiler/gap-resolver.h" |
10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 OutOfLineLoadInteger(CodeGenerator* gen, Register result) | 191 OutOfLineLoadInteger(CodeGenerator* gen, Register result) |
192 : OutOfLineCode(gen), result_(result) {} | 192 : OutOfLineCode(gen), result_(result) {} |
193 | 193 |
194 void Generate() final { __ mov(result_, Operand::Zero()); } | 194 void Generate() final { __ mov(result_, Operand::Zero()); } |
195 | 195 |
196 private: | 196 private: |
197 Register const result_; | 197 Register const result_; |
198 }; | 198 }; |
199 | 199 |
200 | 200 |
| 201 class OutOfLineRecordWrite final : public OutOfLineCode { |
| 202 public: |
| 203 OutOfLineRecordWrite(CodeGenerator* gen, Register object, Register index, |
| 204 Register value, Register scratch0, Register scratch1, |
| 205 RecordWriteMode mode) |
| 206 : OutOfLineCode(gen), |
| 207 object_(object), |
| 208 index_(index), |
| 209 value_(value), |
| 210 scratch0_(scratch0), |
| 211 scratch1_(scratch1), |
| 212 mode_(mode) {} |
| 213 |
| 214 void Generate() final { |
| 215 if (mode_ > RecordWriteMode::kValueIsPointer) { |
| 216 __ JumpIfSmi(value_, exit()); |
| 217 } |
| 218 if (mode_ > RecordWriteMode::kValueIsMap) { |
| 219 __ CheckPageFlag(value_, scratch0_, |
| 220 MemoryChunk::kPointersToHereAreInterestingMask, eq, |
| 221 exit()); |
| 222 } |
| 223 SaveFPRegsMode const save_fp_mode = |
| 224 frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs; |
| 225 // TODO(turbofan): Once we get frame elision working, we need to save |
| 226 // and restore lr properly here if the frame was elided. |
| 227 RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_, |
| 228 EMIT_REMEMBERED_SET, save_fp_mode); |
| 229 __ add(scratch1_, object_, index_); |
| 230 __ CallStub(&stub); |
| 231 } |
| 232 |
| 233 private: |
| 234 Register const object_; |
| 235 Register const index_; |
| 236 Register const value_; |
| 237 Register const scratch0_; |
| 238 Register const scratch1_; |
| 239 RecordWriteMode const mode_; |
| 240 }; |
| 241 |
| 242 |
201 Condition FlagsConditionToCondition(FlagsCondition condition) { | 243 Condition FlagsConditionToCondition(FlagsCondition condition) { |
202 switch (condition) { | 244 switch (condition) { |
203 case kEqual: | 245 case kEqual: |
204 return eq; | 246 return eq; |
205 case kNotEqual: | 247 case kNotEqual: |
206 return ne; | 248 return ne; |
207 case kSignedLessThan: | 249 case kSignedLessThan: |
208 return lt; | 250 return lt; |
209 case kSignedGreaterThanOrEqual: | 251 case kSignedGreaterThanOrEqual: |
210 return ge; | 252 return ge; |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
436 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 478 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
437 break; | 479 break; |
438 case kArchFramePointer: | 480 case kArchFramePointer: |
439 __ mov(i.OutputRegister(), fp); | 481 __ mov(i.OutputRegister(), fp); |
440 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 482 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
441 break; | 483 break; |
442 case kArchTruncateDoubleToI: | 484 case kArchTruncateDoubleToI: |
443 __ TruncateDoubleToI(i.OutputRegister(), i.InputFloat64Register(0)); | 485 __ TruncateDoubleToI(i.OutputRegister(), i.InputFloat64Register(0)); |
444 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 486 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
445 break; | 487 break; |
| 488 case kArchRecordWrite: { |
| 489 RecordWriteMode mode = |
| 490 static_cast<RecordWriteMode>(MiscField::decode(instr->opcode())); |
| 491 Register object = i.InputRegister(0); |
| 492 Register index = i.InputRegister(1); |
| 493 Register value = |
| 494 (mode > RecordWriteMode::kValueIsMap) ? i.InputRegister(2) : no_reg; |
| 495 Register scratch0 = i.TempRegister(0); |
| 496 Register scratch1 = i.TempRegister(1); |
| 497 auto ool = new (zone()) OutOfLineRecordWrite(this, object, index, value, |
| 498 scratch0, scratch1, mode); |
| 499 __ CheckPageFlag(object, scratch0, |
| 500 MemoryChunk::kPointersFromHereAreInterestingMask, ne, |
| 501 ool->entry()); |
| 502 __ bind(ool->exit()); |
| 503 break; |
| 504 } |
446 case kArmAdd: | 505 case kArmAdd: |
447 __ add(i.OutputRegister(), i.InputRegister(0), i.InputOperand2(1), | 506 __ add(i.OutputRegister(), i.InputRegister(0), i.InputOperand2(1), |
448 i.OutputSBit()); | 507 i.OutputSBit()); |
449 break; | 508 break; |
450 case kArmAnd: | 509 case kArmAnd: |
451 __ and_(i.OutputRegister(), i.InputRegister(0), i.InputOperand2(1), | 510 __ and_(i.OutputRegister(), i.InputRegister(0), i.InputOperand2(1), |
452 i.OutputSBit()); | 511 i.OutputSBit()); |
453 break; | 512 break; |
454 case kArmBic: | 513 case kArmBic: |
455 __ bic(i.OutputRegister(), i.InputRegister(0), i.InputOperand2(1), | 514 __ bic(i.OutputRegister(), i.InputRegister(0), i.InputOperand2(1), |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
841 __ push(i.InputRegister(0)); | 900 __ push(i.InputRegister(0)); |
842 } | 901 } |
843 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 902 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
844 break; | 903 break; |
845 case kArmPoke: { | 904 case kArmPoke: { |
846 int const slot = MiscField::decode(instr->opcode()); | 905 int const slot = MiscField::decode(instr->opcode()); |
847 __ str(i.InputRegister(0), MemOperand(sp, slot * kPointerSize)); | 906 __ str(i.InputRegister(0), MemOperand(sp, slot * kPointerSize)); |
848 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 907 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
849 break; | 908 break; |
850 } | 909 } |
851 case kArmStoreWriteBarrier: { | |
852 Register object = i.InputRegister(0); | |
853 Register index = i.InputRegister(1); | |
854 Register value = i.InputRegister(2); | |
855 __ add(index, object, index); | |
856 __ str(value, MemOperand(index)); | |
857 SaveFPRegsMode mode = | |
858 frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs; | |
859 LinkRegisterStatus lr_status = kLRHasNotBeenSaved; | |
860 __ RecordWrite(object, index, value, lr_status, mode); | |
861 DCHECK_EQ(LeaveCC, i.OutputSBit()); | |
862 break; | |
863 } | |
864 case kCheckedLoadInt8: | 910 case kCheckedLoadInt8: |
865 ASSEMBLE_CHECKED_LOAD_INTEGER(ldrsb); | 911 ASSEMBLE_CHECKED_LOAD_INTEGER(ldrsb); |
866 break; | 912 break; |
867 case kCheckedLoadUint8: | 913 case kCheckedLoadUint8: |
868 ASSEMBLE_CHECKED_LOAD_INTEGER(ldrb); | 914 ASSEMBLE_CHECKED_LOAD_INTEGER(ldrb); |
869 break; | 915 break; |
870 case kCheckedLoadInt16: | 916 case kCheckedLoadInt16: |
871 ASSEMBLE_CHECKED_LOAD_INTEGER(ldrsh); | 917 ASSEMBLE_CHECKED_LOAD_INTEGER(ldrsh); |
872 break; | 918 break; |
873 case kCheckedLoadUint16: | 919 case kCheckedLoadUint16: |
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1281 padding_size -= v8::internal::Assembler::kInstrSize; | 1327 padding_size -= v8::internal::Assembler::kInstrSize; |
1282 } | 1328 } |
1283 } | 1329 } |
1284 } | 1330 } |
1285 | 1331 |
1286 #undef __ | 1332 #undef __ |
1287 | 1333 |
1288 } // namespace compiler | 1334 } // namespace compiler |
1289 } // namespace internal | 1335 } // namespace internal |
1290 } // namespace v8 | 1336 } // namespace v8 |
OLD | NEW |