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#include "src/builtins/builtins-utils-gen.h"
6#include "src/builtins/builtins.h"
7#include "src/codegen/code-stub-assembler.h"
8#include "src/ic/binary-op-assembler.h"
9#include "src/ic/unary-op-assembler.h"
10
11namespace v8 {
12namespace internal {
13
14// -----------------------------------------------------------------------------
15// ES6 section 20.1 Number Objects
16
17#define DEF_BINOP(Name, Generator)                                           \
18  TF_BUILTIN(Name, CodeStubAssembler) {                                      \
19    auto lhs = Parameter<Object>(Descriptor::kLeft);                         \
20    auto rhs = Parameter<Object>(Descriptor::kRight);                        \
21    auto context = Parameter<Context>(Descriptor::kContext);                 \
22    auto feedback_vector =                                                   \
23        Parameter<FeedbackVector>(Descriptor::kFeedbackVector);              \
24    auto slot = UncheckedParameter<UintPtrT>(Descriptor::kSlot);             \
25                                                                             \
26    BinaryOpAssembler binop_asm(state());                                    \
27    TNode<Object> result =                                                   \
28        binop_asm.Generator([&]() { return context; }, lhs, rhs, slot,       \
29                            [&]() { return feedback_vector; },               \
30                            UpdateFeedbackMode::kGuaranteedFeedback, false); \
31                                                                             \
32    Return(result);                                                          \
33  }
34DEF_BINOP(Add_WithFeedback, Generate_AddWithFeedback)
35DEF_BINOP(Subtract_WithFeedback, Generate_SubtractWithFeedback)
36DEF_BINOP(Multiply_WithFeedback, Generate_MultiplyWithFeedback)
37DEF_BINOP(Divide_WithFeedback, Generate_DivideWithFeedback)
38DEF_BINOP(Modulus_WithFeedback, Generate_ModulusWithFeedback)
39DEF_BINOP(Exponentiate_WithFeedback, Generate_ExponentiateWithFeedback)
40DEF_BINOP(BitwiseOr_WithFeedback, Generate_BitwiseOrWithFeedback)
41DEF_BINOP(BitwiseXor_WithFeedback, Generate_BitwiseXorWithFeedback)
42DEF_BINOP(BitwiseAnd_WithFeedback, Generate_BitwiseAndWithFeedback)
43DEF_BINOP(ShiftLeft_WithFeedback, Generate_ShiftLeftWithFeedback)
44DEF_BINOP(ShiftRight_WithFeedback, Generate_ShiftRightWithFeedback)
45DEF_BINOP(ShiftRightLogical_WithFeedback,
46          Generate_ShiftRightLogicalWithFeedback)
47#undef DEF_BINOP
48
49#define DEF_BINOP(Name, Generator)                                   \
50  TF_BUILTIN(Name, CodeStubAssembler) {                              \
51    auto lhs = Parameter<Object>(Descriptor::kLeft);                 \
52    auto rhs = Parameter<Object>(Descriptor::kRight);                \
53    auto slot = UncheckedParameter<UintPtrT>(Descriptor::kSlot);     \
54                                                                     \
55    BinaryOpAssembler binop_asm(state());                            \
56    TNode<Object> result = binop_asm.Generator(                      \
57        [&]() { return LoadContextFromBaseline(); }, lhs, rhs, slot, \
58        [&]() { return LoadFeedbackVectorFromBaseline(); },          \
59        UpdateFeedbackMode::kGuaranteedFeedback, false);             \
60                                                                     \
61    Return(result);                                                  \
62  }
63DEF_BINOP(Add_Baseline, Generate_AddWithFeedback)
64DEF_BINOP(Subtract_Baseline, Generate_SubtractWithFeedback)
65DEF_BINOP(Multiply_Baseline, Generate_MultiplyWithFeedback)
66DEF_BINOP(Divide_Baseline, Generate_DivideWithFeedback)
67DEF_BINOP(Modulus_Baseline, Generate_ModulusWithFeedback)
68DEF_BINOP(Exponentiate_Baseline, Generate_ExponentiateWithFeedback)
69DEF_BINOP(BitwiseOr_Baseline, Generate_BitwiseOrWithFeedback)
70DEF_BINOP(BitwiseXor_Baseline, Generate_BitwiseXorWithFeedback)
71DEF_BINOP(BitwiseAnd_Baseline, Generate_BitwiseAndWithFeedback)
72DEF_BINOP(ShiftLeft_Baseline, Generate_ShiftLeftWithFeedback)
73DEF_BINOP(ShiftRight_Baseline, Generate_ShiftRightWithFeedback)
74DEF_BINOP(ShiftRightLogical_Baseline, Generate_ShiftRightLogicalWithFeedback)
75#undef DEF_BINOP
76
77#define DEF_BINOP_RHS_SMI(Name, Generator)                           \
78  TF_BUILTIN(Name, CodeStubAssembler) {                              \
79    auto lhs = Parameter<Object>(Descriptor::kLeft);                 \
80    auto rhs = Parameter<Object>(Descriptor::kRight);                \
81    auto slot = UncheckedParameter<UintPtrT>(Descriptor::kSlot);     \
82                                                                     \
83    BinaryOpAssembler binop_asm(state());                            \
84    TNode<Object> result = binop_asm.Generator(                      \
85        [&]() { return LoadContextFromBaseline(); }, lhs, rhs, slot, \
86        [&]() { return LoadFeedbackVectorFromBaseline(); },          \
87        UpdateFeedbackMode::kGuaranteedFeedback, true);              \
88                                                                     \
89    Return(result);                                                  \
90  }
91DEF_BINOP_RHS_SMI(AddSmi_Baseline, Generate_AddWithFeedback)
92DEF_BINOP_RHS_SMI(SubtractSmi_Baseline, Generate_SubtractWithFeedback)
93DEF_BINOP_RHS_SMI(MultiplySmi_Baseline, Generate_MultiplyWithFeedback)
94DEF_BINOP_RHS_SMI(DivideSmi_Baseline, Generate_DivideWithFeedback)
95DEF_BINOP_RHS_SMI(ModulusSmi_Baseline, Generate_ModulusWithFeedback)
96DEF_BINOP_RHS_SMI(ExponentiateSmi_Baseline, Generate_ExponentiateWithFeedback)
97DEF_BINOP_RHS_SMI(BitwiseOrSmi_Baseline, Generate_BitwiseOrWithFeedback)
98DEF_BINOP_RHS_SMI(BitwiseXorSmi_Baseline, Generate_BitwiseXorWithFeedback)
99DEF_BINOP_RHS_SMI(BitwiseAndSmi_Baseline, Generate_BitwiseAndWithFeedback)
100DEF_BINOP_RHS_SMI(ShiftLeftSmi_Baseline, Generate_ShiftLeftWithFeedback)
101DEF_BINOP_RHS_SMI(ShiftRightSmi_Baseline, Generate_ShiftRightWithFeedback)
102DEF_BINOP_RHS_SMI(ShiftRightLogicalSmi_Baseline,
103                  Generate_ShiftRightLogicalWithFeedback)
104#undef DEF_BINOP_RHS_SMI
105
106#define DEF_UNOP(Name, Generator)                                \
107  TF_BUILTIN(Name, CodeStubAssembler) {                          \
108    auto value = Parameter<Object>(Descriptor::kValue);          \
109    auto context = Parameter<Context>(Descriptor::kContext);     \
110    auto feedback_vector =                                       \
111        Parameter<FeedbackVector>(Descriptor::kFeedbackVector);  \
112    auto slot = UncheckedParameter<UintPtrT>(Descriptor::kSlot); \
113                                                                 \
114    UnaryOpAssembler a(state());                                 \
115    TNode<Object> result =                                       \
116        a.Generator(context, value, slot, feedback_vector,       \
117                    UpdateFeedbackMode::kGuaranteedFeedback);    \
118                                                                 \
119    Return(result);                                              \
120  }
121DEF_UNOP(BitwiseNot_WithFeedback, Generate_BitwiseNotWithFeedback)
122DEF_UNOP(Decrement_WithFeedback, Generate_DecrementWithFeedback)
123DEF_UNOP(Increment_WithFeedback, Generate_IncrementWithFeedback)
124DEF_UNOP(Negate_WithFeedback, Generate_NegateWithFeedback)
125#undef DEF_UNOP
126
127#define DEF_UNOP(Name, Generator)                                \
128  TF_BUILTIN(Name, CodeStubAssembler) {                          \
129    auto value = Parameter<Object>(Descriptor::kValue);          \
130    auto context = LoadContextFromBaseline();                    \
131    auto feedback_vector = LoadFeedbackVectorFromBaseline();     \
132    auto slot = UncheckedParameter<UintPtrT>(Descriptor::kSlot); \
133                                                                 \
134    UnaryOpAssembler a(state());                                 \
135    TNode<Object> result =                                       \
136        a.Generator(context, value, slot, feedback_vector,       \
137                    UpdateFeedbackMode::kGuaranteedFeedback);    \
138                                                                 \
139    Return(result);                                              \
140  }
141DEF_UNOP(BitwiseNot_Baseline, Generate_BitwiseNotWithFeedback)
142DEF_UNOP(Decrement_Baseline, Generate_DecrementWithFeedback)
143DEF_UNOP(Increment_Baseline, Generate_IncrementWithFeedback)
144DEF_UNOP(Negate_Baseline, Generate_NegateWithFeedback)
145#undef DEF_UNOP
146
147#define DEF_COMPARE(Name)                                                      \
148  TF_BUILTIN(Name##_WithFeedback, CodeStubAssembler) {                         \
149    auto lhs = Parameter<Object>(Descriptor::kLeft);                           \
150    auto rhs = Parameter<Object>(Descriptor::kRight);                          \
151    auto context = Parameter<Context>(Descriptor::kContext);                   \
152    auto feedback_vector =                                                     \
153        Parameter<FeedbackVector>(Descriptor::kFeedbackVector);                \
154    auto slot = UncheckedParameter<UintPtrT>(Descriptor::kSlot);               \
155                                                                               \
156    TVARIABLE(Smi, var_type_feedback);                                         \
157    TNode<Oddball> result = RelationalComparison(Operation::k##Name, lhs, rhs, \
158                                                 context, &var_type_feedback); \
159    UpdateFeedback(var_type_feedback.value(), feedback_vector, slot);          \
160                                                                               \
161    Return(result);                                                            \
162  }
163DEF_COMPARE(LessThan)
164DEF_COMPARE(LessThanOrEqual)
165DEF_COMPARE(GreaterThan)
166DEF_COMPARE(GreaterThanOrEqual)
167#undef DEF_COMPARE
168
169#define DEF_COMPARE(Name)                                                 \
170  TF_BUILTIN(Name##_Baseline, CodeStubAssembler) {                        \
171    auto lhs = Parameter<Object>(Descriptor::kLeft);                      \
172    auto rhs = Parameter<Object>(Descriptor::kRight);                     \
173    auto slot = UncheckedParameter<UintPtrT>(Descriptor::kSlot);          \
174                                                                          \
175    TVARIABLE(Smi, var_type_feedback);                                    \
176    TNode<Oddball> result = RelationalComparison(                         \
177        Operation::k##Name, lhs, rhs,                                     \
178        [&]() { return LoadContextFromBaseline(); }, &var_type_feedback); \
179    auto feedback_vector = LoadFeedbackVectorFromBaseline();              \
180    UpdateFeedback(var_type_feedback.value(), feedback_vector, slot);     \
181                                                                          \
182    Return(result);                                                       \
183  }
184DEF_COMPARE(LessThan)
185DEF_COMPARE(LessThanOrEqual)
186DEF_COMPARE(GreaterThan)
187DEF_COMPARE(GreaterThanOrEqual)
188#undef DEF_COMPARE
189
190TF_BUILTIN(Equal_WithFeedback, CodeStubAssembler) {
191  auto lhs = Parameter<Object>(Descriptor::kLeft);
192  auto rhs = Parameter<Object>(Descriptor::kRight);
193  auto context = Parameter<Context>(Descriptor::kContext);
194  auto feedback_vector = Parameter<FeedbackVector>(Descriptor::kFeedbackVector);
195  auto slot = UncheckedParameter<UintPtrT>(Descriptor::kSlot);
196
197  TVARIABLE(Smi, var_type_feedback);
198  TNode<Oddball> result = Equal(
199      lhs, rhs, [&]() { return context; }, &var_type_feedback);
200  UpdateFeedback(var_type_feedback.value(), feedback_vector, slot);
201
202  Return(result);
203}
204
205TF_BUILTIN(StrictEqual_WithFeedback, CodeStubAssembler) {
206  auto lhs = Parameter<Object>(Descriptor::kLeft);
207  auto rhs = Parameter<Object>(Descriptor::kRight);
208  auto feedback_vector = Parameter<FeedbackVector>(Descriptor::kFeedbackVector);
209  auto slot = UncheckedParameter<UintPtrT>(Descriptor::kSlot);
210
211  TVARIABLE(Smi, var_type_feedback);
212  TNode<Oddball> result = StrictEqual(lhs, rhs, &var_type_feedback);
213  UpdateFeedback(var_type_feedback.value(), feedback_vector, slot);
214
215  Return(result);
216}
217
218TF_BUILTIN(Equal_Baseline, CodeStubAssembler) {
219  auto lhs = Parameter<Object>(Descriptor::kLeft);
220  auto rhs = Parameter<Object>(Descriptor::kRight);
221  auto slot = UncheckedParameter<UintPtrT>(Descriptor::kSlot);
222
223  TVARIABLE(Smi, var_type_feedback);
224  TNode<Oddball> result = Equal(
225      lhs, rhs, [&]() { return LoadContextFromBaseline(); },
226      &var_type_feedback);
227  auto feedback_vector = LoadFeedbackVectorFromBaseline();
228  UpdateFeedback(var_type_feedback.value(), feedback_vector, slot);
229
230  Return(result);
231}
232
233TF_BUILTIN(StrictEqual_Baseline, CodeStubAssembler) {
234  auto lhs = Parameter<Object>(Descriptor::kLeft);
235  auto rhs = Parameter<Object>(Descriptor::kRight);
236  auto slot = UncheckedParameter<UintPtrT>(Descriptor::kSlot);
237
238  TVARIABLE(Smi, var_type_feedback);
239  TNode<Oddball> result = StrictEqual(lhs, rhs, &var_type_feedback);
240  auto feedback_vector = LoadFeedbackVectorFromBaseline();
241  UpdateFeedback(var_type_feedback.value(), feedback_vector, slot);
242
243  Return(result);
244}
245
246}  // namespace internal
247}  // namespace v8
248