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

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

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