| 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 |