1 // Copyright 2014 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_CRANKSHAFT_S390_LITHIUM_S390_H_ 6 #define V8_CRANKSHAFT_S390_LITHIUM_S390_H_ 7 8 #include "src/crankshaft/hydrogen.h" 9 #include "src/crankshaft/lithium.h" 10 #include "src/crankshaft/lithium-allocator.h" 11 #include "src/safepoint-table.h" 12 #include "src/utils.h" 13 14 namespace v8 { 15 namespace internal { 16 17 // Forward declarations. 18 class LCodeGen; 19 20 #define LITHIUM_CONCRETE_INSTRUCTION_LIST(V) \ 21 V(AccessArgumentsAt) \ 22 V(AddI) \ 23 V(Allocate) \ 24 V(ApplyArguments) \ 25 V(ArgumentsElements) \ 26 V(ArgumentsLength) \ 27 V(ArithmeticD) \ 28 V(ArithmeticT) \ 29 V(BitI) \ 30 V(BoundsCheck) \ 31 V(Branch) \ 32 V(CallWithDescriptor) \ 33 V(CallNewArray) \ 34 V(CallRuntime) \ 35 V(CheckArrayBufferNotNeutered) \ 36 V(CheckInstanceType) \ 37 V(CheckNonSmi) \ 38 V(CheckMaps) \ 39 V(CheckMapValue) \ 40 V(CheckSmi) \ 41 V(CheckValue) \ 42 V(ClampDToUint8) \ 43 V(ClampIToUint8) \ 44 V(ClampTToUint8) \ 45 V(ClassOfTestAndBranch) \ 46 V(CompareNumericAndBranch) \ 47 V(CmpObjectEqAndBranch) \ 48 V(CmpHoleAndBranch) \ 49 V(CmpMapAndBranch) \ 50 V(CmpT) \ 51 V(ConstantD) \ 52 V(ConstantE) \ 53 V(ConstantI) \ 54 V(ConstantS) \ 55 V(ConstantT) \ 56 V(Context) \ 57 V(DebugBreak) \ 58 V(DeclareGlobals) \ 59 V(Deoptimize) \ 60 V(DivByConstI) \ 61 V(DivByPowerOf2I) \ 62 V(DivI) \ 63 V(DoubleToI) \ 64 V(DoubleToSmi) \ 65 V(Drop) \ 66 V(Dummy) \ 67 V(DummyUse) \ 68 V(FastAllocate) \ 69 V(FlooringDivByConstI) \ 70 V(FlooringDivByPowerOf2I) \ 71 V(FlooringDivI) \ 72 V(ForInCacheArray) \ 73 V(ForInPrepareMap) \ 74 V(Goto) \ 75 V(HasInPrototypeChainAndBranch) \ 76 V(HasInstanceTypeAndBranch) \ 77 V(InnerAllocatedObject) \ 78 V(InstructionGap) \ 79 V(Integer32ToDouble) \ 80 V(InvokeFunction) \ 81 V(IsStringAndBranch) \ 82 V(IsSmiAndBranch) \ 83 V(IsUndetectableAndBranch) \ 84 V(Label) \ 85 V(LazyBailout) \ 86 V(LoadContextSlot) \ 87 V(LoadRoot) \ 88 V(LoadFieldByIndex) \ 89 V(LoadFunctionPrototype) \ 90 V(LoadKeyed) \ 91 V(LoadNamedField) \ 92 V(MathAbs) \ 93 V(MathClz32) \ 94 V(MathCos) \ 95 V(MathSin) \ 96 V(MathExp) \ 97 V(MathFloor) \ 98 V(MathFround) \ 99 V(MathLog) \ 100 V(MathMinMax) \ 101 V(MathPowHalf) \ 102 V(MathRound) \ 103 V(MathSqrt) \ 104 V(MaybeGrowElements) \ 105 V(ModByConstI) \ 106 V(ModByPowerOf2I) \ 107 V(ModI) \ 108 V(MulI) \ 109 V(MultiplyAddD) \ 110 V(MultiplySubD) \ 111 V(NumberTagD) \ 112 V(NumberTagI) \ 113 V(NumberTagU) \ 114 V(NumberUntagD) \ 115 V(OsrEntry) \ 116 V(Parameter) \ 117 V(Power) \ 118 V(Prologue) \ 119 V(PushArgument) \ 120 V(Return) \ 121 V(SeqStringGetChar) \ 122 V(SeqStringSetChar) \ 123 V(ShiftI) \ 124 V(SmiTag) \ 125 V(SmiUntag) \ 126 V(StackCheck) \ 127 V(StoreCodeEntry) \ 128 V(StoreContextSlot) \ 129 V(StoreKeyed) \ 130 V(StoreNamedField) \ 131 V(StringAdd) \ 132 V(StringCharCodeAt) \ 133 V(StringCharFromCode) \ 134 V(StringCompareAndBranch) \ 135 V(SubI) \ 136 V(RSubI) \ 137 V(TaggedToI) \ 138 V(ThisFunction) \ 139 V(TransitionElementsKind) \ 140 V(TrapAllocationMemento) \ 141 V(Typeof) \ 142 V(TypeofIsAndBranch) \ 143 V(Uint32ToDouble) \ 144 V(UnknownOSRValue) \ 145 V(WrapReceiver) 146 147 #define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \ 148 Opcode opcode() const final { return LInstruction::k##type; } \ 149 void CompileToNative(LCodeGen* generator) final; \ 150 const char* Mnemonic() const final { return mnemonic; } \ 151 static L##type* cast(LInstruction* instr) { \ 152 DCHECK(instr->Is##type()); \ 153 return reinterpret_cast<L##type*>(instr); \ 154 } 155 156 #define DECLARE_HYDROGEN_ACCESSOR(type) \ 157 H##type* hydrogen() const { return H##type::cast(hydrogen_value()); } 158 159 class LInstruction : public ZoneObject { 160 public: LInstruction()161 LInstruction() 162 : environment_(NULL), 163 hydrogen_value_(NULL), 164 bit_field_(IsCallBits::encode(false)) {} 165 ~LInstruction()166 virtual ~LInstruction() {} 167 168 virtual void CompileToNative(LCodeGen* generator) = 0; 169 virtual const char* Mnemonic() const = 0; 170 virtual void PrintTo(StringStream* stream); 171 virtual void PrintDataTo(StringStream* stream); 172 virtual void PrintOutputOperandTo(StringStream* stream); 173 174 enum Opcode { 175 // Declare a unique enum value for each instruction. 176 #define DECLARE_OPCODE(type) k##type, 177 LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE) kNumberOfInstructions 178 #undef DECLARE_OPCODE 179 }; 180 181 virtual Opcode opcode() const = 0; 182 183 // Declare non-virtual type testers for all leaf IR classes. 184 #define DECLARE_PREDICATE(type) \ 185 bool Is##type() const { return opcode() == k##type; } LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)186 LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE) 187 #undef DECLARE_PREDICATE 188 189 // Declare virtual predicates for instructions that don't have 190 // an opcode. 191 virtual bool IsGap() const { return false; } 192 IsControl()193 virtual bool IsControl() const { return false; } 194 195 // Try deleting this instruction if possible. TryDelete()196 virtual bool TryDelete() { return false; } 197 set_environment(LEnvironment * env)198 void set_environment(LEnvironment* env) { environment_ = env; } environment()199 LEnvironment* environment() const { return environment_; } HasEnvironment()200 bool HasEnvironment() const { return environment_ != NULL; } 201 set_pointer_map(LPointerMap * p)202 void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); } pointer_map()203 LPointerMap* pointer_map() const { return pointer_map_.get(); } HasPointerMap()204 bool HasPointerMap() const { return pointer_map_.is_set(); } 205 set_hydrogen_value(HValue * value)206 void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; } hydrogen_value()207 HValue* hydrogen_value() const { return hydrogen_value_; } 208 MarkAsCall()209 void MarkAsCall() { bit_field_ = IsCallBits::update(bit_field_, true); } IsCall()210 bool IsCall() const { return IsCallBits::decode(bit_field_); } 211 MarkAsSyntacticTailCall()212 void MarkAsSyntacticTailCall() { 213 bit_field_ = IsSyntacticTailCallBits::update(bit_field_, true); 214 } IsSyntacticTailCall()215 bool IsSyntacticTailCall() const { 216 return IsSyntacticTailCallBits::decode(bit_field_); 217 } 218 219 // Interface to the register allocator and iterators. ClobbersTemps()220 bool ClobbersTemps() const { return IsCall(); } ClobbersRegisters()221 bool ClobbersRegisters() const { return IsCall(); } ClobbersDoubleRegisters(Isolate * isolate)222 virtual bool ClobbersDoubleRegisters(Isolate* isolate) const { 223 return IsCall(); 224 } 225 226 // Interface to the register allocator and iterators. IsMarkedAsCall()227 bool IsMarkedAsCall() const { return IsCall(); } 228 229 virtual bool HasResult() const = 0; 230 virtual LOperand* result() const = 0; 231 FirstInput()232 LOperand* FirstInput() { return InputAt(0); } Output()233 LOperand* Output() { return HasResult() ? result() : NULL; } 234 HasInterestingComment(LCodeGen * gen)235 virtual bool HasInterestingComment(LCodeGen* gen) const { return true; } 236 237 #ifdef DEBUG 238 void VerifyCall(); 239 #endif 240 241 virtual int InputCount() = 0; 242 virtual LOperand* InputAt(int i) = 0; 243 244 private: 245 // Iterator support. 246 friend class InputIterator; 247 248 friend class TempIterator; 249 virtual int TempCount() = 0; 250 virtual LOperand* TempAt(int i) = 0; 251 252 class IsCallBits : public BitField<bool, 0, 1> {}; 253 class IsSyntacticTailCallBits : public BitField<bool, IsCallBits::kNext, 1> { 254 }; 255 256 LEnvironment* environment_; 257 SetOncePointer<LPointerMap> pointer_map_; 258 HValue* hydrogen_value_; 259 int bit_field_; 260 }; 261 262 // R = number of result operands (0 or 1). 263 template <int R> 264 class LTemplateResultInstruction : public LInstruction { 265 public: 266 // Allow 0 or 1 output operands. 267 STATIC_ASSERT(R == 0 || R == 1); HasResult()268 bool HasResult() const final { return R != 0 && result() != NULL; } set_result(LOperand * operand)269 void set_result(LOperand* operand) { results_[0] = operand; } result()270 LOperand* result() const override { return results_[0]; } 271 272 protected: 273 EmbeddedContainer<LOperand*, R> results_; 274 }; 275 276 // R = number of result operands (0 or 1). 277 // I = number of input operands. 278 // T = number of temporary operands. 279 template <int R, int I, int T> 280 class LTemplateInstruction : public LTemplateResultInstruction<R> { 281 protected: 282 EmbeddedContainer<LOperand*, I> inputs_; 283 EmbeddedContainer<LOperand*, T> temps_; 284 285 private: 286 // Iterator support. InputCount()287 int InputCount() final { return I; } InputAt(int i)288 LOperand* InputAt(int i) final { return inputs_[i]; } 289 TempCount()290 int TempCount() final { return T; } TempAt(int i)291 LOperand* TempAt(int i) final { return temps_[i]; } 292 }; 293 294 class LGap : public LTemplateInstruction<0, 0, 0> { 295 public: LGap(HBasicBlock * block)296 explicit LGap(HBasicBlock* block) : block_(block) { 297 parallel_moves_[BEFORE] = NULL; 298 parallel_moves_[START] = NULL; 299 parallel_moves_[END] = NULL; 300 parallel_moves_[AFTER] = NULL; 301 } 302 303 // Can't use the DECLARE-macro here because of sub-classes. IsGap()304 bool IsGap() const override { return true; } 305 void PrintDataTo(StringStream* stream) override; cast(LInstruction * instr)306 static LGap* cast(LInstruction* instr) { 307 DCHECK(instr->IsGap()); 308 return reinterpret_cast<LGap*>(instr); 309 } 310 311 bool IsRedundant() const; 312 block()313 HBasicBlock* block() const { return block_; } 314 315 enum InnerPosition { 316 BEFORE, 317 START, 318 END, 319 AFTER, 320 FIRST_INNER_POSITION = BEFORE, 321 LAST_INNER_POSITION = AFTER 322 }; 323 GetOrCreateParallelMove(InnerPosition pos,Zone * zone)324 LParallelMove* GetOrCreateParallelMove(InnerPosition pos, Zone* zone) { 325 if (parallel_moves_[pos] == NULL) { 326 parallel_moves_[pos] = new (zone) LParallelMove(zone); 327 } 328 return parallel_moves_[pos]; 329 } 330 GetParallelMove(InnerPosition pos)331 LParallelMove* GetParallelMove(InnerPosition pos) { 332 return parallel_moves_[pos]; 333 } 334 335 private: 336 LParallelMove* parallel_moves_[LAST_INNER_POSITION + 1]; 337 HBasicBlock* block_; 338 }; 339 340 class LInstructionGap final : public LGap { 341 public: LInstructionGap(HBasicBlock * block)342 explicit LInstructionGap(HBasicBlock* block) : LGap(block) {} 343 HasInterestingComment(LCodeGen * gen)344 bool HasInterestingComment(LCodeGen* gen) const override { 345 return !IsRedundant(); 346 } 347 348 DECLARE_CONCRETE_INSTRUCTION(InstructionGap, "gap") 349 }; 350 351 class LGoto final : public LTemplateInstruction<0, 0, 0> { 352 public: LGoto(HBasicBlock * block)353 explicit LGoto(HBasicBlock* block) : block_(block) {} 354 355 bool HasInterestingComment(LCodeGen* gen) const override; 356 DECLARE_CONCRETE_INSTRUCTION(Goto, "goto") 357 void PrintDataTo(StringStream* stream) override; IsControl()358 bool IsControl() const override { return true; } 359 block_id()360 int block_id() const { return block_->block_id(); } 361 362 private: 363 HBasicBlock* block_; 364 }; 365 366 class LPrologue final : public LTemplateInstruction<0, 0, 0> { 367 public: 368 DECLARE_CONCRETE_INSTRUCTION(Prologue, "prologue") 369 }; 370 371 class LLazyBailout final : public LTemplateInstruction<0, 0, 0> { 372 public: LLazyBailout()373 LLazyBailout() : gap_instructions_size_(0) {} 374 375 DECLARE_CONCRETE_INSTRUCTION(LazyBailout, "lazy-bailout") 376 set_gap_instructions_size(int gap_instructions_size)377 void set_gap_instructions_size(int gap_instructions_size) { 378 gap_instructions_size_ = gap_instructions_size; 379 } gap_instructions_size()380 int gap_instructions_size() { return gap_instructions_size_; } 381 382 private: 383 int gap_instructions_size_; 384 }; 385 386 class LDummy final : public LTemplateInstruction<1, 0, 0> { 387 public: LDummy()388 LDummy() {} 389 DECLARE_CONCRETE_INSTRUCTION(Dummy, "dummy") 390 }; 391 392 class LDummyUse final : public LTemplateInstruction<1, 1, 0> { 393 public: LDummyUse(LOperand * value)394 explicit LDummyUse(LOperand* value) { inputs_[0] = value; } 395 DECLARE_CONCRETE_INSTRUCTION(DummyUse, "dummy-use") 396 }; 397 398 class LDeoptimize final : public LTemplateInstruction<0, 0, 0> { 399 public: IsControl()400 bool IsControl() const override { return true; } 401 DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize") 402 DECLARE_HYDROGEN_ACCESSOR(Deoptimize) 403 }; 404 405 class LLabel final : public LGap { 406 public: LLabel(HBasicBlock * block)407 explicit LLabel(HBasicBlock* block) : LGap(block), replacement_(NULL) {} 408 HasInterestingComment(LCodeGen * gen)409 bool HasInterestingComment(LCodeGen* gen) const override { return false; } 410 DECLARE_CONCRETE_INSTRUCTION(Label, "label") 411 412 void PrintDataTo(StringStream* stream) override; 413 block_id()414 int block_id() const { return block()->block_id(); } is_loop_header()415 bool is_loop_header() const { return block()->IsLoopHeader(); } is_osr_entry()416 bool is_osr_entry() const { return block()->is_osr_entry(); } label()417 Label* label() { return &label_; } replacement()418 LLabel* replacement() const { return replacement_; } set_replacement(LLabel * label)419 void set_replacement(LLabel* label) { replacement_ = label; } HasReplacement()420 bool HasReplacement() const { return replacement_ != NULL; } 421 422 private: 423 Label label_; 424 LLabel* replacement_; 425 }; 426 427 class LParameter final : public LTemplateInstruction<1, 0, 0> { 428 public: HasInterestingComment(LCodeGen * gen)429 virtual bool HasInterestingComment(LCodeGen* gen) const { return false; } 430 DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter") 431 }; 432 433 class LUnknownOSRValue final : public LTemplateInstruction<1, 0, 0> { 434 public: HasInterestingComment(LCodeGen * gen)435 bool HasInterestingComment(LCodeGen* gen) const override { return false; } 436 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown-osr-value") 437 }; 438 439 template <int I, int T> 440 class LControlInstruction : public LTemplateInstruction<0, I, T> { 441 public: LControlInstruction()442 LControlInstruction() : false_label_(NULL), true_label_(NULL) {} 443 IsControl()444 bool IsControl() const final { return true; } 445 SuccessorCount()446 int SuccessorCount() { return hydrogen()->SuccessorCount(); } SuccessorAt(int i)447 HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); } 448 TrueDestination(LChunk * chunk)449 int TrueDestination(LChunk* chunk) { 450 return chunk->LookupDestination(true_block_id()); 451 } FalseDestination(LChunk * chunk)452 int FalseDestination(LChunk* chunk) { 453 return chunk->LookupDestination(false_block_id()); 454 } 455 TrueLabel(LChunk * chunk)456 Label* TrueLabel(LChunk* chunk) { 457 if (true_label_ == NULL) { 458 true_label_ = chunk->GetAssemblyLabel(TrueDestination(chunk)); 459 } 460 return true_label_; 461 } FalseLabel(LChunk * chunk)462 Label* FalseLabel(LChunk* chunk) { 463 if (false_label_ == NULL) { 464 false_label_ = chunk->GetAssemblyLabel(FalseDestination(chunk)); 465 } 466 return false_label_; 467 } 468 469 protected: true_block_id()470 int true_block_id() { return SuccessorAt(0)->block_id(); } false_block_id()471 int false_block_id() { return SuccessorAt(1)->block_id(); } 472 473 private: hydrogen()474 HControlInstruction* hydrogen() { 475 return HControlInstruction::cast(this->hydrogen_value()); 476 } 477 478 Label* false_label_; 479 Label* true_label_; 480 }; 481 482 class LWrapReceiver final : public LTemplateInstruction<1, 2, 0> { 483 public: LWrapReceiver(LOperand * receiver,LOperand * function)484 LWrapReceiver(LOperand* receiver, LOperand* function) { 485 inputs_[0] = receiver; 486 inputs_[1] = function; 487 } 488 489 DECLARE_CONCRETE_INSTRUCTION(WrapReceiver, "wrap-receiver") DECLARE_HYDROGEN_ACCESSOR(WrapReceiver)490 DECLARE_HYDROGEN_ACCESSOR(WrapReceiver) 491 492 LOperand* receiver() { return inputs_[0]; } function()493 LOperand* function() { return inputs_[1]; } 494 }; 495 496 class LApplyArguments final : public LTemplateInstruction<1, 4, 0> { 497 public: LApplyArguments(LOperand * function,LOperand * receiver,LOperand * length,LOperand * elements)498 LApplyArguments(LOperand* function, LOperand* receiver, LOperand* length, 499 LOperand* elements) { 500 inputs_[0] = function; 501 inputs_[1] = receiver; 502 inputs_[2] = length; 503 inputs_[3] = elements; 504 } 505 506 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply-arguments") DECLARE_HYDROGEN_ACCESSOR(ApplyArguments)507 DECLARE_HYDROGEN_ACCESSOR(ApplyArguments) 508 509 LOperand* function() { return inputs_[0]; } receiver()510 LOperand* receiver() { return inputs_[1]; } length()511 LOperand* length() { return inputs_[2]; } elements()512 LOperand* elements() { return inputs_[3]; } 513 }; 514 515 class LAccessArgumentsAt final : public LTemplateInstruction<1, 3, 0> { 516 public: LAccessArgumentsAt(LOperand * arguments,LOperand * length,LOperand * index)517 LAccessArgumentsAt(LOperand* arguments, LOperand* length, LOperand* index) { 518 inputs_[0] = arguments; 519 inputs_[1] = length; 520 inputs_[2] = index; 521 } 522 523 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access-arguments-at") 524 arguments()525 LOperand* arguments() { return inputs_[0]; } length()526 LOperand* length() { return inputs_[1]; } index()527 LOperand* index() { return inputs_[2]; } 528 529 void PrintDataTo(StringStream* stream) override; 530 }; 531 532 class LArgumentsLength final : public LTemplateInstruction<1, 1, 0> { 533 public: LArgumentsLength(LOperand * elements)534 explicit LArgumentsLength(LOperand* elements) { inputs_[0] = elements; } 535 elements()536 LOperand* elements() { return inputs_[0]; } 537 538 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments-length") 539 }; 540 541 class LArgumentsElements final : public LTemplateInstruction<1, 0, 0> { 542 public: 543 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments-elements") 544 DECLARE_HYDROGEN_ACCESSOR(ArgumentsElements) 545 }; 546 547 class LModByPowerOf2I final : public LTemplateInstruction<1, 1, 0> { 548 public: LModByPowerOf2I(LOperand * dividend,int32_t divisor)549 LModByPowerOf2I(LOperand* dividend, int32_t divisor) { 550 inputs_[0] = dividend; 551 divisor_ = divisor; 552 } 553 dividend()554 LOperand* dividend() { return inputs_[0]; } divisor()555 int32_t divisor() const { return divisor_; } 556 557 DECLARE_CONCRETE_INSTRUCTION(ModByPowerOf2I, "mod-by-power-of-2-i") 558 DECLARE_HYDROGEN_ACCESSOR(Mod) 559 560 private: 561 int32_t divisor_; 562 }; 563 564 class LModByConstI final : public LTemplateInstruction<1, 1, 0> { 565 public: LModByConstI(LOperand * dividend,int32_t divisor)566 LModByConstI(LOperand* dividend, int32_t divisor) { 567 inputs_[0] = dividend; 568 divisor_ = divisor; 569 } 570 dividend()571 LOperand* dividend() { return inputs_[0]; } divisor()572 int32_t divisor() const { return divisor_; } 573 574 DECLARE_CONCRETE_INSTRUCTION(ModByConstI, "mod-by-const-i") 575 DECLARE_HYDROGEN_ACCESSOR(Mod) 576 577 private: 578 int32_t divisor_; 579 }; 580 581 class LModI final : public LTemplateInstruction<1, 2, 0> { 582 public: LModI(LOperand * left,LOperand * right)583 LModI(LOperand* left, LOperand* right) { 584 inputs_[0] = left; 585 inputs_[1] = right; 586 } 587 left()588 LOperand* left() { return inputs_[0]; } right()589 LOperand* right() { return inputs_[1]; } 590 591 DECLARE_CONCRETE_INSTRUCTION(ModI, "mod-i") 592 DECLARE_HYDROGEN_ACCESSOR(Mod) 593 }; 594 595 class LDivByPowerOf2I final : public LTemplateInstruction<1, 1, 0> { 596 public: LDivByPowerOf2I(LOperand * dividend,int32_t divisor)597 LDivByPowerOf2I(LOperand* dividend, int32_t divisor) { 598 inputs_[0] = dividend; 599 divisor_ = divisor; 600 } 601 dividend()602 LOperand* dividend() { return inputs_[0]; } divisor()603 int32_t divisor() const { return divisor_; } 604 605 DECLARE_CONCRETE_INSTRUCTION(DivByPowerOf2I, "div-by-power-of-2-i") 606 DECLARE_HYDROGEN_ACCESSOR(Div) 607 608 private: 609 int32_t divisor_; 610 }; 611 612 class LDivByConstI final : public LTemplateInstruction<1, 1, 0> { 613 public: LDivByConstI(LOperand * dividend,int32_t divisor)614 LDivByConstI(LOperand* dividend, int32_t divisor) { 615 inputs_[0] = dividend; 616 divisor_ = divisor; 617 } 618 dividend()619 LOperand* dividend() { return inputs_[0]; } divisor()620 int32_t divisor() const { return divisor_; } 621 622 DECLARE_CONCRETE_INSTRUCTION(DivByConstI, "div-by-const-i") 623 DECLARE_HYDROGEN_ACCESSOR(Div) 624 625 private: 626 int32_t divisor_; 627 }; 628 629 class LDivI final : public LTemplateInstruction<1, 2, 0> { 630 public: LDivI(LOperand * dividend,LOperand * divisor)631 LDivI(LOperand* dividend, LOperand* divisor) { 632 inputs_[0] = dividend; 633 inputs_[1] = divisor; 634 } 635 dividend()636 LOperand* dividend() { return inputs_[0]; } divisor()637 LOperand* divisor() { return inputs_[1]; } 638 639 DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i") 640 DECLARE_HYDROGEN_ACCESSOR(BinaryOperation) 641 }; 642 643 class LFlooringDivByPowerOf2I final : public LTemplateInstruction<1, 1, 0> { 644 public: LFlooringDivByPowerOf2I(LOperand * dividend,int32_t divisor)645 LFlooringDivByPowerOf2I(LOperand* dividend, int32_t divisor) { 646 inputs_[0] = dividend; 647 divisor_ = divisor; 648 } 649 dividend()650 LOperand* dividend() { return inputs_[0]; } divisor()651 int32_t divisor() { return divisor_; } 652 653 DECLARE_CONCRETE_INSTRUCTION(FlooringDivByPowerOf2I, 654 "flooring-div-by-power-of-2-i") 655 DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv) 656 657 private: 658 int32_t divisor_; 659 }; 660 661 class LFlooringDivByConstI final : public LTemplateInstruction<1, 1, 1> { 662 public: LFlooringDivByConstI(LOperand * dividend,int32_t divisor,LOperand * temp)663 LFlooringDivByConstI(LOperand* dividend, int32_t divisor, LOperand* temp) { 664 inputs_[0] = dividend; 665 divisor_ = divisor; 666 temps_[0] = temp; 667 } 668 dividend()669 LOperand* dividend() { return inputs_[0]; } divisor()670 int32_t divisor() const { return divisor_; } temp()671 LOperand* temp() { return temps_[0]; } 672 673 DECLARE_CONCRETE_INSTRUCTION(FlooringDivByConstI, "flooring-div-by-const-i") 674 DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv) 675 676 private: 677 int32_t divisor_; 678 }; 679 680 class LFlooringDivI final : public LTemplateInstruction<1, 2, 0> { 681 public: LFlooringDivI(LOperand * dividend,LOperand * divisor)682 LFlooringDivI(LOperand* dividend, LOperand* divisor) { 683 inputs_[0] = dividend; 684 inputs_[1] = divisor; 685 } 686 dividend()687 LOperand* dividend() { return inputs_[0]; } divisor()688 LOperand* divisor() { return inputs_[1]; } 689 690 DECLARE_CONCRETE_INSTRUCTION(FlooringDivI, "flooring-div-i") 691 DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv) 692 }; 693 694 class LMulI final : public LTemplateInstruction<1, 2, 0> { 695 public: LMulI(LOperand * left,LOperand * right)696 LMulI(LOperand* left, LOperand* right) { 697 inputs_[0] = left; 698 inputs_[1] = right; 699 } 700 left()701 LOperand* left() { return inputs_[0]; } right()702 LOperand* right() { return inputs_[1]; } 703 704 DECLARE_CONCRETE_INSTRUCTION(MulI, "mul-i") 705 DECLARE_HYDROGEN_ACCESSOR(Mul) 706 }; 707 708 // Instruction for computing multiplier * multiplicand + addend. 709 class LMultiplyAddD final : public LTemplateInstruction<1, 3, 0> { 710 public: LMultiplyAddD(LOperand * addend,LOperand * multiplier,LOperand * multiplicand)711 LMultiplyAddD(LOperand* addend, LOperand* multiplier, 712 LOperand* multiplicand) { 713 inputs_[0] = addend; 714 inputs_[1] = multiplier; 715 inputs_[2] = multiplicand; 716 } 717 addend()718 LOperand* addend() { return inputs_[0]; } multiplier()719 LOperand* multiplier() { return inputs_[1]; } multiplicand()720 LOperand* multiplicand() { return inputs_[2]; } 721 722 DECLARE_CONCRETE_INSTRUCTION(MultiplyAddD, "multiply-add-d") 723 }; 724 725 // Instruction for computing minuend - multiplier * multiplicand. 726 class LMultiplySubD final : public LTemplateInstruction<1, 3, 0> { 727 public: LMultiplySubD(LOperand * minuend,LOperand * multiplier,LOperand * multiplicand)728 LMultiplySubD(LOperand* minuend, LOperand* multiplier, 729 LOperand* multiplicand) { 730 inputs_[0] = minuend; 731 inputs_[1] = multiplier; 732 inputs_[2] = multiplicand; 733 } 734 minuend()735 LOperand* minuend() { return inputs_[0]; } multiplier()736 LOperand* multiplier() { return inputs_[1]; } multiplicand()737 LOperand* multiplicand() { return inputs_[2]; } 738 739 DECLARE_CONCRETE_INSTRUCTION(MultiplySubD, "multiply-sub-d") 740 }; 741 742 class LDebugBreak final : public LTemplateInstruction<0, 0, 0> { 743 public: 744 DECLARE_CONCRETE_INSTRUCTION(DebugBreak, "break") 745 }; 746 747 class LCompareNumericAndBranch final : public LControlInstruction<2, 0> { 748 public: LCompareNumericAndBranch(LOperand * left,LOperand * right)749 LCompareNumericAndBranch(LOperand* left, LOperand* right) { 750 inputs_[0] = left; 751 inputs_[1] = right; 752 } 753 left()754 LOperand* left() { return inputs_[0]; } right()755 LOperand* right() { return inputs_[1]; } 756 757 DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch, 758 "compare-numeric-and-branch") DECLARE_HYDROGEN_ACCESSOR(CompareNumericAndBranch)759 DECLARE_HYDROGEN_ACCESSOR(CompareNumericAndBranch) 760 761 Token::Value op() const { return hydrogen()->token(); } is_double()762 bool is_double() const { return hydrogen()->representation().IsDouble(); } 763 764 void PrintDataTo(StringStream* stream) override; 765 }; 766 767 class LMathFloor final : public LTemplateInstruction<1, 1, 0> { 768 public: LMathFloor(LOperand * value)769 explicit LMathFloor(LOperand* value) { inputs_[0] = value; } 770 value()771 LOperand* value() { return inputs_[0]; } 772 773 DECLARE_CONCRETE_INSTRUCTION(MathFloor, "math-floor") 774 DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation) 775 }; 776 777 class LMathRound final : public LTemplateInstruction<1, 1, 1> { 778 public: LMathRound(LOperand * value,LOperand * temp)779 LMathRound(LOperand* value, LOperand* temp) { 780 inputs_[0] = value; 781 temps_[0] = temp; 782 } 783 value()784 LOperand* value() { return inputs_[0]; } temp()785 LOperand* temp() { return temps_[0]; } 786 787 DECLARE_CONCRETE_INSTRUCTION(MathRound, "math-round") 788 DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation) 789 }; 790 791 class LMathFround final : public LTemplateInstruction<1, 1, 0> { 792 public: LMathFround(LOperand * value)793 explicit LMathFround(LOperand* value) { inputs_[0] = value; } 794 value()795 LOperand* value() { return inputs_[0]; } 796 797 DECLARE_CONCRETE_INSTRUCTION(MathFround, "math-fround") 798 }; 799 800 class LMathAbs final : public LTemplateInstruction<1, 2, 0> { 801 public: LMathAbs(LOperand * context,LOperand * value)802 LMathAbs(LOperand* context, LOperand* value) { 803 inputs_[1] = context; 804 inputs_[0] = value; 805 } 806 context()807 LOperand* context() { return inputs_[1]; } value()808 LOperand* value() { return inputs_[0]; } 809 810 DECLARE_CONCRETE_INSTRUCTION(MathAbs, "math-abs") 811 DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation) 812 }; 813 814 class LMathLog final : public LTemplateInstruction<1, 1, 0> { 815 public: LMathLog(LOperand * value)816 explicit LMathLog(LOperand* value) { inputs_[0] = value; } 817 value()818 LOperand* value() { return inputs_[0]; } 819 820 DECLARE_CONCRETE_INSTRUCTION(MathLog, "math-log") 821 }; 822 823 class LMathClz32 final : public LTemplateInstruction<1, 1, 0> { 824 public: LMathClz32(LOperand * value)825 explicit LMathClz32(LOperand* value) { inputs_[0] = value; } 826 value()827 LOperand* value() { return inputs_[0]; } 828 829 DECLARE_CONCRETE_INSTRUCTION(MathClz32, "math-clz32") 830 }; 831 832 class LMathCos final : public LTemplateInstruction<1, 1, 0> { 833 public: LMathCos(LOperand * value)834 explicit LMathCos(LOperand* value) { inputs_[0] = value; } 835 value()836 LOperand* value() { return inputs_[0]; } 837 838 DECLARE_CONCRETE_INSTRUCTION(MathCos, "math-cos") 839 }; 840 841 class LMathSin final : public LTemplateInstruction<1, 1, 0> { 842 public: LMathSin(LOperand * value)843 explicit LMathSin(LOperand* value) { inputs_[0] = value; } 844 value()845 LOperand* value() { return inputs_[0]; } 846 847 DECLARE_CONCRETE_INSTRUCTION(MathSin, "math-sin") 848 }; 849 850 class LMathExp final : public LTemplateInstruction<1, 1, 0> { 851 public: LMathExp(LOperand * value)852 explicit LMathExp(LOperand* value) { inputs_[0] = value; } 853 value()854 LOperand* value() { return inputs_[0]; } 855 856 DECLARE_CONCRETE_INSTRUCTION(MathExp, "math-exp") 857 }; 858 859 class LMathSqrt final : public LTemplateInstruction<1, 1, 0> { 860 public: LMathSqrt(LOperand * value)861 explicit LMathSqrt(LOperand* value) { inputs_[0] = value; } 862 value()863 LOperand* value() { return inputs_[0]; } 864 865 DECLARE_CONCRETE_INSTRUCTION(MathSqrt, "math-sqrt") 866 }; 867 868 class LMathPowHalf final : public LTemplateInstruction<1, 1, 0> { 869 public: LMathPowHalf(LOperand * value)870 explicit LMathPowHalf(LOperand* value) { inputs_[0] = value; } 871 value()872 LOperand* value() { return inputs_[0]; } 873 874 DECLARE_CONCRETE_INSTRUCTION(MathPowHalf, "math-pow-half") 875 }; 876 877 class LCmpObjectEqAndBranch final : public LControlInstruction<2, 0> { 878 public: LCmpObjectEqAndBranch(LOperand * left,LOperand * right)879 LCmpObjectEqAndBranch(LOperand* left, LOperand* right) { 880 inputs_[0] = left; 881 inputs_[1] = right; 882 } 883 left()884 LOperand* left() { return inputs_[0]; } right()885 LOperand* right() { return inputs_[1]; } 886 887 DECLARE_CONCRETE_INSTRUCTION(CmpObjectEqAndBranch, "cmp-object-eq-and-branch") 888 DECLARE_HYDROGEN_ACCESSOR(CompareObjectEqAndBranch) 889 }; 890 891 class LCmpHoleAndBranch final : public LControlInstruction<1, 0> { 892 public: LCmpHoleAndBranch(LOperand * object)893 explicit LCmpHoleAndBranch(LOperand* object) { inputs_[0] = object; } 894 object()895 LOperand* object() { return inputs_[0]; } 896 897 DECLARE_CONCRETE_INSTRUCTION(CmpHoleAndBranch, "cmp-hole-and-branch") 898 DECLARE_HYDROGEN_ACCESSOR(CompareHoleAndBranch) 899 }; 900 901 class LIsStringAndBranch final : public LControlInstruction<1, 1> { 902 public: LIsStringAndBranch(LOperand * value,LOperand * temp)903 LIsStringAndBranch(LOperand* value, LOperand* temp) { 904 inputs_[0] = value; 905 temps_[0] = temp; 906 } 907 value()908 LOperand* value() { return inputs_[0]; } temp()909 LOperand* temp() { return temps_[0]; } 910 911 DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch, "is-string-and-branch") 912 DECLARE_HYDROGEN_ACCESSOR(IsStringAndBranch) 913 914 void PrintDataTo(StringStream* stream) override; 915 }; 916 917 class LIsSmiAndBranch final : public LControlInstruction<1, 0> { 918 public: LIsSmiAndBranch(LOperand * value)919 explicit LIsSmiAndBranch(LOperand* value) { inputs_[0] = value; } 920 value()921 LOperand* value() { return inputs_[0]; } 922 923 DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch") 924 DECLARE_HYDROGEN_ACCESSOR(IsSmiAndBranch) 925 926 void PrintDataTo(StringStream* stream) override; 927 }; 928 929 class LIsUndetectableAndBranch final : public LControlInstruction<1, 1> { 930 public: LIsUndetectableAndBranch(LOperand * value,LOperand * temp)931 explicit LIsUndetectableAndBranch(LOperand* value, LOperand* temp) { 932 inputs_[0] = value; 933 temps_[0] = temp; 934 } 935 value()936 LOperand* value() { return inputs_[0]; } temp()937 LOperand* temp() { return temps_[0]; } 938 939 DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch, 940 "is-undetectable-and-branch") 941 DECLARE_HYDROGEN_ACCESSOR(IsUndetectableAndBranch) 942 943 void PrintDataTo(StringStream* stream) override; 944 }; 945 946 class LStringCompareAndBranch final : public LControlInstruction<3, 0> { 947 public: LStringCompareAndBranch(LOperand * context,LOperand * left,LOperand * right)948 LStringCompareAndBranch(LOperand* context, LOperand* left, LOperand* right) { 949 inputs_[0] = context; 950 inputs_[1] = left; 951 inputs_[2] = right; 952 } 953 context()954 LOperand* context() { return inputs_[0]; } left()955 LOperand* left() { return inputs_[1]; } right()956 LOperand* right() { return inputs_[2]; } 957 958 DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch, 959 "string-compare-and-branch") DECLARE_HYDROGEN_ACCESSOR(StringCompareAndBranch)960 DECLARE_HYDROGEN_ACCESSOR(StringCompareAndBranch) 961 962 Token::Value op() const { return hydrogen()->token(); } 963 964 void PrintDataTo(StringStream* stream) override; 965 }; 966 967 class LHasInstanceTypeAndBranch final : public LControlInstruction<1, 0> { 968 public: LHasInstanceTypeAndBranch(LOperand * value)969 explicit LHasInstanceTypeAndBranch(LOperand* value) { inputs_[0] = value; } 970 value()971 LOperand* value() { return inputs_[0]; } 972 973 DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch, 974 "has-instance-type-and-branch") 975 DECLARE_HYDROGEN_ACCESSOR(HasInstanceTypeAndBranch) 976 977 void PrintDataTo(StringStream* stream) override; 978 }; 979 980 class LClassOfTestAndBranch final : public LControlInstruction<1, 1> { 981 public: LClassOfTestAndBranch(LOperand * value,LOperand * temp)982 LClassOfTestAndBranch(LOperand* value, LOperand* temp) { 983 inputs_[0] = value; 984 temps_[0] = temp; 985 } 986 value()987 LOperand* value() { return inputs_[0]; } temp()988 LOperand* temp() { return temps_[0]; } 989 990 DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch, "class-of-test-and-branch") 991 DECLARE_HYDROGEN_ACCESSOR(ClassOfTestAndBranch) 992 993 void PrintDataTo(StringStream* stream) override; 994 }; 995 996 class LCmpT final : public LTemplateInstruction<1, 3, 0> { 997 public: LCmpT(LOperand * context,LOperand * left,LOperand * right)998 LCmpT(LOperand* context, LOperand* left, LOperand* right) { 999 inputs_[0] = context; 1000 inputs_[1] = left; 1001 inputs_[2] = right; 1002 } 1003 context()1004 LOperand* context() { return inputs_[0]; } left()1005 LOperand* left() { return inputs_[1]; } right()1006 LOperand* right() { return inputs_[2]; } 1007 1008 DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t") DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)1009 DECLARE_HYDROGEN_ACCESSOR(CompareGeneric) 1010 1011 Token::Value op() const { return hydrogen()->token(); } 1012 }; 1013 1014 class LHasInPrototypeChainAndBranch final : public LControlInstruction<2, 0> { 1015 public: LHasInPrototypeChainAndBranch(LOperand * object,LOperand * prototype)1016 LHasInPrototypeChainAndBranch(LOperand* object, LOperand* prototype) { 1017 inputs_[0] = object; 1018 inputs_[1] = prototype; 1019 } 1020 object()1021 LOperand* object() const { return inputs_[0]; } prototype()1022 LOperand* prototype() const { return inputs_[1]; } 1023 1024 DECLARE_CONCRETE_INSTRUCTION(HasInPrototypeChainAndBranch, 1025 "has-in-prototype-chain-and-branch") 1026 DECLARE_HYDROGEN_ACCESSOR(HasInPrototypeChainAndBranch) 1027 }; 1028 1029 class LBoundsCheck final : public LTemplateInstruction<0, 2, 0> { 1030 public: LBoundsCheck(LOperand * index,LOperand * length)1031 LBoundsCheck(LOperand* index, LOperand* length) { 1032 inputs_[0] = index; 1033 inputs_[1] = length; 1034 } 1035 index()1036 LOperand* index() { return inputs_[0]; } length()1037 LOperand* length() { return inputs_[1]; } 1038 1039 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check") 1040 DECLARE_HYDROGEN_ACCESSOR(BoundsCheck) 1041 }; 1042 1043 class LBitI final : public LTemplateInstruction<1, 2, 0> { 1044 public: LBitI(LOperand * left,LOperand * right)1045 LBitI(LOperand* left, LOperand* right) { 1046 inputs_[0] = left; 1047 inputs_[1] = right; 1048 } 1049 left()1050 LOperand* left() { return inputs_[0]; } right()1051 LOperand* right() { return inputs_[1]; } 1052 op()1053 Token::Value op() const { return hydrogen()->op(); } 1054 1055 DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i") 1056 DECLARE_HYDROGEN_ACCESSOR(Bitwise) 1057 }; 1058 1059 class LShiftI final : public LTemplateInstruction<1, 2, 0> { 1060 public: LShiftI(Token::Value op,LOperand * left,LOperand * right,bool can_deopt)1061 LShiftI(Token::Value op, LOperand* left, LOperand* right, bool can_deopt) 1062 : op_(op), can_deopt_(can_deopt) { 1063 inputs_[0] = left; 1064 inputs_[1] = right; 1065 } 1066 op()1067 Token::Value op() const { return op_; } left()1068 LOperand* left() { return inputs_[0]; } right()1069 LOperand* right() { return inputs_[1]; } can_deopt()1070 bool can_deopt() const { return can_deopt_; } 1071 1072 DECLARE_CONCRETE_INSTRUCTION(ShiftI, "shift-i") 1073 1074 private: 1075 Token::Value op_; 1076 bool can_deopt_; 1077 }; 1078 1079 class LSubI final : public LTemplateInstruction<1, 2, 0> { 1080 public: LSubI(LOperand * left,LOperand * right)1081 LSubI(LOperand* left, LOperand* right) { 1082 inputs_[0] = left; 1083 inputs_[1] = right; 1084 } 1085 left()1086 LOperand* left() { return inputs_[0]; } right()1087 LOperand* right() { return inputs_[1]; } 1088 1089 DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i") 1090 DECLARE_HYDROGEN_ACCESSOR(Sub) 1091 }; 1092 1093 class LRSubI final : public LTemplateInstruction<1, 2, 0> { 1094 public: LRSubI(LOperand * left,LOperand * right)1095 LRSubI(LOperand* left, LOperand* right) { 1096 inputs_[0] = left; 1097 inputs_[1] = right; 1098 } 1099 left()1100 LOperand* left() { return inputs_[0]; } right()1101 LOperand* right() { return inputs_[1]; } 1102 1103 DECLARE_CONCRETE_INSTRUCTION(RSubI, "rsub-i") 1104 DECLARE_HYDROGEN_ACCESSOR(Sub) 1105 }; 1106 1107 class LConstantI final : public LTemplateInstruction<1, 0, 0> { 1108 public: 1109 DECLARE_CONCRETE_INSTRUCTION(ConstantI, "constant-i") DECLARE_HYDROGEN_ACCESSOR(Constant)1110 DECLARE_HYDROGEN_ACCESSOR(Constant) 1111 1112 int32_t value() const { return hydrogen()->Integer32Value(); } 1113 }; 1114 1115 class LConstantS final : public LTemplateInstruction<1, 0, 0> { 1116 public: 1117 DECLARE_CONCRETE_INSTRUCTION(ConstantS, "constant-s") DECLARE_HYDROGEN_ACCESSOR(Constant)1118 DECLARE_HYDROGEN_ACCESSOR(Constant) 1119 1120 Smi* value() const { return Smi::FromInt(hydrogen()->Integer32Value()); } 1121 }; 1122 1123 class LConstantD final : public LTemplateInstruction<1, 0, 0> { 1124 public: 1125 DECLARE_CONCRETE_INSTRUCTION(ConstantD, "constant-d") DECLARE_HYDROGEN_ACCESSOR(Constant)1126 DECLARE_HYDROGEN_ACCESSOR(Constant) 1127 1128 double value() const { return hydrogen()->DoubleValue(); } 1129 bits()1130 uint64_t bits() const { return hydrogen()->DoubleValueAsBits(); } 1131 }; 1132 1133 class LConstantE final : public LTemplateInstruction<1, 0, 0> { 1134 public: 1135 DECLARE_CONCRETE_INSTRUCTION(ConstantE, "constant-e") DECLARE_HYDROGEN_ACCESSOR(Constant)1136 DECLARE_HYDROGEN_ACCESSOR(Constant) 1137 1138 ExternalReference value() const { 1139 return hydrogen()->ExternalReferenceValue(); 1140 } 1141 }; 1142 1143 class LConstantT final : public LTemplateInstruction<1, 0, 0> { 1144 public: 1145 DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t") DECLARE_HYDROGEN_ACCESSOR(Constant)1146 DECLARE_HYDROGEN_ACCESSOR(Constant) 1147 1148 Handle<Object> value(Isolate* isolate) const { 1149 return hydrogen()->handle(isolate); 1150 } 1151 }; 1152 1153 class LBranch final : public LControlInstruction<1, 0> { 1154 public: LBranch(LOperand * value)1155 explicit LBranch(LOperand* value) { inputs_[0] = value; } 1156 value()1157 LOperand* value() { return inputs_[0]; } 1158 1159 DECLARE_CONCRETE_INSTRUCTION(Branch, "branch") 1160 DECLARE_HYDROGEN_ACCESSOR(Branch) 1161 1162 void PrintDataTo(StringStream* stream) override; 1163 }; 1164 1165 class LCmpMapAndBranch final : public LControlInstruction<1, 1> { 1166 public: LCmpMapAndBranch(LOperand * value,LOperand * temp)1167 LCmpMapAndBranch(LOperand* value, LOperand* temp) { 1168 inputs_[0] = value; 1169 temps_[0] = temp; 1170 } 1171 value()1172 LOperand* value() { return inputs_[0]; } temp()1173 LOperand* temp() { return temps_[0]; } 1174 1175 DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch") DECLARE_HYDROGEN_ACCESSOR(CompareMap)1176 DECLARE_HYDROGEN_ACCESSOR(CompareMap) 1177 1178 Handle<Map> map() const { return hydrogen()->map().handle(); } 1179 }; 1180 1181 class LSeqStringGetChar final : public LTemplateInstruction<1, 2, 0> { 1182 public: LSeqStringGetChar(LOperand * string,LOperand * index)1183 LSeqStringGetChar(LOperand* string, LOperand* index) { 1184 inputs_[0] = string; 1185 inputs_[1] = index; 1186 } 1187 string()1188 LOperand* string() const { return inputs_[0]; } index()1189 LOperand* index() const { return inputs_[1]; } 1190 1191 DECLARE_CONCRETE_INSTRUCTION(SeqStringGetChar, "seq-string-get-char") 1192 DECLARE_HYDROGEN_ACCESSOR(SeqStringGetChar) 1193 }; 1194 1195 class LSeqStringSetChar final : public LTemplateInstruction<1, 4, 0> { 1196 public: LSeqStringSetChar(LOperand * context,LOperand * string,LOperand * index,LOperand * value)1197 LSeqStringSetChar(LOperand* context, LOperand* string, LOperand* index, 1198 LOperand* value) { 1199 inputs_[0] = context; 1200 inputs_[1] = string; 1201 inputs_[2] = index; 1202 inputs_[3] = value; 1203 } 1204 string()1205 LOperand* string() { return inputs_[1]; } index()1206 LOperand* index() { return inputs_[2]; } value()1207 LOperand* value() { return inputs_[3]; } 1208 1209 DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar, "seq-string-set-char") 1210 DECLARE_HYDROGEN_ACCESSOR(SeqStringSetChar) 1211 }; 1212 1213 class LAddI final : public LTemplateInstruction<1, 2, 0> { 1214 public: LAddI(LOperand * left,LOperand * right)1215 LAddI(LOperand* left, LOperand* right) { 1216 inputs_[0] = left; 1217 inputs_[1] = right; 1218 } 1219 left()1220 LOperand* left() { return inputs_[0]; } right()1221 LOperand* right() { return inputs_[1]; } 1222 1223 DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i") 1224 DECLARE_HYDROGEN_ACCESSOR(Add) 1225 }; 1226 1227 class LMathMinMax final : public LTemplateInstruction<1, 2, 0> { 1228 public: LMathMinMax(LOperand * left,LOperand * right)1229 LMathMinMax(LOperand* left, LOperand* right) { 1230 inputs_[0] = left; 1231 inputs_[1] = right; 1232 } 1233 left()1234 LOperand* left() { return inputs_[0]; } right()1235 LOperand* right() { return inputs_[1]; } 1236 1237 DECLARE_CONCRETE_INSTRUCTION(MathMinMax, "math-min-max") 1238 DECLARE_HYDROGEN_ACCESSOR(MathMinMax) 1239 }; 1240 1241 class LPower final : public LTemplateInstruction<1, 2, 0> { 1242 public: LPower(LOperand * left,LOperand * right)1243 LPower(LOperand* left, LOperand* right) { 1244 inputs_[0] = left; 1245 inputs_[1] = right; 1246 } 1247 left()1248 LOperand* left() { return inputs_[0]; } right()1249 LOperand* right() { return inputs_[1]; } 1250 1251 DECLARE_CONCRETE_INSTRUCTION(Power, "power") 1252 DECLARE_HYDROGEN_ACCESSOR(Power) 1253 }; 1254 1255 class LArithmeticD final : public LTemplateInstruction<1, 2, 0> { 1256 public: LArithmeticD(Token::Value op,LOperand * left,LOperand * right)1257 LArithmeticD(Token::Value op, LOperand* left, LOperand* right) : op_(op) { 1258 inputs_[0] = left; 1259 inputs_[1] = right; 1260 } 1261 op()1262 Token::Value op() const { return op_; } left()1263 LOperand* left() { return inputs_[0]; } right()1264 LOperand* right() { return inputs_[1]; } 1265 opcode()1266 Opcode opcode() const override { return LInstruction::kArithmeticD; } 1267 void CompileToNative(LCodeGen* generator) override; 1268 const char* Mnemonic() const override; 1269 1270 private: 1271 Token::Value op_; 1272 }; 1273 1274 class LArithmeticT final : public LTemplateInstruction<1, 3, 0> { 1275 public: LArithmeticT(Token::Value op,LOperand * context,LOperand * left,LOperand * right)1276 LArithmeticT(Token::Value op, LOperand* context, LOperand* left, 1277 LOperand* right) 1278 : op_(op) { 1279 inputs_[0] = context; 1280 inputs_[1] = left; 1281 inputs_[2] = right; 1282 } 1283 context()1284 LOperand* context() { return inputs_[0]; } left()1285 LOperand* left() { return inputs_[1]; } right()1286 LOperand* right() { return inputs_[2]; } op()1287 Token::Value op() const { return op_; } 1288 opcode()1289 Opcode opcode() const override { return LInstruction::kArithmeticT; } 1290 void CompileToNative(LCodeGen* generator) override; 1291 const char* Mnemonic() const override; 1292 1293 DECLARE_HYDROGEN_ACCESSOR(BinaryOperation) 1294 1295 private: 1296 Token::Value op_; 1297 }; 1298 1299 class LReturn final : public LTemplateInstruction<0, 3, 0> { 1300 public: LReturn(LOperand * value,LOperand * context,LOperand * parameter_count)1301 LReturn(LOperand* value, LOperand* context, LOperand* parameter_count) { 1302 inputs_[0] = value; 1303 inputs_[1] = context; 1304 inputs_[2] = parameter_count; 1305 } 1306 value()1307 LOperand* value() { return inputs_[0]; } 1308 has_constant_parameter_count()1309 bool has_constant_parameter_count() { 1310 return parameter_count()->IsConstantOperand(); 1311 } constant_parameter_count()1312 LConstantOperand* constant_parameter_count() { 1313 DCHECK(has_constant_parameter_count()); 1314 return LConstantOperand::cast(parameter_count()); 1315 } parameter_count()1316 LOperand* parameter_count() { return inputs_[2]; } 1317 1318 DECLARE_CONCRETE_INSTRUCTION(Return, "return") 1319 }; 1320 1321 class LLoadNamedField final : public LTemplateInstruction<1, 1, 0> { 1322 public: LLoadNamedField(LOperand * object)1323 explicit LLoadNamedField(LOperand* object) { inputs_[0] = object; } 1324 object()1325 LOperand* object() { return inputs_[0]; } 1326 1327 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field") 1328 DECLARE_HYDROGEN_ACCESSOR(LoadNamedField) 1329 }; 1330 1331 class LLoadFunctionPrototype final : public LTemplateInstruction<1, 1, 0> { 1332 public: LLoadFunctionPrototype(LOperand * function)1333 explicit LLoadFunctionPrototype(LOperand* function) { inputs_[0] = function; } 1334 function()1335 LOperand* function() { return inputs_[0]; } 1336 1337 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load-function-prototype") 1338 DECLARE_HYDROGEN_ACCESSOR(LoadFunctionPrototype) 1339 }; 1340 1341 class LLoadRoot final : public LTemplateInstruction<1, 0, 0> { 1342 public: 1343 DECLARE_CONCRETE_INSTRUCTION(LoadRoot, "load-root") DECLARE_HYDROGEN_ACCESSOR(LoadRoot)1344 DECLARE_HYDROGEN_ACCESSOR(LoadRoot) 1345 1346 Heap::RootListIndex index() const { return hydrogen()->index(); } 1347 }; 1348 1349 class LLoadKeyed final : public LTemplateInstruction<1, 3, 0> { 1350 public: LLoadKeyed(LOperand * elements,LOperand * key,LOperand * backing_store_owner)1351 LLoadKeyed(LOperand* elements, LOperand* key, LOperand* backing_store_owner) { 1352 inputs_[0] = elements; 1353 inputs_[1] = key; 1354 inputs_[2] = backing_store_owner; 1355 } 1356 elements()1357 LOperand* elements() { return inputs_[0]; } key()1358 LOperand* key() { return inputs_[1]; } backing_store_owner()1359 LOperand* backing_store_owner() { return inputs_[2]; } elements_kind()1360 ElementsKind elements_kind() const { return hydrogen()->elements_kind(); } is_fixed_typed_array()1361 bool is_fixed_typed_array() const { 1362 return hydrogen()->is_fixed_typed_array(); 1363 } 1364 1365 DECLARE_CONCRETE_INSTRUCTION(LoadKeyed, "load-keyed") 1366 DECLARE_HYDROGEN_ACCESSOR(LoadKeyed) 1367 1368 void PrintDataTo(StringStream* stream) override; base_offset()1369 uint32_t base_offset() const { return hydrogen()->base_offset(); } 1370 }; 1371 1372 class LLoadContextSlot final : public LTemplateInstruction<1, 1, 0> { 1373 public: LLoadContextSlot(LOperand * context)1374 explicit LLoadContextSlot(LOperand* context) { inputs_[0] = context; } 1375 context()1376 LOperand* context() { return inputs_[0]; } 1377 1378 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load-context-slot") DECLARE_HYDROGEN_ACCESSOR(LoadContextSlot)1379 DECLARE_HYDROGEN_ACCESSOR(LoadContextSlot) 1380 1381 int slot_index() { return hydrogen()->slot_index(); } 1382 1383 void PrintDataTo(StringStream* stream) override; 1384 }; 1385 1386 class LStoreContextSlot final : public LTemplateInstruction<0, 2, 0> { 1387 public: LStoreContextSlot(LOperand * context,LOperand * value)1388 LStoreContextSlot(LOperand* context, LOperand* value) { 1389 inputs_[0] = context; 1390 inputs_[1] = value; 1391 } 1392 context()1393 LOperand* context() { return inputs_[0]; } value()1394 LOperand* value() { return inputs_[1]; } 1395 1396 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store-context-slot") DECLARE_HYDROGEN_ACCESSOR(StoreContextSlot)1397 DECLARE_HYDROGEN_ACCESSOR(StoreContextSlot) 1398 1399 int slot_index() { return hydrogen()->slot_index(); } 1400 1401 void PrintDataTo(StringStream* stream) override; 1402 }; 1403 1404 class LPushArgument final : public LTemplateInstruction<0, 1, 0> { 1405 public: LPushArgument(LOperand * value)1406 explicit LPushArgument(LOperand* value) { inputs_[0] = value; } 1407 value()1408 LOperand* value() { return inputs_[0]; } 1409 1410 DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push-argument") 1411 }; 1412 1413 class LDrop final : public LTemplateInstruction<0, 0, 0> { 1414 public: LDrop(int count)1415 explicit LDrop(int count) : count_(count) {} 1416 count()1417 int count() const { return count_; } 1418 1419 DECLARE_CONCRETE_INSTRUCTION(Drop, "drop") 1420 1421 private: 1422 int count_; 1423 }; 1424 1425 class LStoreCodeEntry final : public LTemplateInstruction<0, 2, 0> { 1426 public: LStoreCodeEntry(LOperand * function,LOperand * code_object)1427 LStoreCodeEntry(LOperand* function, LOperand* code_object) { 1428 inputs_[0] = function; 1429 inputs_[1] = code_object; 1430 } 1431 function()1432 LOperand* function() { return inputs_[0]; } code_object()1433 LOperand* code_object() { return inputs_[1]; } 1434 1435 void PrintDataTo(StringStream* stream) override; 1436 1437 DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry, "store-code-entry") 1438 DECLARE_HYDROGEN_ACCESSOR(StoreCodeEntry) 1439 }; 1440 1441 class LInnerAllocatedObject final : public LTemplateInstruction<1, 2, 0> { 1442 public: LInnerAllocatedObject(LOperand * base_object,LOperand * offset)1443 LInnerAllocatedObject(LOperand* base_object, LOperand* offset) { 1444 inputs_[0] = base_object; 1445 inputs_[1] = offset; 1446 } 1447 base_object()1448 LOperand* base_object() const { return inputs_[0]; } offset()1449 LOperand* offset() const { return inputs_[1]; } 1450 1451 void PrintDataTo(StringStream* stream) override; 1452 1453 DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "inner-allocated-object") 1454 }; 1455 1456 class LThisFunction final : public LTemplateInstruction<1, 0, 0> { 1457 public: 1458 DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function") 1459 DECLARE_HYDROGEN_ACCESSOR(ThisFunction) 1460 }; 1461 1462 class LContext final : public LTemplateInstruction<1, 0, 0> { 1463 public: 1464 DECLARE_CONCRETE_INSTRUCTION(Context, "context") 1465 DECLARE_HYDROGEN_ACCESSOR(Context) 1466 }; 1467 1468 class LDeclareGlobals final : public LTemplateInstruction<0, 1, 0> { 1469 public: LDeclareGlobals(LOperand * context)1470 explicit LDeclareGlobals(LOperand* context) { inputs_[0] = context; } 1471 context()1472 LOperand* context() { return inputs_[0]; } 1473 1474 DECLARE_CONCRETE_INSTRUCTION(DeclareGlobals, "declare-globals") 1475 DECLARE_HYDROGEN_ACCESSOR(DeclareGlobals) 1476 }; 1477 1478 class LCallWithDescriptor final : public LTemplateResultInstruction<1> { 1479 public: LCallWithDescriptor(CallInterfaceDescriptor descriptor,const ZoneList<LOperand * > & operands,Zone * zone)1480 LCallWithDescriptor(CallInterfaceDescriptor descriptor, 1481 const ZoneList<LOperand*>& operands, Zone* zone) 1482 : descriptor_(descriptor), 1483 inputs_(descriptor.GetRegisterParameterCount() + 1484 kImplicitRegisterParameterCount, 1485 zone) { 1486 DCHECK(descriptor.GetRegisterParameterCount() + 1487 kImplicitRegisterParameterCount == 1488 operands.length()); 1489 inputs_.AddAll(operands, zone); 1490 } 1491 target()1492 LOperand* target() const { return inputs_[0]; } 1493 descriptor()1494 const CallInterfaceDescriptor descriptor() { return descriptor_; } 1495 1496 DECLARE_HYDROGEN_ACCESSOR(CallWithDescriptor) 1497 1498 // The target and context are passed as implicit parameters that are not 1499 // explicitly listed in the descriptor. 1500 static const int kImplicitRegisterParameterCount = 2; 1501 1502 private: 1503 DECLARE_CONCRETE_INSTRUCTION(CallWithDescriptor, "call-with-descriptor") 1504 1505 void PrintDataTo(StringStream* stream) override; 1506 arity()1507 int arity() const { return hydrogen()->argument_count() - 1; } 1508 1509 CallInterfaceDescriptor descriptor_; 1510 ZoneList<LOperand*> inputs_; 1511 1512 // Iterator support. InputCount()1513 int InputCount() final { return inputs_.length(); } InputAt(int i)1514 LOperand* InputAt(int i) final { return inputs_[i]; } 1515 TempCount()1516 int TempCount() final { return 0; } TempAt(int i)1517 LOperand* TempAt(int i) final { return NULL; } 1518 }; 1519 1520 class LInvokeFunction final : public LTemplateInstruction<1, 2, 0> { 1521 public: LInvokeFunction(LOperand * context,LOperand * function)1522 LInvokeFunction(LOperand* context, LOperand* function) { 1523 inputs_[0] = context; 1524 inputs_[1] = function; 1525 } 1526 context()1527 LOperand* context() { return inputs_[0]; } function()1528 LOperand* function() { return inputs_[1]; } 1529 1530 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function") 1531 DECLARE_HYDROGEN_ACCESSOR(InvokeFunction) 1532 1533 void PrintDataTo(StringStream* stream) override; 1534 arity()1535 int arity() const { return hydrogen()->argument_count() - 1; } 1536 }; 1537 1538 class LCallNewArray final : public LTemplateInstruction<1, 2, 0> { 1539 public: LCallNewArray(LOperand * context,LOperand * constructor)1540 LCallNewArray(LOperand* context, LOperand* constructor) { 1541 inputs_[0] = context; 1542 inputs_[1] = constructor; 1543 } 1544 context()1545 LOperand* context() { return inputs_[0]; } constructor()1546 LOperand* constructor() { return inputs_[1]; } 1547 1548 DECLARE_CONCRETE_INSTRUCTION(CallNewArray, "call-new-array") 1549 DECLARE_HYDROGEN_ACCESSOR(CallNewArray) 1550 1551 void PrintDataTo(StringStream* stream) override; 1552 arity()1553 int arity() const { return hydrogen()->argument_count() - 1; } 1554 }; 1555 1556 class LCallRuntime final : public LTemplateInstruction<1, 1, 0> { 1557 public: LCallRuntime(LOperand * context)1558 explicit LCallRuntime(LOperand* context) { inputs_[0] = context; } 1559 context()1560 LOperand* context() { return inputs_[0]; } 1561 1562 DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime") DECLARE_HYDROGEN_ACCESSOR(CallRuntime)1563 DECLARE_HYDROGEN_ACCESSOR(CallRuntime) 1564 1565 bool ClobbersDoubleRegisters(Isolate* isolate) const override { 1566 return save_doubles() == kDontSaveFPRegs; 1567 } 1568 function()1569 const Runtime::Function* function() const { return hydrogen()->function(); } arity()1570 int arity() const { return hydrogen()->argument_count(); } save_doubles()1571 SaveFPRegsMode save_doubles() const { return hydrogen()->save_doubles(); } 1572 }; 1573 1574 class LInteger32ToDouble final : public LTemplateInstruction<1, 1, 0> { 1575 public: LInteger32ToDouble(LOperand * value)1576 explicit LInteger32ToDouble(LOperand* value) { inputs_[0] = value; } 1577 value()1578 LOperand* value() { return inputs_[0]; } 1579 1580 DECLARE_CONCRETE_INSTRUCTION(Integer32ToDouble, "int32-to-double") 1581 }; 1582 1583 class LUint32ToDouble final : public LTemplateInstruction<1, 1, 0> { 1584 public: LUint32ToDouble(LOperand * value)1585 explicit LUint32ToDouble(LOperand* value) { inputs_[0] = value; } 1586 value()1587 LOperand* value() { return inputs_[0]; } 1588 1589 DECLARE_CONCRETE_INSTRUCTION(Uint32ToDouble, "uint32-to-double") 1590 }; 1591 1592 class LNumberTagI final : public LTemplateInstruction<1, 1, 2> { 1593 public: LNumberTagI(LOperand * value,LOperand * temp1,LOperand * temp2)1594 LNumberTagI(LOperand* value, LOperand* temp1, LOperand* temp2) { 1595 inputs_[0] = value; 1596 temps_[0] = temp1; 1597 temps_[1] = temp2; 1598 } 1599 value()1600 LOperand* value() { return inputs_[0]; } temp1()1601 LOperand* temp1() { return temps_[0]; } temp2()1602 LOperand* temp2() { return temps_[1]; } 1603 1604 DECLARE_CONCRETE_INSTRUCTION(NumberTagI, "number-tag-i") 1605 }; 1606 1607 class LNumberTagU final : public LTemplateInstruction<1, 1, 2> { 1608 public: LNumberTagU(LOperand * value,LOperand * temp1,LOperand * temp2)1609 LNumberTagU(LOperand* value, LOperand* temp1, LOperand* temp2) { 1610 inputs_[0] = value; 1611 temps_[0] = temp1; 1612 temps_[1] = temp2; 1613 } 1614 value()1615 LOperand* value() { return inputs_[0]; } temp1()1616 LOperand* temp1() { return temps_[0]; } temp2()1617 LOperand* temp2() { return temps_[1]; } 1618 1619 DECLARE_CONCRETE_INSTRUCTION(NumberTagU, "number-tag-u") 1620 }; 1621 1622 class LNumberTagD final : public LTemplateInstruction<1, 1, 2> { 1623 public: LNumberTagD(LOperand * value,LOperand * temp,LOperand * temp2)1624 LNumberTagD(LOperand* value, LOperand* temp, LOperand* temp2) { 1625 inputs_[0] = value; 1626 temps_[0] = temp; 1627 temps_[1] = temp2; 1628 } 1629 value()1630 LOperand* value() { return inputs_[0]; } temp()1631 LOperand* temp() { return temps_[0]; } temp2()1632 LOperand* temp2() { return temps_[1]; } 1633 1634 DECLARE_CONCRETE_INSTRUCTION(NumberTagD, "number-tag-d") 1635 DECLARE_HYDROGEN_ACCESSOR(Change) 1636 }; 1637 1638 class LDoubleToSmi final : public LTemplateInstruction<1, 1, 0> { 1639 public: LDoubleToSmi(LOperand * value)1640 explicit LDoubleToSmi(LOperand* value) { inputs_[0] = value; } 1641 value()1642 LOperand* value() { return inputs_[0]; } 1643 1644 DECLARE_CONCRETE_INSTRUCTION(DoubleToSmi, "double-to-smi") DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)1645 DECLARE_HYDROGEN_ACCESSOR(UnaryOperation) 1646 1647 bool truncating() { return hydrogen()->CanTruncateToInt32(); } 1648 }; 1649 1650 // Sometimes truncating conversion from a tagged value to an int32. 1651 class LDoubleToI final : public LTemplateInstruction<1, 1, 0> { 1652 public: LDoubleToI(LOperand * value)1653 explicit LDoubleToI(LOperand* value) { inputs_[0] = value; } 1654 value()1655 LOperand* value() { return inputs_[0]; } 1656 1657 DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i") DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)1658 DECLARE_HYDROGEN_ACCESSOR(UnaryOperation) 1659 1660 bool truncating() { return hydrogen()->CanTruncateToInt32(); } 1661 }; 1662 1663 // Truncating conversion from a tagged value to an int32. 1664 class LTaggedToI final : public LTemplateInstruction<1, 1, 2> { 1665 public: LTaggedToI(LOperand * value,LOperand * temp,LOperand * temp2)1666 LTaggedToI(LOperand* value, LOperand* temp, LOperand* temp2) { 1667 inputs_[0] = value; 1668 temps_[0] = temp; 1669 temps_[1] = temp2; 1670 } 1671 value()1672 LOperand* value() { return inputs_[0]; } temp()1673 LOperand* temp() { return temps_[0]; } temp2()1674 LOperand* temp2() { return temps_[1]; } 1675 1676 DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i") DECLARE_HYDROGEN_ACCESSOR(Change)1677 DECLARE_HYDROGEN_ACCESSOR(Change) 1678 1679 bool truncating() { return hydrogen()->CanTruncateToInt32(); } 1680 }; 1681 1682 class LSmiTag final : public LTemplateInstruction<1, 1, 0> { 1683 public: LSmiTag(LOperand * value)1684 explicit LSmiTag(LOperand* value) { inputs_[0] = value; } 1685 value()1686 LOperand* value() { return inputs_[0]; } 1687 1688 DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag") 1689 DECLARE_HYDROGEN_ACCESSOR(Change) 1690 }; 1691 1692 class LNumberUntagD final : public LTemplateInstruction<1, 1, 0> { 1693 public: LNumberUntagD(LOperand * value)1694 explicit LNumberUntagD(LOperand* value) { inputs_[0] = value; } 1695 value()1696 LOperand* value() { return inputs_[0]; } 1697 1698 DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag") DECLARE_HYDROGEN_ACCESSOR(Change)1699 DECLARE_HYDROGEN_ACCESSOR(Change) 1700 1701 bool truncating() { return hydrogen()->CanTruncateToNumber(); } 1702 }; 1703 1704 class LSmiUntag final : public LTemplateInstruction<1, 1, 0> { 1705 public: LSmiUntag(LOperand * value,bool needs_check)1706 LSmiUntag(LOperand* value, bool needs_check) : needs_check_(needs_check) { 1707 inputs_[0] = value; 1708 } 1709 value()1710 LOperand* value() { return inputs_[0]; } needs_check()1711 bool needs_check() const { return needs_check_; } 1712 1713 DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag") 1714 1715 private: 1716 bool needs_check_; 1717 }; 1718 1719 class LStoreNamedField final : public LTemplateInstruction<0, 2, 1> { 1720 public: LStoreNamedField(LOperand * object,LOperand * value,LOperand * temp)1721 LStoreNamedField(LOperand* object, LOperand* value, LOperand* temp) { 1722 inputs_[0] = object; 1723 inputs_[1] = value; 1724 temps_[0] = temp; 1725 } 1726 object()1727 LOperand* object() { return inputs_[0]; } value()1728 LOperand* value() { return inputs_[1]; } temp()1729 LOperand* temp() { return temps_[0]; } 1730 1731 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field") 1732 DECLARE_HYDROGEN_ACCESSOR(StoreNamedField) 1733 1734 void PrintDataTo(StringStream* stream) override; 1735 representation()1736 Representation representation() const { 1737 return hydrogen()->field_representation(); 1738 } 1739 }; 1740 1741 class LStoreKeyed final : public LTemplateInstruction<0, 4, 0> { 1742 public: LStoreKeyed(LOperand * object,LOperand * key,LOperand * value,LOperand * backing_store_owner)1743 LStoreKeyed(LOperand* object, LOperand* key, LOperand* value, 1744 LOperand* backing_store_owner) { 1745 inputs_[0] = object; 1746 inputs_[1] = key; 1747 inputs_[2] = value; 1748 inputs_[3] = backing_store_owner; 1749 } 1750 is_fixed_typed_array()1751 bool is_fixed_typed_array() const { 1752 return hydrogen()->is_fixed_typed_array(); 1753 } elements()1754 LOperand* elements() { return inputs_[0]; } key()1755 LOperand* key() { return inputs_[1]; } value()1756 LOperand* value() { return inputs_[2]; } backing_store_owner()1757 LOperand* backing_store_owner() { return inputs_[3]; } elements_kind()1758 ElementsKind elements_kind() const { return hydrogen()->elements_kind(); } 1759 1760 DECLARE_CONCRETE_INSTRUCTION(StoreKeyed, "store-keyed") 1761 DECLARE_HYDROGEN_ACCESSOR(StoreKeyed) 1762 1763 void PrintDataTo(StringStream* stream) override; NeedsCanonicalization()1764 bool NeedsCanonicalization() { 1765 if (hydrogen()->value()->IsAdd() || hydrogen()->value()->IsSub() || 1766 hydrogen()->value()->IsMul() || hydrogen()->value()->IsDiv()) { 1767 return false; 1768 } 1769 return hydrogen()->NeedsCanonicalization(); 1770 } base_offset()1771 uint32_t base_offset() const { return hydrogen()->base_offset(); } 1772 }; 1773 1774 class LTransitionElementsKind final : public LTemplateInstruction<0, 2, 1> { 1775 public: LTransitionElementsKind(LOperand * object,LOperand * context,LOperand * new_map_temp)1776 LTransitionElementsKind(LOperand* object, LOperand* context, 1777 LOperand* new_map_temp) { 1778 inputs_[0] = object; 1779 inputs_[1] = context; 1780 temps_[0] = new_map_temp; 1781 } 1782 context()1783 LOperand* context() { return inputs_[1]; } object()1784 LOperand* object() { return inputs_[0]; } new_map_temp()1785 LOperand* new_map_temp() { return temps_[0]; } 1786 1787 DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind, 1788 "transition-elements-kind") 1789 DECLARE_HYDROGEN_ACCESSOR(TransitionElementsKind) 1790 1791 void PrintDataTo(StringStream* stream) override; 1792 original_map()1793 Handle<Map> original_map() { return hydrogen()->original_map().handle(); } transitioned_map()1794 Handle<Map> transitioned_map() { 1795 return hydrogen()->transitioned_map().handle(); 1796 } from_kind()1797 ElementsKind from_kind() { return hydrogen()->from_kind(); } to_kind()1798 ElementsKind to_kind() { return hydrogen()->to_kind(); } 1799 }; 1800 1801 class LTrapAllocationMemento final : public LTemplateInstruction<0, 1, 2> { 1802 public: LTrapAllocationMemento(LOperand * object,LOperand * temp1,LOperand * temp2)1803 LTrapAllocationMemento(LOperand* object, LOperand* temp1, LOperand* temp2) { 1804 inputs_[0] = object; 1805 temps_[0] = temp1; 1806 temps_[1] = temp2; 1807 } 1808 object()1809 LOperand* object() { return inputs_[0]; } temp1()1810 LOperand* temp1() { return temps_[0]; } temp2()1811 LOperand* temp2() { return temps_[1]; } 1812 1813 DECLARE_CONCRETE_INSTRUCTION(TrapAllocationMemento, "trap-allocation-memento") 1814 }; 1815 1816 class LMaybeGrowElements final : public LTemplateInstruction<1, 5, 0> { 1817 public: LMaybeGrowElements(LOperand * context,LOperand * object,LOperand * elements,LOperand * key,LOperand * current_capacity)1818 LMaybeGrowElements(LOperand* context, LOperand* object, LOperand* elements, 1819 LOperand* key, LOperand* current_capacity) { 1820 inputs_[0] = context; 1821 inputs_[1] = object; 1822 inputs_[2] = elements; 1823 inputs_[3] = key; 1824 inputs_[4] = current_capacity; 1825 } 1826 context()1827 LOperand* context() { return inputs_[0]; } object()1828 LOperand* object() { return inputs_[1]; } elements()1829 LOperand* elements() { return inputs_[2]; } key()1830 LOperand* key() { return inputs_[3]; } current_capacity()1831 LOperand* current_capacity() { return inputs_[4]; } 1832 ClobbersDoubleRegisters(Isolate * isolate)1833 bool ClobbersDoubleRegisters(Isolate* isolate) const override { return true; } 1834 1835 DECLARE_HYDROGEN_ACCESSOR(MaybeGrowElements) 1836 DECLARE_CONCRETE_INSTRUCTION(MaybeGrowElements, "maybe-grow-elements") 1837 }; 1838 1839 class LStringAdd final : public LTemplateInstruction<1, 3, 0> { 1840 public: LStringAdd(LOperand * context,LOperand * left,LOperand * right)1841 LStringAdd(LOperand* context, LOperand* left, LOperand* right) { 1842 inputs_[0] = context; 1843 inputs_[1] = left; 1844 inputs_[2] = right; 1845 } 1846 context()1847 LOperand* context() { return inputs_[0]; } left()1848 LOperand* left() { return inputs_[1]; } right()1849 LOperand* right() { return inputs_[2]; } 1850 1851 DECLARE_CONCRETE_INSTRUCTION(StringAdd, "string-add") 1852 DECLARE_HYDROGEN_ACCESSOR(StringAdd) 1853 }; 1854 1855 class LStringCharCodeAt final : public LTemplateInstruction<1, 3, 0> { 1856 public: LStringCharCodeAt(LOperand * context,LOperand * string,LOperand * index)1857 LStringCharCodeAt(LOperand* context, LOperand* string, LOperand* index) { 1858 inputs_[0] = context; 1859 inputs_[1] = string; 1860 inputs_[2] = index; 1861 } 1862 context()1863 LOperand* context() { return inputs_[0]; } string()1864 LOperand* string() { return inputs_[1]; } index()1865 LOperand* index() { return inputs_[2]; } 1866 1867 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string-char-code-at") 1868 DECLARE_HYDROGEN_ACCESSOR(StringCharCodeAt) 1869 }; 1870 1871 class LStringCharFromCode final : public LTemplateInstruction<1, 2, 0> { 1872 public: LStringCharFromCode(LOperand * context,LOperand * char_code)1873 explicit LStringCharFromCode(LOperand* context, LOperand* char_code) { 1874 inputs_[0] = context; 1875 inputs_[1] = char_code; 1876 } 1877 context()1878 LOperand* context() { return inputs_[0]; } char_code()1879 LOperand* char_code() { return inputs_[1]; } 1880 1881 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode, "string-char-from-code") 1882 DECLARE_HYDROGEN_ACCESSOR(StringCharFromCode) 1883 }; 1884 1885 class LCheckValue final : public LTemplateInstruction<0, 1, 0> { 1886 public: LCheckValue(LOperand * value)1887 explicit LCheckValue(LOperand* value) { inputs_[0] = value; } 1888 value()1889 LOperand* value() { return inputs_[0]; } 1890 1891 DECLARE_CONCRETE_INSTRUCTION(CheckValue, "check-value") 1892 DECLARE_HYDROGEN_ACCESSOR(CheckValue) 1893 }; 1894 1895 class LCheckArrayBufferNotNeutered final 1896 : public LTemplateInstruction<0, 1, 0> { 1897 public: LCheckArrayBufferNotNeutered(LOperand * view)1898 explicit LCheckArrayBufferNotNeutered(LOperand* view) { inputs_[0] = view; } 1899 view()1900 LOperand* view() { return inputs_[0]; } 1901 1902 DECLARE_CONCRETE_INSTRUCTION(CheckArrayBufferNotNeutered, 1903 "check-array-buffer-not-neutered") 1904 DECLARE_HYDROGEN_ACCESSOR(CheckArrayBufferNotNeutered) 1905 }; 1906 1907 class LCheckInstanceType final : public LTemplateInstruction<0, 1, 0> { 1908 public: LCheckInstanceType(LOperand * value)1909 explicit LCheckInstanceType(LOperand* value) { inputs_[0] = value; } 1910 value()1911 LOperand* value() { return inputs_[0]; } 1912 1913 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check-instance-type") 1914 DECLARE_HYDROGEN_ACCESSOR(CheckInstanceType) 1915 }; 1916 1917 class LCheckMaps final : public LTemplateInstruction<0, 1, 1> { 1918 public: 1919 explicit LCheckMaps(LOperand* value = NULL, LOperand* temp = NULL) { 1920 inputs_[0] = value; 1921 temps_[0] = temp; 1922 } 1923 value()1924 LOperand* value() { return inputs_[0]; } temp()1925 LOperand* temp() { return temps_[0]; } 1926 1927 DECLARE_CONCRETE_INSTRUCTION(CheckMaps, "check-maps") 1928 DECLARE_HYDROGEN_ACCESSOR(CheckMaps) 1929 }; 1930 1931 class LCheckSmi final : public LTemplateInstruction<1, 1, 0> { 1932 public: LCheckSmi(LOperand * value)1933 explicit LCheckSmi(LOperand* value) { inputs_[0] = value; } 1934 value()1935 LOperand* value() { return inputs_[0]; } 1936 1937 DECLARE_CONCRETE_INSTRUCTION(CheckSmi, "check-smi") 1938 }; 1939 1940 class LCheckNonSmi final : public LTemplateInstruction<0, 1, 0> { 1941 public: LCheckNonSmi(LOperand * value)1942 explicit LCheckNonSmi(LOperand* value) { inputs_[0] = value; } 1943 value()1944 LOperand* value() { return inputs_[0]; } 1945 1946 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check-non-smi") 1947 DECLARE_HYDROGEN_ACCESSOR(CheckHeapObject) 1948 }; 1949 1950 class LClampDToUint8 final : public LTemplateInstruction<1, 1, 0> { 1951 public: LClampDToUint8(LOperand * unclamped)1952 explicit LClampDToUint8(LOperand* unclamped) { inputs_[0] = unclamped; } 1953 unclamped()1954 LOperand* unclamped() { return inputs_[0]; } 1955 1956 DECLARE_CONCRETE_INSTRUCTION(ClampDToUint8, "clamp-d-to-uint8") 1957 }; 1958 1959 class LClampIToUint8 final : public LTemplateInstruction<1, 1, 0> { 1960 public: LClampIToUint8(LOperand * unclamped)1961 explicit LClampIToUint8(LOperand* unclamped) { inputs_[0] = unclamped; } 1962 unclamped()1963 LOperand* unclamped() { return inputs_[0]; } 1964 1965 DECLARE_CONCRETE_INSTRUCTION(ClampIToUint8, "clamp-i-to-uint8") 1966 }; 1967 1968 class LClampTToUint8 final : public LTemplateInstruction<1, 1, 1> { 1969 public: LClampTToUint8(LOperand * unclamped,LOperand * temp)1970 LClampTToUint8(LOperand* unclamped, LOperand* temp) { 1971 inputs_[0] = unclamped; 1972 temps_[0] = temp; 1973 } 1974 unclamped()1975 LOperand* unclamped() { return inputs_[0]; } temp()1976 LOperand* temp() { return temps_[0]; } 1977 1978 DECLARE_CONCRETE_INSTRUCTION(ClampTToUint8, "clamp-t-to-uint8") 1979 }; 1980 1981 class LAllocate final : public LTemplateInstruction<1, 2, 2> { 1982 public: LAllocate(LOperand * context,LOperand * size,LOperand * temp1,LOperand * temp2)1983 LAllocate(LOperand* context, LOperand* size, LOperand* temp1, 1984 LOperand* temp2) { 1985 inputs_[0] = context; 1986 inputs_[1] = size; 1987 temps_[0] = temp1; 1988 temps_[1] = temp2; 1989 } 1990 context()1991 LOperand* context() { return inputs_[0]; } size()1992 LOperand* size() { return inputs_[1]; } temp1()1993 LOperand* temp1() { return temps_[0]; } temp2()1994 LOperand* temp2() { return temps_[1]; } 1995 1996 DECLARE_CONCRETE_INSTRUCTION(Allocate, "allocate") 1997 DECLARE_HYDROGEN_ACCESSOR(Allocate) 1998 }; 1999 2000 class LFastAllocate final : public LTemplateInstruction<1, 1, 2> { 2001 public: LFastAllocate(LOperand * size,LOperand * temp1,LOperand * temp2)2002 LFastAllocate(LOperand* size, LOperand* temp1, LOperand* temp2) { 2003 inputs_[0] = size; 2004 temps_[0] = temp1; 2005 temps_[1] = temp2; 2006 } 2007 size()2008 LOperand* size() { return inputs_[0]; } temp1()2009 LOperand* temp1() { return temps_[0]; } temp2()2010 LOperand* temp2() { return temps_[1]; } 2011 2012 DECLARE_CONCRETE_INSTRUCTION(FastAllocate, "fast-allocate") 2013 DECLARE_HYDROGEN_ACCESSOR(Allocate) 2014 }; 2015 2016 class LTypeof final : public LTemplateInstruction<1, 2, 0> { 2017 public: LTypeof(LOperand * context,LOperand * value)2018 LTypeof(LOperand* context, LOperand* value) { 2019 inputs_[0] = context; 2020 inputs_[1] = value; 2021 } 2022 context()2023 LOperand* context() { return inputs_[0]; } value()2024 LOperand* value() { return inputs_[1]; } 2025 2026 DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof") 2027 }; 2028 2029 class LTypeofIsAndBranch final : public LControlInstruction<1, 0> { 2030 public: LTypeofIsAndBranch(LOperand * value)2031 explicit LTypeofIsAndBranch(LOperand* value) { inputs_[0] = value; } 2032 value()2033 LOperand* value() { return inputs_[0]; } 2034 2035 DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch, "typeof-is-and-branch") DECLARE_HYDROGEN_ACCESSOR(TypeofIsAndBranch)2036 DECLARE_HYDROGEN_ACCESSOR(TypeofIsAndBranch) 2037 2038 Handle<String> type_literal() { return hydrogen()->type_literal(); } 2039 2040 void PrintDataTo(StringStream* stream) override; 2041 }; 2042 2043 class LOsrEntry final : public LTemplateInstruction<0, 0, 0> { 2044 public: LOsrEntry()2045 LOsrEntry() {} 2046 HasInterestingComment(LCodeGen * gen)2047 bool HasInterestingComment(LCodeGen* gen) const override { return false; } 2048 DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry") 2049 }; 2050 2051 class LStackCheck final : public LTemplateInstruction<0, 1, 0> { 2052 public: LStackCheck(LOperand * context)2053 explicit LStackCheck(LOperand* context) { inputs_[0] = context; } 2054 context()2055 LOperand* context() { return inputs_[0]; } 2056 2057 DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack-check") DECLARE_HYDROGEN_ACCESSOR(StackCheck)2058 DECLARE_HYDROGEN_ACCESSOR(StackCheck) 2059 2060 Label* done_label() { return &done_label_; } 2061 2062 private: 2063 Label done_label_; 2064 }; 2065 2066 class LForInPrepareMap final : public LTemplateInstruction<1, 2, 0> { 2067 public: LForInPrepareMap(LOperand * context,LOperand * object)2068 LForInPrepareMap(LOperand* context, LOperand* object) { 2069 inputs_[0] = context; 2070 inputs_[1] = object; 2071 } 2072 context()2073 LOperand* context() { return inputs_[0]; } object()2074 LOperand* object() { return inputs_[1]; } 2075 2076 DECLARE_CONCRETE_INSTRUCTION(ForInPrepareMap, "for-in-prepare-map") 2077 }; 2078 2079 class LForInCacheArray final : public LTemplateInstruction<1, 1, 0> { 2080 public: LForInCacheArray(LOperand * map)2081 explicit LForInCacheArray(LOperand* map) { inputs_[0] = map; } 2082 map()2083 LOperand* map() { return inputs_[0]; } 2084 2085 DECLARE_CONCRETE_INSTRUCTION(ForInCacheArray, "for-in-cache-array") 2086 idx()2087 int idx() { return HForInCacheArray::cast(this->hydrogen_value())->idx(); } 2088 }; 2089 2090 class LCheckMapValue final : public LTemplateInstruction<0, 2, 0> { 2091 public: LCheckMapValue(LOperand * value,LOperand * map)2092 LCheckMapValue(LOperand* value, LOperand* map) { 2093 inputs_[0] = value; 2094 inputs_[1] = map; 2095 } 2096 value()2097 LOperand* value() { return inputs_[0]; } map()2098 LOperand* map() { return inputs_[1]; } 2099 2100 DECLARE_CONCRETE_INSTRUCTION(CheckMapValue, "check-map-value") 2101 }; 2102 2103 class LLoadFieldByIndex final : public LTemplateInstruction<1, 2, 0> { 2104 public: LLoadFieldByIndex(LOperand * object,LOperand * index)2105 LLoadFieldByIndex(LOperand* object, LOperand* index) { 2106 inputs_[0] = object; 2107 inputs_[1] = index; 2108 } 2109 object()2110 LOperand* object() { return inputs_[0]; } index()2111 LOperand* index() { return inputs_[1]; } 2112 2113 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex, "load-field-by-index") 2114 }; 2115 2116 class LChunkBuilder; 2117 class LPlatformChunk final : public LChunk { 2118 public: LPlatformChunk(CompilationInfo * info,HGraph * graph)2119 LPlatformChunk(CompilationInfo* info, HGraph* graph) : LChunk(info, graph) {} 2120 2121 int GetNextSpillIndex(RegisterKind kind); 2122 LOperand* GetNextSpillSlot(RegisterKind kind); 2123 }; 2124 2125 class LChunkBuilder final : public LChunkBuilderBase { 2126 public: LChunkBuilder(CompilationInfo * info,HGraph * graph,LAllocator * allocator)2127 LChunkBuilder(CompilationInfo* info, HGraph* graph, LAllocator* allocator) 2128 : LChunkBuilderBase(info, graph), 2129 current_instruction_(NULL), 2130 current_block_(NULL), 2131 next_block_(NULL), 2132 allocator_(allocator) {} 2133 2134 // Build the sequence for the graph. 2135 LPlatformChunk* Build(); 2136 2137 // Declare methods that deal with the individual node types. 2138 #define DECLARE_DO(type) LInstruction* Do##type(H##type* node); 2139 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_DO) 2140 #undef DECLARE_DO 2141 2142 LInstruction* DoMultiplyAdd(HMul* mul, HValue* addend); 2143 LInstruction* DoMultiplySub(HValue* minuend, HMul* mul); 2144 LInstruction* DoRSub(HSub* instr); 2145 2146 static bool HasMagicNumberForDivisor(int32_t divisor); 2147 2148 LInstruction* DoMathFloor(HUnaryMathOperation* instr); 2149 LInstruction* DoMathRound(HUnaryMathOperation* instr); 2150 LInstruction* DoMathFround(HUnaryMathOperation* instr); 2151 LInstruction* DoMathAbs(HUnaryMathOperation* instr); 2152 LInstruction* DoMathLog(HUnaryMathOperation* instr); 2153 LInstruction* DoMathCos(HUnaryMathOperation* instr); 2154 LInstruction* DoMathSin(HUnaryMathOperation* instr); 2155 LInstruction* DoMathExp(HUnaryMathOperation* instr); 2156 LInstruction* DoMathSqrt(HUnaryMathOperation* instr); 2157 LInstruction* DoMathPowHalf(HUnaryMathOperation* instr); 2158 LInstruction* DoMathClz32(HUnaryMathOperation* instr); 2159 LInstruction* DoDivByPowerOf2I(HDiv* instr); 2160 LInstruction* DoDivByConstI(HDiv* instr); 2161 LInstruction* DoDivI(HDiv* instr); 2162 LInstruction* DoModByPowerOf2I(HMod* instr); 2163 LInstruction* DoModByConstI(HMod* instr); 2164 LInstruction* DoModI(HMod* instr); 2165 LInstruction* DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr); 2166 LInstruction* DoFlooringDivByConstI(HMathFloorOfDiv* instr); 2167 LInstruction* DoFlooringDivI(HMathFloorOfDiv* instr); 2168 2169 private: 2170 // Methods for getting operands for Use / Define / Temp. 2171 LUnallocated* ToUnallocated(Register reg); 2172 LUnallocated* ToUnallocated(DoubleRegister reg); 2173 2174 // Methods for setting up define-use relationships. 2175 MUST_USE_RESULT LOperand* Use(HValue* value, LUnallocated* operand); 2176 MUST_USE_RESULT LOperand* UseFixed(HValue* value, Register fixed_register); 2177 MUST_USE_RESULT LOperand* UseFixedDouble(HValue* value, 2178 DoubleRegister fixed_register); 2179 2180 // A value that is guaranteed to be allocated to a register. 2181 // Operand created by UseRegister is guaranteed to be live until the end of 2182 // instruction. This means that register allocator will not reuse it's 2183 // register for any other operand inside instruction. 2184 // Operand created by UseRegisterAtStart is guaranteed to be live only at 2185 // instruction start. Register allocator is free to assign the same register 2186 // to some other operand used inside instruction (i.e. temporary or 2187 // output). 2188 MUST_USE_RESULT LOperand* UseRegister(HValue* value); 2189 MUST_USE_RESULT LOperand* UseRegisterAtStart(HValue* value); 2190 2191 // An input operand in a register that may be trashed. 2192 MUST_USE_RESULT LOperand* UseTempRegister(HValue* value); 2193 2194 // An input operand in a register or stack slot. 2195 MUST_USE_RESULT LOperand* Use(HValue* value); 2196 MUST_USE_RESULT LOperand* UseAtStart(HValue* value); 2197 2198 // An input operand in a register, stack slot or a constant operand. 2199 MUST_USE_RESULT LOperand* UseOrConstant(HValue* value); 2200 MUST_USE_RESULT LOperand* UseOrConstantAtStart(HValue* value); 2201 2202 // An input operand in a register or a constant operand. 2203 MUST_USE_RESULT LOperand* UseRegisterOrConstant(HValue* value); 2204 MUST_USE_RESULT LOperand* UseRegisterOrConstantAtStart(HValue* value); 2205 2206 // An input operand in a constant operand. 2207 MUST_USE_RESULT LOperand* UseConstant(HValue* value); 2208 2209 // An input operand in register, stack slot or a constant operand. 2210 // Will not be moved to a register even if one is freely available. 2211 MUST_USE_RESULT LOperand* UseAny(HValue* value) override; 2212 2213 // Temporary operand that must be in a register. 2214 MUST_USE_RESULT LUnallocated* TempRegister(); 2215 MUST_USE_RESULT LUnallocated* TempDoubleRegister(); 2216 MUST_USE_RESULT LOperand* FixedTemp(Register reg); 2217 MUST_USE_RESULT LOperand* FixedTemp(DoubleRegister reg); 2218 2219 // Methods for setting up define-use relationships. 2220 // Return the same instruction that they are passed. 2221 LInstruction* Define(LTemplateResultInstruction<1>* instr, 2222 LUnallocated* result); 2223 LInstruction* DefineAsRegister(LTemplateResultInstruction<1>* instr); 2224 LInstruction* DefineAsSpilled(LTemplateResultInstruction<1>* instr, 2225 int index); 2226 LInstruction* DefineSameAsFirst(LTemplateResultInstruction<1>* instr); 2227 LInstruction* DefineFixed(LTemplateResultInstruction<1>* instr, Register reg); 2228 LInstruction* DefineFixedDouble(LTemplateResultInstruction<1>* instr, 2229 DoubleRegister reg); 2230 LInstruction* AssignEnvironment(LInstruction* instr); 2231 LInstruction* AssignPointerMap(LInstruction* instr); 2232 2233 enum CanDeoptimize { CAN_DEOPTIMIZE_EAGERLY, CANNOT_DEOPTIMIZE_EAGERLY }; 2234 2235 // By default we assume that instruction sequences generated for calls 2236 // cannot deoptimize eagerly and we do not attach environment to this 2237 // instruction. 2238 LInstruction* MarkAsCall( 2239 LInstruction* instr, HInstruction* hinstr, 2240 CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY); 2241 2242 void VisitInstruction(HInstruction* current); 2243 void AddInstruction(LInstruction* instr, HInstruction* current); 2244 2245 void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block); 2246 LInstruction* DoShift(Token::Value op, HBitwiseBinaryOperation* instr); 2247 LInstruction* DoArithmeticD(Token::Value op, 2248 HArithmeticBinaryOperation* instr); 2249 LInstruction* DoArithmeticT(Token::Value op, HBinaryOperation* instr); 2250 2251 HInstruction* current_instruction_; 2252 HBasicBlock* current_block_; 2253 HBasicBlock* next_block_; 2254 LAllocator* allocator_; 2255 2256 DISALLOW_COPY_AND_ASSIGN(LChunkBuilder); 2257 }; 2258 2259 #undef DECLARE_HYDROGEN_ACCESSOR 2260 #undef DECLARE_CONCRETE_INSTRUCTION 2261 } // namespace internal 2262 } // namespace v8 2263 2264 #endif // V8_CRANKSHAFT_S390_LITHIUM_S390_H_ 2265