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 /// \file | 10 /// \file |
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 Rsb, | 313 Rsb, |
314 Sbc, | 314 Sbc, |
315 Sdiv, | 315 Sdiv, |
316 Str, | 316 Str, |
317 Sub, | 317 Sub, |
318 Sxt, | 318 Sxt, |
319 Trap, | 319 Trap, |
320 Tst, | 320 Tst, |
321 Udiv, | 321 Udiv, |
322 Umull, | 322 Umull, |
323 Uxt | 323 Uxt, |
| 324 Vadd, |
| 325 Vdiv, |
| 326 Vldr, |
| 327 Vmov, |
| 328 Vmul, |
| 329 Vsqrt, |
| 330 Vsub |
324 }; | 331 }; |
325 | 332 |
326 static const char *getWidthString(Type Ty); | 333 static const char *getWidthString(Type Ty); |
| 334 static const char *getVecWidthString(Type Ty); |
327 static CondARM32::Cond getOppositeCondition(CondARM32::Cond Cond); | 335 static CondARM32::Cond getOppositeCondition(CondARM32::Cond Cond); |
328 | 336 |
| 337 /// Shared emit routines for common forms of instructions. |
| 338 static void emitThreeAddrFP(const char *Opcode, const InstARM32 *Inst, |
| 339 const Cfg *Func); |
| 340 |
329 void dump(const Cfg *Func) const override; | 341 void dump(const Cfg *Func) const override; |
330 | 342 |
331 protected: | 343 protected: |
332 InstARM32(Cfg *Func, InstKindARM32 Kind, SizeT Maxsrcs, Variable *Dest) | 344 InstARM32(Cfg *Func, InstKindARM32 Kind, SizeT Maxsrcs, Variable *Dest) |
333 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {} | 345 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {} |
334 | 346 |
335 static bool isClassof(const Inst *Inst, InstKindARM32 MyKind) { | 347 static bool isClassof(const Inst *Inst, InstKindARM32 MyKind) { |
336 return Inst->getKind() == static_cast<InstKind>(MyKind); | 348 return Inst->getKind() == static_cast<InstKind>(MyKind); |
337 } | 349 } |
338 }; | 350 }; |
(...skipping 11 matching lines...) Expand all Loading... |
350 | 362 |
351 CondARM32::Cond getPredicate() const { return Predicate; } | 363 CondARM32::Cond getPredicate() const { return Predicate; } |
352 void setPredicate(CondARM32::Cond Pred) { Predicate = Pred; } | 364 void setPredicate(CondARM32::Cond Pred) { Predicate = Pred; } |
353 | 365 |
354 static const char *predString(CondARM32::Cond Predicate); | 366 static const char *predString(CondARM32::Cond Predicate); |
355 void dumpOpcodePred(Ostream &Str, const char *Opcode, Type Ty) const; | 367 void dumpOpcodePred(Ostream &Str, const char *Opcode, Type Ty) const; |
356 | 368 |
357 /// Shared emit routines for common forms of instructions. | 369 /// Shared emit routines for common forms of instructions. |
358 static void emitUnaryopGPR(const char *Opcode, const InstARM32Pred *Inst, | 370 static void emitUnaryopGPR(const char *Opcode, const InstARM32Pred *Inst, |
359 const Cfg *Func, bool NeedsWidthSuffix); | 371 const Cfg *Func, bool NeedsWidthSuffix); |
| 372 static void emitUnaryopFP(const char *Opcode, const InstARM32Pred *Inst, |
| 373 const Cfg *Func); |
360 static void emitTwoAddr(const char *Opcode, const InstARM32Pred *Inst, | 374 static void emitTwoAddr(const char *Opcode, const InstARM32Pred *Inst, |
361 const Cfg *Func); | 375 const Cfg *Func); |
362 static void emitThreeAddr(const char *Opcode, const InstARM32Pred *Inst, | 376 static void emitThreeAddr(const char *Opcode, const InstARM32Pred *Inst, |
363 const Cfg *Func, bool SetFlags); | 377 const Cfg *Func, bool SetFlags); |
364 static void emitFourAddr(const char *Opcode, const InstARM32Pred *Inst, | 378 static void emitFourAddr(const char *Opcode, const InstARM32Pred *Inst, |
365 const Cfg *Func); | 379 const Cfg *Func); |
366 static void emitCmpLike(const char *Opcode, const InstARM32Pred *Inst, | 380 static void emitCmpLike(const char *Opcode, const InstARM32Pred *Inst, |
367 const Cfg *Func); | 381 const Cfg *Func); |
368 | 382 |
369 protected: | 383 protected: |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
413 private: | 427 private: |
414 InstARM32UnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src, | 428 InstARM32UnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src, |
415 CondARM32::Cond Predicate) | 429 CondARM32::Cond Predicate) |
416 : InstARM32Pred(Func, K, 1, Dest, Predicate) { | 430 : InstARM32Pred(Func, K, 1, Dest, Predicate) { |
417 addSource(Src); | 431 addSource(Src); |
418 } | 432 } |
419 | 433 |
420 static const char *Opcode; | 434 static const char *Opcode; |
421 }; | 435 }; |
422 | 436 |
| 437 /// Instructions of the form x := op(y), for vector/FP. |
| 438 template <InstARM32::InstKindARM32 K> |
| 439 class InstARM32UnaryopFP : public InstARM32Pred { |
| 440 InstARM32UnaryopFP() = delete; |
| 441 InstARM32UnaryopFP(const InstARM32UnaryopFP &) = delete; |
| 442 InstARM32UnaryopFP &operator=(const InstARM32UnaryopFP &) = delete; |
| 443 |
| 444 public: |
| 445 static InstARM32UnaryopFP *create(Cfg *Func, Variable *Dest, Variable *Src, |
| 446 CondARM32::Cond Predicate) { |
| 447 return new (Func->allocate<InstARM32UnaryopFP>()) |
| 448 InstARM32UnaryopFP(Func, Dest, Src, Predicate); |
| 449 } |
| 450 void emit(const Cfg *Func) const override { |
| 451 if (!BuildDefs::dump()) |
| 452 return; |
| 453 emitUnaryopFP(Opcode, this, Func); |
| 454 } |
| 455 void emitIAS(const Cfg *Func) const override { |
| 456 (void)Func; |
| 457 llvm::report_fatal_error("Not yet implemented"); |
| 458 } |
| 459 void dump(const Cfg *Func) const override { |
| 460 if (!BuildDefs::dump()) |
| 461 return; |
| 462 Ostream &Str = Func->getContext()->getStrDump(); |
| 463 dumpDest(Func); |
| 464 Str << " = "; |
| 465 dumpOpcodePred(Str, Opcode, getDest()->getType()); |
| 466 Str << " "; |
| 467 dumpSources(Func); |
| 468 } |
| 469 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
| 470 |
| 471 private: |
| 472 InstARM32UnaryopFP(Cfg *Func, Variable *Dest, Operand *Src, |
| 473 CondARM32::Cond Predicate) |
| 474 : InstARM32Pred(Func, K, 1, Dest, Predicate) { |
| 475 addSource(Src); |
| 476 } |
| 477 |
| 478 static const char *Opcode; |
| 479 }; |
| 480 |
423 /// Instructions of the form x := x op y. | 481 /// Instructions of the form x := x op y. |
424 template <InstARM32::InstKindARM32 K> | 482 template <InstARM32::InstKindARM32 K> |
425 class InstARM32TwoAddrGPR : public InstARM32Pred { | 483 class InstARM32TwoAddrGPR : public InstARM32Pred { |
426 InstARM32TwoAddrGPR() = delete; | 484 InstARM32TwoAddrGPR() = delete; |
427 InstARM32TwoAddrGPR(const InstARM32TwoAddrGPR &) = delete; | 485 InstARM32TwoAddrGPR(const InstARM32TwoAddrGPR &) = delete; |
428 InstARM32TwoAddrGPR &operator=(const InstARM32TwoAddrGPR &) = delete; | 486 InstARM32TwoAddrGPR &operator=(const InstARM32TwoAddrGPR &) = delete; |
429 | 487 |
430 public: | 488 public: |
431 /// Dest must be a register. | 489 /// Dest must be a register. |
432 static InstARM32TwoAddrGPR *create(Cfg *Func, Variable *Dest, Operand *Src, | 490 static InstARM32TwoAddrGPR *create(Cfg *Func, Variable *Dest, Operand *Src, |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
552 Operand *Src1, CondARM32::Cond Predicate, bool SetFlags) | 610 Operand *Src1, CondARM32::Cond Predicate, bool SetFlags) |
553 : InstARM32Pred(Func, K, 2, Dest, Predicate), SetFlags(SetFlags) { | 611 : InstARM32Pred(Func, K, 2, Dest, Predicate), SetFlags(SetFlags) { |
554 addSource(Src0); | 612 addSource(Src0); |
555 addSource(Src1); | 613 addSource(Src1); |
556 } | 614 } |
557 | 615 |
558 static const char *Opcode; | 616 static const char *Opcode; |
559 bool SetFlags; | 617 bool SetFlags; |
560 }; | 618 }; |
561 | 619 |
562 // Instructions of the form x := a op1 (y op2 z). E.g., multiply accumulate. | 620 /// Instructions of the form x := y op z, for vector/FP. We leave these as |
| 621 /// unconditional: "ARM deprecates the conditional execution of any instruction |
| 622 /// encoding provided by the Advanced SIMD Extension that is not also provided |
| 623 /// by the Floating-point (VFP) extension". They do not set flags. |
| 624 template <InstARM32::InstKindARM32 K> |
| 625 class InstARM32ThreeAddrFP : public InstARM32 { |
| 626 InstARM32ThreeAddrFP() = delete; |
| 627 InstARM32ThreeAddrFP(const InstARM32ThreeAddrFP &) = delete; |
| 628 InstARM32ThreeAddrFP &operator=(const InstARM32ThreeAddrFP &) = delete; |
| 629 |
| 630 public: |
| 631 /// Create a vector/FP binary-op instruction like vadd, and vsub. |
| 632 /// Everything must be a register. |
| 633 static InstARM32ThreeAddrFP *create(Cfg *Func, Variable *Dest, Variable *Src0, |
| 634 Variable *Src1) { |
| 635 return new (Func->allocate<InstARM32ThreeAddrFP>()) |
| 636 InstARM32ThreeAddrFP(Func, Dest, Src0, Src1); |
| 637 } |
| 638 void emit(const Cfg *Func) const override { |
| 639 if (!BuildDefs::dump()) |
| 640 return; |
| 641 emitThreeAddrFP(Opcode, this, Func); |
| 642 } |
| 643 void emitIAS(const Cfg *Func) const override { |
| 644 (void)Func; |
| 645 llvm::report_fatal_error("Not yet implemented"); |
| 646 } |
| 647 void dump(const Cfg *Func) const override { |
| 648 if (!BuildDefs::dump()) |
| 649 return; |
| 650 Ostream &Str = Func->getContext()->getStrDump(); |
| 651 dumpDest(Func); |
| 652 Str << " = "; |
| 653 Str << Opcode << "." << getDest()->getType() << " "; |
| 654 dumpSources(Func); |
| 655 } |
| 656 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
| 657 |
| 658 private: |
| 659 InstARM32ThreeAddrFP(Cfg *Func, Variable *Dest, Variable *Src0, |
| 660 Variable *Src1) |
| 661 : InstARM32(Func, K, 2, Dest) { |
| 662 addSource(Src0); |
| 663 addSource(Src1); |
| 664 } |
| 665 |
| 666 static const char *Opcode; |
| 667 }; |
| 668 |
| 669 /// Instructions of the form x := a op1 (y op2 z). E.g., multiply accumulate. |
563 template <InstARM32::InstKindARM32 K> | 670 template <InstARM32::InstKindARM32 K> |
564 class InstARM32FourAddrGPR : public InstARM32Pred { | 671 class InstARM32FourAddrGPR : public InstARM32Pred { |
565 InstARM32FourAddrGPR() = delete; | 672 InstARM32FourAddrGPR() = delete; |
566 InstARM32FourAddrGPR(const InstARM32FourAddrGPR &) = delete; | 673 InstARM32FourAddrGPR(const InstARM32FourAddrGPR &) = delete; |
567 InstARM32FourAddrGPR &operator=(const InstARM32FourAddrGPR &) = delete; | 674 InstARM32FourAddrGPR &operator=(const InstARM32FourAddrGPR &) = delete; |
568 | 675 |
569 public: | 676 public: |
570 // Every operand must be a register. | 677 // Every operand must be a register. |
571 static InstARM32FourAddrGPR *create(Cfg *Func, Variable *Dest, Variable *Src0, | 678 static InstARM32FourAddrGPR *create(Cfg *Func, Variable *Dest, Variable *Src0, |
572 Variable *Src1, Variable *Src2, | 679 Variable *Src1, Variable *Src2, |
(...skipping 28 matching lines...) Expand all Loading... |
601 CondARM32::Cond Predicate) | 708 CondARM32::Cond Predicate) |
602 : InstARM32Pred(Func, K, 3, Dest, Predicate) { | 709 : InstARM32Pred(Func, K, 3, Dest, Predicate) { |
603 addSource(Src0); | 710 addSource(Src0); |
604 addSource(Src1); | 711 addSource(Src1); |
605 addSource(Src2); | 712 addSource(Src2); |
606 } | 713 } |
607 | 714 |
608 static const char *Opcode; | 715 static const char *Opcode; |
609 }; | 716 }; |
610 | 717 |
611 // Instructions of the form x cmpop y (setting flags). | 718 /// Instructions of the form x cmpop y (setting flags). |
612 template <InstARM32::InstKindARM32 K> | 719 template <InstARM32::InstKindARM32 K> |
613 class InstARM32CmpLike : public InstARM32Pred { | 720 class InstARM32CmpLike : public InstARM32Pred { |
614 InstARM32CmpLike() = delete; | 721 InstARM32CmpLike() = delete; |
615 InstARM32CmpLike(const InstARM32CmpLike &) = delete; | 722 InstARM32CmpLike(const InstARM32CmpLike &) = delete; |
616 InstARM32CmpLike &operator=(const InstARM32CmpLike &) = delete; | 723 InstARM32CmpLike &operator=(const InstARM32CmpLike &) = delete; |
617 | 724 |
618 public: | 725 public: |
619 static InstARM32CmpLike *create(Cfg *Func, Variable *Src0, Operand *Src1, | 726 static InstARM32CmpLike *create(Cfg *Func, Variable *Src0, Operand *Src1, |
620 CondARM32::Cond Predicate) { | 727 CondARM32::Cond Predicate) { |
621 return new (Func->allocate<InstARM32CmpLike>()) | 728 return new (Func->allocate<InstARM32CmpLike>()) |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
659 typedef InstARM32ThreeAddrGPR<InstARM32::Eor> InstARM32Eor; | 766 typedef InstARM32ThreeAddrGPR<InstARM32::Eor> InstARM32Eor; |
660 typedef InstARM32ThreeAddrGPR<InstARM32::Lsl> InstARM32Lsl; | 767 typedef InstARM32ThreeAddrGPR<InstARM32::Lsl> InstARM32Lsl; |
661 typedef InstARM32ThreeAddrGPR<InstARM32::Lsr> InstARM32Lsr; | 768 typedef InstARM32ThreeAddrGPR<InstARM32::Lsr> InstARM32Lsr; |
662 typedef InstARM32ThreeAddrGPR<InstARM32::Mul> InstARM32Mul; | 769 typedef InstARM32ThreeAddrGPR<InstARM32::Mul> InstARM32Mul; |
663 typedef InstARM32ThreeAddrGPR<InstARM32::Orr> InstARM32Orr; | 770 typedef InstARM32ThreeAddrGPR<InstARM32::Orr> InstARM32Orr; |
664 typedef InstARM32ThreeAddrGPR<InstARM32::Rsb> InstARM32Rsb; | 771 typedef InstARM32ThreeAddrGPR<InstARM32::Rsb> InstARM32Rsb; |
665 typedef InstARM32ThreeAddrGPR<InstARM32::Sbc> InstARM32Sbc; | 772 typedef InstARM32ThreeAddrGPR<InstARM32::Sbc> InstARM32Sbc; |
666 typedef InstARM32ThreeAddrGPR<InstARM32::Sdiv> InstARM32Sdiv; | 773 typedef InstARM32ThreeAddrGPR<InstARM32::Sdiv> InstARM32Sdiv; |
667 typedef InstARM32ThreeAddrGPR<InstARM32::Sub> InstARM32Sub; | 774 typedef InstARM32ThreeAddrGPR<InstARM32::Sub> InstARM32Sub; |
668 typedef InstARM32ThreeAddrGPR<InstARM32::Udiv> InstARM32Udiv; | 775 typedef InstARM32ThreeAddrGPR<InstARM32::Udiv> InstARM32Udiv; |
| 776 typedef InstARM32ThreeAddrFP<InstARM32::Vadd> InstARM32Vadd; |
| 777 typedef InstARM32ThreeAddrFP<InstARM32::Vdiv> InstARM32Vdiv; |
| 778 typedef InstARM32ThreeAddrFP<InstARM32::Vmul> InstARM32Vmul; |
| 779 typedef InstARM32ThreeAddrFP<InstARM32::Vsub> InstARM32Vsub; |
| 780 typedef InstARM32Movlike<InstARM32::Ldr> InstARM32Ldr; |
669 /// Move instruction (variable <- flex). This is more of a pseudo-inst. | 781 /// Move instruction (variable <- flex). This is more of a pseudo-inst. |
670 /// If var is a register, then we use "mov". If var is stack, then we use | 782 /// If var is a register, then we use "mov". If var is stack, then we use |
671 /// "str" to store to the stack. | 783 /// "str" to store to the stack. |
672 typedef InstARM32Movlike<InstARM32::Mov> InstARM32Mov; | 784 typedef InstARM32Movlike<InstARM32::Mov> InstARM32Mov; |
| 785 /// Represents various vector mov instruction forms (simple single source, |
| 786 /// single dest forms only, not the 2 GPR <-> 1 D reg forms, etc.). |
| 787 typedef InstARM32Movlike<InstARM32::Vmov> InstARM32Vmov; |
| 788 typedef InstARM32Movlike<InstARM32::Vldr> InstARM32Vldr; |
673 /// MovT leaves the bottom bits alone so dest is also a source. | 789 /// MovT leaves the bottom bits alone so dest is also a source. |
674 /// This helps indicate that a previous MovW setting dest is not dead code. | 790 /// This helps indicate that a previous MovW setting dest is not dead code. |
675 typedef InstARM32TwoAddrGPR<InstARM32::Movt> InstARM32Movt; | 791 typedef InstARM32TwoAddrGPR<InstARM32::Movt> InstARM32Movt; |
676 typedef InstARM32UnaryopGPR<InstARM32::Movw, false> InstARM32Movw; | 792 typedef InstARM32UnaryopGPR<InstARM32::Movw, false> InstARM32Movw; |
677 typedef InstARM32UnaryopGPR<InstARM32::Clz, false> InstARM32Clz; | 793 typedef InstARM32UnaryopGPR<InstARM32::Clz, false> InstARM32Clz; |
678 typedef InstARM32UnaryopGPR<InstARM32::Mvn, false> InstARM32Mvn; | 794 typedef InstARM32UnaryopGPR<InstARM32::Mvn, false> InstARM32Mvn; |
679 typedef InstARM32UnaryopGPR<InstARM32::Rbit, false> InstARM32Rbit; | 795 typedef InstARM32UnaryopGPR<InstARM32::Rbit, false> InstARM32Rbit; |
680 typedef InstARM32UnaryopGPR<InstARM32::Rev, false> InstARM32Rev; | 796 typedef InstARM32UnaryopGPR<InstARM32::Rev, false> InstARM32Rev; |
681 // Technically, the uxt{b,h} and sxt{b,h} instructions have a rotation | 797 // Technically, the uxt{b,h} and sxt{b,h} instructions have a rotation |
682 // operand as well (rotate source by 8, 16, 24 bits prior to extending), | 798 // operand as well (rotate source by 8, 16, 24 bits prior to extending), |
683 // but we aren't using that for now, so just model as a Unaryop. | 799 // but we aren't using that for now, so just model as a Unaryop. |
684 typedef InstARM32UnaryopGPR<InstARM32::Sxt, true> InstARM32Sxt; | 800 typedef InstARM32UnaryopGPR<InstARM32::Sxt, true> InstARM32Sxt; |
685 typedef InstARM32UnaryopGPR<InstARM32::Uxt, true> InstARM32Uxt; | 801 typedef InstARM32UnaryopGPR<InstARM32::Uxt, true> InstARM32Uxt; |
| 802 typedef InstARM32UnaryopFP<InstARM32::Vsqrt> InstARM32Vsqrt; |
686 typedef InstARM32FourAddrGPR<InstARM32::Mla> InstARM32Mla; | 803 typedef InstARM32FourAddrGPR<InstARM32::Mla> InstARM32Mla; |
687 typedef InstARM32FourAddrGPR<InstARM32::Mls> InstARM32Mls; | 804 typedef InstARM32FourAddrGPR<InstARM32::Mls> InstARM32Mls; |
688 typedef InstARM32CmpLike<InstARM32::Cmp> InstARM32Cmp; | 805 typedef InstARM32CmpLike<InstARM32::Cmp> InstARM32Cmp; |
689 typedef InstARM32CmpLike<InstARM32::Tst> InstARM32Tst; | 806 typedef InstARM32CmpLike<InstARM32::Tst> InstARM32Tst; |
690 | 807 |
691 // InstARM32Label represents an intra-block label that is the target | 808 // InstARM32Label represents an intra-block label that is the target |
692 // of an intra-block branch. The offset between the label and the | 809 // of an intra-block branch. The offset between the label and the |
693 // branch must be fit in the instruction immediate (considered "near"). | 810 // branch must be fit in the instruction immediate (considered "near"). |
694 class InstARM32Label : public InstARM32 { | 811 class InstARM32Label : public InstARM32 { |
695 InstARM32Label() = delete; | 812 InstARM32Label() = delete; |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
831 Operand *getCallTarget() const { return getSrc(0); } | 948 Operand *getCallTarget() const { return getSrc(0); } |
832 void emit(const Cfg *Func) const override; | 949 void emit(const Cfg *Func) const override; |
833 void emitIAS(const Cfg *Func) const override; | 950 void emitIAS(const Cfg *Func) const override; |
834 void dump(const Cfg *Func) const override; | 951 void dump(const Cfg *Func) const override; |
835 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); } | 952 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); } |
836 | 953 |
837 private: | 954 private: |
838 InstARM32Call(Cfg *Func, Variable *Dest, Operand *CallTarget); | 955 InstARM32Call(Cfg *Func, Variable *Dest, Operand *CallTarget); |
839 }; | 956 }; |
840 | 957 |
841 /// Load instruction. | |
842 class InstARM32Ldr : public InstARM32Pred { | |
843 InstARM32Ldr() = delete; | |
844 InstARM32Ldr(const InstARM32Ldr &) = delete; | |
845 InstARM32Ldr &operator=(const InstARM32Ldr &) = delete; | |
846 | |
847 public: | |
848 /// Dest must be a register. | |
849 static InstARM32Ldr *create(Cfg *Func, Variable *Dest, OperandARM32Mem *Mem, | |
850 CondARM32::Cond Predicate) { | |
851 return new (Func->allocate<InstARM32Ldr>()) | |
852 InstARM32Ldr(Func, Dest, Mem, Predicate); | |
853 } | |
854 void emit(const Cfg *Func) const override; | |
855 void emitIAS(const Cfg *Func) const override; | |
856 void dump(const Cfg *Func) const override; | |
857 static bool classof(const Inst *Inst) { return isClassof(Inst, Ldr); } | |
858 | |
859 private: | |
860 InstARM32Ldr(Cfg *Func, Variable *Dest, OperandARM32Mem *Mem, | |
861 CondARM32::Cond Predicate); | |
862 }; | |
863 | |
864 /// Pop into a list of GPRs. Technically this can be predicated, but we don't | 958 /// Pop into a list of GPRs. Technically this can be predicated, but we don't |
865 /// need that functionality. | 959 /// need that functionality. |
866 class InstARM32Pop : public InstARM32 { | 960 class InstARM32Pop : public InstARM32 { |
867 InstARM32Pop() = delete; | 961 InstARM32Pop() = delete; |
868 InstARM32Pop(const InstARM32Pop &) = delete; | 962 InstARM32Pop(const InstARM32Pop &) = delete; |
869 InstARM32Pop &operator=(const InstARM32Pop &) = delete; | 963 InstARM32Pop &operator=(const InstARM32Pop &) = delete; |
870 | 964 |
871 public: | 965 public: |
872 static InstARM32Pop *create(Cfg *Func, const VarList &Dests) { | 966 static InstARM32Pop *create(Cfg *Func, const VarList &Dests) { |
873 return new (Func->allocate<InstARM32Pop>()) InstARM32Pop(Func, Dests); | 967 return new (Func->allocate<InstARM32Pop>()) InstARM32Pop(Func, Dests); |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
996 InstARM32Umull(Cfg *Func, Variable *DestLo, Variable *DestHi, Variable *Src0, | 1090 InstARM32Umull(Cfg *Func, Variable *DestLo, Variable *DestHi, Variable *Src0, |
997 Variable *Src1, CondARM32::Cond Predicate); | 1091 Variable *Src1, CondARM32::Cond Predicate); |
998 | 1092 |
999 Variable *DestHi; | 1093 Variable *DestHi; |
1000 }; | 1094 }; |
1001 | 1095 |
1002 // Declare partial template specializations of emit() methods that | 1096 // Declare partial template specializations of emit() methods that |
1003 // already have default implementations. Without this, there is the | 1097 // already have default implementations. Without this, there is the |
1004 // possibility of ODR violations and link errors. | 1098 // possibility of ODR violations and link errors. |
1005 | 1099 |
| 1100 template <> void InstARM32Ldr::emit(const Cfg *Func) const; |
| 1101 template <> void InstARM32Mov::emit(const Cfg *Func) const; |
1006 template <> void InstARM32Movw::emit(const Cfg *Func) const; | 1102 template <> void InstARM32Movw::emit(const Cfg *Func) const; |
1007 template <> void InstARM32Movt::emit(const Cfg *Func) const; | 1103 template <> void InstARM32Movt::emit(const Cfg *Func) const; |
| 1104 template <> void InstARM32Vldr::emit(const Cfg *Func) const; |
| 1105 template <> void InstARM32Vmov::emit(const Cfg *Func) const; |
1008 | 1106 |
1009 } // end of namespace Ice | 1107 } // end of namespace Ice |
1010 | 1108 |
1011 #endif // SUBZERO_SRC_ICEINSTARM32_H | 1109 #endif // SUBZERO_SRC_ICEINSTARM32_H |
OLD | NEW |