summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/simd-scalar-lowering.h
blob: b86071f0ae854d030d6163daa7761380eb51b446 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_COMPILER_SIMD_SCALAR_LOWERING_H_
#define V8_COMPILER_SIMD_SCALAR_LOWERING_H_

#include "src/compiler/common-operator.h"
#include "src/compiler/diamond.h"
#include "src/compiler/graph.h"
#include "src/compiler/machine-graph.h"
#include "src/compiler/machine-operator.h"
#include "src/compiler/node-marker.h"
#include "src/zone/zone-containers.h"

namespace v8 {
namespace internal {

template <typename T>
class Signature;

namespace compiler {

class SimdScalarLowering {
 public:
  SimdScalarLowering(MachineGraph* mcgraph,
                     Signature<MachineRepresentation>* signature);

  void LowerGraph();

  int GetParameterCountAfterLowering();

 private:
  enum class State : uint8_t { kUnvisited, kOnStack, kVisited };

  enum class SimdType : uint8_t {
    kFloat64x2,
    kFloat32x4,
    kInt64x2,
    kInt32x4,
    kInt16x8,
    kInt8x16
  };

#if defined(V8_TARGET_BIG_ENDIAN)
  static constexpr int kLaneOffsets[16] = {15, 14, 13, 12, 11, 10, 9, 8,
                                           7,  6,  5,  4,  3,  2,  1, 0};
#else
  static constexpr int kLaneOffsets[16] = {0, 1, 2,  3,  4,  5,  6,  7,
                                           8, 9, 10, 11, 12, 13, 14, 15};
#endif
  struct Replacement {
    Node** node = nullptr;
    SimdType type;  // represents output type
    int num_replacements = 0;
  };

  struct NodeState {
    Node* node;
    int input_index;
  };

  Zone* zone() const { return mcgraph_->zone(); }
  Graph* graph() const { return mcgraph_->graph(); }
  MachineOperatorBuilder* machine() const { return mcgraph_->machine(); }
  CommonOperatorBuilder* common() const { return mcgraph_->common(); }
  Signature<MachineRepresentation>* signature() const { return signature_; }

  void LowerNode(Node* node);
  bool DefaultLowering(Node* node);

  int NumLanes(SimdType type);
  void ReplaceNode(Node* old, Node** new_nodes, int count);
  bool HasReplacement(size_t index, Node* node);
  Node** GetReplacements(Node* node);
  int ReplacementCount(Node* node);
  void Float64ToInt64(Node** replacements, Node** result);
  void Float32ToInt32(Node** replacements, Node** result);
  void Int32ToFloat32(Node** replacements, Node** result);
  void Int64ToFloat64(Node** replacements, Node** result);
  void Int64ToInt32(Node** replacements, Node** result);
  template <typename T>
  void Int32ToSmallerInt(Node** replacements, Node** result);
  template <typename T>
  void SmallerIntToInt32(Node** replacements, Node** result);
  void Int32ToInt64(Node** replacements, Node** result);
  Node** GetReplacementsWithType(Node* node, SimdType type);
  SimdType ReplacementType(Node* node);
  void PreparePhiReplacement(Node* phi);
  void SetLoweredType(Node* node, Node* output);
  void GetIndexNodes(Node* index, Node** new_indices, SimdType type);
  void LowerLoadOp(Node* node, SimdType type);
  void LowerLoadTransformOp(Node* node, SimdType type);
  void LowerStoreOp(Node* node);
  void LowerBinaryOp(Node* node, SimdType input_rep_type, const Operator* op,
                     bool not_horizontal = true);
  Node* ConstructPhiForComparison(Diamond d, SimdType rep_type, int true_value,
                                  int false_value);
  void LowerCompareOp(Node* node, SimdType input_rep_type, const Operator* op,
                      bool invert_inputs = false);
  Node* FixUpperBits(Node* input, int32_t shift);
  void LowerBinaryOpForSmallInt(Node* node, SimdType input_rep_type,
                                const Operator* op, bool not_horizontal = true);
  Node* Mask(Node* input, int32_t mask);
  void LowerSaturateBinaryOp(Node* node, SimdType input_rep_type,
                             const Operator* op, bool is_signed);
  void LowerUnaryOp(Node* node, SimdType input_rep_type, const Operator* op);
  void LowerIntMinMax(Node* node, const Operator* op, bool is_max,
                      SimdType type);
  void LowerConvertFromFloat(Node* node, bool is_signed);
  void LowerConvertFromInt(Node* node, SimdType input_rep_type,
                           SimdType output_rep_type, bool is_signed,
                           int start_index);
  void LowerPack(Node* node, SimdType input_rep_type, SimdType output_rep_type,
                 bool is_signed);
  void LowerShiftOp(Node* node, SimdType type);
  Node* BuildF64Trunc(Node* input);
  void LowerNotEqual(Node* node, SimdType input_rep_type, const Operator* op);
  MachineType MachineTypeFrom(SimdType simdType);
  void LowerBitMaskOp(Node* node, SimdType rep_type, int msb_index);
  void LowerAllTrueOp(Node* node, SimdType rep_type);

  MachineGraph* const mcgraph_;
  NodeMarker<State> state_;
  ZoneDeque<NodeState> stack_;
  Replacement* replacements_;
  Signature<MachineRepresentation>* signature_;
  Node* placeholder_;
  int parameter_count_after_lowering_;
};

}  // namespace compiler
}  // namespace internal
}  // namespace v8

#endif  // V8_COMPILER_SIMD_SCALAR_LOWERING_H_