OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_MIPS64 | 7 #if V8_TARGET_ARCH_MIPS64 |
8 | 8 |
9 // Note on Mips implementation: | 9 // Note on Mips implementation: |
10 // | 10 // |
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 int no_frame_start = masm_->pc_offset(); | 493 int no_frame_start = masm_->pc_offset(); |
494 masm_->MultiPop(static_cast<RegList>(fp.bit() | ra.bit())); | 494 masm_->MultiPop(static_cast<RegList>(fp.bit() | ra.bit())); |
495 masm_->Daddu(sp, sp, Operand(sp_delta)); | 495 masm_->Daddu(sp, sp, Operand(sp_delta)); |
496 masm_->Jump(ra); | 496 masm_->Jump(ra); |
497 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); | 497 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); |
498 } | 498 } |
499 } | 499 } |
500 } | 500 } |
501 | 501 |
502 | 502 |
| 503 void FullCodeGenerator::EffectContext::Plug(Variable* var) const { |
| 504 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 505 } |
| 506 |
| 507 |
| 508 void FullCodeGenerator::AccumulatorValueContext::Plug(Variable* var) const { |
| 509 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 510 codegen()->GetVar(result_register(), var); |
| 511 } |
| 512 |
| 513 |
503 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { | 514 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { |
504 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 515 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
505 codegen()->GetVar(result_register(), var); | 516 codegen()->GetVar(result_register(), var); |
506 __ push(result_register()); | 517 __ push(result_register()); |
507 } | 518 } |
508 | 519 |
509 | 520 |
| 521 void FullCodeGenerator::TestContext::Plug(Variable* var) const { |
| 522 // For simplicity we always test the accumulator register. |
| 523 codegen()->GetVar(result_register(), var); |
| 524 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); |
| 525 codegen()->DoTest(this); |
| 526 } |
| 527 |
| 528 |
510 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { | 529 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { |
511 } | 530 } |
512 | 531 |
513 | 532 |
514 void FullCodeGenerator::AccumulatorValueContext::Plug( | 533 void FullCodeGenerator::AccumulatorValueContext::Plug( |
515 Heap::RootListIndex index) const { | 534 Heap::RootListIndex index) const { |
516 __ LoadRoot(result_register(), index); | 535 __ LoadRoot(result_register(), index); |
517 } | 536 } |
518 | 537 |
519 | 538 |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
660 } | 679 } |
661 | 680 |
662 | 681 |
663 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, | 682 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, |
664 Label* materialize_false) const { | 683 Label* materialize_false) const { |
665 DCHECK(materialize_true == true_label_); | 684 DCHECK(materialize_true == true_label_); |
666 DCHECK(materialize_false == false_label_); | 685 DCHECK(materialize_false == false_label_); |
667 } | 686 } |
668 | 687 |
669 | 688 |
| 689 void FullCodeGenerator::EffectContext::Plug(bool flag) const { |
| 690 } |
| 691 |
| 692 |
670 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { | 693 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { |
671 Heap::RootListIndex value_root_index = | 694 Heap::RootListIndex value_root_index = |
672 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; | 695 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; |
673 __ LoadRoot(result_register(), value_root_index); | 696 __ LoadRoot(result_register(), value_root_index); |
674 } | 697 } |
675 | 698 |
676 | 699 |
677 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { | 700 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { |
678 Heap::RootListIndex value_root_index = | 701 Heap::RootListIndex value_root_index = |
679 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; | 702 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
932 __ Push(cp, a2, a1); | 955 __ Push(cp, a2, a1); |
933 // Push initial value for function declaration. | 956 // Push initial value for function declaration. |
934 VisitForStackValue(declaration->fun()); | 957 VisitForStackValue(declaration->fun()); |
935 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); | 958 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); |
936 break; | 959 break; |
937 } | 960 } |
938 } | 961 } |
939 } | 962 } |
940 | 963 |
941 | 964 |
| 965 void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) { |
| 966 VariableProxy* proxy = declaration->proxy(); |
| 967 Variable* variable = proxy->var(); |
| 968 switch (variable->location()) { |
| 969 case VariableLocation::GLOBAL: |
| 970 case VariableLocation::UNALLOCATED: |
| 971 // TODO(rossberg) |
| 972 break; |
| 973 |
| 974 case VariableLocation::CONTEXT: { |
| 975 Comment cmnt(masm_, "[ ImportDeclaration"); |
| 976 EmitDebugCheckDeclarationContext(variable); |
| 977 // TODO(rossberg) |
| 978 break; |
| 979 } |
| 980 |
| 981 case VariableLocation::PARAMETER: |
| 982 case VariableLocation::LOCAL: |
| 983 case VariableLocation::LOOKUP: |
| 984 UNREACHABLE(); |
| 985 } |
| 986 } |
| 987 |
| 988 |
| 989 void FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* declaration) { |
| 990 // TODO(rossberg) |
| 991 } |
| 992 |
| 993 |
942 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 994 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
943 // Call the runtime to declare the globals. | 995 // Call the runtime to declare the globals. |
944 // The context is the first argument. | 996 // The context is the first argument. |
945 __ li(a1, Operand(pairs)); | 997 __ li(a1, Operand(pairs)); |
946 __ li(a0, Operand(Smi::FromInt(DeclareGlobalsFlags()))); | 998 __ li(a0, Operand(Smi::FromInt(DeclareGlobalsFlags()))); |
947 __ Push(cp, a1, a0); | 999 __ Push(cp, a1, a0); |
948 __ CallRuntime(Runtime::kDeclareGlobals, 3); | 1000 __ CallRuntime(Runtime::kDeclareGlobals, 3); |
949 // Return value is ignored. | 1001 // Return value is ignored. |
950 } | 1002 } |
951 | 1003 |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1257 __ li(a0, Operand(info)); | 1309 __ li(a0, Operand(info)); |
1258 __ LoadRoot(a1, pretenure ? Heap::kTrueValueRootIndex | 1310 __ LoadRoot(a1, pretenure ? Heap::kTrueValueRootIndex |
1259 : Heap::kFalseValueRootIndex); | 1311 : Heap::kFalseValueRootIndex); |
1260 __ Push(cp, a0, a1); | 1312 __ Push(cp, a0, a1); |
1261 __ CallRuntime(Runtime::kNewClosure, 3); | 1313 __ CallRuntime(Runtime::kNewClosure, 3); |
1262 } | 1314 } |
1263 context()->Plug(v0); | 1315 context()->Plug(v0); |
1264 } | 1316 } |
1265 | 1317 |
1266 | 1318 |
| 1319 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { |
| 1320 Comment cmnt(masm_, "[ VariableProxy"); |
| 1321 EmitVariableLoad(expr); |
| 1322 } |
| 1323 |
| 1324 |
1267 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, | 1325 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, |
1268 int offset, | 1326 int offset, |
1269 FeedbackVectorICSlot slot) { | 1327 FeedbackVectorICSlot slot) { |
1270 if (NeedsHomeObject(initializer)) { | 1328 if (NeedsHomeObject(initializer)) { |
1271 __ ld(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); | 1329 __ ld(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); |
1272 __ li(StoreDescriptor::NameRegister(), | 1330 __ li(StoreDescriptor::NameRegister(), |
1273 Operand(isolate()->factory()->home_object_symbol())); | 1331 Operand(isolate()->factory()->home_object_symbol())); |
1274 __ ld(StoreDescriptor::ValueRegister(), | 1332 __ ld(StoreDescriptor::ValueRegister(), |
1275 MemOperand(sp, offset * kPointerSize)); | 1333 MemOperand(sp, offset * kPointerSize)); |
1276 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); | 1334 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
(...skipping 2552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3829 __ bind(&null); | 3887 __ bind(&null); |
3830 __ LoadRoot(v0, Heap::kNullValueRootIndex); | 3888 __ LoadRoot(v0, Heap::kNullValueRootIndex); |
3831 | 3889 |
3832 // All done. | 3890 // All done. |
3833 __ bind(&done); | 3891 __ bind(&done); |
3834 | 3892 |
3835 context()->Plug(v0); | 3893 context()->Plug(v0); |
3836 } | 3894 } |
3837 | 3895 |
3838 | 3896 |
| 3897 void FullCodeGenerator::EmitSubString(CallRuntime* expr) { |
| 3898 // Load the arguments on the stack and call the stub. |
| 3899 SubStringStub stub(isolate()); |
| 3900 ZoneList<Expression*>* args = expr->arguments(); |
| 3901 DCHECK(args->length() == 3); |
| 3902 VisitForStackValue(args->at(0)); |
| 3903 VisitForStackValue(args->at(1)); |
| 3904 VisitForStackValue(args->at(2)); |
| 3905 __ CallStub(&stub); |
| 3906 context()->Plug(v0); |
| 3907 } |
| 3908 |
| 3909 |
| 3910 void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) { |
| 3911 // Load the arguments on the stack and call the stub. |
| 3912 RegExpExecStub stub(isolate()); |
| 3913 ZoneList<Expression*>* args = expr->arguments(); |
| 3914 DCHECK(args->length() == 4); |
| 3915 VisitForStackValue(args->at(0)); |
| 3916 VisitForStackValue(args->at(1)); |
| 3917 VisitForStackValue(args->at(2)); |
| 3918 VisitForStackValue(args->at(3)); |
| 3919 __ CallStub(&stub); |
| 3920 context()->Plug(v0); |
| 3921 } |
| 3922 |
| 3923 |
3839 void FullCodeGenerator::EmitValueOf(CallRuntime* expr) { | 3924 void FullCodeGenerator::EmitValueOf(CallRuntime* expr) { |
3840 ZoneList<Expression*>* args = expr->arguments(); | 3925 ZoneList<Expression*>* args = expr->arguments(); |
3841 DCHECK(args->length() == 1); | 3926 DCHECK(args->length() == 1); |
3842 | 3927 |
3843 VisitForAccumulatorValue(args->at(0)); // Load the object. | 3928 VisitForAccumulatorValue(args->at(0)); // Load the object. |
3844 | 3929 |
3845 Label done; | 3930 Label done; |
3846 // If the object is a smi return the object. | 3931 // If the object is a smi return the object. |
3847 __ JumpIfSmi(v0, &done); | 3932 __ JumpIfSmi(v0, &done); |
3848 // If the object is not a value type, return the object. | 3933 // If the object is not a value type, return the object. |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3985 string, | 4070 string, |
3986 Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); | 4071 Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); |
3987 __ dsra(index, index, 32 - 1); | 4072 __ dsra(index, index, 32 - 1); |
3988 __ Daddu(at, at, index); | 4073 __ Daddu(at, at, index); |
3989 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); | 4074 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); |
3990 __ sh(value, MemOperand(at)); | 4075 __ sh(value, MemOperand(at)); |
3991 context()->Plug(string); | 4076 context()->Plug(string); |
3992 } | 4077 } |
3993 | 4078 |
3994 | 4079 |
| 4080 void FullCodeGenerator::EmitMathPow(CallRuntime* expr) { |
| 4081 // Load the arguments on the stack and call the runtime function. |
| 4082 ZoneList<Expression*>* args = expr->arguments(); |
| 4083 DCHECK(args->length() == 2); |
| 4084 VisitForStackValue(args->at(0)); |
| 4085 VisitForStackValue(args->at(1)); |
| 4086 MathPowStub stub(isolate(), MathPowStub::ON_STACK); |
| 4087 __ CallStub(&stub); |
| 4088 context()->Plug(v0); |
| 4089 } |
| 4090 |
| 4091 |
3995 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { | 4092 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { |
3996 ZoneList<Expression*>* args = expr->arguments(); | 4093 ZoneList<Expression*>* args = expr->arguments(); |
3997 DCHECK(args->length() == 2); | 4094 DCHECK(args->length() == 2); |
3998 | 4095 |
3999 VisitForStackValue(args->at(0)); // Load the object. | 4096 VisitForStackValue(args->at(0)); // Load the object. |
4000 VisitForAccumulatorValue(args->at(1)); // Load the value. | 4097 VisitForAccumulatorValue(args->at(1)); // Load the value. |
4001 __ pop(a1); // v0 = value. a1 = object. | 4098 __ pop(a1); // v0 = value. a1 = object. |
4002 | 4099 |
4003 Label done; | 4100 Label done; |
4004 // If the object is a smi, return the value. | 4101 // If the object is a smi, return the value. |
4005 __ JumpIfSmi(a1, &done); | 4102 __ JumpIfSmi(a1, &done); |
4006 | 4103 |
4007 // If the object is not a value type, return the value. | 4104 // If the object is not a value type, return the value. |
4008 __ GetObjectType(a1, a2, a2); | 4105 __ GetObjectType(a1, a2, a2); |
4009 __ Branch(&done, ne, a2, Operand(JS_VALUE_TYPE)); | 4106 __ Branch(&done, ne, a2, Operand(JS_VALUE_TYPE)); |
4010 | 4107 |
4011 // Store the value. | 4108 // Store the value. |
4012 __ sd(v0, FieldMemOperand(a1, JSValue::kValueOffset)); | 4109 __ sd(v0, FieldMemOperand(a1, JSValue::kValueOffset)); |
4013 // Update the write barrier. Save the value as it will be | 4110 // Update the write barrier. Save the value as it will be |
4014 // overwritten by the write barrier code and is needed afterward. | 4111 // overwritten by the write barrier code and is needed afterward. |
4015 __ mov(a2, v0); | 4112 __ mov(a2, v0); |
4016 __ RecordWriteField( | 4113 __ RecordWriteField( |
4017 a1, JSValue::kValueOffset, a2, a3, kRAHasBeenSaved, kDontSaveFPRegs); | 4114 a1, JSValue::kValueOffset, a2, a3, kRAHasBeenSaved, kDontSaveFPRegs); |
4018 | 4115 |
4019 __ bind(&done); | 4116 __ bind(&done); |
4020 context()->Plug(v0); | 4117 context()->Plug(v0); |
4021 } | 4118 } |
4022 | 4119 |
| 4120 |
| 4121 void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) { |
| 4122 ZoneList<Expression*>* args = expr->arguments(); |
| 4123 DCHECK_EQ(args->length(), 1); |
| 4124 |
| 4125 // Load the argument into a0 and call the stub. |
| 4126 VisitForAccumulatorValue(args->at(0)); |
| 4127 __ mov(a0, result_register()); |
| 4128 |
| 4129 NumberToStringStub stub(isolate()); |
| 4130 __ CallStub(&stub); |
| 4131 context()->Plug(v0); |
| 4132 } |
| 4133 |
4023 | 4134 |
4024 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { | 4135 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { |
4025 ZoneList<Expression*>* args = expr->arguments(); | 4136 ZoneList<Expression*>* args = expr->arguments(); |
4026 DCHECK(args->length() == 1); | 4137 DCHECK(args->length() == 1); |
4027 | 4138 |
4028 VisitForAccumulatorValue(args->at(0)); | 4139 VisitForAccumulatorValue(args->at(0)); |
4029 | 4140 |
4030 Label done; | 4141 Label done; |
4031 StringCharFromCodeGenerator generator(v0, a1); | 4142 StringCharFromCodeGenerator generator(v0, a1); |
4032 generator.GenerateFast(masm_); | 4143 generator.GenerateFast(masm_); |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4141 DCHECK_EQ(2, args->length()); | 4252 DCHECK_EQ(2, args->length()); |
4142 VisitForStackValue(args->at(0)); | 4253 VisitForStackValue(args->at(0)); |
4143 VisitForAccumulatorValue(args->at(1)); | 4254 VisitForAccumulatorValue(args->at(1)); |
4144 | 4255 |
4145 __ pop(a1); | 4256 __ pop(a1); |
4146 __ mov(a0, result_register()); // StringAddStub requires args in a0, a1. | 4257 __ mov(a0, result_register()); // StringAddStub requires args in a0, a1. |
4147 StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED); | 4258 StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED); |
4148 __ CallStub(&stub); | 4259 __ CallStub(&stub); |
4149 context()->Plug(v0); | 4260 context()->Plug(v0); |
4150 } | 4261 } |
| 4262 |
| 4263 |
| 4264 void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) { |
| 4265 ZoneList<Expression*>* args = expr->arguments(); |
| 4266 DCHECK_EQ(2, args->length()); |
| 4267 |
| 4268 VisitForStackValue(args->at(0)); |
| 4269 VisitForStackValue(args->at(1)); |
| 4270 |
| 4271 StringCompareStub stub(isolate()); |
| 4272 __ CallStub(&stub); |
| 4273 context()->Plug(v0); |
| 4274 } |
4151 | 4275 |
4152 | 4276 |
4153 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { | 4277 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { |
4154 ZoneList<Expression*>* args = expr->arguments(); | 4278 ZoneList<Expression*>* args = expr->arguments(); |
4155 DCHECK(args->length() >= 2); | 4279 DCHECK(args->length() >= 2); |
4156 | 4280 |
4157 int arg_count = args->length() - 2; // 2 ~ receiver and function. | 4281 int arg_count = args->length() - 2; // 2 ~ receiver and function. |
4158 for (int i = 0; i < arg_count + 1; i++) { | 4282 for (int i = 0; i < arg_count + 1; i++) { |
4159 VisitForStackValue(args->at(i)); | 4283 VisitForStackValue(args->at(i)); |
4160 } | 4284 } |
(...skipping 1256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5417 reinterpret_cast<uint64_t>( | 5541 reinterpret_cast<uint64_t>( |
5418 isolate->builtins()->OsrAfterStackCheck()->entry())); | 5542 isolate->builtins()->OsrAfterStackCheck()->entry())); |
5419 return OSR_AFTER_STACK_CHECK; | 5543 return OSR_AFTER_STACK_CHECK; |
5420 } | 5544 } |
5421 | 5545 |
5422 | 5546 |
5423 } // namespace internal | 5547 } // namespace internal |
5424 } // namespace v8 | 5548 } // namespace v8 |
5425 | 5549 |
5426 #endif // V8_TARGET_ARCH_MIPS64 | 5550 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |