Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===- subzero/src/IceInstARM32.h - ARM32 machine instructions --*- C++ -*-===// | 1 //===- subzero/src/IceInstARM32.h - ARM32 machine instructions --*- C++ -*-===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 // | 9 // |
| 10 // This file declares the InstARM32 and OperandARM32 classes and | 10 // This file declares the InstARM32 and OperandARM32 classes and |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 255 Adc, | 255 Adc, |
| 256 Add, | 256 Add, |
| 257 Adjuststack, | 257 Adjuststack, |
| 258 And, | 258 And, |
| 259 Asr, | 259 Asr, |
| 260 Bic, | 260 Bic, |
| 261 Br, | 261 Br, |
| 262 Call, | 262 Call, |
| 263 Cmp, | 263 Cmp, |
| 264 Eor, | 264 Eor, |
| 265 Label, | |
|
jvoung (off chromium)
2015/06/29 21:44:28
Would it make sense to just make Label part of the
Jim Stichnoth
2015/06/30 14:14:08
That seems reasonable.
jvoung (off chromium)
2015/06/30 16:58:07
Okay will try that in a separate CL.
| |
| 265 Ldr, | 266 Ldr, |
| 266 Lsl, | 267 Lsl, |
| 267 Lsr, | 268 Lsr, |
| 268 Mla, | 269 Mla, |
| 270 Mls, | |
| 269 Mov, | 271 Mov, |
| 270 Movt, | 272 Movt, |
| 271 Movw, | 273 Movw, |
| 272 Mul, | 274 Mul, |
| 273 Mvn, | 275 Mvn, |
| 274 Orr, | 276 Orr, |
| 275 Pop, | 277 Pop, |
| 276 Push, | 278 Push, |
| 277 Ret, | 279 Ret, |
| 278 Rsb, | 280 Rsb, |
| 279 Sbc, | 281 Sbc, |
| 282 Sdiv, | |
| 280 Str, | 283 Str, |
| 281 Sub, | 284 Sub, |
| 282 Sxt, | 285 Sxt, |
| 286 Trap, | |
| 287 Tst, | |
| 288 Udiv, | |
| 283 Umull, | 289 Umull, |
| 284 Uxt | 290 Uxt |
| 285 }; | 291 }; |
| 286 | 292 |
| 287 static const char *getWidthString(Type Ty); | 293 static const char *getWidthString(Type Ty); |
| 288 static CondARM32::Cond getOppositeCondition(CondARM32::Cond Cond); | 294 static CondARM32::Cond getOppositeCondition(CondARM32::Cond Cond); |
| 289 | 295 |
| 290 void dump(const Cfg *Func) const override; | 296 void dump(const Cfg *Func) const override; |
| 291 | 297 |
| 292 protected: | 298 protected: |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 315 static const char *predString(CondARM32::Cond Predicate); | 321 static const char *predString(CondARM32::Cond Predicate); |
| 316 void dumpOpcodePred(Ostream &Str, const char *Opcode, Type Ty) const; | 322 void dumpOpcodePred(Ostream &Str, const char *Opcode, Type Ty) const; |
| 317 | 323 |
| 318 // Shared emit routines for common forms of instructions. | 324 // Shared emit routines for common forms of instructions. |
| 319 static void emitUnaryopGPR(const char *Opcode, const InstARM32Pred *Inst, | 325 static void emitUnaryopGPR(const char *Opcode, const InstARM32Pred *Inst, |
| 320 const Cfg *Func); | 326 const Cfg *Func); |
| 321 static void emitTwoAddr(const char *Opcode, const InstARM32Pred *Inst, | 327 static void emitTwoAddr(const char *Opcode, const InstARM32Pred *Inst, |
| 322 const Cfg *Func); | 328 const Cfg *Func); |
| 323 static void emitThreeAddr(const char *Opcode, const InstARM32Pred *Inst, | 329 static void emitThreeAddr(const char *Opcode, const InstARM32Pred *Inst, |
| 324 const Cfg *Func, bool SetFlags); | 330 const Cfg *Func, bool SetFlags); |
| 331 static void emitFourAddr(const char *Opcode, const InstARM32Pred *Inst, | |
| 332 const Cfg *Func); | |
| 325 | 333 |
| 326 protected: | 334 protected: |
| 327 CondARM32::Cond Predicate; | 335 CondARM32::Cond Predicate; |
| 328 }; | 336 }; |
| 329 | 337 |
| 330 template <typename StreamType> | 338 template <typename StreamType> |
| 331 inline StreamType &operator<<(StreamType &Stream, CondARM32::Cond Predicate) { | 339 inline StreamType &operator<<(StreamType &Stream, CondARM32::Cond Predicate) { |
| 332 Stream << InstARM32Pred::predString(Predicate); | 340 Stream << InstARM32Pred::predString(Predicate); |
| 333 return Stream; | 341 return Stream; |
| 334 } | 342 } |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 509 Operand *Src2, CondARM32::Cond Predicate, bool SetFlags) | 517 Operand *Src2, CondARM32::Cond Predicate, bool SetFlags) |
| 510 : InstARM32Pred(Func, K, 2, Dest, Predicate), SetFlags(SetFlags) { | 518 : InstARM32Pred(Func, K, 2, Dest, Predicate), SetFlags(SetFlags) { |
| 511 addSource(Src1); | 519 addSource(Src1); |
| 512 addSource(Src2); | 520 addSource(Src2); |
| 513 } | 521 } |
| 514 | 522 |
| 515 static const char *Opcode; | 523 static const char *Opcode; |
| 516 bool SetFlags; | 524 bool SetFlags; |
| 517 }; | 525 }; |
| 518 | 526 |
| 527 // Instructions of the form x := a op1 (y op2 z). E.g., multiply accumulate. | |
| 528 template <InstARM32::InstKindARM32 K> | |
| 529 class InstARM32FourAddrGPR : public InstARM32Pred { | |
| 530 InstARM32FourAddrGPR() = delete; | |
| 531 InstARM32FourAddrGPR(const InstARM32FourAddrGPR &) = delete; | |
| 532 InstARM32FourAddrGPR &operator=(const InstARM32FourAddrGPR &) = delete; | |
| 533 | |
| 534 public: | |
| 535 // Every operand must be a register. | |
| 536 static InstARM32FourAddrGPR *create(Cfg *Func, Variable *Dest, Variable *Src1, | |
| 537 Variable *Src2, Variable *Src3, | |
| 538 CondARM32::Cond Predicate) { | |
| 539 return new (Func->allocate<InstARM32FourAddrGPR>()) | |
| 540 InstARM32FourAddrGPR(Func, Dest, Src1, Src2, Src3, Predicate); | |
| 541 } | |
| 542 void emit(const Cfg *Func) const override { | |
| 543 if (!BuildDefs::dump()) | |
| 544 return; | |
| 545 emitFourAddr(Opcode, this, Func); | |
| 546 } | |
| 547 void emitIAS(const Cfg *Func) const override { | |
| 548 (void)Func; | |
| 549 llvm::report_fatal_error("Not yet implemented"); | |
| 550 } | |
| 551 void dump(const Cfg *Func) const override { | |
| 552 if (!BuildDefs::dump()) | |
| 553 return; | |
| 554 Ostream &Str = Func->getContext()->getStrDump(); | |
| 555 dumpDest(Func); | |
| 556 Str << " = "; | |
| 557 dumpOpcodePred(Str, Opcode, getDest()->getType()); | |
| 558 Str << " "; | |
| 559 dumpSources(Func); | |
| 560 } | |
| 561 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | |
| 562 | |
| 563 private: | |
| 564 InstARM32FourAddrGPR(Cfg *Func, Variable *Dest, Variable *Src1, | |
| 565 Variable *Src2, Variable *Src3, | |
| 566 CondARM32::Cond Predicate) | |
| 567 : InstARM32Pred(Func, K, 3, Dest, Predicate) { | |
| 568 addSource(Src1); | |
| 569 addSource(Src2); | |
| 570 addSource(Src3); | |
| 571 } | |
| 572 | |
| 573 static const char *Opcode; | |
| 574 }; | |
| 575 | |
| 519 typedef InstARM32ThreeAddrGPR<InstARM32::Adc> InstARM32Adc; | 576 typedef InstARM32ThreeAddrGPR<InstARM32::Adc> InstARM32Adc; |
| 520 typedef InstARM32ThreeAddrGPR<InstARM32::Add> InstARM32Add; | 577 typedef InstARM32ThreeAddrGPR<InstARM32::Add> InstARM32Add; |
| 521 typedef InstARM32ThreeAddrGPR<InstARM32::And> InstARM32And; | 578 typedef InstARM32ThreeAddrGPR<InstARM32::And> InstARM32And; |
| 522 typedef InstARM32ThreeAddrGPR<InstARM32::Asr> InstARM32Asr; | 579 typedef InstARM32ThreeAddrGPR<InstARM32::Asr> InstARM32Asr; |
| 523 typedef InstARM32ThreeAddrGPR<InstARM32::Bic> InstARM32Bic; | 580 typedef InstARM32ThreeAddrGPR<InstARM32::Bic> InstARM32Bic; |
| 524 typedef InstARM32ThreeAddrGPR<InstARM32::Eor> InstARM32Eor; | 581 typedef InstARM32ThreeAddrGPR<InstARM32::Eor> InstARM32Eor; |
| 525 typedef InstARM32ThreeAddrGPR<InstARM32::Lsl> InstARM32Lsl; | 582 typedef InstARM32ThreeAddrGPR<InstARM32::Lsl> InstARM32Lsl; |
| 526 typedef InstARM32ThreeAddrGPR<InstARM32::Lsr> InstARM32Lsr; | 583 typedef InstARM32ThreeAddrGPR<InstARM32::Lsr> InstARM32Lsr; |
| 527 typedef InstARM32ThreeAddrGPR<InstARM32::Mul> InstARM32Mul; | 584 typedef InstARM32ThreeAddrGPR<InstARM32::Mul> InstARM32Mul; |
| 528 typedef InstARM32ThreeAddrGPR<InstARM32::Orr> InstARM32Orr; | 585 typedef InstARM32ThreeAddrGPR<InstARM32::Orr> InstARM32Orr; |
| 529 typedef InstARM32ThreeAddrGPR<InstARM32::Rsb> InstARM32Rsb; | 586 typedef InstARM32ThreeAddrGPR<InstARM32::Rsb> InstARM32Rsb; |
| 530 typedef InstARM32ThreeAddrGPR<InstARM32::Sbc> InstARM32Sbc; | 587 typedef InstARM32ThreeAddrGPR<InstARM32::Sbc> InstARM32Sbc; |
| 588 typedef InstARM32ThreeAddrGPR<InstARM32::Sdiv> InstARM32Sdiv; | |
| 531 typedef InstARM32ThreeAddrGPR<InstARM32::Sub> InstARM32Sub; | 589 typedef InstARM32ThreeAddrGPR<InstARM32::Sub> InstARM32Sub; |
| 590 typedef InstARM32ThreeAddrGPR<InstARM32::Udiv> InstARM32Udiv; | |
| 532 // Move instruction (variable <- flex). This is more of a pseudo-inst. | 591 // Move instruction (variable <- flex). This is more of a pseudo-inst. |
| 533 // If var is a register, then we use "mov". If var is stack, then we use | 592 // If var is a register, then we use "mov". If var is stack, then we use |
| 534 // "str" to store to the stack. | 593 // "str" to store to the stack. |
| 535 typedef InstARM32Movlike<InstARM32::Mov> InstARM32Mov; | 594 typedef InstARM32Movlike<InstARM32::Mov> InstARM32Mov; |
| 536 // MovT leaves the bottom bits alone so dest is also a source. | 595 // MovT leaves the bottom bits alone so dest is also a source. |
| 537 // This helps indicate that a previous MovW setting dest is not dead code. | 596 // This helps indicate that a previous MovW setting dest is not dead code. |
| 538 typedef InstARM32TwoAddrGPR<InstARM32::Movt> InstARM32Movt; | 597 typedef InstARM32TwoAddrGPR<InstARM32::Movt> InstARM32Movt; |
| 539 typedef InstARM32UnaryopGPR<InstARM32::Movw> InstARM32Movw; | 598 typedef InstARM32UnaryopGPR<InstARM32::Movw> InstARM32Movw; |
| 540 typedef InstARM32UnaryopGPR<InstARM32::Mvn> InstARM32Mvn; | 599 typedef InstARM32UnaryopGPR<InstARM32::Mvn> InstARM32Mvn; |
| 541 // Technically, the uxt{b,h} and sxt{b,h} instructions have a rotation | 600 // Technically, the uxt{b,h} and sxt{b,h} instructions have a rotation |
| 542 // operand as well (rotate source by 8, 16, 24 bits prior to extending), | 601 // operand as well (rotate source by 8, 16, 24 bits prior to extending), |
| 543 // but we aren't using that for now, so just model as a Unaryop. | 602 // but we aren't using that for now, so just model as a Unaryop. |
| 544 typedef InstARM32UnaryopGPR<InstARM32::Sxt> InstARM32Sxt; | 603 typedef InstARM32UnaryopGPR<InstARM32::Sxt> InstARM32Sxt; |
| 545 typedef InstARM32UnaryopGPR<InstARM32::Uxt> InstARM32Uxt; | 604 typedef InstARM32UnaryopGPR<InstARM32::Uxt> InstARM32Uxt; |
| 605 typedef InstARM32FourAddrGPR<InstARM32::Mla> InstARM32Mla; | |
| 606 typedef InstARM32FourAddrGPR<InstARM32::Mls> InstARM32Mls; | |
| 607 | |
| 608 // InstARM32Label represents an intra-block label that is the target | |
| 609 // of an intra-block branch. The offset between the label and the | |
| 610 // branch must be fit in the instruction immediate (considered "near"). | |
| 611 class InstARM32Label : public InstARM32 { | |
| 612 InstARM32Label() = delete; | |
| 613 InstARM32Label(const InstARM32Label &) = delete; | |
| 614 InstARM32Label &operator=(const InstARM32Label &) = delete; | |
| 615 | |
| 616 public: | |
| 617 static InstARM32Label *create(Cfg *Func, TargetARM32 *Target) { | |
| 618 return new (Func->allocate<InstARM32Label>()) InstARM32Label(Func, Target); | |
| 619 } | |
| 620 uint32_t getEmitInstCount() const override { return 0; } | |
| 621 IceString getName(const Cfg *Func) const; | |
| 622 SizeT getNumber() const { return Number; } | |
| 623 void emit(const Cfg *Func) const override; | |
| 624 void emitIAS(const Cfg *Func) const override; | |
| 625 void dump(const Cfg *Func) const override; | |
| 626 | |
| 627 private: | |
| 628 InstARM32Label(Cfg *Func, TargetARM32 *Target); | |
| 629 | |
| 630 SizeT Number; // used for unique label generation. | |
| 631 }; | |
| 546 | 632 |
| 547 // Direct branch instruction. | 633 // Direct branch instruction. |
| 548 class InstARM32Br : public InstARM32Pred { | 634 class InstARM32Br : public InstARM32Pred { |
| 549 InstARM32Br() = delete; | 635 InstARM32Br() = delete; |
| 550 InstARM32Br(const InstARM32Br &) = delete; | 636 InstARM32Br(const InstARM32Br &) = delete; |
| 551 InstARM32Br &operator=(const InstARM32Br &) = delete; | 637 InstARM32Br &operator=(const InstARM32Br &) = delete; |
| 552 | 638 |
| 553 public: | 639 public: |
| 554 // Create a conditional branch to one of two nodes. | 640 // Create a conditional branch to one of two nodes. |
| 555 static InstARM32Br *create(Cfg *Func, CfgNode *TargetTrue, | 641 static InstARM32Br *create(Cfg *Func, CfgNode *TargetTrue, |
| 556 CfgNode *TargetFalse, CondARM32::Cond Predicate) { | 642 CfgNode *TargetFalse, CondARM32::Cond Predicate) { |
| 557 assert(Predicate != CondARM32::AL); | 643 assert(Predicate != CondARM32::AL); |
| 644 const InstARM32Label *NoLabel = nullptr; | |
| 558 return new (Func->allocate<InstARM32Br>()) | 645 return new (Func->allocate<InstARM32Br>()) |
| 559 InstARM32Br(Func, TargetTrue, TargetFalse, Predicate); | 646 InstARM32Br(Func, TargetTrue, TargetFalse, NoLabel, Predicate); |
| 560 } | 647 } |
| 561 // Create an unconditional branch to a node. | 648 // Create an unconditional branch to a node. |
| 562 static InstARM32Br *create(Cfg *Func, CfgNode *Target) { | 649 static InstARM32Br *create(Cfg *Func, CfgNode *Target) { |
| 563 const CfgNode *NoCondTarget = nullptr; | 650 const CfgNode *NoCondTarget = nullptr; |
| 651 const InstARM32Label *NoLabel = nullptr; | |
| 564 return new (Func->allocate<InstARM32Br>()) | 652 return new (Func->allocate<InstARM32Br>()) |
| 565 InstARM32Br(Func, NoCondTarget, Target, CondARM32::AL); | 653 InstARM32Br(Func, NoCondTarget, Target, NoLabel, CondARM32::AL); |
| 566 } | 654 } |
| 567 // Create a non-terminator conditional branch to a node, with a | 655 // Create a non-terminator conditional branch to a node, with a |
| 568 // fallthrough to the next instruction in the current node. This is | 656 // fallthrough to the next instruction in the current node. This is |
| 569 // used for switch lowering. | 657 // used for switch lowering. |
| 570 static InstARM32Br *create(Cfg *Func, CfgNode *Target, | 658 static InstARM32Br *create(Cfg *Func, CfgNode *Target, |
| 571 CondARM32::Cond Predicate) { | 659 CondARM32::Cond Predicate) { |
| 572 assert(Predicate != CondARM32::AL); | 660 assert(Predicate != CondARM32::AL); |
| 573 const CfgNode *NoUncondTarget = nullptr; | 661 const CfgNode *NoUncondTarget = nullptr; |
| 662 const InstARM32Label *NoLabel = nullptr; | |
| 574 return new (Func->allocate<InstARM32Br>()) | 663 return new (Func->allocate<InstARM32Br>()) |
| 575 InstARM32Br(Func, Target, NoUncondTarget, Predicate); | 664 InstARM32Br(Func, Target, NoUncondTarget, NoLabel, Predicate); |
| 665 } | |
| 666 // Create a conditional intra-block branch (or unconditional, if | |
| 667 // Condition==AL) to a label in the current block. | |
| 668 static InstARM32Br *create(Cfg *Func, InstARM32Label *Label, | |
| 669 CondARM32::Cond Predicate) { | |
| 670 const CfgNode *NoCondTarget = nullptr; | |
| 671 const CfgNode *NoUncondTarget = nullptr; | |
| 672 return new (Func->allocate<InstARM32Br>()) | |
| 673 InstARM32Br(Func, NoCondTarget, NoUncondTarget, Label, Predicate); | |
| 576 } | 674 } |
| 577 const CfgNode *getTargetTrue() const { return TargetTrue; } | 675 const CfgNode *getTargetTrue() const { return TargetTrue; } |
| 578 const CfgNode *getTargetFalse() const { return TargetFalse; } | 676 const CfgNode *getTargetFalse() const { return TargetFalse; } |
| 579 bool optimizeBranch(const CfgNode *NextNode); | 677 bool optimizeBranch(const CfgNode *NextNode); |
| 580 uint32_t getEmitInstCount() const override { | 678 uint32_t getEmitInstCount() const override { |
| 581 uint32_t Sum = 0; | 679 uint32_t Sum = 0; |
| 680 if (Label) | |
| 681 ++Sum; | |
| 582 if (getTargetTrue()) | 682 if (getTargetTrue()) |
| 583 ++Sum; | 683 ++Sum; |
| 584 if (getTargetFalse()) | 684 if (getTargetFalse()) |
| 585 ++Sum; | 685 ++Sum; |
| 586 return Sum; | 686 return Sum; |
| 587 } | 687 } |
| 588 bool isUnconditionalBranch() const override { | 688 bool isUnconditionalBranch() const override { |
| 589 return getPredicate() == CondARM32::AL; | 689 return getPredicate() == CondARM32::AL; |
| 590 } | 690 } |
| 591 bool repointEdge(CfgNode *OldNode, CfgNode *NewNode) override; | 691 bool repointEdge(CfgNode *OldNode, CfgNode *NewNode) override; |
| 592 void emit(const Cfg *Func) const override; | 692 void emit(const Cfg *Func) const override; |
| 593 void emitIAS(const Cfg *Func) const override; | 693 void emitIAS(const Cfg *Func) const override; |
| 594 void dump(const Cfg *Func) const override; | 694 void dump(const Cfg *Func) const override; |
| 595 static bool classof(const Inst *Inst) { return isClassof(Inst, Br); } | 695 static bool classof(const Inst *Inst) { return isClassof(Inst, Br); } |
| 596 | 696 |
| 597 private: | 697 private: |
| 598 InstARM32Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse, | 698 InstARM32Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse, |
| 599 CondARM32::Cond Predicate); | 699 const InstARM32Label *Label, CondARM32::Cond Predicate); |
| 600 | 700 |
| 601 const CfgNode *TargetTrue; | 701 const CfgNode *TargetTrue; |
| 602 const CfgNode *TargetFalse; | 702 const CfgNode *TargetFalse; |
| 703 const InstARM32Label *Label; // Intra-block branch target | |
| 603 }; | 704 }; |
| 604 | 705 |
| 605 // AdjustStack instruction - subtracts SP by the given amount and | 706 // AdjustStack instruction - subtracts SP by the given amount and |
| 606 // updates the stack offset during code emission. | 707 // updates the stack offset during code emission. |
| 607 class InstARM32AdjustStack : public InstARM32 { | 708 class InstARM32AdjustStack : public InstARM32 { |
| 608 InstARM32AdjustStack() = delete; | 709 InstARM32AdjustStack() = delete; |
| 609 InstARM32AdjustStack(const InstARM32AdjustStack &) = delete; | 710 InstARM32AdjustStack(const InstARM32AdjustStack &) = delete; |
| 610 InstARM32AdjustStack &operator=(const InstARM32AdjustStack &) = delete; | 711 InstARM32AdjustStack &operator=(const InstARM32AdjustStack &) = delete; |
| 611 | 712 |
| 612 public: | 713 public: |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 691 void emit(const Cfg *Func) const override; | 792 void emit(const Cfg *Func) const override; |
| 692 void emitIAS(const Cfg *Func) const override; | 793 void emitIAS(const Cfg *Func) const override; |
| 693 void dump(const Cfg *Func) const override; | 794 void dump(const Cfg *Func) const override; |
| 694 static bool classof(const Inst *Inst) { return isClassof(Inst, Ldr); } | 795 static bool classof(const Inst *Inst) { return isClassof(Inst, Ldr); } |
| 695 | 796 |
| 696 private: | 797 private: |
| 697 InstARM32Ldr(Cfg *Func, Variable *Dest, OperandARM32Mem *Mem, | 798 InstARM32Ldr(Cfg *Func, Variable *Dest, OperandARM32Mem *Mem, |
| 698 CondARM32::Cond Predicate); | 799 CondARM32::Cond Predicate); |
| 699 }; | 800 }; |
| 700 | 801 |
| 701 // Multiply Accumulate: d := x * y + a | |
| 702 class InstARM32Mla : public InstARM32Pred { | |
| 703 InstARM32Mla() = delete; | |
| 704 InstARM32Mla(const InstARM32Mla &) = delete; | |
| 705 InstARM32Mla &operator=(const InstARM32Mla &) = delete; | |
| 706 | |
| 707 public: | |
| 708 // Everything must be a register. | |
| 709 static InstARM32Mla *create(Cfg *Func, Variable *Dest, Variable *Src0, | |
| 710 Variable *Src1, Variable *Acc, | |
| 711 CondARM32::Cond Predicate) { | |
| 712 return new (Func->allocate<InstARM32Mla>()) | |
| 713 InstARM32Mla(Func, Dest, Src0, Src1, Acc, Predicate); | |
| 714 } | |
| 715 void emit(const Cfg *Func) const override; | |
| 716 void emitIAS(const Cfg *Func) const override; | |
| 717 void dump(const Cfg *Func) const override; | |
| 718 static bool classof(const Inst *Inst) { return isClassof(Inst, Mla); } | |
| 719 | |
| 720 private: | |
| 721 InstARM32Mla(Cfg *Func, Variable *Dest, Variable *Src0, Variable *Src1, | |
| 722 Variable *Acc, CondARM32::Cond Predicate); | |
| 723 }; | |
| 724 | |
| 725 // Pop into a list of GPRs. Technically this can be predicated, but we don't | 802 // Pop into a list of GPRs. Technically this can be predicated, but we don't |
| 726 // need that functionality. | 803 // need that functionality. |
| 727 class InstARM32Pop : public InstARM32 { | 804 class InstARM32Pop : public InstARM32 { |
| 728 InstARM32Pop() = delete; | 805 InstARM32Pop() = delete; |
| 729 InstARM32Pop(const InstARM32Pop &) = delete; | 806 InstARM32Pop(const InstARM32Pop &) = delete; |
| 730 InstARM32Pop &operator=(const InstARM32Pop &) = delete; | 807 InstARM32Pop &operator=(const InstARM32Pop &) = delete; |
| 731 | 808 |
| 732 public: | 809 public: |
| 733 static InstARM32Pop *create(Cfg *Func, const VarList &Dests) { | 810 static InstARM32Pop *create(Cfg *Func, const VarList &Dests) { |
| 734 return new (Func->allocate<InstARM32Pop>()) InstARM32Pop(Func, Dests); | 811 return new (Func->allocate<InstARM32Pop>()) InstARM32Pop(Func, Dests); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 809 void emit(const Cfg *Func) const override; | 886 void emit(const Cfg *Func) const override; |
| 810 void emitIAS(const Cfg *Func) const override; | 887 void emitIAS(const Cfg *Func) const override; |
| 811 void dump(const Cfg *Func) const override; | 888 void dump(const Cfg *Func) const override; |
| 812 static bool classof(const Inst *Inst) { return isClassof(Inst, Str); } | 889 static bool classof(const Inst *Inst) { return isClassof(Inst, Str); } |
| 813 | 890 |
| 814 private: | 891 private: |
| 815 InstARM32Str(Cfg *Func, Variable *Value, OperandARM32Mem *Mem, | 892 InstARM32Str(Cfg *Func, Variable *Value, OperandARM32Mem *Mem, |
| 816 CondARM32::Cond Predicate); | 893 CondARM32::Cond Predicate); |
| 817 }; | 894 }; |
| 818 | 895 |
| 896 class InstARM32Trap : public InstARM32 { | |
| 897 InstARM32Trap() = delete; | |
| 898 InstARM32Trap(const InstARM32Trap &) = delete; | |
| 899 InstARM32Trap &operator=(const InstARM32Trap &) = delete; | |
| 900 | |
| 901 public: | |
| 902 static InstARM32Trap *create(Cfg *Func) { | |
| 903 return new (Func->allocate<InstARM32Trap>()) InstARM32Trap(Func); | |
| 904 } | |
| 905 void emit(const Cfg *Func) const override; | |
| 906 void emitIAS(const Cfg *Func) const override; | |
| 907 void dump(const Cfg *Func) const override; | |
| 908 static bool classof(const Inst *Inst) { return isClassof(Inst, Trap); } | |
| 909 | |
| 910 private: | |
| 911 explicit InstARM32Trap(Cfg *Func); | |
| 912 }; | |
| 913 | |
| 914 class InstARM32Tst : public InstARM32Pred { | |
| 915 InstARM32Tst() = delete; | |
| 916 InstARM32Tst(const InstARM32Tst &) = delete; | |
| 917 InstARM32Tst &operator=(const InstARM32Tst &) = delete; | |
| 918 | |
| 919 public: | |
| 920 static InstARM32Tst *create(Cfg *Func, Variable *Src0, Operand *Src1, | |
| 921 CondARM32::Cond Predicate) { | |
| 922 return new (Func->allocate<InstARM32Tst>()) | |
| 923 InstARM32Tst(Func, Src0, Src1, Predicate); | |
| 924 } | |
| 925 void emit(const Cfg *Func) const override; | |
| 926 void emitIAS(const Cfg *Func) const override; | |
| 927 void dump(const Cfg *Func) const override; | |
| 928 static bool classof(const Inst *Inst) { return isClassof(Inst, Tst); } | |
| 929 | |
| 930 private: | |
| 931 InstARM32Tst(Cfg *Func, Variable *Src0, Operand *Src1, | |
| 932 CondARM32::Cond Predicate); | |
| 933 }; | |
| 934 | |
| 819 // Unsigned Multiply Long: d.lo, d.hi := x * y | 935 // Unsigned Multiply Long: d.lo, d.hi := x * y |
| 820 class InstARM32Umull : public InstARM32Pred { | 936 class InstARM32Umull : public InstARM32Pred { |
| 821 InstARM32Umull() = delete; | 937 InstARM32Umull() = delete; |
| 822 InstARM32Umull(const InstARM32Umull &) = delete; | 938 InstARM32Umull(const InstARM32Umull &) = delete; |
| 823 InstARM32Umull &operator=(const InstARM32Umull &) = delete; | 939 InstARM32Umull &operator=(const InstARM32Umull &) = delete; |
| 824 | 940 |
| 825 public: | 941 public: |
| 826 // Everything must be a register. | 942 // Everything must be a register. |
| 827 static InstARM32Umull *create(Cfg *Func, Variable *DestLo, Variable *DestHi, | 943 static InstARM32Umull *create(Cfg *Func, Variable *DestLo, Variable *DestHi, |
| 828 Variable *Src0, Variable *Src1, | 944 Variable *Src0, Variable *Src1, |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 845 // Declare partial template specializations of emit() methods that | 961 // Declare partial template specializations of emit() methods that |
| 846 // already have default implementations. Without this, there is the | 962 // already have default implementations. Without this, there is the |
| 847 // possibility of ODR violations and link errors. | 963 // possibility of ODR violations and link errors. |
| 848 | 964 |
| 849 template <> void InstARM32Movw::emit(const Cfg *Func) const; | 965 template <> void InstARM32Movw::emit(const Cfg *Func) const; |
| 850 template <> void InstARM32Movt::emit(const Cfg *Func) const; | 966 template <> void InstARM32Movt::emit(const Cfg *Func) const; |
| 851 | 967 |
| 852 } // end of namespace Ice | 968 } // end of namespace Ice |
| 853 | 969 |
| 854 #endif // SUBZERO_SRC_ICEINSTARM32_H | 970 #endif // SUBZERO_SRC_ICEINSTARM32_H |
| OLD | NEW |