Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(294)

Side by Side Diff: src/builtins/builtins-number.cc

Issue 2529873002: Revert of [cleanup] Refactor builtins-number.cc (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/builtins/builtins-utils.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/builtins/builtins-utils.h" 5 #include "src/builtins/builtins-utils.h"
6 #include "src/builtins/builtins.h" 6 #include "src/builtins/builtins.h"
7 #include "src/code-factory.h" 7 #include "src/code-factory.h"
8 #include "src/code-stub-assembler.h"
9 8
10 namespace v8 { 9 namespace v8 {
11 namespace internal { 10 namespace internal {
12 11
13 class NumberBuiltinsAssembler : public CodeStubAssembler {
14 public:
15 explicit NumberBuiltinsAssembler(compiler::CodeAssemblerState* state)
16 : CodeStubAssembler(state) {}
17
18 protected:
19 template <Signedness signed_result = kSigned>
20 void BitwiseOp(std::function<Node*(Node* lhs, Node* rhs)> body) {
21 Node* left = Parameter(0);
22 Node* right = Parameter(1);
23 Node* context = Parameter(2);
24
25 Node* lhs_value = TruncateTaggedToWord32(context, left);
26 Node* rhs_value = TruncateTaggedToWord32(context, right);
27 Node* value = body(lhs_value, rhs_value);
28 Node* result = signed_result == kSigned ? ChangeInt32ToTagged(value)
29 : ChangeUint32ToTagged(value);
30 Return(result);
31 }
32
33 template <Signedness signed_result = kSigned>
34 void BitwiseShiftOp(std::function<Node*(Node* lhs, Node* shift_count)> body) {
35 BitwiseOp<signed_result>([this, body](Node* lhs, Node* rhs) {
36 Node* shift_count = Word32And(rhs, Int32Constant(0x1f));
37 return body(lhs, shift_count);
38 });
39 }
40
41 void RelationalComparisonBuiltin(RelationalComparisonMode mode) {
42 Node* lhs = Parameter(0);
43 Node* rhs = Parameter(1);
44 Node* context = Parameter(2);
45
46 Return(RelationalComparison(mode, lhs, rhs, context));
47 }
48 };
49
50 // ----------------------------------------------------------------------------- 12 // -----------------------------------------------------------------------------
51 // ES6 section 20.1 Number Objects 13 // ES6 section 20.1 Number Objects
52 14
53 // ES6 section 20.1.2.2 Number.isFinite ( number ) 15 // ES6 section 20.1.2.2 Number.isFinite ( number )
54 TF_BUILTIN(NumberIsFinite, CodeStubAssembler) { 16 void Builtins::Generate_NumberIsFinite(compiler::CodeAssemblerState* state) {
55 Node* number = Parameter(1); 17 typedef CodeStubAssembler::Label Label;
56 18 typedef compiler::Node Node;
57 Label return_true(this), return_false(this); 19 CodeStubAssembler assembler(state);
58 20
59 // Check if {number} is a Smi. 21 Node* number = assembler.Parameter(1);
60 GotoIf(TaggedIsSmi(number), &return_true); 22
61 23 Label return_true(&assembler), return_false(&assembler);
62 // Check if {number} is a HeapNumber. 24
63 GotoUnless(IsHeapNumberMap(LoadMap(number)), &return_false); 25 // Check if {number} is a Smi.
26 assembler.GotoIf(assembler.TaggedIsSmi(number), &return_true);
27
28 // Check if {number} is a HeapNumber.
29 assembler.GotoUnless(assembler.WordEqual(assembler.LoadMap(number),
30 assembler.HeapNumberMapConstant()),
31 &return_false);
64 32
65 // Check if {number} contains a finite, non-NaN value. 33 // Check if {number} contains a finite, non-NaN value.
66 Node* number_value = LoadHeapNumberValue(number); 34 Node* number_value = assembler.LoadHeapNumberValue(number);
67 BranchIfFloat64IsNaN(Float64Sub(number_value, number_value), &return_false, 35 assembler.BranchIfFloat64IsNaN(
68 &return_true); 36 assembler.Float64Sub(number_value, number_value), &return_false,
69 37 &return_true);
70 Bind(&return_true); 38
71 Return(BooleanConstant(true)); 39 assembler.Bind(&return_true);
72 40 assembler.Return(assembler.BooleanConstant(true));
73 Bind(&return_false); 41
74 Return(BooleanConstant(false)); 42 assembler.Bind(&return_false);
43 assembler.Return(assembler.BooleanConstant(false));
75 } 44 }
76 45
77 // ES6 section 20.1.2.3 Number.isInteger ( number ) 46 // ES6 section 20.1.2.3 Number.isInteger ( number )
78 TF_BUILTIN(NumberIsInteger, CodeStubAssembler) { 47 void Builtins::Generate_NumberIsInteger(compiler::CodeAssemblerState* state) {
79 Node* number = Parameter(1); 48 typedef CodeStubAssembler::Label Label;
80 49 typedef compiler::Node Node;
81 Label return_true(this), return_false(this); 50 CodeStubAssembler assembler(state);
82 51
83 // Check if {number} is a Smi. 52 Node* number = assembler.Parameter(1);
84 GotoIf(TaggedIsSmi(number), &return_true); 53
85 54 Label return_true(&assembler), return_false(&assembler);
86 // Check if {number} is a HeapNumber. 55
87 GotoUnless(IsHeapNumberMap(LoadMap(number)), &return_false); 56 // Check if {number} is a Smi.
57 assembler.GotoIf(assembler.TaggedIsSmi(number), &return_true);
58
59 // Check if {number} is a HeapNumber.
60 assembler.GotoUnless(assembler.WordEqual(assembler.LoadMap(number),
61 assembler.HeapNumberMapConstant()),
62 &return_false);
88 63
89 // Load the actual value of {number}. 64 // Load the actual value of {number}.
90 Node* number_value = LoadHeapNumberValue(number); 65 Node* number_value = assembler.LoadHeapNumberValue(number);
91 66
92 // Truncate the value of {number} to an integer (or an infinity). 67 // Truncate the value of {number} to an integer (or an infinity).
93 Node* integer = Float64Trunc(number_value); 68 Node* integer = assembler.Float64Trunc(number_value);
94 69
95 // Check if {number}s value matches the integer (ruling out the infinities). 70 // Check if {number}s value matches the integer (ruling out the infinities).
96 Branch(Float64Equal(Float64Sub(number_value, integer), Float64Constant(0.0)), 71 assembler.Branch(
97 &return_true, &return_false); 72 assembler.Float64Equal(assembler.Float64Sub(number_value, integer),
98 73 assembler.Float64Constant(0.0)),
99 Bind(&return_true); 74 &return_true, &return_false);
100 Return(BooleanConstant(true)); 75
101 76 assembler.Bind(&return_true);
102 Bind(&return_false); 77 assembler.Return(assembler.BooleanConstant(true));
103 Return(BooleanConstant(false)); 78
79 assembler.Bind(&return_false);
80 assembler.Return(assembler.BooleanConstant(false));
104 } 81 }
105 82
106 // ES6 section 20.1.2.4 Number.isNaN ( number ) 83 // ES6 section 20.1.2.4 Number.isNaN ( number )
107 TF_BUILTIN(NumberIsNaN, CodeStubAssembler) { 84 void Builtins::Generate_NumberIsNaN(compiler::CodeAssemblerState* state) {
108 Node* number = Parameter(1); 85 typedef CodeStubAssembler::Label Label;
109 86 typedef compiler::Node Node;
110 Label return_true(this), return_false(this); 87 CodeStubAssembler assembler(state);
111 88
112 // Check if {number} is a Smi. 89 Node* number = assembler.Parameter(1);
113 GotoIf(TaggedIsSmi(number), &return_false); 90
114 91 Label return_true(&assembler), return_false(&assembler);
115 // Check if {number} is a HeapNumber. 92
116 GotoUnless(IsHeapNumberMap(LoadMap(number)), &return_false); 93 // Check if {number} is a Smi.
94 assembler.GotoIf(assembler.TaggedIsSmi(number), &return_false);
95
96 // Check if {number} is a HeapNumber.
97 assembler.GotoUnless(assembler.WordEqual(assembler.LoadMap(number),
98 assembler.HeapNumberMapConstant()),
99 &return_false);
117 100
118 // Check if {number} contains a NaN value. 101 // Check if {number} contains a NaN value.
119 Node* number_value = LoadHeapNumberValue(number); 102 Node* number_value = assembler.LoadHeapNumberValue(number);
120 BranchIfFloat64IsNaN(number_value, &return_true, &return_false); 103 assembler.BranchIfFloat64IsNaN(number_value, &return_true, &return_false);
121 104
122 Bind(&return_true); 105 assembler.Bind(&return_true);
123 Return(BooleanConstant(true)); 106 assembler.Return(assembler.BooleanConstant(true));
124 107
125 Bind(&return_false); 108 assembler.Bind(&return_false);
126 Return(BooleanConstant(false)); 109 assembler.Return(assembler.BooleanConstant(false));
127 } 110 }
128 111
129 // ES6 section 20.1.2.5 Number.isSafeInteger ( number ) 112 // ES6 section 20.1.2.5 Number.isSafeInteger ( number )
130 TF_BUILTIN(NumberIsSafeInteger, CodeStubAssembler) { 113 void Builtins::Generate_NumberIsSafeInteger(
131 Node* number = Parameter(1); 114 compiler::CodeAssemblerState* state) {
132 115 typedef CodeStubAssembler::Label Label;
133 Label return_true(this), return_false(this); 116 typedef compiler::Node Node;
134 117 CodeStubAssembler assembler(state);
135 // Check if {number} is a Smi. 118
136 GotoIf(TaggedIsSmi(number), &return_true); 119 Node* number = assembler.Parameter(1);
137 120
138 // Check if {number} is a HeapNumber. 121 Label return_true(&assembler), return_false(&assembler);
139 GotoUnless(IsHeapNumberMap(LoadMap(number)), &return_false); 122
123 // Check if {number} is a Smi.
124 assembler.GotoIf(assembler.TaggedIsSmi(number), &return_true);
125
126 // Check if {number} is a HeapNumber.
127 assembler.GotoUnless(assembler.WordEqual(assembler.LoadMap(number),
128 assembler.HeapNumberMapConstant()),
129 &return_false);
140 130
141 // Load the actual value of {number}. 131 // Load the actual value of {number}.
142 Node* number_value = LoadHeapNumberValue(number); 132 Node* number_value = assembler.LoadHeapNumberValue(number);
143 133
144 // Truncate the value of {number} to an integer (or an infinity). 134 // Truncate the value of {number} to an integer (or an infinity).
145 Node* integer = Float64Trunc(number_value); 135 Node* integer = assembler.Float64Trunc(number_value);
146 136
147 // Check if {number}s value matches the integer (ruling out the infinities). 137 // Check if {number}s value matches the integer (ruling out the infinities).
148 GotoUnless( 138 assembler.GotoUnless(
149 Float64Equal(Float64Sub(number_value, integer), Float64Constant(0.0)), 139 assembler.Float64Equal(assembler.Float64Sub(number_value, integer),
140 assembler.Float64Constant(0.0)),
150 &return_false); 141 &return_false);
151 142
152 // Check if the {integer} value is in safe integer range. 143 // Check if the {integer} value is in safe integer range.
153 Branch(Float64LessThanOrEqual(Float64Abs(integer), 144 assembler.Branch(assembler.Float64LessThanOrEqual(
154 Float64Constant(kMaxSafeInteger)), 145 assembler.Float64Abs(integer),
155 &return_true, &return_false); 146 assembler.Float64Constant(kMaxSafeInteger)),
156 147 &return_true, &return_false);
157 Bind(&return_true); 148
158 Return(BooleanConstant(true)); 149 assembler.Bind(&return_true);
159 150 assembler.Return(assembler.BooleanConstant(true));
160 Bind(&return_false); 151
161 Return(BooleanConstant(false)); 152 assembler.Bind(&return_false);
153 assembler.Return(assembler.BooleanConstant(false));
162 } 154 }
163 155
164 // ES6 section 20.1.2.12 Number.parseFloat ( string ) 156 // ES6 section 20.1.2.12 Number.parseFloat ( string )
165 TF_BUILTIN(NumberParseFloat, CodeStubAssembler) { 157 void Builtins::Generate_NumberParseFloat(compiler::CodeAssemblerState* state) {
166 Node* context = Parameter(4); 158 typedef CodeStubAssembler::Label Label;
159 typedef compiler::Node Node;
160 typedef CodeStubAssembler::Variable Variable;
161 CodeStubAssembler assembler(state);
162
163 Node* context = assembler.Parameter(4);
167 164
168 // We might need to loop once for ToString conversion. 165 // We might need to loop once for ToString conversion.
169 Variable var_input(this, MachineRepresentation::kTagged); 166 Variable var_input(&assembler, MachineRepresentation::kTagged);
170 Label loop(this, &var_input); 167 Label loop(&assembler, &var_input);
171 var_input.Bind(Parameter(1)); 168 var_input.Bind(assembler.Parameter(1));
172 Goto(&loop); 169 assembler.Goto(&loop);
173 Bind(&loop); 170 assembler.Bind(&loop);
174 { 171 {
175 // Load the current {input} value. 172 // Load the current {input} value.
176 Node* input = var_input.value(); 173 Node* input = var_input.value();
177 174
178 // Check if the {input} is a HeapObject or a Smi. 175 // Check if the {input} is a HeapObject or a Smi.
179 Label if_inputissmi(this), if_inputisnotsmi(this); 176 Label if_inputissmi(&assembler), if_inputisnotsmi(&assembler);
180 Branch(TaggedIsSmi(input), &if_inputissmi, &if_inputisnotsmi); 177 assembler.Branch(assembler.TaggedIsSmi(input), &if_inputissmi,
181 178 &if_inputisnotsmi);
182 Bind(&if_inputissmi); 179
180 assembler.Bind(&if_inputissmi);
183 { 181 {
184 // The {input} is already a Number, no need to do anything. 182 // The {input} is already a Number, no need to do anything.
185 Return(input); 183 assembler.Return(input);
186 } 184 }
187 185
188 Bind(&if_inputisnotsmi); 186 assembler.Bind(&if_inputisnotsmi);
189 { 187 {
190 // The {input} is a HeapObject, check if it's already a String. 188 // The {input} is a HeapObject, check if it's already a String.
191 Label if_inputisstring(this), if_inputisnotstring(this); 189 Label if_inputisstring(&assembler), if_inputisnotstring(&assembler);
192 Node* input_map = LoadMap(input); 190 Node* input_map = assembler.LoadMap(input);
193 Node* input_instance_type = LoadMapInstanceType(input_map); 191 Node* input_instance_type = assembler.LoadMapInstanceType(input_map);
194 Branch(IsStringInstanceType(input_instance_type), &if_inputisstring, 192 assembler.Branch(assembler.IsStringInstanceType(input_instance_type),
195 &if_inputisnotstring); 193 &if_inputisstring, &if_inputisnotstring);
196 194
197 Bind(&if_inputisstring); 195 assembler.Bind(&if_inputisstring);
198 { 196 {
199 // The {input} is already a String, check if {input} contains 197 // The {input} is already a String, check if {input} contains
200 // a cached array index. 198 // a cached array index.
201 Label if_inputcached(this), if_inputnotcached(this); 199 Label if_inputcached(&assembler), if_inputnotcached(&assembler);
202 Node* input_hash = LoadNameHashField(input); 200 Node* input_hash = assembler.LoadNameHashField(input);
203 Node* input_bit = Word32And( 201 Node* input_bit = assembler.Word32And(
204 input_hash, Int32Constant(String::kContainsCachedArrayIndexMask)); 202 input_hash,
205 Branch(Word32Equal(input_bit, Int32Constant(0)), &if_inputcached, 203 assembler.Int32Constant(String::kContainsCachedArrayIndexMask));
206 &if_inputnotcached); 204 assembler.Branch(
207 205 assembler.Word32Equal(input_bit, assembler.Int32Constant(0)),
208 Bind(&if_inputcached); 206 &if_inputcached, &if_inputnotcached);
207
208 assembler.Bind(&if_inputcached);
209 { 209 {
210 // Just return the {input}s cached array index. 210 // Just return the {input}s cached array index.
211 Node* input_array_index = 211 Node* input_array_index =
212 DecodeWordFromWord32<String::ArrayIndexValueBits>(input_hash); 212 assembler.DecodeWordFromWord32<String::ArrayIndexValueBits>(
213 Return(SmiTag(input_array_index)); 213 input_hash);
214 } 214 assembler.Return(assembler.SmiTag(input_array_index));
215 215 }
216 Bind(&if_inputnotcached); 216
217 assembler.Bind(&if_inputnotcached);
217 { 218 {
218 // Need to fall back to the runtime to convert {input} to double. 219 // Need to fall back to the runtime to convert {input} to double.
219 Return(CallRuntime(Runtime::kStringParseFloat, context, input)); 220 assembler.Return(assembler.CallRuntime(Runtime::kStringParseFloat,
221 context, input));
220 } 222 }
221 } 223 }
222 224
223 Bind(&if_inputisnotstring); 225 assembler.Bind(&if_inputisnotstring);
224 { 226 {
225 // The {input} is neither a String nor a Smi, check for HeapNumber. 227 // The {input} is neither a String nor a Smi, check for HeapNumber.
226 Label if_inputisnumber(this), 228 Label if_inputisnumber(&assembler),
227 if_inputisnotnumber(this, Label::kDeferred); 229 if_inputisnotnumber(&assembler, Label::kDeferred);
228 Branch(IsHeapNumberMap(input_map), &if_inputisnumber, 230 assembler.Branch(
229 &if_inputisnotnumber); 231 assembler.WordEqual(input_map, assembler.HeapNumberMapConstant()),
230 232 &if_inputisnumber, &if_inputisnotnumber);
231 Bind(&if_inputisnumber); 233
234 assembler.Bind(&if_inputisnumber);
232 { 235 {
233 // The {input} is already a Number, take care of -0. 236 // The {input} is already a Number, take care of -0.
234 Label if_inputiszero(this), if_inputisnotzero(this); 237 Label if_inputiszero(&assembler), if_inputisnotzero(&assembler);
235 Node* input_value = LoadHeapNumberValue(input); 238 Node* input_value = assembler.LoadHeapNumberValue(input);
236 Branch(Float64Equal(input_value, Float64Constant(0.0)), 239 assembler.Branch(assembler.Float64Equal(
237 &if_inputiszero, &if_inputisnotzero); 240 input_value, assembler.Float64Constant(0.0)),
238 241 &if_inputiszero, &if_inputisnotzero);
239 Bind(&if_inputiszero); 242
240 Return(SmiConstant(0)); 243 assembler.Bind(&if_inputiszero);
241 244 assembler.Return(assembler.SmiConstant(0));
242 Bind(&if_inputisnotzero); 245
243 Return(input); 246 assembler.Bind(&if_inputisnotzero);
244 } 247 assembler.Return(input);
245 248 }
246 Bind(&if_inputisnotnumber); 249
250 assembler.Bind(&if_inputisnotnumber);
247 { 251 {
248 // Need to convert the {input} to String first. 252 // Need to convert the {input} to String first.
249 // TODO(bmeurer): This could be more efficient if necessary. 253 // TODO(bmeurer): This could be more efficient if necessary.
250 Callable callable = CodeFactory::ToString(isolate()); 254 Callable callable = CodeFactory::ToString(assembler.isolate());
251 var_input.Bind(CallStub(callable, context, input)); 255 var_input.Bind(assembler.CallStub(callable, context, input));
252 Goto(&loop); 256 assembler.Goto(&loop);
253 } 257 }
254 } 258 }
255 } 259 }
256 } 260 }
257 } 261 }
258 262
259 // ES6 section 20.1.2.13 Number.parseInt ( string, radix ) 263 // ES6 section 20.1.2.13 Number.parseInt ( string, radix )
260 TF_BUILTIN(NumberParseInt, CodeStubAssembler) { 264 void Builtins::Generate_NumberParseInt(compiler::CodeAssemblerState* state) {
261 Node* input = Parameter(1); 265 typedef CodeStubAssembler::Label Label;
262 Node* radix = Parameter(2); 266 typedef compiler::Node Node;
263 Node* context = Parameter(5); 267 CodeStubAssembler assembler(state);
268
269 Node* input = assembler.Parameter(1);
270 Node* radix = assembler.Parameter(2);
271 Node* context = assembler.Parameter(5);
264 272
265 // Check if {radix} is treated as 10 (i.e. undefined, 0 or 10). 273 // Check if {radix} is treated as 10 (i.e. undefined, 0 or 10).
266 Label if_radix10(this), if_generic(this, Label::kDeferred); 274 Label if_radix10(&assembler), if_generic(&assembler, Label::kDeferred);
267 GotoIf(WordEqual(radix, UndefinedConstant()), &if_radix10); 275 assembler.GotoIf(assembler.WordEqual(radix, assembler.UndefinedConstant()),
268 GotoIf(WordEqual(radix, SmiConstant(Smi::FromInt(10))), &if_radix10); 276 &if_radix10);
269 GotoIf(WordEqual(radix, SmiConstant(Smi::FromInt(0))), &if_radix10); 277 assembler.GotoIf(
270 Goto(&if_generic); 278 assembler.WordEqual(radix, assembler.SmiConstant(Smi::FromInt(10))),
279 &if_radix10);
280 assembler.GotoIf(
281 assembler.WordEqual(radix, assembler.SmiConstant(Smi::FromInt(0))),
282 &if_radix10);
283 assembler.Goto(&if_generic);
271 284
272 Bind(&if_radix10); 285 assembler.Bind(&if_radix10);
273 { 286 {
274 // Check if we can avoid the ToString conversion on {input}. 287 // Check if we can avoid the ToString conversion on {input}.
275 Label if_inputissmi(this), if_inputisheapnumber(this), 288 Label if_inputissmi(&assembler), if_inputisheapnumber(&assembler),
276 if_inputisstring(this); 289 if_inputisstring(&assembler);
277 GotoIf(TaggedIsSmi(input), &if_inputissmi); 290 assembler.GotoIf(assembler.TaggedIsSmi(input), &if_inputissmi);
278 Node* input_map = LoadMap(input); 291 Node* input_map = assembler.LoadMap(input);
279 GotoIf(IsHeapNumberMap(input_map), &if_inputisheapnumber); 292 assembler.GotoIf(
280 Node* input_instance_type = LoadMapInstanceType(input_map); 293 assembler.WordEqual(input_map, assembler.HeapNumberMapConstant()),
281 Branch(IsStringInstanceType(input_instance_type), &if_inputisstring, 294 &if_inputisheapnumber);
282 &if_generic); 295 Node* input_instance_type = assembler.LoadMapInstanceType(input_map);
296 assembler.Branch(assembler.IsStringInstanceType(input_instance_type),
297 &if_inputisstring, &if_generic);
283 298
284 Bind(&if_inputissmi); 299 assembler.Bind(&if_inputissmi);
285 { 300 {
286 // Just return the {input}. 301 // Just return the {input}.
287 Return(input); 302 assembler.Return(input);
288 } 303 }
289 304
290 Bind(&if_inputisheapnumber); 305 assembler.Bind(&if_inputisheapnumber);
291 { 306 {
292 // Check if the {input} value is in Signed32 range. 307 // Check if the {input} value is in Signed32 range.
293 Label if_inputissigned32(this); 308 Label if_inputissigned32(&assembler);
294 Node* input_value = LoadHeapNumberValue(input); 309 Node* input_value = assembler.LoadHeapNumberValue(input);
295 Node* input_value32 = TruncateFloat64ToWord32(input_value); 310 Node* input_value32 = assembler.TruncateFloat64ToWord32(input_value);
296 GotoIf(Float64Equal(input_value, ChangeInt32ToFloat64(input_value32)), 311 assembler.GotoIf(
297 &if_inputissigned32); 312 assembler.Float64Equal(input_value,
313 assembler.ChangeInt32ToFloat64(input_value32)),
314 &if_inputissigned32);
298 315
299 // Check if the absolute {input} value is in the ]0.01,1e9[ range. 316 // Check if the absolute {input} value is in the ]0.01,1e9[ range.
300 Node* input_value_abs = Float64Abs(input_value); 317 Node* input_value_abs = assembler.Float64Abs(input_value);
301 318
302 GotoUnless(Float64LessThan(input_value_abs, Float64Constant(1e9)), 319 assembler.GotoUnless(assembler.Float64LessThan(
303 &if_generic); 320 input_value_abs, assembler.Float64Constant(1e9)),
304 Branch(Float64LessThan(Float64Constant(0.01), input_value_abs), 321 &if_generic);
305 &if_inputissigned32, &if_generic); 322 assembler.Branch(assembler.Float64LessThan(
323 assembler.Float64Constant(0.01), input_value_abs),
324 &if_inputissigned32, &if_generic);
306 325
307 // Return the truncated int32 value, and return the tagged result. 326 // Return the truncated int32 value, and return the tagged result.
308 Bind(&if_inputissigned32); 327 assembler.Bind(&if_inputissigned32);
309 Node* result = ChangeInt32ToTagged(input_value32); 328 Node* result = assembler.ChangeInt32ToTagged(input_value32);
310 Return(result); 329 assembler.Return(result);
311 } 330 }
312 331
313 Bind(&if_inputisstring); 332 assembler.Bind(&if_inputisstring);
314 { 333 {
315 // Check if the String {input} has a cached array index. 334 // Check if the String {input} has a cached array index.
316 Node* input_hash = LoadNameHashField(input); 335 Node* input_hash = assembler.LoadNameHashField(input);
317 Node* input_bit = Word32And( 336 Node* input_bit = assembler.Word32And(
318 input_hash, Int32Constant(String::kContainsCachedArrayIndexMask)); 337 input_hash,
319 GotoIf(Word32NotEqual(input_bit, Int32Constant(0)), &if_generic); 338 assembler.Int32Constant(String::kContainsCachedArrayIndexMask));
339 assembler.GotoIf(
340 assembler.Word32NotEqual(input_bit, assembler.Int32Constant(0)),
341 &if_generic);
320 342
321 // Return the cached array index as result. 343 // Return the cached array index as result.
322 Node* input_index = 344 Node* input_index =
323 DecodeWordFromWord32<String::ArrayIndexValueBits>(input_hash); 345 assembler.DecodeWordFromWord32<String::ArrayIndexValueBits>(
324 Node* result = SmiTag(input_index); 346 input_hash);
325 Return(result); 347 Node* result = assembler.SmiTag(input_index);
348 assembler.Return(result);
326 } 349 }
327 } 350 }
328 351
329 Bind(&if_generic); 352 assembler.Bind(&if_generic);
330 { 353 {
331 Node* result = CallRuntime(Runtime::kStringParseInt, context, input, radix); 354 Node* result =
332 Return(result); 355 assembler.CallRuntime(Runtime::kStringParseInt, context, input, radix);
356 assembler.Return(result);
333 } 357 }
334 } 358 }
335 359
336 // ES6 section 20.1.3.2 Number.prototype.toExponential ( fractionDigits ) 360 // ES6 section 20.1.3.2 Number.prototype.toExponential ( fractionDigits )
337 BUILTIN(NumberPrototypeToExponential) { 361 BUILTIN(NumberPrototypeToExponential) {
338 HandleScope scope(isolate); 362 HandleScope scope(isolate);
339 Handle<Object> value = args.at<Object>(0); 363 Handle<Object> value = args.at<Object>(0);
340 Handle<Object> fraction_digits = args.atOrUndefined(isolate, 1); 364 Handle<Object> fraction_digits = args.atOrUndefined(isolate, 1);
341 365
342 // Unwrap the receiver {value}. 366 // Unwrap the receiver {value}.
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 : isolate->heap()->infinity_string(); 559 : isolate->heap()->infinity_string();
536 } 560 }
537 char* const str = 561 char* const str =
538 DoubleToRadixCString(value_number, static_cast<int>(radix_number)); 562 DoubleToRadixCString(value_number, static_cast<int>(radix_number));
539 Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str); 563 Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
540 DeleteArray(str); 564 DeleteArray(str);
541 return *result; 565 return *result;
542 } 566 }
543 567
544 // ES6 section 20.1.3.7 Number.prototype.valueOf ( ) 568 // ES6 section 20.1.3.7 Number.prototype.valueOf ( )
545 TF_BUILTIN(NumberPrototypeValueOf, CodeStubAssembler) { 569 void Builtins::Generate_NumberPrototypeValueOf(
546 Node* receiver = Parameter(0); 570 compiler::CodeAssemblerState* state) {
547 Node* context = Parameter(3); 571 typedef compiler::Node Node;
548 572 CodeStubAssembler assembler(state);
549 Node* result = ToThisValue(context, receiver, PrimitiveType::kNumber, 573
550 "Number.prototype.valueOf"); 574 Node* receiver = assembler.Parameter(0);
551 Return(result); 575 Node* context = assembler.Parameter(3);
576
577 Node* result = assembler.ToThisValue(
578 context, receiver, PrimitiveType::kNumber, "Number.prototype.valueOf");
579 assembler.Return(result);
552 } 580 }
553 581
554 TF_BUILTIN(Add, CodeStubAssembler) { 582 // static
555 Node* left = Parameter(0); 583 void Builtins::Generate_Add(compiler::CodeAssemblerState* state) {
556 Node* right = Parameter(1); 584 typedef CodeStubAssembler::Label Label;
557 Node* context = Parameter(2); 585 typedef compiler::Node Node;
586 typedef CodeStubAssembler::Variable Variable;
587 CodeStubAssembler assembler(state);
588
589 Node* left = assembler.Parameter(0);
590 Node* right = assembler.Parameter(1);
591 Node* context = assembler.Parameter(2);
558 592
559 // Shared entry for floating point addition. 593 // Shared entry for floating point addition.
560 Label do_fadd(this); 594 Label do_fadd(&assembler);
561 Variable var_fadd_lhs(this, MachineRepresentation::kFloat64), 595 Variable var_fadd_lhs(&assembler, MachineRepresentation::kFloat64),
562 var_fadd_rhs(this, MachineRepresentation::kFloat64); 596 var_fadd_rhs(&assembler, MachineRepresentation::kFloat64);
563 597
564 // We might need to loop several times due to ToPrimitive, ToString and/or 598 // We might need to loop several times due to ToPrimitive, ToString and/or
565 // ToNumber conversions. 599 // ToNumber conversions.
566 Variable var_lhs(this, MachineRepresentation::kTagged), 600 Variable var_lhs(&assembler, MachineRepresentation::kTagged),
567 var_rhs(this, MachineRepresentation::kTagged), 601 var_rhs(&assembler, MachineRepresentation::kTagged),
568 var_result(this, MachineRepresentation::kTagged); 602 var_result(&assembler, MachineRepresentation::kTagged);
569 Variable* loop_vars[2] = {&var_lhs, &var_rhs}; 603 Variable* loop_vars[2] = {&var_lhs, &var_rhs};
570 Label loop(this, 2, loop_vars), end(this), 604 Label loop(&assembler, 2, loop_vars), end(&assembler),
571 string_add_convert_left(this, Label::kDeferred), 605 string_add_convert_left(&assembler, Label::kDeferred),
572 string_add_convert_right(this, Label::kDeferred); 606 string_add_convert_right(&assembler, Label::kDeferred);
573 var_lhs.Bind(left); 607 var_lhs.Bind(left);
574 var_rhs.Bind(right); 608 var_rhs.Bind(right);
575 Goto(&loop); 609 assembler.Goto(&loop);
576 Bind(&loop); 610 assembler.Bind(&loop);
577 { 611 {
578 // Load the current {lhs} and {rhs} values. 612 // Load the current {lhs} and {rhs} values.
579 Node* lhs = var_lhs.value(); 613 Node* lhs = var_lhs.value();
580 Node* rhs = var_rhs.value(); 614 Node* rhs = var_rhs.value();
581 615
582 // Check if the {lhs} is a Smi or a HeapObject. 616 // Check if the {lhs} is a Smi or a HeapObject.
583 Label if_lhsissmi(this), if_lhsisnotsmi(this); 617 Label if_lhsissmi(&assembler), if_lhsisnotsmi(&assembler);
584 Branch(TaggedIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi); 618 assembler.Branch(assembler.TaggedIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi);
585 619
586 Bind(&if_lhsissmi); 620 assembler.Bind(&if_lhsissmi);
587 { 621 {
588 // Check if the {rhs} is also a Smi. 622 // Check if the {rhs} is also a Smi.
589 Label if_rhsissmi(this), if_rhsisnotsmi(this); 623 Label if_rhsissmi(&assembler), if_rhsisnotsmi(&assembler);
590 Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); 624 assembler.Branch(assembler.TaggedIsSmi(rhs), &if_rhsissmi,
591 625 &if_rhsisnotsmi);
592 Bind(&if_rhsissmi); 626
627 assembler.Bind(&if_rhsissmi);
593 { 628 {
594 // Try fast Smi addition first. 629 // Try fast Smi addition first.
595 Node* pair = IntPtrAddWithOverflow(BitcastTaggedToWord(lhs), 630 Node* pair =
596 BitcastTaggedToWord(rhs)); 631 assembler.IntPtrAddWithOverflow(assembler.BitcastTaggedToWord(lhs),
597 Node* overflow = Projection(1, pair); 632 assembler.BitcastTaggedToWord(rhs));
633 Node* overflow = assembler.Projection(1, pair);
598 634
599 // Check if the Smi additon overflowed. 635 // Check if the Smi additon overflowed.
600 Label if_overflow(this), if_notoverflow(this); 636 Label if_overflow(&assembler), if_notoverflow(&assembler);
601 Branch(overflow, &if_overflow, &if_notoverflow); 637 assembler.Branch(overflow, &if_overflow, &if_notoverflow);
602 638
603 Bind(&if_overflow); 639 assembler.Bind(&if_overflow);
604 { 640 {
605 var_fadd_lhs.Bind(SmiToFloat64(lhs)); 641 var_fadd_lhs.Bind(assembler.SmiToFloat64(lhs));
606 var_fadd_rhs.Bind(SmiToFloat64(rhs)); 642 var_fadd_rhs.Bind(assembler.SmiToFloat64(rhs));
607 Goto(&do_fadd); 643 assembler.Goto(&do_fadd);
608 } 644 }
609 645
610 Bind(&if_notoverflow); 646 assembler.Bind(&if_notoverflow);
611 var_result.Bind(BitcastWordToTaggedSigned(Projection(0, pair))); 647 var_result.Bind(
612 Goto(&end); 648 assembler.BitcastWordToTaggedSigned(assembler.Projection(0, pair)));
649 assembler.Goto(&end);
613 } 650 }
614 651
615 Bind(&if_rhsisnotsmi); 652 assembler.Bind(&if_rhsisnotsmi);
616 { 653 {
617 // Load the map of {rhs}. 654 // Load the map of {rhs}.
618 Node* rhs_map = LoadMap(rhs); 655 Node* rhs_map = assembler.LoadMap(rhs);
619 656
620 // Check if the {rhs} is a HeapNumber. 657 // Check if the {rhs} is a HeapNumber.
621 Label if_rhsisnumber(this), if_rhsisnotnumber(this, Label::kDeferred); 658 Label if_rhsisnumber(&assembler),
622 Branch(IsHeapNumberMap(rhs_map), &if_rhsisnumber, &if_rhsisnotnumber); 659 if_rhsisnotnumber(&assembler, Label::kDeferred);
623 660 assembler.Branch(assembler.IsHeapNumberMap(rhs_map), &if_rhsisnumber,
624 Bind(&if_rhsisnumber); 661 &if_rhsisnotnumber);
625 { 662
626 var_fadd_lhs.Bind(SmiToFloat64(lhs)); 663 assembler.Bind(&if_rhsisnumber);
627 var_fadd_rhs.Bind(LoadHeapNumberValue(rhs)); 664 {
628 Goto(&do_fadd); 665 var_fadd_lhs.Bind(assembler.SmiToFloat64(lhs));
666 var_fadd_rhs.Bind(assembler.LoadHeapNumberValue(rhs));
667 assembler.Goto(&do_fadd);
629 } 668 }
630 669
631 Bind(&if_rhsisnotnumber); 670 assembler.Bind(&if_rhsisnotnumber);
632 { 671 {
633 // Load the instance type of {rhs}. 672 // Load the instance type of {rhs}.
634 Node* rhs_instance_type = LoadMapInstanceType(rhs_map); 673 Node* rhs_instance_type = assembler.LoadMapInstanceType(rhs_map);
635 674
636 // Check if the {rhs} is a String. 675 // Check if the {rhs} is a String.
637 Label if_rhsisstring(this, Label::kDeferred), 676 Label if_rhsisstring(&assembler, Label::kDeferred),
638 if_rhsisnotstring(this, Label::kDeferred); 677 if_rhsisnotstring(&assembler, Label::kDeferred);
639 Branch(IsStringInstanceType(rhs_instance_type), &if_rhsisstring, 678 assembler.Branch(assembler.IsStringInstanceType(rhs_instance_type),
640 &if_rhsisnotstring); 679 &if_rhsisstring, &if_rhsisnotstring);
641 680
642 Bind(&if_rhsisstring); 681 assembler.Bind(&if_rhsisstring);
643 { 682 {
644 var_lhs.Bind(lhs); 683 var_lhs.Bind(lhs);
645 var_rhs.Bind(rhs); 684 var_rhs.Bind(rhs);
646 Goto(&string_add_convert_left); 685 assembler.Goto(&string_add_convert_left);
647 } 686 }
648 687
649 Bind(&if_rhsisnotstring); 688 assembler.Bind(&if_rhsisnotstring);
650 { 689 {
651 // Check if {rhs} is a JSReceiver. 690 // Check if {rhs} is a JSReceiver.
652 Label if_rhsisreceiver(this, Label::kDeferred), 691 Label if_rhsisreceiver(&assembler, Label::kDeferred),
653 if_rhsisnotreceiver(this, Label::kDeferred); 692 if_rhsisnotreceiver(&assembler, Label::kDeferred);
654 Branch(IsJSReceiverInstanceType(rhs_instance_type), 693 assembler.Branch(
655 &if_rhsisreceiver, &if_rhsisnotreceiver); 694 assembler.IsJSReceiverInstanceType(rhs_instance_type),
656 695 &if_rhsisreceiver, &if_rhsisnotreceiver);
657 Bind(&if_rhsisreceiver); 696
697 assembler.Bind(&if_rhsisreceiver);
658 { 698 {
659 // Convert {rhs} to a primitive first passing no hint. 699 // Convert {rhs} to a primitive first passing no hint.
660 Callable callable = 700 Callable callable =
661 CodeFactory::NonPrimitiveToPrimitive(isolate()); 701 CodeFactory::NonPrimitiveToPrimitive(assembler.isolate());
662 var_rhs.Bind(CallStub(callable, context, rhs)); 702 var_rhs.Bind(assembler.CallStub(callable, context, rhs));
663 Goto(&loop); 703 assembler.Goto(&loop);
664 } 704 }
665 705
666 Bind(&if_rhsisnotreceiver); 706 assembler.Bind(&if_rhsisnotreceiver);
667 { 707 {
668 // Convert {rhs} to a Number first. 708 // Convert {rhs} to a Number first.
669 Callable callable = CodeFactory::NonNumberToNumber(isolate()); 709 Callable callable =
670 var_rhs.Bind(CallStub(callable, context, rhs)); 710 CodeFactory::NonNumberToNumber(assembler.isolate());
671 Goto(&loop); 711 var_rhs.Bind(assembler.CallStub(callable, context, rhs));
712 assembler.Goto(&loop);
672 } 713 }
673 } 714 }
674 } 715 }
675 } 716 }
676 } 717 }
677 718
678 Bind(&if_lhsisnotsmi); 719 assembler.Bind(&if_lhsisnotsmi);
679 { 720 {
680 // Load the map and instance type of {lhs}. 721 // Load the map and instance type of {lhs}.
681 Node* lhs_instance_type = LoadInstanceType(lhs); 722 Node* lhs_instance_type = assembler.LoadInstanceType(lhs);
682 723
683 // Check if {lhs} is a String. 724 // Check if {lhs} is a String.
684 Label if_lhsisstring(this), if_lhsisnotstring(this); 725 Label if_lhsisstring(&assembler), if_lhsisnotstring(&assembler);
685 Branch(IsStringInstanceType(lhs_instance_type), &if_lhsisstring, 726 assembler.Branch(assembler.IsStringInstanceType(lhs_instance_type),
686 &if_lhsisnotstring); 727 &if_lhsisstring, &if_lhsisnotstring);
687 728
688 Bind(&if_lhsisstring); 729 assembler.Bind(&if_lhsisstring);
689 { 730 {
690 var_lhs.Bind(lhs); 731 var_lhs.Bind(lhs);
691 var_rhs.Bind(rhs); 732 var_rhs.Bind(rhs);
692 Goto(&string_add_convert_right); 733 assembler.Goto(&string_add_convert_right);
693 } 734 }
694 735
695 Bind(&if_lhsisnotstring); 736 assembler.Bind(&if_lhsisnotstring);
696 { 737 {
697 // Check if {rhs} is a Smi. 738 // Check if {rhs} is a Smi.
698 Label if_rhsissmi(this), if_rhsisnotsmi(this); 739 Label if_rhsissmi(&assembler), if_rhsisnotsmi(&assembler);
699 Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); 740 assembler.Branch(assembler.TaggedIsSmi(rhs), &if_rhsissmi,
700 741 &if_rhsisnotsmi);
701 Bind(&if_rhsissmi); 742
743 assembler.Bind(&if_rhsissmi);
702 { 744 {
703 // Check if {lhs} is a Number. 745 // Check if {lhs} is a Number.
704 Label if_lhsisnumber(this), if_lhsisnotnumber(this, Label::kDeferred); 746 Label if_lhsisnumber(&assembler),
705 Branch( 747 if_lhsisnotnumber(&assembler, Label::kDeferred);
706 Word32Equal(lhs_instance_type, Int32Constant(HEAP_NUMBER_TYPE)), 748 assembler.Branch(
749 assembler.Word32Equal(lhs_instance_type,
750 assembler.Int32Constant(HEAP_NUMBER_TYPE)),
707 &if_lhsisnumber, &if_lhsisnotnumber); 751 &if_lhsisnumber, &if_lhsisnotnumber);
708 752
709 Bind(&if_lhsisnumber); 753 assembler.Bind(&if_lhsisnumber);
710 { 754 {
711 // The {lhs} is a HeapNumber, the {rhs} is a Smi, just add them. 755 // The {lhs} is a HeapNumber, the {rhs} is a Smi, just add them.
712 var_fadd_lhs.Bind(LoadHeapNumberValue(lhs)); 756 var_fadd_lhs.Bind(assembler.LoadHeapNumberValue(lhs));
713 var_fadd_rhs.Bind(SmiToFloat64(rhs)); 757 var_fadd_rhs.Bind(assembler.SmiToFloat64(rhs));
714 Goto(&do_fadd); 758 assembler.Goto(&do_fadd);
715 } 759 }
716 760
717 Bind(&if_lhsisnotnumber); 761 assembler.Bind(&if_lhsisnotnumber);
718 { 762 {
719 // The {lhs} is neither a Number nor a String, and the {rhs} is a 763 // The {lhs} is neither a Number nor a String, and the {rhs} is a
720 // Smi. 764 // Smi.
721 Label if_lhsisreceiver(this, Label::kDeferred), 765 Label if_lhsisreceiver(&assembler, Label::kDeferred),
722 if_lhsisnotreceiver(this, Label::kDeferred); 766 if_lhsisnotreceiver(&assembler, Label::kDeferred);
723 Branch(IsJSReceiverInstanceType(lhs_instance_type), 767 assembler.Branch(
724 &if_lhsisreceiver, &if_lhsisnotreceiver); 768 assembler.IsJSReceiverInstanceType(lhs_instance_type),
725 769 &if_lhsisreceiver, &if_lhsisnotreceiver);
726 Bind(&if_lhsisreceiver); 770
771 assembler.Bind(&if_lhsisreceiver);
727 { 772 {
728 // Convert {lhs} to a primitive first passing no hint. 773 // Convert {lhs} to a primitive first passing no hint.
729 Callable callable = 774 Callable callable =
730 CodeFactory::NonPrimitiveToPrimitive(isolate()); 775 CodeFactory::NonPrimitiveToPrimitive(assembler.isolate());
731 var_lhs.Bind(CallStub(callable, context, lhs)); 776 var_lhs.Bind(assembler.CallStub(callable, context, lhs));
732 Goto(&loop); 777 assembler.Goto(&loop);
733 } 778 }
734 779
735 Bind(&if_lhsisnotreceiver); 780 assembler.Bind(&if_lhsisnotreceiver);
736 { 781 {
737 // Convert {lhs} to a Number first. 782 // Convert {lhs} to a Number first.
738 Callable callable = CodeFactory::NonNumberToNumber(isolate()); 783 Callable callable =
739 var_lhs.Bind(CallStub(callable, context, lhs)); 784 CodeFactory::NonNumberToNumber(assembler.isolate());
740 Goto(&loop); 785 var_lhs.Bind(assembler.CallStub(callable, context, lhs));
786 assembler.Goto(&loop);
741 } 787 }
742 } 788 }
743 } 789 }
744 790
745 Bind(&if_rhsisnotsmi); 791 assembler.Bind(&if_rhsisnotsmi);
746 { 792 {
747 // Load the instance type of {rhs}. 793 // Load the instance type of {rhs}.
748 Node* rhs_instance_type = LoadInstanceType(rhs); 794 Node* rhs_instance_type = assembler.LoadInstanceType(rhs);
749 795
750 // Check if {rhs} is a String. 796 // Check if {rhs} is a String.
751 Label if_rhsisstring(this), if_rhsisnotstring(this); 797 Label if_rhsisstring(&assembler), if_rhsisnotstring(&assembler);
752 Branch(IsStringInstanceType(rhs_instance_type), &if_rhsisstring, 798 assembler.Branch(assembler.IsStringInstanceType(rhs_instance_type),
753 &if_rhsisnotstring); 799 &if_rhsisstring, &if_rhsisnotstring);
754 800
755 Bind(&if_rhsisstring); 801 assembler.Bind(&if_rhsisstring);
756 { 802 {
757 var_lhs.Bind(lhs); 803 var_lhs.Bind(lhs);
758 var_rhs.Bind(rhs); 804 var_rhs.Bind(rhs);
759 Goto(&string_add_convert_left); 805 assembler.Goto(&string_add_convert_left);
760 } 806 }
761 807
762 Bind(&if_rhsisnotstring); 808 assembler.Bind(&if_rhsisnotstring);
763 { 809 {
764 // Check if {lhs} is a HeapNumber. 810 // Check if {lhs} is a HeapNumber.
765 Label if_lhsisnumber(this), if_lhsisnotnumber(this); 811 Label if_lhsisnumber(&assembler), if_lhsisnotnumber(&assembler);
766 Branch( 812 assembler.Branch(assembler.Word32Equal(
767 Word32Equal(lhs_instance_type, Int32Constant(HEAP_NUMBER_TYPE)), 813 lhs_instance_type,
768 &if_lhsisnumber, &if_lhsisnotnumber); 814 assembler.Int32Constant(HEAP_NUMBER_TYPE)),
769 815 &if_lhsisnumber, &if_lhsisnotnumber);
770 Bind(&if_lhsisnumber); 816
817 assembler.Bind(&if_lhsisnumber);
771 { 818 {
772 // Check if {rhs} is also a HeapNumber. 819 // Check if {rhs} is also a HeapNumber.
773 Label if_rhsisnumber(this), 820 Label if_rhsisnumber(&assembler),
774 if_rhsisnotnumber(this, Label::kDeferred); 821 if_rhsisnotnumber(&assembler, Label::kDeferred);
775 Branch(Word32Equal(rhs_instance_type, 822 assembler.Branch(assembler.Word32Equal(
776 Int32Constant(HEAP_NUMBER_TYPE)), 823 rhs_instance_type,
777 &if_rhsisnumber, &if_rhsisnotnumber); 824 assembler.Int32Constant(HEAP_NUMBER_TYPE)),
778 825 &if_rhsisnumber, &if_rhsisnotnumber);
779 Bind(&if_rhsisnumber); 826
827 assembler.Bind(&if_rhsisnumber);
780 { 828 {
781 // Perform a floating point addition. 829 // Perform a floating point addition.
782 var_fadd_lhs.Bind(LoadHeapNumberValue(lhs)); 830 var_fadd_lhs.Bind(assembler.LoadHeapNumberValue(lhs));
783 var_fadd_rhs.Bind(LoadHeapNumberValue(rhs)); 831 var_fadd_rhs.Bind(assembler.LoadHeapNumberValue(rhs));
784 Goto(&do_fadd); 832 assembler.Goto(&do_fadd);
785 } 833 }
786 834
787 Bind(&if_rhsisnotnumber); 835 assembler.Bind(&if_rhsisnotnumber);
788 { 836 {
789 // Check if {rhs} is a JSReceiver. 837 // Check if {rhs} is a JSReceiver.
790 Label if_rhsisreceiver(this, Label::kDeferred), 838 Label if_rhsisreceiver(&assembler, Label::kDeferred),
791 if_rhsisnotreceiver(this, Label::kDeferred); 839 if_rhsisnotreceiver(&assembler, Label::kDeferred);
792 Branch(IsJSReceiverInstanceType(rhs_instance_type), 840 assembler.Branch(
793 &if_rhsisreceiver, &if_rhsisnotreceiver); 841 assembler.IsJSReceiverInstanceType(rhs_instance_type),
794 842 &if_rhsisreceiver, &if_rhsisnotreceiver);
795 Bind(&if_rhsisreceiver); 843
844 assembler.Bind(&if_rhsisreceiver);
796 { 845 {
797 // Convert {rhs} to a primitive first passing no hint. 846 // Convert {rhs} to a primitive first passing no hint.
798 Callable callable = 847 Callable callable =
799 CodeFactory::NonPrimitiveToPrimitive(isolate()); 848 CodeFactory::NonPrimitiveToPrimitive(assembler.isolate());
800 var_rhs.Bind(CallStub(callable, context, rhs)); 849 var_rhs.Bind(assembler.CallStub(callable, context, rhs));
801 Goto(&loop); 850 assembler.Goto(&loop);
802 } 851 }
803 852
804 Bind(&if_rhsisnotreceiver); 853 assembler.Bind(&if_rhsisnotreceiver);
805 { 854 {
806 // Convert {rhs} to a Number first. 855 // Convert {rhs} to a Number first.
807 Callable callable = CodeFactory::NonNumberToNumber(isolate()); 856 Callable callable =
808 var_rhs.Bind(CallStub(callable, context, rhs)); 857 CodeFactory::NonNumberToNumber(assembler.isolate());
809 Goto(&loop); 858 var_rhs.Bind(assembler.CallStub(callable, context, rhs));
859 assembler.Goto(&loop);
810 } 860 }
811 } 861 }
812 } 862 }
813 863
814 Bind(&if_lhsisnotnumber); 864 assembler.Bind(&if_lhsisnotnumber);
815 { 865 {
816 // Check if {lhs} is a JSReceiver. 866 // Check if {lhs} is a JSReceiver.
817 Label if_lhsisreceiver(this, Label::kDeferred), 867 Label if_lhsisreceiver(&assembler, Label::kDeferred),
818 if_lhsisnotreceiver(this); 868 if_lhsisnotreceiver(&assembler);
819 Branch(IsJSReceiverInstanceType(lhs_instance_type), 869 assembler.Branch(
820 &if_lhsisreceiver, &if_lhsisnotreceiver); 870 assembler.IsJSReceiverInstanceType(lhs_instance_type),
821 871 &if_lhsisreceiver, &if_lhsisnotreceiver);
822 Bind(&if_lhsisreceiver); 872
873 assembler.Bind(&if_lhsisreceiver);
823 { 874 {
824 // Convert {lhs} to a primitive first passing no hint. 875 // Convert {lhs} to a primitive first passing no hint.
825 Callable callable = 876 Callable callable =
826 CodeFactory::NonPrimitiveToPrimitive(isolate()); 877 CodeFactory::NonPrimitiveToPrimitive(assembler.isolate());
827 var_lhs.Bind(CallStub(callable, context, lhs)); 878 var_lhs.Bind(assembler.CallStub(callable, context, lhs));
828 Goto(&loop); 879 assembler.Goto(&loop);
829 } 880 }
830 881
831 Bind(&if_lhsisnotreceiver); 882 assembler.Bind(&if_lhsisnotreceiver);
832 { 883 {
833 // Check if {rhs} is a JSReceiver. 884 // Check if {rhs} is a JSReceiver.
834 Label if_rhsisreceiver(this, Label::kDeferred), 885 Label if_rhsisreceiver(&assembler, Label::kDeferred),
835 if_rhsisnotreceiver(this, Label::kDeferred); 886 if_rhsisnotreceiver(&assembler, Label::kDeferred);
836 Branch(IsJSReceiverInstanceType(rhs_instance_type), 887 assembler.Branch(
837 &if_rhsisreceiver, &if_rhsisnotreceiver); 888 assembler.IsJSReceiverInstanceType(rhs_instance_type),
838 889 &if_rhsisreceiver, &if_rhsisnotreceiver);
839 Bind(&if_rhsisreceiver); 890
891 assembler.Bind(&if_rhsisreceiver);
840 { 892 {
841 // Convert {rhs} to a primitive first passing no hint. 893 // Convert {rhs} to a primitive first passing no hint.
842 Callable callable = 894 Callable callable =
843 CodeFactory::NonPrimitiveToPrimitive(isolate()); 895 CodeFactory::NonPrimitiveToPrimitive(assembler.isolate());
844 var_rhs.Bind(CallStub(callable, context, rhs)); 896 var_rhs.Bind(assembler.CallStub(callable, context, rhs));
845 Goto(&loop); 897 assembler.Goto(&loop);
846 } 898 }
847 899
848 Bind(&if_rhsisnotreceiver); 900 assembler.Bind(&if_rhsisnotreceiver);
849 { 901 {
850 // Convert {lhs} to a Number first. 902 // Convert {lhs} to a Number first.
851 Callable callable = CodeFactory::NonNumberToNumber(isolate()); 903 Callable callable =
852 var_lhs.Bind(CallStub(callable, context, lhs)); 904 CodeFactory::NonNumberToNumber(assembler.isolate());
853 Goto(&loop); 905 var_lhs.Bind(assembler.CallStub(callable, context, lhs));
906 assembler.Goto(&loop);
854 } 907 }
855 } 908 }
856 } 909 }
857 } 910 }
858 } 911 }
859 } 912 }
860 } 913 }
861 } 914 }
862 Bind(&string_add_convert_left); 915 assembler.Bind(&string_add_convert_left);
863 {
864 // Convert {lhs}, which is a Smi, to a String and concatenate the
865 // resulting string with the String {rhs}.
866 Callable callable =
867 CodeFactory::StringAdd(isolate(), STRING_ADD_CONVERT_LEFT, NOT_TENURED);
868 var_result.Bind(
869 CallStub(callable, context, var_lhs.value(), var_rhs.value()));
870 Goto(&end);
871 }
872
873 Bind(&string_add_convert_right);
874 { 916 {
875 // Convert {lhs}, which is a Smi, to a String and concatenate the 917 // Convert {lhs}, which is a Smi, to a String and concatenate the
876 // resulting string with the String {rhs}. 918 // resulting string with the String {rhs}.
877 Callable callable = CodeFactory::StringAdd( 919 Callable callable = CodeFactory::StringAdd(
878 isolate(), STRING_ADD_CONVERT_RIGHT, NOT_TENURED); 920 assembler.isolate(), STRING_ADD_CONVERT_LEFT, NOT_TENURED);
879 var_result.Bind( 921 var_result.Bind(assembler.CallStub(callable, context, var_lhs.value(),
880 CallStub(callable, context, var_lhs.value(), var_rhs.value())); 922 var_rhs.value()));
881 Goto(&end); 923 assembler.Goto(&end);
882 } 924 }
883 925
884 Bind(&do_fadd); 926 assembler.Bind(&string_add_convert_right);
927 {
928 // Convert {lhs}, which is a Smi, to a String and concatenate the
929 // resulting string with the String {rhs}.
930 Callable callable = CodeFactory::StringAdd(
931 assembler.isolate(), STRING_ADD_CONVERT_RIGHT, NOT_TENURED);
932 var_result.Bind(assembler.CallStub(callable, context, var_lhs.value(),
933 var_rhs.value()));
934 assembler.Goto(&end);
935 }
936
937 assembler.Bind(&do_fadd);
885 { 938 {
886 Node* lhs_value = var_fadd_lhs.value(); 939 Node* lhs_value = var_fadd_lhs.value();
887 Node* rhs_value = var_fadd_rhs.value(); 940 Node* rhs_value = var_fadd_rhs.value();
888 Node* value = Float64Add(lhs_value, rhs_value); 941 Node* value = assembler.Float64Add(lhs_value, rhs_value);
889 Node* result = AllocateHeapNumberWithValue(value); 942 Node* result = assembler.AllocateHeapNumberWithValue(value);
890 var_result.Bind(result); 943 var_result.Bind(result);
891 Goto(&end); 944 assembler.Goto(&end);
892 } 945 }
893 Bind(&end); 946 assembler.Bind(&end);
894 Return(var_result.value()); 947 assembler.Return(var_result.value());
895 } 948 }
896 949
897 TF_BUILTIN(Subtract, CodeStubAssembler) { 950 void Builtins::Generate_Subtract(compiler::CodeAssemblerState* state) {
898 Node* left = Parameter(0); 951 typedef CodeStubAssembler::Label Label;
899 Node* right = Parameter(1); 952 typedef compiler::Node Node;
900 Node* context = Parameter(2); 953 typedef CodeStubAssembler::Variable Variable;
954 CodeStubAssembler assembler(state);
955
956 Node* left = assembler.Parameter(0);
957 Node* right = assembler.Parameter(1);
958 Node* context = assembler.Parameter(2);
901 959
902 // Shared entry for floating point subtraction. 960 // Shared entry for floating point subtraction.
903 Label do_fsub(this), end(this); 961 Label do_fsub(&assembler), end(&assembler);
904 Variable var_fsub_lhs(this, MachineRepresentation::kFloat64), 962 Variable var_fsub_lhs(&assembler, MachineRepresentation::kFloat64),
905 var_fsub_rhs(this, MachineRepresentation::kFloat64); 963 var_fsub_rhs(&assembler, MachineRepresentation::kFloat64);
906 964
907 // We might need to loop several times due to ToPrimitive and/or ToNumber 965 // We might need to loop several times due to ToPrimitive and/or ToNumber
908 // conversions. 966 // conversions.
909 Variable var_lhs(this, MachineRepresentation::kTagged), 967 Variable var_lhs(&assembler, MachineRepresentation::kTagged),
910 var_rhs(this, MachineRepresentation::kTagged), 968 var_rhs(&assembler, MachineRepresentation::kTagged),
911 var_result(this, MachineRepresentation::kTagged); 969 var_result(&assembler, MachineRepresentation::kTagged);
912 Variable* loop_vars[2] = {&var_lhs, &var_rhs}; 970 Variable* loop_vars[2] = {&var_lhs, &var_rhs};
913 Label loop(this, 2, loop_vars); 971 Label loop(&assembler, 2, loop_vars);
914 var_lhs.Bind(left); 972 var_lhs.Bind(left);
915 var_rhs.Bind(right); 973 var_rhs.Bind(right);
916 Goto(&loop); 974 assembler.Goto(&loop);
917 Bind(&loop); 975 assembler.Bind(&loop);
918 { 976 {
919 // Load the current {lhs} and {rhs} values. 977 // Load the current {lhs} and {rhs} values.
920 Node* lhs = var_lhs.value(); 978 Node* lhs = var_lhs.value();
921 Node* rhs = var_rhs.value(); 979 Node* rhs = var_rhs.value();
922 980
923 // Check if the {lhs} is a Smi or a HeapObject. 981 // Check if the {lhs} is a Smi or a HeapObject.
924 Label if_lhsissmi(this), if_lhsisnotsmi(this); 982 Label if_lhsissmi(&assembler), if_lhsisnotsmi(&assembler);
925 Branch(TaggedIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi); 983 assembler.Branch(assembler.TaggedIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi);
926 984
927 Bind(&if_lhsissmi); 985 assembler.Bind(&if_lhsissmi);
928 { 986 {
929 // Check if the {rhs} is also a Smi. 987 // Check if the {rhs} is also a Smi.
930 Label if_rhsissmi(this), if_rhsisnotsmi(this); 988 Label if_rhsissmi(&assembler), if_rhsisnotsmi(&assembler);
931 Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); 989 assembler.Branch(assembler.TaggedIsSmi(rhs), &if_rhsissmi,
932 990 &if_rhsisnotsmi);
933 Bind(&if_rhsissmi); 991
992 assembler.Bind(&if_rhsissmi);
934 { 993 {
935 // Try a fast Smi subtraction first. 994 // Try a fast Smi subtraction first.
936 Node* pair = IntPtrSubWithOverflow(BitcastTaggedToWord(lhs), 995 Node* pair =
937 BitcastTaggedToWord(rhs)); 996 assembler.IntPtrSubWithOverflow(assembler.BitcastTaggedToWord(lhs),
938 Node* overflow = Projection(1, pair); 997 assembler.BitcastTaggedToWord(rhs));
998 Node* overflow = assembler.Projection(1, pair);
939 999
940 // Check if the Smi subtraction overflowed. 1000 // Check if the Smi subtraction overflowed.
941 Label if_overflow(this), if_notoverflow(this); 1001 Label if_overflow(&assembler), if_notoverflow(&assembler);
942 Branch(overflow, &if_overflow, &if_notoverflow); 1002 assembler.Branch(overflow, &if_overflow, &if_notoverflow);
943 1003
944 Bind(&if_overflow); 1004 assembler.Bind(&if_overflow);
945 { 1005 {
946 // The result doesn't fit into Smi range. 1006 // The result doesn't fit into Smi range.
947 var_fsub_lhs.Bind(SmiToFloat64(lhs)); 1007 var_fsub_lhs.Bind(assembler.SmiToFloat64(lhs));
948 var_fsub_rhs.Bind(SmiToFloat64(rhs)); 1008 var_fsub_rhs.Bind(assembler.SmiToFloat64(rhs));
949 Goto(&do_fsub); 1009 assembler.Goto(&do_fsub);
950 } 1010 }
951 1011
952 Bind(&if_notoverflow); 1012 assembler.Bind(&if_notoverflow);
953 var_result.Bind(BitcastWordToTaggedSigned(Projection(0, pair))); 1013 var_result.Bind(
954 Goto(&end); 1014 assembler.BitcastWordToTaggedSigned(assembler.Projection(0, pair)));
955 } 1015 assembler.Goto(&end);
956 1016 }
957 Bind(&if_rhsisnotsmi); 1017
1018 assembler.Bind(&if_rhsisnotsmi);
958 { 1019 {
959 // Load the map of the {rhs}. 1020 // Load the map of the {rhs}.
960 Node* rhs_map = LoadMap(rhs); 1021 Node* rhs_map = assembler.LoadMap(rhs);
961 1022
962 // Check if {rhs} is a HeapNumber. 1023 // Check if {rhs} is a HeapNumber.
963 Label if_rhsisnumber(this), if_rhsisnotnumber(this, Label::kDeferred); 1024 Label if_rhsisnumber(&assembler),
964 Branch(IsHeapNumberMap(rhs_map), &if_rhsisnumber, &if_rhsisnotnumber); 1025 if_rhsisnotnumber(&assembler, Label::kDeferred);
965 1026 assembler.Branch(assembler.IsHeapNumberMap(rhs_map), &if_rhsisnumber,
966 Bind(&if_rhsisnumber); 1027 &if_rhsisnotnumber);
1028
1029 assembler.Bind(&if_rhsisnumber);
967 { 1030 {
968 // Perform a floating point subtraction. 1031 // Perform a floating point subtraction.
969 var_fsub_lhs.Bind(SmiToFloat64(lhs)); 1032 var_fsub_lhs.Bind(assembler.SmiToFloat64(lhs));
970 var_fsub_rhs.Bind(LoadHeapNumberValue(rhs)); 1033 var_fsub_rhs.Bind(assembler.LoadHeapNumberValue(rhs));
971 Goto(&do_fsub); 1034 assembler.Goto(&do_fsub);
972 } 1035 }
973 1036
974 Bind(&if_rhsisnotnumber); 1037 assembler.Bind(&if_rhsisnotnumber);
975 { 1038 {
976 // Convert the {rhs} to a Number first. 1039 // Convert the {rhs} to a Number first.
977 Callable callable = CodeFactory::NonNumberToNumber(isolate()); 1040 Callable callable =
978 var_rhs.Bind(CallStub(callable, context, rhs)); 1041 CodeFactory::NonNumberToNumber(assembler.isolate());
979 Goto(&loop); 1042 var_rhs.Bind(assembler.CallStub(callable, context, rhs));
1043 assembler.Goto(&loop);
980 } 1044 }
981 } 1045 }
982 } 1046 }
983 1047
984 Bind(&if_lhsisnotsmi); 1048 assembler.Bind(&if_lhsisnotsmi);
985 { 1049 {
986 // Load the map of the {lhs}. 1050 // Load the map of the {lhs}.
987 Node* lhs_map = LoadMap(lhs); 1051 Node* lhs_map = assembler.LoadMap(lhs);
988 1052
989 // Check if the {lhs} is a HeapNumber. 1053 // Check if the {lhs} is a HeapNumber.
990 Label if_lhsisnumber(this), if_lhsisnotnumber(this, Label::kDeferred); 1054 Label if_lhsisnumber(&assembler),
991 Node* number_map = HeapNumberMapConstant(); 1055 if_lhsisnotnumber(&assembler, Label::kDeferred);
992 Branch(WordEqual(lhs_map, number_map), &if_lhsisnumber, 1056 Node* number_map = assembler.HeapNumberMapConstant();
993 &if_lhsisnotnumber); 1057 assembler.Branch(assembler.WordEqual(lhs_map, number_map),
994 1058 &if_lhsisnumber, &if_lhsisnotnumber);
995 Bind(&if_lhsisnumber); 1059
1060 assembler.Bind(&if_lhsisnumber);
996 { 1061 {
997 // Check if the {rhs} is a Smi. 1062 // Check if the {rhs} is a Smi.
998 Label if_rhsissmi(this), if_rhsisnotsmi(this); 1063 Label if_rhsissmi(&assembler), if_rhsisnotsmi(&assembler);
999 Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); 1064 assembler.Branch(assembler.TaggedIsSmi(rhs), &if_rhsissmi,
1000 1065 &if_rhsisnotsmi);
1001 Bind(&if_rhsissmi); 1066
1067 assembler.Bind(&if_rhsissmi);
1002 { 1068 {
1003 // Perform a floating point subtraction. 1069 // Perform a floating point subtraction.
1004 var_fsub_lhs.Bind(LoadHeapNumberValue(lhs)); 1070 var_fsub_lhs.Bind(assembler.LoadHeapNumberValue(lhs));
1005 var_fsub_rhs.Bind(SmiToFloat64(rhs)); 1071 var_fsub_rhs.Bind(assembler.SmiToFloat64(rhs));
1006 Goto(&do_fsub); 1072 assembler.Goto(&do_fsub);
1007 } 1073 }
1008 1074
1009 Bind(&if_rhsisnotsmi); 1075 assembler.Bind(&if_rhsisnotsmi);
1010 { 1076 {
1011 // Load the map of the {rhs}. 1077 // Load the map of the {rhs}.
1012 Node* rhs_map = LoadMap(rhs); 1078 Node* rhs_map = assembler.LoadMap(rhs);
1013 1079
1014 // Check if the {rhs} is a HeapNumber. 1080 // Check if the {rhs} is a HeapNumber.
1015 Label if_rhsisnumber(this), if_rhsisnotnumber(this, Label::kDeferred); 1081 Label if_rhsisnumber(&assembler),
1016 Branch(WordEqual(rhs_map, number_map), &if_rhsisnumber, 1082 if_rhsisnotnumber(&assembler, Label::kDeferred);
1017 &if_rhsisnotnumber); 1083 assembler.Branch(assembler.WordEqual(rhs_map, number_map),
1018 1084 &if_rhsisnumber, &if_rhsisnotnumber);
1019 Bind(&if_rhsisnumber); 1085
1086 assembler.Bind(&if_rhsisnumber);
1020 { 1087 {
1021 // Perform a floating point subtraction. 1088 // Perform a floating point subtraction.
1022 var_fsub_lhs.Bind(LoadHeapNumberValue(lhs)); 1089 var_fsub_lhs.Bind(assembler.LoadHeapNumberValue(lhs));
1023 var_fsub_rhs.Bind(LoadHeapNumberValue(rhs)); 1090 var_fsub_rhs.Bind(assembler.LoadHeapNumberValue(rhs));
1024 Goto(&do_fsub); 1091 assembler.Goto(&do_fsub);
1025 } 1092 }
1026 1093
1027 Bind(&if_rhsisnotnumber); 1094 assembler.Bind(&if_rhsisnotnumber);
1028 { 1095 {
1029 // Convert the {rhs} to a Number first. 1096 // Convert the {rhs} to a Number first.
1030 Callable callable = CodeFactory::NonNumberToNumber(isolate()); 1097 Callable callable =
1031 var_rhs.Bind(CallStub(callable, context, rhs)); 1098 CodeFactory::NonNumberToNumber(assembler.isolate());
1032 Goto(&loop); 1099 var_rhs.Bind(assembler.CallStub(callable, context, rhs));
1100 assembler.Goto(&loop);
1033 } 1101 }
1034 } 1102 }
1035 } 1103 }
1036 1104
1037 Bind(&if_lhsisnotnumber); 1105 assembler.Bind(&if_lhsisnotnumber);
1038 { 1106 {
1039 // Convert the {lhs} to a Number first. 1107 // Convert the {lhs} to a Number first.
1040 Callable callable = CodeFactory::NonNumberToNumber(isolate()); 1108 Callable callable = CodeFactory::NonNumberToNumber(assembler.isolate());
1041 var_lhs.Bind(CallStub(callable, context, lhs)); 1109 var_lhs.Bind(assembler.CallStub(callable, context, lhs));
1042 Goto(&loop); 1110 assembler.Goto(&loop);
1043 } 1111 }
1044 } 1112 }
1045 } 1113 }
1046 1114
1047 Bind(&do_fsub); 1115 assembler.Bind(&do_fsub);
1048 { 1116 {
1049 Node* lhs_value = var_fsub_lhs.value(); 1117 Node* lhs_value = var_fsub_lhs.value();
1050 Node* rhs_value = var_fsub_rhs.value(); 1118 Node* rhs_value = var_fsub_rhs.value();
1051 Node* value = Float64Sub(lhs_value, rhs_value); 1119 Node* value = assembler.Float64Sub(lhs_value, rhs_value);
1052 var_result.Bind(AllocateHeapNumberWithValue(value)); 1120 var_result.Bind(assembler.AllocateHeapNumberWithValue(value));
1053 Goto(&end); 1121 assembler.Goto(&end);
1054 } 1122 }
1055 Bind(&end); 1123 assembler.Bind(&end);
1056 Return(var_result.value()); 1124 assembler.Return(var_result.value());
1057 } 1125 }
1058 1126
1059 TF_BUILTIN(Multiply, CodeStubAssembler) { 1127 void Builtins::Generate_Multiply(compiler::CodeAssemblerState* state) {
1060 Node* left = Parameter(0); 1128 typedef CodeStubAssembler::Label Label;
1061 Node* right = Parameter(1); 1129 typedef compiler::Node Node;
1062 Node* context = Parameter(2); 1130 typedef CodeStubAssembler::Variable Variable;
1131 CodeStubAssembler assembler(state);
1132
1133 Node* left = assembler.Parameter(0);
1134 Node* right = assembler.Parameter(1);
1135 Node* context = assembler.Parameter(2);
1063 1136
1064 // Shared entry point for floating point multiplication. 1137 // Shared entry point for floating point multiplication.
1065 Label do_fmul(this), return_result(this); 1138 Label do_fmul(&assembler), return_result(&assembler);
1066 Variable var_lhs_float64(this, MachineRepresentation::kFloat64), 1139 Variable var_lhs_float64(&assembler, MachineRepresentation::kFloat64),
1067 var_rhs_float64(this, MachineRepresentation::kFloat64); 1140 var_rhs_float64(&assembler, MachineRepresentation::kFloat64);
1068 1141
1069 Node* number_map = HeapNumberMapConstant(); 1142 Node* number_map = assembler.HeapNumberMapConstant();
1070 1143
1071 // We might need to loop one or two times due to ToNumber conversions. 1144 // We might need to loop one or two times due to ToNumber conversions.
1072 Variable var_lhs(this, MachineRepresentation::kTagged), 1145 Variable var_lhs(&assembler, MachineRepresentation::kTagged),
1073 var_rhs(this, MachineRepresentation::kTagged), 1146 var_rhs(&assembler, MachineRepresentation::kTagged),
1074 var_result(this, MachineRepresentation::kTagged); 1147 var_result(&assembler, MachineRepresentation::kTagged);
1075 Variable* loop_variables[] = {&var_lhs, &var_rhs}; 1148 Variable* loop_variables[] = {&var_lhs, &var_rhs};
1076 Label loop(this, 2, loop_variables); 1149 Label loop(&assembler, 2, loop_variables);
1077 var_lhs.Bind(left); 1150 var_lhs.Bind(left);
1078 var_rhs.Bind(right); 1151 var_rhs.Bind(right);
1079 Goto(&loop); 1152 assembler.Goto(&loop);
1080 Bind(&loop); 1153 assembler.Bind(&loop);
1081 { 1154 {
1082 Node* lhs = var_lhs.value(); 1155 Node* lhs = var_lhs.value();
1083 Node* rhs = var_rhs.value(); 1156 Node* rhs = var_rhs.value();
1084 1157
1085 Label lhs_is_smi(this), lhs_is_not_smi(this); 1158 Label lhs_is_smi(&assembler), lhs_is_not_smi(&assembler);
1086 Branch(TaggedIsSmi(lhs), &lhs_is_smi, &lhs_is_not_smi); 1159 assembler.Branch(assembler.TaggedIsSmi(lhs), &lhs_is_smi, &lhs_is_not_smi);
1087 1160
1088 Bind(&lhs_is_smi); 1161 assembler.Bind(&lhs_is_smi);
1089 { 1162 {
1090 Label rhs_is_smi(this), rhs_is_not_smi(this); 1163 Label rhs_is_smi(&assembler), rhs_is_not_smi(&assembler);
1091 Branch(TaggedIsSmi(rhs), &rhs_is_smi, &rhs_is_not_smi); 1164 assembler.Branch(assembler.TaggedIsSmi(rhs), &rhs_is_smi,
1092 1165 &rhs_is_not_smi);
1093 Bind(&rhs_is_smi); 1166
1167 assembler.Bind(&rhs_is_smi);
1094 { 1168 {
1095 // Both {lhs} and {rhs} are Smis. The result is not necessarily a smi, 1169 // Both {lhs} and {rhs} are Smis. The result is not necessarily a smi,
1096 // in case of overflow. 1170 // in case of overflow.
1097 var_result.Bind(SmiMul(lhs, rhs)); 1171 var_result.Bind(assembler.SmiMul(lhs, rhs));
1098 Goto(&return_result); 1172 assembler.Goto(&return_result);
1099 } 1173 }
1100 1174
1101 Bind(&rhs_is_not_smi); 1175 assembler.Bind(&rhs_is_not_smi);
1102 { 1176 {
1103 Node* rhs_map = LoadMap(rhs); 1177 Node* rhs_map = assembler.LoadMap(rhs);
1104 1178
1105 // Check if {rhs} is a HeapNumber. 1179 // Check if {rhs} is a HeapNumber.
1106 Label rhs_is_number(this), rhs_is_not_number(this, Label::kDeferred); 1180 Label rhs_is_number(&assembler),
1107 Branch(WordEqual(rhs_map, number_map), &rhs_is_number, 1181 rhs_is_not_number(&assembler, Label::kDeferred);
1108 &rhs_is_not_number); 1182 assembler.Branch(assembler.WordEqual(rhs_map, number_map),
1109 1183 &rhs_is_number, &rhs_is_not_number);
1110 Bind(&rhs_is_number); 1184
1185 assembler.Bind(&rhs_is_number);
1111 { 1186 {
1112 // Convert {lhs} to a double and multiply it with the value of {rhs}. 1187 // Convert {lhs} to a double and multiply it with the value of {rhs}.
1113 var_lhs_float64.Bind(SmiToFloat64(lhs)); 1188 var_lhs_float64.Bind(assembler.SmiToFloat64(lhs));
1114 var_rhs_float64.Bind(LoadHeapNumberValue(rhs)); 1189 var_rhs_float64.Bind(assembler.LoadHeapNumberValue(rhs));
1115 Goto(&do_fmul); 1190 assembler.Goto(&do_fmul);
1116 } 1191 }
1117 1192
1118 Bind(&rhs_is_not_number); 1193 assembler.Bind(&rhs_is_not_number);
1119 { 1194 {
1120 // Multiplication is commutative, swap {lhs} with {rhs} and loop. 1195 // Multiplication is commutative, swap {lhs} with {rhs} and loop.
1121 var_lhs.Bind(rhs); 1196 var_lhs.Bind(rhs);
1122 var_rhs.Bind(lhs); 1197 var_rhs.Bind(lhs);
1123 Goto(&loop); 1198 assembler.Goto(&loop);
1124 } 1199 }
1125 } 1200 }
1126 } 1201 }
1127 1202
1128 Bind(&lhs_is_not_smi); 1203 assembler.Bind(&lhs_is_not_smi);
1129 { 1204 {
1130 Node* lhs_map = LoadMap(lhs); 1205 Node* lhs_map = assembler.LoadMap(lhs);
1131 1206
1132 // Check if {lhs} is a HeapNumber. 1207 // Check if {lhs} is a HeapNumber.
1133 Label lhs_is_number(this), lhs_is_not_number(this, Label::kDeferred); 1208 Label lhs_is_number(&assembler),
1134 Branch(WordEqual(lhs_map, number_map), &lhs_is_number, 1209 lhs_is_not_number(&assembler, Label::kDeferred);
1135 &lhs_is_not_number); 1210 assembler.Branch(assembler.WordEqual(lhs_map, number_map), &lhs_is_number,
1136 1211 &lhs_is_not_number);
1137 Bind(&lhs_is_number); 1212
1213 assembler.Bind(&lhs_is_number);
1138 { 1214 {
1139 // Check if {rhs} is a Smi. 1215 // Check if {rhs} is a Smi.
1140 Label rhs_is_smi(this), rhs_is_not_smi(this); 1216 Label rhs_is_smi(&assembler), rhs_is_not_smi(&assembler);
1141 Branch(TaggedIsSmi(rhs), &rhs_is_smi, &rhs_is_not_smi); 1217 assembler.Branch(assembler.TaggedIsSmi(rhs), &rhs_is_smi,
1142 1218 &rhs_is_not_smi);
1143 Bind(&rhs_is_smi); 1219
1220 assembler.Bind(&rhs_is_smi);
1144 { 1221 {
1145 // Convert {rhs} to a double and multiply it with the value of {lhs}. 1222 // Convert {rhs} to a double and multiply it with the value of {lhs}.
1146 var_lhs_float64.Bind(LoadHeapNumberValue(lhs)); 1223 var_lhs_float64.Bind(assembler.LoadHeapNumberValue(lhs));
1147 var_rhs_float64.Bind(SmiToFloat64(rhs)); 1224 var_rhs_float64.Bind(assembler.SmiToFloat64(rhs));
1148 Goto(&do_fmul); 1225 assembler.Goto(&do_fmul);
1149 } 1226 }
1150 1227
1151 Bind(&rhs_is_not_smi); 1228 assembler.Bind(&rhs_is_not_smi);
1152 { 1229 {
1153 Node* rhs_map = LoadMap(rhs); 1230 Node* rhs_map = assembler.LoadMap(rhs);
1154 1231
1155 // Check if {rhs} is a HeapNumber. 1232 // Check if {rhs} is a HeapNumber.
1156 Label rhs_is_number(this), rhs_is_not_number(this, Label::kDeferred); 1233 Label rhs_is_number(&assembler),
1157 Branch(WordEqual(rhs_map, number_map), &rhs_is_number, 1234 rhs_is_not_number(&assembler, Label::kDeferred);
1158 &rhs_is_not_number); 1235 assembler.Branch(assembler.WordEqual(rhs_map, number_map),
1159 1236 &rhs_is_number, &rhs_is_not_number);
1160 Bind(&rhs_is_number); 1237
1238 assembler.Bind(&rhs_is_number);
1161 { 1239 {
1162 // Both {lhs} and {rhs} are HeapNumbers. Load their values and 1240 // Both {lhs} and {rhs} are HeapNumbers. Load their values and
1163 // multiply them. 1241 // multiply them.
1164 var_lhs_float64.Bind(LoadHeapNumberValue(lhs)); 1242 var_lhs_float64.Bind(assembler.LoadHeapNumberValue(lhs));
1165 var_rhs_float64.Bind(LoadHeapNumberValue(rhs)); 1243 var_rhs_float64.Bind(assembler.LoadHeapNumberValue(rhs));
1166 Goto(&do_fmul); 1244 assembler.Goto(&do_fmul);
1167 } 1245 }
1168 1246
1169 Bind(&rhs_is_not_number); 1247 assembler.Bind(&rhs_is_not_number);
1170 { 1248 {
1171 // Multiplication is commutative, swap {lhs} with {rhs} and loop. 1249 // Multiplication is commutative, swap {lhs} with {rhs} and loop.
1172 var_lhs.Bind(rhs); 1250 var_lhs.Bind(rhs);
1173 var_rhs.Bind(lhs); 1251 var_rhs.Bind(lhs);
1174 Goto(&loop); 1252 assembler.Goto(&loop);
1175 } 1253 }
1176 } 1254 }
1177 } 1255 }
1178 1256
1179 Bind(&lhs_is_not_number); 1257 assembler.Bind(&lhs_is_not_number);
1180 { 1258 {
1181 // Convert {lhs} to a Number and loop. 1259 // Convert {lhs} to a Number and loop.
1182 Callable callable = CodeFactory::NonNumberToNumber(isolate()); 1260 Callable callable = CodeFactory::NonNumberToNumber(assembler.isolate());
1183 var_lhs.Bind(CallStub(callable, context, lhs)); 1261 var_lhs.Bind(assembler.CallStub(callable, context, lhs));
1184 Goto(&loop); 1262 assembler.Goto(&loop);
1185 } 1263 }
1186 } 1264 }
1187 } 1265 }
1188 1266
1189 Bind(&do_fmul); 1267 assembler.Bind(&do_fmul);
1190 { 1268 {
1191 Node* value = Float64Mul(var_lhs_float64.value(), var_rhs_float64.value()); 1269 Node* value =
1192 Node* result = AllocateHeapNumberWithValue(value); 1270 assembler.Float64Mul(var_lhs_float64.value(), var_rhs_float64.value());
1271 Node* result = assembler.AllocateHeapNumberWithValue(value);
1193 var_result.Bind(result); 1272 var_result.Bind(result);
1194 Goto(&return_result); 1273 assembler.Goto(&return_result);
1195 } 1274 }
1196 1275
1197 Bind(&return_result); 1276 assembler.Bind(&return_result);
1198 Return(var_result.value()); 1277 assembler.Return(var_result.value());
1199 } 1278 }
1200 1279
1201 TF_BUILTIN(Divide, CodeStubAssembler) { 1280 void Builtins::Generate_Divide(compiler::CodeAssemblerState* state) {
1202 Node* left = Parameter(0); 1281 typedef CodeStubAssembler::Label Label;
1203 Node* right = Parameter(1); 1282 typedef compiler::Node Node;
1204 Node* context = Parameter(2); 1283 typedef CodeStubAssembler::Variable Variable;
1284 CodeStubAssembler assembler(state);
1285
1286 Node* left = assembler.Parameter(0);
1287 Node* right = assembler.Parameter(1);
1288 Node* context = assembler.Parameter(2);
1205 1289
1206 // Shared entry point for floating point division. 1290 // Shared entry point for floating point division.
1207 Label do_fdiv(this), end(this); 1291 Label do_fdiv(&assembler), end(&assembler);
1208 Variable var_dividend_float64(this, MachineRepresentation::kFloat64), 1292 Variable var_dividend_float64(&assembler, MachineRepresentation::kFloat64),
1209 var_divisor_float64(this, MachineRepresentation::kFloat64); 1293 var_divisor_float64(&assembler, MachineRepresentation::kFloat64);
1210 1294
1211 Node* number_map = HeapNumberMapConstant(); 1295 Node* number_map = assembler.HeapNumberMapConstant();
1212 1296
1213 // We might need to loop one or two times due to ToNumber conversions. 1297 // We might need to loop one or two times due to ToNumber conversions.
1214 Variable var_dividend(this, MachineRepresentation::kTagged), 1298 Variable var_dividend(&assembler, MachineRepresentation::kTagged),
1215 var_divisor(this, MachineRepresentation::kTagged), 1299 var_divisor(&assembler, MachineRepresentation::kTagged),
1216 var_result(this, MachineRepresentation::kTagged); 1300 var_result(&assembler, MachineRepresentation::kTagged);
1217 Variable* loop_variables[] = {&var_dividend, &var_divisor}; 1301 Variable* loop_variables[] = {&var_dividend, &var_divisor};
1218 Label loop(this, 2, loop_variables); 1302 Label loop(&assembler, 2, loop_variables);
1219 var_dividend.Bind(left); 1303 var_dividend.Bind(left);
1220 var_divisor.Bind(right); 1304 var_divisor.Bind(right);
1221 Goto(&loop); 1305 assembler.Goto(&loop);
1222 Bind(&loop); 1306 assembler.Bind(&loop);
1223 { 1307 {
1224 Node* dividend = var_dividend.value(); 1308 Node* dividend = var_dividend.value();
1225 Node* divisor = var_divisor.value(); 1309 Node* divisor = var_divisor.value();
1226 1310
1227 Label dividend_is_smi(this), dividend_is_not_smi(this); 1311 Label dividend_is_smi(&assembler), dividend_is_not_smi(&assembler);
1228 Branch(TaggedIsSmi(dividend), &dividend_is_smi, &dividend_is_not_smi); 1312 assembler.Branch(assembler.TaggedIsSmi(dividend), &dividend_is_smi,
1229 1313 &dividend_is_not_smi);
1230 Bind(&dividend_is_smi); 1314
1315 assembler.Bind(&dividend_is_smi);
1231 { 1316 {
1232 Label divisor_is_smi(this), divisor_is_not_smi(this); 1317 Label divisor_is_smi(&assembler), divisor_is_not_smi(&assembler);
1233 Branch(TaggedIsSmi(divisor), &divisor_is_smi, &divisor_is_not_smi); 1318 assembler.Branch(assembler.TaggedIsSmi(divisor), &divisor_is_smi,
1234 1319 &divisor_is_not_smi);
1235 Bind(&divisor_is_smi); 1320
1236 { 1321 assembler.Bind(&divisor_is_smi);
1237 Label bailout(this); 1322 {
1323 Label bailout(&assembler);
1238 1324
1239 // Do floating point division if {divisor} is zero. 1325 // Do floating point division if {divisor} is zero.
1240 GotoIf(WordEqual(divisor, IntPtrConstant(0)), &bailout); 1326 assembler.GotoIf(
1327 assembler.WordEqual(divisor, assembler.IntPtrConstant(0)),
1328 &bailout);
1241 1329
1242 // Do floating point division {dividend} is zero and {divisor} is 1330 // Do floating point division {dividend} is zero and {divisor} is
1243 // negative. 1331 // negative.
1244 Label dividend_is_zero(this), dividend_is_not_zero(this); 1332 Label dividend_is_zero(&assembler), dividend_is_not_zero(&assembler);
1245 Branch(WordEqual(dividend, IntPtrConstant(0)), &dividend_is_zero, 1333 assembler.Branch(
1246 &dividend_is_not_zero); 1334 assembler.WordEqual(dividend, assembler.IntPtrConstant(0)),
1247 1335 &dividend_is_zero, &dividend_is_not_zero);
1248 Bind(&dividend_is_zero); 1336
1249 { 1337 assembler.Bind(&dividend_is_zero);
1250 GotoIf(IntPtrLessThan(divisor, IntPtrConstant(0)), &bailout); 1338 {
1251 Goto(&dividend_is_not_zero); 1339 assembler.GotoIf(
1252 } 1340 assembler.IntPtrLessThan(divisor, assembler.IntPtrConstant(0)),
1253 Bind(&dividend_is_not_zero); 1341 &bailout);
1254 1342 assembler.Goto(&dividend_is_not_zero);
1255 Node* untagged_divisor = SmiUntag(divisor); 1343 }
1256 Node* untagged_dividend = SmiUntag(dividend); 1344 assembler.Bind(&dividend_is_not_zero);
1345
1346 Node* untagged_divisor = assembler.SmiUntag(divisor);
1347 Node* untagged_dividend = assembler.SmiUntag(dividend);
1257 1348
1258 // Do floating point division if {dividend} is kMinInt (or kMinInt - 1 1349 // Do floating point division if {dividend} is kMinInt (or kMinInt - 1
1259 // if the Smi size is 31) and {divisor} is -1. 1350 // if the Smi size is 31) and {divisor} is -1.
1260 Label divisor_is_minus_one(this), divisor_is_not_minus_one(this); 1351 Label divisor_is_minus_one(&assembler),
1261 Branch(Word32Equal(untagged_divisor, Int32Constant(-1)), 1352 divisor_is_not_minus_one(&assembler);
1262 &divisor_is_minus_one, &divisor_is_not_minus_one); 1353 assembler.Branch(assembler.Word32Equal(untagged_divisor,
1263 1354 assembler.Int32Constant(-1)),
1264 Bind(&divisor_is_minus_one); 1355 &divisor_is_minus_one, &divisor_is_not_minus_one);
1265 { 1356
1266 GotoIf( 1357 assembler.Bind(&divisor_is_minus_one);
1267 Word32Equal(untagged_dividend, 1358 {
1268 Int32Constant(kSmiValueSize == 32 ? kMinInt 1359 assembler.GotoIf(
1269 : (kMinInt >> 1))), 1360 assembler.Word32Equal(
1361 untagged_dividend,
1362 assembler.Int32Constant(
1363 kSmiValueSize == 32 ? kMinInt : (kMinInt >> 1))),
1270 &bailout); 1364 &bailout);
1271 Goto(&divisor_is_not_minus_one); 1365 assembler.Goto(&divisor_is_not_minus_one);
1272 } 1366 }
1273 Bind(&divisor_is_not_minus_one); 1367 assembler.Bind(&divisor_is_not_minus_one);
1274 1368
1275 // TODO(epertoso): consider adding a machine instruction that returns 1369 // TODO(epertoso): consider adding a machine instruction that returns
1276 // both the result and the remainder. 1370 // both the result and the remainder.
1277 Node* untagged_result = Int32Div(untagged_dividend, untagged_divisor); 1371 Node* untagged_result =
1278 Node* truncated = Int32Mul(untagged_result, untagged_divisor); 1372 assembler.Int32Div(untagged_dividend, untagged_divisor);
1373 Node* truncated = assembler.Int32Mul(untagged_result, untagged_divisor);
1279 // Do floating point division if the remainder is not 0. 1374 // Do floating point division if the remainder is not 0.
1280 GotoIf(Word32NotEqual(untagged_dividend, truncated), &bailout); 1375 assembler.GotoIf(assembler.Word32NotEqual(untagged_dividend, truncated),
1281 var_result.Bind(SmiTag(untagged_result)); 1376 &bailout);
1282 Goto(&end); 1377 var_result.Bind(assembler.SmiTag(untagged_result));
1378 assembler.Goto(&end);
1283 1379
1284 // Bailout: convert {dividend} and {divisor} to double and do double 1380 // Bailout: convert {dividend} and {divisor} to double and do double
1285 // division. 1381 // division.
1286 Bind(&bailout); 1382 assembler.Bind(&bailout);
1287 { 1383 {
1288 var_dividend_float64.Bind(SmiToFloat64(dividend)); 1384 var_dividend_float64.Bind(assembler.SmiToFloat64(dividend));
1289 var_divisor_float64.Bind(SmiToFloat64(divisor)); 1385 var_divisor_float64.Bind(assembler.SmiToFloat64(divisor));
1290 Goto(&do_fdiv); 1386 assembler.Goto(&do_fdiv);
1291 } 1387 }
1292 } 1388 }
1293 1389
1294 Bind(&divisor_is_not_smi); 1390 assembler.Bind(&divisor_is_not_smi);
1295 { 1391 {
1296 Node* divisor_map = LoadMap(divisor); 1392 Node* divisor_map = assembler.LoadMap(divisor);
1297 1393
1298 // Check if {divisor} is a HeapNumber. 1394 // Check if {divisor} is a HeapNumber.
1299 Label divisor_is_number(this), 1395 Label divisor_is_number(&assembler),
1300 divisor_is_not_number(this, Label::kDeferred); 1396 divisor_is_not_number(&assembler, Label::kDeferred);
1301 Branch(WordEqual(divisor_map, number_map), &divisor_is_number, 1397 assembler.Branch(assembler.WordEqual(divisor_map, number_map),
1302 &divisor_is_not_number); 1398 &divisor_is_number, &divisor_is_not_number);
1303 1399
1304 Bind(&divisor_is_number); 1400 assembler.Bind(&divisor_is_number);
1305 { 1401 {
1306 // Convert {dividend} to a double and divide it with the value of 1402 // Convert {dividend} to a double and divide it with the value of
1307 // {divisor}. 1403 // {divisor}.
1308 var_dividend_float64.Bind(SmiToFloat64(dividend)); 1404 var_dividend_float64.Bind(assembler.SmiToFloat64(dividend));
1309 var_divisor_float64.Bind(LoadHeapNumberValue(divisor)); 1405 var_divisor_float64.Bind(assembler.LoadHeapNumberValue(divisor));
1310 Goto(&do_fdiv); 1406 assembler.Goto(&do_fdiv);
1311 } 1407 }
1312 1408
1313 Bind(&divisor_is_not_number); 1409 assembler.Bind(&divisor_is_not_number);
1314 { 1410 {
1315 // Convert {divisor} to a number and loop. 1411 // Convert {divisor} to a number and loop.
1316 Callable callable = CodeFactory::NonNumberToNumber(isolate()); 1412 Callable callable =
1317 var_divisor.Bind(CallStub(callable, context, divisor)); 1413 CodeFactory::NonNumberToNumber(assembler.isolate());
1318 Goto(&loop); 1414 var_divisor.Bind(assembler.CallStub(callable, context, divisor));
1415 assembler.Goto(&loop);
1319 } 1416 }
1320 } 1417 }
1321 } 1418 }
1322 1419
1323 Bind(&dividend_is_not_smi); 1420 assembler.Bind(&dividend_is_not_smi);
1324 { 1421 {
1325 Node* dividend_map = LoadMap(dividend); 1422 Node* dividend_map = assembler.LoadMap(dividend);
1326 1423
1327 // Check if {dividend} is a HeapNumber. 1424 // Check if {dividend} is a HeapNumber.
1328 Label dividend_is_number(this), 1425 Label dividend_is_number(&assembler),
1329 dividend_is_not_number(this, Label::kDeferred); 1426 dividend_is_not_number(&assembler, Label::kDeferred);
1330 Branch(WordEqual(dividend_map, number_map), &dividend_is_number, 1427 assembler.Branch(assembler.WordEqual(dividend_map, number_map),
1331 &dividend_is_not_number); 1428 &dividend_is_number, &dividend_is_not_number);
1332 1429
1333 Bind(&dividend_is_number); 1430 assembler.Bind(&dividend_is_number);
1334 { 1431 {
1335 // Check if {divisor} is a Smi. 1432 // Check if {divisor} is a Smi.
1336 Label divisor_is_smi(this), divisor_is_not_smi(this); 1433 Label divisor_is_smi(&assembler), divisor_is_not_smi(&assembler);
1337 Branch(TaggedIsSmi(divisor), &divisor_is_smi, &divisor_is_not_smi); 1434 assembler.Branch(assembler.TaggedIsSmi(divisor), &divisor_is_smi,
1338 1435 &divisor_is_not_smi);
1339 Bind(&divisor_is_smi); 1436
1437 assembler.Bind(&divisor_is_smi);
1340 { 1438 {
1341 // Convert {divisor} to a double and use it for a floating point 1439 // Convert {divisor} to a double and use it for a floating point
1342 // division. 1440 // division.
1343 var_dividend_float64.Bind(LoadHeapNumberValue(dividend)); 1441 var_dividend_float64.Bind(assembler.LoadHeapNumberValue(dividend));
1344 var_divisor_float64.Bind(SmiToFloat64(divisor)); 1442 var_divisor_float64.Bind(assembler.SmiToFloat64(divisor));
1345 Goto(&do_fdiv); 1443 assembler.Goto(&do_fdiv);
1346 } 1444 }
1347 1445
1348 Bind(&divisor_is_not_smi); 1446 assembler.Bind(&divisor_is_not_smi);
1349 { 1447 {
1350 Node* divisor_map = LoadMap(divisor); 1448 Node* divisor_map = assembler.LoadMap(divisor);
1351 1449
1352 // Check if {divisor} is a HeapNumber. 1450 // Check if {divisor} is a HeapNumber.
1353 Label divisor_is_number(this), 1451 Label divisor_is_number(&assembler),
1354 divisor_is_not_number(this, Label::kDeferred); 1452 divisor_is_not_number(&assembler, Label::kDeferred);
1355 Branch(WordEqual(divisor_map, number_map), &divisor_is_number, 1453 assembler.Branch(assembler.WordEqual(divisor_map, number_map),
1356 &divisor_is_not_number); 1454 &divisor_is_number, &divisor_is_not_number);
1357 1455
1358 Bind(&divisor_is_number); 1456 assembler.Bind(&divisor_is_number);
1359 { 1457 {
1360 // Both {dividend} and {divisor} are HeapNumbers. Load their values 1458 // Both {dividend} and {divisor} are HeapNumbers. Load their values
1361 // and divide them. 1459 // and divide them.
1362 var_dividend_float64.Bind(LoadHeapNumberValue(dividend)); 1460 var_dividend_float64.Bind(assembler.LoadHeapNumberValue(dividend));
1363 var_divisor_float64.Bind(LoadHeapNumberValue(divisor)); 1461 var_divisor_float64.Bind(assembler.LoadHeapNumberValue(divisor));
1364 Goto(&do_fdiv); 1462 assembler.Goto(&do_fdiv);
1365 } 1463 }
1366 1464
1367 Bind(&divisor_is_not_number); 1465 assembler.Bind(&divisor_is_not_number);
1368 { 1466 {
1369 // Convert {divisor} to a number and loop. 1467 // Convert {divisor} to a number and loop.
1370 Callable callable = CodeFactory::NonNumberToNumber(isolate()); 1468 Callable callable =
1371 var_divisor.Bind(CallStub(callable, context, divisor)); 1469 CodeFactory::NonNumberToNumber(assembler.isolate());
1372 Goto(&loop); 1470 var_divisor.Bind(assembler.CallStub(callable, context, divisor));
1471 assembler.Goto(&loop);
1373 } 1472 }
1374 } 1473 }
1375 } 1474 }
1376 1475
1377 Bind(&dividend_is_not_number); 1476 assembler.Bind(&dividend_is_not_number);
1378 { 1477 {
1379 // Convert {dividend} to a Number and loop. 1478 // Convert {dividend} to a Number and loop.
1380 Callable callable = CodeFactory::NonNumberToNumber(isolate()); 1479 Callable callable = CodeFactory::NonNumberToNumber(assembler.isolate());
1381 var_dividend.Bind(CallStub(callable, context, dividend)); 1480 var_dividend.Bind(assembler.CallStub(callable, context, dividend));
1382 Goto(&loop); 1481 assembler.Goto(&loop);
1383 } 1482 }
1384 } 1483 }
1385 } 1484 }
1386 1485
1387 Bind(&do_fdiv); 1486 assembler.Bind(&do_fdiv);
1388 { 1487 {
1389 Node* value = 1488 Node* value = assembler.Float64Div(var_dividend_float64.value(),
1390 Float64Div(var_dividend_float64.value(), var_divisor_float64.value()); 1489 var_divisor_float64.value());
1391 var_result.Bind(AllocateHeapNumberWithValue(value)); 1490 var_result.Bind(assembler.AllocateHeapNumberWithValue(value));
1392 Goto(&end); 1491 assembler.Goto(&end);
1393 } 1492 }
1394 Bind(&end); 1493 assembler.Bind(&end);
1395 Return(var_result.value()); 1494 assembler.Return(var_result.value());
1396 } 1495 }
1397 1496
1398 TF_BUILTIN(Modulus, CodeStubAssembler) { 1497 void Builtins::Generate_Modulus(compiler::CodeAssemblerState* state) {
1399 Node* left = Parameter(0); 1498 typedef CodeStubAssembler::Label Label;
1400 Node* right = Parameter(1); 1499 typedef compiler::Node Node;
1401 Node* context = Parameter(2); 1500 typedef CodeStubAssembler::Variable Variable;
1402 1501 CodeStubAssembler assembler(state);
1403 Variable var_result(this, MachineRepresentation::kTagged); 1502
1404 Label return_result(this, &var_result); 1503 Node* left = assembler.Parameter(0);
1504 Node* right = assembler.Parameter(1);
1505 Node* context = assembler.Parameter(2);
1506
1507 Variable var_result(&assembler, MachineRepresentation::kTagged);
1508 Label return_result(&assembler, &var_result);
1405 1509
1406 // Shared entry point for floating point modulus. 1510 // Shared entry point for floating point modulus.
1407 Label do_fmod(this); 1511 Label do_fmod(&assembler);
1408 Variable var_dividend_float64(this, MachineRepresentation::kFloat64), 1512 Variable var_dividend_float64(&assembler, MachineRepresentation::kFloat64),
1409 var_divisor_float64(this, MachineRepresentation::kFloat64); 1513 var_divisor_float64(&assembler, MachineRepresentation::kFloat64);
1410 1514
1411 Node* number_map = HeapNumberMapConstant(); 1515 Node* number_map = assembler.HeapNumberMapConstant();
1412 1516
1413 // We might need to loop one or two times due to ToNumber conversions. 1517 // We might need to loop one or two times due to ToNumber conversions.
1414 Variable var_dividend(this, MachineRepresentation::kTagged), 1518 Variable var_dividend(&assembler, MachineRepresentation::kTagged),
1415 var_divisor(this, MachineRepresentation::kTagged); 1519 var_divisor(&assembler, MachineRepresentation::kTagged);
1416 Variable* loop_variables[] = {&var_dividend, &var_divisor}; 1520 Variable* loop_variables[] = {&var_dividend, &var_divisor};
1417 Label loop(this, 2, loop_variables); 1521 Label loop(&assembler, 2, loop_variables);
1418 var_dividend.Bind(left); 1522 var_dividend.Bind(left);
1419 var_divisor.Bind(right); 1523 var_divisor.Bind(right);
1420 Goto(&loop); 1524 assembler.Goto(&loop);
1421 Bind(&loop); 1525 assembler.Bind(&loop);
1422 { 1526 {
1423 Node* dividend = var_dividend.value(); 1527 Node* dividend = var_dividend.value();
1424 Node* divisor = var_divisor.value(); 1528 Node* divisor = var_divisor.value();
1425 1529
1426 Label dividend_is_smi(this), dividend_is_not_smi(this); 1530 Label dividend_is_smi(&assembler), dividend_is_not_smi(&assembler);
1427 Branch(TaggedIsSmi(dividend), &dividend_is_smi, &dividend_is_not_smi); 1531 assembler.Branch(assembler.TaggedIsSmi(dividend), &dividend_is_smi,
1428 1532 &dividend_is_not_smi);
1429 Bind(&dividend_is_smi); 1533
1534 assembler.Bind(&dividend_is_smi);
1430 { 1535 {
1431 Label dividend_is_not_zero(this); 1536 Label dividend_is_not_zero(&assembler);
1432 Label divisor_is_smi(this), divisor_is_not_smi(this); 1537 Label divisor_is_smi(&assembler), divisor_is_not_smi(&assembler);
1433 Branch(TaggedIsSmi(divisor), &divisor_is_smi, &divisor_is_not_smi); 1538 assembler.Branch(assembler.TaggedIsSmi(divisor), &divisor_is_smi,
1434 1539 &divisor_is_not_smi);
1435 Bind(&divisor_is_smi); 1540
1541 assembler.Bind(&divisor_is_smi);
1436 { 1542 {
1437 // Compute the modulus of two Smis. 1543 // Compute the modulus of two Smis.
1438 var_result.Bind(SmiMod(dividend, divisor)); 1544 var_result.Bind(assembler.SmiMod(dividend, divisor));
1439 Goto(&return_result); 1545 assembler.Goto(&return_result);
1440 } 1546 }
1441 1547
1442 Bind(&divisor_is_not_smi); 1548 assembler.Bind(&divisor_is_not_smi);
1443 { 1549 {
1444 Node* divisor_map = LoadMap(divisor); 1550 Node* divisor_map = assembler.LoadMap(divisor);
1445 1551
1446 // Check if {divisor} is a HeapNumber. 1552 // Check if {divisor} is a HeapNumber.
1447 Label divisor_is_number(this), 1553 Label divisor_is_number(&assembler),
1448 divisor_is_not_number(this, Label::kDeferred); 1554 divisor_is_not_number(&assembler, Label::kDeferred);
1449 Branch(WordEqual(divisor_map, number_map), &divisor_is_number, 1555 assembler.Branch(assembler.WordEqual(divisor_map, number_map),
1450 &divisor_is_not_number); 1556 &divisor_is_number, &divisor_is_not_number);
1451 1557
1452 Bind(&divisor_is_number); 1558 assembler.Bind(&divisor_is_number);
1453 { 1559 {
1454 // Convert {dividend} to a double and compute its modulus with the 1560 // Convert {dividend} to a double and compute its modulus with the
1455 // value of {dividend}. 1561 // value of {dividend}.
1456 var_dividend_float64.Bind(SmiToFloat64(dividend)); 1562 var_dividend_float64.Bind(assembler.SmiToFloat64(dividend));
1457 var_divisor_float64.Bind(LoadHeapNumberValue(divisor)); 1563 var_divisor_float64.Bind(assembler.LoadHeapNumberValue(divisor));
1458 Goto(&do_fmod); 1564 assembler.Goto(&do_fmod);
1459 } 1565 }
1460 1566
1461 Bind(&divisor_is_not_number); 1567 assembler.Bind(&divisor_is_not_number);
1462 { 1568 {
1463 // Convert {divisor} to a number and loop. 1569 // Convert {divisor} to a number and loop.
1464 Callable callable = CodeFactory::NonNumberToNumber(isolate()); 1570 Callable callable =
1465 var_divisor.Bind(CallStub(callable, context, divisor)); 1571 CodeFactory::NonNumberToNumber(assembler.isolate());
1466 Goto(&loop); 1572 var_divisor.Bind(assembler.CallStub(callable, context, divisor));
1573 assembler.Goto(&loop);
1467 } 1574 }
1468 } 1575 }
1469 } 1576 }
1470 1577
1471 Bind(&dividend_is_not_smi); 1578 assembler.Bind(&dividend_is_not_smi);
1472 { 1579 {
1473 Node* dividend_map = LoadMap(dividend); 1580 Node* dividend_map = assembler.LoadMap(dividend);
1474 1581
1475 // Check if {dividend} is a HeapNumber. 1582 // Check if {dividend} is a HeapNumber.
1476 Label dividend_is_number(this), 1583 Label dividend_is_number(&assembler),
1477 dividend_is_not_number(this, Label::kDeferred); 1584 dividend_is_not_number(&assembler, Label::kDeferred);
1478 Branch(WordEqual(dividend_map, number_map), &dividend_is_number, 1585 assembler.Branch(assembler.WordEqual(dividend_map, number_map),
1479 &dividend_is_not_number); 1586 &dividend_is_number, &dividend_is_not_number);
1480 1587
1481 Bind(&dividend_is_number); 1588 assembler.Bind(&dividend_is_number);
1482 { 1589 {
1483 // Check if {divisor} is a Smi. 1590 // Check if {divisor} is a Smi.
1484 Label divisor_is_smi(this), divisor_is_not_smi(this); 1591 Label divisor_is_smi(&assembler), divisor_is_not_smi(&assembler);
1485 Branch(TaggedIsSmi(divisor), &divisor_is_smi, &divisor_is_not_smi); 1592 assembler.Branch(assembler.TaggedIsSmi(divisor), &divisor_is_smi,
1486 1593 &divisor_is_not_smi);
1487 Bind(&divisor_is_smi); 1594
1595 assembler.Bind(&divisor_is_smi);
1488 { 1596 {
1489 // Convert {divisor} to a double and compute {dividend}'s modulus with 1597 // Convert {divisor} to a double and compute {dividend}'s modulus with
1490 // it. 1598 // it.
1491 var_dividend_float64.Bind(LoadHeapNumberValue(dividend)); 1599 var_dividend_float64.Bind(assembler.LoadHeapNumberValue(dividend));
1492 var_divisor_float64.Bind(SmiToFloat64(divisor)); 1600 var_divisor_float64.Bind(assembler.SmiToFloat64(divisor));
1493 Goto(&do_fmod); 1601 assembler.Goto(&do_fmod);
1494 } 1602 }
1495 1603
1496 Bind(&divisor_is_not_smi); 1604 assembler.Bind(&divisor_is_not_smi);
1497 { 1605 {
1498 Node* divisor_map = LoadMap(divisor); 1606 Node* divisor_map = assembler.LoadMap(divisor);
1499 1607
1500 // Check if {divisor} is a HeapNumber. 1608 // Check if {divisor} is a HeapNumber.
1501 Label divisor_is_number(this), 1609 Label divisor_is_number(&assembler),
1502 divisor_is_not_number(this, Label::kDeferred); 1610 divisor_is_not_number(&assembler, Label::kDeferred);
1503 Branch(WordEqual(divisor_map, number_map), &divisor_is_number, 1611 assembler.Branch(assembler.WordEqual(divisor_map, number_map),
1504 &divisor_is_not_number); 1612 &divisor_is_number, &divisor_is_not_number);
1505 1613
1506 Bind(&divisor_is_number); 1614 assembler.Bind(&divisor_is_number);
1507 { 1615 {
1508 // Both {dividend} and {divisor} are HeapNumbers. Load their values 1616 // Both {dividend} and {divisor} are HeapNumbers. Load their values
1509 // and compute their modulus. 1617 // and compute their modulus.
1510 var_dividend_float64.Bind(LoadHeapNumberValue(dividend)); 1618 var_dividend_float64.Bind(assembler.LoadHeapNumberValue(dividend));
1511 var_divisor_float64.Bind(LoadHeapNumberValue(divisor)); 1619 var_divisor_float64.Bind(assembler.LoadHeapNumberValue(divisor));
1512 Goto(&do_fmod); 1620 assembler.Goto(&do_fmod);
1513 } 1621 }
1514 1622
1515 Bind(&divisor_is_not_number); 1623 assembler.Bind(&divisor_is_not_number);
1516 { 1624 {
1517 // Convert {divisor} to a number and loop. 1625 // Convert {divisor} to a number and loop.
1518 Callable callable = CodeFactory::NonNumberToNumber(isolate()); 1626 Callable callable =
1519 var_divisor.Bind(CallStub(callable, context, divisor)); 1627 CodeFactory::NonNumberToNumber(assembler.isolate());
1520 Goto(&loop); 1628 var_divisor.Bind(assembler.CallStub(callable, context, divisor));
1629 assembler.Goto(&loop);
1521 } 1630 }
1522 } 1631 }
1523 } 1632 }
1524 1633
1525 Bind(&dividend_is_not_number); 1634 assembler.Bind(&dividend_is_not_number);
1526 { 1635 {
1527 // Convert {dividend} to a Number and loop. 1636 // Convert {dividend} to a Number and loop.
1528 Callable callable = CodeFactory::NonNumberToNumber(isolate()); 1637 Callable callable = CodeFactory::NonNumberToNumber(assembler.isolate());
1529 var_dividend.Bind(CallStub(callable, context, dividend)); 1638 var_dividend.Bind(assembler.CallStub(callable, context, dividend));
1530 Goto(&loop); 1639 assembler.Goto(&loop);
1531 } 1640 }
1532 } 1641 }
1533 } 1642 }
1534 1643
1535 Bind(&do_fmod); 1644 assembler.Bind(&do_fmod);
1536 { 1645 {
1537 Node* value = 1646 Node* value = assembler.Float64Mod(var_dividend_float64.value(),
1538 Float64Mod(var_dividend_float64.value(), var_divisor_float64.value()); 1647 var_divisor_float64.value());
1539 var_result.Bind(AllocateHeapNumberWithValue(value)); 1648 var_result.Bind(assembler.AllocateHeapNumberWithValue(value));
1540 Goto(&return_result); 1649 assembler.Goto(&return_result);
1541 } 1650 }
1542 1651
1543 Bind(&return_result); 1652 assembler.Bind(&return_result);
1544 Return(var_result.value()); 1653 assembler.Return(var_result.value());
1545 } 1654 }
1546 1655
1547 TF_BUILTIN(ShiftLeft, NumberBuiltinsAssembler) { 1656 void Builtins::Generate_ShiftLeft(compiler::CodeAssemblerState* state) {
1548 BitwiseShiftOp([this](Node* lhs, Node* shift_count) { 1657 using compiler::Node;
1549 return Word32Shl(lhs, shift_count); 1658 CodeStubAssembler assembler(state);
1550 }); 1659
1551 } 1660 Node* left = assembler.Parameter(0);
1552 1661 Node* right = assembler.Parameter(1);
1553 TF_BUILTIN(ShiftRight, NumberBuiltinsAssembler) { 1662 Node* context = assembler.Parameter(2);
1554 BitwiseShiftOp([this](Node* lhs, Node* shift_count) { 1663
1555 return Word32Sar(lhs, shift_count); 1664 Node* lhs_value = assembler.TruncateTaggedToWord32(context, left);
1556 }); 1665 Node* rhs_value = assembler.TruncateTaggedToWord32(context, right);
1557 } 1666 Node* shift_count =
1558 1667 assembler.Word32And(rhs_value, assembler.Int32Constant(0x1f));
1559 TF_BUILTIN(ShiftRightLogical, NumberBuiltinsAssembler) { 1668 Node* value = assembler.Word32Shl(lhs_value, shift_count);
1560 BitwiseShiftOp<kUnsigned>([this](Node* lhs, Node* shift_count) { 1669 Node* result = assembler.ChangeInt32ToTagged(value);
1561 return Word32Shr(lhs, shift_count); 1670 assembler.Return(result);
1562 }); 1671 }
1563 } 1672
1564 1673 void Builtins::Generate_ShiftRight(compiler::CodeAssemblerState* state) {
1565 TF_BUILTIN(BitwiseAnd, NumberBuiltinsAssembler) { 1674 using compiler::Node;
1566 BitwiseOp([this](Node* lhs, Node* rhs) { return Word32And(lhs, rhs); }); 1675 CodeStubAssembler assembler(state);
1567 } 1676
1568 1677 Node* left = assembler.Parameter(0);
1569 TF_BUILTIN(BitwiseOr, NumberBuiltinsAssembler) { 1678 Node* right = assembler.Parameter(1);
1570 BitwiseOp([this](Node* lhs, Node* rhs) { return Word32Or(lhs, rhs); }); 1679 Node* context = assembler.Parameter(2);
1571 } 1680
1572 1681 Node* lhs_value = assembler.TruncateTaggedToWord32(context, left);
1573 TF_BUILTIN(BitwiseXor, NumberBuiltinsAssembler) { 1682 Node* rhs_value = assembler.TruncateTaggedToWord32(context, right);
1574 BitwiseOp([this](Node* lhs, Node* rhs) { return Word32Xor(lhs, rhs); }); 1683 Node* shift_count =
1575 } 1684 assembler.Word32And(rhs_value, assembler.Int32Constant(0x1f));
1576 1685 Node* value = assembler.Word32Sar(lhs_value, shift_count);
1577 TF_BUILTIN(LessThan, NumberBuiltinsAssembler) { 1686 Node* result = assembler.ChangeInt32ToTagged(value);
1578 RelationalComparisonBuiltin(kLessThan); 1687 assembler.Return(result);
1579 } 1688 }
1580 1689
1581 TF_BUILTIN(LessThanOrEqual, NumberBuiltinsAssembler) { 1690 void Builtins::Generate_ShiftRightLogical(compiler::CodeAssemblerState* state) {
1582 RelationalComparisonBuiltin(kLessThanOrEqual); 1691 using compiler::Node;
1583 } 1692 CodeStubAssembler assembler(state);
1584 1693
1585 TF_BUILTIN(GreaterThan, NumberBuiltinsAssembler) { 1694 Node* left = assembler.Parameter(0);
1586 RelationalComparisonBuiltin(kGreaterThan); 1695 Node* right = assembler.Parameter(1);
1587 } 1696 Node* context = assembler.Parameter(2);
1588 1697
1589 TF_BUILTIN(GreaterThanOrEqual, NumberBuiltinsAssembler) { 1698 Node* lhs_value = assembler.TruncateTaggedToWord32(context, left);
1590 RelationalComparisonBuiltin(kGreaterThanOrEqual); 1699 Node* rhs_value = assembler.TruncateTaggedToWord32(context, right);
1591 } 1700 Node* shift_count =
1592 1701 assembler.Word32And(rhs_value, assembler.Int32Constant(0x1f));
1593 TF_BUILTIN(Equal, CodeStubAssembler) { 1702 Node* value = assembler.Word32Shr(lhs_value, shift_count);
1594 Node* lhs = Parameter(0); 1703 Node* result = assembler.ChangeUint32ToTagged(value);
1595 Node* rhs = Parameter(1); 1704 assembler.Return(result);
1596 Node* context = Parameter(2); 1705 }
1597 1706
1598 Return(Equal(kDontNegateResult, lhs, rhs, context)); 1707 void Builtins::Generate_BitwiseAnd(compiler::CodeAssemblerState* state) {
1599 } 1708 CodeStubAssembler assembler(state);
1600 1709 using compiler::Node;
1601 TF_BUILTIN(NotEqual, CodeStubAssembler) { 1710
1602 Node* lhs = Parameter(0); 1711 Node* left = assembler.Parameter(0);
1603 Node* rhs = Parameter(1); 1712 Node* right = assembler.Parameter(1);
1604 Node* context = Parameter(2); 1713 Node* context = assembler.Parameter(2);
1605 1714
1606 Return(Equal(kNegateResult, lhs, rhs, context)); 1715 Node* lhs_value = assembler.TruncateTaggedToWord32(context, left);
1607 } 1716 Node* rhs_value = assembler.TruncateTaggedToWord32(context, right);
1608 1717 Node* value = assembler.Word32And(lhs_value, rhs_value);
1609 TF_BUILTIN(StrictEqual, CodeStubAssembler) { 1718 Node* result = assembler.ChangeInt32ToTagged(value);
1610 Node* lhs = Parameter(0); 1719 assembler.Return(result);
1611 Node* rhs = Parameter(1); 1720 }
1612 Node* context = Parameter(2); 1721
1613 1722 void Builtins::Generate_BitwiseOr(compiler::CodeAssemblerState* state) {
1614 Return(StrictEqual(kDontNegateResult, lhs, rhs, context)); 1723 CodeStubAssembler assembler(state);
1615 } 1724 using compiler::Node;
1616 1725
1617 TF_BUILTIN(StrictNotEqual, CodeStubAssembler) { 1726 Node* left = assembler.Parameter(0);
1618 Node* lhs = Parameter(0); 1727 Node* right = assembler.Parameter(1);
1619 Node* rhs = Parameter(1); 1728 Node* context = assembler.Parameter(2);
1620 Node* context = Parameter(2); 1729
1621 1730 Node* lhs_value = assembler.TruncateTaggedToWord32(context, left);
1622 Return(StrictEqual(kNegateResult, lhs, rhs, context)); 1731 Node* rhs_value = assembler.TruncateTaggedToWord32(context, right);
1732 Node* value = assembler.Word32Or(lhs_value, rhs_value);
1733 Node* result = assembler.ChangeInt32ToTagged(value);
1734 assembler.Return(result);
1735 }
1736
1737 void Builtins::Generate_BitwiseXor(compiler::CodeAssemblerState* state) {
1738 CodeStubAssembler assembler(state);
1739 using compiler::Node;
1740
1741 Node* left = assembler.Parameter(0);
1742 Node* right = assembler.Parameter(1);
1743 Node* context = assembler.Parameter(2);
1744
1745 Node* lhs_value = assembler.TruncateTaggedToWord32(context, left);
1746 Node* rhs_value = assembler.TruncateTaggedToWord32(context, right);
1747 Node* value = assembler.Word32Xor(lhs_value, rhs_value);
1748 Node* result = assembler.ChangeInt32ToTagged(value);
1749 assembler.Return(result);
1750 }
1751
1752 void Builtins::Generate_LessThan(compiler::CodeAssemblerState* state) {
1753 CodeStubAssembler assembler(state);
1754 compiler::Node* lhs = assembler.Parameter(0);
1755 compiler::Node* rhs = assembler.Parameter(1);
1756 compiler::Node* context = assembler.Parameter(2);
1757
1758 assembler.Return(assembler.RelationalComparison(CodeStubAssembler::kLessThan,
1759 lhs, rhs, context));
1760 }
1761
1762 void Builtins::Generate_LessThanOrEqual(compiler::CodeAssemblerState* state) {
1763 CodeStubAssembler assembler(state);
1764 compiler::Node* lhs = assembler.Parameter(0);
1765 compiler::Node* rhs = assembler.Parameter(1);
1766 compiler::Node* context = assembler.Parameter(2);
1767
1768 assembler.Return(assembler.RelationalComparison(
1769 CodeStubAssembler::kLessThanOrEqual, lhs, rhs, context));
1770 }
1771
1772 void Builtins::Generate_GreaterThan(compiler::CodeAssemblerState* state) {
1773 CodeStubAssembler assembler(state);
1774 compiler::Node* lhs = assembler.Parameter(0);
1775 compiler::Node* rhs = assembler.Parameter(1);
1776 compiler::Node* context = assembler.Parameter(2);
1777
1778 assembler.Return(assembler.RelationalComparison(
1779 CodeStubAssembler::kGreaterThan, lhs, rhs, context));
1780 }
1781
1782 void Builtins::Generate_GreaterThanOrEqual(
1783 compiler::CodeAssemblerState* state) {
1784 CodeStubAssembler assembler(state);
1785 compiler::Node* lhs = assembler.Parameter(0);
1786 compiler::Node* rhs = assembler.Parameter(1);
1787 compiler::Node* context = assembler.Parameter(2);
1788
1789 assembler.Return(assembler.RelationalComparison(
1790 CodeStubAssembler::kGreaterThanOrEqual, lhs, rhs, context));
1791 }
1792
1793 void Builtins::Generate_Equal(compiler::CodeAssemblerState* state) {
1794 CodeStubAssembler assembler(state);
1795 compiler::Node* lhs = assembler.Parameter(0);
1796 compiler::Node* rhs = assembler.Parameter(1);
1797 compiler::Node* context = assembler.Parameter(2);
1798
1799 assembler.Return(
1800 assembler.Equal(CodeStubAssembler::kDontNegateResult, lhs, rhs, context));
1801 }
1802
1803 void Builtins::Generate_NotEqual(compiler::CodeAssemblerState* state) {
1804 CodeStubAssembler assembler(state);
1805 compiler::Node* lhs = assembler.Parameter(0);
1806 compiler::Node* rhs = assembler.Parameter(1);
1807 compiler::Node* context = assembler.Parameter(2);
1808
1809 assembler.Return(
1810 assembler.Equal(CodeStubAssembler::kNegateResult, lhs, rhs, context));
1811 }
1812
1813 void Builtins::Generate_StrictEqual(compiler::CodeAssemblerState* state) {
1814 CodeStubAssembler assembler(state);
1815 compiler::Node* lhs = assembler.Parameter(0);
1816 compiler::Node* rhs = assembler.Parameter(1);
1817 compiler::Node* context = assembler.Parameter(2);
1818
1819 assembler.Return(assembler.StrictEqual(CodeStubAssembler::kDontNegateResult,
1820 lhs, rhs, context));
1821 }
1822
1823 void Builtins::Generate_StrictNotEqual(compiler::CodeAssemblerState* state) {
1824 CodeStubAssembler assembler(state);
1825 compiler::Node* lhs = assembler.Parameter(0);
1826 compiler::Node* rhs = assembler.Parameter(1);
1827 compiler::Node* context = assembler.Parameter(2);
1828
1829 assembler.Return(assembler.StrictEqual(CodeStubAssembler::kNegateResult, lhs,
1830 rhs, context));
1623 } 1831 }
1624 1832
1625 } // namespace internal 1833 } // namespace internal
1626 } // namespace v8 1834 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/builtins/builtins-utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698