LCOV - code coverage report
Current view: top level - asmjit - funcargscontext_p.h (source / functions) Hit Total Coverage
Test: plumed test coverage (other modules) Lines: 17 46 37.0 %
Date: 2026-11-05 10:19:06 Functions: 1 5 20.0 %

          Line data    Source code
       1             : #ifdef __PLUMED_HAS_ASMJIT
       2             : // This file is part of AsmJit project <https://asmjit.com>
       3             : //
       4             : // See asmjit.h or LICENSE.md for license and copyright information
       5             : // SPDX-License-Identifier: Zlib
       6             : 
       7             : #ifndef ASMJIT_CORE_FUNCARGSCONTEXT_P_H_INCLUDED
       8             : #define ASMJIT_CORE_FUNCARGSCONTEXT_P_H_INCLUDED
       9             : 
      10             : #include "archtraits.h"
      11             : #include "environment.h"
      12             : #include "func.h"
      13             : #include "operand.h"
      14             : #include "radefs_p.h"
      15             : #include "support.h"
      16             : 
      17             : ASMJIT_BEGIN_NAMESPACE
      18             : 
      19             : //! \cond INTERNAL
      20             : //! \addtogroup asmjit_core
      21             : //! \{
      22             : 
      23           0 : static inline OperandSignature getSuitableRegForMemToMemMove(Arch arch, TypeId dstTypeId, TypeId srcTypeId) noexcept {
      24             :   const ArchTraits& archTraits = ArchTraits::byArch(arch);
      25             : 
      26             :   uint32_t dstSize = TypeUtils::sizeOf(dstTypeId);
      27             :   uint32_t srcSize = TypeUtils::sizeOf(srcTypeId);
      28             :   uint32_t maxSize = Support::max<uint32_t>(dstSize, srcSize);
      29             :   uint32_t regSize = Environment::registerSizeFromArch(arch);
      30             : 
      31             :   OperandSignature signature{0};
      32           0 :   if (maxSize <= regSize || (TypeUtils::isInt(dstTypeId) && TypeUtils::isInt(srcTypeId)))
      33           0 :     signature = maxSize <= 4 ? archTraits.regTypeToSignature(RegType::kGp32)
      34             :                              : archTraits.regTypeToSignature(RegType::kGp64);
      35           0 :   else if (maxSize <= 8 && archTraits.hasRegType(RegType::kVec64))
      36             :     signature = archTraits.regTypeToSignature(RegType::kVec64);
      37           0 :   else if (maxSize <= 16 && archTraits.hasRegType(RegType::kVec128))
      38             :     signature = archTraits.regTypeToSignature(RegType::kVec128);
      39           0 :   else if (maxSize <= 32 && archTraits.hasRegType(RegType::kVec256))
      40             :     signature = archTraits.regTypeToSignature(RegType::kVec256);
      41           0 :   else if (maxSize <= 64 && archTraits.hasRegType(RegType::kVec512))
      42             :     signature = archTraits.regTypeToSignature(RegType::kVec512);
      43             : 
      44           0 :   return signature;
      45             : }
      46             : 
      47             : class FuncArgsContext {
      48             : public:
      49             :   enum VarId : uint32_t {
      50             :     kVarIdNone = 0xFF
      51             :   };
      52             : 
      53             :   //! Contains information about a single argument or SA register that may need shuffling.
      54             :   struct Var {
      55             :     FuncValue cur;
      56             :     FuncValue out;
      57             : 
      58             :     inline void init(const FuncValue& cur_, const FuncValue& out_) noexcept {
      59           0 :       cur = cur_;
      60           0 :       out = out_;
      61             :     }
      62             : 
      63             :     //! Reset the value to its unassigned state.
      64             :     inline void reset() noexcept {
      65             :       cur.reset();
      66             :       out.reset();
      67             :     }
      68             : 
      69             :     inline bool isDone() const noexcept { return cur.isDone(); }
      70           0 :     inline void markDone() noexcept { cur.addFlags(FuncValue::kFlagIsDone); }
      71             :   };
      72             : 
      73             :   struct WorkData {
      74             :     //! All allocable registers provided by the architecture.
      75             :     RegMask _archRegs;
      76             :     //! All registers that can be used by the shuffler.
      77             :     RegMask _workRegs;
      78             :     //! Registers used by the shuffler (all).
      79             :     RegMask _usedRegs;
      80             :     //! Assigned registers.
      81             :     RegMask _assignedRegs;
      82             :     //! Destination registers assigned to arguments or SA.
      83             :     RegMask _dstRegs;
      84             :     //! Destination registers that require shuffling.
      85             :     RegMask _dstShuf;
      86             :     //! Number of register swaps.
      87             :     uint8_t _numSwaps;
      88             :     //! Number of stack loads.
      89             :     uint8_t _numStackArgs;
      90             :     //! Reserved (only used as padding).
      91             :     uint8_t _reserved[6];
      92             :     //! Physical ID to variable ID mapping.
      93             :     uint8_t _physToVarId[32];
      94             : 
      95      219936 :     inline void reset() noexcept {
      96      219936 :       _archRegs = 0;
      97      219936 :       _workRegs = 0;
      98      219936 :       _usedRegs = 0;
      99      219936 :       _assignedRegs = 0;
     100      219936 :       _dstRegs = 0;
     101      219936 :       _dstShuf = 0;
     102      219936 :       _numSwaps = 0;
     103      219936 :       _numStackArgs = 0;
     104      219936 :       memset(_reserved, 0, sizeof(_reserved));
     105      219936 :       memset(_physToVarId, kVarIdNone, 32);
     106      219936 :     }
     107             : 
     108             :     inline bool isAssigned(uint32_t regId) const noexcept {
     109             :       ASMJIT_ASSERT(regId < 32);
     110       27492 :       return Support::bitTest(_assignedRegs, regId);
     111             :     }
     112             : 
     113           0 :     inline void assign(uint32_t varId, uint32_t regId) noexcept {
     114             :       ASMJIT_ASSERT(!isAssigned(regId));
     115             :       ASMJIT_ASSERT(_physToVarId[regId] == kVarIdNone);
     116             : 
     117           0 :       _physToVarId[regId] = uint8_t(varId);
     118           0 :       _assignedRegs ^= Support::bitMask(regId);
     119           0 :     }
     120             : 
     121           0 :     inline void reassign(uint32_t varId, uint32_t newId, uint32_t oldId) noexcept {
     122             :       ASMJIT_ASSERT( isAssigned(oldId));
     123             :       ASMJIT_ASSERT(!isAssigned(newId));
     124             :       ASMJIT_ASSERT(_physToVarId[oldId] == varId);
     125             :       ASMJIT_ASSERT(_physToVarId[newId] == kVarIdNone);
     126             : 
     127           0 :       _physToVarId[oldId] = uint8_t(kVarIdNone);
     128           0 :       _physToVarId[newId] = uint8_t(varId);
     129           0 :       _assignedRegs ^= Support::bitMask(newId) ^ Support::bitMask(oldId);
     130           0 :     }
     131             : 
     132             :     inline void swap(uint32_t aVarId, uint32_t aRegId, uint32_t bVarId, uint32_t bRegId) noexcept {
     133             :       ASMJIT_ASSERT(isAssigned(aRegId));
     134             :       ASMJIT_ASSERT(isAssigned(bRegId));
     135             :       ASMJIT_ASSERT(_physToVarId[aRegId] == aVarId);
     136             :       ASMJIT_ASSERT(_physToVarId[bRegId] == bVarId);
     137             : 
     138           0 :       _physToVarId[aRegId] = uint8_t(bVarId);
     139           0 :       _physToVarId[bRegId] = uint8_t(aVarId);
     140             :     }
     141             : 
     142           0 :     inline void unassign(uint32_t varId, uint32_t regId) noexcept {
     143             :       ASMJIT_ASSERT(isAssigned(regId));
     144             :       ASMJIT_ASSERT(_physToVarId[regId] == varId);
     145             : 
     146             :       DebugUtils::unused(varId);
     147           0 :       _physToVarId[regId] = uint8_t(kVarIdNone);
     148           0 :       _assignedRegs ^= Support::bitMask(regId);
     149           0 :     }
     150             : 
     151      219936 :     inline RegMask archRegs() const noexcept { return _archRegs; }
     152           0 :     inline RegMask workRegs() const noexcept { return _workRegs; }
     153      109968 :     inline RegMask usedRegs() const noexcept { return _usedRegs; }
     154      219936 :     inline RegMask assignedRegs() const noexcept { return _assignedRegs; }
     155      219936 :     inline RegMask dstRegs() const noexcept { return _dstRegs; }
     156           0 :     inline RegMask availableRegs() const noexcept { return _workRegs & ~_assignedRegs; }
     157             :   };
     158             : 
     159             :   //! Architecture traits.
     160             :   const ArchTraits* _archTraits = nullptr;
     161             :   //! Architecture constraints.
     162             :   const RAConstraints* _constraints = nullptr;
     163             :   //! Target architecture.
     164             :   Arch _arch = Arch::kUnknown;
     165             :   //! Has arguments passed via stack (SRC).
     166             :   bool _hasStackSrc = false;
     167             :   //! Has preserved frame-pointer (FP).
     168             :   bool _hasPreservedFP = false;
     169             :   //! Has arguments assigned to stack (DST).
     170             :   uint8_t _stackDstMask = 0;
     171             :   //! Register swap groups (bit-mask).
     172             :   uint8_t _regSwapsMask = 0;
     173             :   uint8_t _saVarId = kVarIdNone;
     174             :   uint32_t _varCount = 0;
     175             :   Support::Array<WorkData, Globals::kNumVirtGroups> _workData;
     176             :   Var _vars[Globals::kMaxFuncArgs * Globals::kMaxValuePack + 1];
     177             : 
     178             :   FuncArgsContext() noexcept;
     179             : 
     180           0 :   inline const ArchTraits& archTraits() const noexcept { return *_archTraits; }
     181             :   inline Arch arch() const noexcept { return _arch; }
     182             : 
     183             :   inline uint32_t varCount() const noexcept { return _varCount; }
     184             :   inline size_t indexOf(const Var* var) const noexcept { return (size_t)(var - _vars); }
     185             : 
     186             :   inline Var& var(size_t varId) noexcept { return _vars[varId]; }
     187             :   inline const Var& var(size_t varId) const noexcept { return _vars[varId]; }
     188             : 
     189             :   Error initWorkData(const FuncFrame& frame, const FuncArgsAssignment& args, const RAConstraints* constraints) noexcept;
     190             :   Error markScratchRegs(FuncFrame& frame) noexcept;
     191             :   Error markDstRegsDirty(FuncFrame& frame) noexcept;
     192             :   Error markStackArgsReg(FuncFrame& frame) noexcept;
     193             : };
     194             : 
     195             : //! \}
     196             : //! \endcond
     197             : 
     198             : ASMJIT_END_NAMESPACE
     199             : 
     200             : #endif // ASMJIT_CORE_FUNCARGSCONTEXT_P_H_INCLUDED
     201             : 
     202             : #endif // __PLUMED_HAS_ASMJIT

Generated by: LCOV version 1.16