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 |