Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(160)

Side by Side Diff: src/IceInstARM32.h

Issue 1214693004: ARM lowering integer divide and remainder, with div by 0 checks. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: fill in todo Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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,
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
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);
333 static void emitCmpLike(const char *Opcode, const InstARM32Pred *Inst,
334 const Cfg *Func);
325 335
326 protected: 336 protected:
327 CondARM32::Cond Predicate; 337 CondARM32::Cond Predicate;
328 }; 338 };
329 339
330 template <typename StreamType> 340 template <typename StreamType>
331 inline StreamType &operator<<(StreamType &Stream, CondARM32::Cond Predicate) { 341 inline StreamType &operator<<(StreamType &Stream, CondARM32::Cond Predicate) {
332 Stream << InstARM32Pred::predString(Predicate); 342 Stream << InstARM32Pred::predString(Predicate);
333 return Stream; 343 return Stream;
334 } 344 }
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 Operand *Src2, CondARM32::Cond Predicate, bool SetFlags) 519 Operand *Src2, CondARM32::Cond Predicate, bool SetFlags)
510 : InstARM32Pred(Func, K, 2, Dest, Predicate), SetFlags(SetFlags) { 520 : InstARM32Pred(Func, K, 2, Dest, Predicate), SetFlags(SetFlags) {
511 addSource(Src1); 521 addSource(Src1);
512 addSource(Src2); 522 addSource(Src2);
513 } 523 }
514 524
515 static const char *Opcode; 525 static const char *Opcode;
516 bool SetFlags; 526 bool SetFlags;
517 }; 527 };
518 528
529 // Instructions of the form x := a op1 (y op2 z). E.g., multiply accumulate.
530 template <InstARM32::InstKindARM32 K>
531 class InstARM32FourAddrGPR : public InstARM32Pred {
532 InstARM32FourAddrGPR() = delete;
533 InstARM32FourAddrGPR(const InstARM32FourAddrGPR &) = delete;
534 InstARM32FourAddrGPR &operator=(const InstARM32FourAddrGPR &) = delete;
535
536 public:
537 // Every operand must be a register.
538 static InstARM32FourAddrGPR *create(Cfg *Func, Variable *Dest, Variable *Src1,
Jim Stichnoth 2015/06/30 14:14:08 Minor naming nit. I think that we've been naming
jvoung (off chromium) 2015/06/30 16:58:08 Ah -- Done here and for ThreeAddr also.
539 Variable *Src2, Variable *Src3,
540 CondARM32::Cond Predicate) {
541 return new (Func->allocate<InstARM32FourAddrGPR>())
542 InstARM32FourAddrGPR(Func, Dest, Src1, Src2, Src3, Predicate);
543 }
544 void emit(const Cfg *Func) const override {
545 if (!BuildDefs::dump())
546 return;
547 emitFourAddr(Opcode, this, Func);
548 }
549 void emitIAS(const Cfg *Func) const override {
550 (void)Func;
551 llvm::report_fatal_error("Not yet implemented");
552 }
553 void dump(const Cfg *Func) const override {
554 if (!BuildDefs::dump())
555 return;
556 Ostream &Str = Func->getContext()->getStrDump();
557 dumpDest(Func);
558 Str << " = ";
559 dumpOpcodePred(Str, Opcode, getDest()->getType());
560 Str << " ";
561 dumpSources(Func);
562 }
563 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
564
565 private:
566 InstARM32FourAddrGPR(Cfg *Func, Variable *Dest, Variable *Src1,
567 Variable *Src2, Variable *Src3,
568 CondARM32::Cond Predicate)
569 : InstARM32Pred(Func, K, 3, Dest, Predicate) {
570 addSource(Src1);
571 addSource(Src2);
572 addSource(Src3);
573 }
574
575 static const char *Opcode;
576 };
577
578 // Instructions of the form x cmpop y (setting flags).
579 template <InstARM32::InstKindARM32 K>
580 class InstARM32CmpLike : public InstARM32Pred {
581 InstARM32CmpLike() = delete;
582 InstARM32CmpLike(const InstARM32CmpLike &) = delete;
583 InstARM32CmpLike &operator=(const InstARM32CmpLike &) = delete;
584
585 public:
586 static InstARM32CmpLike *create(Cfg *Func, Variable *Src0, Operand *Src1,
587 CondARM32::Cond Predicate) {
588 return new (Func->allocate<InstARM32CmpLike>())
589 InstARM32CmpLike(Func, Src0, Src1, Predicate);
590 }
591 void emit(const Cfg *Func) const override {
592 if (!BuildDefs::dump())
593 return;
594 emitCmpLike(Opcode, this, Func);
595 }
596 void emitIAS(const Cfg *Func) const override {
597 (void)Func;
598 llvm_unreachable("Not yet implemented");
599 }
600 void dump(const Cfg *Func) const override {
601 if (!BuildDefs::dump())
602 return;
603 Ostream &Str = Func->getContext()->getStrDump();
604 dumpOpcodePred(Str, Opcode, getSrc(0)->getType());
605 Str << " ";
606 dumpSources(Func);
607 }
608 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
609
610 private:
611 InstARM32CmpLike(Cfg *Func, Variable *Src0, Operand *Src1,
612 CondARM32::Cond Predicate)
613 : InstARM32Pred(Func, K, 2, nullptr, Predicate) {
614 addSource(Src0);
615 addSource(Src1);
616 }
617
618 static const char *Opcode;
619 };
620
519 typedef InstARM32ThreeAddrGPR<InstARM32::Adc> InstARM32Adc; 621 typedef InstARM32ThreeAddrGPR<InstARM32::Adc> InstARM32Adc;
520 typedef InstARM32ThreeAddrGPR<InstARM32::Add> InstARM32Add; 622 typedef InstARM32ThreeAddrGPR<InstARM32::Add> InstARM32Add;
521 typedef InstARM32ThreeAddrGPR<InstARM32::And> InstARM32And; 623 typedef InstARM32ThreeAddrGPR<InstARM32::And> InstARM32And;
522 typedef InstARM32ThreeAddrGPR<InstARM32::Asr> InstARM32Asr; 624 typedef InstARM32ThreeAddrGPR<InstARM32::Asr> InstARM32Asr;
523 typedef InstARM32ThreeAddrGPR<InstARM32::Bic> InstARM32Bic; 625 typedef InstARM32ThreeAddrGPR<InstARM32::Bic> InstARM32Bic;
524 typedef InstARM32ThreeAddrGPR<InstARM32::Eor> InstARM32Eor; 626 typedef InstARM32ThreeAddrGPR<InstARM32::Eor> InstARM32Eor;
525 typedef InstARM32ThreeAddrGPR<InstARM32::Lsl> InstARM32Lsl; 627 typedef InstARM32ThreeAddrGPR<InstARM32::Lsl> InstARM32Lsl;
526 typedef InstARM32ThreeAddrGPR<InstARM32::Lsr> InstARM32Lsr; 628 typedef InstARM32ThreeAddrGPR<InstARM32::Lsr> InstARM32Lsr;
527 typedef InstARM32ThreeAddrGPR<InstARM32::Mul> InstARM32Mul; 629 typedef InstARM32ThreeAddrGPR<InstARM32::Mul> InstARM32Mul;
528 typedef InstARM32ThreeAddrGPR<InstARM32::Orr> InstARM32Orr; 630 typedef InstARM32ThreeAddrGPR<InstARM32::Orr> InstARM32Orr;
529 typedef InstARM32ThreeAddrGPR<InstARM32::Rsb> InstARM32Rsb; 631 typedef InstARM32ThreeAddrGPR<InstARM32::Rsb> InstARM32Rsb;
530 typedef InstARM32ThreeAddrGPR<InstARM32::Sbc> InstARM32Sbc; 632 typedef InstARM32ThreeAddrGPR<InstARM32::Sbc> InstARM32Sbc;
633 typedef InstARM32ThreeAddrGPR<InstARM32::Sdiv> InstARM32Sdiv;
531 typedef InstARM32ThreeAddrGPR<InstARM32::Sub> InstARM32Sub; 634 typedef InstARM32ThreeAddrGPR<InstARM32::Sub> InstARM32Sub;
635 typedef InstARM32ThreeAddrGPR<InstARM32::Udiv> InstARM32Udiv;
532 // Move instruction (variable <- flex). This is more of a pseudo-inst. 636 // 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 637 // If var is a register, then we use "mov". If var is stack, then we use
534 // "str" to store to the stack. 638 // "str" to store to the stack.
535 typedef InstARM32Movlike<InstARM32::Mov> InstARM32Mov; 639 typedef InstARM32Movlike<InstARM32::Mov> InstARM32Mov;
536 // MovT leaves the bottom bits alone so dest is also a source. 640 // 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. 641 // This helps indicate that a previous MovW setting dest is not dead code.
538 typedef InstARM32TwoAddrGPR<InstARM32::Movt> InstARM32Movt; 642 typedef InstARM32TwoAddrGPR<InstARM32::Movt> InstARM32Movt;
539 typedef InstARM32UnaryopGPR<InstARM32::Movw> InstARM32Movw; 643 typedef InstARM32UnaryopGPR<InstARM32::Movw> InstARM32Movw;
540 typedef InstARM32UnaryopGPR<InstARM32::Mvn> InstARM32Mvn; 644 typedef InstARM32UnaryopGPR<InstARM32::Mvn> InstARM32Mvn;
541 // Technically, the uxt{b,h} and sxt{b,h} instructions have a rotation 645 // 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), 646 // 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. 647 // but we aren't using that for now, so just model as a Unaryop.
544 typedef InstARM32UnaryopGPR<InstARM32::Sxt> InstARM32Sxt; 648 typedef InstARM32UnaryopGPR<InstARM32::Sxt> InstARM32Sxt;
545 typedef InstARM32UnaryopGPR<InstARM32::Uxt> InstARM32Uxt; 649 typedef InstARM32UnaryopGPR<InstARM32::Uxt> InstARM32Uxt;
650 typedef InstARM32FourAddrGPR<InstARM32::Mla> InstARM32Mla;
651 typedef InstARM32FourAddrGPR<InstARM32::Mls> InstARM32Mls;
652 typedef InstARM32CmpLike<InstARM32::Cmp> InstARM32Cmp;
653 typedef InstARM32CmpLike<InstARM32::Tst> InstARM32Tst;
654
655 // InstARM32Label represents an intra-block label that is the target
656 // of an intra-block branch. The offset between the label and the
657 // branch must be fit in the instruction immediate (considered "near").
658 class InstARM32Label : public InstARM32 {
659 InstARM32Label() = delete;
660 InstARM32Label(const InstARM32Label &) = delete;
661 InstARM32Label &operator=(const InstARM32Label &) = delete;
662
663 public:
664 static InstARM32Label *create(Cfg *Func, TargetARM32 *Target) {
665 return new (Func->allocate<InstARM32Label>()) InstARM32Label(Func, Target);
666 }
667 uint32_t getEmitInstCount() const override { return 0; }
668 IceString getName(const Cfg *Func) const;
669 SizeT getNumber() const { return Number; }
670 void emit(const Cfg *Func) const override;
671 void emitIAS(const Cfg *Func) const override;
672 void dump(const Cfg *Func) const override;
673
674 private:
675 InstARM32Label(Cfg *Func, TargetARM32 *Target);
676
677 SizeT Number; // used for unique label generation.
678 };
546 679
547 // Direct branch instruction. 680 // Direct branch instruction.
548 class InstARM32Br : public InstARM32Pred { 681 class InstARM32Br : public InstARM32Pred {
549 InstARM32Br() = delete; 682 InstARM32Br() = delete;
550 InstARM32Br(const InstARM32Br &) = delete; 683 InstARM32Br(const InstARM32Br &) = delete;
551 InstARM32Br &operator=(const InstARM32Br &) = delete; 684 InstARM32Br &operator=(const InstARM32Br &) = delete;
552 685
553 public: 686 public:
554 // Create a conditional branch to one of two nodes. 687 // Create a conditional branch to one of two nodes.
555 static InstARM32Br *create(Cfg *Func, CfgNode *TargetTrue, 688 static InstARM32Br *create(Cfg *Func, CfgNode *TargetTrue,
556 CfgNode *TargetFalse, CondARM32::Cond Predicate) { 689 CfgNode *TargetFalse, CondARM32::Cond Predicate) {
557 assert(Predicate != CondARM32::AL); 690 assert(Predicate != CondARM32::AL);
691 const InstARM32Label *NoLabel = nullptr;
Jim Stichnoth 2015/06/30 14:14:08 constexpr?
jvoung (off chromium) 2015/06/30 16:58:08 Done.
558 return new (Func->allocate<InstARM32Br>()) 692 return new (Func->allocate<InstARM32Br>())
559 InstARM32Br(Func, TargetTrue, TargetFalse, Predicate); 693 InstARM32Br(Func, TargetTrue, TargetFalse, NoLabel, Predicate);
560 } 694 }
561 // Create an unconditional branch to a node. 695 // Create an unconditional branch to a node.
562 static InstARM32Br *create(Cfg *Func, CfgNode *Target) { 696 static InstARM32Br *create(Cfg *Func, CfgNode *Target) {
563 const CfgNode *NoCondTarget = nullptr; 697 const CfgNode *NoCondTarget = nullptr;
698 const InstARM32Label *NoLabel = nullptr;
564 return new (Func->allocate<InstARM32Br>()) 699 return new (Func->allocate<InstARM32Br>())
565 InstARM32Br(Func, NoCondTarget, Target, CondARM32::AL); 700 InstARM32Br(Func, NoCondTarget, Target, NoLabel, CondARM32::AL);
566 } 701 }
567 // Create a non-terminator conditional branch to a node, with a 702 // Create a non-terminator conditional branch to a node, with a
568 // fallthrough to the next instruction in the current node. This is 703 // fallthrough to the next instruction in the current node. This is
569 // used for switch lowering. 704 // used for switch lowering.
570 static InstARM32Br *create(Cfg *Func, CfgNode *Target, 705 static InstARM32Br *create(Cfg *Func, CfgNode *Target,
571 CondARM32::Cond Predicate) { 706 CondARM32::Cond Predicate) {
572 assert(Predicate != CondARM32::AL); 707 assert(Predicate != CondARM32::AL);
573 const CfgNode *NoUncondTarget = nullptr; 708 const CfgNode *NoUncondTarget = nullptr;
709 const InstARM32Label *NoLabel = nullptr;
574 return new (Func->allocate<InstARM32Br>()) 710 return new (Func->allocate<InstARM32Br>())
575 InstARM32Br(Func, Target, NoUncondTarget, Predicate); 711 InstARM32Br(Func, Target, NoUncondTarget, NoLabel, Predicate);
712 }
713 // Create a conditional intra-block branch (or unconditional, if
714 // Condition==AL) to a label in the current block.
715 static InstARM32Br *create(Cfg *Func, InstARM32Label *Label,
716 CondARM32::Cond Predicate) {
717 const CfgNode *NoCondTarget = nullptr;
718 const CfgNode *NoUncondTarget = nullptr;
719 return new (Func->allocate<InstARM32Br>())
720 InstARM32Br(Func, NoCondTarget, NoUncondTarget, Label, Predicate);
576 } 721 }
577 const CfgNode *getTargetTrue() const { return TargetTrue; } 722 const CfgNode *getTargetTrue() const { return TargetTrue; }
578 const CfgNode *getTargetFalse() const { return TargetFalse; } 723 const CfgNode *getTargetFalse() const { return TargetFalse; }
579 bool optimizeBranch(const CfgNode *NextNode); 724 bool optimizeBranch(const CfgNode *NextNode);
580 uint32_t getEmitInstCount() const override { 725 uint32_t getEmitInstCount() const override {
581 uint32_t Sum = 0; 726 uint32_t Sum = 0;
727 if (Label)
728 ++Sum;
582 if (getTargetTrue()) 729 if (getTargetTrue())
583 ++Sum; 730 ++Sum;
584 if (getTargetFalse()) 731 if (getTargetFalse())
585 ++Sum; 732 ++Sum;
586 return Sum; 733 return Sum;
587 } 734 }
588 bool isUnconditionalBranch() const override { 735 bool isUnconditionalBranch() const override {
589 return getPredicate() == CondARM32::AL; 736 return getPredicate() == CondARM32::AL;
590 } 737 }
591 bool repointEdge(CfgNode *OldNode, CfgNode *NewNode) override; 738 bool repointEdge(CfgNode *OldNode, CfgNode *NewNode) override;
592 void emit(const Cfg *Func) const override; 739 void emit(const Cfg *Func) const override;
593 void emitIAS(const Cfg *Func) const override; 740 void emitIAS(const Cfg *Func) const override;
594 void dump(const Cfg *Func) const override; 741 void dump(const Cfg *Func) const override;
595 static bool classof(const Inst *Inst) { return isClassof(Inst, Br); } 742 static bool classof(const Inst *Inst) { return isClassof(Inst, Br); }
596 743
597 private: 744 private:
598 InstARM32Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse, 745 InstARM32Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse,
599 CondARM32::Cond Predicate); 746 const InstARM32Label *Label, CondARM32::Cond Predicate);
600 747
601 const CfgNode *TargetTrue; 748 const CfgNode *TargetTrue;
602 const CfgNode *TargetFalse; 749 const CfgNode *TargetFalse;
750 const InstARM32Label *Label; // Intra-block branch target
603 }; 751 };
604 752
605 // AdjustStack instruction - subtracts SP by the given amount and 753 // AdjustStack instruction - subtracts SP by the given amount and
606 // updates the stack offset during code emission. 754 // updates the stack offset during code emission.
607 class InstARM32AdjustStack : public InstARM32 { 755 class InstARM32AdjustStack : public InstARM32 {
608 InstARM32AdjustStack() = delete; 756 InstARM32AdjustStack() = delete;
609 InstARM32AdjustStack(const InstARM32AdjustStack &) = delete; 757 InstARM32AdjustStack(const InstARM32AdjustStack &) = delete;
610 InstARM32AdjustStack &operator=(const InstARM32AdjustStack &) = delete; 758 InstARM32AdjustStack &operator=(const InstARM32AdjustStack &) = delete;
611 759
612 public: 760 public:
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
646 Operand *getCallTarget() const { return getSrc(0); } 794 Operand *getCallTarget() const { return getSrc(0); }
647 void emit(const Cfg *Func) const override; 795 void emit(const Cfg *Func) const override;
648 void emitIAS(const Cfg *Func) const override; 796 void emitIAS(const Cfg *Func) const override;
649 void dump(const Cfg *Func) const override; 797 void dump(const Cfg *Func) const override;
650 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); } 798 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); }
651 799
652 private: 800 private:
653 InstARM32Call(Cfg *Func, Variable *Dest, Operand *CallTarget); 801 InstARM32Call(Cfg *Func, Variable *Dest, Operand *CallTarget);
654 }; 802 };
655 803
656 // Integer compare instruction.
657 class InstARM32Cmp : public InstARM32Pred {
658 InstARM32Cmp() = delete;
659 InstARM32Cmp(const InstARM32Cmp &) = delete;
660 InstARM32Cmp &operator=(const InstARM32Cmp &) = delete;
661
662 public:
663 static InstARM32Cmp *create(Cfg *Func, Variable *Src1, Operand *Src2,
664 CondARM32::Cond Predicate) {
665 return new (Func->allocate<InstARM32Cmp>())
666 InstARM32Cmp(Func, Src1, Src2, Predicate);
667 }
668 void emit(const Cfg *Func) const override;
669 void emitIAS(const Cfg *Func) const override;
670 void dump(const Cfg *Func) const override;
671 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmp); }
672
673 private:
674 InstARM32Cmp(Cfg *Func, Variable *Src1, Operand *Src2,
675 CondARM32::Cond Predicate);
676 };
677
678 // Load instruction. 804 // Load instruction.
679 class InstARM32Ldr : public InstARM32Pred { 805 class InstARM32Ldr : public InstARM32Pred {
680 InstARM32Ldr() = delete; 806 InstARM32Ldr() = delete;
681 InstARM32Ldr(const InstARM32Ldr &) = delete; 807 InstARM32Ldr(const InstARM32Ldr &) = delete;
682 InstARM32Ldr &operator=(const InstARM32Ldr &) = delete; 808 InstARM32Ldr &operator=(const InstARM32Ldr &) = delete;
683 809
684 public: 810 public:
685 // Dest must be a register. 811 // Dest must be a register.
686 static InstARM32Ldr *create(Cfg *Func, Variable *Dest, OperandARM32Mem *Mem, 812 static InstARM32Ldr *create(Cfg *Func, Variable *Dest, OperandARM32Mem *Mem,
687 CondARM32::Cond Predicate) { 813 CondARM32::Cond Predicate) {
688 return new (Func->allocate<InstARM32Ldr>()) 814 return new (Func->allocate<InstARM32Ldr>())
689 InstARM32Ldr(Func, Dest, Mem, Predicate); 815 InstARM32Ldr(Func, Dest, Mem, Predicate);
690 } 816 }
691 void emit(const Cfg *Func) const override; 817 void emit(const Cfg *Func) const override;
692 void emitIAS(const Cfg *Func) const override; 818 void emitIAS(const Cfg *Func) const override;
693 void dump(const Cfg *Func) const override; 819 void dump(const Cfg *Func) const override;
694 static bool classof(const Inst *Inst) { return isClassof(Inst, Ldr); } 820 static bool classof(const Inst *Inst) { return isClassof(Inst, Ldr); }
695 821
696 private: 822 private:
697 InstARM32Ldr(Cfg *Func, Variable *Dest, OperandARM32Mem *Mem, 823 InstARM32Ldr(Cfg *Func, Variable *Dest, OperandARM32Mem *Mem,
698 CondARM32::Cond Predicate); 824 CondARM32::Cond Predicate);
699 }; 825 };
700 826
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 827 // Pop into a list of GPRs. Technically this can be predicated, but we don't
726 // need that functionality. 828 // need that functionality.
727 class InstARM32Pop : public InstARM32 { 829 class InstARM32Pop : public InstARM32 {
728 InstARM32Pop() = delete; 830 InstARM32Pop() = delete;
729 InstARM32Pop(const InstARM32Pop &) = delete; 831 InstARM32Pop(const InstARM32Pop &) = delete;
730 InstARM32Pop &operator=(const InstARM32Pop &) = delete; 832 InstARM32Pop &operator=(const InstARM32Pop &) = delete;
731 833
732 public: 834 public:
733 static InstARM32Pop *create(Cfg *Func, const VarList &Dests) { 835 static InstARM32Pop *create(Cfg *Func, const VarList &Dests) {
734 return new (Func->allocate<InstARM32Pop>()) InstARM32Pop(Func, Dests); 836 return new (Func->allocate<InstARM32Pop>()) InstARM32Pop(Func, Dests);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
809 void emit(const Cfg *Func) const override; 911 void emit(const Cfg *Func) const override;
810 void emitIAS(const Cfg *Func) const override; 912 void emitIAS(const Cfg *Func) const override;
811 void dump(const Cfg *Func) const override; 913 void dump(const Cfg *Func) const override;
812 static bool classof(const Inst *Inst) { return isClassof(Inst, Str); } 914 static bool classof(const Inst *Inst) { return isClassof(Inst, Str); }
813 915
814 private: 916 private:
815 InstARM32Str(Cfg *Func, Variable *Value, OperandARM32Mem *Mem, 917 InstARM32Str(Cfg *Func, Variable *Value, OperandARM32Mem *Mem,
816 CondARM32::Cond Predicate); 918 CondARM32::Cond Predicate);
817 }; 919 };
818 920
921 class InstARM32Trap : public InstARM32 {
922 InstARM32Trap() = delete;
923 InstARM32Trap(const InstARM32Trap &) = delete;
924 InstARM32Trap &operator=(const InstARM32Trap &) = delete;
925
926 public:
927 static InstARM32Trap *create(Cfg *Func) {
928 return new (Func->allocate<InstARM32Trap>()) InstARM32Trap(Func);
929 }
930 void emit(const Cfg *Func) const override;
931 void emitIAS(const Cfg *Func) const override;
932 void dump(const Cfg *Func) const override;
933 static bool classof(const Inst *Inst) { return isClassof(Inst, Trap); }
934
935 private:
936 explicit InstARM32Trap(Cfg *Func);
937 };
938
819 // Unsigned Multiply Long: d.lo, d.hi := x * y 939 // Unsigned Multiply Long: d.lo, d.hi := x * y
820 class InstARM32Umull : public InstARM32Pred { 940 class InstARM32Umull : public InstARM32Pred {
821 InstARM32Umull() = delete; 941 InstARM32Umull() = delete;
822 InstARM32Umull(const InstARM32Umull &) = delete; 942 InstARM32Umull(const InstARM32Umull &) = delete;
823 InstARM32Umull &operator=(const InstARM32Umull &) = delete; 943 InstARM32Umull &operator=(const InstARM32Umull &) = delete;
824 944
825 public: 945 public:
826 // Everything must be a register. 946 // Everything must be a register.
827 static InstARM32Umull *create(Cfg *Func, Variable *DestLo, Variable *DestHi, 947 static InstARM32Umull *create(Cfg *Func, Variable *DestLo, Variable *DestHi,
828 Variable *Src0, Variable *Src1, 948 Variable *Src0, Variable *Src1,
(...skipping 16 matching lines...) Expand all
845 // Declare partial template specializations of emit() methods that 965 // Declare partial template specializations of emit() methods that
846 // already have default implementations. Without this, there is the 966 // already have default implementations. Without this, there is the
847 // possibility of ODR violations and link errors. 967 // possibility of ODR violations and link errors.
848 968
849 template <> void InstARM32Movw::emit(const Cfg *Func) const; 969 template <> void InstARM32Movw::emit(const Cfg *Func) const;
850 template <> void InstARM32Movt::emit(const Cfg *Func) const; 970 template <> void InstARM32Movt::emit(const Cfg *Func) const;
851 971
852 } // end of namespace Ice 972 } // end of namespace Ice
853 973
854 #endif // SUBZERO_SRC_ICEINSTARM32_H 974 #endif // SUBZERO_SRC_ICEINSTARM32_H
OLDNEW
« no previous file with comments | « src/IceGlobalContext.cpp ('k') | src/IceInstARM32.cpp » ('j') | src/IceTargetLowering.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698