LCOV - code coverage report
Current view: top level - asmjit - logging.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage (other modules) Lines: 0 147 0.0 %
Date: 2024-10-18 14:00:27 Functions: 0 25 0.0 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             : Copyright (c) 2008-2017, Petr Kobalicek
       3             : 
       4             : This software is provided 'as-is', without any express or implied
       5             : warranty. In no event will the authors be held liable for any damages
       6             : arising from the use of this software.
       7             : 
       8             : Permission is granted to anyone to use this software for any purpose,
       9             : including commercial applications, and to alter it and redistribute it
      10             : freely, subject to the following restrictions:
      11             : 
      12             : 1. The origin of this software must not be misrepresented; you must not
      13             :    claim that you wrote the original software. If you use this software
      14             :    in a product, an acknowledgment in the product documentation would be
      15             :    appreciated but is not required.
      16             : 2. Altered source versions must be plainly marked as such, and must not be
      17             :    misrepresented as being the original software.
      18             : 3. This notice may not be removed or altered from any source distribution.
      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
      20             : #ifdef __PLUMED_HAS_ASMJIT
      21             : #pragma GCC diagnostic push
      22             : #pragma GCC diagnostic ignored "-Wpedantic"
      23             : // [AsmJit]
      24             : // Complete x86/x64 JIT and Remote Assembler for C++.
      25             : //
      26             : // [License]
      27             : // Zlib - See LICENSE.md file in the package.
      28             : 
      29             : // [Export]
      30             : #define ASMJIT_EXPORTS
      31             : 
      32             : // [Guard]
      33             : #include "./asmjit_build.h"
      34             : #if !defined(ASMJIT_DISABLE_LOGGING)
      35             : 
      36             : // [Dependencies]
      37             : #include "./codeholder.h"
      38             : #include "./codeemitter.h"
      39             : #include "./logging.h"
      40             : #include "./utils.h"
      41             : 
      42             : #if !defined(ASMJIT_DISABLE_BUILDER)
      43             : # include "./codebuilder.h"
      44             : #endif // !ASMJIT_DISABLE_BUILDER
      45             : 
      46             : #if !defined(ASMJIT_DISABLE_COMPILER)
      47             : # include "./codecompiler.h"
      48             : #else
      49             : namespace PLMD {
      50             : namespace asmjit { class VirtReg; }
      51             : #endif // !ASMJIT_DISABLE_COMPILER
      52             : 
      53             : #if defined(ASMJIT_BUILD_X86)
      54             : # include "./x86logging_p.h"
      55             : #endif // ASMJIT_BUILD_X86
      56             : 
      57             : #if defined(ASMJIT_BUILD_ARM)
      58             : # include "./armlogging_p.h"
      59             : #endif // ASMJIT_BUILD_ARM
      60             : 
      61             : // [Api-Begin]
      62             : #include "./asmjit_apibegin.h"
      63             : 
      64             : namespace PLMD {
      65             : namespace asmjit {
      66             : 
      67             : // ============================================================================
      68             : // [asmjit::Logger - Construction / Destruction]
      69             : // ============================================================================
      70             : 
      71           0 : Logger::Logger() noexcept {
      72           0 :   _options = 0;
      73           0 :   ::memset(_indentation, 0, ASMJIT_ARRAY_SIZE(_indentation));
      74           0 : }
      75           0 : Logger::~Logger() noexcept {}
      76             : 
      77             : // ============================================================================
      78             : // [asmjit::Logger - Logging]
      79             : // ============================================================================
      80             : 
      81           0 : Error Logger::logf(const char* fmt, ...) noexcept {
      82             :   Error err;
      83             : 
      84             :   va_list ap;
      85           0 :   va_start(ap, fmt);
      86           0 :   err = logv(fmt, ap);
      87           0 :   va_end(ap);
      88             : 
      89           0 :   return err;
      90             : }
      91             : 
      92           0 : Error Logger::logv(const char* fmt, va_list ap) noexcept {
      93             :   char buf[1024];
      94           0 :   size_t len = vsnprintf(buf, sizeof(buf), fmt, ap);
      95             : 
      96             :   if (len >= sizeof(buf))
      97             :     len = sizeof(buf) - 1;
      98           0 :   return log(buf, len);
      99             : }
     100             : 
     101           0 : Error Logger::logBinary(const void* data, size_t size) noexcept {
     102             :   static const char prefix[] = ".data ";
     103             :   static const char hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
     104             : 
     105             :   const uint8_t* s = static_cast<const uint8_t*>(data);
     106           0 :   size_t i = size;
     107             : 
     108             :   char buffer[128];
     109             :   ::memcpy(buffer, prefix, ASMJIT_ARRAY_SIZE(prefix) - 1);
     110             : 
     111           0 :   while (i) {
     112           0 :     uint32_t n = static_cast<uint32_t>(std::min<size_t>(i, 16));
     113             :     char* p = buffer + ASMJIT_ARRAY_SIZE(prefix) - 1;
     114             : 
     115           0 :     i -= n;
     116             :     do {
     117           0 :       uint32_t c = s[0];
     118             : 
     119           0 :       p[0] = hex[c >> 4];
     120           0 :       p[1] = hex[c & 15];
     121             : 
     122           0 :       p += 2;
     123           0 :       s += 1;
     124           0 :     } while (--n);
     125             : 
     126           0 :     *p++ = '\n';
     127           0 :     ASMJIT_PROPAGATE(log(buffer, (size_t)(p - buffer)));
     128             :   }
     129             : 
     130             :   return kErrorOk;
     131             : }
     132             : 
     133             : // ============================================================================
     134             : // [asmjit::Logger - Indentation]
     135             : // ============================================================================
     136             : 
     137           0 : void Logger::setIndentation(const char* indentation) noexcept {
     138           0 :   ::memset(_indentation, 0, ASMJIT_ARRAY_SIZE(_indentation));
     139           0 :   if (!indentation)
     140             :     return;
     141             : 
     142             :   size_t length = Utils::strLen(indentation, ASMJIT_ARRAY_SIZE(_indentation) - 1);
     143             :   ::memcpy(_indentation, indentation, length);
     144             : }
     145             : 
     146             : // ============================================================================
     147             : // [asmjit::FileLogger - Construction / Destruction]
     148             : // ============================================================================
     149             : 
     150           0 : FileLogger::FileLogger(FILE* stream) noexcept : _stream(nullptr) { setStream(stream); }
     151           0 : FileLogger::~FileLogger() noexcept {}
     152             : 
     153             : // ============================================================================
     154             : // [asmjit::FileLogger - Logging]
     155             : // ============================================================================
     156             : 
     157           0 : Error FileLogger::_log(const char* buf, size_t len) noexcept {
     158           0 :   if (!_stream)
     159             :     return kErrorOk;
     160             : 
     161           0 :   if (len == Globals::kInvalidIndex)
     162           0 :     len = strlen(buf);
     163             : 
     164           0 :   fwrite(buf, 1, len, _stream);
     165           0 :   return kErrorOk;
     166             : }
     167             : 
     168             : // ============================================================================
     169             : // [asmjit::StringLogger - Construction / Destruction]
     170             : // ============================================================================
     171             : 
     172           0 : StringLogger::StringLogger() noexcept {}
     173           0 : StringLogger::~StringLogger() noexcept {}
     174             : 
     175             : // ============================================================================
     176             : // [asmjit::StringLogger - Logging]
     177             : // ============================================================================
     178             : 
     179           0 : Error StringLogger::_log(const char* buf, size_t len) noexcept {
     180           0 :   return _stringBuilder.appendString(buf, len);
     181             : }
     182             : 
     183             : // ============================================================================
     184             : // [asmjit::Logging]
     185             : // ============================================================================
     186             : 
     187           0 : Error Logging::formatLabel(
     188             :   StringBuilder& sb,
     189             :   uint32_t logOptions,
     190             :   const CodeEmitter* emitter,
     191             :   uint32_t labelId) noexcept {
     192             : 
     193             :   const LabelEntry* le = emitter->getCode()->getLabelEntry(labelId);
     194           0 :   if (ASMJIT_UNLIKELY(!le))
     195           0 :     return sb.appendFormat("InvalidLabel[Id=%u]", static_cast<unsigned int>(labelId));
     196             : 
     197           0 :   if (le->hasName()) {
     198           0 :     if (le->hasParent()) {
     199             :       uint32_t parentId = le->getParentId();
     200             :       const LabelEntry* pe = emitter->getCode()->getLabelEntry(parentId);
     201             : 
     202           0 :       if (ASMJIT_UNLIKELY(!pe))
     203           0 :         ASMJIT_PROPAGATE(sb.appendFormat("InvalidLabel[Id=%u]", static_cast<unsigned int>(labelId)));
     204           0 :       else if (ASMJIT_UNLIKELY(!pe->hasName()))
     205           0 :         ASMJIT_PROPAGATE(sb.appendFormat("L%u", Operand::unpackId(parentId)));
     206             :       else
     207           0 :         ASMJIT_PROPAGATE(sb.appendString(pe->getName()));
     208             : 
     209           0 :       ASMJIT_PROPAGATE(sb.appendChar('.'));
     210             :     }
     211           0 :     return sb.appendString(le->getName());
     212             :   }
     213             :   else {
     214           0 :     return sb.appendFormat("L%u", Operand::unpackId(labelId));
     215             :   }
     216             : }
     217             : 
     218           0 : Error Logging::formatRegister(
     219             :   StringBuilder& sb,
     220             :   uint32_t logOptions,
     221             :   const CodeEmitter* emitter,
     222             :   uint32_t archType,
     223             :   uint32_t regType,
     224             :   uint32_t regId) noexcept {
     225             : 
     226             : #if defined(ASMJIT_BUILD_X86)
     227           0 :   return X86Logging::formatRegister(sb, logOptions, emitter, archType, regType, regId);
     228             : #endif // ASMJIT_BUILD_X86
     229             : 
     230             : #if defined(ASMJIT_BUILD_ARM)
     231             :   return ArmLogging::formatRegister(sb, logOptions, emitter, archType, regType, regId);
     232             : #endif // ASMJIT_BUILD_ARM
     233             : 
     234             :   return kErrorInvalidArch;
     235             : }
     236             : 
     237           0 : Error Logging::formatOperand(
     238             :   StringBuilder& sb,
     239             :   uint32_t logOptions,
     240             :   const CodeEmitter* emitter,
     241             :   uint32_t archType,
     242             :   const Operand_& op) noexcept {
     243             : 
     244             : #if defined(ASMJIT_BUILD_X86)
     245           0 :   return X86Logging::formatOperand(sb, logOptions, emitter, archType, op);
     246             : #endif // ASMJIT_BUILD_X86
     247             : 
     248             : #if defined(ASMJIT_BUILD_ARM)
     249             :   return ArmLogging::formatOperand(sb, logOptions, emitter, archType, op);
     250             : #endif // ASMJIT_BUILD_ARM
     251             : 
     252             :   return kErrorInvalidArch;
     253             : }
     254             : 
     255           0 : Error Logging::formatInstruction(
     256             :   StringBuilder& sb,
     257             :   uint32_t logOptions,
     258             :   const CodeEmitter* emitter,
     259             :   uint32_t archType,
     260             :   const Inst::Detail& detail, const Operand_* opArray, uint32_t opCount) noexcept {
     261             : 
     262             : #if defined(ASMJIT_BUILD_X86)
     263           0 :   return X86Logging::formatInstruction(sb, logOptions, emitter, archType, detail, opArray, opCount);
     264             : #endif // ASMJIT_BUILD_X86
     265             : 
     266             : #if defined(ASMJIT_BUILD_ARM)
     267             :   return ArmLogging::formatInstruction(sb, logOptions, emitter, archType, detail, opArray, opCount);
     268             : #endif // ASMJIT_BUILD_ARM
     269             : 
     270             :   return kErrorInvalidArch;
     271             : }
     272             : 
     273             : #if !defined(ASMJIT_DISABLE_BUILDER)
     274           0 : static Error formatTypeId(StringBuilder& sb, uint32_t typeId) noexcept {
     275           0 :   if (typeId == TypeId::kVoid)
     276           0 :     return sb.appendString("void");
     277             : 
     278           0 :   if (!TypeId::isValid(typeId))
     279           0 :     return sb.appendString("unknown");
     280             : 
     281             :   const char* typeName = "unknown";
     282             :   uint32_t typeSize = TypeId::sizeOf(typeId);
     283             : 
     284             :   uint32_t elementId = TypeId::elementOf(typeId);
     285           0 :   switch (elementId) {
     286           0 :     case TypeId::kIntPtr : typeName = "intptr" ; break;
     287           0 :     case TypeId::kUIntPtr: typeName = "uintptr"; break;
     288           0 :     case TypeId::kI8     : typeName = "i8"     ; break;
     289           0 :     case TypeId::kU8     : typeName = "u8"     ; break;
     290           0 :     case TypeId::kI16    : typeName = "i16"    ; break;
     291           0 :     case TypeId::kU16    : typeName = "u16"    ; break;
     292           0 :     case TypeId::kI32    : typeName = "i32"    ; break;
     293           0 :     case TypeId::kU32    : typeName = "u32"    ; break;
     294           0 :     case TypeId::kI64    : typeName = "i64"    ; break;
     295           0 :     case TypeId::kU64    : typeName = "u64"    ; break;
     296           0 :     case TypeId::kF32    : typeName = "f32"    ; break;
     297           0 :     case TypeId::kF64    : typeName = "f64"    ; break;
     298           0 :     case TypeId::kF80    : typeName = "f80"    ; break;
     299           0 :     case TypeId::kMask8  : typeName = "mask8"  ; break;
     300           0 :     case TypeId::kMask16 : typeName = "mask16" ; break;
     301           0 :     case TypeId::kMask32 : typeName = "mask32" ; break;
     302           0 :     case TypeId::kMask64 : typeName = "mask64" ; break;
     303           0 :     case TypeId::kMmx32  : typeName = "mmx32"  ; break;
     304           0 :     case TypeId::kMmx64  : typeName = "mmx64"  ; break;
     305             :   }
     306             : 
     307             :   uint32_t elementSize = TypeId::sizeOf(elementId);
     308           0 :   if (typeSize > elementSize) {
     309           0 :     unsigned int numElements = typeSize / elementSize;
     310           0 :     return sb.appendFormat("%sx%u", typeName, numElements);
     311             :   }
     312             :   else {
     313           0 :     return sb.appendString(typeName);
     314             :   }
     315             : }
     316             : 
     317           0 : static Error formatFuncDetailValue(
     318             :   StringBuilder& sb,
     319             :   uint32_t logOptions,
     320             :   const CodeEmitter* emitter,
     321             :   FuncDetail::Value value) noexcept {
     322             : 
     323             :   uint32_t typeId = value.getTypeId();
     324           0 :   ASMJIT_PROPAGATE(formatTypeId(sb, typeId));
     325             : 
     326           0 :   if (value.byReg()) {
     327           0 :     ASMJIT_PROPAGATE(sb.appendChar(':'));
     328           0 :     ASMJIT_PROPAGATE(Logging::formatRegister(sb, logOptions, emitter, emitter->getArchType(), value.getRegType(), value.getRegId()));
     329             :   }
     330             : 
     331           0 :   if (value.byStack()) {
     332           0 :     ASMJIT_PROPAGATE(sb.appendFormat(":[%d]", static_cast<int>(value.getStackOffset())));
     333             :   }
     334             : 
     335             :   return kErrorOk;
     336             : }
     337             : 
     338           0 : static Error formatFuncRets(
     339             :   StringBuilder& sb,
     340             :   uint32_t logOptions,
     341             :   const CodeEmitter* emitter,
     342             :   const FuncDetail& fd,
     343             :   VirtReg* const* vRegs) noexcept {
     344             : 
     345           0 :   if (!fd.hasRet())
     346           0 :     return sb.appendString("void");
     347             : 
     348           0 :   for (uint32_t i = 0; i < fd.getRetCount(); i++) {
     349           0 :     if (i) ASMJIT_PROPAGATE(sb.appendString(", "));
     350           0 :     ASMJIT_PROPAGATE(formatFuncDetailValue(sb, logOptions, emitter, fd.getRet(i)));
     351             : 
     352             : #if !defined(ASMJIT_DISABLE_COMPILER)
     353           0 :     if (vRegs)
     354           0 :       ASMJIT_PROPAGATE(sb.appendFormat(" {%s}", vRegs[i]->getName()));
     355             : #endif // !ASMJIT_DISABLE_COMPILER
     356             :   }
     357             : 
     358             :   return kErrorOk;
     359             : }
     360             : 
     361           0 : static Error formatFuncArgs(
     362             :   StringBuilder& sb,
     363             :   uint32_t logOptions,
     364             :   const CodeEmitter* emitter,
     365             :   const FuncDetail& fd,
     366             :   VirtReg* const* vRegs) noexcept {
     367             : 
     368           0 :   for (uint32_t i = 0; i < fd.getArgCount(); i++) {
     369           0 :     if (i) ASMJIT_PROPAGATE(sb.appendString(", "));
     370           0 :     ASMJIT_PROPAGATE(formatFuncDetailValue(sb, logOptions, emitter, fd.getArg(i)));
     371             : 
     372             : #if !defined(ASMJIT_DISABLE_COMPILER)
     373           0 :     if (vRegs)
     374           0 :       ASMJIT_PROPAGATE(sb.appendFormat(" {%s}", vRegs[i]->getName()));
     375             : #endif // !ASMJIT_DISABLE_COMPILER
     376             :   }
     377             : 
     378             :   return kErrorOk;
     379             : }
     380             : 
     381           0 : Error Logging::formatNode(
     382             :   StringBuilder& sb,
     383             :   uint32_t logOptions,
     384             :   const CodeBuilder* cb,
     385             :   const CBNode* node_) noexcept {
     386             : 
     387           0 :   if (node_->hasPosition())
     388           0 :     ASMJIT_PROPAGATE(sb.appendFormat("<%04u> ", node_->getPosition()));
     389             : 
     390           0 :   switch (node_->getType()) {
     391             :     case CBNode::kNodeInst: {
     392             :       const CBInst* node = node_->as<CBInst>();
     393           0 :       ASMJIT_PROPAGATE(
     394             :         Logging::formatInstruction(sb, logOptions, cb,
     395             :           cb->getArchType(),
     396             :           node->getInstDetail(), node->getOpArray(), node->getOpCount()));
     397             :       break;
     398             :     }
     399             : 
     400             :     case CBNode::kNodeLabel: {
     401             :       const CBLabel* node = node_->as<CBLabel>();
     402           0 :       ASMJIT_PROPAGATE(sb.appendFormat("L%u:", Operand::unpackId(node->getId())));
     403             :       break;
     404             :     }
     405             : 
     406             :     case CBNode::kNodeData: {
     407             :       const CBData* node = node_->as<CBData>();
     408           0 :       ASMJIT_PROPAGATE(sb.appendFormat(".embed (%u bytes)", node->getSize()));
     409             :       break;
     410             :     }
     411             : 
     412             :     case CBNode::kNodeAlign: {
     413             :       const CBAlign* node = node_->as<CBAlign>();
     414           0 :       ASMJIT_PROPAGATE(
     415             :         sb.appendFormat(".align %u (%s)",
     416             :           node->getAlignment(),
     417             :           node->getMode() == kAlignCode ? "code" : "data"));
     418             :       break;
     419             :     }
     420             : 
     421             :     case CBNode::kNodeComment: {
     422             :       const CBComment* node = node_->as<CBComment>();
     423           0 :       ASMJIT_PROPAGATE(sb.appendFormat("; %s", node->getInlineComment()));
     424             :       break;
     425             :     }
     426             : 
     427             :     case CBNode::kNodeSentinel: {
     428           0 :       ASMJIT_PROPAGATE(sb.appendString("[sentinel]"));
     429             :       break;
     430             :     }
     431             : 
     432             : #if !defined(ASMJIT_DISABLE_COMPILER)
     433             :     case CBNode::kNodeFunc: {
     434             :       const CCFunc* node = node_->as<CCFunc>();
     435           0 :       ASMJIT_PROPAGATE(formatLabel(sb, logOptions, cb, node->getId()));
     436             : 
     437           0 :       ASMJIT_PROPAGATE(sb.appendString(": ["));
     438           0 :       ASMJIT_PROPAGATE(formatFuncRets(sb, logOptions, cb, node->getDetail(), nullptr));
     439           0 :       ASMJIT_PROPAGATE(sb.appendString("]"));
     440             : 
     441           0 :       ASMJIT_PROPAGATE(sb.appendString("("));
     442           0 :       ASMJIT_PROPAGATE(formatFuncArgs(sb, logOptions, cb, node->getDetail(), node->getArgs()));
     443           0 :       ASMJIT_PROPAGATE(sb.appendString(")"));
     444             :       break;
     445             :     }
     446             : 
     447             :     case CBNode::kNodeFuncExit: {
     448           0 :       ASMJIT_PROPAGATE(sb.appendString("[ret]"));
     449             :       break;
     450             :     }
     451             : 
     452             :     case CBNode::kNodeFuncCall: {
     453             :       const CCFuncCall* node = node_->as<CCFuncCall>();
     454           0 :       ASMJIT_PROPAGATE(
     455             :         Logging::formatInstruction(sb, logOptions, cb,
     456             :           cb->getArchType(),
     457             :           node->getInstDetail(), node->getOpArray(), node->getOpCount()));
     458             :       break;
     459             :     }
     460             : #endif // !ASMJIT_DISABLE_COMPILER
     461             : 
     462             :     default: {
     463           0 :       ASMJIT_PROPAGATE(sb.appendFormat("[unknown (type=%u)]", node_->getType()));
     464             :       break;
     465             :     }
     466             :   }
     467             : 
     468             :   return kErrorOk;
     469             : }
     470             : #endif // !ASMJIT_DISABLE_BUILDER
     471             : 
     472           0 : Error Logging::formatLine(StringBuilder& sb, const uint8_t* binData, size_t binLen, size_t dispLen, size_t imLen, const char* comment) noexcept {
     473             :   size_t currentLen = sb.getLength();
     474           0 :   size_t commentLen = comment ? Utils::strLen(comment, kMaxCommentLength) : 0;
     475             : 
     476             :   ASMJIT_ASSERT(binLen >= dispLen);
     477             : 
     478           0 :   if ((binLen != 0 && binLen != Globals::kInvalidIndex) || commentLen) {
     479             :     size_t align = kMaxInstLength;
     480             :     char sep = ';';
     481             : 
     482           0 :     for (size_t i = (binLen == Globals::kInvalidIndex); i < 2; i++) {
     483             :       size_t begin = sb.getLength();
     484             : 
     485             :       // Append align.
     486           0 :       if (currentLen < align)
     487           0 :         ASMJIT_PROPAGATE(sb.appendChars(' ', align - currentLen));
     488             : 
     489             :       // Append separator.
     490             :       if (sep) {
     491           0 :         ASMJIT_PROPAGATE(sb.appendChar(sep));
     492           0 :         ASMJIT_PROPAGATE(sb.appendChar(' '));
     493             :       }
     494             : 
     495             :       // Append binary data or comment.
     496           0 :       if (i == 0) {
     497           0 :         ASMJIT_PROPAGATE(sb.appendHex(binData, binLen - dispLen - imLen));
     498           0 :         ASMJIT_PROPAGATE(sb.appendChars('.', dispLen * 2));
     499           0 :         ASMJIT_PROPAGATE(sb.appendHex(binData + binLen - imLen, imLen));
     500           0 :         if (commentLen == 0) break;
     501             :       }
     502             :       else {
     503           0 :         ASMJIT_PROPAGATE(sb.appendString(comment, commentLen));
     504             :       }
     505             : 
     506           0 :       currentLen += sb.getLength() - begin;
     507           0 :       align += kMaxBinaryLength;
     508             :       sep = '|';
     509             :     }
     510             :   }
     511             : 
     512           0 :   return sb.appendChar('\n');
     513             : }
     514             : 
     515             : } // asmjit namespace
     516             : } // namespace PLMD
     517             : 
     518             : // [Api-End]
     519             : #include "./asmjit_apiend.h"
     520             : 
     521             : // [Guard]
     522             : #endif // !ASMJIT_DISABLE_LOGGING
     523             : #pragma GCC diagnostic pop
     524             : #endif // __PLUMED_HAS_ASMJIT

Generated by: LCOV version 1.16