• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_IC_BINARY_OP_ASSEMBLER_H_
6 #define V8_IC_BINARY_OP_ASSEMBLER_H_
7 
8 #include <functional>
9 
10 #include "src/codegen/code-stub-assembler.h"
11 
12 namespace v8 {
13 namespace internal {
14 
15 namespace compiler {
16 class CodeAssemblerState;
17 }  // namespace compiler
18 
19 class BinaryOpAssembler : public CodeStubAssembler {
20  public:
BinaryOpAssembler(compiler::CodeAssemblerState * state)21   explicit BinaryOpAssembler(compiler::CodeAssemblerState* state)
22       : CodeStubAssembler(state) {}
23 
24   TNode<Object> Generate_AddWithFeedback(
25       const LazyNode<Context>& context, TNode<Object> left, TNode<Object> right,
26       TNode<UintPtrT> slot, const LazyNode<HeapObject>& maybe_feedback_vector,
27       UpdateFeedbackMode update_feedback_mode, bool rhs_known_smi);
28 
29   TNode<Object> Generate_SubtractWithFeedback(
30       const LazyNode<Context>& context, TNode<Object> left, TNode<Object> right,
31       TNode<UintPtrT> slot, const LazyNode<HeapObject>& maybe_feedback_vector,
32       UpdateFeedbackMode update_feedback_mode, bool rhs_known_smi);
33 
34   TNode<Object> Generate_MultiplyWithFeedback(
35       const LazyNode<Context>& context, TNode<Object> left, TNode<Object> right,
36       TNode<UintPtrT> slot, const LazyNode<HeapObject>& maybe_feedback_vector,
37       UpdateFeedbackMode update_feedback_mode, bool rhs_known_smi);
38 
39   TNode<Object> Generate_DivideWithFeedback(
40       const LazyNode<Context>& context, TNode<Object> dividend,
41       TNode<Object> divisor, TNode<UintPtrT> slot,
42       const LazyNode<HeapObject>& maybe_feedback_vector,
43       UpdateFeedbackMode update_feedback_mode, bool rhs_known_smi);
44 
45   TNode<Object> Generate_ModulusWithFeedback(
46       const LazyNode<Context>& context, TNode<Object> dividend,
47       TNode<Object> divisor, TNode<UintPtrT> slot,
48       const LazyNode<HeapObject>& maybe_feedback_vector,
49       UpdateFeedbackMode update_feedback_mode, bool rhs_known_smi);
50 
51   TNode<Object> Generate_ExponentiateWithFeedback(
52       const LazyNode<Context>& context, TNode<Object> base,
53       TNode<Object> exponent, TNode<UintPtrT> slot,
54       const LazyNode<HeapObject>& maybe_feedback_vector,
55       UpdateFeedbackMode update_feedback_mode, bool rhs_known_smi);
56 
Generate_BitwiseOrWithFeedback(const LazyNode<Context> & context,TNode<Object> left,TNode<Object> right,TNode<UintPtrT> slot,const LazyNode<HeapObject> & maybe_feedback_vector,UpdateFeedbackMode update_feedback_mode,bool rhs_known_smi)57   TNode<Object> Generate_BitwiseOrWithFeedback(
58       const LazyNode<Context>& context, TNode<Object> left, TNode<Object> right,
59       TNode<UintPtrT> slot, const LazyNode<HeapObject>& maybe_feedback_vector,
60       UpdateFeedbackMode update_feedback_mode, bool rhs_known_smi) {
61     TNode<Object> result = Generate_BitwiseBinaryOpWithFeedback(
62         Operation::kBitwiseOr, left, right, context, slot,
63         maybe_feedback_vector, update_feedback_mode, rhs_known_smi);
64     return result;
65   }
66 
Generate_BitwiseXorWithFeedback(const LazyNode<Context> & context,TNode<Object> left,TNode<Object> right,TNode<UintPtrT> slot,const LazyNode<HeapObject> & maybe_feedback_vector,UpdateFeedbackMode update_feedback_mode,bool rhs_known_smi)67   TNode<Object> Generate_BitwiseXorWithFeedback(
68       const LazyNode<Context>& context, TNode<Object> left, TNode<Object> right,
69       TNode<UintPtrT> slot, const LazyNode<HeapObject>& maybe_feedback_vector,
70       UpdateFeedbackMode update_feedback_mode, bool rhs_known_smi) {
71     TNode<Object> result = Generate_BitwiseBinaryOpWithFeedback(
72         Operation::kBitwiseXor, left, right, context, slot,
73         maybe_feedback_vector, update_feedback_mode, rhs_known_smi);
74 
75     return result;
76   }
77 
Generate_BitwiseAndWithFeedback(const LazyNode<Context> & context,TNode<Object> left,TNode<Object> right,TNode<UintPtrT> slot,const LazyNode<HeapObject> & maybe_feedback_vector,UpdateFeedbackMode update_feedback_mode,bool rhs_known_smi)78   TNode<Object> Generate_BitwiseAndWithFeedback(
79       const LazyNode<Context>& context, TNode<Object> left, TNode<Object> right,
80       TNode<UintPtrT> slot, const LazyNode<HeapObject>& maybe_feedback_vector,
81       UpdateFeedbackMode update_feedback_mode, bool rhs_known_smi) {
82     TNode<Object> result = Generate_BitwiseBinaryOpWithFeedback(
83         Operation::kBitwiseAnd, left, right, context, slot,
84         maybe_feedback_vector, update_feedback_mode, rhs_known_smi);
85 
86     return result;
87   }
88 
Generate_ShiftLeftWithFeedback(const LazyNode<Context> & context,TNode<Object> left,TNode<Object> right,TNode<UintPtrT> slot,const LazyNode<HeapObject> & maybe_feedback_vector,UpdateFeedbackMode update_feedback_mode,bool rhs_known_smi)89   TNode<Object> Generate_ShiftLeftWithFeedback(
90       const LazyNode<Context>& context, TNode<Object> left, TNode<Object> right,
91       TNode<UintPtrT> slot, const LazyNode<HeapObject>& maybe_feedback_vector,
92       UpdateFeedbackMode update_feedback_mode, bool rhs_known_smi) {
93     TNode<Object> result = Generate_BitwiseBinaryOpWithFeedback(
94         Operation::kShiftLeft, left, right, context, slot,
95         maybe_feedback_vector, update_feedback_mode, rhs_known_smi);
96 
97     return result;
98   }
99 
Generate_ShiftRightWithFeedback(const LazyNode<Context> & context,TNode<Object> left,TNode<Object> right,TNode<UintPtrT> slot,const LazyNode<HeapObject> & maybe_feedback_vector,UpdateFeedbackMode update_feedback_mode,bool rhs_known_smi)100   TNode<Object> Generate_ShiftRightWithFeedback(
101       const LazyNode<Context>& context, TNode<Object> left, TNode<Object> right,
102       TNode<UintPtrT> slot, const LazyNode<HeapObject>& maybe_feedback_vector,
103       UpdateFeedbackMode update_feedback_mode, bool rhs_known_smi) {
104     TNode<Object> result = Generate_BitwiseBinaryOpWithFeedback(
105         Operation::kShiftRight, left, right, context, slot,
106         maybe_feedback_vector, update_feedback_mode, rhs_known_smi);
107 
108     return result;
109   }
110 
Generate_ShiftRightLogicalWithFeedback(const LazyNode<Context> & context,TNode<Object> left,TNode<Object> right,TNode<UintPtrT> slot,const LazyNode<HeapObject> & maybe_feedback_vector,UpdateFeedbackMode update_feedback_mode,bool rhs_known_smi)111   TNode<Object> Generate_ShiftRightLogicalWithFeedback(
112       const LazyNode<Context>& context, TNode<Object> left, TNode<Object> right,
113       TNode<UintPtrT> slot, const LazyNode<HeapObject>& maybe_feedback_vector,
114       UpdateFeedbackMode update_feedback_mode, bool rhs_known_smi) {
115     TNode<Object> result = Generate_BitwiseBinaryOpWithFeedback(
116         Operation::kShiftRightLogical, left, right, context, slot,
117         maybe_feedback_vector, update_feedback_mode, rhs_known_smi);
118 
119     return result;
120   }
121 
Generate_BitwiseBinaryOpWithFeedback(Operation bitwise_op,TNode<Object> left,TNode<Object> right,const LazyNode<Context> & context,TNode<UintPtrT> slot,const LazyNode<HeapObject> & maybe_feedback_vector,UpdateFeedbackMode update_feedback_mode,bool rhs_known_smi)122   TNode<Object> Generate_BitwiseBinaryOpWithFeedback(
123       Operation bitwise_op, TNode<Object> left, TNode<Object> right,
124       const LazyNode<Context>& context, TNode<UintPtrT> slot,
125       const LazyNode<HeapObject>& maybe_feedback_vector,
126       UpdateFeedbackMode update_feedback_mode, bool rhs_known_smi) {
127     return rhs_known_smi
128                ? Generate_BitwiseBinaryOpWithSmiOperandAndOptionalFeedback(
129                      bitwise_op, left, right, context, &slot,
130                      &maybe_feedback_vector, update_feedback_mode)
131                : Generate_BitwiseBinaryOpWithOptionalFeedback(
132                      bitwise_op, left, right, context, &slot,
133                      &maybe_feedback_vector, update_feedback_mode);
134   }
135 
Generate_BitwiseBinaryOp(Operation bitwise_op,TNode<Object> left,TNode<Object> right,TNode<Context> context)136   TNode<Object> Generate_BitwiseBinaryOp(Operation bitwise_op,
137                                          TNode<Object> left,
138                                          TNode<Object> right,
139                                          TNode<Context> context) {
140     return Generate_BitwiseBinaryOpWithOptionalFeedback(
141         bitwise_op, left, right, [&] { return context; }, nullptr, nullptr,
142         UpdateFeedbackMode::kOptionalFeedback);
143   }
144 
145  private:
146   using SmiOperation =
147       std::function<TNode<Object>(TNode<Smi>, TNode<Smi>, TVariable<Smi>*)>;
148   using FloatOperation =
149       std::function<TNode<Float64T>(TNode<Float64T>, TNode<Float64T>)>;
150 
151   TNode<Object> Generate_BinaryOperationWithFeedback(
152       const LazyNode<Context>& context, TNode<Object> left, TNode<Object> right,
153       TNode<UintPtrT> slot, const LazyNode<HeapObject>& maybe_feedback_vector,
154       const SmiOperation& smiOperation, const FloatOperation& floatOperation,
155       Operation op, UpdateFeedbackMode update_feedback_mode,
156       bool rhs_known_smi);
157 
158   TNode<Object> Generate_BitwiseBinaryOpWithOptionalFeedback(
159       Operation bitwise_op, TNode<Object> left, TNode<Object> right,
160       const LazyNode<Context>& context, TNode<UintPtrT>* slot,
161       const LazyNode<HeapObject>* maybe_feedback_vector,
162       UpdateFeedbackMode update_feedback_mode);
163 
164   TNode<Object> Generate_BitwiseBinaryOpWithSmiOperandAndOptionalFeedback(
165       Operation bitwise_op, TNode<Object> left, TNode<Object> right,
166       const LazyNode<Context>& context, TNode<UintPtrT>* slot,
167       const LazyNode<HeapObject>* maybe_feedback_vector,
168       UpdateFeedbackMode update_feedback_mode);
169 
170   // Check if output is known to be Smi when both operands of bitwise operation
171   // are Smi.
IsBitwiseOutputKnownSmi(Operation bitwise_op)172   bool IsBitwiseOutputKnownSmi(Operation bitwise_op) {
173     switch (bitwise_op) {
174       case Operation::kBitwiseAnd:
175       case Operation::kBitwiseOr:
176       case Operation::kBitwiseXor:
177       case Operation::kShiftRight:
178         return true;
179       default:
180         return false;
181     }
182   }
183 };
184 
185 }  // namespace internal
186 }  // namespace v8
187 
188 #endif  // V8_IC_BINARY_OP_ASSEMBLER_H_
189