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 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
421 Sxt, | 421 Sxt, |
422 Trap, | 422 Trap, |
423 Tst, | 423 Tst, |
424 Udiv, | 424 Udiv, |
425 Umull, | 425 Umull, |
426 Uxt, | 426 Uxt, |
427 Vabs, | 427 Vabs, |
428 Vadd, | 428 Vadd, |
429 Vand, | 429 Vand, |
430 Vbsl, | 430 Vbsl, |
| 431 Vceq, |
| 432 Vcge, |
| 433 Vcgt, |
431 Vcmp, | 434 Vcmp, |
432 Vcvt, | 435 Vcvt, |
433 Vdiv, | 436 Vdiv, |
434 Veor, | 437 Veor, |
435 Vmla, | 438 Vmla, |
436 Vmls, | 439 Vmls, |
437 Vmrs, | 440 Vmrs, |
438 Vmul, | 441 Vmul, |
| 442 Vmvn, |
439 Vneg, | 443 Vneg, |
440 Vorr, | 444 Vorr, |
441 Vshl, | 445 Vshl, |
442 Vshr, | 446 Vshr, |
443 Vsqrt, | 447 Vsqrt, |
444 Vsub | 448 Vsub |
445 }; | 449 }; |
446 | 450 |
447 static constexpr size_t InstSize = sizeof(uint32_t); | 451 static constexpr size_t InstSize = sizeof(uint32_t); |
448 | 452 |
449 static CondARM32::Cond getOppositeCondition(CondARM32::Cond Cond); | 453 static CondARM32::Cond getOppositeCondition(CondARM32::Cond Cond); |
450 | 454 |
451 /// Called inside derived methods emit() to communicate that multiple | 455 /// Called inside derived methods emit() to communicate that multiple |
452 /// instructions are being generated. Used by emitIAS() methods to | 456 /// instructions are being generated. Used by emitIAS() methods to |
453 /// generate textual fixups for instructions that are not yet | 457 /// generate textual fixups for instructions that are not yet |
454 /// implemented. | 458 /// implemented. |
455 void startNextInst(const Cfg *Func) const; | 459 void startNextInst(const Cfg *Func) const; |
456 | 460 |
457 /// FPSign is used for certain vector instructions (particularly, right | 461 /// FPSign is used for certain vector instructions (particularly, right |
458 /// shifts) that require an operand sign specification. | 462 /// shifts) that require an operand sign specification. |
459 enum FPSign { | 463 enum FPSign { |
460 FS_None, | 464 FS_None, |
461 FS_Signed, | 465 FS_Signed, |
462 FS_Unsigned, | 466 FS_Unsigned, |
463 }; | 467 }; |
464 /// Shared emit routines for common forms of instructions. | 468 /// Shared emit routines for common forms of instructions. |
465 /// @{ | 469 /// @{ |
466 static void emitThreeAddrFP(const char *Opcode, FPSign Sign, | 470 static void emitThreeAddrFP(const char *Opcode, FPSign Sign, |
467 const InstARM32 *Instr, const Cfg *Func); | 471 const InstARM32 *Instr, const Cfg *Func, |
| 472 Type OpType); |
468 static void emitFourAddrFP(const char *Opcode, FPSign Sign, | 473 static void emitFourAddrFP(const char *Opcode, FPSign Sign, |
469 const InstARM32 *Instr, const Cfg *Func); | 474 const InstARM32 *Instr, const Cfg *Func); |
470 /// @} | 475 /// @} |
471 | 476 |
472 void dump(const Cfg *Func) const override; | 477 void dump(const Cfg *Func) const override; |
473 | 478 |
474 void emitIAS(const Cfg *Func) const override; | 479 void emitIAS(const Cfg *Func) const override; |
475 | 480 |
476 protected: | 481 protected: |
477 InstARM32(Cfg *Func, InstKindARM32 Kind, SizeT Maxsrcs, Variable *Dest) | 482 InstARM32(Cfg *Func, InstKindARM32 Kind, SizeT Maxsrcs, Variable *Dest) |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
775 /// Create a vector/FP binary-op instruction like vadd, and vsub. Everything | 780 /// Create a vector/FP binary-op instruction like vadd, and vsub. Everything |
776 /// must be a register. | 781 /// must be a register. |
777 static InstARM32ThreeAddrFP *create(Cfg *Func, Variable *Dest, Variable *Src0, | 782 static InstARM32ThreeAddrFP *create(Cfg *Func, Variable *Dest, Variable *Src0, |
778 Variable *Src1) { | 783 Variable *Src1) { |
779 return new (Func->allocate<InstARM32ThreeAddrFP>()) | 784 return new (Func->allocate<InstARM32ThreeAddrFP>()) |
780 InstARM32ThreeAddrFP(Func, Dest, Src0, Src1); | 785 InstARM32ThreeAddrFP(Func, Dest, Src0, Src1); |
781 } | 786 } |
782 void emit(const Cfg *Func) const override { | 787 void emit(const Cfg *Func) const override { |
783 if (!BuildDefs::dump()) | 788 if (!BuildDefs::dump()) |
784 return; | 789 return; |
785 emitThreeAddrFP(Opcode, Sign, this, Func); | 790 const Type OpType = (isVectorCompare() ? getSrc(0) : getDest())->getType(); |
| 791 emitThreeAddrFP(Opcode, Sign, this, Func, OpType); |
786 } | 792 } |
787 void emitIAS(const Cfg *Func) const override; | 793 void emitIAS(const Cfg *Func) const override; |
788 void dump(const Cfg *Func) const override { | 794 void dump(const Cfg *Func) const override { |
789 if (!BuildDefs::dump()) | 795 if (!BuildDefs::dump()) |
790 return; | 796 return; |
791 Ostream &Str = Func->getContext()->getStrDump(); | 797 Ostream &Str = Func->getContext()->getStrDump(); |
792 dumpDest(Func); | 798 dumpDest(Func); |
793 Str << " = "; | 799 const Type OpType = (isVectorCompare() ? getSrc(0) : getDest())->getType(); |
794 Str << Opcode << "." << getDest()->getType() << " "; | 800 Str << " = " << Opcode << "." << OpType << " "; |
795 dumpSources(Func); | 801 dumpSources(Func); |
796 } | 802 } |
797 static bool classof(const Inst *Instr) { return isClassof(Instr, K); } | 803 static bool classof(const Inst *Instr) { return isClassof(Instr, K); } |
798 | 804 |
799 protected: | 805 protected: |
800 FPSign Sign = FS_None; | 806 FPSign Sign = FS_None; |
801 | 807 |
802 InstARM32ThreeAddrFP(Cfg *Func, Variable *Dest, Variable *Src0, Operand *Src1) | 808 InstARM32ThreeAddrFP(Cfg *Func, Variable *Dest, Variable *Src0, Operand *Src1) |
803 : InstARM32(Func, K, 2, Dest) { | 809 : InstARM32(Func, K, 2, Dest) { |
804 addSource(Src0); | 810 addSource(Src0); |
805 addSource(Src1); | 811 addSource(Src1); |
806 } | 812 } |
807 | 813 |
808 static const char *Opcode; | 814 static const char *Opcode; |
| 815 |
| 816 private: |
| 817 static constexpr bool isVectorCompare() { |
| 818 return K == InstARM32::Vceq || K == InstARM32::Vcgt || K == InstARM32::Vcge; |
| 819 } |
809 }; | 820 }; |
810 | 821 |
811 template <InstARM32::InstKindARM32 K> | 822 template <InstARM32::InstKindARM32 K> |
812 class InstARM32ThreeAddrSignAwareFP : public InstARM32ThreeAddrFP<K> { | 823 class InstARM32ThreeAddrSignAwareFP : public InstARM32ThreeAddrFP<K> { |
813 InstARM32ThreeAddrSignAwareFP() = delete; | 824 InstARM32ThreeAddrSignAwareFP() = delete; |
814 InstARM32ThreeAddrSignAwareFP(const InstARM32ThreeAddrSignAwareFP &) = delete; | 825 InstARM32ThreeAddrSignAwareFP(const InstARM32ThreeAddrSignAwareFP &) = delete; |
815 InstARM32ThreeAddrSignAwareFP & | 826 InstARM32ThreeAddrSignAwareFP & |
816 operator=(const InstARM32ThreeAddrSignAwareFP &) = delete; | 827 operator=(const InstARM32ThreeAddrSignAwareFP &) = delete; |
817 | 828 |
818 public: | 829 public: |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
987 using InstARM32Orr = InstARM32ThreeAddrGPR<InstARM32::Orr>; | 998 using InstARM32Orr = InstARM32ThreeAddrGPR<InstARM32::Orr>; |
988 using InstARM32Rsb = InstARM32ThreeAddrGPR<InstARM32::Rsb>; | 999 using InstARM32Rsb = InstARM32ThreeAddrGPR<InstARM32::Rsb>; |
989 using InstARM32Rsc = InstARM32ThreeAddrGPR<InstARM32::Rsc>; | 1000 using InstARM32Rsc = InstARM32ThreeAddrGPR<InstARM32::Rsc>; |
990 using InstARM32Sbc = InstARM32ThreeAddrGPR<InstARM32::Sbc>; | 1001 using InstARM32Sbc = InstARM32ThreeAddrGPR<InstARM32::Sbc>; |
991 using InstARM32Sdiv = InstARM32ThreeAddrGPR<InstARM32::Sdiv>; | 1002 using InstARM32Sdiv = InstARM32ThreeAddrGPR<InstARM32::Sdiv>; |
992 using InstARM32Sub = InstARM32ThreeAddrGPR<InstARM32::Sub>; | 1003 using InstARM32Sub = InstARM32ThreeAddrGPR<InstARM32::Sub>; |
993 using InstARM32Udiv = InstARM32ThreeAddrGPR<InstARM32::Udiv>; | 1004 using InstARM32Udiv = InstARM32ThreeAddrGPR<InstARM32::Udiv>; |
994 using InstARM32Vadd = InstARM32ThreeAddrFP<InstARM32::Vadd>; | 1005 using InstARM32Vadd = InstARM32ThreeAddrFP<InstARM32::Vadd>; |
995 using InstARM32Vand = InstARM32ThreeAddrFP<InstARM32::Vand>; | 1006 using InstARM32Vand = InstARM32ThreeAddrFP<InstARM32::Vand>; |
996 using InstARM32Vbsl = InstARM32ThreeAddrFP<InstARM32::Vbsl>; | 1007 using InstARM32Vbsl = InstARM32ThreeAddrFP<InstARM32::Vbsl>; |
| 1008 using InstARM32Vceq = InstARM32ThreeAddrFP<InstARM32::Vceq>; |
| 1009 using InstARM32Vcge = InstARM32ThreeAddrSignAwareFP<InstARM32::Vcge>; |
| 1010 using InstARM32Vcgt = InstARM32ThreeAddrSignAwareFP<InstARM32::Vcgt>; |
997 using InstARM32Vdiv = InstARM32ThreeAddrFP<InstARM32::Vdiv>; | 1011 using InstARM32Vdiv = InstARM32ThreeAddrFP<InstARM32::Vdiv>; |
998 using InstARM32Veor = InstARM32ThreeAddrFP<InstARM32::Veor>; | 1012 using InstARM32Veor = InstARM32ThreeAddrFP<InstARM32::Veor>; |
999 using InstARM32Vmla = InstARM32FourAddrFP<InstARM32::Vmla>; | 1013 using InstARM32Vmla = InstARM32FourAddrFP<InstARM32::Vmla>; |
1000 using InstARM32Vmls = InstARM32FourAddrFP<InstARM32::Vmls>; | 1014 using InstARM32Vmls = InstARM32FourAddrFP<InstARM32::Vmls>; |
1001 using InstARM32Vmul = InstARM32ThreeAddrFP<InstARM32::Vmul>; | 1015 using InstARM32Vmul = InstARM32ThreeAddrFP<InstARM32::Vmul>; |
| 1016 using InstARM32Vmvn = InstARM32UnaryopFP<InstARM32::Vmvn>; |
1002 using InstARM32Vneg = InstARM32UnaryopSignAwareFP<InstARM32::Vneg>; | 1017 using InstARM32Vneg = InstARM32UnaryopSignAwareFP<InstARM32::Vneg>; |
1003 using InstARM32Vorr = InstARM32ThreeAddrFP<InstARM32::Vorr>; | 1018 using InstARM32Vorr = InstARM32ThreeAddrFP<InstARM32::Vorr>; |
1004 using InstARM32Vshl = InstARM32ThreeAddrSignAwareFP<InstARM32::Vshl>; | 1019 using InstARM32Vshl = InstARM32ThreeAddrSignAwareFP<InstARM32::Vshl>; |
1005 using InstARM32Vshr = InstARM32ThreeAddrSignAwareFP<InstARM32::Vshr>; | 1020 using InstARM32Vshr = InstARM32ThreeAddrSignAwareFP<InstARM32::Vshr>; |
1006 using InstARM32Vsub = InstARM32ThreeAddrFP<InstARM32::Vsub>; | 1021 using InstARM32Vsub = InstARM32ThreeAddrFP<InstARM32::Vsub>; |
1007 using InstARM32Ldr = InstARM32LoadBase<InstARM32::Ldr>; | 1022 using InstARM32Ldr = InstARM32LoadBase<InstARM32::Ldr>; |
1008 using InstARM32Ldrex = InstARM32LoadBase<InstARM32::Ldrex>; | 1023 using InstARM32Ldrex = InstARM32LoadBase<InstARM32::Ldrex>; |
1009 /// MovT leaves the bottom bits alone so dest is also a source. This helps | 1024 /// MovT leaves the bottom bits alone so dest is also a source. This helps |
1010 /// indicate that a previous MovW setting dest is not dead code. | 1025 /// indicate that a previous MovW setting dest is not dead code. |
1011 using InstARM32Movt = InstARM32TwoAddrGPR<InstARM32::Movt>; | 1026 using InstARM32Movt = InstARM32TwoAddrGPR<InstARM32::Movt>; |
(...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1609 // violations and link errors. | 1624 // violations and link errors. |
1610 | 1625 |
1611 template <> void InstARM32Ldr::emit(const Cfg *Func) const; | 1626 template <> void InstARM32Ldr::emit(const Cfg *Func) const; |
1612 template <> void InstARM32Movw::emit(const Cfg *Func) const; | 1627 template <> void InstARM32Movw::emit(const Cfg *Func) const; |
1613 template <> void InstARM32Movt::emit(const Cfg *Func) const; | 1628 template <> void InstARM32Movt::emit(const Cfg *Func) const; |
1614 | 1629 |
1615 } // end of namespace ARM32 | 1630 } // end of namespace ARM32 |
1616 } // end of namespace Ice | 1631 } // end of namespace Ice |
1617 | 1632 |
1618 #endif // SUBZERO_SRC_ICEINSTARM32_H | 1633 #endif // SUBZERO_SRC_ICEINSTARM32_H |
OLD | NEW |