19using namespace turboshaft;
21#define TRACE(...) PrintF(__VA_ARGS__)
41 if ((constant->IsIntegral() && constant->integral() == 0) ||
42 (constant->kind == ConstantOp::Kind::kFloat32 &&
43 constant->float32().get_bits() == 0) ||
44 (constant->kind == ConstantOp::Kind::kFloat64 &&
45 constant->float64().get_bits() == 0))
65 if (!constant)
return false;
66 if (constant->kind == ConstantOp::Kind::kCompressedHeapObject) {
97 return is_uint5(value);
101 return is_uint6(value);
109 return is_uint12(value);
114 case kAtomicLoadWord32:
115 case kAtomicStoreWord32:
116 case kLoong64Word64AtomicLoadUint64:
117 case kLoong64Word64AtomicStoreWord64:
118 case kLoong64StoreCompressTagged:
119 return (is_int12(value) || (is_int16(value) && ((value & 0b11) == 0)));
121 return is_int12(value);
127 TRACE(
"UNIMPLEMENTED instr_sel: %s at line %d\n", __FUNCTION__, __LINE__);
192struct ExtendingLoadMatcher {
222 DCHECK(shift.
kind == ShiftOp::Kind::kShiftRightArithmetic ||
223 shift.
kind == ShiftOp::Kind::kShiftRightArithmeticShiftOutZeros);
228 int64_t constant_rhs;
231 selector_->MatchIntegralWord64Constant(shift.
right(), &constant_rhs) &&
232 constant_rhs == 32 &&
selector_->CanCover(node, shift.
left())) {
238 if (load.index().has_value()) {
239 int64_t index_constant;
240 if (
selector_->MatchIntegralWord64Constant(load.index().value(),
256 ExtendingLoadMatcher
m(node, selector);
263 DCHECK(is_int32(
m.immediate()));
280 *input_count_return = 1;
292 size_t input_count = 0;
294 size_t output_count = 0;
304 }
else if (has_reverse_opcode &&
306 &input_count, &inputs[1])) {
308 opcode = reverse_opcode;
312 inputs[input_count++] = g.
UseOperand(right_node, opcode);
330 VisitBinop(selector, node, opcode, has_reverse_opcode, reverse_opcode, &cont);
335 VisitBinop(selector, node, opcode,
false, kArchNop, cont);
340 VisitBinop(selector, node, opcode,
false, kArchNop);
343void InstructionSelectorT::VisitStackSlot(
OpIndex node) {
349 Emit(kArchStackSlot, g.DefineAsRegister(node),
350 sequence()->AddImmediate(Constant(slot)), 0,
nullptr);
353void InstructionSelectorT::VisitAbortCSADcheck(
OpIndex node) {
354 Loong64OperandGeneratorT g(
this);
355 Emit(kArchAbortCSADcheck, g.NoOutput(),
356 g.UseFixed(this->input_at(node, 0), a0));
361 Loong64OperandGeneratorT g(selector);
368 OpIndex index = load.index().value();
372 InstructionOperand inputs[3];
373 size_t input_count = 0;
374 InstructionOperand output_op;
378 output_op = g.DefineAsRegister(output.valid() ? output : node);
387 ptrdiff_t
const delta =
394 if (is_int32(delta)) {
395 inputs[0] = g.UseImmediate(
static_cast<int32_t
>(delta));
397 selector->
Emit(opcode, 1, &output_op, input_count, inputs);
403 if (base_op.
Is<LoadRootRegisterOp>()) {
407 inputs[0] = g.UseImmediate64(index_value);
409 selector->
Emit(opcode, 1, &output_op, input_count, inputs);
413 if (g.CanBeImmediate(index, opcode)) {
415 g.DefineAsRegister(output.valid() ? output : node),
416 g.UseRegister(base), g.UseImmediate(index));
419 g.DefineAsRegister(output.valid() ? output : node),
420 g.UseRegister(base), g.UseRegister(index));
437 switch (loaded_rep) {
443 return kLoong64Ld_bu;
449 return kLoong64Ld_hu;
462 return kLoong64Fld_s;
465 return kLoong64Fld_d;
466#ifdef V8_COMPRESS_POINTERS
470 return kLoong64Ld_wu;
473 return kLoong64LoadDecompressTagged;
476 return kLoong64Ld_wu;
479 return kLoong64LoadDecompressTaggedSigned;
482 case MemoryRepresentation::TaggedPointer():
483 case MemoryRepresentation::TaggedSigned():
488 case MemoryRepresentation::UncompressedTaggedPointer():
489 case MemoryRepresentation::UncompressedTaggedSigned():
494 return kLoong64LoadDecompressProtected;
498 return kLoong64LoadDecodeSandboxedPointer;
500 case MemoryRepresentation::
Simd256():
505ArchOpcode GetStoreOpcode(turboshaft::MemoryRepresentation stored_rep) {
506 switch (stored_rep) {
508 case MemoryRepresentation::Uint8():
511 case MemoryRepresentation::Uint16():
514 case MemoryRepresentation::Uint32():
517 case MemoryRepresentation::Uint64():
522 return kLoong64Fst_s;
524 return kLoong64Fst_d;
526 case MemoryRepresentation::TaggedPointer():
527 case MemoryRepresentation::TaggedSigned():
528 return kLoong64StoreCompressTagged;
530 case MemoryRepresentation::UncompressedTaggedPointer():
531 case MemoryRepresentation::UncompressedTaggedSigned():
537 return kLoong64StoreIndirectPointer;
539 return kLoong64StoreEncodeSandboxedPointer;
541 case MemoryRepresentation::
Simd256():
552 opcode = GetLoadOpcode(load.ts_loaded_rep(), load.ts_result_rep());
555 if (load.is_protected(&traps_on_null)) {
566void InstructionSelectorT::VisitProtectedLoad(
OpIndex node) {
VisitLoad(node); }
570void InstructionSelectorT::VisitStore(
OpIndex node) {
571 Loong64OperandGeneratorT g(
this);
582 if (
v8_flags.enable_unconditional_write_barriers &&
592 InstructionOperand
inputs[4];
597 if (g.CanBeImmediate(index, kLoong64Add_d)) {
599 addressing_mode = kMode_MRI;
602 addressing_mode = kMode_MRR;
611 code = kArchStoreIndirectWithWriteBarrier;
615 code = kArchStoreWithWriteBarrier;
629 std::optional<ExternalReference> external_base;
631 ExternalReference
value;
633 external_base =
value;
637 std::optional<int64_t> constant_index;
640 constant_index = g.GetOptionalIntegerConstant(index);
642 if (external_base.has_value() && constant_index.has_value() &&
644 ptrdiff_t
const delta =
650 if (is_int32(delta)) {
652 g.UseImmediate(
static_cast<int32_t>(delta)),
653 g.UseRegisterOrImmediateZero(value));
661 g.UseImmediate(index), g.UseRegisterOrImmediateZero(value));
672 if (g.CanBeImmediate(index, code)) {
674 g.UseRegister(base), g.UseImmediate(index),
675 g.UseRegisterOrImmediateZero(value));
678 g.UseRegister(base), g.UseRegister(index),
679 g.UseRegisterOrImmediateZero(value));
683void InstructionSelectorT::VisitProtectedStore(
OpIndex node) {
689 VisitBinop(
this, node, kLoong64And32,
true, kLoong64And32);
692void InstructionSelectorT::VisitWord64And(
OpIndex node) {
694 VisitBinop(
this, node, kLoong64And,
true, kLoong64And);
697void InstructionSelectorT::VisitWord32Or(
OpIndex node) {
698 VisitBinop(
this, node, kLoong64Or32,
true, kLoong64Or32);
701void InstructionSelectorT::VisitWord64Or(
OpIndex node) {
702 VisitBinop(
this, node, kLoong64Or,
true, kLoong64Or);
705void InstructionSelectorT::VisitWord32Xor(
OpIndex node) {
707 VisitBinop(
this, node, kLoong64Xor32,
true, kLoong64Xor32);
710void InstructionSelectorT::VisitWord64Xor(
OpIndex node) {
712 VisitBinop(
this, node, kLoong64Xor,
true, kLoong64Xor);
715void InstructionSelectorT::VisitWord32Shl(
OpIndex node) {
717 VisitRRO(
this, kLoong64Sll_w, node);
720void InstructionSelectorT::VisitWord32Shr(
OpIndex node) {
721 VisitRRO(
this, kLoong64Srl_w, node);
726 VisitRRO(
this, kLoong64Sra_w, node);
729void InstructionSelectorT::VisitWord64Shl(
OpIndex node) {
736 int64_t shift_by = rhs.Cast<ConstantOp>().signed_integral();
738 Loong64OperandGeneratorT g(
this);
741 Emit(kLoong64Sll_d, g.DefineAsRegister(node),
742 g.UseRegister(lhs.Cast<ChangeOp>().input()),
743 g.UseImmediate(shift_by));
747 VisitRRO(
this, kLoong64Sll_d, node);
750void InstructionSelectorT::VisitWord64Shr(
OpIndex node) {
752 VisitRRO(
this, kLoong64Srl_d, node);
755void InstructionSelectorT::VisitWord64Sar(
OpIndex node) {
763 int64_t constant_rhs;
766 is_uint5(constant_rhs) &&
CanCover(node, shiftop.left())) {
767 OpIndex input = lhs.Cast<ChangeOp>().input();
769 Loong64OperandGeneratorT g(
this);
770 int right =
static_cast<int>(constant_rhs);
771 Emit(kLoong64Sra_w, g.DefineAsRegister(node), g.UseRegister(input),
772 g.UseImmediate(right));
777 VisitRRO(
this, kLoong64Sra_d, node);
784void InstructionSelectorT::VisitWord32Ror(
OpIndex node) {
785 VisitRRO(
this, kLoong64Rotr_w, node);
788void InstructionSelectorT::VisitWord64Ror(
OpIndex node) {
789 VisitRRO(
this, kLoong64Rotr_d, node);
792void InstructionSelectorT::VisitWord32ReverseBits(
OpIndex node) {
796void InstructionSelectorT::VisitWord64ReverseBits(
OpIndex node) {
800void InstructionSelectorT::VisitWord32ReverseBytes(
OpIndex node) {
801 VisitRR(
this, kLoong64ByteSwap32, node);
804void InstructionSelectorT::VisitWord64ReverseBytes(
OpIndex node) {
805 VisitRR(
this, kLoong64ByteSwap64, node);
808void InstructionSelectorT::VisitSimd128ReverseBytes(
OpIndex node) {
812void InstructionSelectorT::VisitWord32Clz(
OpIndex node) {
813 VisitRR(
this, kLoong64Clz_w, node);
816void InstructionSelectorT::VisitWord64Clz(
OpIndex node) {
817 VisitRR(
this, kLoong64Clz_d, node);
828void InstructionSelectorT::VisitInt32Add(
OpIndex node) {
830 VisitBinop(
this, node, kLoong64Add_w,
true, kLoong64Add_w);
833void InstructionSelectorT::VisitInt64Add(
OpIndex node) {
835 VisitBinop(
this, node, kLoong64Add_d,
true, kLoong64Add_d);
838void InstructionSelectorT::VisitInt32Sub(
OpIndex node) {
842void InstructionSelectorT::VisitInt64Sub(
OpIndex node) {
846void InstructionSelectorT::VisitInt32Mul(
OpIndex node) {
848 VisitBinop(
this, node, kLoong64Mul_w,
true, kLoong64Mul_w);
851void InstructionSelectorT::VisitInt32MulHigh(
OpIndex node) {
852 VisitRRR(
this, kLoong64Mulh_w, node);
855void InstructionSelectorT::VisitInt64MulHigh(
OpIndex node) {
856 VisitRRR(
this, kLoong64Mulh_d, node);
859void InstructionSelectorT::VisitUint32MulHigh(
OpIndex node) {
860 VisitRRR(
this, kLoong64Mulh_wu, node);
863void InstructionSelectorT::VisitUint64MulHigh(
OpIndex node) {
864 VisitRRR(
this, kLoong64Mulh_du, node);
867void InstructionSelectorT::VisitInt64Mul(
OpIndex node) {
869 VisitBinop(
this, node, kLoong64Mul_d,
true, kLoong64Mul_d);
872void InstructionSelectorT::VisitInt32Div(
OpIndex node) {
873 Loong64OperandGeneratorT g(
this);
876 Emit(kLoong64Div_w, g.DefineSameAsFirst(node), g.UseRegister(left),
877 g.UseRegister(right));
880void InstructionSelectorT::VisitUint32Div(
OpIndex node) {
881 Loong64OperandGeneratorT g(
this);
884 Emit(kLoong64Div_wu, g.DefineSameAsFirst(node), g.UseRegister(left),
885 g.UseRegister(right));
888void InstructionSelectorT::VisitInt32Mod(
OpIndex node) {
889 Loong64OperandGeneratorT g(
this);
892 Emit(kLoong64Mod_w, g.DefineSameAsFirst(node), g.UseRegister(left),
893 g.UseRegister(right));
896void InstructionSelectorT::VisitUint32Mod(
OpIndex node) {
897 VisitRRR(
this, kLoong64Mod_wu, node);
900void InstructionSelectorT::VisitInt64Div(
OpIndex node) {
901 Loong64OperandGeneratorT g(
this);
904 Emit(kLoong64Div_d, g.DefineSameAsFirst(node), g.UseRegister(left),
905 g.UseRegister(right));
908void InstructionSelectorT::VisitUint64Div(
OpIndex node) {
909 Loong64OperandGeneratorT g(
this);
912 Emit(kLoong64Div_du, g.DefineSameAsFirst(node), g.UseRegister(left),
913 g.UseRegister(right));
916void InstructionSelectorT::VisitInt64Mod(
OpIndex node) {
917 VisitRRR(
this, kLoong64Mod_d, node);
920void InstructionSelectorT::VisitUint64Mod(
OpIndex node) {
921 VisitRRR(
this, kLoong64Mod_du, node);
924void InstructionSelectorT::VisitChangeFloat32ToFloat64(
OpIndex node) {
925 VisitRR(
this, kLoong64Float32ToFloat64, node);
928void InstructionSelectorT::VisitRoundInt32ToFloat32(
OpIndex node) {
929 VisitRR(
this, kLoong64Int32ToFloat32, node);
932void InstructionSelectorT::VisitRoundUint32ToFloat32(
OpIndex node) {
933 VisitRR(
this, kLoong64Uint32ToFloat32, node);
936void InstructionSelectorT::VisitChangeInt32ToFloat64(
OpIndex node) {
937 VisitRR(
this, kLoong64Int32ToFloat64, node);
940void InstructionSelectorT::VisitChangeInt64ToFloat64(
OpIndex node) {
941 VisitRR(
this, kLoong64Int64ToFloat64, node);
944void InstructionSelectorT::VisitChangeUint32ToFloat64(
OpIndex node) {
945 VisitRR(
this, kLoong64Uint32ToFloat64, node);
948void InstructionSelectorT::VisitTruncateFloat32ToInt32(
OpIndex node) {
949 Loong64OperandGeneratorT g(
this);
956 g.UseRegister(this->input_at(node, 0)));
959void InstructionSelectorT::VisitTruncateFloat32ToUint32(
OpIndex node) {
960 Loong64OperandGeneratorT g(
this);
969 g.UseRegister(this->input_at(node, 0)));
972void InstructionSelectorT::VisitChangeFloat64ToInt32(
OpIndex node) {
973 VisitRR(
this, kLoong64Float64ToInt32, node);
976void InstructionSelectorT::VisitChangeFloat64ToInt64(
OpIndex node) {
977 VisitRR(
this, kLoong64Float64ToInt64, node);
980void InstructionSelectorT::VisitChangeFloat64ToUint32(
OpIndex node) {
981 VisitRR(
this, kLoong64Float64ToUint32, node);
984void InstructionSelectorT::VisitChangeFloat64ToUint64(
OpIndex node) {
985 VisitRR(
this, kLoong64Float64ToUint64, node);
988void InstructionSelectorT::VisitTruncateFloat64ToUint32(
OpIndex node) {
989 VisitRR(
this, kLoong64Float64ToUint32, node);
992void InstructionSelectorT::VisitTruncateFloat64ToInt64(
OpIndex node) {
993 Loong64OperandGeneratorT g(
this);
1000 Emit(
opcode, g.DefineAsRegister(node), g.UseRegister(op.input(0)));
1003void InstructionSelectorT::VisitTruncateFloat64ToFloat16RawBits(
OpIndex node) {
1007void InstructionSelectorT::VisitChangeFloat16RawBitsToFloat64(
OpIndex node) {
1011void InstructionSelectorT::VisitTryTruncateFloat32ToInt64(
OpIndex node) {
1012 Loong64OperandGeneratorT g(
this);
1014 InstructionOperand
inputs[] = {g.UseRegister(this->
input_at(node, 0))};
1015 InstructionOperand outputs[2];
1016 size_t output_count = 0;
1017 outputs[output_count++] = g.DefineAsRegister(node);
1020 if (success_output.valid()) {
1021 outputs[output_count++] = g.DefineAsRegister(success_output.value());
1024 Emit(kLoong64Float32ToInt64, output_count, outputs, 1,
inputs);
1027void InstructionSelectorT::VisitTryTruncateFloat64ToInt64(
OpIndex node) {
1028 Loong64OperandGeneratorT g(
this);
1030 InstructionOperand
inputs[] = {g.UseRegister(this->
input_at(node, 0))};
1031 InstructionOperand outputs[2];
1032 size_t output_count = 0;
1033 outputs[output_count++] = g.DefineAsRegister(node);
1036 if (success_output.valid()) {
1037 outputs[output_count++] = g.DefineAsRegister(success_output.value());
1040 Emit(kLoong64Float64ToInt64, output_count, outputs, 1,
inputs);
1043void InstructionSelectorT::VisitTryTruncateFloat32ToUint64(
OpIndex node) {
1044 Loong64OperandGeneratorT g(
this);
1046 InstructionOperand
inputs[] = {g.UseRegister(this->
input_at(node, 0))};
1047 InstructionOperand outputs[2];
1048 size_t output_count = 0;
1049 outputs[output_count++] = g.DefineAsRegister(node);
1052 if (success_output.valid()) {
1053 outputs[output_count++] = g.DefineAsRegister(success_output.value());
1056 Emit(kLoong64Float32ToUint64, output_count, outputs, 1,
inputs);
1059void InstructionSelectorT::VisitTryTruncateFloat64ToUint64(
OpIndex node) {
1060 Loong64OperandGeneratorT g(
this);
1062 InstructionOperand
inputs[] = {g.UseRegister(this->
input_at(node, 0))};
1063 InstructionOperand outputs[2];
1064 size_t output_count = 0;
1065 outputs[output_count++] = g.DefineAsRegister(node);
1068 if (success_output.valid()) {
1069 outputs[output_count++] = g.DefineAsRegister(success_output.value());
1072 Emit(kLoong64Float64ToUint64, output_count, outputs, 1,
inputs);
1075void InstructionSelectorT::VisitTryTruncateFloat64ToInt32(
OpIndex node) {
1076 Loong64OperandGeneratorT g(
this);
1078 InstructionOperand
inputs[] = {g.UseRegister(this->
input_at(node, 0))};
1079 InstructionOperand outputs[2];
1080 size_t output_count = 0;
1081 outputs[output_count++] = g.DefineAsRegister(node);
1084 if (success_output.valid()) {
1085 outputs[output_count++] = g.DefineAsRegister(success_output.value());
1088 Emit(kLoong64Float64ToInt32, output_count, outputs, 1,
inputs);
1091void InstructionSelectorT::VisitTryTruncateFloat64ToUint32(
OpIndex node) {
1092 Loong64OperandGeneratorT g(
this);
1094 InstructionOperand
inputs[] = {g.UseRegister(this->
input_at(node, 0))};
1095 InstructionOperand outputs[2];
1096 size_t output_count = 0;
1097 outputs[output_count++] = g.DefineAsRegister(node);
1100 if (success_output.valid()) {
1101 outputs[output_count++] = g.DefineAsRegister(success_output.value());
1104 Emit(kLoong64Float64ToUint32, output_count, outputs, 1,
inputs);
1107void InstructionSelectorT::VisitBitcastWord32ToWord64(
OpIndex node) {
1113void InstructionSelectorT::VisitChangeInt32ToInt64(
OpIndex node) {
1114 Loong64OperandGeneratorT g(
this);
1116 const Operation& input_op = this->
Get(change_op.input());
1117 if (input_op.Is<LoadOp>() &&
CanCover(node, change_op.input())) {
1126 opcode = load_rep.IsUnsigned() ? kLoong64Ld_bu : kLoong64Ld_b;
1129 opcode = load_rep.IsUnsigned() ? kLoong64Ld_hu : kLoong64Ld_h;
1143 CanCover(node, change_op.input())) {
1147 Emit(kLoong64Sll_w, g.DefineAsRegister(node),
1148 g.UseRegister(change_op.input()), g.TempImmediate(0));
1151bool InstructionSelectorT::ZeroExtendsWord32ToWord64NoPhis(
OpIndex node) {
1154 switch (op.opcode) {
1156 case Opcode::kComparison:
1158 case Opcode::kOverflowCheckedBinop:
1159 return op.Cast<OverflowCheckedBinopOp>().rep ==
1161 case Opcode::kLoad: {
1164 if (load_rep.IsUnsigned()) {
1165 switch (load_rep.representation()) {
1181void InstructionSelectorT::VisitChangeUint32ToUint64(
OpIndex node) {
1182 Loong64OperandGeneratorT g(
this);
1184 OpIndex input = change_op.input();
1187 if (input_op.Is<LoadOp>() &&
CanCover(node, input)) {
1190 if (load_rep.IsUnsigned() &&
1192 EmitLoad(
this, input, kLoong64Ld_wu, node);
1196 if (ZeroExtendsWord32ToWord64(input)) {
1200 Emit(kLoong64Bstrpick_d, g.DefineAsRegister(node), g.UseRegister(input),
1201 g.TempImmediate(0), g.TempImmediate(32));
1204void InstructionSelectorT::VisitTruncateInt64ToInt32(
OpIndex node) {
1205 Loong64OperandGeneratorT g(
this);
1209 auto shift_value =
input_at(value, 1);
1213 }
else if (int64_t constant;
1215 if (constant >= 32 && constant <= 63) {
1217 Emit(kLoong64Sra_d, g.DefineAsRegister(node),
1218 g.UseRegister(
input_at(value, 0)), g.UseImmediate(constant));
1224 Emit(kLoong64Sll_w, g.DefineAsRegister(node), g.UseRegister(value),
1225 g.TempImmediate(0));
1228void InstructionSelectorT::VisitTruncateFloat64ToFloat32(
OpIndex node) {
1229 VisitRR(
this, kLoong64Float64ToFloat32, node);
1232void InstructionSelectorT::VisitTruncateFloat64ToWord32(
OpIndex node) {
1233 VisitRR(
this, kArchTruncateDoubleToI, node);
1236void InstructionSelectorT::VisitRoundFloat64ToInt32(
OpIndex node) {
1237 VisitRR(
this, kLoong64Float64ToInt32, node);
1240void InstructionSelectorT::VisitRoundInt64ToFloat32(
OpIndex node) {
1241 VisitRR(
this, kLoong64Int64ToFloat32, node);
1244void InstructionSelectorT::VisitRoundInt64ToFloat64(
OpIndex node) {
1245 VisitRR(
this, kLoong64Int64ToFloat64, node);
1248void InstructionSelectorT::VisitRoundUint64ToFloat32(
OpIndex node) {
1249 VisitRR(
this, kLoong64Uint64ToFloat32, node);
1252void InstructionSelectorT::VisitRoundUint64ToFloat64(
OpIndex node) {
1253 VisitRR(
this, kLoong64Uint64ToFloat64, node);
1256void InstructionSelectorT::VisitBitcastFloat32ToInt32(
OpIndex node) {
1257 VisitRR(
this, kLoong64Float64ExtractLowWord32, node);
1260void InstructionSelectorT::VisitBitcastFloat64ToInt64(
OpIndex node) {
1261 VisitRR(
this, kLoong64BitcastDL, node);
1264void InstructionSelectorT::VisitBitcastInt32ToFloat32(
OpIndex node) {
1268 VisitRR(
this, kLoong64BitcastLD, node);
1271void InstructionSelectorT::VisitBitcastInt64ToFloat64(
OpIndex node) {
1272 VisitRR(
this, kLoong64BitcastLD, node);
1275void InstructionSelectorT::VisitFloat32Add(
OpIndex node) {
1276 VisitRRR(
this, kLoong64Float32Add, node);
1279void InstructionSelectorT::VisitFloat64Add(
OpIndex node) {
1280 VisitRRR(
this, kLoong64Float64Add, node);
1283void InstructionSelectorT::VisitFloat32Sub(
OpIndex node) {
1284 VisitRRR(
this, kLoong64Float32Sub, node);
1287void InstructionSelectorT::VisitFloat64Sub(
OpIndex node) {
1288 VisitRRR(
this, kLoong64Float64Sub, node);
1291void InstructionSelectorT::VisitFloat32Mul(
OpIndex node) {
1292 VisitRRR(
this, kLoong64Float32Mul, node);
1295void InstructionSelectorT::VisitFloat64Mul(
OpIndex node) {
1296 VisitRRR(
this, kLoong64Float64Mul, node);
1299void InstructionSelectorT::VisitFloat32Div(
OpIndex node) {
1300 VisitRRR(
this, kLoong64Float32Div, node);
1303void InstructionSelectorT::VisitFloat64Div(
OpIndex node) {
1304 VisitRRR(
this, kLoong64Float64Div, node);
1307void InstructionSelectorT::VisitFloat64Mod(
OpIndex node) {
1308 Loong64OperandGeneratorT g(
this);
1309 Emit(kLoong64Float64Mod, g.DefineAsFixed(node, f0),
1310 g.UseFixed(this->input_at(node, 0), f0),
1311 g.UseFixed(this->input_at(node, 1), f1))
1315void InstructionSelectorT::VisitFloat32Max(
OpIndex node) {
1316 VisitRRR(
this, kLoong64Float32Max, node);
1319void InstructionSelectorT::VisitFloat64Max(
OpIndex node) {
1320 VisitRRR(
this, kLoong64Float64Max, node);
1323void InstructionSelectorT::VisitFloat32Min(
OpIndex node) {
1324 VisitRRR(
this, kLoong64Float32Min, node);
1327void InstructionSelectorT::VisitFloat64Min(
OpIndex node) {
1328 VisitRRR(
this, kLoong64Float64Min, node);
1331void InstructionSelectorT::VisitFloat32Abs(
OpIndex node) {
1332 VisitRR(
this, kLoong64Float32Abs, node);
1335void InstructionSelectorT::VisitFloat64Abs(
OpIndex node) {
1336 VisitRR(
this, kLoong64Float64Abs, node);
1339void InstructionSelectorT::VisitFloat32Sqrt(
OpIndex node) {
1340 VisitRR(
this, kLoong64Float32Sqrt, node);
1343void InstructionSelectorT::VisitFloat64Sqrt(
OpIndex node) {
1344 VisitRR(
this, kLoong64Float64Sqrt, node);
1347void InstructionSelectorT::VisitFloat32RoundDown(
OpIndex node) {
1348 VisitRR(
this, kLoong64Float32RoundDown, node);
1351void InstructionSelectorT::VisitFloat64RoundDown(
OpIndex node) {
1352 VisitRR(
this, kLoong64Float64RoundDown, node);
1355void InstructionSelectorT::VisitFloat32RoundUp(
OpIndex node) {
1356 VisitRR(
this, kLoong64Float32RoundUp, node);
1359void InstructionSelectorT::VisitFloat64RoundUp(
OpIndex node) {
1360 VisitRR(
this, kLoong64Float64RoundUp, node);
1363void InstructionSelectorT::VisitFloat32RoundTruncate(
OpIndex node) {
1364 VisitRR(
this, kLoong64Float32RoundTruncate, node);
1367void InstructionSelectorT::VisitFloat64RoundTruncate(
OpIndex node) {
1368 VisitRR(
this, kLoong64Float64RoundTruncate, node);
1371void InstructionSelectorT::VisitFloat64RoundTiesAway(
OpIndex node) {
1375void InstructionSelectorT::VisitFloat32RoundTiesEven(
OpIndex node) {
1376 VisitRR(
this, kLoong64Float32RoundTiesEven, node);
1379void InstructionSelectorT::VisitFloat64RoundTiesEven(
OpIndex node) {
1380 VisitRR(
this, kLoong64Float64RoundTiesEven, node);
1383void InstructionSelectorT::VisitFloat32Neg(
OpIndex node) {
1384 VisitRR(
this, kLoong64Float32Neg, node);
1387void InstructionSelectorT::VisitFloat64Neg(
OpIndex node) {
1388 VisitRR(
this, kLoong64Float64Neg, node);
1393 Loong64OperandGeneratorT g(
this);
1395 g.UseFixed(this->input_at(node, 0), f0),
1396 g.UseFixed(this->input_at(node, 1), f1))
1402 Loong64OperandGeneratorT g(
this);
1404 g.UseFixed(this->input_at(node, 0), f0))
1411 InstructionOperand out_op = g.TempRegister(-count);
1412 Emit(kArchNop, out_op);
1413 Emit(kLoong64BitcastLD, g.DefineAsRegister(node), out_op);
1417 LinkageLocation location) {
1419 int count = location.GetLocation();
1420 InstructionOperand new_op = g.TempRegister(-count);
1421 Emit(kLoong64BitcastDL, new_op, *op);
1426 ZoneVector<PushParameter>* arguments,
const CallDescriptor* call_descriptor,
1428 Loong64OperandGeneratorT g(
this);
1431 if (call_descriptor->IsCFunctionCall()) {
1432 int gp_param_count =
static_cast<int>(call_descriptor->GPParameterCount());
1433 int fp_param_count =
static_cast<int>(call_descriptor->FPParameterCount());
1436 0,
nullptr, 0,
nullptr);
1441 Emit(kLoong64Poke, g.NoOutput(), g.UseRegister(input.node),
1446 int push_count =
static_cast<int>(call_descriptor->ParameterSlotCount());
1447 if (push_count > 0) {
1451 if (input.node.valid()) {
1452 stack_size += input.location.GetSizeInPointers();
1455 Emit(kLoong64StackClaim, g.NoOutput(),
1458 for (
size_t n = 0; n < arguments->size(); ++
n) {
1460 if (input.node.valid()) {
1461 Emit(kLoong64Poke, g.NoOutput(), g.UseRegister(input.node),
1469 ZoneVector<PushParameter>* results,
const CallDescriptor* call_descriptor,
1471 Loong64OperandGeneratorT g(
this);
1474 if (!output.location.IsCallerFrameSlot())
continue;
1476 if (output.node.valid()) {
1477 DCHECK(!call_descriptor->IsCFunctionCall());
1485 int offset = call_descriptor->GetOffsetToReturns();
1486 int reverse_slot = -output.location.GetLocation() -
offset;
1487 Emit(kLoong64Peek, g.DefineAsRegister(output.node),
1488 g.UseImmediate(reverse_slot));
1502static Instruction*
VisitCompare(InstructionSelectorT* selector,
1504 InstructionOperand left,
1505 InstructionOperand right,
1506 FlagsContinuationT* cont) {
1507#ifdef V8_COMPRESS_POINTERS
1508 if (opcode == kLoong64Cmp32) {
1509 Loong64OperandGeneratorT g(selector);
1510 InstructionOperand inputs[] = {left, right};
1511 if (right.IsImmediate()) {
1512 InstructionOperand temps[1] = {g.TempRegister()};
1513 return selector->EmitWithContinuation(opcode, 0,
nullptr,
1517 InstructionOperand temps[2] = {g.TempRegister(), g.TempRegister()};
1518 return selector->EmitWithContinuation(opcode, 0,
nullptr,
1524 return selector->EmitWithContinuation(opcode, left, right, cont);
1529 FlagsContinuationT* cont) {
1530 Loong64OperandGeneratorT g(selector);
1534 InstructionOperand lhs, rhs;
1536 lhs = selector->MatchZero(left) ? g.UseImmediate(left) : g.UseRegister(left);
1538 selector->MatchZero(right) ? g.UseImmediate(right) : g.UseRegister(right);
1539 VisitCompare(selector, kLoong64Float32Cmp, lhs, rhs, cont);
1544 FlagsContinuationT* cont) {
1545 Loong64OperandGeneratorT g(selector);
1550 if (selector->MatchZero(rhs)) {
1551 VisitCompare(selector, kLoong64Float64Cmp, g.UseRegister(lhs),
1552 g.UseImmediate(rhs), cont);
1553 }
else if (selector->MatchZero(lhs)) {
1554 VisitCompare(selector, kLoong64Float64Cmp, g.UseImmediate(lhs),
1555 g.UseRegister(rhs), cont);
1557 VisitCompare(selector, kLoong64Float64Cmp, g.UseRegister(lhs),
1558 g.UseRegister(rhs), cont);
1566 Loong64OperandGeneratorT g(selector);
1567 DCHECK_EQ(selector->value_input_count(node), 2);
1568 auto left = selector->input_at(node, 0);
1569 auto right = selector->input_at(node, 1);
1572 if (g.CanBeImmediate(right, opcode)) {
1573 if (opcode == kLoong64Tst) {
1574 VisitCompare(selector, opcode, g.UseRegister(left), g.UseImmediate(right),
1577 switch (cont->condition()) {
1580 if (cont->IsSet()) {
1581 VisitCompare(selector, opcode, g.UseUniqueRegister(left),
1582 g.UseImmediate(right), cont);
1584 VisitCompare(selector, opcode, g.UseUniqueRegister(left),
1585 g.UseImmediate(right), cont);
1596 VisitCompare(selector, opcode, g.UseUniqueRegister(left),
1597 g.UseImmediate(right), cont);
1603 }
else if (g.CanBeImmediate(left, opcode)) {
1604 if (!commutative) cont->Commute();
1605 if (opcode == kLoong64Tst) {
1606 VisitCompare(selector, opcode, g.UseRegister(right), g.UseImmediate(left),
1609 switch (cont->condition()) {
1612 if (cont->IsSet()) {
1613 VisitCompare(selector, opcode, g.UseUniqueRegister(right),
1614 g.UseImmediate(left), cont);
1616 VisitCompare(selector, opcode, g.UseUniqueRegister(right),
1617 g.UseImmediate(left), cont);
1628 VisitCompare(selector, opcode, g.UseUniqueRegister(right),
1629 g.UseImmediate(left), cont);
1636 VisitCompare(selector, opcode, g.UseUniqueRegister(left),
1637 g.UseUniqueRegister(right), cont);
1642void VisitFullWord32Compare(InstructionSelectorT* selector,
OpIndex node,
1644 Loong64OperandGeneratorT g(selector);
1645 InstructionOperand leftOp = g.TempRegister();
1646 InstructionOperand rightOp = g.TempRegister();
1648 selector->Emit(kLoong64Sll_d, leftOp,
1649 g.UseRegister(selector->input_at(node, 0)),
1650 g.TempImmediate(32));
1651 selector->Emit(kLoong64Sll_d, rightOp,
1652 g.UseRegister(selector->input_at(node, 1)),
1653 g.TempImmediate(32));
1656 selector->UpdateSourcePosition(
instr, node);
1659void VisitWord32Compare(InstructionSelectorT* selector,
OpIndex node,
1660 FlagsContinuationT* cont) {
1661 VisitFullWord32Compare(selector, node, kLoong64Cmp64, cont);
1664void VisitWord64Compare(InstructionSelectorT* selector,
OpIndex node,
1665 FlagsContinuationT* cont) {
1669void VisitAtomicLoad(InstructionSelectorT* selector,
OpIndex node,
1672 Loong64OperandGeneratorT g(selector);
1673 auto load = selector->load_view(node);
1680 switch (load_rep.representation()) {
1683 code = load_rep.IsSigned() ? kAtomicLoadInt8 : kAtomicLoadUint8;
1687 code = load_rep.IsSigned() ? kAtomicLoadInt16 : kAtomicLoadUint16;
1691 : kLoong64Word64AtomicLoadUint32;
1694 code = kLoong64Word64AtomicLoadUint64;
1696#ifdef V8_COMPRESS_POINTERS
1698 code = kLoong64AtomicLoadDecompressTaggedSigned;
1702 code = kLoong64AtomicLoadDecompressTagged;
1708 code = kLoong64Word64AtomicLoadUint64;
1714 code = kLoong64Word64AtomicLoadUint32;
1721 if (load.is_protected(&traps_on_null)) {
1729 if (g.CanBeImmediate(index, code)) {
1732 g.DefineAsRegister(node), g.UseRegister(base),
1733 g.UseImmediate(index));
1737 g.DefineAsRegister(node), g.UseRegister(base),
1738 g.UseRegister(index));
1744 auto store = selector->store_view(node);
1745 return AtomicStoreParameters(store.stored_rep().representation(),
1746 store.stored_rep().write_barrier_kind(),
1747 store.memory_order().value(),
1748 store.access_kind());
1751void VisitAtomicStore(InstructionSelectorT* selector,
OpIndex node,
1754 Loong64OperandGeneratorT g(selector);
1755 auto store = selector->store_view(node);
1757 OpIndex index = selector->value(store.index());
1758 OpIndex value = store.value();
1766 if (
v8_flags.enable_unconditional_write_barriers &&
1774 !
v8_flags.disable_write_barriers) {
1780 code = kArchAtomicStoreWithWriteBarrier;
1785 code = kAtomicStoreWord8;
1788 code = kAtomicStoreWord16;
1791 code = kAtomicStoreWord32;
1795 code = kLoong64Word64AtomicStoreWord64;
1801 code = kLoong64AtomicStoreCompressTagged;
1807 code = kLoong64AtomicStoreCompressTagged;
1818 if (g.CanBeImmediate(index, code)) {
1821 g.NoOutput(), g.UseRegister(base), g.UseImmediate(index),
1822 g.UseRegisterOrImmediateZero(value));
1826 g.NoOutput(), g.UseRegister(base), g.UseRegister(index),
1827 g.UseRegisterOrImmediateZero(value));
1835 Loong64OperandGeneratorT g(selector);
1836 const AtomicRMWOp& atomic_op = selector->Cast<AtomicRMWOp>(
node);
1838 OpIndex index = atomic_op.index();
1839 OpIndex value = atomic_op.value();
1842 InstructionOperand inputs[3];
1844 inputs[
input_count++] = g.UseUniqueRegister(base);
1845 inputs[
input_count++] = g.UseUniqueRegister(index);
1846 inputs[
input_count++] = g.UseUniqueRegister(value);
1847 InstructionOperand outputs[1];
1848 outputs[0] = g.UseUniqueRegister(node);
1849 InstructionOperand temp[3];
1850 temp[0] = g.TempRegister();
1851 temp[1] = g.TempRegister();
1852 temp[2] = g.TempRegister();
1858 selector->Emit(code, 1, outputs, input_count, inputs, 3, temp);
1865 Loong64OperandGeneratorT g(selector);
1866 const AtomicRMWOp& atomic_op = selector->Cast<AtomicRMWOp>(
node);
1868 OpIndex index = atomic_op.index();
1869 OpIndex old_value = atomic_op.expected().value();
1870 OpIndex new_value = atomic_op.value();
1873 InstructionOperand inputs[4];
1875 inputs[
input_count++] = g.UseUniqueRegister(base);
1876 inputs[
input_count++] = g.UseUniqueRegister(index);
1877 inputs[
input_count++] = g.UseUniqueRegister(old_value);
1878 inputs[
input_count++] = g.UseUniqueRegister(new_value);
1879 InstructionOperand outputs[1];
1880 outputs[0] = g.UseUniqueRegister(node);
1881 InstructionOperand temp[3];
1882 temp[0] = g.TempRegister();
1883 temp[1] = g.TempRegister();
1884 temp[2] = g.TempRegister();
1890 selector->Emit(code, 1, outputs, input_count, inputs, 3, temp);
1897 Loong64OperandGeneratorT g(selector);
1898 const AtomicRMWOp& atomic_op = selector->Cast<AtomicRMWOp>(
node);
1900 OpIndex index = atomic_op.index();
1901 OpIndex value = atomic_op.value();
1904 InstructionOperand inputs[3];
1906 inputs[
input_count++] = g.UseUniqueRegister(base);
1907 inputs[
input_count++] = g.UseUniqueRegister(index);
1908 inputs[
input_count++] = g.UseUniqueRegister(value);
1909 InstructionOperand outputs[1];
1910 outputs[0] = g.UseUniqueRegister(node);
1911 InstructionOperand temps[4];
1912 temps[0] = g.TempRegister();
1913 temps[1] = g.TempRegister();
1914 temps[2] = g.TempRegister();
1915 temps[3] = g.TempRegister();
1921 selector->Emit(code, 1, outputs, input_count, inputs, 4, temps);
1927 OpIndex node, FlagsContinuationT* cont) {
1934 value = op.stack_limit();
1938 Loong64OperandGeneratorT g(
this);
1941 InstructionOperand*
const outputs =
nullptr;
1942 const int output_count = 0;
1948 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()};
1954 InstructionOperand
inputs[] = {g.UseRegisterWithMode(value, register_mode)};
1958 temp_count, temps, cont);
1963 FlagsContinuation* cont) {
1965 Loong64OperandGeneratorT g(
this);
1967 while (
const ComparisonOp*
equal =
1972 value =
equal->left();
1978 if (
const ComparisonOp* comparison = value_op.TryCast<ComparisonOp>()) {
1979 switch (comparison->rep.value()) {
1981 cont->OverwriteAndNegateIfEqual(
1983 return VisitWord32Compare(
this, value, cont);
1986 cont->OverwriteAndNegateIfEqual(
1988 return VisitWord64Compare(
this, value, cont);
1992 case ComparisonOp::Kind::kEqual:
1993 cont->OverwriteAndNegateIfEqual(
kEqual);
1995 case ComparisonOp::Kind::kSignedLessThan:
1998 case ComparisonOp::Kind::kSignedLessThanOrEqual:
2007 case ComparisonOp::Kind::kEqual:
2008 cont->OverwriteAndNegateIfEqual(
kEqual);
2010 case ComparisonOp::Kind::kSignedLessThan:
2013 case ComparisonOp::Kind::kSignedLessThanOrEqual:
2023 }
else if (
const ProjectionOp* projection =
2024 value_op.TryCast<ProjectionOp>()) {
2027 if (projection->index == 1u) {
2033 OpIndex node = projection->input();
2036 if (
const OverflowCheckedBinopOp* binop =
2039 switch (binop->kind) {
2040 case OverflowCheckedBinopOp::Kind::kSignedAdd:
2041 cont->OverwriteAndNegateIfEqual(
kOverflow);
2043 is64 ? kLoong64AddOvf_d : kLoong64Add_d,
2045 case OverflowCheckedBinopOp::Kind::kSignedSub:
2046 cont->OverwriteAndNegateIfEqual(
kOverflow);
2048 is64 ? kLoong64SubOvf_d : kLoong64Sub_d,
2050 case OverflowCheckedBinopOp::Kind::kSignedMul:
2051 cont->OverwriteAndNegateIfEqual(
kOverflow);
2053 is64 ? kLoong64MulOvf_d : kLoong64MulOvf_w,
2062 }
else if (value_op.Is<StackPointerGreaterThanOp>()) {
2064 return VisitStackPointerGreaterThan(value, cont);
2070 VisitCompare(
this, kLoong64Cmp32, g.UseRegister(value), g.TempImmediate(0),
2075void InstructionSelectorT::VisitSwitch(
OpIndex node,
const SwitchInfo& sw) {
2076 Loong64OperandGeneratorT g(
this);
2077 InstructionOperand value_operand = g.UseRegister(this->input_at(node, 0));
2080 if (enable_switch_jump_table_ ==
2081 InstructionSelector::kEnableSwitchJumpTable) {
2082 static const size_t kMaxTableSwitchValueRange = 2 << 16;
2083 size_t table_space_cost = 10 + 2 * sw.value_range();
2084 size_t table_time_cost = 3;
2085 size_t lookup_space_cost = 2 + 2 * sw.case_count();
2086 size_t lookup_time_cost = sw.case_count();
2087 if (sw.case_count() > 0 &&
2088 table_space_cost + 3 * table_time_cost <=
2089 lookup_space_cost + 3 * lookup_time_cost &&
2090 sw.min_value() > std::numeric_limits<int32_t>::min() &&
2091 sw.value_range() <= kMaxTableSwitchValueRange) {
2092 InstructionOperand index_operand = value_operand;
2093 if (sw.min_value()) {
2094 index_operand = g.TempRegister();
2095 Emit(kLoong64Sub_w, index_operand, value_operand,
2096 g.TempImmediate(sw.min_value()));
2099 return EmitTableSwitch(sw, index_operand);
2104 return EmitBinarySearchSwitch(sw, value_operand);
2107void InstructionSelectorT::VisitWord32Equal(
OpIndex node) {
2113 FlagsContinuation cont = FlagsContinuation::ForSet(
kEqual, node);
2115 if (MatchZero(right)) {
2116 return VisitWordCompareZero(user, left, &cont);
2121 Loong64OperandGeneratorT g(
this);
2124 Handle<HeapObject> right;
2128 if (MatchHeapConstant(node, &right) && !right.is_null() &&
2129 roots_table.IsRootHandle(right, &root_index)) {
2133 if (g.CanBeImmediate(ptr, kLoong64Cmp32)) {
2134 VisitCompare(
this, kLoong64Cmp32, g.UseRegister(left),
2135 g.TempImmediate(
int32_t(ptr)), &cont);
2141 VisitWord32Compare(
this, node, &cont);
2144void InstructionSelectorT::VisitInt32LessThan(
OpIndex node) {
2145 FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThan, node);
2146 VisitWord32Compare(
this, node, &cont);
2149void InstructionSelectorT::VisitInt32LessThanOrEqual(
OpIndex node) {
2150 FlagsContinuation cont =
2151 FlagsContinuation::ForSet(kSignedLessThanOrEqual, node);
2152 VisitWord32Compare(
this, node, &cont);
2155void InstructionSelectorT::VisitUint32LessThan(
OpIndex node) {
2157 VisitWord32Compare(
this, node, &cont);
2160void InstructionSelectorT::VisitUint32LessThanOrEqual(
OpIndex node) {
2161 FlagsContinuation cont =
2162 FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
2163 VisitWord32Compare(
this, node, &cont);
2166void InstructionSelectorT::VisitInt32AddWithOverflow(
OpIndex node) {
2168 if (ovf.valid() && IsUsed(ovf.value())) {
2169 FlagsContinuation cont = FlagsContinuation::ForSet(
kOverflow, ovf.value());
2170 return VisitBinop(
this, node, kLoong64Add_d, &cont);
2173 FlagsContinuation cont;
2174 VisitBinop(
this, node, kLoong64Add_d, &cont);
2177void InstructionSelectorT::VisitInt32SubWithOverflow(
OpIndex node) {
2180 FlagsContinuation cont = FlagsContinuation::ForSet(
kOverflow, ovf.value());
2181 return VisitBinop(
this, node, kLoong64Sub_d, &cont);
2184 FlagsContinuation cont;
2185 VisitBinop(
this, node, kLoong64Sub_d, &cont);
2188void InstructionSelectorT::VisitInt32MulWithOverflow(
OpIndex node) {
2191 FlagsContinuation cont = FlagsContinuation::ForSet(
kOverflow, ovf.value());
2192 return VisitBinop(
this, node, kLoong64MulOvf_w, &cont);
2195 FlagsContinuation cont;
2196 VisitBinop(
this, node, kLoong64MulOvf_w, &cont);
2199void InstructionSelectorT::VisitInt64MulWithOverflow(
OpIndex node) {
2202 FlagsContinuation cont = FlagsContinuation::ForSet(
kOverflow, ovf.value());
2203 return VisitBinop(
this, node, kLoong64MulOvf_d, &cont);
2206 FlagsContinuation cont;
2207 VisitBinop(
this, node, kLoong64MulOvf_d, &cont);
2210void InstructionSelectorT::VisitInt64AddWithOverflow(
OpIndex node) {
2213 FlagsContinuation cont = FlagsContinuation::ForSet(
kOverflow, ovf.value());
2214 return VisitBinop(
this, node, kLoong64AddOvf_d, &cont);
2217 FlagsContinuation cont;
2218 VisitBinop(
this, node, kLoong64AddOvf_d, &cont);
2221void InstructionSelectorT::VisitInt64SubWithOverflow(
OpIndex node) {
2224 FlagsContinuation cont = FlagsContinuation::ForSet(
kOverflow, ovf.value());
2225 return VisitBinop(
this, node, kLoong64SubOvf_d, &cont);
2228 FlagsContinuation cont;
2229 VisitBinop(
this, node, kLoong64SubOvf_d, &cont);
2232void InstructionSelectorT::VisitWord64Equal(
OpIndex node) {
2233 FlagsContinuation cont = FlagsContinuation::ForSet(
kEqual, node);
2234 VisitWord64Compare(
this, node, &cont);
2237void InstructionSelectorT::VisitInt64LessThan(
OpIndex node) {
2238 FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThan, node);
2239 VisitWord64Compare(
this, node, &cont);
2242void InstructionSelectorT::VisitInt64LessThanOrEqual(
OpIndex node) {
2243 FlagsContinuation cont =
2244 FlagsContinuation::ForSet(kSignedLessThanOrEqual, node);
2245 VisitWord64Compare(
this, node, &cont);
2248void InstructionSelectorT::VisitUint64LessThan(
OpIndex node) {
2250 VisitWord64Compare(
this, node, &cont);
2253void InstructionSelectorT::VisitUint64LessThanOrEqual(
OpIndex node) {
2254 FlagsContinuation cont =
2255 FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
2256 VisitWord64Compare(
this, node, &cont);
2259void InstructionSelectorT::VisitFloat32Equal(
OpIndex node) {
2260 FlagsContinuation cont = FlagsContinuation::ForSet(
kEqual, node);
2264void InstructionSelectorT::VisitFloat32LessThan(
OpIndex node) {
2269void InstructionSelectorT::VisitFloat32LessThanOrEqual(
OpIndex node) {
2270 FlagsContinuation cont =
2271 FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
2275void InstructionSelectorT::VisitFloat64Equal(
OpIndex node) {
2276 FlagsContinuation cont = FlagsContinuation::ForSet(
kEqual, node);
2280void InstructionSelectorT::VisitFloat64LessThan(
OpIndex node) {
2285void InstructionSelectorT::VisitFloat64LessThanOrEqual(
OpIndex node) {
2286 FlagsContinuation cont =
2287 FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
2291void InstructionSelectorT::VisitFloat64ExtractLowWord32(
OpIndex node) {
2292 VisitRR(
this, kLoong64Float64ExtractLowWord32, node);
2295void InstructionSelectorT::VisitFloat64ExtractHighWord32(
OpIndex node) {
2296 VisitRR(
this, kLoong64Float64ExtractHighWord32, node);
2299void InstructionSelectorT::VisitBitcastWord32PairToFloat64(
OpIndex node) {
2300 Loong64OperandGeneratorT g(
this);
2305 InstructionOperand temps[] = {g.TempRegister()};
2306 Emit(kLoong64Float64FromWord32Pair, g.DefineAsRegister(node), g.Use(
hi),
2310void InstructionSelectorT::VisitFloat64SilenceNaN(
OpIndex node) {
2311 VisitRR(
this, kLoong64Float64SilenceNaN, node);
2314void InstructionSelectorT::VisitFloat64InsertLowWord32(
OpIndex node) {
2318void InstructionSelectorT::VisitFloat64InsertHighWord32(
OpIndex node) {
2322void InstructionSelectorT::VisitMemoryBarrier(
OpIndex node) {
2323 Loong64OperandGeneratorT g(
this);
2324 Emit(kLoong64Dbar, g.NoOutput());
2327void InstructionSelectorT::VisitWord32AtomicLoad(
OpIndex node) {
2328 VisitAtomicLoad(
this, node, AtomicWidth::kWord32);
2331void InstructionSelectorT::VisitWord32AtomicStore(
OpIndex node) {
2332 VisitAtomicStore(
this, node, AtomicWidth::kWord32);
2335void InstructionSelectorT::VisitWord64AtomicLoad(
OpIndex node) {
2336 VisitAtomicLoad(
this, node, AtomicWidth::kWord64);
2339void InstructionSelectorT::VisitWord64AtomicStore(
OpIndex node) {
2340 VisitAtomicStore(
this, node, AtomicWidth::kWord64);
2343void InstructionSelectorT::VisitWord32AtomicExchange(
OpIndex node) {
2347 opcode = kAtomicExchangeInt8;
2349 opcode = kAtomicExchangeUint8;
2351 opcode = kAtomicExchangeInt16;
2353 opcode = kAtomicExchangeUint16;
2356 opcode = kAtomicExchangeWord32;
2361 atomic_op.memory_access_kind);
2364void InstructionSelectorT::VisitWord64AtomicExchange(
OpIndex node) {
2368 opcode = kAtomicExchangeUint8;
2370 opcode = kAtomicExchangeUint16;
2372 opcode = kAtomicExchangeWord32;
2374 opcode = kLoong64Word64AtomicExchangeUint64;
2379 atomic_op.memory_access_kind);
2382void InstructionSelectorT::VisitWord32AtomicCompareExchange(
OpIndex node) {
2386 opcode = kAtomicCompareExchangeInt8;
2388 opcode = kAtomicCompareExchangeUint8;
2390 opcode = kAtomicCompareExchangeInt16;
2392 opcode = kAtomicCompareExchangeUint16;
2395 opcode = kAtomicCompareExchangeWord32;
2400 atomic_op.memory_access_kind);
2403void InstructionSelectorT::VisitWord64AtomicCompareExchange(
OpIndex node) {
2407 opcode = kAtomicCompareExchangeUint8;
2409 opcode = kAtomicCompareExchangeUint16;
2411 opcode = kAtomicCompareExchangeWord32;
2413 opcode = kLoong64Word64AtomicCompareExchangeUint64;
2418 atomic_op.memory_access_kind);
2421void InstructionSelectorT::VisitWord32AtomicBinaryOperation(
2422 OpIndex node, ArchOpcode int8_op, ArchOpcode uint8_op, ArchOpcode int16_op,
2423 ArchOpcode uint16_op, ArchOpcode word32_op) {
2441 atomic_op.memory_access_kind);
2444#define VISIT_ATOMIC_BINOP(op) \
2445 void InstructionSelectorT::VisitWord32Atomic##op(OpIndex node) { \
2446 VisitWord32AtomicBinaryOperation( \
2447 node, kAtomic##op##Int8, kAtomic##op##Uint8, kAtomic##op##Int16, \
2448 kAtomic##op##Uint16, kAtomic##op##Word32); \
2455#undef VISIT_ATOMIC_BINOP
2457void InstructionSelectorT::VisitWord64AtomicBinaryOperation(
2458 OpIndex node, ArchOpcode uint8_op, ArchOpcode uint16_op,
2459 ArchOpcode uint32_op, ArchOpcode uint64_op) {
2473 VisitAtomicBinop(
this, node, opcode, AtomicWidth::kWord64,
2474 atomic_op.memory_access_kind);
2477#define VISIT_ATOMIC_BINOP(op) \
2478 void InstructionSelectorT::VisitWord64Atomic##op(OpIndex node) { \
2479 VisitWord64AtomicBinaryOperation(node, kAtomic##op##Uint8, \
2480 kAtomic##op##Uint16, kAtomic##op##Word32, \
2481 kLoong64Word64Atomic##op##Uint64); \
2488#undef VISIT_ATOMIC_BINOP
2490void InstructionSelectorT::VisitInt32AbsWithOverflow(
OpIndex node) {
2494void InstructionSelectorT::VisitInt64AbsWithOverflow(
OpIndex node) {
2498#define SIMD_TYPE_LIST(V) \
2506#define SIMD_UNOP_LIST(V) \
2507 V(F64x2Abs, kLoong64F64x2Abs) \
2508 V(F64x2Neg, kLoong64F64x2Neg) \
2509 V(F64x2Sqrt, kLoong64F64x2Sqrt) \
2510 V(F64x2Ceil, kLoong64F64x2Ceil) \
2511 V(F64x2Floor, kLoong64F64x2Floor) \
2512 V(F64x2Trunc, kLoong64F64x2Trunc) \
2513 V(F64x2NearestInt, kLoong64F64x2NearestInt) \
2514 V(I64x2Neg, kLoong64I64x2Neg) \
2515 V(I64x2BitMask, kLoong64I64x2BitMask) \
2516 V(F64x2ConvertLowI32x4S, kLoong64F64x2ConvertLowI32x4S) \
2517 V(F64x2ConvertLowI32x4U, kLoong64F64x2ConvertLowI32x4U) \
2518 V(F64x2PromoteLowF32x4, kLoong64F64x2PromoteLowF32x4) \
2519 V(F32x4SConvertI32x4, kLoong64F32x4SConvertI32x4) \
2520 V(F32x4UConvertI32x4, kLoong64F32x4UConvertI32x4) \
2521 V(F32x4Abs, kLoong64F32x4Abs) \
2522 V(F32x4Neg, kLoong64F32x4Neg) \
2523 V(F32x4Sqrt, kLoong64F32x4Sqrt) \
2524 V(F32x4Ceil, kLoong64F32x4Ceil) \
2525 V(F32x4Floor, kLoong64F32x4Floor) \
2526 V(F32x4Trunc, kLoong64F32x4Trunc) \
2527 V(F32x4NearestInt, kLoong64F32x4NearestInt) \
2528 V(F32x4DemoteF64x2Zero, kLoong64F32x4DemoteF64x2Zero) \
2529 V(I64x2Abs, kLoong64I64x2Abs) \
2530 V(I64x2SConvertI32x4Low, kLoong64I64x2SConvertI32x4Low) \
2531 V(I64x2SConvertI32x4High, kLoong64I64x2SConvertI32x4High) \
2532 V(I64x2UConvertI32x4Low, kLoong64I64x2UConvertI32x4Low) \
2533 V(I64x2UConvertI32x4High, kLoong64I64x2UConvertI32x4High) \
2534 V(I32x4SConvertF32x4, kLoong64I32x4SConvertF32x4) \
2535 V(I32x4UConvertF32x4, kLoong64I32x4UConvertF32x4) \
2536 V(I32x4Neg, kLoong64I32x4Neg) \
2537 V(I32x4SConvertI16x8Low, kLoong64I32x4SConvertI16x8Low) \
2538 V(I32x4SConvertI16x8High, kLoong64I32x4SConvertI16x8High) \
2539 V(I32x4UConvertI16x8Low, kLoong64I32x4UConvertI16x8Low) \
2540 V(I32x4UConvertI16x8High, kLoong64I32x4UConvertI16x8High) \
2541 V(I32x4Abs, kLoong64I32x4Abs) \
2542 V(I32x4BitMask, kLoong64I32x4BitMask) \
2543 V(I32x4TruncSatF64x2SZero, kLoong64I32x4TruncSatF64x2SZero) \
2544 V(I32x4TruncSatF64x2UZero, kLoong64I32x4TruncSatF64x2UZero) \
2545 V(I32x4RelaxedTruncF32x4S, kLoong64I32x4RelaxedTruncF32x4S) \
2546 V(I32x4RelaxedTruncF32x4U, kLoong64I32x4RelaxedTruncF32x4U) \
2547 V(I32x4RelaxedTruncF64x2SZero, kLoong64I32x4RelaxedTruncF64x2SZero) \
2548 V(I32x4RelaxedTruncF64x2UZero, kLoong64I32x4RelaxedTruncF64x2UZero) \
2549 V(I16x8Neg, kLoong64I16x8Neg) \
2550 V(I16x8SConvertI8x16Low, kLoong64I16x8SConvertI8x16Low) \
2551 V(I16x8SConvertI8x16High, kLoong64I16x8SConvertI8x16High) \
2552 V(I16x8UConvertI8x16Low, kLoong64I16x8UConvertI8x16Low) \
2553 V(I16x8UConvertI8x16High, kLoong64I16x8UConvertI8x16High) \
2554 V(I16x8Abs, kLoong64I16x8Abs) \
2555 V(I16x8BitMask, kLoong64I16x8BitMask) \
2556 V(I8x16Neg, kLoong64I8x16Neg) \
2557 V(I8x16Abs, kLoong64I8x16Abs) \
2558 V(I8x16Popcnt, kLoong64I8x16Popcnt) \
2559 V(I8x16BitMask, kLoong64I8x16BitMask) \
2560 V(S128Not, kLoong64S128Not) \
2561 V(I64x2AllTrue, kLoong64I64x2AllTrue) \
2562 V(I32x4AllTrue, kLoong64I32x4AllTrue) \
2563 V(I16x8AllTrue, kLoong64I16x8AllTrue) \
2564 V(I8x16AllTrue, kLoong64I8x16AllTrue) \
2565 V(V128AnyTrue, kLoong64V128AnyTrue)
2567#define SIMD_SHIFT_OP_LIST(V) \
2581#define SIMD_BINOP_LIST(V) \
2582 V(F64x2Add, kLoong64F64x2Add) \
2583 V(F64x2Sub, kLoong64F64x2Sub) \
2584 V(F64x2Mul, kLoong64F64x2Mul) \
2585 V(F64x2Div, kLoong64F64x2Div) \
2586 V(F64x2Min, kLoong64F64x2Min) \
2587 V(F64x2Max, kLoong64F64x2Max) \
2588 V(F64x2Eq, kLoong64F64x2Eq) \
2589 V(F64x2Ne, kLoong64F64x2Ne) \
2590 V(F64x2Lt, kLoong64F64x2Lt) \
2591 V(F64x2Le, kLoong64F64x2Le) \
2592 V(F64x2RelaxedMin, kLoong64F64x2RelaxedMin) \
2593 V(F64x2RelaxedMax, kLoong64F64x2RelaxedMax) \
2594 V(I64x2Eq, kLoong64I64x2Eq) \
2595 V(I64x2Ne, kLoong64I64x2Ne) \
2596 V(I64x2Add, kLoong64I64x2Add) \
2597 V(I64x2Sub, kLoong64I64x2Sub) \
2598 V(I64x2Mul, kLoong64I64x2Mul) \
2599 V(I64x2GtS, kLoong64I64x2GtS) \
2600 V(I64x2GeS, kLoong64I64x2GeS) \
2601 V(F32x4Add, kLoong64F32x4Add) \
2602 V(F32x4Sub, kLoong64F32x4Sub) \
2603 V(F32x4Mul, kLoong64F32x4Mul) \
2604 V(F32x4Div, kLoong64F32x4Div) \
2605 V(F32x4Max, kLoong64F32x4Max) \
2606 V(F32x4Min, kLoong64F32x4Min) \
2607 V(F32x4Eq, kLoong64F32x4Eq) \
2608 V(F32x4Ne, kLoong64F32x4Ne) \
2609 V(F32x4Lt, kLoong64F32x4Lt) \
2610 V(F32x4Le, kLoong64F32x4Le) \
2611 V(F32x4RelaxedMin, kLoong64F32x4RelaxedMin) \
2612 V(F32x4RelaxedMax, kLoong64F32x4RelaxedMax) \
2613 V(I32x4Add, kLoong64I32x4Add) \
2614 V(I32x4Sub, kLoong64I32x4Sub) \
2615 V(I32x4Mul, kLoong64I32x4Mul) \
2616 V(I32x4MaxS, kLoong64I32x4MaxS) \
2617 V(I32x4MinS, kLoong64I32x4MinS) \
2618 V(I32x4MaxU, kLoong64I32x4MaxU) \
2619 V(I32x4MinU, kLoong64I32x4MinU) \
2620 V(I32x4Eq, kLoong64I32x4Eq) \
2621 V(I32x4Ne, kLoong64I32x4Ne) \
2622 V(I32x4GtS, kLoong64I32x4GtS) \
2623 V(I32x4GeS, kLoong64I32x4GeS) \
2624 V(I32x4GtU, kLoong64I32x4GtU) \
2625 V(I32x4GeU, kLoong64I32x4GeU) \
2626 V(I32x4DotI16x8S, kLoong64I32x4DotI16x8S) \
2627 V(I16x8Add, kLoong64I16x8Add) \
2628 V(I16x8AddSatS, kLoong64I16x8AddSatS) \
2629 V(I16x8AddSatU, kLoong64I16x8AddSatU) \
2630 V(I16x8Sub, kLoong64I16x8Sub) \
2631 V(I16x8SubSatS, kLoong64I16x8SubSatS) \
2632 V(I16x8SubSatU, kLoong64I16x8SubSatU) \
2633 V(I16x8Mul, kLoong64I16x8Mul) \
2634 V(I16x8MaxS, kLoong64I16x8MaxS) \
2635 V(I16x8MinS, kLoong64I16x8MinS) \
2636 V(I16x8MaxU, kLoong64I16x8MaxU) \
2637 V(I16x8MinU, kLoong64I16x8MinU) \
2638 V(I16x8Eq, kLoong64I16x8Eq) \
2639 V(I16x8Ne, kLoong64I16x8Ne) \
2640 V(I16x8GtS, kLoong64I16x8GtS) \
2641 V(I16x8GeS, kLoong64I16x8GeS) \
2642 V(I16x8GtU, kLoong64I16x8GtU) \
2643 V(I16x8GeU, kLoong64I16x8GeU) \
2644 V(I16x8RoundingAverageU, kLoong64I16x8RoundingAverageU) \
2645 V(I16x8SConvertI32x4, kLoong64I16x8SConvertI32x4) \
2646 V(I16x8UConvertI32x4, kLoong64I16x8UConvertI32x4) \
2647 V(I16x8Q15MulRSatS, kLoong64I16x8Q15MulRSatS) \
2648 V(I16x8RelaxedQ15MulRS, kLoong64I16x8RelaxedQ15MulRS) \
2649 V(I8x16Add, kLoong64I8x16Add) \
2650 V(I8x16AddSatS, kLoong64I8x16AddSatS) \
2651 V(I8x16AddSatU, kLoong64I8x16AddSatU) \
2652 V(I8x16Sub, kLoong64I8x16Sub) \
2653 V(I8x16SubSatS, kLoong64I8x16SubSatS) \
2654 V(I8x16SubSatU, kLoong64I8x16SubSatU) \
2655 V(I8x16MaxS, kLoong64I8x16MaxS) \
2656 V(I8x16MinS, kLoong64I8x16MinS) \
2657 V(I8x16MaxU, kLoong64I8x16MaxU) \
2658 V(I8x16MinU, kLoong64I8x16MinU) \
2659 V(I8x16Eq, kLoong64I8x16Eq) \
2660 V(I8x16Ne, kLoong64I8x16Ne) \
2661 V(I8x16GtS, kLoong64I8x16GtS) \
2662 V(I8x16GeS, kLoong64I8x16GeS) \
2663 V(I8x16GtU, kLoong64I8x16GtU) \
2664 V(I8x16GeU, kLoong64I8x16GeU) \
2665 V(I8x16RoundingAverageU, kLoong64I8x16RoundingAverageU) \
2666 V(I8x16SConvertI16x8, kLoong64I8x16SConvertI16x8) \
2667 V(I8x16UConvertI16x8, kLoong64I8x16UConvertI16x8) \
2668 V(S128And, kLoong64S128And) \
2669 V(S128Or, kLoong64S128Or) \
2670 V(S128Xor, kLoong64S128Xor) \
2671 V(S128AndNot, kLoong64S128AndNot)
2677#define SIMD_VISIT_SPLAT(Type) \
2678 void InstructionSelectorT::Visit##Type##Splat(OpIndex node) { \
2679 VisitRR(this, kLoong64##Type##Splat, node); \
2682#undef SIMD_VISIT_SPLAT
2684#define SIMD_VISIT_EXTRACT_LANE(Type, Sign) \
2685 void InstructionSelectorT::Visit##Type##ExtractLane##Sign(OpIndex node) { \
2686 VisitRRI(this, kLoong64##Type##ExtractLane##Sign, node); \
2696#undef SIMD_VISIT_EXTRACT_LANE
2698#define SIMD_VISIT_REPLACE_LANE(Type) \
2699 void InstructionSelectorT::Visit##Type##ReplaceLane(OpIndex node) { \
2700 VisitRRIR(this, kLoong64##Type##ReplaceLane, node); \
2703#undef SIMD_VISIT_REPLACE_LANE
2705#define SIMD_VISIT_UNOP(Name, instruction) \
2706 void InstructionSelectorT::Visit##Name(OpIndex node) { \
2707 VisitRR(this, instruction, node); \
2710#undef SIMD_VISIT_UNOP
2712#define SIMD_VISIT_SHIFT_OP(Name) \
2713 void InstructionSelectorT::Visit##Name(OpIndex node) { \
2714 VisitSimdShift(this, kLoong64##Name, node); \
2717#undef SIMD_VISIT_SHIFT_OP
2719#define SIMD_VISIT_BINOP(Name, instruction) \
2720 void InstructionSelectorT::Visit##Name(OpIndex node) { \
2721 VisitRRR(this, instruction, node); \
2724#undef SIMD_VISIT_BINOP
2726void InstructionSelectorT::VisitS128Select(
OpIndex node) {
2727 VisitRRRR(
this, kLoong64S128Select, node);
2730void InstructionSelectorT::VisitI8x16RelaxedLaneSelect(
OpIndex node) {
2731 VisitS128Select(node);
2734void InstructionSelectorT::VisitI16x8RelaxedLaneSelect(
OpIndex node) {
2735 VisitS128Select(node);
2738void InstructionSelectorT::VisitI32x4RelaxedLaneSelect(
OpIndex node) {
2739 VisitS128Select(node);
2742void InstructionSelectorT::VisitI64x2RelaxedLaneSelect(
OpIndex node) {
2743 VisitS128Select(node);
2746#define SIMD_UNIMP_OP_LIST(V) \
2751 V(I16x8DotI8x16I7x16S) \
2752 V(I32x4DotI8x16I7x16AddS)
2754#define SIMD_VISIT_UNIMP_OP(Name) \
2755 void InstructionSelectorT::Visit##Name(OpIndex node) { UNIMPLEMENTED(); }
2758#undef SIMD_VISIT_UNIMP_OP
2759#undef SIMD_UNIMP_OP_LIST
2761#define UNIMPLEMENTED_SIMD_FP16_OP_LIST(V) \
2763 V(F16x8ExtractLane) \
2764 V(F16x8ReplaceLane) \
2771 V(F16x8NearestInt) \
2784 V(F16x8SConvertI16x8) \
2785 V(F16x8UConvertI16x8) \
2786 V(I16x8SConvertF16x8) \
2787 V(I16x8UConvertF16x8) \
2788 V(F32x4PromoteLowF16x8) \
2789 V(F16x8DemoteF32x4Zero) \
2790 V(F16x8DemoteF64x2Zero) \
2794#define SIMD_VISIT_UNIMPL_FP16_OP(Name) \
2795 void InstructionSelectorT::Visit##Name(OpIndex node) { UNIMPLEMENTED(); }
2798#undef SIMD_VISIT_UNIMPL_FP16_OP
2799#undef UNIMPLEMENTED_SIMD_FP16_OP_LIST
2801#if V8_ENABLE_WEBASSEMBLY
2811void InstructionSelectorT::VisitSetStackPointer(
OpIndex node) {
2812 OperandGenerator g(
this);
2813 auto input = g.UseRegister(this->input_at(node, 0));
2814 Emit(kArchSetStackPointer, 0,
nullptr, 1, &input);
2817void InstructionSelectorT::VisitSignExtendWord8ToInt32(
OpIndex node) {
2818 VisitRR(
this, kLoong64Ext_w_b, node);
2821void InstructionSelectorT::VisitSignExtendWord16ToInt32(
OpIndex node) {
2822 VisitRR(
this, kLoong64Ext_w_h, node);
2825void InstructionSelectorT::VisitSignExtendWord8ToInt64(
OpIndex node) {
2826 VisitRR(
this, kLoong64Ext_w_b, node);
2829void InstructionSelectorT::VisitSignExtendWord16ToInt64(
OpIndex node) {
2830 VisitRR(
this, kLoong64Ext_w_h, node);
2833void InstructionSelectorT::VisitSignExtendWord32ToInt64(
OpIndex node) {
2837void InstructionSelectorT::VisitF32x4Pmin(
OpIndex node) {
2841void InstructionSelectorT::VisitF32x4Pmax(
OpIndex node) {
2845void InstructionSelectorT::VisitF64x2Pmin(
OpIndex node) {
2849void InstructionSelectorT::VisitF64x2Pmax(
OpIndex node) {
2853#define VISIT_EXT_MUL(OPCODE1, OPCODE2) \
2854 void InstructionSelectorT::Visit##OPCODE1##ExtMulLow##OPCODE2( \
2856 void InstructionSelectorT::Visit##OPCODE1##ExtMulHigh##OPCODE2( \
2867#define VISIT_EXTADD_PAIRWISE(OPCODE) \
2868 void InstructionSelectorT::Visit##OPCODE(OpIndex node) { UNIMPLEMENTED(); }
2873#undef VISIT_EXTADD_PAIRWISE
2875void InstructionSelectorT::AddOutputToSelectContinuation(OperandGenerator* g,
2876 int first_input_index,
2882MachineOperatorBuilder::Flags
2883InstructionSelector::SupportedMachineOperatorFlags() {
2884 MachineOperatorBuilder::Flags flags = MachineOperatorBuilder::kNoFlags;
2885 return flags | MachineOperatorBuilder::kWord32ShiftIsSafe |
2886 MachineOperatorBuilder::kInt32DivIsSafe |
2887 MachineOperatorBuilder::kUint32DivIsSafe |
2888 MachineOperatorBuilder::kFloat64RoundDown |
2889 MachineOperatorBuilder::kFloat32RoundDown |
2890 MachineOperatorBuilder::kFloat64RoundUp |
2891 MachineOperatorBuilder::kFloat32RoundUp |
2892 MachineOperatorBuilder::kFloat64RoundTruncate |
2893 MachineOperatorBuilder::kFloat32RoundTruncate |
2894 MachineOperatorBuilder::kFloat64RoundTiesEven |
2895 MachineOperatorBuilder::kFloat32RoundTiesEven;
2899MachineOperatorBuilder::AlignmentRequirements
2900InstructionSelector::AlignmentRequirements() {
2901 return MachineOperatorBuilder::AlignmentRequirements::
2902 FullUnalignedAccessSupport();
2905#undef SIMD_BINOP_LIST
2906#undef SIMD_SHIFT_OP_LIST
2907#undef SIMD_UNOP_LIST
2908#undef SIMD_TYPE_LIST
static constexpr T decode(U value)
static constexpr U encode(T value)
RootsTable & roots_table()
int32_t GetLocation() const
static constexpr MachineType Float64()
constexpr MachineRepresentation representation() const
static constexpr MachineType Simd128()
static constexpr MachineType Float32()
Tagged_t ReadOnlyRootPtr(RootIndex index)
static intptr_t RootRegisterOffsetForExternalReference(Isolate *isolate, const ExternalReference &reference)
bool IsRootHandle(IndirectHandle< T > handle, RootIndex *index) const
static constexpr bool IsReadOnly(RootIndex root_index)
int AllocateSpillSlot(int width, int alignment=0, bool is_tagged=false)
void VisitWordCompareZero(turboshaft::OpIndex user, turboshaft::OpIndex value, FlagsContinuation *cont)
FlagsCondition GetComparisonFlagCondition(const turboshaft::ComparisonOp &op) const
Linkage * linkage() const
void EmitPrepareArguments(ZoneVector< PushParameter > *arguments, const CallDescriptor *call_descriptor, turboshaft::OpIndex node)
Instruction * Emit(InstructionCode opcode, InstructionOperand output, size_t temp_count=0, InstructionOperand *temps=nullptr)
void MarkAsFloat64(turboshaft::OpIndex node)
Isolate * isolate() const
bool CanCover(turboshaft::OpIndex user, turboshaft::OpIndex node) const
void EmitMoveFPRToParam(InstructionOperand *op, LinkageLocation location)
Instruction * EmitWithContinuation(InstructionCode opcode, FlagsContinuation *cont)
void EmitIdentity(turboshaft::OpIndex node)
void VisitLoadTransform(Node *node, Node *value, InstructionCode opcode)
bool IsTailCallAddressImmediate()
void VisitStackPointerGreaterThan(turboshaft::OpIndex node, FlagsContinuation *cont)
turboshaft::OptionalOpIndex FindProjection(turboshaft::OpIndex node, size_t projection_index)
void VisitLoad(turboshaft::OpIndex node, turboshaft::OpIndex value, InstructionCode opcode)
bool CanAddressRelativeToRootsRegister(const ExternalReference &reference) const
PushParameterT PushParameter
OperandGeneratorT OperandGenerator
void VisitFloat64Ieee754Binop(turboshaft::OpIndex, InstructionCode code)
auto Inputs(turboshaft::OpIndex node)
void MarkAsFloat32(turboshaft::OpIndex node)
void EmitMoveParamToFPR(turboshaft::OpIndex node, int index)
void VisitFloat64Ieee754Unop(turboshaft::OpIndex, InstructionCode code)
void EmitPrepareResults(ZoneVector< PushParameter > *results, const CallDescriptor *call_descriptor, turboshaft::OpIndex node)
Instruction * MarkAsCall()
LinkageLocation GetParameterLocation(int index) const
bool IsIntegerConstant(OpIndex node)
bool CanBeImmediate(OpIndex node, InstructionCode mode)
bool ImmediateFitsAddrMode1Instruction(int32_t imm) const
InstructionOperand UseRegisterOrImmediateZero(OpIndex node)
std::optional< int64_t > GetOptionalIntegerConstant(OpIndex operation)
bool CanBeImmediate(int64_t value, InstructionCode opcode)
Loong64OperandGeneratorT(InstructionSelectorT *selector)
InstructionOperand UseOperand(OpIndex node, InstructionCode opcode)
InstructionOperand UseImmediate(int immediate)
InstructionOperand DefineAsRegister(turboshaft::OpIndex node)
InstructionOperand UseUniqueRegister(turboshaft::OpIndex node)
InstructionOperand TempImmediate(int32_t imm)
InstructionSelectorT * selector() const
InstructionOperand UseRegister(turboshaft::OpIndex node)
MachineRepresentation representation() const
WriteBarrierKind write_barrier_kind() const
LoadRepresentation loaded_rep() const
MemoryAccessKind access_kind() const
turboshaft::OptionalOpIndex index() const
IndirectPointerTag indirect_pointer_tag() const
turboshaft::OpIndex base() const
turboshaft::OpIndex value() const
turboshaft::MemoryRepresentation ts_stored_rep() const
int32_t displacement() const
StoreRepresentation stored_rep() const
bool is_store_trap_on_null() const
V8_INLINE const Operation & Get(OpIndex i) const
static constexpr MemoryRepresentation AnyTagged()
static constexpr MemoryRepresentation Int8()
static constexpr MemoryRepresentation Float16()
static constexpr MemoryRepresentation AnyUncompressedTagged()
static constexpr MemoryRepresentation Uint32()
static constexpr MemoryRepresentation TaggedSigned()
static constexpr MemoryRepresentation Int32()
static constexpr MemoryRepresentation Int64()
static constexpr MemoryRepresentation Simd128()
static constexpr MemoryRepresentation SandboxedPointer()
static constexpr MemoryRepresentation Uint16()
static constexpr MemoryRepresentation ProtectedPointer()
static constexpr MemoryRepresentation Uint8()
static constexpr MemoryRepresentation Int16()
static constexpr MemoryRepresentation IndirectPointer()
static constexpr MemoryRepresentation Uint64()
static constexpr MemoryRepresentation Float32()
static constexpr MemoryRepresentation Float64()
bool Is(V< AnyOrNone > op_idx) const
const Operation & Get(V< AnyOrNone > op_idx) const
bool MatchIntegralZero(V< Any > matched) const
const underlying_operation_t< Op > * TryCast(V< AnyOrNone > op_idx) const
bool MatchExternalConstant(V< Any > matched, ExternalReference *reference) const
bool MatchIntegralWord64Constant(V< Any > matched, uint64_t *constant) const
const underlying_operation_t< Op > & Cast(V< AnyOrNone > op_idx) const
bool MatchSignedIntegralConstant(V< Any > matched, int64_t *constant) const
constexpr bool valid() const
static constexpr RegisterRepresentation Word32()
static constexpr RegisterRepresentation Float64()
static constexpr RegisterRepresentation Float32()
static constexpr RegisterRepresentation Word64()
static constexpr RegisterRepresentation Tagged()
static constexpr WordRepresentation Word32()
static constexpr WordRepresentation Word64()
#define COMPRESS_POINTERS_BOOL
#define V8_ENABLE_SANDBOX_BOOL
InstructionSelectorT * selector_
#define SIMD_SHIFT_OP_LIST(V)
#define VISIT_ATOMIC_BINOP(op)
#define SIMD_VISIT_SHIFT_OP(Name)
#define SIMD_VISIT_UNIMPL_FP16_OP(Name)
#define VISIT_EXT_MUL(OPCODE1, OPCODE2)
#define SIMD_VISIT_SPLAT(Type)
#define VISIT_EXTADD_PAIRWISE(OPCODE)
#define SIMD_VISIT_EXTRACT_LANE(Type, Sign)
#define SIMD_VISIT_UNIMP_OP(Name)
#define SIMD_VISIT_REPLACE_LANE(Type)
#define SIMD_UNIMP_OP_LIST(V)
#define SIMD_VISIT_UNOP(Name, instruction)
#define SIMD_VISIT_BINOP(Name, instruction)
#define SIMD_TYPE_LIST(V)
#define UNIMPLEMENTED_SIMD_FP16_OP_LIST(V)
ZoneVector< RpoNumber > & result
#define SIMD_UNOP_LIST(V)
#define SIMD_BINOP_LIST(V)
constexpr bool IsInRange(T value, U lower_limit, U higher_limit)
ChangeOpMask::For< ChangeOp::Kind::kSignedFloatTruncateOverflowToMin, ChangeOp::Assumption::kNoAssumption, RegisterRepresentation::Float64(), RegisterRepresentation::Word64()> kTruncateFloat64ToInt64OverflowToMin
WordBinopMask::For< WordBinopOp::Kind::kBitwiseAnd, WordRepresentation::Word64()> kWord64BitwiseAnd
WordBinopMask::For< WordBinopOp::Kind::kBitwiseAnd, WordRepresentation::Word32()> kWord32BitwiseAnd
ConstantMask::For< ConstantOp::Kind::kWord32 > kWord32Constant
ChangeOpMask::For< ChangeOp::Kind::kSignExtend, ChangeOp::Assumption::kNoAssumption, RegisterRepresentation::Word32(), RegisterRepresentation::Word64()> kChangeInt32ToInt64
ChangeOpMask::For< ChangeOp::Kind::kSignedFloatTruncateOverflowToMin, ChangeOp::Assumption::kNoAssumption, RegisterRepresentation::Float32(), RegisterRepresentation::Word32()> kTruncateFloat32ToInt32OverflowToMin
ChangeOpMask::For< ChangeOp::Kind::kZeroExtend, ChangeOp::Assumption::kNoAssumption, RegisterRepresentation::Word32(), RegisterRepresentation::Word64()> kChangeUint32ToUint64
ChangeOpMask::For< ChangeOp::Kind::kUnsignedFloatTruncateOverflowToMin, ChangeOp::Assumption::kNoAssumption, RegisterRepresentation::Float32(), RegisterRepresentation::Word32()> kTruncateFloat32ToUint32OverflowToMin
ShiftMask::For< ShiftOp::Kind::kShiftRightArithmetic, WordRepresentation::Word32()> kWord32ShiftRightArithmetic
constexpr size_t input_count()
V8_INLINE const Operation & Get(const Graph &graph, OpIndex index)
WordWithBits< 256 > Simd256
void VisitAtomicBinop(InstructionSelectorT *selector, OpIndex node, ArchOpcode opcode, AtomicWidth width)
static void VisitRRIR(InstructionSelectorT *selector, ArchOpcode opcode, OpIndex node)
void VisitAtomicExchange(InstructionSelectorT *selector, OpIndex node, ArchOpcode opcode)
static void VisitRRO(InstructionSelectorT *selector, ArchOpcode opcode, OpIndex node)
void VisitRRRR(InstructionSelectorT *selector, ArchOpcode opcode, OpIndex node)
static void VisitRR(InstructionSelectorT *selector, ArchOpcode opcode, OpIndex node)
@ kIndirectPointerWriteBarrier
static void VisitRRI(InstructionSelectorT *selector, ArchOpcode opcode, OpIndex node)
void VisitRRR(InstructionSelectorT *selector, ArchOpcode opcode, OpIndex node)
AtomicStoreParameters const & AtomicStoreParametersOf(Operator const *op)
bool TryEmitExtendingLoad(InstructionSelectorT *selector, OpIndex node, OpIndex output_node)
size_t AtomicWidthSize(AtomicWidth width)
static Instruction * VisitCompare(InstructionSelectorT *selector, InstructionCode opcode, InstructionOperand left, InstructionOperand right, FlagsContinuationT *cont)
static void VisitSimdShift(InstructionSelectorT *selector, ArchOpcode opcode, OpIndex node)
void VisitFloat32Compare(InstructionSelectorT *selector, OpIndex node, FlagsContinuationT *cont)
void EmitLoad(InstructionSelectorT *selector, OpIndex node, InstructionCode opcode, ImmediateMode immediate_mode, MachineRepresentation rep, OptionalOpIndex output={})
static void VisitBinop(InstructionSelectorT *selector, turboshaft::OpIndex node, InstructionCode opcode, bool has_reverse_opcode, InstructionCode reverse_opcode, FlagsContinuationT *cont)
MachineType LoadRepresentation
Instruction * VisitWordCompare(InstructionSelectorT *selector, OpIndex node, InstructionCode opcode, FlagsContinuationT *cont, bool commutative)
@ kSignedGreaterThanOrEqual
@ kUnsignedLessThanOrEqual
@ kUnsignedGreaterThanOrEqual
void VisitFloat64Compare(InstructionSelectorT *selector, OpIndex node, FlagsContinuationT *cont)
RecordWriteMode WriteBarrierKindToRecordWriteMode(WriteBarrierKind write_barrier_kind)
@ kProtectedByTrapHandler
static constexpr FlagsCondition kStackPointerGreaterThanCondition
bool TryMatchImmediate(InstructionSelectorT *selector, InstructionCode *opcode_return, OpIndex node, size_t *input_count_return, InstructionOperand *inputs)
static void VisitUniqueRRR(InstructionSelectorT *selector, ArchOpcode opcode, OpIndex node)
@ kMemoryAccessProtectedMemOutOfBounds
@ kMemoryAccessProtectedNullDereference
void VisitAtomicCompareExchange(InstructionSelectorT *selector, OpIndex node, ArchOpcode opcode)
bool TryCast(Tagged< From > value, Tagged< To > *out)
constexpr int kTaggedSize
constexpr bool CanBeTaggedOrCompressedOrIndirectPointer(MachineRepresentation rep)
Tagged(T object) -> Tagged< T >
constexpr bool CanBeTaggedOrCompressedPointer(MachineRepresentation rep)
constexpr int kSystemPointerSizeLog2
constexpr bool SmiValuesAre31Bits()
constexpr bool CanBeTaggedPointer(MachineRepresentation rep)
V8_EXPORT_PRIVATE FlagValues v8_flags
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
#define DCHECK_IMPLIES(v1, v2)
#define DCHECK_NE(v1, v2)
#define DCHECK_GE(v1, v2)
#define CHECK_EQ(lhs, rhs)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
ExtendingLoadMatcher(OpIndex node, InstructionSelectorT *selector)
ArchOpcode opcode() const
void Initialize(turboshaft::OpIndex node)
InstructionSelectorT * selector_
int64_t immediate() const
bool is_load_root_register(turboshaft::OpIndex node) const
turboshaft::OpIndex input_at(turboshaft::OpIndex node, size_t index) const
base::Vector< const turboshaft::OpIndex > inputs(turboshaft::OpIndex node) const
LoadView load_view(turboshaft::OpIndex node)
turboshaft::Opcode opcode(turboshaft::OpIndex node) const
turboshaft::Graph * turboshaft_graph() const
StoreView store_view(turboshaft::OpIndex node)
ExternalReference external_reference() const
V8_INLINE OpIndex input(size_t i) const
underlying_operation_t< Op > & Cast()
V< Word32 > right() const
#define V8_STATIC_ROOTS_BOOL