1 // [Blend2D] 2 // 2D Vector Graphics Powered by a JIT Compiler. 3 // 4 // [License] 5 // Zlib - See LICENSE.md file in the package. 6 7 #ifndef BLEND2D_PIPEGEN_PIPEPART_P_H 8 #define BLEND2D_PIPEGEN_PIPEPART_P_H 9 10 #include "../pipegen/pipegencore_p.h" 11 #include "../pipegen/piperegusage_p.h" 12 13 //! \cond INTERNAL 14 //! \addtogroup blend2d_internal_pipegen 15 //! \{ 16 17 namespace BLPipeGen { 18 19 // ============================================================================ 20 // [BLPipeGen::PipePart] 21 // ============================================================================ 22 23 //! A base interface of a pipeline part. 24 //! 25 //! This class has basically no functionality, it just defines members that all 26 //! parts inherit and can use. Also, since many parts use virtual functions to 27 //! make them extensible `Part` must contain at least one virtual function 28 //! too. 29 class PipePart { 30 public: 31 BL_OVERRIDE_NEW_DELETE(PipePart) 32 33 //! PipePart type. 34 enum Type { 35 kTypeComposite = 0, //!< Composite two `FetchPart` parts. 36 kTypeFetch = 1, //!< Fetch part. 37 kTypeFill = 2 //!< Fill part. 38 }; 39 40 //! PipePart flags. 41 enum Flags : uint32_t { 42 kFlagPrepareDone = 0x00000001u, //!< Prepare was already called(). 43 kFlagPreInitDone = 0x00000002u, //!< Part was already pre-initialized. 44 kFlagPostInitDone = 0x00000004u //!< Part was already post-initialized. 45 }; 46 47 //! Reference to `PipeCompiler`. 48 PipeCompiler* pc; 49 //! Reference to `asmjit::x86::Compiler`. 50 x86::Compiler* cc; 51 52 //! Part type. 53 uint8_t _partType; 54 //! Count of children parts, cannot be greater than the capacity of `_children`. 55 uint8_t _childrenCount; 56 57 //! Maximum SIMD width this part supports. 58 uint8_t _maxSimdWidthSupported; 59 //! Informs to conserve a particular group of registers. 60 uint8_t _hasLowRegs[kNumVirtGroups]; 61 62 //! Part flags, see `Part::Flags`. 63 uint32_t _flags; 64 65 //! Used to store children parts, can be introspected as well. 66 PipePart* _children[2]; 67 68 //! Number of persistent registers the part requires. 69 PipeRegUsage _persistentRegs; 70 //! Number of persistent registers the part can spill to decrease the pressure. 71 PipeRegUsage _spillableRegs; 72 //! Number of temporary registers the part uses. 73 PipeRegUsage _temporaryRegs; 74 75 //! A global initialization hook. 76 //! 77 //! This hook is acquired during initialization phase of the part. Please do 78 //! not confuse this with loop initializers that contain another hook that 79 //! is used during the loop only. Initialization hooks define an entry for 80 //! the part where an additional code can be injected at any time during 81 //! pipeline construction. 82 asmjit::BaseNode* _globalHook; 83 84 PipePart(PipeCompiler* pc, uint32_t partType) noexcept; 85 86 template<typename T> as()87 inline T* as() noexcept { return static_cast<T*>(this); } 88 template<typename T> as()89 inline const T* as() const noexcept { return static_cast<const T*>(this); } 90 91 //! Tests whether the part is initialized isPartInitialized()92 inline bool isPartInitialized() const noexcept { return _globalHook != nullptr; } 93 //! Returns the part type. partType()94 inline uint32_t partType() const noexcept { return _partType; } 95 96 //! Tests whether the part should restrict using GP registers. hasLowRegs(uint32_t rKind)97 inline uint8_t hasLowRegs(uint32_t rKind) const noexcept { return _hasLowRegs[rKind]; } 98 99 //! Tests whether the part should restrict using GP registers. hasLowGpRegs()100 inline uint8_t hasLowGpRegs() const noexcept { return hasLowRegs(x86::Reg::kGroupGp); } 101 //! Tests whether the part should restrict using MM registers. hasLowMmRegs()102 inline uint8_t hasLowMmRegs() const noexcept { return hasLowRegs(x86::Reg::kGroupMm); } 103 //! Tests whether the part should restrict using XMM/YMM registers. hasLowVecRegs()104 inline uint8_t hasLowVecRegs() const noexcept { return hasLowRegs(x86::Reg::kGroupVec); } 105 flags()106 inline uint32_t flags() const noexcept { return _flags; } 107 108 //! Returns the number children parts. childrenCount()109 inline uint32_t childrenCount() const noexcept { return _childrenCount; } 110 //! Returns children parts as an array. children()111 inline PipePart** children() const noexcept { return (PipePart**)_children; } 112 113 //! Prepares the part - it would call `prepare()` on all child parts. 114 virtual void preparePart() noexcept; 115 116 //! Calls `preparePart()` on all children and also prevents calling it 117 //! multiple times. 118 void prepareChildren() noexcept; 119 _initGlobalHook(asmjit::BaseNode * node)120 inline void _initGlobalHook(asmjit::BaseNode* node) noexcept { 121 // Can be initialized only once. 122 BL_ASSERT(_globalHook == nullptr); 123 _globalHook = node; 124 } 125 _finiGlobalHook()126 inline void _finiGlobalHook() noexcept { 127 // Initialized by `_initGlobalHook()`, cannot be null here. 128 BL_ASSERT(_globalHook != nullptr); 129 _globalHook = nullptr; 130 } 131 }; 132 133 } // {BLPipeGen} 134 135 //! \} 136 //! \endcond 137 138 #endif // BLEND2D_PIPEGEN_PIPEPART_P_H 139