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

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: rebase, refactor, and fix switch MINIMAL=1 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
« no previous file with comments | « src/IceGlobalContext.cpp ('k') | src/IceInstARM32.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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,
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/IceGlobalContext.cpp ('k') | src/IceInstARM32.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698