| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/compiler/instruction-selector-impl.h" | 5 #include "src/compiler/instruction-selector-impl.h" |
| 6 #include "src/compiler/node-matchers.h" | 6 #include "src/compiler/node-matchers.h" |
| 7 | 7 |
| 8 namespace v8 { | 8 namespace v8 { |
| 9 namespace internal { | 9 namespace internal { |
| 10 namespace compiler { | 10 namespace compiler { |
| (...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 975 } else { | 975 } else { |
| 976 DCHECK(cont->IsSet()); | 976 DCHECK(cont->IsSet()); |
| 977 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); | 977 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); |
| 978 } | 978 } |
| 979 } | 979 } |
| 980 | 980 |
| 981 | 981 |
| 982 // Shared routine for multiple word compare operations. | 982 // Shared routine for multiple word compare operations. |
| 983 static void VisitWordCompare(InstructionSelector* selector, Node* node, | 983 static void VisitWordCompare(InstructionSelector* selector, Node* node, |
| 984 InstructionCode opcode, FlagsContinuation* cont, | 984 InstructionCode opcode, FlagsContinuation* cont, |
| 985 bool commutative) { | 985 bool commutative, ImmediateMode immediate_mode) { |
| 986 Arm64OperandGenerator g(selector); | 986 Arm64OperandGenerator g(selector); |
| 987 Node* left = node->InputAt(0); | 987 Node* left = node->InputAt(0); |
| 988 Node* right = node->InputAt(1); | 988 Node* right = node->InputAt(1); |
| 989 | 989 |
| 990 // Match immediates on left or right side of comparison. | 990 // Match immediates on left or right side of comparison. |
| 991 if (g.CanBeImmediate(right, kArithmeticImm)) { | 991 if (g.CanBeImmediate(right, immediate_mode)) { |
| 992 VisitCompare(selector, opcode, g.UseRegister(left), g.UseImmediate(right), | 992 VisitCompare(selector, opcode, g.UseRegister(left), g.UseImmediate(right), |
| 993 cont); | 993 cont); |
| 994 } else if (g.CanBeImmediate(left, kArithmeticImm)) { | 994 } else if (g.CanBeImmediate(left, immediate_mode)) { |
| 995 if (!commutative) cont->Commute(); | 995 if (!commutative) cont->Commute(); |
| 996 VisitCompare(selector, opcode, g.UseRegister(right), g.UseImmediate(left), | 996 VisitCompare(selector, opcode, g.UseRegister(right), g.UseImmediate(left), |
| 997 cont); | 997 cont); |
| 998 } else { | 998 } else { |
| 999 VisitCompare(selector, opcode, g.UseRegister(left), g.UseRegister(right), | 999 VisitCompare(selector, opcode, g.UseRegister(left), g.UseRegister(right), |
| 1000 cont); | 1000 cont); |
| 1001 } | 1001 } |
| 1002 } | 1002 } |
| 1003 | 1003 |
| 1004 | 1004 |
| 1005 static void VisitWord32Compare(InstructionSelector* selector, Node* node, | 1005 static void VisitWord32Compare(InstructionSelector* selector, Node* node, |
| 1006 FlagsContinuation* cont) { | 1006 FlagsContinuation* cont) { |
| 1007 VisitWordCompare(selector, node, kArm64Cmp32, cont, false); | 1007 VisitWordCompare(selector, node, kArm64Cmp32, cont, false, kArithmeticImm); |
| 1008 } | 1008 } |
| 1009 | 1009 |
| 1010 | 1010 |
| 1011 static void VisitWordTest(InstructionSelector* selector, Node* node, | 1011 static void VisitWordTest(InstructionSelector* selector, Node* node, |
| 1012 InstructionCode opcode, FlagsContinuation* cont) { | 1012 InstructionCode opcode, FlagsContinuation* cont) { |
| 1013 Arm64OperandGenerator g(selector); | 1013 Arm64OperandGenerator g(selector); |
| 1014 VisitCompare(selector, opcode, g.UseRegister(node), g.UseRegister(node), | 1014 VisitCompare(selector, opcode, g.UseRegister(node), g.UseRegister(node), |
| 1015 cont); | 1015 cont); |
| 1016 } | 1016 } |
| 1017 | 1017 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1091 cont.OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); | 1091 cont.OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); |
| 1092 return VisitWord32Compare(this, value, &cont); | 1092 return VisitWord32Compare(this, value, &cont); |
| 1093 case IrOpcode::kUint32LessThan: | 1093 case IrOpcode::kUint32LessThan: |
| 1094 cont.OverwriteAndNegateIfEqual(kUnsignedLessThan); | 1094 cont.OverwriteAndNegateIfEqual(kUnsignedLessThan); |
| 1095 return VisitWord32Compare(this, value, &cont); | 1095 return VisitWord32Compare(this, value, &cont); |
| 1096 case IrOpcode::kUint32LessThanOrEqual: | 1096 case IrOpcode::kUint32LessThanOrEqual: |
| 1097 cont.OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); | 1097 cont.OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); |
| 1098 return VisitWord32Compare(this, value, &cont); | 1098 return VisitWord32Compare(this, value, &cont); |
| 1099 case IrOpcode::kWord64Equal: | 1099 case IrOpcode::kWord64Equal: |
| 1100 cont.OverwriteAndNegateIfEqual(kEqual); | 1100 cont.OverwriteAndNegateIfEqual(kEqual); |
| 1101 return VisitWordCompare(this, value, kArm64Cmp, &cont, false); | 1101 return VisitWordCompare(this, value, kArm64Cmp, &cont, false, |
| 1102 kArithmeticImm); |
| 1102 case IrOpcode::kInt64LessThan: | 1103 case IrOpcode::kInt64LessThan: |
| 1103 cont.OverwriteAndNegateIfEqual(kSignedLessThan); | 1104 cont.OverwriteAndNegateIfEqual(kSignedLessThan); |
| 1104 return VisitWordCompare(this, value, kArm64Cmp, &cont, false); | 1105 return VisitWordCompare(this, value, kArm64Cmp, &cont, false, |
| 1106 kArithmeticImm); |
| 1105 case IrOpcode::kInt64LessThanOrEqual: | 1107 case IrOpcode::kInt64LessThanOrEqual: |
| 1106 cont.OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); | 1108 cont.OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); |
| 1107 return VisitWordCompare(this, value, kArm64Cmp, &cont, false); | 1109 return VisitWordCompare(this, value, kArm64Cmp, &cont, false, |
| 1110 kArithmeticImm); |
| 1108 case IrOpcode::kUint64LessThan: | 1111 case IrOpcode::kUint64LessThan: |
| 1109 cont.OverwriteAndNegateIfEqual(kUnsignedLessThan); | 1112 cont.OverwriteAndNegateIfEqual(kUnsignedLessThan); |
| 1110 return VisitWordCompare(this, value, kArm64Cmp, &cont, false); | 1113 return VisitWordCompare(this, value, kArm64Cmp, &cont, false, |
| 1114 kArithmeticImm); |
| 1111 case IrOpcode::kFloat64Equal: | 1115 case IrOpcode::kFloat64Equal: |
| 1112 cont.OverwriteAndNegateIfEqual(kUnorderedEqual); | 1116 cont.OverwriteAndNegateIfEqual(kUnorderedEqual); |
| 1113 return VisitFloat64Compare(this, value, &cont); | 1117 return VisitFloat64Compare(this, value, &cont); |
| 1114 case IrOpcode::kFloat64LessThan: | 1118 case IrOpcode::kFloat64LessThan: |
| 1115 cont.OverwriteAndNegateIfEqual(kUnorderedLessThan); | 1119 cont.OverwriteAndNegateIfEqual(kUnorderedLessThan); |
| 1116 return VisitFloat64Compare(this, value, &cont); | 1120 return VisitFloat64Compare(this, value, &cont); |
| 1117 case IrOpcode::kFloat64LessThanOrEqual: | 1121 case IrOpcode::kFloat64LessThanOrEqual: |
| 1118 cont.OverwriteAndNegateIfEqual(kUnorderedLessThanOrEqual); | 1122 cont.OverwriteAndNegateIfEqual(kUnorderedLessThanOrEqual); |
| 1119 return VisitFloat64Compare(this, value, &cont); | 1123 return VisitFloat64Compare(this, value, &cont); |
| 1120 case IrOpcode::kProjection: | 1124 case IrOpcode::kProjection: |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1138 cont.OverwriteAndNegateIfEqual(kOverflow); | 1142 cont.OverwriteAndNegateIfEqual(kOverflow); |
| 1139 return VisitBinop<Int32BinopMatcher>(this, node, kArm64Sub32, | 1143 return VisitBinop<Int32BinopMatcher>(this, node, kArm64Sub32, |
| 1140 kArithmeticImm, &cont); | 1144 kArithmeticImm, &cont); |
| 1141 default: | 1145 default: |
| 1142 break; | 1146 break; |
| 1143 } | 1147 } |
| 1144 } | 1148 } |
| 1145 } | 1149 } |
| 1146 break; | 1150 break; |
| 1147 case IrOpcode::kInt32Add: | 1151 case IrOpcode::kInt32Add: |
| 1148 return VisitWordCompare(this, value, kArm64Cmn32, &cont, true); | 1152 return VisitWordCompare(this, value, kArm64Cmn32, &cont, true, |
| 1153 kArithmeticImm); |
| 1149 case IrOpcode::kInt32Sub: | 1154 case IrOpcode::kInt32Sub: |
| 1150 return VisitWordCompare(this, value, kArm64Cmp32, &cont, false); | 1155 return VisitWordCompare(this, value, kArm64Cmp32, &cont, false, |
| 1156 kArithmeticImm); |
| 1151 case IrOpcode::kWord32And: | 1157 case IrOpcode::kWord32And: |
| 1152 return VisitWordCompare(this, value, kArm64Tst32, &cont, true); | 1158 return VisitWordCompare(this, value, kArm64Tst32, &cont, true, |
| 1159 kLogical32Imm); |
| 1153 default: | 1160 default: |
| 1154 break; | 1161 break; |
| 1155 } | 1162 } |
| 1156 } | 1163 } |
| 1157 | 1164 |
| 1158 // Branch could not be combined with a compare, emit compare against 0. | 1165 // Branch could not be combined with a compare, emit compare against 0. |
| 1159 VisitWord32Test(this, value, &cont); | 1166 VisitWord32Test(this, value, &cont); |
| 1160 } | 1167 } |
| 1161 | 1168 |
| 1162 | 1169 |
| 1163 void InstructionSelector::VisitWord32Equal(Node* const node) { | 1170 void InstructionSelector::VisitWord32Equal(Node* const node) { |
| 1164 Node* const user = node; | 1171 Node* const user = node; |
| 1165 FlagsContinuation cont(kEqual, node); | 1172 FlagsContinuation cont(kEqual, node); |
| 1166 Int32BinopMatcher m(user); | 1173 Int32BinopMatcher m(user); |
| 1167 if (m.right().Is(0)) { | 1174 if (m.right().Is(0)) { |
| 1168 Node* const value = m.left().node(); | 1175 Node* const value = m.left().node(); |
| 1169 if (CanCover(user, value)) { | 1176 if (CanCover(user, value)) { |
| 1170 switch (value->opcode()) { | 1177 switch (value->opcode()) { |
| 1171 case IrOpcode::kInt32Add: | 1178 case IrOpcode::kInt32Add: |
| 1172 return VisitWordCompare(this, value, kArm64Cmn32, &cont, true); | 1179 return VisitWordCompare(this, value, kArm64Cmn32, &cont, true, |
| 1180 kArithmeticImm); |
| 1173 case IrOpcode::kInt32Sub: | 1181 case IrOpcode::kInt32Sub: |
| 1174 return VisitWordCompare(this, value, kArm64Cmp32, &cont, false); | 1182 return VisitWordCompare(this, value, kArm64Cmp32, &cont, false, |
| 1183 kArithmeticImm); |
| 1175 case IrOpcode::kWord32And: | 1184 case IrOpcode::kWord32And: |
| 1176 return VisitWordCompare(this, value, kArm64Tst32, &cont, true); | 1185 return VisitWordCompare(this, value, kArm64Tst32, &cont, true, |
| 1186 kLogical32Imm); |
| 1177 default: | 1187 default: |
| 1178 break; | 1188 break; |
| 1179 } | 1189 } |
| 1180 return VisitWord32Test(this, value, &cont); | 1190 return VisitWord32Test(this, value, &cont); |
| 1181 } | 1191 } |
| 1182 } | 1192 } |
| 1183 VisitWord32Compare(this, node, &cont); | 1193 VisitWord32Compare(this, node, &cont); |
| 1184 } | 1194 } |
| 1185 | 1195 |
| 1186 | 1196 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1210 | 1220 |
| 1211 void InstructionSelector::VisitWord64Equal(Node* const node) { | 1221 void InstructionSelector::VisitWord64Equal(Node* const node) { |
| 1212 Node* const user = node; | 1222 Node* const user = node; |
| 1213 FlagsContinuation cont(kEqual, node); | 1223 FlagsContinuation cont(kEqual, node); |
| 1214 Int64BinopMatcher m(user); | 1224 Int64BinopMatcher m(user); |
| 1215 if (m.right().Is(0)) { | 1225 if (m.right().Is(0)) { |
| 1216 Node* const value = m.left().node(); | 1226 Node* const value = m.left().node(); |
| 1217 if (CanCover(user, value)) { | 1227 if (CanCover(user, value)) { |
| 1218 switch (value->opcode()) { | 1228 switch (value->opcode()) { |
| 1219 case IrOpcode::kWord64And: | 1229 case IrOpcode::kWord64And: |
| 1220 return VisitWordCompare(this, value, kArm64Tst, &cont, true); | 1230 return VisitWordCompare(this, value, kArm64Tst, &cont, true, |
| 1231 kLogical64Imm); |
| 1221 default: | 1232 default: |
| 1222 break; | 1233 break; |
| 1223 } | 1234 } |
| 1224 return VisitWord64Test(this, value, &cont); | 1235 return VisitWord64Test(this, value, &cont); |
| 1225 } | 1236 } |
| 1226 } | 1237 } |
| 1227 VisitWordCompare(this, node, kArm64Cmp, &cont, false); | 1238 VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm); |
| 1228 } | 1239 } |
| 1229 | 1240 |
| 1230 | 1241 |
| 1231 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) { | 1242 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) { |
| 1232 if (Node* ovf = node->FindProjection(1)) { | 1243 if (Node* ovf = node->FindProjection(1)) { |
| 1233 FlagsContinuation cont(kOverflow, ovf); | 1244 FlagsContinuation cont(kOverflow, ovf); |
| 1234 return VisitBinop<Int32BinopMatcher>(this, node, kArm64Add32, | 1245 return VisitBinop<Int32BinopMatcher>(this, node, kArm64Add32, |
| 1235 kArithmeticImm, &cont); | 1246 kArithmeticImm, &cont); |
| 1236 } | 1247 } |
| 1237 FlagsContinuation cont; | 1248 FlagsContinuation cont; |
| 1238 VisitBinop<Int32BinopMatcher>(this, node, kArm64Add32, kArithmeticImm, &cont); | 1249 VisitBinop<Int32BinopMatcher>(this, node, kArm64Add32, kArithmeticImm, &cont); |
| 1239 } | 1250 } |
| 1240 | 1251 |
| 1241 | 1252 |
| 1242 void InstructionSelector::VisitInt32SubWithOverflow(Node* node) { | 1253 void InstructionSelector::VisitInt32SubWithOverflow(Node* node) { |
| 1243 if (Node* ovf = node->FindProjection(1)) { | 1254 if (Node* ovf = node->FindProjection(1)) { |
| 1244 FlagsContinuation cont(kOverflow, ovf); | 1255 FlagsContinuation cont(kOverflow, ovf); |
| 1245 return VisitBinop<Int32BinopMatcher>(this, node, kArm64Sub32, | 1256 return VisitBinop<Int32BinopMatcher>(this, node, kArm64Sub32, |
| 1246 kArithmeticImm, &cont); | 1257 kArithmeticImm, &cont); |
| 1247 } | 1258 } |
| 1248 FlagsContinuation cont; | 1259 FlagsContinuation cont; |
| 1249 VisitBinop<Int32BinopMatcher>(this, node, kArm64Sub32, kArithmeticImm, &cont); | 1260 VisitBinop<Int32BinopMatcher>(this, node, kArm64Sub32, kArithmeticImm, &cont); |
| 1250 } | 1261 } |
| 1251 | 1262 |
| 1252 | 1263 |
| 1253 void InstructionSelector::VisitInt64LessThan(Node* node) { | 1264 void InstructionSelector::VisitInt64LessThan(Node* node) { |
| 1254 FlagsContinuation cont(kSignedLessThan, node); | 1265 FlagsContinuation cont(kSignedLessThan, node); |
| 1255 VisitWordCompare(this, node, kArm64Cmp, &cont, false); | 1266 VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm); |
| 1256 } | 1267 } |
| 1257 | 1268 |
| 1258 | 1269 |
| 1259 void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) { | 1270 void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) { |
| 1260 FlagsContinuation cont(kSignedLessThanOrEqual, node); | 1271 FlagsContinuation cont(kSignedLessThanOrEqual, node); |
| 1261 VisitWordCompare(this, node, kArm64Cmp, &cont, false); | 1272 VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm); |
| 1262 } | 1273 } |
| 1263 | 1274 |
| 1264 | 1275 |
| 1265 void InstructionSelector::VisitUint64LessThan(Node* node) { | 1276 void InstructionSelector::VisitUint64LessThan(Node* node) { |
| 1266 FlagsContinuation cont(kUnsignedLessThan, node); | 1277 FlagsContinuation cont(kUnsignedLessThan, node); |
| 1267 VisitWordCompare(this, node, kArm64Cmp, &cont, false); | 1278 VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm); |
| 1268 } | 1279 } |
| 1269 | 1280 |
| 1270 | 1281 |
| 1271 void InstructionSelector::VisitFloat64Equal(Node* node) { | 1282 void InstructionSelector::VisitFloat64Equal(Node* node) { |
| 1272 FlagsContinuation cont(kUnorderedEqual, node); | 1283 FlagsContinuation cont(kUnorderedEqual, node); |
| 1273 VisitFloat64Compare(this, node, &cont); | 1284 VisitFloat64Compare(this, node, &cont); |
| 1274 } | 1285 } |
| 1275 | 1286 |
| 1276 | 1287 |
| 1277 void InstructionSelector::VisitFloat64LessThan(Node* node) { | 1288 void InstructionSelector::VisitFloat64LessThan(Node* node) { |
| 1278 FlagsContinuation cont(kUnorderedLessThan, node); | 1289 FlagsContinuation cont(kUnorderedLessThan, node); |
| 1279 VisitFloat64Compare(this, node, &cont); | 1290 VisitFloat64Compare(this, node, &cont); |
| 1280 } | 1291 } |
| 1281 | 1292 |
| 1282 | 1293 |
| 1283 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) { | 1294 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) { |
| 1284 FlagsContinuation cont(kUnorderedLessThanOrEqual, node); | 1295 FlagsContinuation cont(kUnorderedLessThanOrEqual, node); |
| 1285 VisitFloat64Compare(this, node, &cont); | 1296 VisitFloat64Compare(this, node, &cont); |
| 1286 } | 1297 } |
| 1287 | 1298 |
| 1288 } // namespace compiler | 1299 } // namespace compiler |
| 1289 } // namespace internal | 1300 } // namespace internal |
| 1290 } // namespace v8 | 1301 } // namespace v8 |
| OLD | NEW |