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/code-stubs.h" | 5 #include "src/code-stubs.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 1079 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1090 assembler->Branch(assembler->WordIsSmi(lhs), &lhs_is_smi, &lhs_is_not_smi); | 1090 assembler->Branch(assembler->WordIsSmi(lhs), &lhs_is_smi, &lhs_is_not_smi); |
1091 | 1091 |
1092 assembler->Bind(&lhs_is_smi); | 1092 assembler->Bind(&lhs_is_smi); |
1093 { | 1093 { |
1094 Label rhs_is_smi(assembler), rhs_is_not_smi(assembler); | 1094 Label rhs_is_smi(assembler), rhs_is_not_smi(assembler); |
1095 assembler->Branch(assembler->WordIsSmi(rhs), &rhs_is_smi, | 1095 assembler->Branch(assembler->WordIsSmi(rhs), &rhs_is_smi, |
1096 &rhs_is_not_smi); | 1096 &rhs_is_not_smi); |
1097 | 1097 |
1098 assembler->Bind(&rhs_is_smi); | 1098 assembler->Bind(&rhs_is_smi); |
1099 { | 1099 { |
1100 // Both {lhs} and {rhs} are Smis. Convert them to integers and multiply. | 1100 // Both {lhs} and {rhs} are Smis. The result is not necessarily a smi, |
1101 Node* lhs32 = assembler->SmiToWord32(lhs); | 1101 // in case of overflow. |
1102 Node* rhs32 = assembler->SmiToWord32(rhs); | 1102 var_result.Bind(assembler->SmiMul(lhs, rhs)); |
1103 Node* pair = assembler->Int32MulWithOverflow(lhs32, rhs32); | 1103 assembler->Goto(&return_result); |
1104 | |
1105 Node* overflow = assembler->Projection(1, pair); | |
1106 | |
1107 // Check if the multiplication overflowed. | |
1108 Label if_overflow(assembler, Label::kDeferred), | |
1109 if_notoverflow(assembler); | |
1110 assembler->Branch(overflow, &if_overflow, &if_notoverflow); | |
1111 assembler->Bind(&if_notoverflow); | |
1112 { | |
1113 // If the answer is zero, we may need to return -0.0, depending on the | |
1114 // input. | |
1115 Label answer_zero(assembler), answer_not_zero(assembler); | |
1116 Node* answer = assembler->Projection(0, pair); | |
1117 Node* zero = assembler->Int32Constant(0); | |
1118 assembler->Branch(assembler->WordEqual(answer, zero), &answer_zero, | |
1119 &answer_not_zero); | |
1120 assembler->Bind(&answer_not_zero); | |
1121 { | |
1122 var_result.Bind(assembler->ChangeInt32ToTagged(answer)); | |
1123 assembler->Goto(&return_result); | |
1124 } | |
1125 assembler->Bind(&answer_zero); | |
1126 { | |
1127 Node* or_result = assembler->Word32Or(lhs32, rhs32); | |
1128 Label if_should_be_negative_zero(assembler), | |
1129 if_should_be_zero(assembler); | |
1130 assembler->Branch(assembler->Int32LessThan(or_result, zero), | |
1131 &if_should_be_negative_zero, &if_should_be_zero); | |
1132 assembler->Bind(&if_should_be_negative_zero); | |
1133 { | |
1134 var_result.Bind(assembler->MinusZeroConstant()); | |
1135 assembler->Goto(&return_result); | |
1136 } | |
1137 assembler->Bind(&if_should_be_zero); | |
1138 { | |
1139 var_result.Bind(zero); | |
1140 assembler->Goto(&return_result); | |
1141 } | |
1142 } | |
1143 } | |
1144 assembler->Bind(&if_overflow); | |
1145 { | |
1146 var_lhs_float64.Bind(assembler->SmiToFloat64(lhs)); | |
1147 var_rhs_float64.Bind(assembler->SmiToFloat64(rhs)); | |
1148 assembler->Goto(&do_fmul); | |
1149 } | |
1150 } | 1104 } |
1151 | 1105 |
1152 assembler->Bind(&rhs_is_not_smi); | 1106 assembler->Bind(&rhs_is_not_smi); |
1153 { | 1107 { |
1154 Node* rhs_map = assembler->LoadMap(rhs); | 1108 Node* rhs_map = assembler->LoadMap(rhs); |
1155 | 1109 |
1156 // Check if {rhs} is a HeapNumber. | 1110 // Check if {rhs} is a HeapNumber. |
1157 Label rhs_is_number(assembler), | 1111 Label rhs_is_number(assembler), |
1158 rhs_is_not_number(assembler, Label::kDeferred); | 1112 rhs_is_not_number(assembler, Label::kDeferred); |
1159 assembler->Branch(assembler->WordEqual(rhs_map, number_map), | 1113 assembler->Branch(assembler->WordEqual(rhs_map, number_map), |
(...skipping 3820 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4980 if (type->Is(Type::UntaggedPointer())) { | 4934 if (type->Is(Type::UntaggedPointer())) { |
4981 return Representation::External(); | 4935 return Representation::External(); |
4982 } | 4936 } |
4983 | 4937 |
4984 DCHECK(!type->Is(Type::Untagged())); | 4938 DCHECK(!type->Is(Type::Untagged())); |
4985 return Representation::Tagged(); | 4939 return Representation::Tagged(); |
4986 } | 4940 } |
4987 | 4941 |
4988 } // namespace internal | 4942 } // namespace internal |
4989 } // namespace v8 | 4943 } // namespace v8 |
OLD | NEW |