| 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 |