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 29 matching lines...) Expand all Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |