LCOV - code coverage report
Current view: top level - asmjit - a64instapi.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage (other modules) Lines: 0 86 0.0 %
Date: 2026-11-05 10:19:06 Functions: 0 5 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             : #if !defined(ASMJIT_NO_AARCH64)
       9             : 
      10             : #include "cpuinfo.h"
      11             : #include "misc_p.h"
      12             : #include "support.h"
      13             : #include "a64instapi_p.h"
      14             : #include "a64instdb_p.h"
      15             : #include "a64operand.h"
      16             : 
      17             : ASMJIT_BEGIN_SUB_NAMESPACE(a64)
      18             : 
      19             : // a64::InstInternal - Text
      20             : // ========================
      21             : 
      22             : #ifndef ASMJIT_NO_TEXT
      23           0 : Error InstInternal::instIdToString(Arch arch, InstId instId, String& output) noexcept {
      24           0 :   uint32_t realId = instId & uint32_t(InstIdParts::kRealId);
      25             :   DebugUtils::unused(arch);
      26             : 
      27           0 :   if (ASMJIT_UNLIKELY(!Inst::isDefinedId(realId)))
      28             :     return DebugUtils::errored(kErrorInvalidInstruction);
      29             : 
      30             :   const InstDB::InstInfo& info = InstDB::infoById(realId);
      31           0 :   return output.append(InstDB::_nameData + info._nameDataIndex);
      32             : }
      33             : 
      34           0 : InstId InstInternal::stringToInstId(Arch arch, const char* s, size_t len) noexcept {
      35             :   DebugUtils::unused(arch);
      36             : 
      37           0 :   if (ASMJIT_UNLIKELY(!s))
      38             :     return Inst::kIdNone;
      39             : 
      40           0 :   if (len == SIZE_MAX)
      41           0 :     len = strlen(s);
      42             : 
      43           0 :   if (ASMJIT_UNLIKELY(len == 0 || len > InstDB::kMaxNameSize))
      44             :     return Inst::kIdNone;
      45             : 
      46           0 :   uint32_t prefix = uint32_t(s[0]) - 'a';
      47           0 :   if (ASMJIT_UNLIKELY(prefix > 'z' - 'a'))
      48             :     return Inst::kIdNone;
      49             : 
      50           0 :   uint32_t index = InstDB::instNameIndex[prefix].start;
      51           0 :   if (ASMJIT_UNLIKELY(!index))
      52             :     return Inst::kIdNone;
      53             : 
      54             :   const char* nameData = InstDB::_nameData;
      55             :   const InstDB::InstInfo* table = InstDB::_instInfoTable;
      56             : 
      57           0 :   const InstDB::InstInfo* base = table + index;
      58           0 :   const InstDB::InstInfo* end  = table + InstDB::instNameIndex[prefix].end;
      59             : 
      60           0 :   for (size_t lim = (size_t)(end - base); lim != 0; lim >>= 1) {
      61           0 :     const InstDB::InstInfo* cur = base + (lim >> 1);
      62           0 :     int result = Support::cmpInstName(nameData + cur[0]._nameDataIndex, s, len);
      63             : 
      64           0 :     if (result < 0) {
      65           0 :       base = cur + 1;
      66           0 :       lim--;
      67           0 :       continue;
      68             :     }
      69             : 
      70           0 :     if (result > 0)
      71           0 :       continue;
      72             : 
      73           0 :     return uint32_t((size_t)(cur - table));
      74             :   }
      75             : 
      76             :   return Inst::kIdNone;
      77             : }
      78             : #endif // !ASMJIT_NO_TEXT
      79             : 
      80             : // a64::InstInternal - Validate
      81             : // ============================
      82             : 
      83             : #ifndef ASMJIT_NO_VALIDATION
      84           0 : ASMJIT_FAVOR_SIZE Error InstInternal::validate(Arch arch, const BaseInst& inst, const Operand_* operands, size_t opCount, ValidationFlags validationFlags) noexcept {
      85             :   // TODO:
      86             :   DebugUtils::unused(arch, inst, operands, opCount, validationFlags);
      87           0 :   return kErrorOk;
      88             : }
      89             : #endif // !ASMJIT_NO_VALIDATION
      90             : 
      91             : // a64::InstInternal - QueryRWInfo
      92             : // ===============================
      93             : 
      94             : #ifndef ASMJIT_NO_INTROSPECTION
      95             : struct InstRWInfoData {
      96             :   uint8_t rwx[Globals::kMaxOpCount];
      97             : };
      98             : 
      99             : static const InstRWInfoData instRWInfoData[] = {
     100             :   #define R uint8_t(OpRWFlags::kRead)
     101             :   #define W uint8_t(OpRWFlags::kWrite)
     102             :   #define X uint8_t(OpRWFlags::kRW)
     103             : 
     104             :   {{ R, R, R, R, R, R }}, // kRWI_R
     105             :   {{ R, W, R, R, R, R }}, // kRWI_RW
     106             :   {{ R, X, R, R, R, R }}, // kRWI_RX
     107             :   {{ R, R, W, R, R, R }}, // kRWI_RRW
     108             :   {{ R, W, X, R, R, R }}, // kRWI_RWX
     109             :   {{ W, R, R, R, R, R }}, // kRWI_W
     110             :   {{ W, R, W, R, R, R }}, // kRWI_WRW
     111             :   {{ W, R, X, R, R, R }}, // kRWI_WRX
     112             :   {{ W, R, R, W, R, R }}, // kRWI_WRRW
     113             :   {{ W, R, R, X, R, R }}, // kRWI_WRRX
     114             :   {{ W, W, R, R, R, R }}, // kRWI_WW
     115             :   {{ X, R, R, R, R, R }}, // kRWI_X
     116             :   {{ X, R, X, R, R, R }}, // kRWI_XRX
     117             :   {{ X, X, R, R, X, R }}, // kRWI_XXRRX
     118             : 
     119             :   {{ W, R, R, R, R, R }}, // kRWI_LDn
     120             :   {{ R, W, R, R, R, R }}, // kRWI_STn
     121             :   {{ R, R, R, R, R, R }}  // kRWI_TODO
     122             : 
     123             :   #undef R
     124             :   #undef W
     125             :   #undef X
     126             : };
     127             : 
     128             : static const uint8_t elementTypeSize[8] = { 0, 1, 2, 4, 8, 4, 4, 0 };
     129             : 
     130           0 : Error InstInternal::queryRWInfo(Arch arch, const BaseInst& inst, const Operand_* operands, size_t opCount, InstRWInfo* out) noexcept {
     131             :   // Unused in Release configuration as the assert is not compiled in.
     132             :   DebugUtils::unused(arch);
     133             : 
     134             :   // Only called when `arch` matches X86 family.
     135             :   ASMJIT_ASSERT(Environment::isFamilyARM(arch));
     136             : 
     137             :   // Get the instruction data.
     138           0 :   uint32_t realId = inst.id() & uint32_t(InstIdParts::kRealId);
     139             : 
     140           0 :   if (ASMJIT_UNLIKELY(!Inst::isDefinedId(realId)))
     141             :     return DebugUtils::errored(kErrorInvalidInstruction);
     142             : 
     143           0 :   out->_instFlags = InstRWFlags::kNone;
     144           0 :   out->_opCount = uint8_t(opCount);
     145           0 :   out->_rmFeature = 0;
     146           0 :   out->_extraReg.reset();
     147           0 :   out->_readFlags = CpuRWFlags::kNone; // TODO: [ARM] Read PSTATUS.
     148           0 :   out->_writeFlags = CpuRWFlags::kNone; // TODO: [ARM] Write PSTATUS
     149             : 
     150             :   const InstDB::InstInfo& instInfo = InstDB::_instInfoTable[realId];
     151             :   const InstRWInfoData& rwInfo = instRWInfoData[instInfo.rwInfoIndex()];
     152             : 
     153           0 :   if (instInfo.hasFlag(InstDB::kInstFlagConsecutive) && opCount > 2) {
     154           0 :     for (uint32_t i = 0; i < opCount; i++) {
     155           0 :       OpRWInfo& op = out->_operands[i];
     156           0 :       const Operand_& srcOp = operands[i];
     157             : 
     158           0 :       if (!srcOp.isRegOrMem()) {
     159           0 :         op.reset();
     160           0 :         continue;
     161             :       }
     162             : 
     163           0 :       OpRWFlags rwFlags = i < opCount - 1 ? (OpRWFlags)rwInfo.rwx[0] : (OpRWFlags)rwInfo.rwx[1];
     164             : 
     165           0 :       op._opFlags = rwFlags & ~(OpRWFlags::kZExt);
     166           0 :       op._physId = BaseReg::kIdBad;
     167           0 :       op._rmSize = 0;
     168             :       op._resetReserved();
     169             : 
     170           0 :       uint64_t rByteMask = op.isRead() ? 0xFFFFFFFFFFFFFFFFu : 0x0000000000000000u;
     171           0 :       uint64_t wByteMask = op.isWrite() ? 0xFFFFFFFFFFFFFFFFu : 0x0000000000000000u;
     172             : 
     173           0 :       op._readByteMask = rByteMask;
     174           0 :       op._writeByteMask = wByteMask;
     175           0 :       op._extendByteMask = 0;
     176           0 :       op._consecutiveLeadCount = 0;
     177             : 
     178           0 :       if (srcOp.isReg()) {
     179           0 :         if (i == 0)
     180           0 :           op._consecutiveLeadCount = uint8_t(opCount - 1);
     181             :         else
     182             :           op.addOpFlags(OpRWFlags::kConsecutive);
     183             :       }
     184             :       else {
     185             :         const Mem& memOp = srcOp.as<Mem>();
     186             : 
     187           0 :         if (memOp.hasBase()) {
     188             :           op.addOpFlags(OpRWFlags::kMemBaseRead);
     189             :         }
     190             : 
     191           0 :         if (memOp.hasIndex()) {
     192             :           op.addOpFlags(OpRWFlags::kMemIndexRead);
     193           0 :           op.addOpFlags(memOp.isPreOrPost() ? OpRWFlags::kMemIndexWrite : OpRWFlags::kNone);
     194             :         }
     195             :       }
     196             :     }
     197             :   }
     198             :   else {
     199           0 :     for (uint32_t i = 0; i < opCount; i++) {
     200           0 :       OpRWInfo& op = out->_operands[i];
     201           0 :       const Operand_& srcOp = operands[i];
     202             : 
     203           0 :       if (!srcOp.isRegOrMem()) {
     204           0 :         op.reset();
     205           0 :         continue;
     206             :       }
     207             : 
     208           0 :       OpRWFlags rwFlags = (OpRWFlags)rwInfo.rwx[i];
     209             : 
     210           0 :       op._opFlags = rwFlags & ~(OpRWFlags::kZExt);
     211           0 :       op._physId = BaseReg::kIdBad;
     212           0 :       op._rmSize = 0;
     213             :       op._resetReserved();
     214             : 
     215           0 :       uint64_t rByteMask = op.isRead() ? 0xFFFFFFFFFFFFFFFFu : 0x0000000000000000u;
     216           0 :       uint64_t wByteMask = op.isWrite() ? 0xFFFFFFFFFFFFFFFFu : 0x0000000000000000u;
     217             : 
     218           0 :       op._readByteMask = rByteMask;
     219           0 :       op._writeByteMask = wByteMask;
     220           0 :       op._extendByteMask = 0;
     221           0 :       op._consecutiveLeadCount = 0;
     222             : 
     223           0 :       if (srcOp.isReg()) {
     224           0 :         if (srcOp.as<Vec>().hasElementIndex()) {
     225             :           // Only part of the vector is accessed if element index [] is used.
     226             :           uint32_t elementType = srcOp.as<Vec>().elementType();
     227             :           uint32_t elementIndex = srcOp.as<Vec>().elementIndex();
     228             : 
     229           0 :           uint32_t elementSize = elementTypeSize[elementType];
     230           0 :           uint64_t accessMask = uint64_t(Support::lsbMask<uint32_t>(elementSize)) << (elementIndex * elementSize);
     231             : 
     232           0 :           op._readByteMask &= accessMask;
     233           0 :           op._writeByteMask &= accessMask;
     234             :         }
     235             : 
     236             :         // TODO: [ARM] RW info is not finished.
     237             :       }
     238             :       else {
     239             :         const Mem& memOp = srcOp.as<Mem>();
     240             : 
     241           0 :         if (memOp.hasBase()) {
     242             :           op.addOpFlags(OpRWFlags::kMemBaseRead);
     243             :         }
     244             : 
     245           0 :         if (memOp.hasIndex()) {
     246             :           op.addOpFlags(OpRWFlags::kMemIndexRead);
     247           0 :           op.addOpFlags(memOp.isPreOrPost() ? OpRWFlags::kMemIndexWrite : OpRWFlags::kNone);
     248             :         }
     249             :       }
     250             :     }
     251             :   }
     252             : 
     253             :   return kErrorOk;
     254             : }
     255             : #endif // !ASMJIT_NO_INTROSPECTION
     256             : 
     257             : // a64::InstInternal - QueryFeatures
     258             : // =================================
     259             : 
     260             : #ifndef ASMJIT_NO_INTROSPECTION
     261           0 : Error InstInternal::queryFeatures(Arch arch, const BaseInst& inst, const Operand_* operands, size_t opCount, CpuFeatures* out) noexcept {
     262             :   // TODO: [ARM] QueryFeatures not implemented yet.
     263             :   DebugUtils::unused(arch, inst, operands, opCount, out);
     264           0 :   return kErrorOk;
     265             : }
     266             : #endif // !ASMJIT_NO_INTROSPECTION
     267             : 
     268             : // a64::InstInternal - Unit
     269             : // ========================
     270             : 
     271             : #if defined(ASMJIT_TEST)
     272             : UNIT(arm_inst_api_text) {
     273             :   // TODO:
     274             : }
     275             : #endif
     276             : 
     277             : ASMJIT_END_SUB_NAMESPACE
     278             : 
     279             : #endif // !ASMJIT_NO_AARCH64
     280             : 
     281             : #endif // __PLUMED_HAS_ASMJIT

Generated by: LCOV version 1.16