LCOV - code coverage report
Current view: top level - asmjit - codewriter.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage (other modules) Lines: 0 54 0.0 %
Date: 2026-11-05 10:19:06 Functions: 0 3 0.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             : #include "api-build_p.h"
       8             : #include "codeholder.h"
       9             : #include "codewriter_p.h"
      10             : 
      11             : ASMJIT_BEGIN_NAMESPACE
      12             : 
      13           0 : bool CodeWriterUtils::encodeOffset32(uint32_t* dst, int64_t offset64, const OffsetFormat& format) noexcept {
      14             :   uint32_t bitCount = format.immBitCount();
      15             :   uint32_t bitShift = format.immBitShift();
      16             :   uint32_t discardLsb = format.immDiscardLsb();
      17             : 
      18             :   // Invalid offset (should not happen).
      19           0 :   if (!bitCount || bitCount > format.valueSize() * 8u)
      20             :     return false;
      21             : 
      22             :   uint32_t value;
      23             : 
      24             :   // First handle all unsigned offset types.
      25           0 :   if (format.type() == OffsetType::kUnsignedOffset) {
      26           0 :     if (discardLsb) {
      27             :       ASMJIT_ASSERT(discardLsb <= 32);
      28           0 :       if ((offset64 & Support::lsbMask<uint32_t>(discardLsb)) != 0)
      29             :         return false;
      30           0 :       offset64 = int64_t(uint64_t(offset64) >> discardLsb);
      31             :     }
      32             : 
      33           0 :     value = uint32_t(offset64 & Support::lsbMask<uint32_t>(bitCount));
      34           0 :     if (value != offset64)
      35             :       return false;
      36             :   }
      37             :   else {
      38             :     // The rest of OffsetType options are all signed.
      39           0 :     if (discardLsb) {
      40             :       ASMJIT_ASSERT(discardLsb <= 32);
      41           0 :       if ((offset64 & Support::lsbMask<uint32_t>(discardLsb)) != 0)
      42             :         return false;
      43           0 :       offset64 >>= discardLsb;
      44             :     }
      45             : 
      46             :     if (!Support::isInt32(offset64))
      47             :       return false;
      48             : 
      49           0 :     value = uint32_t(int32_t(offset64));
      50           0 :     if (!Support::isEncodableOffset32(int32_t(value), bitCount))
      51             :       return false;
      52             :   }
      53             : 
      54           0 :   switch (format.type()) {
      55             :     case OffsetType::kSignedOffset:
      56             :     case OffsetType::kUnsignedOffset: {
      57           0 :       *dst = (value & Support::lsbMask<uint32_t>(bitCount)) << bitShift;
      58           0 :       return true;
      59             :     }
      60             : 
      61             :     case OffsetType::kAArch64_ADR:
      62             :     case OffsetType::kAArch64_ADRP: {
      63             :       // Sanity checks.
      64           0 :       if (format.valueSize() != 4 || bitCount != 21 || bitShift != 5)
      65             :         return false;
      66             : 
      67             :       uint32_t immLo = value & 0x3u;
      68           0 :       uint32_t immHi = (value >> 2) & Support::lsbMask<uint32_t>(19);
      69             : 
      70           0 :       *dst = (immLo << 29) | (immHi << 5);
      71           0 :       return true;
      72             :     }
      73             : 
      74             :     default:
      75             :       return false;
      76             :   }
      77             : }
      78             : 
      79           0 : bool CodeWriterUtils::encodeOffset64(uint64_t* dst, int64_t offset64, const OffsetFormat& format) noexcept {
      80             :   uint32_t bitCount = format.immBitCount();
      81             :   uint32_t discardLsb = format.immDiscardLsb();
      82             : 
      83           0 :   if (!bitCount || bitCount > format.valueSize() * 8u)
      84             :     return false;
      85             : 
      86             :   uint64_t value;
      87             : 
      88             :   // First handle all unsigned offset types.
      89           0 :   if (format.type() == OffsetType::kUnsignedOffset) {
      90           0 :     if (discardLsb) {
      91             :       ASMJIT_ASSERT(discardLsb <= 32);
      92           0 :       if ((offset64 & Support::lsbMask<uint32_t>(discardLsb)) != 0)
      93             :         return false;
      94           0 :       offset64 = int64_t(uint64_t(offset64) >> discardLsb);
      95             :     }
      96             : 
      97           0 :     value = uint64_t(offset64) & Support::lsbMask<uint64_t>(bitCount);
      98           0 :     if (value != uint64_t(offset64))
      99             :       return false;
     100             :   }
     101             :   else {
     102             :     // The rest of OffsetType options are all signed.
     103           0 :     if (discardLsb) {
     104             :       ASMJIT_ASSERT(discardLsb <= 32);
     105           0 :       if ((offset64 & Support::lsbMask<uint32_t>(discardLsb)) != 0)
     106             :         return false;
     107           0 :       offset64 >>= discardLsb;
     108             :     }
     109             : 
     110           0 :     if (!Support::isEncodableOffset64(offset64, bitCount))
     111             :       return false;
     112             : 
     113             :     value = uint64_t(offset64);
     114             :   }
     115             : 
     116           0 :   switch (format.type()) {
     117             :     case OffsetType::kSignedOffset:
     118             :     case OffsetType::kUnsignedOffset: {
     119           0 :       *dst = (value & Support::lsbMask<uint64_t>(bitCount)) << format.immBitShift();
     120           0 :       return true;
     121             :     }
     122             : 
     123             :     default:
     124             :       return false;
     125             :   }
     126             : }
     127             : 
     128           0 : bool CodeWriterUtils::writeOffset(void* dst, int64_t offset64, const OffsetFormat& format) noexcept {
     129             :   // Offset the destination by ValueOffset so the `dst` points to the
     130             :   // patched word instead of the beginning of the patched region.
     131           0 :   dst = static_cast<char*>(dst) + format.valueOffset();
     132             : 
     133           0 :   switch (format.valueSize()) {
     134           0 :     case 1: {
     135             :       uint32_t mask;
     136           0 :       if (!encodeOffset32(&mask, offset64, format))
     137             :         return false;
     138             : 
     139           0 :       Support::writeU8(dst, uint8_t(Support::readU8(dst) | mask));
     140           0 :       return true;
     141             :     }
     142             : 
     143           0 :     case 2: {
     144             :       uint32_t mask;
     145           0 :       if (!encodeOffset32(&mask, offset64, format))
     146             :         return false;
     147             : 
     148           0 :       Support::writeU16uLE(dst, uint16_t(Support::readU16uLE(dst) | mask));
     149           0 :       return true;
     150             :     }
     151             : 
     152           0 :     case 4: {
     153             :       uint32_t mask;
     154           0 :       if (!encodeOffset32(&mask, offset64, format)) {
     155             :         return false;
     156             :       }
     157             : 
     158           0 :       Support::writeU32uLE(dst, Support::readU32uLE(dst) | mask);
     159           0 :       return true;
     160             :     }
     161             : 
     162           0 :     case 8: {
     163             :       uint64_t mask;
     164           0 :       if (!encodeOffset64(&mask, offset64, format))
     165             :         return false;
     166             : 
     167           0 :       Support::writeU64uLE(dst, Support::readU64uLE(dst) | mask);
     168           0 :       return true;
     169             :     }
     170             : 
     171             :     default:
     172             :       return false;
     173             :   }
     174             : }
     175             : 
     176             : ASMJIT_END_NAMESPACE
     177             : 
     178             : #endif // __PLUMED_HAS_ASMJIT

Generated by: LCOV version 1.16