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