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

Side by Side Diff: src/compiler/code-stub-assembler.cc

Issue 1841993002: [builtins] Make Math.ceil, Math.trunc and Math.round optimizable. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 8 months 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/compiler/code-stub-assembler.h ('k') | src/compiler/js-builtin-reducer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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/compiler/code-stub-assembler.h" 5 #include "src/compiler/code-stub-assembler.h"
6 6
7 #include <ostream> 7 #include <ostream>
8 8
9 #include "src/code-factory.h" 9 #include "src/code-factory.h"
10 #include "src/compiler/graph.h" 10 #include "src/compiler/graph.h"
(...skipping 29 matching lines...) Expand all
40 int parameter_count, Code::Flags flags, 40 int parameter_count, Code::Flags flags,
41 const char* name) 41 const char* name)
42 : CodeStubAssembler(isolate, zone, Linkage::GetJSCallDescriptor( 42 : CodeStubAssembler(isolate, zone, Linkage::GetJSCallDescriptor(
43 zone, false, parameter_count, 43 zone, false, parameter_count,
44 CallDescriptor::kNoFlags), 44 CallDescriptor::kNoFlags),
45 flags, name) {} 45 flags, name) {}
46 46
47 CodeStubAssembler::CodeStubAssembler(Isolate* isolate, Zone* zone, 47 CodeStubAssembler::CodeStubAssembler(Isolate* isolate, Zone* zone,
48 CallDescriptor* call_descriptor, 48 CallDescriptor* call_descriptor,
49 Code::Flags flags, const char* name) 49 Code::Flags flags, const char* name)
50 : raw_assembler_(new RawMachineAssembler(isolate, new (zone) Graph(zone), 50 : raw_assembler_(new RawMachineAssembler(
51 call_descriptor)), 51 isolate, new (zone) Graph(zone), call_descriptor,
52 MachineType::PointerRepresentation(),
53 InstructionSelector::SupportedMachineOperatorFlags())),
52 flags_(flags), 54 flags_(flags),
53 name_(name), 55 name_(name),
54 code_generated_(false), 56 code_generated_(false),
55 variables_(zone) {} 57 variables_(zone) {}
56 58
57 CodeStubAssembler::~CodeStubAssembler() {} 59 CodeStubAssembler::~CodeStubAssembler() {}
58 60
59 void CodeStubAssembler::CallPrologue() {} 61 void CodeStubAssembler::CallPrologue() {}
60 62
61 void CodeStubAssembler::CallEpilogue() {} 63 void CodeStubAssembler::CallEpilogue() {}
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 } 147 }
146 148
147 Node* CodeStubAssembler::LoadStackPointer() { 149 Node* CodeStubAssembler::LoadStackPointer() {
148 return raw_assembler_->LoadStackPointer(); 150 return raw_assembler_->LoadStackPointer();
149 } 151 }
150 152
151 Node* CodeStubAssembler::SmiShiftBitsConstant() { 153 Node* CodeStubAssembler::SmiShiftBitsConstant() {
152 return IntPtrConstant(kSmiShiftSize + kSmiTagSize); 154 return IntPtrConstant(kSmiShiftSize + kSmiTagSize);
153 } 155 }
154 156
157 Node* CodeStubAssembler::Float64Round(Node* x) {
158 Node* one = Float64Constant(1.0);
159 Node* one_half = Float64Constant(0.5);
160
161 Variable var_x(this, MachineRepresentation::kFloat64);
162 Label return_x(this);
163
164 // Round up {x} towards Infinity.
165 var_x.Bind(Float64Ceil(x));
166
167 GotoIf(Float64LessThanOrEqual(Float64Sub(var_x.value(), one_half), x),
168 &return_x);
169 var_x.Bind(Float64Sub(var_x.value(), one));
170 Goto(&return_x);
171
172 Bind(&return_x);
173 return var_x.value();
174 }
175
176 Node* CodeStubAssembler::Float64Ceil(Node* x) {
177 if (raw_assembler_->machine()->Float64RoundUp().IsSupported()) {
178 return raw_assembler_->Float64RoundUp(x);
179 }
180
181 Node* one = Float64Constant(1.0);
182 Node* zero = Float64Constant(0.0);
183 Node* two_52 = Float64Constant(4503599627370496.0E0);
184 Node* minus_two_52 = Float64Constant(-4503599627370496.0E0);
185
186 Variable var_x(this, MachineRepresentation::kFloat64);
187 Label return_x(this), return_minus_x(this);
188 var_x.Bind(x);
189
190 // Check if {x} is greater than zero.
191 Label if_xgreaterthanzero(this), if_xnotgreaterthanzero(this);
192 Branch(Float64GreaterThan(x, zero), &if_xgreaterthanzero,
193 &if_xnotgreaterthanzero);
194
195 Bind(&if_xgreaterthanzero);
196 {
197 // Just return {x} unless it's in the range ]0,2^52[.
198 GotoIf(Float64GreaterThanOrEqual(x, two_52), &return_x);
199
200 // Round positive {x} towards Infinity.
201 var_x.Bind(Float64Sub(Float64Add(two_52, x), two_52));
202 GotoUnless(Float64LessThan(var_x.value(), x), &return_x);
203 var_x.Bind(Float64Add(var_x.value(), one));
204 Goto(&return_x);
205 }
206
207 Bind(&if_xnotgreaterthanzero);
208 {
209 // Just return {x} unless it's in the range ]-2^52,0[
210 GotoIf(Float64LessThanOrEqual(x, minus_two_52), &return_x);
211 GotoUnless(Float64LessThan(x, zero), &return_x);
212
213 // Round negated {x} towards Infinity and return the result negated.
214 Node* minus_x = Float64Neg(x);
215 var_x.Bind(Float64Sub(Float64Add(two_52, minus_x), two_52));
216 GotoUnless(Float64GreaterThan(var_x.value(), minus_x), &return_minus_x);
217 var_x.Bind(Float64Sub(var_x.value(), one));
218 Goto(&return_minus_x);
219 }
220
221 Bind(&return_minus_x);
222 var_x.Bind(Float64Neg(var_x.value()));
223 Goto(&return_x);
224
225 Bind(&return_x);
226 return var_x.value();
227 }
228
155 Node* CodeStubAssembler::Float64Floor(Node* x) { 229 Node* CodeStubAssembler::Float64Floor(Node* x) {
156 if (raw_assembler_->machine()->Float64RoundDown().IsSupported()) { 230 if (raw_assembler_->machine()->Float64RoundDown().IsSupported()) {
157 return raw_assembler_->Float64RoundDown(x); 231 return raw_assembler_->Float64RoundDown(x);
158 } 232 }
159 233
234 Node* one = Float64Constant(1.0);
235 Node* zero = Float64Constant(0.0);
160 Node* two_52 = Float64Constant(4503599627370496.0E0); 236 Node* two_52 = Float64Constant(4503599627370496.0E0);
161 Node* minus_two_52 = Float64Constant(-4503599627370496.0E0); 237 Node* minus_two_52 = Float64Constant(-4503599627370496.0E0);
162 238
163 Variable var_x(this, MachineRepresentation::kFloat64); 239 Variable var_x(this, MachineRepresentation::kFloat64);
240 Label return_x(this), return_minus_x(this);
164 var_x.Bind(x); 241 var_x.Bind(x);
165 242
166 Label return_x(this); 243 // Check if {x} is greater than zero.
244 Label if_xgreaterthanzero(this), if_xnotgreaterthanzero(this);
245 Branch(Float64GreaterThan(x, zero), &if_xgreaterthanzero,
246 &if_xnotgreaterthanzero);
167 247
168 // Check if {x} is a large positive integer. 248 Bind(&if_xgreaterthanzero);
169 Label if_xlargeposint(this), if_xnotlargeposint(this); 249 {
170 Branch(Float64GreaterThanOrEqual(x, two_52), &if_xlargeposint, 250 // Just return {x} unless it's in the range ]0,2^52[.
171 &if_xnotlargeposint); 251 GotoIf(Float64GreaterThanOrEqual(x, two_52), &return_x);
172 252
173 Bind(&if_xlargeposint); 253 // Round positive {x} towards -Infinity.
174 { 254 var_x.Bind(Float64Sub(Float64Add(two_52, x), two_52));
175 // The {x} is already an even integer. 255 GotoUnless(Float64GreaterThan(var_x.value(), x), &return_x);
256 var_x.Bind(Float64Sub(var_x.value(), one));
176 Goto(&return_x); 257 Goto(&return_x);
177 } 258 }
178 259
179 Bind(&if_xnotlargeposint); 260 Bind(&if_xnotgreaterthanzero);
180 { 261 {
181 // Check if {x} is negative. 262 // Just return {x} unless it's in the range ]-2^52,0[
182 Label if_xnegative(this), if_xpositive(this); 263 GotoIf(Float64LessThanOrEqual(x, minus_two_52), &return_x);
183 Branch(Float64LessThan(x, Float64Constant(0.0)), &if_xnegative, 264 GotoUnless(Float64LessThan(x, zero), &return_x);
184 &if_xpositive);
185 265
186 Bind(&if_xnegative); 266 // Round negated {x} towards -Infinity and return the result negated.
187 { 267 Node* minus_x = Float64Neg(x);
188 // Check if {x} is a large negative integer. 268 var_x.Bind(Float64Sub(Float64Add(two_52, minus_x), two_52));
189 Label if_xlargenegint(this), if_xnotlargenegint(this); 269 GotoUnless(Float64LessThan(var_x.value(), minus_x), &return_minus_x);
190 Branch(Float64LessThanOrEqual(x, minus_two_52), &if_xlargenegint, 270 var_x.Bind(Float64Add(var_x.value(), one));
191 &if_xnotlargenegint); 271 Goto(&return_minus_x);
272 }
192 273
193 Bind(&if_xlargenegint); 274 Bind(&return_minus_x);
194 { 275 var_x.Bind(Float64Neg(var_x.value()));
195 // The {x} is already an even integer. 276 Goto(&return_x);
196 Goto(&return_x);
197 }
198
199 Bind(&if_xnotlargenegint);
200 {
201 // Round negative {x} towards -Infinity.
202 Node* z = Float64Sub(Float64Constant(-0.0), x);
203 Node* y = Float64Sub(Float64Add(two_52, z), two_52);
204
205 // Check if we need to adjust {y}.
206 Label if_adjust(this), if_notadjust(this);
207 Branch(Float64GreaterThan(z, y), &if_adjust, &if_notadjust);
208
209 Bind(&if_adjust);
210 {
211 var_x.Bind(Float64Sub(Float64Constant(-1.0), y));
212 Goto(&return_x);
213 }
214
215 Bind(&if_notadjust);
216 {
217 var_x.Bind(Float64Sub(Float64Constant(-0.0), y));
218 Goto(&return_x);
219 }
220 }
221 }
222
223 Bind(&if_xpositive);
224 {
225 // Check if {x} is zero (either positive or negative).
226 Label if_xzero(this), if_xnotzero(this);
227 Branch(Float64Equal(x, Float64Constant(0.0)), &if_xzero, &if_xnotzero);
228
229 Bind(&if_xzero);
230 {
231 // We have to return both 0.0 and -0.0 as is.
232 Goto(&return_x);
233 }
234
235 Bind(&if_xnotzero);
236 {
237 // Round positive {x} towards -Infinity.
238 Node* y = Float64Sub(Float64Add(two_52, x), two_52);
239
240 // Check if we need to adjust {y}.
241 Label if_adjust(this), if_notadjust(this);
242 Branch(Float64LessThan(x, y), &if_adjust, &if_notadjust);
243
244 Bind(&if_adjust);
245 {
246 var_x.Bind(Float64Sub(y, Float64Constant(1.0)));
247 Goto(&return_x);
248 }
249
250 Bind(&if_notadjust);
251 {
252 var_x.Bind(y);
253 Goto(&return_x);
254 }
255 }
256 }
257 }
258 277
259 Bind(&return_x); 278 Bind(&return_x);
260 return var_x.value(); 279 return var_x.value();
261 } 280 }
281
282 Node* CodeStubAssembler::Float64Trunc(Node* x) {
283 if (raw_assembler_->machine()->Float64RoundTruncate().IsSupported()) {
284 return raw_assembler_->Float64RoundTruncate(x);
285 }
286
287 Node* one = Float64Constant(1.0);
288 Node* zero = Float64Constant(0.0);
289 Node* two_52 = Float64Constant(4503599627370496.0E0);
290 Node* minus_two_52 = Float64Constant(-4503599627370496.0E0);
291
292 Variable var_x(this, MachineRepresentation::kFloat64);
293 Label return_x(this), return_minus_x(this);
294 var_x.Bind(x);
295
296 // Check if {x} is greater than 0.
297 Label if_xgreaterthanzero(this), if_xnotgreaterthanzero(this);
298 Branch(Float64GreaterThan(x, zero), &if_xgreaterthanzero,
299 &if_xnotgreaterthanzero);
300
301 Bind(&if_xgreaterthanzero);
302 {
303 if (raw_assembler_->machine()->Float64RoundDown().IsSupported()) {
304 var_x.Bind(raw_assembler_->Float64RoundDown(x));
305 } else {
306 // Just return {x} unless it's in the range ]0,2^52[.
307 GotoIf(Float64GreaterThanOrEqual(x, two_52), &return_x);
308
309 // Round positive {x} towards -Infinity.
310 var_x.Bind(Float64Sub(Float64Add(two_52, x), two_52));
311 GotoUnless(Float64GreaterThan(var_x.value(), x), &return_x);
312 var_x.Bind(Float64Sub(var_x.value(), one));
313 }
314 Goto(&return_x);
315 }
316
317 Bind(&if_xnotgreaterthanzero);
318 {
319 if (raw_assembler_->machine()->Float64RoundUp().IsSupported()) {
320 var_x.Bind(raw_assembler_->Float64RoundUp(x));
321 Goto(&return_x);
322 } else {
323 // Just return {x} unless its in the range ]-2^52,0[.
324 GotoIf(Float64LessThanOrEqual(x, minus_two_52), &return_x);
325 GotoUnless(Float64LessThan(x, zero), &return_x);
326
327 // Round negated {x} towards -Infinity and return result negated.
328 Node* minus_x = Float64Neg(x);
329 var_x.Bind(Float64Sub(Float64Add(two_52, minus_x), two_52));
330 GotoUnless(Float64GreaterThan(var_x.value(), minus_x), &return_minus_x);
331 var_x.Bind(Float64Sub(var_x.value(), one));
332 Goto(&return_minus_x);
333 }
334 }
335
336 Bind(&return_minus_x);
337 var_x.Bind(Float64Neg(var_x.value()));
338 Goto(&return_x);
339
340 Bind(&return_x);
341 return var_x.value();
342 }
262 343
263 Node* CodeStubAssembler::SmiTag(Node* value) { 344 Node* CodeStubAssembler::SmiTag(Node* value) {
264 return raw_assembler_->WordShl(value, SmiShiftBitsConstant()); 345 return raw_assembler_->WordShl(value, SmiShiftBitsConstant());
265 } 346 }
266 347
267 Node* CodeStubAssembler::SmiUntag(Node* value) { 348 Node* CodeStubAssembler::SmiUntag(Node* value) {
268 return raw_assembler_->WordSar(value, SmiShiftBitsConstant()); 349 return raw_assembler_->WordSar(value, SmiShiftBitsConstant());
269 } 350 }
270 351
271 Node* CodeStubAssembler::SmiToWord32(Node* value) { 352 Node* CodeStubAssembler::SmiToWord32(Node* value) {
(...skipping 757 matching lines...) Expand 10 before | Expand all | Expand 10 after
1029 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties, 1110 CallDescriptor::kSupportsTailCalls, Operator::kNoProperties,
1030 MachineType::AnyTagged(), result_size); 1111 MachineType::AnyTagged(), result_size);
1031 return raw_assembler_->TailCallN(descriptor, code_target, args); 1112 return raw_assembler_->TailCallN(descriptor, code_target, args);
1032 } 1113 }
1033 1114
1034 void CodeStubAssembler::Goto(CodeStubAssembler::Label* label) { 1115 void CodeStubAssembler::Goto(CodeStubAssembler::Label* label) {
1035 label->MergeVariables(); 1116 label->MergeVariables();
1036 raw_assembler_->Goto(label->label_); 1117 raw_assembler_->Goto(label->label_);
1037 } 1118 }
1038 1119
1120 void CodeStubAssembler::GotoIf(Node* condition, Label* true_label) {
1121 Label false_label(this);
1122 Branch(condition, true_label, &false_label);
1123 Bind(&false_label);
1124 }
1125
1126 void CodeStubAssembler::GotoUnless(Node* condition, Label* false_label) {
1127 Label true_label(this);
1128 Branch(condition, &true_label, false_label);
1129 Bind(&true_label);
1130 }
1131
1039 void CodeStubAssembler::Branch(Node* condition, 1132 void CodeStubAssembler::Branch(Node* condition,
1040 CodeStubAssembler::Label* true_label, 1133 CodeStubAssembler::Label* true_label,
1041 CodeStubAssembler::Label* false_label) { 1134 CodeStubAssembler::Label* false_label) {
1042 true_label->MergeVariables(); 1135 true_label->MergeVariables();
1043 false_label->MergeVariables(); 1136 false_label->MergeVariables();
1044 return raw_assembler_->Branch(condition, true_label->label_, 1137 return raw_assembler_->Branch(condition, true_label->label_,
1045 false_label->label_); 1138 false_label->label_);
1046 } 1139 }
1047 1140
1048 void CodeStubAssembler::Switch(Node* index, Label* default_label, 1141 void CodeStubAssembler::Switch(Node* index, Label* default_label,
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
1215 } 1308 }
1216 } 1309 }
1217 } 1310 }
1218 1311
1219 bound_ = true; 1312 bound_ = true;
1220 } 1313 }
1221 1314
1222 } // namespace compiler 1315 } // namespace compiler
1223 } // namespace internal 1316 } // namespace internal
1224 } // namespace v8 1317 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/code-stub-assembler.h ('k') | src/compiler/js-builtin-reducer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698