OLD | NEW |
---|---|
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 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
145 } | 145 } |
146 | 146 |
147 Node* CodeStubAssembler::LoadStackPointer() { | 147 Node* CodeStubAssembler::LoadStackPointer() { |
148 return raw_assembler_->LoadStackPointer(); | 148 return raw_assembler_->LoadStackPointer(); |
149 } | 149 } |
150 | 150 |
151 Node* CodeStubAssembler::SmiShiftBitsConstant() { | 151 Node* CodeStubAssembler::SmiShiftBitsConstant() { |
152 return IntPtrConstant(kSmiShiftSize + kSmiTagSize); | 152 return IntPtrConstant(kSmiShiftSize + kSmiTagSize); |
153 } | 153 } |
154 | 154 |
155 Node* CodeStubAssembler::Float64Floor(Node* x) { | |
156 if (raw_assembler_->machine()->Float64RoundDown().IsSupported()) { | |
157 return raw_assembler_->Float64RoundDown(x); | |
158 } | |
159 | |
160 Node* two_52 = Float64Constant(4503599627370496.0E0); | |
161 Node* minus_two_52 = Float64Constant(-4503599627370496.0E0); | |
162 | |
163 Variable var_x(this, MachineRepresentation::kFloat64); | |
164 var_x.Bind(x); | |
165 | |
166 Label return_x(this); | |
167 | |
168 // Check if {x} is a large positive integer. | |
169 Label if_xlargeposint(this), if_xnotlargeposint(this); | |
170 Branch(Float64GreaterThanOrEqual(x, two_52), &if_xlargeposint, | |
171 &if_xnotlargeposint); | |
172 | |
173 Bind(&if_xlargeposint); | |
174 { | |
175 // The {x} is already an even integer. | |
176 Goto(&return_x); | |
177 } | |
178 | |
179 Bind(&if_xnotlargeposint); | |
180 { | |
181 // Check if {x} is negative. | |
182 Label if_xnegative(this), if_xpositive(this); | |
183 Branch(Float64LessThan(x, Float64Constant(0.0)), &if_xnegative, | |
184 &if_xpositive); | |
185 | |
186 Bind(&if_xnegative); | |
187 { | |
188 // Check if {x} is a large negative integer. | |
189 Label if_xlargenegint(this), if_xnotlargenegint(this); | |
190 Branch(Float64LessThanOrEqual(x, minus_two_52), &if_xlargenegint, | |
191 &if_xnotlargenegint); | |
192 | |
193 Bind(&if_xlargenegint); | |
194 { | |
195 // The {x} is already an even integer. | |
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 | |
259 Bind(&return_x); | |
260 return var_x.value(); | |
261 } | |
155 | 262 |
156 Node* CodeStubAssembler::SmiTag(Node* value) { | 263 Node* CodeStubAssembler::SmiTag(Node* value) { |
157 return raw_assembler_->WordShl(value, SmiShiftBitsConstant()); | 264 return raw_assembler_->WordShl(value, SmiShiftBitsConstant()); |
158 } | 265 } |
159 | 266 |
160 Node* CodeStubAssembler::SmiUntag(Node* value) { | 267 Node* CodeStubAssembler::SmiUntag(Node* value) { |
161 return raw_assembler_->WordSar(value, SmiShiftBitsConstant()); | 268 return raw_assembler_->WordSar(value, SmiShiftBitsConstant()); |
162 } | 269 } |
163 | 270 |
164 Node* CodeStubAssembler::SmiToWord32(Node* value) { | 271 Node* CodeStubAssembler::SmiToWord32(Node* value) { |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
503 return LoadMapInstanceType(LoadMap(object)); | 610 return LoadMapInstanceType(LoadMap(object)); |
504 } | 611 } |
505 | 612 |
506 Node* CodeStubAssembler::BitFieldDecode(Node* word32, uint32_t shift, | 613 Node* CodeStubAssembler::BitFieldDecode(Node* word32, uint32_t shift, |
507 uint32_t mask) { | 614 uint32_t mask) { |
508 return raw_assembler_->Word32Shr( | 615 return raw_assembler_->Word32Shr( |
509 raw_assembler_->Word32And(word32, raw_assembler_->Int32Constant(mask)), | 616 raw_assembler_->Word32And(word32, raw_assembler_->Int32Constant(mask)), |
510 raw_assembler_->Int32Constant(shift)); | 617 raw_assembler_->Int32Constant(shift)); |
511 } | 618 } |
512 | 619 |
620 Node* CodeStubAssembler::ChangeFloat64ToTagged(Node* value) { | |
621 Node* value32 = raw_assembler_->TruncateFloat64ToInt32( | |
622 TruncationMode::kRoundToZero, value); | |
623 Node* value64 = ChangeInt32ToFloat64(value32); | |
624 | |
625 Label if_valueisint32(this), if_valueisheapnumber(this), if_join(this); | |
626 | |
627 Label if_valueisequal(this), if_valueisnotequal(this); | |
628 Branch(Float64Equal(value, value64), &if_valueisequal, &if_valueisnotequal); | |
629 Bind(&if_valueisequal); | |
630 { | |
631 Label if_valueiszero(this), if_valueisnotzero(this); | |
632 Branch(Float64Equal(value, Float64Constant(0.0)), &if_valueiszero, | |
633 &if_valueisnotzero); | |
634 | |
635 Bind(&if_valueiszero); | |
636 BranchIfInt32LessThan(Float64ExtractHighWord32(value), Int32Constant(0), | |
637 &if_valueisheapnumber, &if_valueisint32); | |
638 | |
639 Bind(&if_valueisnotzero); | |
640 Goto(&if_valueisint32); | |
641 } | |
642 Bind(&if_valueisnotequal); | |
643 Goto(&if_valueisheapnumber); | |
644 | |
645 Variable var_result(this, MachineRepresentation::kTagged); | |
646 Bind(&if_valueisint32); | |
647 { | |
648 if (raw_assembler_->machine()->Is64()) { | |
649 Node* result = SmiTag(ChangeInt32ToInt64(value32)); | |
650 var_result.Bind(result); | |
651 Goto(&if_join); | |
652 } else { | |
653 Node* pair = Int32AddWithOverflow(value32, value32); | |
654 Node* overflow = Projection(1, pair); | |
655 Label if_overflow(this, Label::kDeferred), if_notoverflow(this), | |
656 if_join(this); | |
657 Branch(overflow, &if_overflow, &if_notoverflow); | |
658 Bind(&if_overflow); | |
659 { Goto(&if_valueisheapnumber); } | |
epertoso
2016/03/28 09:55:08
nit: remove the braces for consistency.
Benedikt Meurer
2016/03/28 17:00:58
Done.
| |
660 Bind(&if_notoverflow); | |
661 { | |
662 Node* result = Projection(0, pair); | |
663 var_result.Bind(result); | |
664 Goto(&if_join); | |
665 } | |
666 } | |
667 } | |
668 Bind(&if_valueisheapnumber); | |
669 { | |
670 Node* result = AllocateHeapNumberWithValue(value); | |
671 var_result.Bind(result); | |
672 Goto(&if_join); | |
673 } | |
674 Bind(&if_join); | |
675 return var_result.value(); | |
676 } | |
677 | |
513 Node* CodeStubAssembler::ChangeInt32ToTagged(Node* value) { | 678 Node* CodeStubAssembler::ChangeInt32ToTagged(Node* value) { |
514 if (raw_assembler_->machine()->Is64()) { | 679 if (raw_assembler_->machine()->Is64()) { |
515 return SmiTag(ChangeInt32ToInt64(value)); | 680 return SmiTag(ChangeInt32ToInt64(value)); |
516 } | 681 } |
517 Variable var_result(this, MachineRepresentation::kTagged); | 682 Variable var_result(this, MachineRepresentation::kTagged); |
518 Node* pair = Int32AddWithOverflow(value, value); | 683 Node* pair = Int32AddWithOverflow(value, value); |
519 Node* overflow = Projection(1, pair); | 684 Node* overflow = Projection(1, pair); |
520 Label if_overflow(this, Label::kDeferred), if_notoverflow(this), | 685 Label if_overflow(this, Label::kDeferred), if_notoverflow(this), |
521 if_join(this); | 686 if_join(this); |
522 Branch(overflow, &if_overflow, &if_notoverflow); | 687 Branch(overflow, &if_overflow, &if_notoverflow); |
(...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1050 } | 1215 } |
1051 } | 1216 } |
1052 } | 1217 } |
1053 | 1218 |
1054 bound_ = true; | 1219 bound_ = true; |
1055 } | 1220 } |
1056 | 1221 |
1057 } // namespace compiler | 1222 } // namespace compiler |
1058 } // namespace internal | 1223 } // namespace internal |
1059 } // namespace v8 | 1224 } // namespace v8 |
OLD | NEW |