Home | History | Annotate | Download | only in arm64

Lines Matching refs:node

6 #include "src/compiler/node-matchers.h"
7 #include "src/compiler/node-properties.h"
33 InstructionOperand UseOperand(Node* node, ImmediateMode mode) {
34 if (CanBeImmediate(node, mode)) {
35 return UseImmediate(node);
37 return UseRegister(node);
40 // Use the zero register if the node has the immediate value zero, otherwise
42 InstructionOperand UseRegisterOrImmediateZero(Node* node) {
43 if ((IsIntegerConstant(node) && (GetIntegerConstantValue(node) == 0)) ||
44 (IsFloatConstant(node) &&
45 (bit_cast<int64_t>(GetFloatConstantValue(node)) == V8_INT64_C(0)))) {
46 return UseImmediate(node);
48 return UseRegister(node);
51 // Use the provided node if it has the required value, or create a
53 InstructionOperand UseImmediateOrTemp(Node* node, int32_t value) {
54 if (GetIntegerConstantValue(node) == value) {
55 return UseImmediate(node);
60 bool IsIntegerConstant(Node* node) {
61 return (node->opcode() == IrOpcode::kInt32Constant) ||
62 (node->opcode() == IrOpcode::kInt64Constant);
65 int64_t GetIntegerConstantValue(Node* node) {
66 if (node->opcode() == IrOpcode::kInt32Constant) {
67 return OpParameter<int32_t>(node);
69 DCHECK(node->opcode() == IrOpcode::kInt64Constant);
70 return OpParameter<int64_t>(node);
73 bool IsFloatConstant(Node* node) {
74 return (node->opcode() == IrOpcode::kFloat32Constant) ||
75 (node->opcode() == IrOpcode::kFloat64Constant);
78 double GetFloatConstantValue(Node* node) {
79 if (node->opcode() == IrOpcode::kFloat32Constant) {
80 return OpParameter<float>(node);
82 DCHECK_EQ(IrOpcode::kFloat64Constant, node->opcode());
83 return OpParameter<double>(node);
86 bool CanBeImmediate(Node* node, ImmediateMode mode) {
87 return IsIntegerConstant(node) &&
88 CanBeImmediate(GetIntegerConstantValue(node), mode);
124 bool CanBeLoadStoreShiftImmediate(Node* node, MachineRepresentation rep) {
127 return IsIntegerConstant(node) &&
128 (GetIntegerConstantValue(node) == ElementSizeLog2Of(rep));
141 void VisitRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) {
143 selector->Emit(opcode, g.DefineAsRegister(node),
144 g.UseRegister(node->InputAt(0)));
148 void VisitRRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) {
150 selector->Emit(opcode, g.DefineAsRegister(node),
151 g.UseRegister(node->InputAt(0)),
152 g.UseRegister(node->InputAt(1)));
156 void VisitRRO(InstructionSelector* selector, ArchOpcode opcode, Node* node,
159 selector->Emit(opcode, g.DefineAsRegister(node),
160 g.UseRegister(node->InputAt(0)),
161 g.UseOperand(node->InputAt(1), operand_mode));
165 bool TryMatchAnyShift(InstructionSelector* selector, Node* node,
166 Node* input_node, InstructionCode* opcode, bool try_ror) {
169 if (!selector->CanCover(node, input_node)) return false;
200 Node* node, Node* left_node, Node* right_node,
203 if (!selector->CanCover(node, right_node)) return false;
212 *right_op = g->UseRegister(mright.left().node());
219 if (selector->CanCover(mright.node(), mright.left().node()) &&
221 Int32BinopMatcher mleft_of_right(mright.left().node());
226 *right_op = g->UseRegister(mleft_of_right.left().node());
238 MachineRepresentation rep, Node* node, Node* index,
241 if (!selector->CanCover(node, index)) return false;
243 Node* left = index->InputAt(0);
244 Node* right = index->InputAt(1);
327 void VisitBinop(InstructionSelector* selector, Node* node,
336 Node* left_node = node->InputAt(0);
337 Node* right_node = node->InputAt(1);
352 TryMatchAnyExtend(&g, selector, node, left_node, right_node,
356 TryMatchAnyExtend(&g, selector, node, right_node, left_node,
360 } else if (TryMatchAnyShift(selector, node, right_node, &opcode,
364 inputs[input_count++] = g.UseRegister(m_shift.left().node());
365 inputs[input_count++] = g.UseImmediate(m_shift.right().node());
366 } else if (can_commute && TryMatchAnyShift(selector, node, left_node, &opcode,
371 inputs[input_count++] = g.UseRegister(m_shift.left().node());
372 inputs[input_count++] = g.UseImmediate(m_shift.right().node());
384 outputs[output_count++] = g.DefineAsRegister(node);
408 void VisitBinop(InstructionSelector* selector, Node* node, ArchOpcode opcode,
411 VisitBinop<Matcher>(selector, node, opcode, operand_mode, &cont);
416 void VisitAddSub(InstructionSelector* selector, Node* node, ArchOpcode opcode,
419 Matcher m(node);
422 selector->Emit(negate_opcode, g.DefineAsRegister(node),
423 g.UseRegister(m.left().node()),
426 VisitBinop<Matcher>(selector, node, opcode, kArithmeticImm);
449 void InstructionSelector::VisitLoad(Node* node) {
450 LoadRepresentation load_rep = LoadRepresentationOf(node->op());
453 Node* base = node->InputAt(0);
454 Node* index = node->InputAt(1);
493 outputs[0] = g.DefineAsRegister(node);
500 } else if (TryMatchLoadStoreShift(&g, this, rep, node, index, &inputs[1],
514 void InstructionSelector::VisitStore(Node* node) {
516 Node* base = node->InputAt(0);
517 Node* index = node->InputAt(1);
518 Node* value = node->InputAt(2);
520 StoreRepresentation store_rep = StoreRepresentationOf(node->op());
608 } else if (TryMatchLoadStoreShift(&g, this, rep, node, index, &inputs[2],
623 void InstructionSelector::VisitCheckedLoad(Node* node) {
624 CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op());
626 Node* const buffer = node->InputAt(0);
627 Node* const offset = node->InputAt(1);
628 Node* const length = node->InputAt(2);
662 Emit(opcode, g.DefineAsRegister(node), g.UseRegister(buffer),
667 Emit(opcode, g.DefineAsRegister(node), g.UseRegister(buffer),
672 void InstructionSelector::VisitCheckedStore(Node* node) {
673 MachineRepresentation rep = CheckedStoreRepresentationOf(node->op());
675 Node* const buffer = node->InputAt(0);
676 Node* const offset = node->InputAt(1);
677 Node* const length = node->InputAt(2);
678 Node* const value = node->InputAt(3);
724 static void VisitLogical(InstructionSelector* selector, Node* node, Matcher* m,
756 Matcher mleft(m->left().node());
759 selector->Emit(inv_opcode, g.DefineAsRegister(node),
760 g.UseRegister(m->right().node()),
761 g.UseRegister(mleft.left().node()));
769 Matcher mright(m->right().node());
772 selector->Emit(inv_opcode, g.DefineAsRegister(node),
773 g.UseRegister(m->left().node()),
774 g.UseRegister(mright.left().node()));
780 selector->Emit(kArm64Not32, g.DefineAsRegister(node),
781 g.UseRegister(m->left().node()));
783 selector->Emit(kArm64Not, g.DefineAsRegister(node),
784 g.UseRegister(m->left().node()));
786 VisitBinop<Matcher>(selector, node, opcode, imm_mode);
791 void InstructionSelector::VisitWord32And(Node* node) {
793 Int32BinopMatcher m(node);
794 if (m.left().IsWord32Shr() && CanCover(node, m.left().node()) &&
805 Int32BinopMatcher mleft(m.left().node());
816 Emit(kArm64Ubfx32, g.DefineAsRegister(node),
817 g.UseRegister(mleft.left().node()),
818 g.UseImmediateOrTemp(mleft.right().node(), lsb),
826 this, node, &m, kArm64And32, CanCover(node, m.left().node()),
827 CanCover(node, m.right().node()), kLogical32Imm);
831 void InstructionSelector::VisitWord64And(Node* node) {
833 Int64BinopMatcher m(node);
834 if (m.left().IsWord64Shr() && CanCover(node, m.left().node()) &&
845 Int64BinopMatcher mleft(m.left().node());
856 Emit(kArm64Ubfx, g.DefineAsRegister(node),
857 g.UseRegister(mleft.left().node()),
858 g.UseImmediateOrTemp(mleft.right().node(), lsb),
866 this, node, &m, kArm64And, CanCover(node, m.left().node()),
867 CanCover(node, m.right().node()), kLogical64Imm);
871 void InstructionSelector::VisitWord32Or(Node* node) {
872 Int32BinopMatcher m(node);
874 this, node, &m, kArm64Or32, CanCover(node, m.left().node()),
875 CanCover(node, m.right().node()), kLogical32Imm);
879 void InstructionSelector::VisitWord64Or(Node* node) {
880 Int64BinopMatcher m(node);
882 this, node, &m, kArm64Or, CanCover(node, m.left().node()),
883 CanCover(node, m.right().node()), kLogical64Imm);
887 void InstructionSelector::VisitWord32Xor(Node* node) {
888 Int32BinopMatcher m(node);
890 this, node, &m, kArm64Eor32, CanCover(node, m.left().node()),
891 CanCover(node, m.right().node()), kLogical32Imm);
895 void InstructionSelector::VisitWord64Xor(Node* node) {
896 Int64BinopMatcher m(node);
898 this, node, &m, kArm64Eor, CanCover(node, m.left().node()),
899 CanCover(node, m.right().node()), kLogical64Imm);
903 void InstructionSelector::VisitWord32Shl(Node* node) {
904 Int32BinopMatcher m(node);
905 if (m.left().IsWord32And() && CanCover(node, m.left().node()) &&
908 Int32BinopMatcher mleft(m.left().node());
921 Emit(kArm64Lsl32, g.DefineAsRegister(node),
922 g.UseRegister(mleft.left().node()),
923 g.UseImmediate(m.right().node()));
928 Emit(kArm64Ubfiz32, g.DefineAsRegister(node),
929 g.UseRegister(mleft.left().node()),
930 g.UseImmediate(m.right().node()), g.TempImmediate(mask_width));
936 VisitRRO(this, kArm64Lsl32, node, kShift32Imm);
940 void InstructionSelector::VisitWord64Shl(Node* node) {
942 Int64BinopMatcher m(node);
947 Emit(kArm64Lsl, g.DefineAsRegister(node),
948 g.UseRegister(m.left().node()->InputAt(0)),
949 g.UseImmediate(m.right().node()));
952 VisitRRO(this, kArm64Lsl, node, kShift64Imm);
958 bool TryEmitBitfieldExtract32(InstructionSelector* selector, Node* node) {
960 Int32BinopMatcher m(node);
961 if (selector->CanCover(node, m.left().node()) && m.left().IsWord32Shl()) {
964 Int32BinopMatcher mleft(m.left().node());
973 selector->Emit(opcode, g.DefineAsRegister(node),
974 g.UseRegister(mleft.left().node()), g.TempImmediate(0),
985 void InstructionSelector::VisitWord32Shr(Node* node) {
986 Int32BinopMatcher m(node);
989 Int32BinopMatcher mleft(m.left().node());
999 Emit(kArm64Ubfx32, g.DefineAsRegister(node),
1000 g.UseRegister(mleft.left().node()),
1001 g.UseImmediateOrTemp(m.right().node(), lsb),
1006 } else if (TryEmitBitfieldExtract32(this, node)) {
1011 CanCover(node, node->InputAt(0))) {
1015 Node* left = m.left().node();
1020 Emit(kArm64Lsr, g.DefineAsRegister(node), smull_operand,
1025 VisitRRO(this, kArm64Lsr32, node, kShift32Imm);
1029 void InstructionSelector::VisitWord64Shr(Node* node) {
1030 Int64BinopMatcher m(node);
1033 Int64BinopMatcher mleft(m.left().node());
1043 Emit(kArm64Ubfx, g.DefineAsRegister(node),
1044 g.UseRegister(mleft.left().node()),
1045 g.UseImmediateOrTemp(m.right().node(), lsb),
1051 VisitRRO(this, kArm64Lsr, node, kShift64Imm);
1055 void InstructionSelector::VisitWord32Sar(Node* node) {
1056 if (TryEmitBitfieldExtract32(this, node)) {
1060 Int32BinopMatcher m(node);
1062 CanCover(node, node->InputAt(0))) {
1066 Node* left = m.left().node();
1071 Emit(kArm64Asr, g.DefineAsRegister(node), smull_operand,
1077 CanCover(node, node->InputAt(0))) {
1078 Node* add_node = m.left().node();
1081 CanCover(add_node, madd_node.left().node())) {
1087 Node* mul_node = madd_node.left().node();
1098 Emit(kArm64Asr32, g.DefineAsRegister(node), add_operand,
1099 g.UseImmediate(node->InputAt(1)));
1104 VisitRRO(this, kArm64Asr32, node, kShift32Imm);
1108 void InstructionSelector::VisitWord64Sar(Node* node) {
1109 VisitRRO(this, kArm64Asr, node, kShift64Imm);
1113 void InstructionSelector::VisitWord32Ror(Node* node) {
1114 VisitRRO(this, kArm64Ror32, node, kShift32Imm);
1118 void InstructionSelector::VisitWord64Ror(Node* node) {
1119 VisitRRO(this, kArm64Ror, node, kShift64Imm);
1123 void InstructionSelector::VisitWord64Clz(Node* node) {
1125 Emit(kArm64Clz, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
1129 void InstructionSelector::VisitWord32Clz(Node* node) {
1131 Emit(kArm64Clz32, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
1135 void InstructionSelector::VisitWord32Ctz(Node* node) { UNREACHABLE(); }
1138 void InstructionSelector::VisitWord64Ctz(Node* node) { UNREACHABLE(); }
1141 void InstructionSelector::VisitWord32ReverseBits(Node* node) {
1142 VisitRR(this, kArm64Rbit32, node);
1146 void InstructionSelector::VisitWord64ReverseBits(Node* node) {
1147 VisitRR(this, kArm64Rbit, node);
1151 void InstructionSelector::VisitWord32Popcnt(Node* node) { UNREACHABLE(); }
1154 void InstructionSelector::VisitWord64Popcnt(Node* node) { UNREACHABLE(); }
1157 void InstructionSelector::VisitInt32Add(Node* node) {
1159 Int32BinopMatcher m(node);
1161 if (m.left().IsInt32Mul() && CanCover(node, m.left().node())) {
1162 Int32BinopMatcher mleft(m.left().node());
1165 Emit(kArm64Madd32, g.DefineAsRegister(node),
1166 g.UseRegister(mleft.left().node()),
1167 g.UseRegister(mleft.right().node()),
1168 g.UseRegister(m.right().node()));
1173 if (m.right().IsInt32Mul() && CanCover(node, m.right().node())) {
1174 Int32BinopMatcher mright(m.right().node());
1177 Emit(kArm64Madd32, g.DefineAsRegister(node),
1178 g.UseRegister(mright.left().node()),
1179 g.UseRegister(mright.right().node()),
1180 g.UseRegister(m.left().node()));
1184 VisitAddSub<Int32BinopMatcher>(this, node, kArm64Add32, kArm64Sub32);
1188 void InstructionSelector::VisitInt64Add(Node* node) {
1190 Int64BinopMatcher m(node);
1192 if (m.left().IsInt64Mul() && CanCover(node, m.left().node())) {
1193 Int64BinopMatcher mleft(m.left().node());
1196 Emit(kArm64Madd, g.DefineAsRegister(node),
1197 g.UseRegister(mleft.left().node()),
1198 g.UseRegister(mleft.right().node()),
1199 g.UseRegister(m.right().node()));
1204 if (m.right().IsInt64Mul() && CanCover(node, m.right().node())) {
1205 Int64BinopMatcher mright(m.right().node());
1208 Emit(kArm64Madd, g.DefineAsRegister(node),
1209 g.UseRegister(mright.left().node()),
1210 g.UseRegister(mright.right().node()),
1211 g.UseRegister(m.left().node()));
1215 VisitAddSub<Int64BinopMatcher>(this, node, kArm64Add, kArm64Sub);
1219 void InstructionSelector::VisitInt32Sub(Node* node) {
1221 Int32BinopMatcher m(node);
1224 if (m.right().IsInt32Mul() && CanCover(node, m.right().node())) {
1225 Int32BinopMatcher mright(m.right().node());
1228 Emit(kArm64Msub32, g.DefineAsRegister(node),
1229 g.UseRegister(mright.left().node()),
1230 g.UseRegister(mright.right().node()),
1231 g.UseRegister(m.left().node()));
1236 VisitAddSub<Int32BinopMatcher>(this, node, kArm64Sub32, kArm64Add32);
1240 void InstructionSelector::VisitInt64Sub(Node* node) {
1242 Int64BinopMatcher m(node);
1245 if (m.right().IsInt64Mul() && CanCover(node, m.right().node())) {
1246 Int64BinopMatcher mright(m.right().node());
1249 Emit(kArm64Msub, g.DefineAsRegister(node),
1250 g.UseRegister(mright.left().node()),
1251 g.UseRegister(mright.right().node()),
1252 g.UseRegister(m.left().node()));
1257 VisitAddSub<Int64BinopMatcher>(this, node, kArm64Sub, kArm64Add);
1261 void InstructionSelector::VisitInt32Mul(Node* node) {
1263 Int32BinopMatcher m(node);
1270 g.DefineAsRegister(node), g.UseRegister(m.left().node()),
1271 g.UseRegister(m.left().node()), g.TempImmediate(shift));
1275 if (m.left().IsInt32Sub() && CanCover(node, m.left().node())) {
1276 Int32BinopMatcher mleft(m.left().node());
1280 Emit(kArm64Mneg32, g.DefineAsRegister(node),
1281 g.UseRegister(mleft.right().node()),
1282 g.UseRegister(m.right().node()));
1287 if (m.right().IsInt32Sub() && CanCover(node, m.right().node())) {
1288 Int32BinopMatcher mright(m.right().node());
1292 Emit(kArm64Mneg32, g.DefineAsRegister(node),
1293 g.UseRegister(m.left().node()),
1294 g.UseRegister(mright.right().node()));
1299 VisitRRR(this, kArm64Mul32, node);
1303 void InstructionSelector::VisitInt64Mul(Node* node) {
1305 Int64BinopMatcher m(node);
1312 g.DefineAsRegister(node), g.UseRegister(m.left().node()),
1313 g.UseRegister(m.left().node()), g.TempImmediate(shift));
1317 if (m.left().IsInt64Sub() && CanCover(node, m.left().node())) {
1318 Int64BinopMatcher mleft(m.left().node());
1322 Emit(kArm64Mneg, g.DefineAsRegister(node),
1323 g.UseRegister(mleft.right().node()),
1324 g.UseRegister(m.right().node()));
1329 if (m.right().IsInt64Sub() && CanCover(node, m.right().node())) {
1330 Int64BinopMatcher mright(m.right().node());
1334 Emit(kArm64Mneg, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
1335 g.UseRegister(mright.right().node()));
1340 VisitRRR(this, kArm64Mul, node);
1344 void InstructionSelector::VisitInt32MulHigh(Node* node) {
1347 Emit(kArm64Smull, smull_operand, g.UseRegister(node->InputAt(0)),
1348 g.UseRegister(node->InputAt(1)));
1349 Emit(kArm64Asr, g.DefineAsRegister(node), smull_operand, g.TempImmediate(32));
1353 void InstructionSelector::VisitUint32MulHigh(Node* node) {
1356 Emit(kArm64Umull, smull_operand, g.UseRegister(node->InputAt(0)),
1357 g.UseRegister(node->InputAt(1)));
1358 Emit(kArm64Lsr, g.DefineAsRegister(node), smull_operand, g.TempImmediate(32));
1362 void InstructionSelector::VisitInt32Div(Node* node) {
1363 VisitRRR(this, kArm64Idiv32, node);
1367 void InstructionSelector::VisitInt64Div(Node* node) {
1368 VisitRRR(this, kArm64Idiv, node);
1372 void InstructionSelector::VisitUint32Div(Node* node) {
1373 VisitRRR(this, kArm64Udiv32, node);
1377 void InstructionSelector::VisitUint64Div(Node* node) {
1378 VisitRRR(this, kArm64Udiv, node);
1382 void InstructionSelector::VisitInt32Mod(Node* node) {
1383 VisitRRR(this, kArm64Imod32, node);
1387 void InstructionSelector::VisitInt64Mod(Node* node) {
1388 VisitRRR(this, kArm64Imod, node);
1392 void InstructionSelector::VisitUint32Mod(Node* node) {
1393 VisitRRR(this, kArm64Umod32, node);
1397 void InstructionSelector::VisitUint64Mod(Node* node) {
1398 VisitRRR(this, kArm64Umod, node);
1402 void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) {
1403 VisitRR(this, kArm64Float32ToFloat64, node);
1407 Node* node) {
1408 VisitRR(this, kArm64Int32ToFloat32, node);
1412 void InstructionSelector::VisitRoundUint32ToFloat32(Node* node) {
1413 VisitRR(this, kArm64Uint32ToFloat32, node);
1417 void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) {
1418 VisitRR(this, kArm64Int32ToFloat64, node);
1422 void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) {
1423 VisitRR(this, kArm64Uint32ToFloat64, node);
1427 void InstructionSelector::VisitTruncateFloat32ToInt32(Node* node) {
1428 VisitRR(this, kArm64Float32ToInt32, node);
1432 void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) {
1433 VisitRR(this, kArm64Float64ToInt32, node);
1437 void InstructionSelector::VisitTruncateFloat32ToUint32(Node* node) {
1438 VisitRR(this, kArm64Float32ToUint32, node);
1442 void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) {
1443 VisitRR(this, kArm64Float64ToUint32, node);
1446 void InstructionSelector::VisitTruncateFloat64ToUint32(Node* node) {
1447 VisitRR(this, kArm64Float64ToUint32, node);
1450 void InstructionSelector::VisitTryTruncateFloat32ToInt64(Node* node) {
1453 InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))};
1456 outputs[output_count++] = g.DefineAsRegister(node);
1458 Node* success_output = NodeProperties::FindProjection(node, 1);
1467 void InstructionSelector::VisitTryTruncateFloat64ToInt64(Node* node) {
1470 InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))};
1473 outputs[output_count++] = g.DefineAsRegister(node);
1475 Node* success_output = NodeProperties::FindProjection(node, 1);
1484 void InstructionSelector::VisitTryTruncateFloat32ToUint64(Node* node) {
1487 InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))};
1490 outputs[output_count++] = g.DefineAsRegister(node);
1492 Node* success_output = NodeProperties::FindProjection(node, 1);
1501 void InstructionSelector::VisitTryTruncateFloat64ToUint64(Node* node) {
1504 InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))};
1507 outputs[output_count++] = g.DefineAsRegister(node);
1509 Node* success_output = NodeProperties::FindProjection(node, 1);
1518 void InstructionSelector::VisitChangeInt32ToInt64(Node* node) {
1519 VisitRR(this, kArm64Sxtw, node);
1523 void InstructionSelector::VisitChangeUint32ToUint64(Node* node) {
1525 Node* value = node->InputAt(0);
1553 Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value));
1564 Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value));
1573 Emit(kArm64Mov32, g.DefineAsRegister(node), g.UseRegister(value));
1577 void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) {
1578 VisitRR(this, kArm64Float64ToFloat32, node);
1581 void InstructionSelector::VisitTruncateFloat64ToWord32(Node* node) {
1582 VisitRR(this, kArchTruncateDoubleToI, node);
1585 void InstructionSelector::VisitRoundFloat64ToInt32(Node* node) {
1586 VisitRR(this, kArm64Float64ToInt32, node);
1590 void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) {
1592 Node* value = node->InputAt(0);
1593 if (CanCover(node, value) && value->InputCount() >= 2) {
1598 Emit(kArm64Lsr, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
1599 g.UseImmediate(m.right().node()));
1604 Emit(kArm64Mov32, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
1608 void InstructionSelector::VisitRoundInt64ToFloat32(Node* node) {
1609 VisitRR(this, kArm64Int64ToFloat32, node);
1613 void InstructionSelector::VisitRoundInt64ToFloat64(Node* node) {
1614 VisitRR(this, kArm64Int64ToFloat64, node);
1618 void InstructionSelector::VisitRoundUint64ToFloat32(Node* node) {
1619 VisitRR(this, kArm64Uint64ToFloat32, node);
1623 void InstructionSelector::VisitRoundUint64ToFloat64(Node* node) {
1624 VisitRR(this, kArm64Uint64ToFloat64, node);
1628 void InstructionSelector::VisitBitcastFloat32ToInt32(Node* node) {
1629 VisitRR(this, kArm64Float64ExtractLowWord32, node);
1633 void InstructionSelector::VisitBitcastFloat64ToInt64(Node* node) {
1634 VisitRR(this, kArm64U64MoveFloat64, node);
1638 void InstructionSelector::VisitBitcastInt32ToFloat32(Node* node) {
1639 VisitRR(this, kArm64Float64MoveU64, node);
1643 void InstructionSelector::VisitBitcastInt64ToFloat64(Node* node) {
1644 VisitRR(this, kArm64Float64MoveU64, node);
1648 void InstructionSelector::VisitFloat32Add(Node* node) {
1649 VisitRRR(this, kArm64Float32Add, node);
1653 void InstructionSelector::VisitFloat64Add(Node* node) {
1654 VisitRRR(this, kArm64Float64Add, node);
1658 void InstructionSelector::VisitFloat32Sub(Node* node) {
1659 VisitRRR(this, kArm64Float32Sub, node);
1662 void InstructionSelector::VisitFloat32SubPreserveNan(Node* node) {
1663 VisitRRR(this, kArm64Float32Sub, node);
1666 void InstructionSelector::VisitFloat64Sub(Node* node) {
1668 Float64BinopMatcher m(node);
1671 CanCover(m.node(), m.right().node())) {
1673 CanCover(m.right().node(), m.right().InputAt(0))) {
1676 Emit(kArm64Float64RoundUp, g.DefineAsRegister(node),
1677 g.UseRegister(mright0.right().node()));
1682 Emit(kArm64Float64Neg, g.DefineAsRegister(node),
1683 g.UseRegister(m.right().node()));
1686 VisitRRR(this, kArm64Float64Sub, node);
1689 void InstructionSelector::VisitFloat64SubPreserveNan(Node* node) {
1690 VisitRRR(this, kArm64Float64Sub, node);
1693 void InstructionSelector::VisitFloat32Mul(Node* node) {
1694 VisitRRR(this, kArm64Float32Mul, node);
1698 void InstructionSelector::VisitFloat64Mul(Node* node) {
1699 VisitRRR(this, kArm64Float64Mul, node);
1703 void InstructionSelector::VisitFloat32Div(Node* node) {
1704 VisitRRR(this, kArm64Float32Div, node);
1708 void InstructionSelector::VisitFloat64Div(Node* node) {
1709 VisitRRR(this, kArm64Float64Div, node);
1713 void InstructionSelector::VisitFloat64Mod(Node* node) {
1715 Emit(kArm64Float64Mod, g.DefineAsFixed(node, d0),
1716 g.UseFixed(node->InputAt(0), d0),
1717 g.UseFixed(node->InputAt(1), d1))->MarkAsCall();
1721 void InstructionSelector::VisitFloat32Max(Node* node) {
1722 VisitRRR(this, kArm64Float32Max, node);
1726 void InstructionSelector::VisitFloat64Max(Node* node) {
1727 VisitRRR(this, kArm64Float64Max, node);
1731 void InstructionSelector::VisitFloat32Min(Node* node) {
1732 VisitRRR(this, kArm64Float32Min, node);
1736 void InstructionSelector::VisitFloat64Min(Node* node) {
1737 VisitRRR(this, kArm64Float64Min, node);
1741 void InstructionSelector::VisitFloat32Abs(Node* node) {
1742 VisitRR(this, kArm64Float32Abs, node);
1746 void InstructionSelector::VisitFloat64Abs(Node* node) {
1747 VisitRR(this, kArm64Float64Abs, node);
1750 void InstructionSelector::VisitFloat32Sqrt(Node* node) {
1751 VisitRR(this, kArm64Float32Sqrt, node);
1755 void InstructionSelector::VisitFloat64Sqrt(Node* node) {
1756 VisitRR(this, kArm64Float64Sqrt, node);
1760 void InstructionSelector::VisitFloat32RoundDown(Node* node) {
1761 VisitRR(this, kArm64Float32RoundDown, node);
1765 void InstructionSelector::VisitFloat64RoundDown(Node* node) {
1766 VisitRR(this, kArm64Float64RoundDown, node);
1770 void InstructionSelector::VisitFloat32RoundUp(Node* node) {
1771 VisitRR(this, kArm64Float32RoundUp, node);
1775 void InstructionSelector::VisitFloat64RoundUp(Node* node) {
1776 VisitRR(this, kArm64Float64RoundUp, node);
1780 void InstructionSelector::VisitFloat32RoundTruncate(Node* node) {
1781 VisitRR(this, kArm64Float32RoundTruncate, node);
1785 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) {
1786 VisitRR(this, kArm64Float64RoundTruncate, node);
1790 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) {
1791 VisitRR(this, kArm64Float64RoundTiesAway, node);
1795 void InstructionSelector::VisitFloat32RoundTiesEven(Node* node) {
1796 VisitRR(this, kArm64Float32RoundTiesEven, node);
1800 void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) {
1801 VisitRR(this, kArm64Float64RoundTiesEven, node);
1804 void InstructionSelector::VisitFloat32Neg(Node* node) {
1805 VisitRR(this, kArm64Float32Neg, node);
1808 void InstructionSelector::VisitFloat64Neg(Node* node) {
1809 VisitRR(this, kArm64Float64Neg, node);
1812 void InstructionSelector::VisitFloat64Ieee754Binop(Node* node,
1815 Emit(opcode, g.DefineAsFixed(node, d0), g.UseFixed(node->InputAt(0), d0),
1816 g.UseFixed(node->InputAt(1), d1))
1820 void InstructionSelector::VisitFloat64Ieee754Unop(Node* node,
1823 Emit(opcode, g.DefineAsFixed(node, d0), g.UseFixed(node->InputAt(0), d0))
1829 Node* node) {
1852 Emit(poke, g.NoOutput(), g.UseRegister((*arguments)[slot].node()),
1890 void VisitWordCompare(InstructionSelector* selector, Node* node,
1894 Node* left = node->InputAt(0);
1895 Node* right = node->InputAt(1);
1912 void VisitWord32Compare(InstructionSelector* selector, Node* node,
1914 Int32BinopMatcher m(node);
1919 Node* sub = m.right().node();
1922 bool can_cover = selector->CanCover(node, sub);
1923 node->ReplaceInput(1, msub.right().node());
1924 // Even if the comparison node covers the subtraction, after the input
1925 // replacement above, the node still won't cover the input to the
1928 // input to the subtraction, as TryMatchAnyShift requires this node to
1931 // any other node.
1932 if (can_cover) sub->ReplaceInput(1, msub.left().node());
1936 VisitBinop<Int32BinopMatcher>(selector, node, opcode, kArithmeticImm, cont);
1940 void VisitWordTest(InstructionSelector* selector, Node* node,
1943 VisitCompare(selector, opcode, g.UseRegister(node), g.UseRegister(node),
1948 Node* node,
1950 VisitWordTest(selector, node, kArm64Tst32, cont);
1954 void VisitWord64Test(InstructionSelector* selector, Node* node,
1956 VisitWordTest(selector, node, kArm64Tst, cont);
1960 bool TryEmitTestAndBranch(InstructionSelector* selector, Node* node,
1963 Matcher m(node);
1969 cont->Encode(kOpcode), g.NoOutput(), g.UseRegister(m.left().node()),
1978 void VisitFloat32Compare(InstructionSelector* selector, Node* node,
1981 Float32BinopMatcher m(node);
1983 VisitCompare(selector, kArm64Float32Cmp, g.UseRegister(m.left().node()),
1984 g.UseImmediate(m.right().node()), cont);
1987 VisitCompare(selector, kArm64Float32Cmp, g.UseRegister(m.right().node()),
1988 g.UseImmediate(m.left().node()), cont);
1990 VisitCompare(selector, kArm64Float32Cmp, g.UseRegister(m.left().node()),
1991 g.UseRegister(m.right().node()), cont);
1997 void VisitFloat64Compare(InstructionSelector* selector, Node* node,
2000 Float64BinopMatcher m(node);
2002 VisitCompare(selector, kArm64Float64Cmp, g.UseRegister(m.left().node()),
2003 g.UseImmediate(m.right().node()), cont);
2006 VisitCompare(selector, kArm64Float64Cmp, g.UseRegister(m.right().node()),
2007 g.UseImmediate(m.left().node()), cont);
2009 VisitCompare(selector, kArm64Float64Cmp, g.UseRegister(m.left().node()),
2010 g.UseRegister(m.right().node()), cont);
2014 void VisitWordCompareZero(InstructionSelector* selector, Node* user,
2015 Node* value, FlagsContinuation* cont) {
2025 value = m.left().node();
2048 Node* const left = m.left().node();
2107 // <Operation>WithOverflow node.
2114 Node* const node = value->InputAt(0);
2115 Node* const result = NodeProperties::FindProjection(node, 0);
2117 switch (node->opcode()) {
2121 selector, node, kArm64Add32, kArithmeticImm, cont);
2125 selector, node, kArm64Sub32, kArithmeticImm, cont);
2128 return VisitBinop<Int64BinopMatcher>(selector, node, kArm64Add,
2132 return VisitBinop<Int64BinopMatcher>(selector, node, kArm64Sub,
2180 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
2186 void InstructionSelector::VisitDeoptimizeIf(Node* node) {
2188 FlagsContinuation::ForDeoptimize(kNotEqual, node->InputAt(1));
2189 VisitWordCompareZero(this, node, node->InputAt(0), &cont);
2192 void InstructionSelector::VisitDeoptimizeUnless(Node* node) {
2194 FlagsContinuation::ForDeoptimize(kEqual, node->InputAt(1));
2195 VisitWordCompareZero(this, node, node->InputAt(0), &cont);
2198 void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) {
2200 InstructionOperand value_operand = g.UseRegister(node->InputAt(0));
2226 void InstructionSelector::VisitWord32Equal(Node* const node) {
2227 Node* const user = node;
2228 FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
2231 Node* const value = m.left().node();
2246 node->ReplaceInput(0, mequal.left().node());
2247 node->ReplaceInput(1, mequal.right().node());
2249 return VisitWord32Compare(this, node, &cont);
2257 VisitWord32Compare(this, node, &cont);
2261 void InstructionSelector::VisitInt32LessThan(Node* node) {
2262 FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThan, node);
2263 VisitWord32Compare(this, node, &cont);
2267 void InstructionSelector::VisitInt32LessThanOrEqual(Node* node) {
2269 FlagsContinuation::ForSet(kSignedLessThanOrEqual, node);
2270 VisitWord32Compare(this, node, &cont);
2274 void InstructionSelector::VisitUint32LessThan(Node* node) {
2275 FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node);
2276 VisitWord32Compare(this, node, &cont);
2280 void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) {
2282 FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
2283 VisitWord32Compare(this, node, &cont);
2287 void InstructionSelector::VisitWord64Equal(Node* const node) {
2288 Node* const user = node;
2289 FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
2292 Node* const value = m.left().node();
2304 VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm);
2308 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
2309 if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
2311 return VisitBinop<Int32BinopMatcher>(this, node, kArm64Add32,
2315 VisitBinop<Int32BinopMatcher>(this, node, kArm64Add32, kArithmeticImm, &cont);
2319 void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
2320 if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
2322 return VisitBinop<Int32BinopMatcher>(this, node, kArm64Sub32,
2326 VisitBinop<Int32BinopMatcher>(this, node, kArm64Sub32, kArithmeticImm, &cont);
2330 void InstructionSelector::VisitInt64AddWithOverflow(Node* node) {
2331 if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
2333 return VisitBinop<Int64BinopMatcher>(this, node, kArm64Add, kArithmeticImm,
2337 VisitBinop<Int64BinopMatcher>(this, node, kArm64Add, kArithmeticImm, &cont);
2341 void InstructionSelector::VisitInt64SubWithOverflow(Node* node) {
2342 if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
2344 return VisitBinop<Int64BinopMatcher>(this, node, kArm64Sub, kArithmeticImm,
2348 node, kArm64Sub, kArithmeticImm, &cont);
2352 void InstructionSelector::VisitInt64LessThan(Node* node) {
2353 FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThan, node);
2354 VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm);
2358 void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) {
2360 FlagsContinuation::ForSet(kSignedLessThanOrEqual, node);
2361 VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm);
2365 void InstructionSelector::VisitUint64LessThan(Node* node) {
2366 FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node);
2367 VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm);
2371 void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) {
2373 FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
2374 VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm);
2378 void InstructionSelector::VisitFloat32Equal(Node* node) {
2379 FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
2380 VisitFloat32Compare(this, node, &cont);
2384 void InstructionSelector::VisitFloat32LessThan(Node* node) {
2385 FlagsContinuation cont = FlagsContinuation::ForSet(kFloatLessThan, node);
2386 VisitFloat32Compare(this, node, &cont);
2390 void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) {
2392 FlagsContinuation::ForSet(kFloatLessThanOrEqual, node);
2393 VisitFloat32Compare(this, node, &cont);
2397 void InstructionSelector::VisitFloat64Equal(Node* node) {
2398 FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
2399 VisitFloat64Compare(this, node, &cont);
2403 void InstructionSelector::VisitFloat64LessThan(Node* node) {
2404 FlagsContinuation cont = FlagsContinuation::ForSet(kFloatLessThan, node);
2405 VisitFloat64Compare(this, node, &cont);
2409 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
2411 FlagsContinuation::ForSet(kFloatLessThanOrEqual, node);
2412 VisitFloat64Compare(this, node, &cont);
2416 void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) {
2418 Emit(kArm64Float64ExtractLowWord32, g.DefineAsRegister(node),
2419 g.UseRegister(node->InputAt(0)));
2423 void InstructionSelector::VisitFloat64ExtractHighWord32(Node* node) {
2425 Emit(kArm64Float64ExtractHighWord32, g.DefineAsRegister(node),
2426 g.UseRegister(node->InputAt(0)));
2430 void InstructionSelector::VisitFloat64InsertLowWord32(Node* node) {
2432 Node* left = node->InputAt(0);
2433 Node* right = node->InputAt(1);
2435 CanCover(node, left)) {
2436 Node* right_of_left = left->InputAt(1);
2440 Emit(kArm64Float64MoveU64, g.DefineAsRegister(node), g.UseRegister(right));
2443 Emit(kArm64Float64InsertLowWord32, g.DefineAsRegister(node),
2448 void InstructionSelector::VisitFloat64InsertHighWord32(Node* node) {
2450 Node* left = node->InputAt(0);
2451 Node* right = node->InputAt(1);
2453 CanCover(node, left)) {
2454 Node* right_of_left = left->InputAt(1);
2457 Emit(kArm64Float64MoveU64, g.DefineAsRegister(node), g.UseRegister(left));
2460 Emit(kArm64Float64InsertHighWord32, g.DefineAsRegister(node),
2464 void InstructionSelector::VisitFloat64SilenceNaN(Node* node) {
2465 VisitRR(this, kArm64Float64SilenceNaN, node);
2468 void InstructionSelector::VisitAtomicLoad(Node* node) {
2469 LoadRepresentation load_rep = LoadRepresentationOf(node->op());
2471 Node* base = node->InputAt(0);
2472 Node* index = node->InputAt(1);
2489 g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(index));
2492 void InstructionSelector::VisitAtomicStore(Node* node) {
2493 MachineRepresentation rep = AtomicStoreRepresentationOf(node->op());
2495 Node* base = node->InputAt(0);
2496 Node* index = node->InputAt(1);
2497 Node* value = node->InputAt(2);