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

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

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

Powered by Google App Engine
This is Rietveld 408576698