| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 717 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 728 convert_undefined = FloatingPointHelper::CONVERT_UNDEFINED_TO_ZERO; | 728 convert_undefined = FloatingPointHelper::CONVERT_UNDEFINED_TO_ZERO; |
| 729 } | 729 } |
| 730 FloatingPointHelper::NumbersToSmis(masm, left, right, rbx, rdi, rcx, | 730 FloatingPointHelper::NumbersToSmis(masm, left, right, rbx, rdi, rcx, |
| 731 &smi_values, &fail, convert_undefined); | 731 &smi_values, &fail, convert_undefined); |
| 732 __ jmp(&smi_values); | 732 __ jmp(&smi_values); |
| 733 __ bind(&fail); | 733 __ bind(&fail); |
| 734 } | 734 } |
| 735 | 735 |
| 736 | 736 |
| 737 static void BinaryOpStub_GenerateHeapResultAllocation(MacroAssembler* masm, | 737 static void BinaryOpStub_GenerateHeapResultAllocation(MacroAssembler* masm, |
| 738 Label* alloc_failure, | 738 Label* alloc_failure); |
| 739 OverwriteMode mode); | |
| 740 | 739 |
| 741 | 740 |
| 742 static void BinaryOpStub_GenerateFloatingPointCode(MacroAssembler* masm, | 741 static void BinaryOpStub_GenerateFloatingPointCode(MacroAssembler* masm, |
| 743 Label* allocation_failure, | 742 Label* allocation_failure, |
| 744 Label* non_numeric_failure, | 743 Label* non_numeric_failure, |
| 745 Token::Value op, | 744 Token::Value op) { |
| 746 OverwriteMode mode) { | |
| 747 switch (op) { | 745 switch (op) { |
| 748 case Token::ADD: | 746 case Token::ADD: |
| 749 case Token::SUB: | 747 case Token::SUB: |
| 750 case Token::MUL: | 748 case Token::MUL: |
| 751 case Token::DIV: { | 749 case Token::DIV: { |
| 752 FloatingPointHelper::LoadSSE2UnknownOperands(masm, non_numeric_failure); | 750 FloatingPointHelper::LoadSSE2UnknownOperands(masm, non_numeric_failure); |
| 753 | 751 |
| 754 switch (op) { | 752 switch (op) { |
| 755 case Token::ADD: __ addsd(xmm0, xmm1); break; | 753 case Token::ADD: __ addsd(xmm0, xmm1); break; |
| 756 case Token::SUB: __ subsd(xmm0, xmm1); break; | 754 case Token::SUB: __ subsd(xmm0, xmm1); break; |
| 757 case Token::MUL: __ mulsd(xmm0, xmm1); break; | 755 case Token::MUL: __ mulsd(xmm0, xmm1); break; |
| 758 case Token::DIV: __ divsd(xmm0, xmm1); break; | 756 case Token::DIV: __ divsd(xmm0, xmm1); break; |
| 759 default: UNREACHABLE(); | 757 default: UNREACHABLE(); |
| 760 } | 758 } |
| 761 BinaryOpStub_GenerateHeapResultAllocation( | 759 BinaryOpStub_GenerateHeapResultAllocation( |
| 762 masm, allocation_failure, mode); | 760 masm, allocation_failure); |
| 763 __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm0); | 761 __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm0); |
| 764 __ ret(0); | 762 __ ret(0); |
| 765 break; | 763 break; |
| 766 } | 764 } |
| 767 case Token::MOD: { | 765 case Token::MOD: { |
| 768 // For MOD we jump to the allocation_failure label, to call runtime. | 766 // For MOD we jump to the allocation_failure label, to call runtime. |
| 769 __ jmp(allocation_failure); | 767 __ jmp(allocation_failure); |
| 770 break; | 768 break; |
| 771 } | 769 } |
| 772 case Token::BIT_OR: | 770 case Token::BIT_OR: |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1025 // or the right operand. For precise type feedback, patch the IC | 1023 // or the right operand. For precise type feedback, patch the IC |
| 1026 // again if this changes. | 1024 // again if this changes. |
| 1027 if (left_type_ == BinaryOpIC::SMI) { | 1025 if (left_type_ == BinaryOpIC::SMI) { |
| 1028 BinaryOpStub_CheckSmiInput(masm, rdx, ¬_number); | 1026 BinaryOpStub_CheckSmiInput(masm, rdx, ¬_number); |
| 1029 } | 1027 } |
| 1030 if (right_type_ == BinaryOpIC::SMI) { | 1028 if (right_type_ == BinaryOpIC::SMI) { |
| 1031 BinaryOpStub_CheckSmiInput(masm, rax, ¬_number); | 1029 BinaryOpStub_CheckSmiInput(masm, rax, ¬_number); |
| 1032 } | 1030 } |
| 1033 | 1031 |
| 1034 BinaryOpStub_GenerateFloatingPointCode( | 1032 BinaryOpStub_GenerateFloatingPointCode( |
| 1035 masm, &gc_required, ¬_number, op_, mode_); | 1033 masm, &gc_required, ¬_number, op_); |
| 1036 | 1034 |
| 1037 __ bind(¬_number); | 1035 __ bind(¬_number); |
| 1038 GenerateTypeTransition(masm); | 1036 GenerateTypeTransition(masm); |
| 1039 | 1037 |
| 1040 __ bind(&gc_required); | 1038 __ bind(&gc_required); |
| 1041 { | 1039 { |
| 1042 FrameScope scope(masm, StackFrame::INTERNAL); | 1040 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1043 GenerateRegisterArgsPush(masm); | 1041 GenerateRegisterArgsPush(masm); |
| 1044 GenerateCallRuntime(masm); | 1042 GenerateCallRuntime(masm); |
| 1045 } | 1043 } |
| 1046 __ Ret(); | 1044 __ Ret(); |
| 1047 } | 1045 } |
| 1048 | 1046 |
| 1049 | 1047 |
| 1050 void BinaryOpStub::GenerateGeneric(MacroAssembler* masm) { | 1048 void BinaryOpStub::GenerateGeneric(MacroAssembler* masm) { |
| 1051 Label call_runtime, call_string_add_or_runtime; | 1049 Label call_runtime, call_string_add_or_runtime; |
| 1052 | 1050 |
| 1053 BinaryOpStub_GenerateSmiCode( | 1051 BinaryOpStub_GenerateSmiCode( |
| 1054 masm, &call_runtime, ALLOW_HEAPNUMBER_RESULTS, op_); | 1052 masm, &call_runtime, ALLOW_HEAPNUMBER_RESULTS, op_); |
| 1055 | 1053 |
| 1056 BinaryOpStub_GenerateFloatingPointCode( | 1054 BinaryOpStub_GenerateFloatingPointCode( |
| 1057 masm, &call_runtime, &call_string_add_or_runtime, op_, mode_); | 1055 masm, &call_runtime, &call_string_add_or_runtime, op_); |
| 1058 | 1056 |
| 1059 __ bind(&call_string_add_or_runtime); | 1057 __ bind(&call_string_add_or_runtime); |
| 1060 if (op_ == Token::ADD) { | 1058 if (op_ == Token::ADD) { |
| 1061 GenerateAddStrings(masm); | 1059 GenerateAddStrings(masm); |
| 1062 } | 1060 } |
| 1063 | 1061 |
| 1064 __ bind(&call_runtime); | 1062 __ bind(&call_runtime); |
| 1065 { | 1063 { |
| 1066 FrameScope scope(masm, StackFrame::INTERNAL); | 1064 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1067 GenerateRegisterArgsPush(masm); | 1065 GenerateRegisterArgsPush(masm); |
| 1068 GenerateCallRuntime(masm); | 1066 GenerateCallRuntime(masm); |
| 1069 } | 1067 } |
| 1070 __ Ret(); | 1068 __ Ret(); |
| 1071 } | 1069 } |
| 1072 | 1070 |
| 1073 | 1071 |
| 1074 static void BinaryOpStub_GenerateHeapResultAllocation(MacroAssembler* masm, | 1072 static void BinaryOpStub_GenerateHeapResultAllocation(MacroAssembler* masm, |
| 1075 Label* alloc_failure, | 1073 Label* alloc_failure) { |
| 1076 OverwriteMode mode) { | |
| 1077 Label skip_allocation; | 1074 Label skip_allocation; |
| 1078 switch (mode) { | 1075 // Allocate a heap number for the result. Keep rax and rdx intact |
| 1079 case OVERWRITE_LEFT: { | 1076 // for the possible runtime call. |
| 1080 // If the argument in rdx is already an object, we skip the | 1077 __ AllocateHeapNumber(rbx, rcx, alloc_failure); |
| 1081 // allocation of a heap number. | 1078 // Now rax can be overwritten losing one of the arguments as we are |
| 1082 __ JumpIfNotSmi(rdx, &skip_allocation); | 1079 // now done and will not need it any more. |
| 1083 // Allocate a heap number for the result. Keep rax and rdx intact | 1080 __ movq(rax, rbx); |
| 1084 // for the possible runtime call. | 1081 __ bind(&skip_allocation); |
| 1085 __ AllocateHeapNumber(rbx, rcx, alloc_failure); | |
| 1086 // Now rdx can be overwritten losing one of the arguments as we are | |
| 1087 // now done and will not need it any more. | |
| 1088 __ movq(rdx, rbx); | |
| 1089 __ bind(&skip_allocation); | |
| 1090 // Use object in rdx as a result holder | |
| 1091 __ movq(rax, rdx); | |
| 1092 break; | |
| 1093 } | |
| 1094 case OVERWRITE_RIGHT: | |
| 1095 // If the argument in rax is already an object, we skip the | |
| 1096 // allocation of a heap number. | |
| 1097 __ JumpIfNotSmi(rax, &skip_allocation); | |
| 1098 // Fall through! | |
| 1099 case NO_OVERWRITE: | |
| 1100 // Allocate a heap number for the result. Keep rax and rdx intact | |
| 1101 // for the possible runtime call. | |
| 1102 __ AllocateHeapNumber(rbx, rcx, alloc_failure); | |
| 1103 // Now rax can be overwritten losing one of the arguments as we are | |
| 1104 // now done and will not need it any more. | |
| 1105 __ movq(rax, rbx); | |
| 1106 __ bind(&skip_allocation); | |
| 1107 break; | |
| 1108 default: UNREACHABLE(); | |
| 1109 } | |
| 1110 } | 1082 } |
| 1111 | 1083 |
| 1112 | 1084 |
| 1113 void BinaryOpStub::GenerateRegisterArgsPush(MacroAssembler* masm) { | 1085 void BinaryOpStub::GenerateRegisterArgsPush(MacroAssembler* masm) { |
| 1114 __ push(rdx); | 1086 __ push(rdx); |
| 1115 __ push(rax); | 1087 __ push(rax); |
| 1116 } | 1088 } |
| 1117 | 1089 |
| 1118 | 1090 |
| 1119 void TranscendentalCacheStub::Generate(MacroAssembler* masm) { | 1091 void TranscendentalCacheStub::Generate(MacroAssembler* masm) { |
| (...skipping 5521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6641 __ bind(&fast_elements_case); | 6613 __ bind(&fast_elements_case); |
| 6642 GenerateCase(masm, FAST_ELEMENTS); | 6614 GenerateCase(masm, FAST_ELEMENTS); |
| 6643 } | 6615 } |
| 6644 | 6616 |
| 6645 | 6617 |
| 6646 #undef __ | 6618 #undef __ |
| 6647 | 6619 |
| 6648 } } // namespace v8::internal | 6620 } } // namespace v8::internal |
| 6649 | 6621 |
| 6650 #endif // V8_TARGET_ARCH_X64 | 6622 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |