| 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 1015 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1026 { | 1026 { |
| 1027 Node* lhs_value = var_fsub_lhs.value(); | 1027 Node* lhs_value = var_fsub_lhs.value(); |
| 1028 Node* rhs_value = var_fsub_rhs.value(); | 1028 Node* rhs_value = var_fsub_rhs.value(); |
| 1029 Node* value = assembler->Float64Sub(lhs_value, rhs_value); | 1029 Node* value = assembler->Float64Sub(lhs_value, rhs_value); |
| 1030 // TODO(bmeurer): Introduce a ChangeFloat64ToTagged. | 1030 // TODO(bmeurer): Introduce a ChangeFloat64ToTagged. |
| 1031 Node* result = assembler->AllocateHeapNumberWithValue(value); | 1031 Node* result = assembler->AllocateHeapNumberWithValue(value); |
| 1032 assembler->Return(result); | 1032 assembler->Return(result); |
| 1033 } | 1033 } |
| 1034 } | 1034 } |
| 1035 | 1035 |
| 1036 namespace { | |
| 1037 | |
| 1038 void GenerateBitwiseOperation( | |
| 1039 compiler::CodeStubAssembler* assembler, | |
| 1040 compiler::Node* (compiler::CodeStubAssembler::*bitop)(compiler::Node*, | |
| 1041 compiler::Node*)) { | |
| 1042 typedef compiler::CodeStubAssembler::Label Label; | |
| 1043 typedef compiler::Node Node; | |
| 1044 typedef compiler::CodeStubAssembler::Variable Variable; | |
| 1045 | |
| 1046 Node* context = assembler->Parameter(2); | |
| 1047 | |
| 1048 // Shared entry for word32 bitwise operation. | |
| 1049 Label do_bitop(assembler); | |
| 1050 Variable var_bitop_lhs(assembler, MachineRepresentation::kWord32), | |
| 1051 var_bitop_rhs(assembler, MachineRepresentation::kWord32); | |
| 1052 | |
| 1053 // We might need to loop several times due to ToNumber conversions. | |
| 1054 Variable var_lhs(assembler, MachineRepresentation::kTagged), | |
| 1055 var_rhs(assembler, MachineRepresentation::kTagged); | |
| 1056 Variable* loop_vars[2] = {&var_lhs, &var_rhs}; | |
| 1057 Label loop(assembler, 2, loop_vars); | |
| 1058 var_lhs.Bind(assembler->Parameter(0)); | |
| 1059 var_rhs.Bind(assembler->Parameter(1)); | |
| 1060 assembler->Goto(&loop); | |
| 1061 assembler->Bind(&loop); | |
| 1062 { | |
| 1063 // Load the current {lhs} and {rhs} values. | |
| 1064 Node* lhs = var_lhs.value(); | |
| 1065 Node* rhs = var_rhs.value(); | |
| 1066 | |
| 1067 // Check if the {lhs} is a Smi or a HeapObject. | |
| 1068 Label if_lhsissmi(assembler), if_lhsisnotsmi(assembler); | |
| 1069 assembler->Branch(assembler->WordIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi); | |
| 1070 | |
| 1071 assembler->Bind(&if_lhsissmi); | |
| 1072 { | |
| 1073 // Check if the {rhs} is also a Smi. | |
| 1074 Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler); | |
| 1075 assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi, | |
| 1076 &if_rhsisnotsmi); | |
| 1077 | |
| 1078 assembler->Bind(&if_rhsissmi); | |
| 1079 { | |
| 1080 // Perform the word32 bitwise operation. | |
| 1081 var_bitop_lhs.Bind(assembler->SmiToInt32(lhs)); | |
| 1082 var_bitop_rhs.Bind(assembler->SmiToInt32(rhs)); | |
| 1083 assembler->Goto(&do_bitop); | |
| 1084 } | |
| 1085 | |
| 1086 assembler->Bind(&if_rhsisnotsmi); | |
| 1087 { | |
| 1088 // Load the map of the {rhs}. | |
| 1089 Node* rhs_map = assembler->LoadMap(rhs); | |
| 1090 | |
| 1091 // Check if {rhs} is a HeapNumber. | |
| 1092 Label if_rhsisnumber(assembler), | |
| 1093 if_rhsisnotnumber(assembler, Label::kDeferred); | |
| 1094 Node* number_map = assembler->HeapNumberMapConstant(); | |
| 1095 assembler->Branch(assembler->WordEqual(rhs_map, number_map), | |
| 1096 &if_rhsisnumber, &if_rhsisnotnumber); | |
| 1097 | |
| 1098 assembler->Bind(&if_rhsisnumber); | |
| 1099 { | |
| 1100 // Perform the word32 bitwise operation. | |
| 1101 var_bitop_lhs.Bind(assembler->SmiToInt32(lhs)); | |
| 1102 var_bitop_rhs.Bind(assembler->TruncateHeapNumberValueToInt32(rhs)); | |
| 1103 assembler->Goto(&do_bitop); | |
| 1104 } | |
| 1105 | |
| 1106 assembler->Bind(&if_rhsisnotnumber); | |
| 1107 { | |
| 1108 // Convert the {rhs} to a Number first. | |
| 1109 Callable callable = | |
| 1110 CodeFactory::NonNumberToNumber(assembler->isolate()); | |
| 1111 var_rhs.Bind(assembler->CallStub(callable, context, rhs)); | |
| 1112 assembler->Goto(&loop); | |
| 1113 } | |
| 1114 } | |
| 1115 } | |
| 1116 | |
| 1117 assembler->Bind(&if_lhsisnotsmi); | |
| 1118 { | |
| 1119 // Load the map of the {lhs}. | |
| 1120 Node* lhs_map = assembler->LoadMap(lhs); | |
| 1121 | |
| 1122 // Check if the {lhs} is a HeapNumber. | |
| 1123 Label if_lhsisnumber(assembler), | |
| 1124 if_lhsisnotnumber(assembler, Label::kDeferred); | |
| 1125 Node* number_map = assembler->HeapNumberMapConstant(); | |
| 1126 assembler->Branch(assembler->WordEqual(lhs_map, number_map), | |
| 1127 &if_lhsisnumber, &if_lhsisnotnumber); | |
| 1128 | |
| 1129 assembler->Bind(&if_lhsisnumber); | |
| 1130 { | |
| 1131 // Check if the {rhs} is a Smi. | |
| 1132 Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler); | |
| 1133 assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi, | |
| 1134 &if_rhsisnotsmi); | |
| 1135 | |
| 1136 assembler->Bind(&if_rhsissmi); | |
| 1137 { | |
| 1138 // Perform the word32 bitwise operation. | |
| 1139 var_bitop_lhs.Bind(assembler->TruncateHeapNumberValueToInt32(lhs)); | |
| 1140 var_bitop_rhs.Bind(assembler->SmiToInt32(rhs)); | |
| 1141 assembler->Goto(&do_bitop); | |
| 1142 } | |
| 1143 | |
| 1144 assembler->Bind(&if_rhsisnotsmi); | |
| 1145 { | |
| 1146 // Load the map of the {rhs}. | |
| 1147 Node* rhs_map = assembler->LoadMap(rhs); | |
| 1148 | |
| 1149 // Check if the {rhs} is a HeapNumber. | |
| 1150 Label if_rhsisnumber(assembler), | |
| 1151 if_rhsisnotnumber(assembler, Label::kDeferred); | |
| 1152 assembler->Branch(assembler->WordEqual(rhs_map, number_map), | |
| 1153 &if_rhsisnumber, &if_rhsisnotnumber); | |
| 1154 | |
| 1155 assembler->Bind(&if_rhsisnumber); | |
| 1156 { | |
| 1157 // Perform the word32 bitwise operation. | |
| 1158 var_bitop_lhs.Bind(assembler->TruncateHeapNumberValueToInt32(lhs)); | |
| 1159 var_bitop_rhs.Bind(assembler->TruncateHeapNumberValueToInt32(rhs)); | |
| 1160 assembler->Goto(&do_bitop); | |
| 1161 } | |
| 1162 | |
| 1163 assembler->Bind(&if_rhsisnotnumber); | |
| 1164 { | |
| 1165 // Convert the {rhs} to a Number first. | |
| 1166 Callable callable = | |
| 1167 CodeFactory::NonNumberToNumber(assembler->isolate()); | |
| 1168 var_rhs.Bind(assembler->CallStub(callable, context, rhs)); | |
| 1169 assembler->Goto(&loop); | |
| 1170 } | |
| 1171 } | |
| 1172 } | |
| 1173 | |
| 1174 assembler->Bind(&if_lhsisnotnumber); | |
| 1175 { | |
| 1176 // Convert the {lhs} to a Number first. | |
| 1177 Callable callable = | |
| 1178 CodeFactory::NonNumberToNumber(assembler->isolate()); | |
| 1179 var_lhs.Bind(assembler->CallStub(callable, context, lhs)); | |
| 1180 assembler->Goto(&loop); | |
| 1181 } | |
| 1182 } | |
| 1183 } | |
| 1184 | |
| 1185 assembler->Bind(&do_bitop); | |
| 1186 { | |
| 1187 Node* lhs_value = var_bitop_lhs.value(); | |
| 1188 Node* rhs_value = var_bitop_rhs.value(); | |
| 1189 Node* value = (assembler->*bitop)(lhs_value, rhs_value); | |
| 1190 Node* result = assembler->ChangeInt32ToTagged(value); | |
| 1191 assembler->Return(result); | |
| 1192 } | |
| 1193 } | |
| 1194 | |
| 1195 } // namespace | |
| 1196 | |
| 1197 void BitwiseAndStub::GenerateAssembly( | 1036 void BitwiseAndStub::GenerateAssembly( |
| 1198 compiler::CodeStubAssembler* assembler) const { | 1037 compiler::CodeStubAssembler* assembler) const { |
| 1199 GenerateBitwiseOperation(assembler, &compiler::CodeStubAssembler::Word32And); | 1038 using compiler::Node; |
| 1039 |
| 1040 Node* lhs = assembler->Parameter(0); |
| 1041 Node* rhs = assembler->Parameter(1); |
| 1042 Node* context = assembler->Parameter(2); |
| 1043 Node* lhs_value = assembler->TruncateTaggedToWord32(context, lhs); |
| 1044 Node* rhs_value = assembler->TruncateTaggedToWord32(context, rhs); |
| 1045 Node* value = assembler->Word32And(lhs_value, rhs_value); |
| 1046 Node* result = assembler->ChangeInt32ToTagged(value); |
| 1047 assembler->Return(result); |
| 1200 } | 1048 } |
| 1201 | 1049 |
| 1202 void BitwiseOrStub::GenerateAssembly( | 1050 void BitwiseOrStub::GenerateAssembly( |
| 1203 compiler::CodeStubAssembler* assembler) const { | 1051 compiler::CodeStubAssembler* assembler) const { |
| 1204 GenerateBitwiseOperation(assembler, &compiler::CodeStubAssembler::Word32Or); | 1052 using compiler::Node; |
| 1053 |
| 1054 Node* lhs = assembler->Parameter(0); |
| 1055 Node* rhs = assembler->Parameter(1); |
| 1056 Node* context = assembler->Parameter(2); |
| 1057 Node* lhs_value = assembler->TruncateTaggedToWord32(context, lhs); |
| 1058 Node* rhs_value = assembler->TruncateTaggedToWord32(context, rhs); |
| 1059 Node* value = assembler->Word32Or(lhs_value, rhs_value); |
| 1060 Node* result = assembler->ChangeInt32ToTagged(value); |
| 1061 assembler->Return(result); |
| 1205 } | 1062 } |
| 1206 | 1063 |
| 1207 void BitwiseXorStub::GenerateAssembly( | 1064 void BitwiseXorStub::GenerateAssembly( |
| 1208 compiler::CodeStubAssembler* assembler) const { | 1065 compiler::CodeStubAssembler* assembler) const { |
| 1209 GenerateBitwiseOperation(assembler, &compiler::CodeStubAssembler::Word32Xor); | 1066 using compiler::Node; |
| 1067 |
| 1068 Node* lhs = assembler->Parameter(0); |
| 1069 Node* rhs = assembler->Parameter(1); |
| 1070 Node* context = assembler->Parameter(2); |
| 1071 Node* lhs_value = assembler->TruncateTaggedToWord32(context, lhs); |
| 1072 Node* rhs_value = assembler->TruncateTaggedToWord32(context, rhs); |
| 1073 Node* value = assembler->Word32Xor(lhs_value, rhs_value); |
| 1074 Node* result = assembler->ChangeInt32ToTagged(value); |
| 1075 assembler->Return(result); |
| 1210 } | 1076 } |
| 1211 | 1077 |
| 1212 namespace { | 1078 namespace { |
| 1213 | 1079 |
| 1214 enum RelationalComparisonMode { | 1080 enum RelationalComparisonMode { |
| 1215 kLessThan, | 1081 kLessThan, |
| 1216 kLessThanOrEqual, | 1082 kLessThanOrEqual, |
| 1217 kGreaterThan, | 1083 kGreaterThan, |
| 1218 kGreaterThanOrEqual | 1084 kGreaterThanOrEqual |
| 1219 }; | 1085 }; |
| (...skipping 2291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3511 if (type->Is(Type::UntaggedPointer())) { | 3377 if (type->Is(Type::UntaggedPointer())) { |
| 3512 return Representation::External(); | 3378 return Representation::External(); |
| 3513 } | 3379 } |
| 3514 | 3380 |
| 3515 DCHECK(!type->Is(Type::Untagged())); | 3381 DCHECK(!type->Is(Type::Untagged())); |
| 3516 return Representation::Tagged(); | 3382 return Representation::Tagged(); |
| 3517 } | 3383 } |
| 3518 | 3384 |
| 3519 } // namespace internal | 3385 } // namespace internal |
| 3520 } // namespace v8 | 3386 } // namespace v8 |
| OLD | NEW |