| 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 |