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/crankshaft/mips64/lithium-codegen-mips64.h" | 5 #include "src/crankshaft/mips64/lithium-codegen-mips64.h" |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/crankshaft/hydrogen-osr.h" | 9 #include "src/crankshaft/hydrogen-osr.h" |
10 #include "src/crankshaft/mips64/lithium-gap-resolver-mips64.h" | 10 #include "src/crankshaft/mips64/lithium-gap-resolver-mips64.h" |
(...skipping 1392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1403 int32_t mask = constant >> 31; | 1403 int32_t mask = constant >> 31; |
1404 uint32_t constant_abs = (constant + mask) ^ mask; | 1404 uint32_t constant_abs = (constant + mask) ^ mask; |
1405 | 1405 |
1406 if (base::bits::IsPowerOfTwo32(constant_abs)) { | 1406 if (base::bits::IsPowerOfTwo32(constant_abs)) { |
1407 int32_t shift = WhichPowerOf2(constant_abs); | 1407 int32_t shift = WhichPowerOf2(constant_abs); |
1408 __ dsll(result, left, shift); | 1408 __ dsll(result, left, shift); |
1409 // Correct the sign of the result if the constant is negative. | 1409 // Correct the sign of the result if the constant is negative. |
1410 if (constant < 0) __ Dsubu(result, zero_reg, result); | 1410 if (constant < 0) __ Dsubu(result, zero_reg, result); |
1411 } else if (base::bits::IsPowerOfTwo32(constant_abs - 1)) { | 1411 } else if (base::bits::IsPowerOfTwo32(constant_abs - 1)) { |
1412 int32_t shift = WhichPowerOf2(constant_abs - 1); | 1412 int32_t shift = WhichPowerOf2(constant_abs - 1); |
1413 __ dsll(scratch, left, shift); | 1413 __ Dlsa(result, left, left, shift); |
1414 __ Daddu(result, scratch, left); | |
1415 // Correct the sign of the result if the constant is negative. | 1414 // Correct the sign of the result if the constant is negative. |
1416 if (constant < 0) __ Dsubu(result, zero_reg, result); | 1415 if (constant < 0) __ Dsubu(result, zero_reg, result); |
1417 } else if (base::bits::IsPowerOfTwo32(constant_abs + 1)) { | 1416 } else if (base::bits::IsPowerOfTwo32(constant_abs + 1)) { |
1418 int32_t shift = WhichPowerOf2(constant_abs + 1); | 1417 int32_t shift = WhichPowerOf2(constant_abs + 1); |
1419 __ dsll(scratch, left, shift); | 1418 __ dsll(scratch, left, shift); |
1420 __ Dsubu(result, scratch, left); | 1419 __ Dsubu(result, scratch, left); |
1421 // Correct the sign of the result if the constant is negative. | 1420 // Correct the sign of the result if the constant is negative. |
1422 if (constant < 0) __ Dsubu(result, zero_reg, result); | 1421 if (constant < 0) __ Dsubu(result, zero_reg, result); |
1423 } else { | 1422 } else { |
1424 // Generate standard code. | 1423 // Generate standard code. |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1505 int32_t mask = constant >> 31; | 1504 int32_t mask = constant >> 31; |
1506 uint32_t constant_abs = (constant + mask) ^ mask; | 1505 uint32_t constant_abs = (constant + mask) ^ mask; |
1507 | 1506 |
1508 if (base::bits::IsPowerOfTwo32(constant_abs)) { | 1507 if (base::bits::IsPowerOfTwo32(constant_abs)) { |
1509 int32_t shift = WhichPowerOf2(constant_abs); | 1508 int32_t shift = WhichPowerOf2(constant_abs); |
1510 __ sll(result, left, shift); | 1509 __ sll(result, left, shift); |
1511 // Correct the sign of the result if the constant is negative. | 1510 // Correct the sign of the result if the constant is negative. |
1512 if (constant < 0) __ Subu(result, zero_reg, result); | 1511 if (constant < 0) __ Subu(result, zero_reg, result); |
1513 } else if (base::bits::IsPowerOfTwo32(constant_abs - 1)) { | 1512 } else if (base::bits::IsPowerOfTwo32(constant_abs - 1)) { |
1514 int32_t shift = WhichPowerOf2(constant_abs - 1); | 1513 int32_t shift = WhichPowerOf2(constant_abs - 1); |
1515 __ sll(scratch, left, shift); | 1514 __ Lsa(result, left, left, shift); |
1516 __ addu(result, scratch, left); | |
1517 // Correct the sign of the result if the constant is negative. | 1515 // Correct the sign of the result if the constant is negative. |
1518 if (constant < 0) __ Subu(result, zero_reg, result); | 1516 if (constant < 0) __ Subu(result, zero_reg, result); |
1519 } else if (base::bits::IsPowerOfTwo32(constant_abs + 1)) { | 1517 } else if (base::bits::IsPowerOfTwo32(constant_abs + 1)) { |
1520 int32_t shift = WhichPowerOf2(constant_abs + 1); | 1518 int32_t shift = WhichPowerOf2(constant_abs + 1); |
1521 __ sll(scratch, left, shift); | 1519 __ sll(scratch, left, shift); |
1522 __ Subu(result, scratch, left); | 1520 __ Subu(result, scratch, left); |
1523 // Correct the sign of the result if the constant is negative. | 1521 // Correct the sign of the result if the constant is negative. |
1524 if (constant < 0) __ Subu(result, zero_reg, result); | 1522 if (constant < 0) __ Subu(result, zero_reg, result); |
1525 } else { | 1523 } else { |
1526 // Generate standard code. | 1524 // Generate standard code. |
(...skipping 1169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2696 int parameter_count = ToInteger32(instr->constant_parameter_count()); | 2694 int parameter_count = ToInteger32(instr->constant_parameter_count()); |
2697 int32_t sp_delta = (parameter_count + 1) * kPointerSize; | 2695 int32_t sp_delta = (parameter_count + 1) * kPointerSize; |
2698 if (sp_delta != 0) { | 2696 if (sp_delta != 0) { |
2699 __ Daddu(sp, sp, Operand(sp_delta)); | 2697 __ Daddu(sp, sp, Operand(sp_delta)); |
2700 } | 2698 } |
2701 } else { | 2699 } else { |
2702 DCHECK(info()->IsStub()); // Functions would need to drop one more value. | 2700 DCHECK(info()->IsStub()); // Functions would need to drop one more value. |
2703 Register reg = ToRegister(instr->parameter_count()); | 2701 Register reg = ToRegister(instr->parameter_count()); |
2704 // The argument count parameter is a smi | 2702 // The argument count parameter is a smi |
2705 __ SmiUntag(reg); | 2703 __ SmiUntag(reg); |
2706 __ dsll(at, reg, kPointerSizeLog2); | 2704 __ Dlsa(sp, sp, reg, kPointerSizeLog2); |
2707 __ Daddu(sp, sp, at); | |
2708 } | 2705 } |
2709 | 2706 |
2710 __ Jump(ra); | 2707 __ Jump(ra); |
2711 } | 2708 } |
2712 | 2709 |
2713 | 2710 |
2714 template <class T> | 2711 template <class T> |
2715 void LCodeGen::EmitVectorLoadICRegisters(T* instr) { | 2712 void LCodeGen::EmitVectorLoadICRegisters(T* instr) { |
2716 Register vector_register = ToRegister(instr->temp_vector()); | 2713 Register vector_register = ToRegister(instr->temp_vector()); |
2717 Register slot_register = LoadWithVectorDescriptor::SlotRegister(); | 2714 Register slot_register = LoadWithVectorDescriptor::SlotRegister(); |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2914 if (instr->length()->IsConstantOperand()) { | 2911 if (instr->length()->IsConstantOperand()) { |
2915 int const_length = ToInteger32(LConstantOperand::cast(instr->length())); | 2912 int const_length = ToInteger32(LConstantOperand::cast(instr->length())); |
2916 if (instr->index()->IsConstantOperand()) { | 2913 if (instr->index()->IsConstantOperand()) { |
2917 int const_index = ToInteger32(LConstantOperand::cast(instr->index())); | 2914 int const_index = ToInteger32(LConstantOperand::cast(instr->index())); |
2918 int index = (const_length - const_index) + 1; | 2915 int index = (const_length - const_index) + 1; |
2919 __ ld(result, MemOperand(arguments, index * kPointerSize)); | 2916 __ ld(result, MemOperand(arguments, index * kPointerSize)); |
2920 } else { | 2917 } else { |
2921 Register index = ToRegister(instr->index()); | 2918 Register index = ToRegister(instr->index()); |
2922 __ li(at, Operand(const_length + 1)); | 2919 __ li(at, Operand(const_length + 1)); |
2923 __ Dsubu(result, at, index); | 2920 __ Dsubu(result, at, index); |
2924 __ dsll(at, result, kPointerSizeLog2); | 2921 __ Dlsa(at, arguments, result, kPointerSizeLog2); |
2925 __ Daddu(at, arguments, at); | |
2926 __ ld(result, MemOperand(at)); | 2922 __ ld(result, MemOperand(at)); |
2927 } | 2923 } |
2928 } else if (instr->index()->IsConstantOperand()) { | 2924 } else if (instr->index()->IsConstantOperand()) { |
2929 Register length = ToRegister(instr->length()); | 2925 Register length = ToRegister(instr->length()); |
2930 int const_index = ToInteger32(LConstantOperand::cast(instr->index())); | 2926 int const_index = ToInteger32(LConstantOperand::cast(instr->index())); |
2931 int loc = const_index - 1; | 2927 int loc = const_index - 1; |
2932 if (loc != 0) { | 2928 if (loc != 0) { |
2933 __ Dsubu(result, length, Operand(loc)); | 2929 __ Dsubu(result, length, Operand(loc)); |
2934 __ dsll(at, result, kPointerSizeLog2); | 2930 __ Dlsa(at, arguments, result, kPointerSizeLog2); |
2935 __ Daddu(at, arguments, at); | |
2936 __ ld(result, MemOperand(at)); | 2931 __ ld(result, MemOperand(at)); |
2937 } else { | 2932 } else { |
2938 __ dsll(at, length, kPointerSizeLog2); | 2933 __ Dlsa(at, arguments, length, kPointerSizeLog2); |
2939 __ Daddu(at, arguments, at); | |
2940 __ ld(result, MemOperand(at)); | 2934 __ ld(result, MemOperand(at)); |
2941 } | 2935 } |
2942 } else { | 2936 } else { |
2943 Register length = ToRegister(instr->length()); | 2937 Register length = ToRegister(instr->length()); |
2944 Register index = ToRegister(instr->index()); | 2938 Register index = ToRegister(instr->index()); |
2945 __ Dsubu(result, length, index); | 2939 __ Dsubu(result, length, index); |
2946 __ Daddu(result, result, 1); | 2940 __ Daddu(result, result, 1); |
2947 __ dsll(at, result, kPointerSizeLog2); | 2941 __ Dlsa(at, arguments, result, kPointerSizeLog2); |
2948 __ Daddu(at, arguments, at); | |
2949 __ ld(result, MemOperand(at)); | 2942 __ ld(result, MemOperand(at)); |
2950 } | 2943 } |
2951 } | 2944 } |
2952 | 2945 |
2953 | 2946 |
2954 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { | 2947 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { |
2955 Register external_pointer = ToRegister(instr->elements()); | 2948 Register external_pointer = ToRegister(instr->elements()); |
2956 Register key = no_reg; | 2949 Register key = no_reg; |
2957 ElementsKind elements_kind = instr->elements_kind(); | 2950 ElementsKind elements_kind = instr->elements_kind(); |
2958 bool key_is_constant = instr->key()->IsConstantOperand(); | 2951 bool key_is_constant = instr->key()->IsConstantOperand(); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3100 } else { | 3093 } else { |
3101 Register key = ToRegister(instr->key()); | 3094 Register key = ToRegister(instr->key()); |
3102 // Even though the HLoadKeyed instruction forces the input | 3095 // Even though the HLoadKeyed instruction forces the input |
3103 // representation for the key to be an integer, the input gets replaced | 3096 // representation for the key to be an integer, the input gets replaced |
3104 // during bound check elimination with the index argument to the bounds | 3097 // during bound check elimination with the index argument to the bounds |
3105 // check, which can be tagged, so that case must be handled here, too. | 3098 // check, which can be tagged, so that case must be handled here, too. |
3106 if (instr->hydrogen()->key()->representation().IsSmi()) { | 3099 if (instr->hydrogen()->key()->representation().IsSmi()) { |
3107 __ SmiScale(scratch, key, kPointerSizeLog2); | 3100 __ SmiScale(scratch, key, kPointerSizeLog2); |
3108 __ daddu(scratch, elements, scratch); | 3101 __ daddu(scratch, elements, scratch); |
3109 } else { | 3102 } else { |
3110 __ dsll(scratch, key, kPointerSizeLog2); | 3103 __ Dlsa(scratch, elements, key, kPointerSizeLog2); |
3111 __ daddu(scratch, elements, scratch); | |
3112 } | 3104 } |
3113 } | 3105 } |
3114 | 3106 |
3115 Representation representation = hinstr->representation(); | 3107 Representation representation = hinstr->representation(); |
3116 if (representation.IsInteger32() && SmiValuesAre32Bits() && | 3108 if (representation.IsInteger32() && SmiValuesAre32Bits() && |
3117 hinstr->elements_kind() == FAST_SMI_ELEMENTS) { | 3109 hinstr->elements_kind() == FAST_SMI_ELEMENTS) { |
3118 DCHECK(!hinstr->RequiresHoleCheck()); | 3110 DCHECK(!hinstr->RequiresHoleCheck()); |
3119 if (FLAG_debug_code) { | 3111 if (FLAG_debug_code) { |
3120 Register temp = scratch1(); | 3112 Register temp = scratch1(); |
3121 __ Load(temp, MemOperand(store_base, offset), Representation::Smi()); | 3113 __ Load(temp, MemOperand(store_base, offset), Representation::Smi()); |
(...skipping 1153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4275 store_base = elements; | 4267 store_base = elements; |
4276 } else { | 4268 } else { |
4277 // Even though the HLoadKeyed instruction forces the input | 4269 // Even though the HLoadKeyed instruction forces the input |
4278 // representation for the key to be an integer, the input gets replaced | 4270 // representation for the key to be an integer, the input gets replaced |
4279 // during bound check elimination with the index argument to the bounds | 4271 // during bound check elimination with the index argument to the bounds |
4280 // check, which can be tagged, so that case must be handled here, too. | 4272 // check, which can be tagged, so that case must be handled here, too. |
4281 if (instr->hydrogen()->key()->representation().IsSmi()) { | 4273 if (instr->hydrogen()->key()->representation().IsSmi()) { |
4282 __ SmiScale(scratch, key, kPointerSizeLog2); | 4274 __ SmiScale(scratch, key, kPointerSizeLog2); |
4283 __ daddu(store_base, elements, scratch); | 4275 __ daddu(store_base, elements, scratch); |
4284 } else { | 4276 } else { |
4285 __ dsll(scratch, key, kPointerSizeLog2); | 4277 __ Dlsa(store_base, elements, key, kPointerSizeLog2); |
4286 __ daddu(store_base, elements, scratch); | |
4287 } | 4278 } |
4288 } | 4279 } |
4289 | 4280 |
4290 Representation representation = instr->hydrogen()->value()->representation(); | 4281 Representation representation = instr->hydrogen()->value()->representation(); |
4291 if (representation.IsInteger32() && SmiValuesAre32Bits()) { | 4282 if (representation.IsInteger32() && SmiValuesAre32Bits()) { |
4292 DCHECK(instr->hydrogen()->store_mode() == STORE_TO_INITIALIZED_ENTRY); | 4283 DCHECK(instr->hydrogen()->store_mode() == STORE_TO_INITIALIZED_ENTRY); |
4293 DCHECK(instr->hydrogen()->elements_kind() == FAST_SMI_ELEMENTS); | 4284 DCHECK(instr->hydrogen()->elements_kind() == FAST_SMI_ELEMENTS); |
4294 if (FLAG_debug_code) { | 4285 if (FLAG_debug_code) { |
4295 Register temp = scratch1(); | 4286 Register temp = scratch1(); |
4296 __ Load(temp, MemOperand(store_base, offset), Representation::Smi()); | 4287 __ Load(temp, MemOperand(store_base, offset), Representation::Smi()); |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4581 | 4572 |
4582 DCHECK(instr->hydrogen()->value()->representation().IsInteger32()); | 4573 DCHECK(instr->hydrogen()->value()->representation().IsInteger32()); |
4583 Register char_code = ToRegister(instr->char_code()); | 4574 Register char_code = ToRegister(instr->char_code()); |
4584 Register result = ToRegister(instr->result()); | 4575 Register result = ToRegister(instr->result()); |
4585 Register scratch = scratch0(); | 4576 Register scratch = scratch0(); |
4586 DCHECK(!char_code.is(result)); | 4577 DCHECK(!char_code.is(result)); |
4587 | 4578 |
4588 __ Branch(deferred->entry(), hi, | 4579 __ Branch(deferred->entry(), hi, |
4589 char_code, Operand(String::kMaxOneByteCharCode)); | 4580 char_code, Operand(String::kMaxOneByteCharCode)); |
4590 __ LoadRoot(result, Heap::kSingleCharacterStringCacheRootIndex); | 4581 __ LoadRoot(result, Heap::kSingleCharacterStringCacheRootIndex); |
4591 __ dsll(scratch, char_code, kPointerSizeLog2); | 4582 __ Dlsa(result, result, char_code, kPointerSizeLog2); |
4592 __ Daddu(result, result, scratch); | |
4593 __ ld(result, FieldMemOperand(result, FixedArray::kHeaderSize)); | 4583 __ ld(result, FieldMemOperand(result, FixedArray::kHeaderSize)); |
4594 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); | 4584 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); |
4595 __ Branch(deferred->entry(), eq, result, Operand(scratch)); | 4585 __ Branch(deferred->entry(), eq, result, Operand(scratch)); |
4596 __ bind(deferred->exit()); | 4586 __ bind(deferred->exit()); |
4597 } | 4587 } |
4598 | 4588 |
4599 | 4589 |
4600 void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) { | 4590 void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) { |
4601 Register char_code = ToRegister(instr->char_code()); | 4591 Register char_code = ToRegister(instr->char_code()); |
4602 Register result = ToRegister(instr->result()); | 4592 Register result = ToRegister(instr->result()); |
(...skipping 1231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5834 __ Push(at, ToRegister(instr->function())); | 5824 __ Push(at, ToRegister(instr->function())); |
5835 CallRuntime(Runtime::kPushBlockContext, instr); | 5825 CallRuntime(Runtime::kPushBlockContext, instr); |
5836 RecordSafepoint(Safepoint::kNoLazyDeopt); | 5826 RecordSafepoint(Safepoint::kNoLazyDeopt); |
5837 } | 5827 } |
5838 | 5828 |
5839 | 5829 |
5840 #undef __ | 5830 #undef __ |
5841 | 5831 |
5842 } // namespace internal | 5832 } // namespace internal |
5843 } // namespace v8 | 5833 } // namespace v8 |
OLD | NEW |