diff options
Diffstat (limited to 'src')
46 files changed, 18 insertions, 6644 deletions
diff --git a/src/CompilerKit/AE.h b/src/CompilerKit/AE.h deleted file mode 100644 index cf6e71b..0000000 --- a/src/CompilerKit/AE.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * ======================================================== - * - * CompilerKit - * Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license. - * - * ======================================================== - */ - -#ifndef _NECTI_AE_H_ -#define _NECTI_AE_H_ - -#include <CompilerKit/Detail/Config.h> -#include <fstream> - -#define kAEIdentVersion (0x0122) - -#define kAEMag0 'A' -#define kAEMag1 'E' -#define kAEMag2 'F' - -#define kAESymbolLen (256) -#define kAEPad (8) -#define kAEMagLen (3) -#define kAENullType (0x00) - -/// @author Amlal El Mahrouss - -/// @brief -// Advanced Executable File Format for ld64. -// Reloctable by offset is the default strategy. -// You can also relocate at runtime but that's up to the operating system loader. - -namespace CompilerKit { -// @brief Advanced Executable Header -// One thing to keep in mind. -// This object format, is reloctable. -typedef struct AEHeader final { - Char fMagic[kAEMagLen] = {}; - UInt16 fVersion{kAEIdentVersion}; - Char fArch{}; - Char fSubArch{}; - SizeType fCount{}; - Char fSize{}; - SizeType fStartCode{}; - SizeType fCodeSize{}; - Char fPad[kAEPad] = {}; -} PACKED AEHeader, *AEHeaderPtr; - -// @brief Advanced Executable Record. -// Could be data, code or bss. -// fKind must be filled with PEF fields. - -typedef struct AERecordHeader final { - Char fName[kAESymbolLen]; - SizeType fKind; - SizeType fSize; - SizeType fFlags; - UIntPtr fOffset; - Char fPad[kAEPad]; -} PACKED AERecordHeader, *AERecordHeaderPtr; - -enum { - kKindRelocationByOffset = 0x23f, - kKindRelocationAtRuntime = 0x34f, -}; -} // namespace CompilerKit - -// provide operator<< for AE - -inline std::ofstream& operator<<(std::ofstream& fp, CompilerKit::AEHeader& container) { - fp.write((char*) &container, sizeof(CompilerKit::AEHeader)); - - return fp; -} - -inline std::ofstream& operator<<(std::ofstream& fp, CompilerKit::AERecordHeader& container) { - fp.write((char*) &container, sizeof(CompilerKit::AERecordHeader)); - - return fp; -} - -inline std::ifstream& operator>>(std::ifstream& fp, CompilerKit::AEHeader& container) { - fp.read((char*) &container, sizeof(CompilerKit::AEHeader)); - return fp; -} - -inline std::ifstream& operator>>(std::ifstream& fp, CompilerKit::AERecordHeader& container) { - fp.read((char*) &container, sizeof(CompilerKit::AERecordHeader)); - return fp; -} - -namespace CompilerKit::Utils { -/** - * @brief AE Reader protocol - * - */ -class AEReadableProtocol final { - public: - std::ifstream file_pointer_; - - public: - explicit AEReadableProtocol() = default; - ~AEReadableProtocol() = default; - - NECTI_COPY_DELETE(AEReadableProtocol); - - /** - * @brief Read AE Record headers. - * - * @param raw the containing buffer - * @param sz it's size (1 = one AERecordHeader, 2 two AERecordHeader(s)) - * @return AERecordHeaderPtr - */ - AERecordHeaderPtr Read(char* raw, std::size_t sz) { - if (!raw) return nullptr; - - return this->Read_<AERecordHeader>(raw, sz * sizeof(AERecordHeader)); - } - - private: - /** - * @brief Implementation of Read for raw classes. - * - * @tparam TypeClass The class to read. - * @param raw the buffer - * @param sz the size - * @return TypeClass* the returning class. - */ - template <typename TypeClass> - TypeClass* Read_(char* raw, std::size_t sz) { - file_pointer_.read(raw, std::streamsize(sz)); - return reinterpret_cast<TypeClass*>(raw); - } -}; -} // namespace CompilerKit::Utils - -#endif /* ifndef _NECTI_AE_H_ */
\ No newline at end of file diff --git a/src/CompilerKit/AST.h b/src/CompilerKit/AST.h deleted file mode 100644 index 3987f13..0000000 --- a/src/CompilerKit/AST.h +++ /dev/null @@ -1,143 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license - -======================================== */ - -#pragma once - -#include <CompilerKit/CodeGenerator.h> -#include <vector> - -#define CK_COMPILER_FRONTEND : public ::CompilerKit::CompilerFrontendInterface - -namespace CompilerKit { -inline static auto kInvalidFrontend = "(null)"; - -struct SyntaxLeafList; -struct SyntaxLeafList; -struct CompilerKeyword; - -/// =========================================================== /// -/// @note we want to do that to separate keywords. -/// =========================================================== /// - -enum KeywordKind { - kKeywordKindReserved = 0, - kKeywordKindNamespace = 100, - kKeywordKindFunctionStart, - kKeywordKindFunctionEnd, - kKeywordKindVariable, - kKeywordKindVariablePtr, - kKeywordKindType, - kKeywordKindTypePtr, - kKeywordKindExpressionBegin, - kKeywordKindExpressionEnd, - kKeywordKindArgSeparator, - kKeywordKindBodyStart, - kKeywordKindBodyEnd, - kKeywordKindClass, - kKeywordKindPtrAccess, - kKeywordKindAccess, - kKeywordKindIf, - kKeywordKindElse, - kKeywordKindElseIf, - kKeywordKindVariableAssign, - kKeywordKindVariableDec, - kKeywordKindVariableInc, - kKeywordKindConstant, - kKeywordKindTypedef, - kKeywordKindEndInstr, - kKeywordKindSpecifier, - kKeywordKindInvalid, - kKeywordKindReturn, - kKeywordKindCommentInline, - kKeywordKindCommentMultiLineStart, - kKeywordKindCommentMultiLineEnd, - kKeywordKindEq, - kKeywordKindNotEq, - kKeywordKindGreaterEq, - kKeywordKindLessEq, - kKeywordKindPtr, - kKeywordKindCount = kKeywordKindPtr - kKeywordKindNamespace + 1, -}; - -/// =========================================================== /// -/// \brief Compiler keyword information struct. -/// =========================================================== /// -struct CompilerKeyword { - CompilerKeyword(STLString name, KeywordKind kind) : keyword_name(name), keyword_kind(kind) {} - - STLString keyword_name{""}; - KeywordKind keyword_kind{kKeywordKindInvalid}; -}; - -struct SyntaxLeafList final { - struct SyntaxLeaf final { - Int32 fUserType{0U}; - CompilerKeyword fUserData{"", kKeywordKindInvalid}; - - STLString fUserValue{""}; - struct SyntaxLeaf* fNext{nullptr}; - }; - - std::vector<SyntaxLeaf> fLeafList; - SizeType fNumLeafs{0}; - - SizeType SizeOf() { return fNumLeafs; } - std::vector<SyntaxLeaf>& Get() { return fLeafList; } - SyntaxLeaf& At(SizeType index) { return fLeafList[index]; } -}; - -/// =========================================================== /// -/// find the perfect matching word in a haystack. -/// \param haystack base string -/// \param needle the string we search for. -/// \return if we found it or not. -/// =========================================================== /// -bool find_word(STLString haystack, STLString needle) noexcept; - -/// =========================================================== /// -/// find a word within strict conditions and returns a range of it. -/// \param haystack -/// \param needle -/// \return position of needle. -/// =========================================================== /// -SizeType find_word_range(STLString haystack, STLString needle) noexcept; - -/// =========================================================== /// -/// @brief Compiler backend, implements a frontend, such as C, C++... -/// See Toolchain, for some examples. -/// =========================================================== /// -class CompilerFrontendInterface { - public: - explicit CompilerFrontendInterface() = default; - virtual ~CompilerFrontendInterface() = default; - - NECTI_COPY_DEFAULT(CompilerFrontendInterface); - - /// =========================================================== /// - // NOTE: cast this to your user defined ast. - /// =========================================================== /// - typedef VoidPtr AstType; - - /// =========================================================== /// - //! @brief Compile a syntax tree ouf of the text. - //! Also takes the source file name for metadata. - /// =========================================================== /// - - virtual CompilerKit::SyntaxLeafList::SyntaxLeaf Compile(std::string text, std::string file) = 0; - - /// =========================================================== /// - //! @brief What language are we dealing with? - /// =========================================================== /// - virtual const char* Language(); - - /// =========================================================== /// - /// @brief Checks if language is a valid frontend. - /// =========================================================== /// - virtual bool IsValid(); -}; -} // namespace CompilerKit - -#include <CompilerKit/AST.inl>
\ No newline at end of file diff --git a/src/CompilerKit/AST.inl b/src/CompilerKit/AST.inl deleted file mode 100644 index 3dc9456..0000000 --- a/src/CompilerKit/AST.inl +++ /dev/null @@ -1,63 +0,0 @@ -/* ======================================== - - Copyright (C) 2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license - -======================================== */ - -namespace CompilerKit { -/// find the perfect matching word in a haystack. -/// \param haystack base string -/// \param needle the string we search for. -/// \return if we found it or not. -inline bool find_word(STLString haystack, STLString needle) noexcept { - auto index = haystack.find(needle); - - // check for needle validity. - if (index == STLString::npos) return false; - - // declare lambda - auto not_part_of_word = [&](int index) { - if (std::isspace(haystack[index]) || std::ispunct(haystack[index])) return true; - - if (index <= 0 || index >= haystack.size()) return true; - - return false; - }; - - return not_part_of_word(index - 1) && not_part_of_word(index + needle.size()); -} - -/// find a word within strict conditions and returns a range of it. -/// \param haystack -/// \param needle -/// \return position of needle. -inline SizeType find_word_range(STLString haystack, STLString needle) noexcept { - auto index = haystack.find(needle); - - // check for needle validity. - if (index == STLString::npos) return false; - - if (!isalnum((haystack[index + needle.size() + 1])) && - !isdigit(haystack[index + needle.size() + 1]) && - !isalnum((haystack[index - needle.size() - 1])) && - !isdigit(haystack[index - needle.size() - 1])) { - return index; - } - - return STLString::npos; -} - -/// =========================================================== /// -//! @brief What language are we dealing with? -/// =========================================================== /// -inline const char* CompilerFrontendInterface::Language() { - return kInvalidFrontend; -} - -/// =========================================================== /// -/// @brief Checks if language is a valid frontend. -/// =========================================================== /// -inline bool CompilerFrontendInterface::IsValid() { - return strcmp(this->Language(), kInvalidFrontend) > 0; -} -} // namespace CompilerKit
\ No newline at end of file diff --git a/src/CompilerKit/CodeGenerator.h b/src/CompilerKit/CodeGenerator.h deleted file mode 100644 index 383f170..0000000 --- a/src/CompilerKit/CodeGenerator.h +++ /dev/null @@ -1,228 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license - -======================================== */ - -#pragma once - -#include <CompilerKit/Detail/Config.h> -#include <CompilerKit/Macros.h> -#include <cstring> - -#define CK_ASSEMBLY_INTERFACE : public ::CompilerKit::AssemblyInterface -#define CK_ENCODER : public ::CompilerKit::EncoderInterface - -namespace CompilerKit { -class AssemblyFactory; -class AssemblyInterface; - -/// =========================================================== /// -/// @brief Simple assembly factory -/// =========================================================== /// -class AssemblyFactory final { - public: - explicit AssemblyFactory() = default; - ~AssemblyFactory() = default; - - NECTI_COPY_DEFAULT(AssemblyFactory); - - public: - enum { - kArchInvalid = 0, - kArchAMD64 = 100, - kArch32x0, - kArch64x0, - kArchRISCV, - kArchPowerPC, - kArchAARCH64, - kArchUnknown, - kArchCount = kArchUnknown - kArchAMD64, - }; - - Int32 Compile(std::string sourceFile, const Int32& arch) noexcept; - - void Mount(AssemblyInterface* mountPtr) noexcept; - AssemblyInterface* Unmount() noexcept; - - private: - AssemblyInterface* fMounted{nullptr}; -}; - -/// =========================================================== /// -/// @brief Assembly to binary generator class. -/// @note This interface creates according to the CPU target of the child class. -/// =========================================================== /// -class AssemblyInterface { - public: - explicit AssemblyInterface() = default; - virtual ~AssemblyInterface() = default; - - NECTI_COPY_DEFAULT(AssemblyInterface); - - virtual UInt32 Arch() noexcept { return AssemblyFactory::kArchAMD64; } - - /// =========================================================== /// - /// @brief compile to object file. - /// @note Example C++ -> MASM -> AE object. - /// =========================================================== /// - virtual Int32 CompileToFormat(std::string src, Int32 arch) = 0; -}; - -/// =========================================================== /// -/// @brief Number casting unions for different sizes. -/// =========================================================== /// -union NumberCastBase { - NumberCastBase() = default; - ~NumberCastBase() = default; -}; - -union NumberCast64 final { - NumberCast64() = default; - explicit NumberCast64(UInt64 raw) : raw(raw) {} - - ~NumberCast64() { raw = 0; } - - static constexpr auto kLimit = 8; - - Char number[kLimit]; - UInt64 raw; -}; - -union NumberCast32 final { - NumberCast32() = default; - explicit NumberCast32(UInt32 raw) : raw(raw) {} - - ~NumberCast32() { raw = 0; } - - static constexpr auto kLimit = 4; - - Char number[kLimit]; - UInt32 raw; -}; - -union NumberCast16 final { - NumberCast16() = default; - explicit NumberCast16(UInt16 raw) : raw(raw) {} - - ~NumberCast16() { raw = 0; } - - static constexpr auto kLimit = 2; - - Char number[kLimit]; - UInt16 raw; -}; - -union NumberCast8 final { - NumberCast8() = default; - explicit NumberCast8(UInt8 raw) : raw(raw) {} - - ~NumberCast8() { raw = 0; } - - Char number; - UInt8 raw; -}; - -/// =========================================================== /// -/// @brief Assembly encoder interface. -/// =========================================================== /// -class EncoderInterface { - public: - explicit EncoderInterface() = default; - virtual ~EncoderInterface() = default; - - NECTI_COPY_DEFAULT(EncoderInterface); - - virtual std::string CheckLine(std::string line, std::string file) = 0; - virtual bool WriteLine(std::string line, std::string file) = 0; - virtual bool WriteNumber(const std::size_t& pos, std::string& from_what) = 0; -}; - -/// =========================================================== /// -/// @brief Different architecture encoders. -/// =========================================================== /// - -#ifdef __ASM_NEED_AMD64__ - -class EncoderAMD64 final : public EncoderInterface { - public: - explicit EncoderAMD64() = default; - ~EncoderAMD64() override = default; - - NECTI_COPY_DEFAULT(EncoderAMD64); - - virtual std::string CheckLine(std::string line, std::string file) override; - virtual bool WriteLine(std::string line, std::string file) override; - virtual bool WriteNumber(const std::size_t& pos, std::string& from_what) override; - - virtual bool WriteNumber16(const std::size_t& pos, std::string& from_what); - virtual bool WriteNumber32(const std::size_t& pos, std::string& from_what); - virtual bool WriteNumber8(const std::size_t& pos, std::string& from_what); -}; - -#endif // __ASM_NEED_AMD64__ - -#ifdef __ASM_NEED_ARM64__ - -class EncoderARM64 final : public EncoderInterface { - public: - explicit EncoderARM64() = default; - ~EncoderARM64() override = default; - - NECTI_COPY_DEFAULT(EncoderARM64); - - virtual std::string CheckLine(std::string line, std::string file) override; - virtual bool WriteLine(std::string line, std::string file) override; - virtual bool WriteNumber(const std::size_t& pos, std::string& from_what) override; -}; - -#endif // __ASM_NEED_ARM64__ - -#ifdef __ASM_NEED_64x0__ - -class Encoder64x0 final : public EncoderInterface { - public: - explicit Encoder64x0() = default; - ~Encoder64x0() override = default; - - NECTI_COPY_DEFAULT(Encoder64x0); - - virtual std::string CheckLine(std::string line, std::string file) override; - virtual bool WriteLine(std::string line, std::string file) override; - virtual bool WriteNumber(const std::size_t& pos, std::string& from_what) override; -}; - -#endif // __ASM_NEED_64x0__ - -#ifdef __ASM_NEED_32x0__ - -class Encoder32x0 final : public EncoderInterface { - public: - explicit Encoder32x0() = default; - ~Encoder32x0() override = default; - - NECTI_COPY_DEFAULT(Encoder32x0); - - virtual std::string CheckLine(std::string line, std::string file) override; - virtual bool WriteLine(std::string line, std::string file) override; - virtual bool WriteNumber(const std::size_t& pos, std::string& from_what) override; -}; - -#endif // __ASM_NEED_32x0__ - -#ifdef __ASM_NEED_PPC__ - -class EncoderPowerPC final : public EncoderInterface { - public: - explicit EncoderPowerPC() = default; - ~EncoderPowerPC() override = default; - - NECTI_COPY_DEFAULT(EncoderPowerPC); - - virtual std::string CheckLine(std::string line, std::string file) override; - virtual bool WriteLine(std::string line, std::string file) override; - virtual bool WriteNumber(const std::size_t& pos, std::string& from_what) override; -}; - -#endif // __ASM_NEED_32x0__ -} // namespace CompilerKit diff --git a/src/CompilerKit/Detail/32x0.h b/src/CompilerKit/Detail/32x0.h deleted file mode 100644 index fc3e0e9..0000000 --- a/src/CompilerKit/Detail/32x0.h +++ /dev/null @@ -1,94 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license - -======================================== */ - -#pragma once - -#include <CompilerKit/Detail/Config.h> -#include <vector> - -// @brief Open32x0 support. -// @file Detail/32x0.h - -#define CK_ASM_OPCODE(__NAME, __OPCODE, __FUNCT3, __FUNCT7) \ - {.fName = __NAME, .fOpcode = __OPCODE, .fFunct3 = __FUNCT3, .fFunct7 = __FUNCT7}, - -#define kAsmImmediate 0x01 -#define kAsmSyscall 0x02 -#define kAsmJump 0x03 -#define kAsmNoArgs 0x04 - -#define kAsmByte 0 -#define kAsmHWord 1 -#define kAsmWord 2 - -struct CpuCode32x0 { - const char fName[32]; - uint8_t fOpcode; - uint8_t fSize; - uint8_t fFunct3; - uint8_t fFunct7; -}; - -#define kAsmDWordStr ".dword" /* 64 bit */ -#define kAsmWordStr ".word" /* 32-bit */ -#define kAsmHWordStr ".half" /* 16-bit */ -#define kAsmByteStr ".byte" /* 8-bit */ - -inline std::vector<CpuCode32x0> kOpcodes32x0 = { - CK_ASM_OPCODE("nop", 0b0100011, 0b000, kAsmNoArgs) // nothing to do. (1C) - CK_ASM_OPCODE("jmp", 0b1110011, 0b001, kAsmJump) // jump to branch (2C) - CK_ASM_OPCODE("mov", 0b0100011, 0b101, kAsmImmediate) // move registers (3C) - CK_ASM_OPCODE("psh", 0b0111011, 0b000, kAsmImmediate) // push to sp (2C) - CK_ASM_OPCODE("pop", 0b0111011, 0b001, kAsmImmediate) // pop from sp. (1C) - CK_ASM_OPCODE("lea", 0b0111011, 0b010, - kAsmImmediate) // setup stack and call, store address to CR (1C). - CK_ASM_OPCODE("ret", 0b0111011, 0b110, - kAsmImmediate) // return from procedure (2C). - CK_ASM_OPCODE("uc", 0b0111111, 0b000, kAsmSyscall) // user call (1C) - CK_ASM_OPCODE("kc", 0b0111111, 0b001, kAsmSyscall) // kernel call (1C) - CK_ASM_OPCODE("int", 0b0111111, 0b010, kAsmSyscall) // raise interrupt (1C) -}; - -// \brief 64x0 register prefix -// example: r32, r0 -// r32 -> sp -// r0 -> hw zero - -#define kAsmRegisterPrefix "r" -#define kAsmRegisterLimit 16 -#define kAsmPcRegister 17 -#define kAsmCrRegister 18 -#define kAsmSpRegister 5 - -/* return address register */ -#define kAsmRetRegister 19 - -///////////////////////////////////////////////////////////////////////////// - -// SYSTEM CALL ADDRESSING - -// | OPCODE | FUNCT3 | FUNCT7 | OFF | - -// IMMEDIATE ADDRESSING - -// | OPCODE | FUNCT3 | FUNCT7 | REG | OFF | -// | OPCODE | FUNCT3 | FUNCT7 | REG | OFF | REG | -// | OPCODE | FUNCT3 | FUNCT7 | REG | REG | OFF | - -// REG TO REG ADDRESSING - -// | OPCODE | FUNCT3 | FUNCT7 | REG | REG2 | - -//////////////////////////////// - -// LOAD/CALL INTERRUPTS - -// SET A HANDLER IN ADDRESS: TODO: find one -// DISABLE INTERRUPTS -// PROCESS INTERRUPT -// ENABLE INTERRUPTS - -//////////////////////////////// diff --git a/src/CompilerKit/Detail/64x0.h b/src/CompilerKit/Detail/64x0.h deleted file mode 100644 index ba539f6..0000000 --- a/src/CompilerKit/Detail/64x0.h +++ /dev/null @@ -1,100 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license - -======================================== */ - -#pragma once - -#include <CompilerKit/Detail/Config.h> -#include <vector> - -// @brief Open64x0 support. -// @file Detail/64x0.h - -#define CK_ASM_OPCODE(__NAME, __OPCODE, __FUNCT3, __FUNCT7) \ - {.fName = __NAME, .fOpcode = __OPCODE, .fFunct3 = __FUNCT3, .fFunct7 = __FUNCT7}, - -#define kAsmImmediate 0x01 -#define kAsmRegToReg 0x02 -#define kAsmSyscall 0x03 -#define kAsmJump 0x04 -#define kAsmNoArgs 0x00 - -typedef char e64k_character_t; -typedef uint8_t e64k_num_t; - -struct CpuOpcode64x0 { - const e64k_character_t fName[32]; - e64k_num_t fOpcode; - e64k_num_t fFunct3; - e64k_num_t fFunct7; -}; - -inline std::vector<CpuOpcode64x0> kOpcodes64x0 = { - CK_ASM_OPCODE("nop", 0b0000000, 0b0000000, kAsmNoArgs) // no-operation. - CK_ASM_OPCODE("np", 0b0000000, 0b0000000, kAsmNoArgs) // no-operation. - CK_ASM_OPCODE("jlr", 0b1110011, 0b0000111, - kAsmJump) // jump to linked return register - CK_ASM_OPCODE("jrl", 0b1110011, 0b0001111, - kAsmJump) // jump from return register. - CK_ASM_OPCODE("mv", 0b0100011, 0b101, kAsmRegToReg) CK_ASM_OPCODE( - "bg", 0b1100111, 0b111, kAsmRegToReg) CK_ASM_OPCODE("bl", 0b1100111, 0b011, kAsmRegToReg) - CK_ASM_OPCODE("beq", 0b1100111, 0b000, kAsmRegToReg) - CK_ASM_OPCODE("bne", 0b1100111, 0b001, kAsmRegToReg) - CK_ASM_OPCODE("bge", 0b1100111, 0b101, kAsmRegToReg) - CK_ASM_OPCODE("ble", 0b1100111, 0b100, kAsmRegToReg) - CK_ASM_OPCODE("stw", 0b0001111, 0b100, kAsmImmediate) - CK_ASM_OPCODE("ldw", 0b0001111, 0b100, kAsmImmediate) - CK_ASM_OPCODE("lda", 0b0001111, 0b101, kAsmImmediate) - CK_ASM_OPCODE("sta", 0b0001111, 0b001, kAsmImmediate) - // add/sub without carry flag - CK_ASM_OPCODE("add", 0b0101011, 0b100, kAsmImmediate) - CK_ASM_OPCODE("sub", 0b0101011, 0b101, kAsmImmediate) - // add/sub with carry flag - CK_ASM_OPCODE("addc", 0b0101011, 0b110, kAsmImmediate) CK_ASM_OPCODE( - "subc", 0b0101011, 0b111, kAsmImmediate) CK_ASM_OPCODE("sc", 0b1110011, 0b00, kAsmSyscall)}; - -// \brief 64x0 register prefix -// example: r32, r0 -// r32 -> sp -// r0 -> hw zero - -#define kAsmFloatZeroRegister 0 -#define kAsmZeroRegister 0 - -#define kAsmRegisterPrefix "r" -#define kAsmRegisterLimit 30 -#define kAsmPcRegister 17 -#define kAsmCrRegister 18 -#define kAsmSpRegister 5 - -/* return address register */ -#define kAsmRetRegister 19 - -///////////////////////////////////////////////////////////////////////////// - -// SYSTEM CALL/JUMP ADDRESSING - -// | OPCODE | FUNCT3 | FUNCT7 | OFF | - -// IMMEDIATE ADDRESSING - -// | OPCODE | FUNCT3 | FUNCT7 | REG | OFF | -// | OPCODE | FUNCT3 | FUNCT7 | REG | OFF | REG | -// | OPCODE | FUNCT3 | FUNCT7 | REG | REG | OFF | - -// REG TO REG ADDRESSING - -// | OPCODE | FUNCT3 | FUNCT7 | REG | REG2 | - -//////////////////////////////// - -// LOAD/CALL INTERRUPTS - -// SET A HANDLER IN ADDRESS: -// DISABLE INTERRUPTS -// PROCESS INTERRUPT -// ENABLE INTERRUPTS - -//////////////////////////////// diff --git a/src/CompilerKit/Detail/AMD64.h b/src/CompilerKit/Detail/AMD64.h deleted file mode 100644 index a123c02..0000000 --- a/src/CompilerKit/Detail/AMD64.h +++ /dev/null @@ -1,50 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license - -======================================== */ - -#pragma once - -#include <CompilerKit/Detail/Config.h> -#include <vector> - -// @brief AMD64 support. -// @file Detail/AMD64.h - -#define CK_ASM_OPCODE(__NAME, __OPCODE) {.fName = __NAME, .fOpcode = __OPCODE}, - -typedef char i64_character_t; -typedef uint8_t i64_byte_t; -typedef uint16_t i64_hword_t; -typedef uint32_t i64_word_t; - -#define kAsmRegisterPrefix "r" - -struct CpuOpcodeAMD64 { - std::string fName; - i64_byte_t fPrefixBytes[4]; - i64_hword_t fOpcode; - i64_hword_t fModReg; - i64_word_t fDisplacment; - i64_word_t fImmediate; -}; - -/// these two are edge cases -#define kAsmIntOpcode 0xCC -#define kasmIntOpcodeAlt 0xCD - -#define kAsmJumpOpcode 0x0F80 -#define kJumpLimit 30 -#define kJumpLimitStandard 0xE3 -#define kJumpLimitStandardLimit 0xEB - -inline std::vector<CpuOpcodeAMD64> kOpcodesAMD64 = { - CK_ASM_OPCODE("int", 0xCD) CK_ASM_OPCODE("into", 0xCE) CK_ASM_OPCODE("intd", 0xF1) - CK_ASM_OPCODE("int3", 0xC3) CK_ASM_OPCODE("iret", 0xCF) CK_ASM_OPCODE("retf", 0xCB) - CK_ASM_OPCODE("retn", 0xC3) CK_ASM_OPCODE("ret", 0xC3) CK_ASM_OPCODE("sti", 0xfb) - CK_ASM_OPCODE("cli", 0xfa) CK_ASM_OPCODE("hlt", 0xf4) CK_ASM_OPCODE("nop", 0x90) - CK_ASM_OPCODE("mov", 0x48) CK_ASM_OPCODE("call", 0xFF) - CK_ASM_OPCODE("syscall", 0x0F) CK_ASM_OPCODE("xor", 0x48)}; - -#define kAsmRegisterLimit 16 diff --git a/src/CompilerKit/Detail/Aarch64.h b/src/CompilerKit/Detail/Aarch64.h deleted file mode 100644 index 1ce1719..0000000 --- a/src/CompilerKit/Detail/Aarch64.h +++ /dev/null @@ -1,41 +0,0 @@ -/* ======================================== - -Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license - -======================================== */ - -#pragma once - -#include <CompilerKit/Detail/Config.h> -#include <stdint.h> - -/// @brief ARM64 encoding support. -/// @file Detail/Aarch64.h - -struct CpuOpcodeArm64; - -/// @brief ARM64 opcode header. -struct PACKED CpuOpcodeArm64_Data final { - uint32_t fOpcode : 10; // Bits 31–22: Opcode for operation - uint32_t fRm : 5; // Bits 21–16: Source register Rm - uint32_t fShamt : 6; // Bits 15–10: Shift amount - uint32_t fRn : 5; // Bits 9–5: Source register Rn - uint32_t fRd : 5; // Bits 4–0: Destination register Rd -}; - -typedef struct { - uint32_t opcode : 6; // Bits 31–26: Branch opcode - int32_t offset : 26; // Bits 25–0: Signed offset (branch target) -} PACKED CpuOpcodeArm64_Branch; - -typedef struct { - uint32_t size : 2; // Bits 31–30: Size of the data - uint32_t opcode : 7; // Bits 29–23: Opcode for load/store - uint32_t offset : 12; // Bits 22–10: Offset - uint32_t rn : 5; // Bits 9–5: Base address register Rn - uint32_t rt : 5; // Bits 4–0: Target/source register Rt -} PACKED CpuOpcodeArm64_LoadStore; - -#define kAsmRegisterLimit (30) -#define kAsmRegisterPrefix "x" -#define kOpcodeARM64Count (1000) diff --git a/src/CompilerKit/Detail/Config.h b/src/CompilerKit/Detail/Config.h deleted file mode 100644 index 6137e2a..0000000 --- a/src/CompilerKit/Detail/Config.h +++ /dev/null @@ -1,64 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license - -======================================== */ - -#pragma once - -/// =========================================================== /// -/// @file detail/Config.h -/// @author Amlal El Mahrouss -/// @brief Basic defines and types for CompilerKit. -/// =========================================================== /// - -#include <CompilerKit/Detail/PreConfig.h> - -namespace CompilerKit { -inline constexpr int kBaseYear = 1900; -using STLString = std::string; - -inline STLString current_date() noexcept { - auto time_data = time(nullptr); - auto time_struct = gmtime(&time_data); - - STLString fmt = std::to_string(kBaseYear + time_struct->tm_year); - - fmt += "-"; - fmt += std::to_string(time_struct->tm_mon + 1); - fmt += "-"; - fmt += std::to_string(time_struct->tm_mday); - - return fmt; -} - -inline bool to_str(Char* str, Int32 limit, Int32 base) noexcept { - if (limit == 0) return false; - - Int32 copy_limit = limit; - Int32 cnt = 0; - Int32 ret = base; - - while (limit != 1) { - ret = ret % 10; - str[cnt] = ret; - - ++cnt; - --limit; - --ret; - } - - str[copy_limit] = '\0'; - return true; -} - -inline bool install_signal(Int32 signal, void (*handler)(int)) noexcept { - if (handler == nullptr) return false; - - if (::signal(signal, handler) == SIG_ERR) { - return false; - } - - return true; -} -} // namespace CompilerKit diff --git a/src/CompilerKit/Detail/Power64.h b/src/CompilerKit/Detail/Power64.h deleted file mode 100644 index 7c7f67c..0000000 --- a/src/CompilerKit/Detail/Power64.h +++ /dev/null @@ -1,1557 +0,0 @@ -/* ======================================== - - Some modifications are copyrighted under: - Amlal El Mahrouss - - Original author: - Apple Inc - -======================================== */ - -#pragma once - -#include <stdint.h> - -/// @note Based of: -/// https://opensource.apple.com/source/cctools/cctools-750/as/ppc-opcode.h.auto.html - -#define kOpcodePPCCount (1073U) - -/* - * These defines are use in the cpus field of the instructions. If the field - * is zero it can execute on all cpus. The defines are or'ed together. This - * information is used to set the cpusubtype in the resulting object file. - */ -#define CPU601 0x1 -#define IMPL64 0x2 -#define OPTIONAL 0x4 -#define VMX 0x8 -#define CPU970 0x10 /* added to OPTIONAL insts that the 970 has */ -#define CPUMAHROUSS 0x12 /* optional mahrouss insts. */ - -enum OpcodeType { - NONE, /* no operand */ - JBSR, /* jbsr pseudo op */ - PCREL, /* PC relative (branch offset) */ - BADDR, /* Branch address (sign extended absolute address) */ - D, /* 16 bit displacement */ - DS, /* 14 bit displacement (double word) */ - SI, /* signed 16 bit immediate */ - UI, /* unsigned 16 bit immediate */ - HI, /* high 16 bit immediate (with truncation) */ - GREG, /* general register */ - G0REG, /* general register r1-r31 or 0 */ - FREG, /* float register */ - VREG, /* vector register */ - SGREG, /* segment register */ - SPREG, /* special register (or 10 bit number, 5 bit halves reversed) */ - BCND, /* branch condition opcode */ - CRF, /* condition register field */ - CRFONLY, /* condition register field only no expression allowed */ - sh, /* 6 bit number (0 - 63) (sh field, split and reversed) */ - mb, /* 6 bit number (0 - 63) (mb field, mb5 || mb0:4 reversed) */ - NUM, /* number */ - SNUM, /* signed number */ - NUM0, /* number (where 1<<width is the same as 0) */ - MBE, /* mask defined by MB and ME fields */ - FXM, /* 8-bit mask with only one bit set */ - ZERO /* the number zero */ -}; - -struct CpuOpcodePPC { - struct OpcodeType final { - uint32_t offset : 5; - uint32_t width : 5; - uint32_t type : 6; - }; - - uint32_t opcode; - const char* name; // c++ wants the string to be const, it makes sense here. - OpcodeType ops[5]; - uint32_t cpus; -}; - -inline CpuOpcodePPC kOpcodesPowerPC[] = { - {0x38000000, "addi", {{21, 5, GREG}, {16, 5, G0REG}, {0, 16, SI}}}, - {0x38000000, "li", {{21, 5, GREG}, {0, 16, SI}}}, - {0x3c000000, "addis", {{21, 5, GREG}, {16, 5, G0REG}, {0, 16, HI}}}, - {0x3c000000, "lis", {{21, 5, GREG}, {0, 16, HI}}}, - {0x30000000, "addic", {{21, 5, GREG}, {16, 5, GREG}, {0, 16, SI}}}, - {0x34000000, "addic.", {{21, 5, GREG}, {16, 5, GREG}, {0, 16, SI}}}, - {0x7c000214, "add", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000215, "add.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000614, "addo", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000615, "addo.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - - {0x7c000014, "addc", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000015, "addc.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000414, "addco", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000415, "addco.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - - {0x7c000114, "adde", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000115, "adde.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000514, "addeo", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000515, "addeo.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - - {0x7c0001d4, "addme", {{21, 5, GREG}, {16, 5, GREG}}}, - {0x7c0001d5, "addme.", {{21, 5, GREG}, {16, 5, GREG}}}, - {0x7c0005d4, "addmeo", {{21, 5, GREG}, {16, 5, GREG}}}, - {0x7c0005d5, "addmeo.", {{21, 5, GREG}, {16, 5, GREG}}}, - - {0x7c000194, "addze", {{21, 5, GREG}, {16, 5, GREG}}}, - {0x7c000195, "addze.", {{21, 5, GREG}, {16, 5, GREG}}}, - {0x7c000594, "addzeo", {{21, 5, GREG}, {16, 5, GREG}}}, - {0x7c000595, "addzeo.", {{21, 5, GREG}, {16, 5, GREG}}}, - - {0x70000000, "andi.", {{16, 5, GREG}, {21, 5, GREG}, {0, 16, UI}}}, - {0x74000000, "andis.", {{16, 5, GREG}, {21, 5, GREG}, {0, 16, UI}}}, - {0x7c000038, "and", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}}, - {0x7c000039, "and.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}}, - - {0x7c000078, "andc", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}}, - {0x7c000079, "andc.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}}, - - {0x48000000, "b", {{2, 24, PCREL}}}, - {0x48000002, "ba", {{2, 24, BADDR}}}, - {0x48000001, "bl", {{2, 24, PCREL}}}, - {0x48000003, "bla", {{2, 24, BADDR}}}, - - {0x48000001, "jbsr", {{0, 0, JBSR}, {2, 24, PCREL}}}, - {0x48000000, "jmp", {{0, 0, JBSR}, {2, 24, PCREL}}}, - - {0x40000000, "bc", {{21, 5, NUM}, {16, 5, NUM}, {2, 14, PCREL}}}, - {0x40000002, "bca", {{21, 5, NUM}, {16, 5, NUM}, {2, 14, BADDR}}}, - {0x40000001, "bcl", {{21, 5, NUM}, {16, 5, NUM}, {2, 14, PCREL}}}, - {0x40000003, "bcla", {{21, 5, NUM}, {16, 5, NUM}, {2, 14, BADDR}}}, - - {0x4c000420, "bcctr", {{21, 5, NUM}, {16, 5, NUM}}}, - {0x4c000420, "bcctr", {{21, 5, NUM}, {16, 5, NUM}, {11, 2, NUM}}}, - {0x4c000421, "bcctrl", {{21, 5, NUM}, {16, 5, NUM}}}, - {0x4c000421, "bcctrl", {{21, 5, NUM}, {16, 5, NUM}, {11, 2, NUM}}}, - {0x4c000020, "bclr", {{21, 5, NUM}, {16, 5, NUM}}}, - {0x4c000020, "bclr", {{21, 5, NUM}, {16, 5, NUM}, {11, 2, NUM}}}, - {0x4c000021, "bclrl", {{21, 5, NUM}, {16, 5, NUM}}}, - {0x4c000021, "bclrl", {{21, 5, NUM}, {16, 5, NUM}, {11, 2, NUM}}}, - - /* Basic branch mnemonics (assember extended mnemonics) */ - /* { 0x42800000, "b", {{2,14,PCREL}} }, overlaps */ - /* { 0x42800001, "bl", {{2,14,PCREL}} }, overlaps */ - {0x41800000, "bt", {{16, 5, BCND}, {2, 14, PCREL}}}, - {0x41800001, "btl", {{16, 5, BCND}, {2, 14, PCREL}}}, - {0x40800000, "bf", {{16, 5, BCND}, {2, 14, PCREL}}}, - {0x40800001, "bfl", {{16, 5, BCND}, {2, 14, PCREL}}}, - {0x42000000, "bdnz", {{2, 14, PCREL}}}, - {0x42000001, "bdnzl", {{2, 14, PCREL}}}, - {0x41000000, "bdnzt", {{16, 5, BCND}, {2, 14, PCREL}}}, - {0x41000001, "bdnztl", {{16, 5, BCND}, {2, 14, PCREL}}}, - {0x40000000, "bdnzf", {{16, 5, BCND}, {2, 14, PCREL}}}, - {0x40000001, "bdnzfl", {{16, 5, BCND}, {2, 14, PCREL}}}, - {0x42400000, "bdz", {{2, 14, PCREL}}}, - {0x42400001, "bdzl", {{2, 14, PCREL}}}, - {0x41400000, "bdzt", {{16, 5, BCND}, {2, 14, PCREL}}}, - {0x41400001, "bdztl", {{16, 5, BCND}, {2, 14, PCREL}}}, - {0x40400000, "bdzf", {{16, 5, BCND}, {2, 14, PCREL}}}, - {0x40400001, "bdzfl", {{16, 5, BCND}, {2, 14, PCREL}}}, - - /* { 0x42800002, "ba", {{2,14,BADDR}} }, overlaps */ - /* { 0x42800003, "bla", {{2,14,BADDR}} }, overlaps */ - {0x41800002, "bta", {{16, 5, BCND}, {2, 14, BADDR}}}, - {0x41800003, "btla", {{16, 5, BCND}, {2, 14, BADDR}}}, - {0x40800002, "bfa", {{16, 5, BCND}, {2, 14, BADDR}}}, - {0x40800003, "bfla", {{16, 5, BCND}, {2, 14, BADDR}}}, - {0x42000002, "bdnza", {{2, 14, BADDR}}}, - {0x42000003, "bdnzla", {{2, 14, BADDR}}}, - {0x41000002, "bdnzta", {{16, 5, BCND}, {2, 14, BADDR}}}, - {0x41000003, "bdnztla", {{16, 5, BCND}, {2, 14, BADDR}}}, - {0x40000002, "bdnzfa", {{16, 5, BCND}, {2, 14, BADDR}}}, - {0x40000003, "bdnzfla", {{16, 5, BCND}, {2, 14, BADDR}}}, - {0x42400002, "bdza", {{2, 14, BADDR}}}, - {0x42400003, "bdzla", {{2, 14, BADDR}}}, - {0x41400002, "bdzta", {{16, 5, BCND}, {2, 14, BADDR}}}, - {0x41400003, "bdztla", {{16, 5, BCND}, {2, 14, BADDR}}}, - {0x40400002, "bdzfa", {{16, 5, BCND}, {2, 14, BADDR}}}, - {0x40400003, "bdzfla", {{16, 5, BCND}, {2, 14, BADDR}}}, - - { - 0x4e800020, - "blr", - }, - {0x4e800020, "blr", {{11, 2, NUM}}}, - { - 0x4e800021, - "blrl", - }, - {0x4e800021, "blrl", {{11, 2, NUM}}}, - {0x4d800020, "btlr", {{16, 5, BCND}}}, - {0x4d800020, "btlr", {{16, 5, BCND}, {11, 2, NUM}}}, - {0x4d800021, "btlrl", {{16, 5, BCND}}}, - {0x4d800021, "btlrl", {{16, 5, BCND}, {11, 2, NUM}}}, - {0x4c800020, "bflr", {{16, 5, BCND}}}, - {0x4c800020, "bflr", {{16, 5, BCND}, {11, 2, NUM}}}, - {0x4c800021, "bflrl", {{16, 5, BCND}}}, - {0x4c800021, "bflrl", {{16, 5, BCND}, {11, 2, NUM}}}, - { - 0x4e000020, - "bdnzlr", - }, - {0x4e000020, "bdnzlr", {{11, 2, NUM}}}, - { - 0x4e000021, - "bdnzlrl", - }, - {0x4e000021, "bdnzlrl", {{11, 2, NUM}}}, - {0x4d000020, "bdnztlr", {{16, 5, BCND}}}, - {0x4d000020, "bdnztlr", {{16, 5, BCND}, {11, 2, NUM}}}, - {0x4d000021, "bdnztlrl", {{16, 5, BCND}}}, - {0x4d000021, "bdnztlrl", {{16, 5, BCND}, {11, 2, NUM}}}, - {0x4c000020, "bdnzflr", {{16, 5, BCND}}}, - {0x4c000020, "bdnzflr", {{16, 5, BCND}, {11, 2, NUM}}}, - {0x4c000021, "bdnzflrl", {{16, 5, BCND}}}, - {0x4c000021, "bdnzflrl", {{16, 5, BCND}, {11, 2, NUM}}}, - { - 0x4e400020, - "bdzlr", - }, - {0x4e400020, "bdzlr", {{11, 2, NUM}}}, - { - 0x4e400021, - "bdzlrl", - }, - {0x4e400021, "bdzlrl", {{11, 2, NUM}}}, - {0x4d400020, "bdztlr", {{16, 5, BCND}}}, - {0x4d400020, "bdztlr", {{16, 5, BCND}, {11, 2, NUM}}}, - {0x4d400021, "bdztlrl", {{16, 5, BCND}}}, - {0x4d400021, "bdztlrl", {{16, 5, BCND}, {11, 2, NUM}}}, - {0x4c400020, "bdzflr", {{16, 5, BCND}}}, - {0x4c400020, "bdzflr", {{16, 5, BCND}, {11, 2, NUM}}}, - {0x4c400021, "bdzflrl", {{16, 5, BCND}}}, - {0x4c400021, "bdzflrl", {{16, 5, BCND}, {11, 2, NUM}}}, - - {0x4c000420, "bctr", {{21, 5, NUM}, {16, 5, NUM}}}, - { - 0x4e800420, - "bctr", - }, - {0x4e800420, "bctr", {{11, 2, NUM}}}, - {0x4c000421, "bctrl", {{21, 5, NUM}, {16, 5, NUM}}}, - { - 0x4e800421, - "bctrl", - }, - {0x4e800421, "bctrl", {{11, 2, NUM}}}, - {0x4d800420, "btctr", {{16, 5, BCND}}}, - {0x4d800420, "btctr", {{16, 5, BCND}, {11, 2, NUM}}}, - {0x4d800421, "btctrl", {{16, 5, BCND}}}, - {0x4d800421, "btctrl", {{16, 5, BCND}, {11, 2, NUM}}}, - {0x4c800420, "bfctr", {{16, 5, BCND}}}, - {0x4c800420, "bfctr", {{16, 5, BCND}, {11, 2, NUM}}}, - {0x4c800421, "bfctrl", {{16, 5, BCND}}}, - {0x4c800421, "bfctrl", {{16, 5, BCND}, {11, 2, NUM}}}, - - /* branch mnemonics incorporating conditions (assember extended mnemonics) - */ - {0x41800000, "blt", {{16, 5, CRF}, {2, 14, PCREL}}}, - {0x41800000, "blt", {{2, 14, PCREL}}}, - {0x41800001, "bltl", {{16, 5, CRF}, {2, 14, PCREL}}}, - {0x41800001, "bltl", {{2, 14, PCREL}}}, - {0x40810000, "ble", {{16, 5, CRF}, {2, 14, PCREL}}}, - {0x40810000, "ble", {{2, 14, PCREL}}}, - {0x40810001, "blel", {{16, 5, CRF}, {2, 14, PCREL}}}, - {0x40810001, "blel", {{2, 14, PCREL}}}, - {0x41820000, "beq", {{16, 5, CRF}, {2, 14, PCREL}}}, - {0x41820000, "beq", {{2, 14, PCREL}}}, - {0x41820001, "beql", {{16, 5, CRF}, {2, 14, PCREL}}}, - {0x41820001, "beql", {{2, 14, PCREL}}}, - {0x40800000, "bge", {{16, 5, CRF}, {2, 14, PCREL}}}, - {0x40800000, "bge", {{2, 14, PCREL}}}, - {0x40800001, "bgel", {{16, 5, CRF}, {2, 14, PCREL}}}, - {0x40800001, "bgel", {{2, 14, PCREL}}}, - {0x41810000, "bgt", {{16, 5, CRF}, {2, 14, PCREL}}}, - {0x41810000, "bgt", {{2, 14, PCREL}}}, - {0x41810001, "bgtl", {{16, 5, CRF}, {2, 14, PCREL}}}, - {0x41810001, "bgtl", {{2, 14, PCREL}}}, - {0x40800000, "bnl", {{16, 5, CRF}, {2, 14, PCREL}}}, - {0x40800000, "bnl", {{2, 14, PCREL}}}, - {0x40800001, "bnll", {{16, 5, CRF}, {2, 14, PCREL}}}, - {0x40800001, "bnll", {{2, 14, PCREL}}}, - {0x40820000, "bne", {{16, 5, CRF}, {2, 14, PCREL}}}, - {0x40820000, "bne", {{2, 14, PCREL}}}, - {0x40820001, "bnel", {{16, 5, CRF}, {2, 14, PCREL}}}, - {0x40820001, "bnel", {{2, 14, PCREL}}}, - {0x40810000, "bng", {{16, 5, CRF}, {2, 14, PCREL}}}, - {0x40810000, "bng", {{2, 14, PCREL}}}, - {0x40810001, "bngl", {{16, 5, CRF}, {2, 14, PCREL}}}, - {0x40810001, "bngl", {{2, 14, PCREL}}}, - {0x41830000, "bso", {{16, 5, CRF}, {2, 14, PCREL}}}, - {0x41830000, "bso", {{2, 14, PCREL}}}, - {0x41830001, "bsol", {{16, 5, CRF}, {2, 14, PCREL}}}, - {0x41830001, "bsol", {{2, 14, PCREL}}}, - {0x40830000, "bns", {{16, 5, CRF}, {2, 14, PCREL}}}, - {0x40830000, "bns", {{2, 14, PCREL}}}, - {0x40830001, "bnsl", {{16, 5, CRF}, {2, 14, PCREL}}}, - {0x40830001, "bnsl", {{2, 14, PCREL}}}, - {0x41830000, "bun", {{16, 5, CRF}, {2, 14, PCREL}}}, - {0x41830000, "bun", {{2, 14, PCREL}}}, - {0x41830001, "bunl", {{16, 5, CRF}, {2, 14, PCREL}}}, - {0x41830001, "bunl", {{2, 14, PCREL}}}, - {0x40830000, "bnu", {{16, 5, CRF}, {2, 14, PCREL}}}, - {0x40830000, "bnu", {{2, 14, PCREL}}}, - {0x40830001, "bnul", {{16, 5, CRF}, {2, 14, PCREL}}}, - {0x40830001, "bnul", {{2, 14, PCREL}}}, - - {0x41800002, "blta", {{16, 5, CRF}, {2, 14, BADDR}}}, - {0x41800002, "blta", {{2, 14, BADDR}}}, - {0x41800003, "bltla", {{16, 5, CRF}, {2, 14, BADDR}}}, - {0x41800003, "bltla", {{2, 14, BADDR}}}, - {0x40810002, "blea", {{16, 5, CRF}, {2, 14, BADDR}}}, - {0x40810002, "blea", {{2, 14, BADDR}}}, - {0x40810003, "blela", {{16, 5, CRF}, {2, 14, BADDR}}}, - {0x40810003, "blela", {{2, 14, BADDR}}}, - {0x41820002, "beqa", {{16, 5, CRF}, {2, 14, BADDR}}}, - {0x41820002, "beqa", {{2, 14, BADDR}}}, - {0x41820003, "beqla", {{16, 5, CRF}, {2, 14, BADDR}}}, - {0x41820003, "beqla", {{2, 14, BADDR}}}, - {0x40800002, "bgea", {{16, 5, CRF}, {2, 14, BADDR}}}, - {0x40800002, "bgea", {{2, 14, BADDR}}}, - {0x40800003, "bgela", {{16, 5, CRF}, {2, 14, BADDR}}}, - {0x40800003, "bgela", {{2, 14, BADDR}}}, - {0x41810002, "bgta", {{16, 5, CRF}, {2, 14, BADDR}}}, - {0x41810002, "bgta", {{2, 14, BADDR}}}, - {0x41810003, "bgtla", {{16, 5, CRF}, {2, 14, BADDR}}}, - {0x41810003, "bgtla", {{2, 14, BADDR}}}, - {0x40800002, "bnla", {{16, 5, CRF}, {2, 14, BADDR}}}, - {0x40800002, "bnla", {{2, 14, BADDR}}}, - {0x40800003, "bnlla", {{16, 5, CRF}, {2, 14, BADDR}}}, - {0x40800003, "bnlla", {{2, 14, BADDR}}}, - {0x40820002, "bnea", {{16, 5, CRF}, {2, 14, BADDR}}}, - {0x40820002, "bnea", {{2, 14, BADDR}}}, - {0x40820003, "bnela", {{16, 5, CRF}, {2, 14, BADDR}}}, - {0x40820003, "bnela", {{2, 14, BADDR}}}, - {0x40810002, "bnga", {{16, 5, CRF}, {2, 14, BADDR}}}, - {0x40810002, "bnga", {{2, 14, BADDR}}}, - {0x40810003, "bngla", {{16, 5, CRF}, {2, 14, BADDR}}}, - {0x40810003, "bngla", {{2, 14, BADDR}}}, - {0x41830002, "bsoa", {{16, 5, CRF}, {2, 14, BADDR}}}, - {0x41830002, "bsoa", {{2, 14, BADDR}}}, - {0x41830003, "bsola", {{16, 5, CRF}, {2, 14, BADDR}}}, - {0x41830003, "bsola", {{2, 14, BADDR}}}, - {0x40830002, "bnsa", {{16, 5, CRF}, {2, 14, BADDR}}}, - {0x40830002, "bnsa", {{2, 14, BADDR}}}, - {0x40830003, "bnsla", {{16, 5, CRF}, {2, 14, BADDR}}}, - {0x40830003, "bnsla", {{2, 14, BADDR}}}, - {0x41830002, "buna", {{16, 5, CRF}, {2, 14, BADDR}}}, - {0x41830002, "buna", {{2, 14, BADDR}}}, - {0x41830003, "bunla", {{16, 5, CRF}, {2, 14, BADDR}}}, - {0x41830003, "bunla", {{2, 14, BADDR}}}, - {0x40830002, "bnua", {{16, 5, CRF}, {2, 14, BADDR}}}, - {0x40830002, "bnua", {{2, 14, BADDR}}}, - {0x40830003, "bnula", {{16, 5, CRF}, {2, 14, BADDR}}}, - {0x40830003, "bnula", {{2, 14, BADDR}}}, - - {0x4d800020, "bltlr", {{16, 5, CRF}}}, - {0x4d800020, "bltlr", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4d800020, - "bltlr", - }, - {0x4d800021, "bltlrl", {{16, 5, CRF}}}, - {0x4d800021, "bltlrl", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4d800021, - "bltlrl", - }, - {0x4c810020, "blelr", {{16, 5, CRF}}}, - {0x4c810020, "blelr", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4c810020, - "blelr", - }, - {0x4c810021, "blelrl", {{16, 5, CRF}}}, - {0x4c810021, "blelrl", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4c810021, - "blelrl", - }, - {0x4d820020, "beqlr", {{16, 5, CRF}}}, - {0x4d820020, "beqlr", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4d820020, - "beqlr", - }, - {0x4d820021, "beqlrl", {{16, 5, CRF}}}, - {0x4d820021, "beqlrl", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4d820021, - "beqlrl", - }, - {0x4c800020, "bgelr", {{16, 5, CRF}}}, - {0x4c800020, "bgelr", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4c800020, - "bgelr", - }, - {0x4c800021, "bgelrl", {{16, 5, CRF}}}, - {0x4c800021, "bgelrl", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4c800021, - "bgelrl", - }, - {0x4d810020, "bgtlr", {{16, 5, CRF}}}, - {0x4d810020, "bgtlr", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4d810020, - "bgtlr", - }, - {0x4d810021, "bgtlrl", {{16, 5, CRF}}}, - {0x4d810021, "bgtlrl", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4d810021, - "bgtlrl", - }, - {0x4c800020, "bnllr", {{16, 5, CRF}}}, - {0x4c800020, "bnllr", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4c800020, - "bnllr", - }, - {0x4c800021, "bnllrl", {{16, 5, CRF}}}, - {0x4c800021, "bnllrl", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4c800021, - "bnllrl", - }, - {0x4c820020, "bnelr", {{16, 5, CRF}}}, - {0x4c820020, "bnelr", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4c820020, - "bnelr", - }, - {0x4c820021, "bnelrl", {{16, 5, CRF}}}, - {0x4c820021, "bnelrl", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4c820021, - "bnelrl", - }, - {0x4c810020, "bnglr", {{16, 5, CRF}}}, - {0x4c810020, "bnglr", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4c810020, - "bnglr", - }, - {0x4c810021, "bnglrl", {{16, 5, CRF}}}, - {0x4c810021, "bnglrl", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4c810021, - "bnglrl", - }, - {0x4d830020, "bsolr", {{16, 5, CRF}}}, - {0x4d830020, "bsolr", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4d830020, - "bsolr", - }, - {0x4d830021, "bsolrl", {{16, 5, CRF}}}, - {0x4d830021, "bsolrl", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4d830021, - "bsolrl", - }, - {0x4c830020, "bnslr", {{16, 5, CRF}}}, - {0x4c830020, "bnslr", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4c830020, - "bnslr", - }, - {0x4c830021, "bnslrl", {{16, 5, CRF}}}, - {0x4c830021, "bnslrl", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4c830021, - "bnslrl", - }, - {0x4d830020, "bunlr", {{16, 5, CRF}}}, - {0x4d830020, "bunlr", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4d830020, - "bunlr", - }, - {0x4d830021, "bunlrl", {{16, 5, CRF}}}, - {0x4d830021, "bunlrl", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4d830021, - "bunlrl", - }, - {0x4c830020, "bnulr", {{16, 5, CRF}}}, - {0x4c830020, "bnulr", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4c830020, - "bnulr", - }, - {0x4c830021, "bnulrl", {{16, 5, CRF}}}, - {0x4c830021, "bnulrl", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4c830021, - "bnulrl", - }, - - {0x4d800420, "bltctr", {{16, 5, CRF}}}, - {0x4d800420, "bltctr", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4d800420, - "bltctr", - }, - {0x4d800421, "bltctrl", {{16, 5, CRF}}}, - {0x4d800421, "bltctrl", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4d800421, - "bltctrl", - }, - {0x4c810420, "blectr", {{16, 5, CRF}}}, - {0x4c810420, "blectr", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4c810420, - "blectr", - }, - {0x4c810421, "blectrl", {{16, 5, CRF}}}, - {0x4c810421, "blectrl", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4c810421, - "blectrl", - }, - {0x4d820420, "beqctr", {{16, 5, CRF}}}, - {0x4d820420, "beqctr", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4d820420, - "beqctr", - }, - {0x4d820421, "beqctrl", {{16, 5, CRF}}}, - {0x4d820421, "beqctrl", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4d820421, - "beqctrl", - }, - {0x4c800420, "bgectr", {{16, 5, CRF}}}, - {0x4c800420, "bgectr", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4c800420, - "bgectr", - }, - {0x4c800421, "bgectrl", {{16, 5, CRF}}}, - {0x4c800421, "bgectrl", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4c800421, - "bgectrl", - }, - {0x4d810420, "bgtctr", {{16, 5, CRF}}}, - {0x4d810420, "bgtctr", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4d810420, - "bgtctr", - }, - {0x4d810421, "bgtctrl", {{16, 5, CRF}}}, - {0x4d810421, "bgtctrl", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4d810421, - "bgtctrl", - }, - {0x4c800420, "bnlctr", {{16, 5, CRF}}}, - {0x4c800420, "bnlctr", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4c800420, - "bnlctr", - }, - {0x4c800421, "bnlctrl", {{16, 5, CRF}}}, - {0x4c800421, "bnlctrl", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4c800421, - "bnlctrl", - }, - {0x4c820420, "bnectr", {{16, 5, CRF}}}, - {0x4c820420, "bnectr", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4c820420, - "bnectr", - }, - {0x4c820421, "bnectrl", {{16, 5, CRF}}}, - {0x4c820421, "bnectrl", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4c820421, - "bnectrl", - }, - {0x4c810420, "bngctr", {{16, 5, CRF}}}, - {0x4c810420, "bngctr", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4c810420, - "bngctr", - }, - {0x4c810421, "bngctrl", {{16, 5, CRF}}}, - {0x4c810421, "bngctrl", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4c810421, - "bngctrl", - }, - {0x4d830420, "bsoctr", {{16, 5, CRF}}}, - {0x4d830420, "bsoctr", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4d830420, - "bsoctr", - }, - {0x4d830421, "bsoctrl", {{16, 5, CRF}}}, - {0x4d830421, "bsoctrl", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4d830421, - "bsoctrl", - }, - {0x4c830420, "bnsctr", {{16, 5, CRF}}}, - {0x4c830420, "bnsctr", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4c830420, - "bnsctr", - }, - {0x4c830421, "bnsctrl", {{16, 5, CRF}}}, - {0x4c830421, "bnsctrl", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4c830421, - "bnsctrl", - }, - {0x4d830420, "bunctr", {{16, 5, CRF}}}, - {0x4d830420, "bunctr", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4d830420, - "bunctr", - }, - {0x4d830421, "bunctrl", {{16, 5, CRF}}}, - {0x4d830421, "bunctrl", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4d830421, - "bunctrl", - }, - {0x4c830420, "bnuctr", {{16, 5, CRF}}}, - {0x4c830420, "bnuctr", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4c830420, - "bnuctr", - }, - {0x4c830421, "bnuctrl", {{16, 5, CRF}}}, - {0x4c830421, "bnuctrl", {{16, 5, CRF}, {11, 2, NUM}}}, - { - 0x4c830421, - "bnuctrl", - }, - - {0x2c000000, "cmpi", {{21, 5, CRFONLY}, {16, 5, GREG}, {0, 16, SI}}}, - {0x2c000000, "cmpi", {{21, 5, CRFONLY}, {21, 1, NUM}, {16, 5, GREG}, {0, 16, SI}}}, - {0x2c000000, "cmpi", {{23, 3, NUM}, {16, 5, GREG}, {0, 16, SI}}}, - {0x2c000000, "cmpi", {{23, 3, NUM}, {21, 1, NUM}, {16, 5, GREG}, {0, 16, SI}}}, - {0x2c000000, "cmpwi", {{16, 5, GREG}, {0, 16, SI}}}, - {0x2c000000, "cmpwi", {{21, 5, CRFONLY}, {16, 5, GREG}, {0, 16, SI}}}, - {0x2c000000, "cmpwi", {{23, 3, NUM}, {16, 5, GREG}, {0, 16, SI}}}, - {0x2c200000, "cmpdi", {{16, 5, GREG}, {0, 16, SI}}}, - {0x2c200000, "cmpdi", {{21, 5, CRFONLY}, {16, 5, GREG}, {0, 16, SI}}}, - {0x2c200000, "cmpdi", {{23, 3, NUM}, {16, 5, GREG}, {0, 16, SI}}}, - - {0x7c000000, "cmp", {{21, 5, CRFONLY}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000000, "cmp", {{21, 5, CRFONLY}, {21, 1, NUM}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000000, "cmp", {{23, 3, NUM}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000000, "cmp", {{23, 3, NUM}, {21, 1, NUM}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000000, "cmpw", {{16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000000, "cmpw", {{21, 5, CRFONLY}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000000, "cmpw", {{23, 3, NUM}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c200000, "cmpd", {{16, 5, GREG}, {11, 5, GREG}}}, - {0x7c200000, "cmpd", {{21, 5, CRFONLY}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c200000, "cmpd", {{23, 3, NUM}, {16, 5, GREG}, {11, 5, GREG}}}, - - {0x28000000, "cmpli", {{21, 5, CRFONLY}, {16, 5, GREG}, {0, 16, UI}}}, - {0x28000000, "cmpli", {{21, 5, CRFONLY}, {21, 1, NUM}, {16, 5, GREG}, {0, 16, UI}}}, - {0x28000000, "cmpli", {{23, 3, NUM}, {16, 5, GREG}, {0, 16, UI}}}, - {0x28000000, "cmpli", {{23, 3, NUM}, {21, 1, NUM}, {16, 5, GREG}, {0, 16, UI}}}, - {0x28000000, "cmplwi", {{16, 5, GREG}, {0, 16, UI}}}, - {0x28000000, "cmplwi", {{21, 5, CRFONLY}, {16, 5, GREG}, {0, 16, UI}}}, - {0x28000000, "cmplwi", {{23, 3, NUM}, {16, 5, GREG}, {0, 16, UI}}}, - {0x28200000, "cmpldi", {{16, 5, GREG}, {0, 16, UI}}}, - {0x28200000, "cmpldi", {{21, 5, CRFONLY}, {16, 5, GREG}, {0, 16, UI}}}, - {0x28200000, "cmpldi", {{23, 3, NUM}, {16, 5, GREG}, {0, 16, UI}}}, - - {0x7c000040, "cmpl", {{21, 5, CRFONLY}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000040, "cmpl", {{21, 5, CRFONLY}, {21, 1, NUM}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000040, "cmpl", {{23, 3, NUM}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000040, "cmpl", {{23, 3, NUM}, {21, 1, NUM}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000040, "cmplw", {{16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000040, "cmplw", {{21, 5, CRFONLY}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000040, "cmplw", {{23, 3, NUM}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c200040, "cmpld", {{16, 5, GREG}, {11, 5, GREG}}}, - {0x7c200040, "cmpld", {{21, 5, CRFONLY}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c200040, "cmpld", {{23, 3, NUM}, {16, 5, GREG}, {11, 5, GREG}}}, - - {0x7c000034, "cntlzw", {{16, 5, GREG}, {21, 5, GREG}}}, - {0x7c000035, "cntlzw.", {{16, 5, GREG}, {21, 5, GREG}}}, - {0x7c000074, "cntlzd", {{16, 5, GREG}, {21, 5, GREG}}, IMPL64}, - {0x7c000075, "cntlzd.", {{16, 5, GREG}, {21, 5, GREG}}, IMPL64}, - - {0x4c000202, "crand", {{21, 5, NUM}, {16, 5, NUM}, {11, 5, NUM}}}, - {0x4c000102, "crandc", {{21, 5, NUM}, {16, 5, NUM}, {11, 5, NUM}}}, - {0x4c000242, "creqv", {{21, 5, NUM}, {16, 5, NUM}, {11, 5, NUM}}}, - {0x4c0001c2, "crnand", {{21, 5, NUM}, {16, 5, NUM}, {11, 5, NUM}}}, - {0x4c000042, "crnor", {{21, 5, NUM}, {16, 5, NUM}, {11, 5, NUM}}}, - {0x4c000382, "cror", {{21, 5, NUM}, {16, 5, NUM}, {11, 5, NUM}}}, - {0x4c000342, "crorc", {{21, 5, NUM}, {16, 5, NUM}, {11, 5, NUM}}}, - {0x4c000182, "crxor", {{21, 5, NUM}, {16, 5, NUM}, {11, 5, NUM}}}, - - {0x7c0003d2, "divd", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - {0x7c0003d3, "divd.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - {0x7c0007d2, "divdo", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - {0x7c0007d3, "divdo.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - - {0x7c000392, "divdu", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - {0x7c000393, "divdu.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - {0x7c000792, "divduo", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - {0x7c000793, "divduo.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - - {0x7c0003d6, "divw", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c0003d7, "divw.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c0007d6, "divwo", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c0007d7, "divwo.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - - {0x7c000396, "divwu", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000397, "divwu.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000796, "divwuo", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000797, "divwuo.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - - {0x7c000238, "eqv", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}}, - {0x7c000239, "eqv.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}}, - - {0x7c000774, "extsb", {{16, 5, GREG}, {21, 5, GREG}}}, - {0x7c000775, "extsb.", {{16, 5, GREG}, {21, 5, GREG}}}, - {0x7c000734, "extsh", {{16, 5, GREG}, {21, 5, GREG}}}, - {0x7c000735, "extsh.", {{16, 5, GREG}, {21, 5, GREG}}}, - {0x7c0007b4, "extsw", {{16, 5, GREG}, {21, 5, GREG}}, IMPL64}, - {0x7c0007b5, "extsw.", {{16, 5, GREG}, {21, 5, GREG}}, IMPL64}, - - {0xfc00002a, "fadd", {{21, 5, FREG}, {16, 5, FREG}, {11, 5, FREG}}}, - {0xfc00002b, "fadd.", {{21, 5, FREG}, {16, 5, FREG}, {11, 5, FREG}}}, - {0xec00002a, "fadds", {{21, 5, FREG}, {16, 5, FREG}, {11, 5, FREG}}}, - {0xec00002b, "fadds.", {{21, 5, FREG}, {16, 5, FREG}, {11, 5, FREG}}}, - {0xfc000028, "fsub", {{21, 5, FREG}, {16, 5, FREG}, {11, 5, FREG}}}, - {0xfc000029, "fsub.", {{21, 5, FREG}, {16, 5, FREG}, {11, 5, FREG}}}, - {0xec000028, "fsubs", {{21, 5, FREG}, {16, 5, FREG}, {11, 5, FREG}}}, - {0xec000029, "fsubs.", {{21, 5, FREG}, {16, 5, FREG}, {11, 5, FREG}}}, - {0xfc000032, "fmul", {{21, 5, FREG}, {16, 5, FREG}, {6, 5, FREG}}}, - {0xfc000033, "fmul.", {{21, 5, FREG}, {16, 5, FREG}, {6, 5, FREG}}}, - {0xec000032, "fmuls", {{21, 5, FREG}, {16, 5, FREG}, {6, 5, FREG}}}, - {0xec000033, "fmuls.", {{21, 5, FREG}, {16, 5, FREG}, {6, 5, FREG}}}, - {0xfc000024, "fdiv", {{21, 5, FREG}, {16, 5, FREG}, {11, 5, FREG}}}, - {0xfc000025, "fdiv.", {{21, 5, FREG}, {16, 5, FREG}, {11, 5, FREG}}}, - {0xec000024, "fdivs", {{21, 5, FREG}, {16, 5, FREG}, {11, 5, FREG}}}, - {0xec000025, "fdivs.", {{21, 5, FREG}, {16, 5, FREG}, {11, 5, FREG}}}, - - {0xfc00003a, "fmadd", {{21, 5, FREG}, {16, 5, FREG}, {6, 5, FREG}, {11, 5, FREG}}}, - {0xfc00003b, "fmadd.", {{21, 5, FREG}, {16, 5, FREG}, {6, 5, FREG}, {11, 5, FREG}}}, - {0xec00003a, "fmadds", {{21, 5, FREG}, {16, 5, FREG}, {6, 5, FREG}, {11, 5, FREG}}}, - {0xec00003b, "fmadds.", {{21, 5, FREG}, {16, 5, FREG}, {6, 5, FREG}, {11, 5, FREG}}}, - {0xfc000038, "fmsub", {{21, 5, FREG}, {16, 5, FREG}, {6, 5, FREG}, {11, 5, FREG}}}, - {0xfc000039, "fmsub.", {{21, 5, FREG}, {16, 5, FREG}, {6, 5, FREG}, {11, 5, FREG}}}, - {0xec000038, "fmsubs", {{21, 5, FREG}, {16, 5, FREG}, {6, 5, FREG}, {11, 5, FREG}}}, - {0xec000039, "fmsubs.", {{21, 5, FREG}, {16, 5, FREG}, {6, 5, FREG}, {11, 5, FREG}}}, - {0xfc00003e, "fnmadd", {{21, 5, FREG}, {16, 5, FREG}, {6, 5, FREG}, {11, 5, FREG}}}, - {0xfc00003f, "fnmadd.", {{21, 5, FREG}, {16, 5, FREG}, {6, 5, FREG}, {11, 5, FREG}}}, - {0xec00003e, "fnmadds", {{21, 5, FREG}, {16, 5, FREG}, {6, 5, FREG}, {11, 5, FREG}}}, - {0xec00003f, "fnmadds.", {{21, 5, FREG}, {16, 5, FREG}, {6, 5, FREG}, {11, 5, FREG}}}, - {0xfc00003c, "fnmsub", {{21, 5, FREG}, {16, 5, FREG}, {6, 5, FREG}, {11, 5, FREG}}}, - {0xfc00003d, "fnmsub.", {{21, 5, FREG}, {16, 5, FREG}, {6, 5, FREG}, {11, 5, FREG}}}, - {0xec00003c, "fnmsubs", {{21, 5, FREG}, {16, 5, FREG}, {6, 5, FREG}, {11, 5, FREG}}}, - {0xec00003d, "fnmsubs.", {{21, 5, FREG}, {16, 5, FREG}, {6, 5, FREG}, {11, 5, FREG}}}, - - {0xfc000090, "fmr", {{21, 5, FREG}, {11, 5, FREG}}}, - {0xfc000091, "fmr.", {{21, 5, FREG}, {11, 5, FREG}}}, - {0xfc000210, "fabs", {{21, 5, FREG}, {11, 5, FREG}}}, - {0xfc000211, "fabs.", {{21, 5, FREG}, {11, 5, FREG}}}, - {0xfc000050, "fneg", {{21, 5, FREG}, {11, 5, FREG}}}, - {0xfc000051, "fneg.", {{21, 5, FREG}, {11, 5, FREG}}}, - {0xfc000110, "fnabs", {{21, 5, FREG}, {11, 5, FREG}}}, - {0xfc000111, "fnabs.", {{21, 5, FREG}, {11, 5, FREG}}}, - {0xec000030, "fres", {{21, 5, FREG}, {11, 5, FREG}}}, - {0xec000031, "fres.", {{21, 5, FREG}, {11, 5, FREG}}}, - {0xfc000018, "frsp", {{21, 5, FREG}, {11, 5, FREG}}}, - {0xfc000019, "frsp.", {{21, 5, FREG}, {11, 5, FREG}}}, - {0xfc000034, "frsqrte", {{21, 5, FREG}, {11, 5, FREG}}}, - {0xfc000035, "frsqrte.", {{21, 5, FREG}, {11, 5, FREG}}}, - {0xfc00002e, "fsel", {{21, 5, FREG}, {16, 5, FREG}, {6, 5, FREG}, {11, 5, FREG}}}, - {0xfc00002f, "fsel.", {{21, 5, FREG}, {16, 5, FREG}, {6, 5, FREG}, {11, 5, FREG}}}, - {0xfc00002c, "fsqrt", {{21, 5, FREG}, {11, 5, FREG}}, OPTIONAL | CPU970}, - {0xfc00002d, "fsqrt.", {{21, 5, FREG}, {11, 5, FREG}}, OPTIONAL | CPU970}, - {0xec00002c, "fsqrts", {{21, 5, FREG}, {11, 5, FREG}}, OPTIONAL | CPU970}, - {0xec00002d, "fsqrts.", {{21, 5, FREG}, {11, 5, FREG}}, OPTIONAL | CPU970}, - {0xfc00065c, "fctid", {{21, 5, FREG}, {11, 5, FREG}}, IMPL64}, - {0xfc00065d, "fctid.", {{21, 5, FREG}, {11, 5, FREG}}, IMPL64}, - {0xfc00065e, "fctidz", {{21, 5, FREG}, {11, 5, FREG}}, IMPL64}, - {0xfc00065f, "fctidz.", {{21, 5, FREG}, {11, 5, FREG}}, IMPL64}, - {0xfc00001c, "fctiw", {{21, 5, FREG}, {11, 5, FREG}}}, - {0xfc00001d, "fctiw.", {{21, 5, FREG}, {11, 5, FREG}}}, - {0xfc00001e, "fctiwz", {{21, 5, FREG}, {11, 5, FREG}}}, - {0xfc00001f, "fctiwz.", {{21, 5, FREG}, {11, 5, FREG}}}, - {0xfc00069c, "fcfid", {{21, 5, FREG}, {11, 5, FREG}}, IMPL64}, - {0xfc00069d, "fcfid.", {{21, 5, FREG}, {11, 5, FREG}}, IMPL64}, - - {0xfc000000, "fcmpu", {{21, 5, CRFONLY}, {16, 5, FREG}, {11, 5, FREG}}}, - {0xfc000000, "fcmpu", {{23, 3, NUM}, {16, 5, FREG}, {11, 5, FREG}}}, - {0xfc000040, "fcmpo", {{21, 5, CRFONLY}, {16, 5, FREG}, {11, 5, FREG}}}, - {0xfc000040, "fcmpo", {{23, 3, NUM}, {16, 5, FREG}, {11, 5, FREG}}}, - {0xfc00048e, "mffs", {{21, 5, FREG}}}, - {0xfc00048f, "mffs.", {{21, 5, FREG}}}, - {0xfc000080, "mcrfs", {{21, 5, CRFONLY}, {18, 5, NUM}}}, - {0xfc000080, "mcrfs", {{23, 3, NUM}, {18, 5, NUM}}}, - {0xfc00010c, "mtfsfi", {{23, 3, NUM}, {12, 4, NUM}}}, - {0xfc00010d, "mtfsfi.", {{23, 3, NUM}, {12, 4, NUM}}}, - {0xfc00058e, "mtfsf", {{17, 8, NUM}, {11, 5, FREG}}}, - {0xfc00058f, "mtfsf.", {{17, 8, NUM}, {11, 5, FREG}}}, - {0xfc00008c, "mtfsb0", {{21, 5, NUM}}}, - {0xfc00008d, "mtfsb0.", {{21, 5, NUM}}}, - {0xfc00004c, "mtfsb1", {{21, 5, NUM}}}, - {0xfc00004d, "mtfsb1.", {{21, 5, NUM}}}, - - {0x88000000, "lbz", {{21, 5, GREG}, {0, 16, D}, {16, 5, G0REG}}}, - {0x7c0000ae, "lbzx", {{21, 5, GREG}, {16, 5, G0REG}, {11, 5, GREG}}}, - {0x8c000000, "lbzu", {{21, 5, GREG}, {0, 16, D}, {16, 5, G0REG}}}, - {0x7c0000ee, "lbzux", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0xa0000000, "lhz", {{21, 5, GREG}, {0, 16, D}, {16, 5, G0REG}}}, - {0x7c00022e, "lhzx", {{21, 5, GREG}, {16, 5, G0REG}, {11, 5, GREG}}}, - {0xa4000000, "lhzu", {{21, 5, GREG}, {0, 16, D}, {16, 5, G0REG}}}, - {0x7c00026e, "lhzux", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0xa8000000, "lha", {{21, 5, GREG}, {0, 16, D}, {16, 5, G0REG}}}, - {0x7c0002ae, "lhax", {{21, 5, GREG}, {16, 5, G0REG}, {11, 5, GREG}}}, - {0xac000000, "lhau", {{21, 5, GREG}, {0, 16, D}, {16, 5, GREG}}}, - {0x7c0002ee, "lhaux", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x80000000, "lwz", {{21, 5, GREG}, {0, 16, D}, {16, 5, G0REG}}}, - {0x7c00002e, "lwzx", {{21, 5, GREG}, {16, 5, G0REG}, {11, 5, GREG}}}, - {0x84000000, "lwzu", {{21, 5, GREG}, {0, 16, D}, {16, 5, GREG}}}, - {0x7c00006e, "lwzux", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0xe8000002, "lwa", {{21, 5, GREG}, {2, 14, DS}, {16, 5, G0REG}}, IMPL64}, - {0x7c0002aa, "lwax", {{21, 5, GREG}, {16, 5, G0REG}, {11, 5, GREG}}, IMPL64}, - {0x7c0002ea, "lwaux", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - {0xe8000000, "ld", {{21, 5, GREG}, {2, 14, DS}, {16, 5, G0REG}}, IMPL64}, - {0x7c00002a, "ldx", {{21, 5, GREG}, {16, 5, G0REG}, {11, 5, GREG}}, IMPL64}, - {0xe8000001, "ldu", {{21, 5, GREG}, {2, 14, DS}, {16, 5, GREG}}, IMPL64}, - {0x7c00006a, "ldux", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - - {0xb8000000, "lmw", {{21, 5, GREG}, {0, 16, D}, {16, 5, G0REG}}}, - {0xbc000000, "stmw", {{21, 5, GREG}, {0, 16, D}, {16, 5, G0REG}}}, - - {0x7c00062c, "lhbrx", {{21, 5, GREG}, {16, 5, G0REG}, {11, 5, GREG}}}, - {0x7c00042c, "lwbrx", {{21, 5, GREG}, {16, 5, G0REG}, {11, 5, GREG}}}, - {0x7c00042a, "lswx", {{21, 5, GREG}, {16, 5, G0REG}, {11, 5, GREG}}}, - {0x7c000028, "lwarx", {{21, 5, GREG}, {16, 5, G0REG}, {11, 5, GREG}}}, - {0x7c0000a8, "ldarx", {{21, 5, GREG}, {16, 5, G0REG}, {11, 5, GREG}}, IMPL64}, - - {0x7c00022a, "lscbx", {{21, 5, GREG}, {16, 5, G0REG}, {11, 5, GREG}}, CPU601}, - {0x7c00022b, "lscbx.", {{21, 5, GREG}, {16, 5, G0REG}, {11, 5, GREG}}, CPU601}, - - {0x7c0004aa, "lswi", {{21, 5, GREG}, {16, 5, G0REG}, {11, 5, NUM0}}}, - - {0xc0000000, "lfs", {{21, 5, FREG}, {0, 16, D}, {16, 5, G0REG}}}, - {0xc4000000, "lfsu", {{21, 5, FREG}, {0, 16, D}, {16, 5, GREG}}}, - {0x7c00042e, "lfsx", {{21, 5, FREG}, {16, 5, G0REG}, {11, 5, GREG}}}, - {0x7c00046e, "lfsux", {{21, 5, FREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0xc8000000, "lfd", {{21, 5, FREG}, {0, 16, D}, {16, 5, G0REG}}}, - {0xcc000000, "lfdu", {{21, 5, FREG}, {0, 16, D}, {16, 5, GREG}}}, - {0x7c0004ae, "lfdx", {{21, 5, FREG}, {16, 5, G0REG}, {11, 5, GREG}}}, - {0x7c0004ee, "lfdux", {{21, 5, FREG}, {16, 5, GREG}, {11, 5, GREG}}}, - - {0x38000000, "la", {{21, 5, GREG}, {0, 16, D}, {16, 5, G0REG}}}, - - {0x4c000000, "mcrf", {{21, 5, CRFONLY}, {16, 5, CRFONLY}}}, - {0x4c000000, "mcrf", {{23, 3, NUM}, {18, 3, NUM}}}, - - {0x7c0002a6, "mfspr", {{21, 5, GREG}, {11, 10, SPREG}}}, - {0x7c0003a6, "mtspr", {{11, 10, SPREG}, {21, 5, GREG}}}, - {0x7c000120, "mtcrf", {{12, 8, FXM}, {21, 5, GREG}}}, - {0x7c000120, "mtocrf", {{12, 8, FXM}, {21, 5, GREG}}}, - {0x7c000400, "mcrxr", {{21, 5, CRFONLY}}}, - {0x7c000400, "mcrxr", {{23, 3, NUM}}}, - {0x7c000026, "mfcr", {{21, 5, GREG}}}, - {0x7c100026, "mfcr", {{21, 5, GREG}, {12, 8, FXM}}}, - {0x7c100026, "mfocrf", {{21, 5, GREG}, {12, 8, FXM}}}, - - /* Move to/from spr mnemonics (assember extended mnemonics) */ - {0x7c0102a6, "mfxer", {{21, 5, GREG}}}, - {0x7c0802a6, "mflr", {{21, 5, GREG}}}, - {0x7c0902a6, "mfctr", {{21, 5, GREG}}}, - {0x7c0103a6, "mtxer", {{21, 5, GREG}}}, - {0x7c0803a6, "mtlr", {{21, 5, GREG}}}, - {0x7c0903a6, "mtctr", {{21, 5, GREG}}}, - {0x7c0002a6, "mfmq", {{21, 5, GREG}}}, - {0x7c0502a6, "mfrtcl", {{21, 5, GREG}}}, - {0x7c0402a6, "mfrtcu", {{21, 5, GREG}}}, - {0x7c0003a6, "mtmq", {{21, 5, GREG}}}, - {0x7c1503a6, "mtrtcl", {{21, 5, GREG}}}, - {0x7c1403a6, "mtrtcu", {{21, 5, GREG}}}, - -#ifdef NRW_COMPILER - {0x7c0001d6, "mull", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c0001d7, "mull.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c0005d6, "mullo", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c0005d7, "mullo.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, -#endif /* NRW_COMPILER */ - {0x7c0001d6, "mullw", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c0001d7, "mullw.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c0005d6, "mullwo", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c0005d7, "mullwo.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - - {0x7c000092, "mulhd", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - {0x7c000093, "mulhd.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - -#ifdef NRW_COMPILER - {0x7c000096, "mulwd", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000097, "mulwd.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, -#endif /* NRW_COMPILER */ - {0x7c000096, "mulhw", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000097, "mulhw.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - - {0x7c000012, "mulhdu", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - {0x7c000013, "mulhdu.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - - {0x7c000016, "mulhwu", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000017, "mulhwu.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - - {0x7c0001d2, "mulld", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - {0x7c0001d3, "mulld.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - {0x7c0005d2, "mulldo", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - {0x7c0005d3, "mulldo.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - - {0x7c0003b8, "nand", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}}, - {0x7c0003b9, "nand.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}}, - - {0x7c0000d0, "neg", {{21, 5, GREG}, {16, 5, GREG}}}, - {0x7c0000d1, "neg.", {{21, 5, GREG}, {16, 5, GREG}}}, - {0x7c0004d0, "nego", {{21, 5, GREG}, {16, 5, GREG}}}, - {0x7c0004d1, "nego.", {{21, 5, GREG}, {16, 5, GREG}}}, - - {0x7c0000f8, "nor", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}}, - {0x7c0000f9, "nor.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}}, - - /* Miscellaneous mnemonics (assember extended mnemonics) */ - { - 0x60000000, - "nop", - }, - - {0x60000000, "ori", {{16, 5, GREG}, {21, 5, GREG}, {0, 16, UI}}}, - {0x60000000, "ori", {{16, 5, ZERO}, {21, 5, ZERO}, {0, 16, ZERO}}}, - {0x64000000, "oris", {{16, 5, GREG}, {21, 5, GREG}, {0, 16, UI}}}, - {0x7c000378, "or", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}}, - {0x7c000379, "or.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}}, - - /// @brief Move register - {0x7c000378, "mr", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}}, - - {0x7c000338, "orc", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}}, - {0x7c000339, "orc.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}}, - - {0x78000000, "rldicl", {{16, 5, GREG}, {21, 5, GREG}, {0, 0, sh}, {0, 0, mb}}, IMPL64}, - {0x78000001, "rldicl.", {{16, 5, GREG}, {21, 5, GREG}, {0, 0, sh}, {0, 0, mb}}, IMPL64}, - {0x78000004, "rldicr", {{16, 5, GREG}, {21, 5, GREG}, {0, 0, sh}, {0, 0, mb}}, IMPL64}, - {0x78000005, "rldicr.", {{16, 5, GREG}, {21, 5, GREG}, {0, 0, sh}, {0, 0, mb}}, IMPL64}, - {0x78000008, "rldic", {{16, 5, GREG}, {21, 5, GREG}, {0, 0, sh}, {0, 0, mb}}, IMPL64}, - {0x78000009, "rldic.", {{16, 5, GREG}, {21, 5, GREG}, {0, 0, sh}, {0, 0, mb}}, IMPL64}, - {0x7800000c, "rldimi", {{16, 5, GREG}, {21, 5, GREG}, {0, 0, sh}, {0, 0, mb}}, IMPL64}, - {0x7800000d, "rldimi.", {{16, 5, GREG}, {21, 5, GREG}, {0, 0, sh}, {0, 0, mb}}, IMPL64}, - {0x78000010, "rldcl", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}, {0, 0, mb}}, IMPL64}, - {0x78000011, "rldcl.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}, {0, 0, mb}}, IMPL64}, - {0x78000012, "rldcr", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}, {0, 0, mb}}, IMPL64}, - {0x78000013, "rldcr.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}, {0, 0, mb}}, IMPL64}, - - {0x54000000, "rlwinm", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, NUM0}, {6, 5, MBE}, {1, 5, MBE}}}, - {0x54000001, - "rlwinm.", - {{16, 5, GREG}, {21, 5, GREG}, {11, 5, NUM0}, {6, 5, MBE}, {1, 5, MBE}}}, - {0x5c000000, "rlwnm", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}, {6, 5, MBE}, {1, 5, MBE}}}, - {0x5c000001, "rlwnm.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}, {6, 5, MBE}, {1, 5, MBE}}}, - {0x50000000, "rlwimi", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, NUM0}, {6, 5, MBE}, {1, 5, MBE}}}, - {0x50000001, - "rlwimi.", - {{16, 5, GREG}, {21, 5, GREG}, {11, 5, NUM0}, {6, 5, MBE}, {1, 5, MBE}}}, - - { - 0x44000002, - "sc", - }, - {0x4c000024, "rfid", {{0}}, IMPL64 | OPTIONAL}, - - {0x7c000030, "slw", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}}, - {0x7c000031, "slw.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}}, - {0x7c000036, "sld", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}, IMPL64}, - {0x7c000037, "sld.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}, IMPL64}, - - {0x7c000430, "srw", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}}, - {0x7c000431, "srw.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}}, - {0x7c000436, "srd", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}, IMPL64}, - {0x7c000437, "srd.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}, IMPL64}, - - {0x7c000670, "srawi", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, NUM}}}, - {0x7c000671, "srawi.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, NUM}}}, - {0x7c000674, "sradi", {{16, 5, GREG}, {21, 5, GREG}, {0, 0, sh}}, IMPL64}, - {0x7c000675, "sradi.", {{16, 5, GREG}, {21, 5, GREG}, {0, 0, sh}}, IMPL64}, - - {0x7c000630, "sraw", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}}, - {0x7c000631, "sraw.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}}, - {0x7c000634, "srad", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}, IMPL64}, - {0x7c000635, "srad.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}, IMPL64}, - - {0x98000000, "stb", {{21, 5, GREG}, {0, 16, D}, {16, 5, G0REG}}}, - {0x9c000000, "stbu", {{21, 5, GREG}, {0, 16, D}, {16, 5, GREG}}}, - {0x7c0001ae, "stbx", {{21, 5, GREG}, {16, 5, G0REG}, {11, 5, GREG}}}, - {0x7c0001ee, "stbux", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0xb0000000, "sth", {{21, 5, GREG}, {0, 16, D}, {16, 5, G0REG}}}, - {0xb4000000, "sthu", {{21, 5, GREG}, {0, 16, D}, {16, 5, GREG}}}, - {0x7c00032e, "sthx", {{21, 5, GREG}, {16, 5, G0REG}, {11, 5, GREG}}}, - {0x7c00036e, "sthux", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x90000000, "stw", {{21, 5, GREG}, {0, 16, D}, {16, 5, G0REG}}}, - {0x94000000, "stwu", {{21, 5, GREG}, {0, 16, D}, {16, 5, GREG}}}, - {0x7c00012e, "stwx", {{21, 5, GREG}, {16, 5, G0REG}, {11, 5, GREG}}}, - {0x7c00016e, "stwux", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0xf8000000, "std", {{21, 5, GREG}, {2, 14, DS}, {16, 5, G0REG}}, IMPL64}, - {0xf8000001, "stdu", {{21, 5, GREG}, {2, 14, DS}, {16, 5, GREG}}, IMPL64}, - {0x7c00012a, "stdx", {{21, 5, GREG}, {16, 5, G0REG}, {11, 5, GREG}}, IMPL64}, - {0x7c00016a, "stdux", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - - {0x7c00072c, "sthbrx", {{21, 5, GREG}, {16, 5, G0REG}, {11, 5, GREG}}}, - {0x7c00052c, "stwbrx", {{21, 5, GREG}, {16, 5, G0REG}, {11, 5, GREG}}}, - {0x7c00052a, "stswx", {{21, 5, GREG}, {16, 5, G0REG}, {11, 5, GREG}}}, - {0x7c00012d, "stwcx.", {{21, 5, GREG}, {16, 5, G0REG}, {11, 5, GREG}}}, - {0x7c0001ad, "stdcx.", {{21, 5, GREG}, {16, 5, G0REG}, {11, 5, GREG}}, IMPL64}, - - {0x7c0005aa, "stswi", {{21, 5, GREG}, {16, 5, G0REG}, {11, 5, NUM0}}}, - - { - 0x7c0007ae, - "stfiwx", - {{21, 5, FREG}, {16, 5, G0REG}, {11, 5, GREG}}, - }, - - {0xd0000000, "stfs", {{21, 5, FREG}, {0, 16, D}, {16, 5, G0REG}}}, - {0xd4000000, "stfsu", {{21, 5, FREG}, {0, 16, D}, {16, 5, GREG}}}, - {0x7c00052e, "stfsx", {{21, 5, FREG}, {16, 5, G0REG}, {11, 5, GREG}}}, - {0x7c00056e, "stfsux", {{21, 5, FREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0xd8000000, "stfd", {{21, 5, FREG}, {0, 16, D}, {16, 5, G0REG}}}, - {0xdc000000, "stfdu", {{21, 5, FREG}, {0, 16, D}, {16, 5, GREG}}}, - {0x7c0005ae, "stfdx", {{21, 5, FREG}, {16, 5, G0REG}, {11, 5, GREG}}}, - {0x7c0005ee, "stfdux", {{21, 5, FREG}, {16, 5, GREG}, {11, 5, GREG}}}, - - {0x20000000, "subfic", {{21, 5, GREG}, {16, 5, GREG}, {0, 16, SI}}}, - {0x7c000050, "sub", {{21, 5, GREG}, {11, 5, GREG}, {16, 5, GREG}}}, - {0x7c000051, "sub.", {{21, 5, GREG}, {11, 5, GREG}, {16, 5, GREG}}}, - {0x7c000450, "subo", {{21, 5, GREG}, {11, 5, GREG}, {16, 5, GREG}}}, - {0x7c000451, "subo.", {{21, 5, GREG}, {11, 5, GREG}, {16, 5, GREG}}}, - {0x7c000050, "subf", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000051, "subf.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000450, "subfo", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000451, "subfo.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - - {0x7c000010, "subc", {{21, 5, GREG}, {11, 5, GREG}, {16, 5, GREG}}}, - {0x7c000011, "subc.", {{21, 5, GREG}, {11, 5, GREG}, {16, 5, GREG}}}, - {0x7c000410, "subco", {{21, 5, GREG}, {11, 5, GREG}, {16, 5, GREG}}}, - {0x7c000411, "subco.", {{21, 5, GREG}, {11, 5, GREG}, {16, 5, GREG}}}, - {0x7c000010, "subfc", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000011, "subfc.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000410, "subfco", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000411, "subfco.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - - {0x7c000110, "subfe", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000111, "subfe.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000510, "subfeo", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000511, "subfeo.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}}, - - {0x7c0001d0, "subfme", {{21, 5, GREG}, {16, 5, GREG}}}, - {0x7c0001d1, "subfme.", {{21, 5, GREG}, {16, 5, GREG}}}, - {0x7c0005d0, "subfmeo", {{21, 5, GREG}, {16, 5, GREG}}}, - {0x7c0005d1, "subfmeo.", {{21, 5, GREG}, {16, 5, GREG}}}, - - {0x7c000190, "subfze", {{21, 5, GREG}, {16, 5, GREG}}}, - {0x7c000191, "subfze.", {{21, 5, GREG}, {16, 5, GREG}}}, - {0x7c000590, "subfzeo", {{21, 5, GREG}, {16, 5, GREG}}}, - {0x7c000591, "subfzeo.", {{21, 5, GREG}, {16, 5, GREG}}}, - - { - 0x7c0004ac, - "sync", - }, - {0x7c0004ac, "sync", {{21, 2, NUM}}}, - { - 0x7c2004ac, - "lwsync", - }, - { - 0x7c4004ac, - "ptesync", - }, - - {0x08000000, "tdi", {{21, 5, NUM}, {16, 5, GREG}, {0, 16, SI}}, IMPL64}, - {0x0a000000, "tdlti", {{16, 5, GREG}, {0, 16, SI}}, IMPL64}, - {0x0a800000, "tdlei", {{16, 5, GREG}, {0, 16, SI}}, IMPL64}, - {0x08800000, "tdeqi", {{16, 5, GREG}, {0, 16, SI}}, IMPL64}, - {0x09800000, "tdgei", {{16, 5, GREG}, {0, 16, SI}}, IMPL64}, - {0x09000000, "tdgti", {{16, 5, GREG}, {0, 16, SI}}, IMPL64}, - {0x09800000, "tdnli", {{16, 5, GREG}, {0, 16, SI}}, IMPL64}, - {0x0b000000, "tdnei", {{16, 5, GREG}, {0, 16, SI}}, IMPL64}, - {0x0a800000, "tdngi", {{16, 5, GREG}, {0, 16, SI}}, IMPL64}, - {0x08400000, "tdllti", {{16, 5, GREG}, {0, 16, SI}}, IMPL64}, - {0x08c00000, "tdllei", {{16, 5, GREG}, {0, 16, SI}}, IMPL64}, - {0x08a00000, "tdlgei", {{16, 5, GREG}, {0, 16, SI}}, IMPL64}, - {0x08200000, "tdlgti", {{16, 5, GREG}, {0, 16, SI}}, IMPL64}, - {0x08a00000, "tdlnli", {{16, 5, GREG}, {0, 16, SI}}, IMPL64}, - {0x08c00000, "tdlngi", {{16, 5, GREG}, {0, 16, SI}}, IMPL64}, - - {0x7c000088, "td", {{21, 5, NUM}, {16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - {0x7e000088, "tdlt", {{16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - {0x7e800088, "tdle", {{16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - {0x7c800088, "tdeq", {{16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - {0x7d800088, "tdge", {{16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - {0x7d000088, "tdgt", {{16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - {0x7d800088, "tdnl", {{16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - {0x7f000088, "tdne", {{16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - {0x7e800088, "tdng", {{16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - {0x7c400088, "tdllt", {{16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - {0x7cc00088, "tdlle", {{16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - {0x7ca00088, "tdlge", {{16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - {0x7c200088, "tdlgt", {{16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - {0x7ca00088, "tdlnl", {{16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - {0x7cc00088, "tdlng", {{16, 5, GREG}, {11, 5, GREG}}, IMPL64}, - - {0x0c000000, "twi", {{21, 5, NUM}, {16, 5, GREG}, {0, 16, SI}}}, - {0x0e000000, "twlti", {{16, 5, GREG}, {0, 16, SI}}}, - {0x0e800000, "twlei", {{16, 5, GREG}, {0, 16, SI}}}, - {0x0c800000, "tweqi", {{16, 5, GREG}, {0, 16, SI}}}, - {0x0d800000, "twgei", {{16, 5, GREG}, {0, 16, SI}}}, - {0x0d000000, "twgti", {{16, 5, GREG}, {0, 16, SI}}}, - {0x0d800000, "twnli", {{16, 5, GREG}, {0, 16, SI}}}, - {0x0f000000, "twnei", {{16, 5, GREG}, {0, 16, SI}}}, - {0x0e800000, "twngi", {{16, 5, GREG}, {0, 16, SI}}}, - {0x0c400000, "twllti", {{16, 5, GREG}, {0, 16, SI}}}, - {0x0cc00000, "twllei", {{16, 5, GREG}, {0, 16, SI}}}, - {0x0ca00000, "twlgei", {{16, 5, GREG}, {0, 16, SI}}}, - {0x0c200000, "twlgti", {{16, 5, GREG}, {0, 16, SI}}}, - {0x0ca00000, "twlnli", {{16, 5, GREG}, {0, 16, SI}}}, - {0x0cc00000, "twlngi", {{16, 5, GREG}, {0, 16, SI}}}, - - {0x7c000008, "tw", {{21, 5, NUM}, {16, 5, GREG}, {11, 5, GREG}}}, - {0x7c000008, "tw", {{21, 5, NUM}, {16, 5, ZERO}, {11, 5, ZERO}}}, - {0x7e000008, "twlt", {{16, 5, GREG}, {11, 5, GREG}}}, - {0x7e800008, "twle", {{16, 5, GREG}, {11, 5, GREG}}}, - {0x7c800008, "tweq", {{16, 5, GREG}, {11, 5, GREG}}}, - {0x7d800008, "twge", {{16, 5, GREG}, {11, 5, GREG}}}, - {0x7d000008, "twgt", {{16, 5, GREG}, {11, 5, GREG}}}, - {0x7d800008, "twnl", {{16, 5, GREG}, {11, 5, GREG}}}, - {0x7f000008, "twne", {{16, 5, GREG}, {11, 5, GREG}}}, - {0x7e800008, "twng", {{16, 5, GREG}, {11, 5, GREG}}}, - {0x7c400008, "twllt", {{16, 5, GREG}, {11, 5, GREG}}}, - {0x7cc00008, "twlle", {{16, 5, GREG}, {11, 5, GREG}}}, - {0x7ca00008, "twlge", {{16, 5, GREG}, {11, 5, GREG}}}, - {0x7c200008, "twlgt", {{16, 5, GREG}, {11, 5, GREG}}}, - {0x7ca00008, "twlnl", {{16, 5, GREG}, {11, 5, GREG}}}, - {0x7cc00008, "twlng", {{16, 5, GREG}, {11, 5, GREG}}}, - { - 0x7fe00008, - "trap", - }, - - {0x68000000, "xori", {{16, 5, GREG}, {21, 5, GREG}, {0, 16, UI}}}, - {0x6c000000, "xoris", {{16, 5, GREG}, {21, 5, GREG}, {0, 16, UI}}}, - {0x7c000278, "xor", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}}, - {0x7c000279, "xor.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}}, - - /* Cache Management Instructions (from book II) */ - {0x7c0007ac, "icbi", {{16, 5, G0REG}, {11, 5, GREG}}}, - { - 0x4c00012c, - "isync", - }, - {0x7c00022c, "dcbt", {{16, 5, G0REG}, {11, 5, GREG}}}, - { - 0x7c00022c, - "dcbt", - {{16, 5, G0REG}, {11, 5, GREG}, {21, 4, NUM}}, - }, - {0x7c0001ec, "dcbtst", {{16, 5, G0REG}, {11, 5, GREG}}}, - {0x7c00022c, "dcbt128", {{16, 5, G0REG}, {11, 5, GREG}, {21, 4, NUM}}, IMPL64 | OPTIONAL}, - {0x7c0007ec, "dcbz", {{16, 5, G0REG}, {11, 5, GREG}}}, - {0x7c2007ec, "dcbzl", {{16, 5, G0REG}, {11, 5, GREG}}}, - {0x7c2007ec, "dcbz128", {{16, 5, G0REG}, {11, 5, GREG}}, IMPL64 | OPTIONAL}, - {0x7c00006c, "dcbst", {{16, 5, G0REG}, {11, 5, GREG}}}, - {0x7c0000ac, "dcbf", {{16, 5, G0REG}, {11, 5, GREG}}}, - {0x7c00026c, "eciwx", {{21, 5, GREG}, {16, 5, G0REG}, {11, 5, GREG}}, OPTIONAL | CPU970}, - {0x7c00036c, "ecowx", {{21, 5, GREG}, {16, 5, G0REG}, {11, 5, GREG}}, OPTIONAL | CPU970}, - { - 0x7c0006ac, - "eieio", - }, - /* Instructions (from book III) */ - { - 0x4c000064, - "rfi", - }, - {0x7c000124, "mtmsr", {{21, 5, GREG}}}, - {0x7c000164, "mtmsrd", {{21, 5, GREG}}, IMPL64 | OPTIONAL}, - {0x7c000164, "mtmsrd", {{21, 5, GREG}, {16, 1, NUM}}, IMPL64 | OPTIONAL}, - {0x7c0000a6, "mfmsr", {{21, 5, GREG}}}, - {0x7c0005ec, "dcba", {{16, 5, G0REG}, {11, 5, GREG}}, OPTIONAL}, - {0x7c0003ac, "dcbi", {{16, 5, G0REG}, {11, 5, GREG}}}, - {0x7c0001a4, "mtsr", {{16, 4, SGREG}, {21, 5, GREG}}}, - {0x7c0004a6, "mfsr", {{21, 5, GREG}, {16, 4, SGREG}}}, - {0x7c0001e4, "mtsrin", {{21, 5, GREG}, {11, 5, GREG}}}, - {0x7c000526, "mfsrin", {{21, 5, GREG}, {11, 5, GREG}}}, - {0x7c000364, "slbie", {{11, 5, GREG}}, IMPL64 | OPTIONAL}, - {0x7c0003e4, "slbia", {{0}}, IMPL64 | OPTIONAL}, - {0x7c000324, "slbmte", {{21, 5, GREG}, {11, 5, GREG}}, IMPL64 | OPTIONAL}, - {0x7c0006a6, "slbmfev", {{21, 5, GREG}, {11, 5, GREG}}, IMPL64 | OPTIONAL}, - {0x7c000726, "slbmfee", {{21, 5, GREG}, {11, 5, GREG}}, IMPL64 | OPTIONAL}, - {0x7c000264, "tlbie", {{11, 5, GREG}}, OPTIONAL | CPU970}, - {0x7c000264, "tlbie", {{11, 5, GREG}, {21, 1, NUM}}, IMPL64 | OPTIONAL | CPU970}, - {0x7c000224, "tlbiel", {{11, 5, GREG}}, IMPL64 | OPTIONAL}, - {0x7c0002e4, "tlbia", {{0}}, OPTIONAL | CPU970}, - {0x7c00046c, "tlbsync", {{0}}, OPTIONAL | CPU970}, - {0x7c1c43a6, "mttbl", {{21, 5, GREG}}}, - {0x7c1d43a6, "mttbu", {{21, 5, GREG}}}, - {0x7c0002e6, "mftb", {{21, 5, GREG}, {11, 10, SPREG}}}, - {0x7c0c42e6, "mftb", {{21, 5, GREG}}}, - {0x7c0d42e6, "mftbu", {{21, 5, GREG}}}, - {0x00000200, "attn", {{11, 15, NUM}}, OPTIONAL | CPU970}, - - /* Instructions (from book IV) */ - {0x24000000, "dozi", {{21, 5, GREG}, {16, 5, GREG}, {0, 16, SI}}, CPU601}, - {0x7c000210, "doz", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, CPU601}, - {0x7c000211, "doz.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, CPU601}, - {0x7c000610, "dozo", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, CPU601}, - {0x7c000611, "dozo.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, CPU601}, - - {0x7c0002d0, "abs", {{21, 5, GREG}, {16, 5, GREG}}, CPU601}, - {0x7c0002d1, "abs.", {{21, 5, GREG}, {16, 5, GREG}}, CPU601}, - {0x7c0006d0, "abso", {{21, 5, GREG}, {16, 5, GREG}}, CPU601}, - {0x7c0006d1, "abso.", {{21, 5, GREG}, {16, 5, GREG}}, CPU601}, - - {0x7c0003d0, "nabs", {{21, 5, GREG}, {16, 5, GREG}}, CPU601}, - {0x7c0003d1, "nabs.", {{21, 5, GREG}, {16, 5, GREG}}, CPU601}, - {0x7c0007d0, "nabso", {{21, 5, GREG}, {16, 5, GREG}}, CPU601}, - {0x7c0007d1, "nabso.", {{21, 5, GREG}, {16, 5, GREG}}, CPU601}, - - {0x1c000000, "mulli", {{21, 5, GREG}, {16, 5, GREG}, {0, 16, SI}}}, - - {0x7c0000d6, "mul", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, CPU601}, - {0x7c0000d7, "mul.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, CPU601}, - {0x7c0004d6, "mulo", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, CPU601}, - {0x7c0004d7, "mulo.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, CPU601}, - - {0x7c000296, "div", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, CPU601}, - {0x7c000297, "div.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, CPU601}, - {0x7c000696, "divo", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, CPU601}, - {0x7c000697, "divo.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, CPU601}, - - {0x7c0002d6, "divs", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, CPU601}, - {0x7c0002d7, "divs.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, CPU601}, - {0x7c0006d6, "divso", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, CPU601}, - {0x7c0006d7, "divso.", {{21, 5, GREG}, {16, 5, GREG}, {11, 5, GREG}}, CPU601}, - - {0x58000000, - "rlmi", - {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}, {6, 5, MBE}, {1, 5, MBE}}, - CPU601}, - {0x58000001, - "rlmi.", - {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}, {6, 5, MBE}, {1, 5, MBE}}, - CPU601}, - - {0x7c000432, "rrib", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}, CPU601}, - {0x7c000433, "rrib.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}, CPU601}, - - {0x7c00003a, "maskg", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}, CPU601}, - {0x7c00003b, "maskg.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}, CPU601}, - - {0x7c00043a, "maskir", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}, CPU601}, - {0x7c00043b, "maskir.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}, CPU601}, - - {0x7c000130, "slq", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}, CPU601}, - {0x7c000131, "slq.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}, CPU601}, - - {0x7c000530, "srq", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}, CPU601}, - {0x7c000531, "srq.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}, CPU601}, - - {0x7c000170, "sliq", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, NUM}}, CPU601}, - {0x7c000171, "sliq.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, NUM}}, CPU601}, - - {0x7c000570, "sriq", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, NUM}}, CPU601}, - {0x7c000571, "sriq.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, NUM}}, CPU601}, - - {0x7c0001f0, "slliq", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, NUM}}, CPU601}, - {0x7c0001f1, "slliq.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, NUM}}, CPU601}, - - {0x7c0005f0, "srliq", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, NUM}}, CPU601}, - {0x7c0005f1, "srliq.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, NUM}}, CPU601}, - - {0x7c0001b0, "sllq", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}, CPU601}, - {0x7c0001b1, "sllq.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}, CPU601}, - - {0x7c0005b0, "srlq", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}, CPU601}, - {0x7c0005b1, "srlq.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}, CPU601}, - - {0x7c000132, "sle", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}, CPU601}, - {0x7c000133, "sle.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}, CPU601}, - - {0x7c000532, "sre", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}, CPU601}, - {0x7c000533, "sre.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}, CPU601}, - - {0x7c0001b2, "sleq", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}, CPU601}, - {0x7c0001b3, "sleq.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}, CPU601}, - - {0x7c0005b2, "sreq", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}, CPU601}, - {0x7c0005b3, "sreq.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}, CPU601}, - - {0x7c000770, "sraiq", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, NUM}}, CPU601}, - {0x7c000771, "sraiq.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, NUM}}, CPU601}, - - {0x7c000730, "sraq", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}, CPU601}, - {0x7c000731, "sraq.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}, CPU601}, - - {0x7c000732, "srea", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}, CPU601}, - {0x7c000733, "srea.", {{16, 5, GREG}, {21, 5, GREG}, {11, 5, GREG}}, CPU601}, - - /* Added from the POWER 601 book */ - {0x7c000426, "clcs", {{21, 5, GREG}, {16, 5, GREG}}, CPU601}, - - /* Added from the POWER 603 book. - * These are really 603 specific instructions but we mark them as OPTIONAL - * so that the -force_cpusubtype_ALL flag as to be used. This makes it so - * only 601 instructions will cause the cputype to be set to other an ALL. - */ - {0x7c0007a4, "tlbld", {{11, 5, GREG}}, OPTIONAL}, - {0x7c0007e4, "tlbli", {{11, 5, GREG}}, OPTIONAL}, - - /* VMX Instructions */ - {0x7c00000e, "lvebx", {{21, 5, VREG}, {16, 5, G0REG}, {11, 5, GREG}}, VMX}, - {0x7c00004e, "lvehx", {{21, 5, VREG}, {16, 5, G0REG}, {11, 5, GREG}}, VMX}, - {0x7c00008e, "lvewx", {{21, 5, VREG}, {16, 5, G0REG}, {11, 5, GREG}}, VMX}, - {0x7c0000ce, "lvx", {{21, 5, VREG}, {16, 5, G0REG}, {11, 5, GREG}}, VMX}, - {0x7c0002ce, "lvxl", {{21, 5, VREG}, {16, 5, G0REG}, {11, 5, GREG}}, VMX}, - - {0x7c00010e, "stvebx", {{21, 5, VREG}, {16, 5, G0REG}, {11, 5, GREG}}, VMX}, - {0x7c00014e, "stvehx", {{21, 5, VREG}, {16, 5, G0REG}, {11, 5, GREG}}, VMX}, - {0x7c00018e, "stvewx", {{21, 5, VREG}, {16, 5, G0REG}, {11, 5, GREG}}, VMX}, - {0x7c0001ce, "stvx", {{21, 5, VREG}, {16, 5, G0REG}, {11, 5, GREG}}, VMX}, - {0x7c0003ce, "stvxl", {{21, 5, VREG}, {16, 5, G0REG}, {11, 5, GREG}}, VMX}, - - {0x7c00000c, "lvsl", {{21, 5, VREG}, {16, 5, G0REG}, {11, 5, GREG}}, VMX}, - {0x7c00004c, "lvsr", {{21, 5, VREG}, {16, 5, G0REG}, {11, 5, GREG}}, VMX}, - - {0x10000644, "mtvscr", {{11, 5, VREG}}, VMX}, - {0x10000604, "mfvscr", {{21, 5, VREG}}, VMX}, - - {0x7c0002ac, "dst", {{16, 5, GREG}, {11, 5, GREG}, {21, 2, NUM}}, VMX}, - {0x7e0002ac, "dstt", {{16, 5, GREG}, {11, 5, GREG}, {21, 2, NUM}}, VMX}, - {0x7c0002ec, "dstst", {{16, 5, GREG}, {11, 5, GREG}, {21, 2, NUM}}, VMX}, - {0x7e0002ec, "dststt", {{16, 5, GREG}, {11, 5, GREG}, {21, 2, NUM}}, VMX}, - {0x7c00066c, "dss", {{21, 2, NUM}}, VMX}, - {0x7e00066c, "dssall", {{0}}, VMX}, - - {0x10000000, "vaddubm", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000200, "vaddubs", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000300, "vaddsbs", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000040, "vadduhm", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000240, "vadduhs", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000340, "vaddshs", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000080, "vadduwm", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000280, "vadduws", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000380, "vaddsws", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x1000000a, "vaddfp", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - - {0x10000180, "vaddcuw", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - - {0x10000400, "vsububm", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000600, "vsububs", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000700, "vsubsbs", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000440, "vsubuhm", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000640, "vsubuhs", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000740, "vsubshs", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000480, "vsubuwm", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000680, "vsubuws", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000780, "vsubsws", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x1000004a, "vsubfp", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - - {0x10000580, "vsubcuw", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - - {0x10000008, "vmuloub", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000108, "vmulosb", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000048, "vmulouh", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000148, "vmulosh", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - - {0x10000208, "vmuleub", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000308, "vmulesb", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000248, "vmuleuh", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000348, "vmulesh", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - - {0x10000020, "vmhaddshs", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}, {6, 5, VREG}}, VMX}, - {0x10000021, "vmhraddshs", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}, {6, 5, VREG}}, VMX}, - {0x10000022, "vmladduhm", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}, {6, 5, VREG}}, VMX}, - {0x1000002e, "vmaddfp", {{21, 5, VREG}, {16, 5, VREG}, {6, 5, VREG}, {11, 5, VREG}}, VMX}, - - {0x10000024, "vmsumubm", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}, {6, 5, VREG}}, VMX}, - {0x10000025, "vmsummbm", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}, {6, 5, VREG}}, VMX}, - {0x10000026, "vmsumuhm", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}, {6, 5, VREG}}, VMX}, - {0x10000027, "vmsumuhs", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}, {6, 5, VREG}}, VMX}, - {0x10000028, "vmsumshm", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}, {6, 5, VREG}}, VMX}, - {0x10000029, "vmsumshs", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}, {6, 5, VREG}}, VMX}, - - {0x10000788, "vsumsws", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - - {0x10000688, "vsum2sws", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - - {0x10000608, "vsum4ubs", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000708, "vsum4sbs", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000648, "vsum4shs", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - - {0x10000402, "vavgub", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000442, "vavguh", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000482, "vavguw", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000502, "vavgsb", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000542, "vavgsh", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000582, "vavgsw", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - - {0x10000404, "vand", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000484, "vor", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x100004c4, "vxor", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000444, "vandc", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000504, "vnor", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - - {0x10000004, "vrlb", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000044, "vrlh", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000084, "vrlw", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - - {0x10000104, "vslb", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000144, "vslh", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000184, "vslw", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x100001c4, "vsl", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - - {0x10000204, "vsrb", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000304, "vsrab", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000244, "vsrh", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000344, "vsrah", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000284, "vsrw", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000384, "vsraw", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x100002c4, "vsr", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - - {0x10000206, "vcmpgtub", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000606, "vcmpgtub.", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000306, "vcmpgtsb", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000706, "vcmpgtsb.", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000246, "vcmpgtuh", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000646, "vcmpgtuh.", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000346, "vcmpgtsh", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000746, "vcmpgtsh.", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000286, "vcmpgtuw", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000686, "vcmpgtuw.", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000386, "vcmpgtsw", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000786, "vcmpgtsw.", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x100002c6, "vcmpgtfp", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x100006c6, "vcmpgtfp.", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - - {0x10000006, "vcmpequb", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000406, "vcmpequb.", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000046, "vcmpequh", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000446, "vcmpequh.", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000086, "vcmpequw", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000486, "vcmpequw.", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x100000c6, "vcmpeqfp", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x100004c6, "vcmpeqfp.", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - - {0x100001c6, "vcmpgefp", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x100005c6, "vcmpgefp.", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - - {0x100003c6, "vcmpbfp", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x100007c6, "vcmpbfp.", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - - {0x1000002a, "vsel", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}, {6, 5, VREG}}, VMX}, - - {0x1000000e, "vpkuhum", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x1000008e, "vpkuhus", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x1000010e, "vpkshus", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x1000018e, "vpkshss", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x1000004e, "vpkuwum", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x100000ce, "vpkuwus", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x1000014e, "vpkswus", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x100001ce, "vpkswss", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x1000030e, "vpkpx", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - - {0x1000020e, "vupkhsb", {{21, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x1000024e, "vupkhsh", {{21, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x1000034e, "vupkhpx", {{21, 5, VREG}, {11, 5, VREG}}, VMX}, - - {0x1000028e, "vupklsb", {{21, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x100002ce, "vupklsh", {{21, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x100003ce, "vupklpx", {{21, 5, VREG}, {11, 5, VREG}}, VMX}, - - {0x1000000c, "vmrghb", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x1000004c, "vmrghh", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x1000008c, "vmrghw", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - - {0x1000010c, "vmrglb", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x1000014c, "vmrglh", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x1000018c, "vmrglw", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - - {0x1000020c, "vspltb", {{21, 5, VREG}, {11, 5, VREG}, {16, 5, NUM}}, VMX}, - {0x1000024c, "vsplth", {{21, 5, VREG}, {11, 5, VREG}, {16, 5, NUM}}, VMX}, - {0x1000028c, "vspltw", {{21, 5, VREG}, {11, 5, VREG}, {16, 5, NUM}}, VMX}, - - {0x1000030c, "vspltisb", {{21, 5, VREG}, {16, 5, SNUM}}, VMX}, - {0x1000034c, "vspltish", {{21, 5, VREG}, {16, 5, SNUM}}, VMX}, - {0x1000038c, "vspltisw", {{21, 5, VREG}, {16, 5, SNUM}}, VMX}, - - {0x1000002b, "vperm", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}, {6, 5, VREG}}, VMX}, - - {0x1000002c, "vsldoi", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}, {6, 4, NUM}}, VMX}, - - {0x1000040c, "vslo", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x1000044c, "vsro", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - - {0x10000002, "vmaxub", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000102, "vmaxsb", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000042, "vmaxuh", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000142, "vmaxsh", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000082, "vmaxuw", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000182, "vmaxsw", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x1000040a, "vmaxfp", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - - {0x10000202, "vminub", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000302, "vminsb", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000242, "vminuh", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000342, "vminsh", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000282, "vminuw", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x10000382, "vminsw", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x1000044a, "vminfp", {{21, 5, VREG}, {16, 5, VREG}, {11, 5, VREG}}, VMX}, - - {0x1000010a, "vrefp", {{21, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x1000014a, "vrsqrtefp", {{21, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x100001ca, "vlogefp", {{21, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x1000018a, "vexptefp", {{21, 5, VREG}, {11, 5, VREG}}, VMX}, - - {0x1000002f, "vnmsubfp", {{21, 5, VREG}, {16, 5, VREG}, {6, 5, VREG}, {11, 5, VREG}}, VMX}, - - {0x1000020a, "vrfin", {{21, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x1000024a, "vrfiz", {{21, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x1000028a, "vrfip", {{21, 5, VREG}, {11, 5, VREG}}, VMX}, - {0x100002ca, "vrfim", {{21, 5, VREG}, {11, 5, VREG}}, VMX}, - - {0x1000038a, "vctuxs", {{21, 5, VREG}, {11, 5, VREG}, {16, 5, NUM}}, VMX}, - {0x100003ca, "vctsxs", {{21, 5, VREG}, {11, 5, VREG}, {16, 5, NUM}}, VMX}, - - {0x1000030a, "vcfux", {{21, 5, VREG}, {11, 5, VREG}, {16, 5, NUM}}, VMX}, - {0x1000034a, "vcfsx", {{21, 5, VREG}, {11, 5, VREG}, {16, 5, NUM}}, VMX}, - - {0, ""} /* end of table marker */ -}; - -#define kAsmFloatZeroRegister 0 -#define kAsmZeroRegister 0 - -#define kAsmRegisterPrefix "r" -#define kAsmRegisterLimit 31 -#define kAsmPcRegister 17 -#define kAsmCrRegister 18 -#define kAsmSpRegister 5 - -/* return address register */ -#define kAsmRetRegister 19 diff --git a/src/CompilerKit/Detail/PreConfig.h b/src/CompilerKit/Detail/PreConfig.h deleted file mode 100644 index 6742c53..0000000 --- a/src/CompilerKit/Detail/PreConfig.h +++ /dev/null @@ -1,120 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license - -======================================== */ - -#pragma once - -#ifndef Yes -#define Yes true -#endif // ifndef Yes - -#ifndef No -#define No false -#endif // ifndef No - -#ifndef YES -#define YES true -#endif // ifndef YES - -#ifndef NO -#define NO false -#endif // ifndef NO - -#define SizeType size_t - -#define VoidPtr void* -#define voidPtr VoidPtr - -#define UIntPtr uintptr_t - -#define Int64 int64_t -#define UInt64 uint64_t - -#define Int32 int -#define UInt32 unsigned - -#define Int16 int16_t -#define UInt16 uint16_t - -#define Int8 int8_t -#define UInt8 uint8_t - -#define Char char - -#include <signal.h> -#include <stdint.h> -#include <time.h> -#include <unistd.h> -#include <cassert> -#include <string> - -#define kDistVersion "v0.0.7-compilerkit" -#define kDistVersionBCD 0x0002 - -#define ToString(X) Stringify(X) -#define Stringify(X) #X - -#define kDistRelease ToString(kDistReleaseBranch) - -#ifndef kDistRelease - -#define kDistVersion "v0.0.7-compilerkit" -#define kDistVersionBCD 0x0002 - -#define ToString(X) Stringify(X) -#define Stringify(X) #X - -#define kDistRelease ToString(kDistReleaseBranch) - -#endif // !kDistRelease - -#define MUST_PASS(E) assert(E) - -#ifndef __FORCE_STRLEN -#define __FORCE_STRLEN 1 - -#define string_length(len) strlen(len) -#endif - -#ifndef __FORCE_MEMCPY -#define __FORCE_MEMCPY 1 - -#define rt_copy_memory(dst, src, len) memcpy(dst, src, len) -#endif - -#define ATTRIBUTE(X) __attribute__((X)) -#define PACKED ATTRIBUTE(packed) - -#define kObjectFileExt ".obj" -#define kBinaryFileExt ".bin" - -#define kAsmFileExts {".64x", ".32x", ".masm", ".s", ".S", ".asm", ".x64"} - -#define kAsmFileExtsMax (7U) - -#define NECTI_MODULE(name) extern "C" int name(int argc, char** argv) - -#ifdef MSVC -#pragma scalar_storage_order big - endian -#endif // ifdef MSVC - -#define NECTI_COPY_DELETE(KLASS) \ - KLASS& operator=(const KLASS&) = delete; \ - KLASS(const KLASS&) = delete; - -#define NECTI_COPY_DEFAULT(KLASS) \ - KLASS& operator=(const KLASS&) = default; \ - KLASS(const KLASS&) = default; - -#define NECTI_MOVE_DELETE(KLASS) \ - KLASS& operator=(KLASS&&) = delete; \ - KLASS(KLASS&&) = delete; - -#define NECTI_MOVE_DEFAULT(KLASS) \ - KLASS& operator=(KLASS&&) = default; \ - KLASS(KLASS&&) = default; - -#define CK_IMPORT_C extern "C" -#define CK_IMPORT extern diff --git a/src/CompilerKit/ErrorID.h b/src/CompilerKit/ErrorID.h deleted file mode 100644 index 3e3b0d7..0000000 --- a/src/CompilerKit/ErrorID.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * ======================================================== - * - * CompilerKit - * Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license. - * - * ======================================================== - */ - -#pragma once - -#include <CompilerKit/Detail/Config.h> - -/// =========================================================== /// -/// @file ErrorID.h -/// @author Amlal El Mahrouss -/// @brief Error IDs for CompilerKit. -/// =========================================================== /// - -#define NECTI_SUCCESS 0 -#define NECTI_EXEC_ERROR -30 -#define NECTI_FILE_NOT_FOUND -31 -#define NECTI_DIR_NOT_FOUND -32 -#define NECTI_FILE_EXISTS -33 -#define NECTI_TOO_LONG -34 -#define NECTI_INVALID_DATA -35 -#define NECTI_UNIMPLEMENTED -36 -#define NECTI_FAT_ERROR -37 -#define NECTI_INVALID_ARCH -38 diff --git a/src/CompilerKit/ErrorOr.h b/src/CompilerKit/ErrorOr.h deleted file mode 100644 index 100624e..0000000 --- a/src/CompilerKit/ErrorOr.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * ======================================================== - * - * CompilerKit - * Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license. - * - * ======================================================== - */ - -#pragma once - -/// =========================================================== /// -/// @file ErrorOr.h -/// @author Amlal El Mahrouss -/// @brief ErrorOr for CompilerKit. -/// =========================================================== /// - -#include <CompilerKit/Detail/Config.h> -#include <CompilerKit/ErrorID.h> -#include <CompilerKit/Ref.h> - -namespace CompilerKit { -using ErrorT = Int32; - -template <typename T> -class ErrorOr final { - public: - ErrorOr() = default; - ~ErrorOr() = default; - - public: - explicit ErrorOr(ErrorT err) : mId(err) {} - explicit ErrorOr(std::nullptr_t null) {} - explicit ErrorOr(T klass) : mRef(klass) {} - - ErrorOr& operator=(const ErrorOr&) = default; - ErrorOr(const ErrorOr&) = default; - - Ref<T>& Leak() { return mRef; } - - ErrorT Error() { return mId; } - - bool HasError() { return mId != NECTI_SUCCESS; } - - explicit operator bool() { return mRef; } - - private: - Ref<T> mRef; - ErrorT mId{0}; -}; - -using ErrorOrAny = ErrorOr<VoidPtr>; -using ErrorOrString = ErrorOr<STLString>; -} // namespace CompilerKit diff --git a/src/CompilerKit/Macros.h b/src/CompilerKit/Macros.h deleted file mode 100644 index 6cef758..0000000 --- a/src/CompilerKit/Macros.h +++ /dev/null @@ -1,28 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license - -======================================== */ - -/// @brief provide support for Macros.h header. - -#ifndef _NECTI_MACROS_H_ -#define _NECTI_MACROS_H_ - -#define NECTI_COPY_DELETE(KLASS) \ - KLASS& operator=(const KLASS&) = delete; \ - KLASS(const KLASS&) = delete; - -#define NECTI_COPY_DEFAULT(KLASS) \ - KLASS& operator=(const KLASS&) = default; \ - KLASS(const KLASS&) = default; - -#define NECTI_MOVE_DELETE(KLASS) \ - KLASS& operator=(KLASS&&) = delete; \ - KLASS(KLASS&&) = delete; - -#define NECTI_MOVE_DEFAULT(KLASS) \ - KLASS& operator=(KLASS&&) = default; \ - KLASS(KLASS&&) = default; - -#endif /* ifndef _NECTI_MACROS_H_ */ diff --git a/src/CompilerKit/PEF.h b/src/CompilerKit/PEF.h deleted file mode 100644 index 2838f52..0000000 --- a/src/CompilerKit/PEF.h +++ /dev/null @@ -1,138 +0,0 @@ -/* ========================================= - - Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license - -======================================== */ - -#pragma once - -#include <CompilerKit/Detail/Config.h> -#include <fstream> - -// @file PEF.h -// @brief Preferred Executable Format - -#define kPefMagic "Open" -#define kPefMagicFat "nepO" - -#define kPefExt ".exec" -#define kPefDylibExt ".dylib" -#define kPefLibExt ".lib" -#define kPefObjectExt ".obj" -#define kPefDebugExt ".dbg" -#define kPefDriverExt ".sys" - -#define kPefZero128 ".zero128" -#define kPefCode128 ".code128" -#define kPefData128 ".data128" - -#define kPefZero64 ".zero64" -#define kPefCode64 ".code64" -#define kPefData64 ".data64" - -/* @note counting the \0 at the end */ -#define kPefMagicLen (5) - -#define kPefVersion (0x0500) -#define kPefNameLen (255) - -#define kPefBaseOrigin (0x40000000) - -/* @note this doesn't have to be __ImageStart only, any C initialization stub will do. */ -#define kPefStart "__ImageStart" - -namespace CompilerKit { -/* @brief Architecture type. */ -enum { - kPefArchIntel86S, - kPefArchAMD64, - kPefArchRISCV, - kPefArch64000, /* Open64x0 RISC architecture. */ - kPefArch32000, - kPefArchPowerPC, /* 64-bit POWER architecture. */ - kPefArchARM64, - kPefArchCount = (kPefArchARM64 - kPefArchIntel86S) + 1, - kPefArchInvalid = 0xFF, -}; - -/* @brief Architecture vendor. */ -enum { - kPefSubArchGeneric = 0, - kPefSubArchAMD = 200, - kPefSubArchIntel, - kPefSubArchARM, - kPefSubArchIBM, -}; - -enum { - kPefKindInvalid = 0, - kPefKindExec = 1, /* .exec */ - kPefKindDylib = 2, /* .dylib */ - kPefKindObject = 4, /* .obj */ - kPefKindDebug = 5, /* .dbg */ - kPefKindDriver = 6, - kPefKindCount, -}; - -/* PEF container information */ -typedef struct PEFContainer final { - Char Magic[kPefMagicLen]; - UInt32 Linker; /* Linker used to link executable */ - UInt32 Version; - UInt32 Kind; - UInt32 Abi; - UInt32 Cpu; - UInt32 SubCpu; /* Cpu specific information */ - UIntPtr Start; /* Origin of code */ - SizeType HdrSz; /* Size of header */ - SizeType Count; /* container header count */ - UInt32 Checksum; /* Whole binary checksum */ -} PACKED PEFContainer, *PEFContainerPtr; - -/* First PEFCommandHeader starts after PEFContainer */ -/* Last container is __exec_end */ - -/* PEF executable section and commands. */ - -/* @brief Command Header, a la Mach-O, designed with FAT binaries and virtual memory in mind. */ -typedef struct PEFCommandHeader final { - Char Name[kPefNameLen]; /* container name */ - UInt32 Cpu; /* container cpu */ - UInt32 SubCpu; /* container sub-cpu */ - UInt32 Flags; /* container flags */ - UInt16 Kind; /* container kind */ - UIntPtr Offset; /* File offset */ - SizeType OffsetSize; - UIntPtr VirtualAddress; /* Virtual Address */ - SizeType VirtualSize; /* Virtual Size */ -} PACKED PEFCommandHeader, *PEFCommandHeaderPtr; - -enum { - kPefInvalid = 0x0, - kPefCode = 0xC, - kPefData = 0xD, - kPefZero = 0xE, - kPefLinkerID = 0x1, - kPefCount = 4, -}; -} // namespace CompilerKit - -inline std::ofstream& operator<<(std::ofstream& fp, CompilerKit::PEFContainer& container) { - fp.write((char*) &container, sizeof(CompilerKit::PEFContainer)); - return fp; -} - -inline std::ofstream& operator<<(std::ofstream& fp, CompilerKit::PEFCommandHeader& container) { - fp.write((char*) &container, sizeof(CompilerKit::PEFCommandHeader)); - return fp; -} - -inline std::ifstream& operator>>(std::ifstream& fp, CompilerKit::PEFContainer& container) { - fp.read((char*) &container, sizeof(CompilerKit::PEFContainer)); - return fp; -} - -inline std::ifstream& operator>>(std::ifstream& fp, CompilerKit::PEFCommandHeader& container) { - fp.read((char*) &container, sizeof(CompilerKit::PEFCommandHeader)); - return fp; -} diff --git a/src/CompilerKit/Ref.h b/src/CompilerKit/Ref.h deleted file mode 100644 index 863a100..0000000 --- a/src/CompilerKit/Ref.h +++ /dev/null @@ -1,77 +0,0 @@ - -/* - * ======================================================== - * - * CompilerKit - * Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license. - * - * ======================================================== - */ - -#pragma once - -#include <CompilerKit/Detail/Config.h> - -namespace CompilerKit { -/// @author Amlal El Mahrouss -/// @brief Reference holder class, refers to a pointer of data in static memory. -template <typename T> -class Ref final { - public: - explicit Ref() = default; - - ~Ref() { - if (m_Strong) { - MUST_PASS(m_Class); - if (m_Class) delete m_Class; - m_Class = nullptr; - } - } - - NECTI_COPY_DEFAULT(Ref); - - public: - explicit Ref(T* cls, const bool& strong = false) : m_Class(cls), m_Strong(strong) {} - - Ref& operator=(T ref) { - *m_Class = ref; - return *this; - } - - public: - T* operator->() const { return m_Class; } - - T& Leak() { return *m_Class; } - - T operator*() { return *m_Class; } - - bool IsStrong() const { return m_Strong; } - - explicit operator bool() { return *m_Class; } - - private: - T* m_Class{nullptr}; - bool m_Strong{false}; -}; - -// @author Amlal El Mahrouss -// @brief Non null Reference holder class, refers to a pointer of data in static memory. -template <typename T> -class NonNullRef final { - public: - explicit NonNullRef() = delete; - - explicit NonNullRef(T* ref) : m_Ref(ref, true) {} - - Ref<T>& operator->() { - MUST_PASS(m_Ref); - return m_Ref; - } - - NonNullRef& operator=(const NonNullRef<T>& ref) = delete; - NonNullRef(const NonNullRef<T>& ref) = default; - - private: - Ref<T> m_Ref{nullptr}; -}; -} // namespace CompilerKit diff --git a/src/CompilerKit/UUID.h b/src/CompilerKit/UUID.h deleted file mode 100644 index 2993b8b..0000000 --- a/src/CompilerKit/UUID.h +++ /dev/null @@ -1,826 +0,0 @@ -#ifndef STDUUID_H -#define STDUUID_H - -#include <array> -#include <atomic> -#include <cctype> -#include <chrono> -#include <cstring> -#include <functional> -#include <iomanip> -#include <iterator> -#include <memory> -#include <numeric> -#include <optional> -#include <random> -#include <sstream> -#include <string> -#include <string_view> -#include <type_traits> - -#ifdef __cplusplus - -#if (__cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L) -#define LIBUUID_CPP20_OR_GREATER -#endif - -#endif - -#ifdef LIBUUID_CPP20_OR_GREATER -#include <span> -#else -#include <gsl/span> -#endif - -#ifdef _WIN32 - -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#ifndef NOMINMAX -#define NOMINMAX -#endif - -#ifdef UUID_SYSTEM_GENERATOR -#include <objbase.h> -#endif - -#ifdef UUID_TIME_GENERATOR -#include <iphlpapi.h> -#pragma comment(lib, "IPHLPAPI.lib") -#endif - -#elif defined(__linux__) || defined(__unix__) - -#ifdef UUID_SYSTEM_GENERATOR -#include <uuid/uuid.h> -#endif - -#elif defined(__APPLE__) - -#ifdef UUID_SYSTEM_GENERATOR -#include <CoreFoundation/CFUUID.h> -#endif - -#endif - -namespace uuids { -#ifdef __cpp_lib_span -template <class ElementType, std::size_t Extent> -using span = std::span<ElementType, Extent>; -#else -template <class ElementType, std::ptrdiff_t Extent> -using span = gsl::span<ElementType, Extent>; -#endif - -namespace Detail { - template <typename TChar> - [[nodiscard]] constexpr inline unsigned char hex2char(TChar const ch) noexcept { - if (ch >= static_cast<TChar>('0') && ch <= static_cast<TChar>('9')) - return static_cast<unsigned char>(ch - static_cast<TChar>('0')); - if (ch >= static_cast<TChar>('a') && ch <= static_cast<TChar>('f')) - return static_cast<unsigned char>(10 + ch - static_cast<TChar>('a')); - if (ch >= static_cast<TChar>('A') && ch <= static_cast<TChar>('F')) - return static_cast<unsigned char>(10 + ch - static_cast<TChar>('A')); - return 0; - } - - template <typename TChar> - [[nodiscard]] constexpr std::basic_string_view<TChar> to_string_view(TChar const* str) noexcept { - return str; - } - - template <typename StringType> - [[nodiscard]] constexpr std::basic_string_view<typename StringType::value_type, - typename StringType::traits_type> - to_string_view(StringType const& str) noexcept { - return str; - } - - class sha1 { - public: - using digest32_t = uint32_t[5]; - using digest8_t = uint8_t[20]; - - static constexpr unsigned int block_bytes = 64; - - [[nodiscard]] inline static uint32_t left_rotate(uint32_t value, size_t const count) noexcept { - return (value << count) ^ (value >> (32 - count)); - } - - sha1() { reset(); } - - void reset() noexcept { - m_digest[0] = 0x67452301; - m_digest[1] = 0xEFCDAB89; - m_digest[2] = 0x98BADCFE; - m_digest[3] = 0x10325476; - m_digest[4] = 0xC3D2E1F0; - m_blockByteIndex = 0; - m_byteCount = 0; - } - - void process_byte(uint8_t octet) { - this->m_block[this->m_blockByteIndex++] = octet; - ++this->m_byteCount; - if (m_blockByteIndex == block_bytes) { - this->m_blockByteIndex = 0; - process_block(); - } - } - - void process_block(void const* const start, void const* const end) { - const uint8_t* begin = static_cast<const uint8_t*>(start); - const uint8_t* finish = static_cast<const uint8_t*>(end); - while (begin != finish) { - process_byte(*begin); - begin++; - } - } - - void process_bytes(void const* const data, size_t const len) { - const uint8_t* block = static_cast<const uint8_t*>(data); - process_block(block, block + len); - } - - uint32_t const* get_digest(digest32_t digest) { - size_t const bitCount = this->m_byteCount * 8; - process_byte(0x80); - if (this->m_blockByteIndex > 56) { - while (m_blockByteIndex != 0) { - process_byte(0); - } - while (m_blockByteIndex < 56) { - process_byte(0); - } - } else { - while (m_blockByteIndex < 56) { - process_byte(0); - } - } - process_byte(0); - process_byte(0); - process_byte(0); - process_byte(0); - process_byte(static_cast<unsigned char>((bitCount >> 24) & 0xFF)); - process_byte(static_cast<unsigned char>((bitCount >> 16) & 0xFF)); - process_byte(static_cast<unsigned char>((bitCount >> 8) & 0xFF)); - process_byte(static_cast<unsigned char>((bitCount) & 0xFF)); - - memcpy(digest, m_digest, 5 * sizeof(uint32_t)); - return digest; - } - - uint8_t const* get_digest_bytes(digest8_t digest) { - digest32_t d32; - get_digest(d32); - size_t di = 0; - digest[di++] = static_cast<uint8_t>(d32[0] >> 24); - digest[di++] = static_cast<uint8_t>(d32[0] >> 16); - digest[di++] = static_cast<uint8_t>(d32[0] >> 8); - digest[di++] = static_cast<uint8_t>(d32[0] >> 0); - - digest[di++] = static_cast<uint8_t>(d32[1] >> 24); - digest[di++] = static_cast<uint8_t>(d32[1] >> 16); - digest[di++] = static_cast<uint8_t>(d32[1] >> 8); - digest[di++] = static_cast<uint8_t>(d32[1] >> 0); - - digest[di++] = static_cast<uint8_t>(d32[2] >> 24); - digest[di++] = static_cast<uint8_t>(d32[2] >> 16); - digest[di++] = static_cast<uint8_t>(d32[2] >> 8); - digest[di++] = static_cast<uint8_t>(d32[2] >> 0); - - digest[di++] = static_cast<uint8_t>(d32[3] >> 24); - digest[di++] = static_cast<uint8_t>(d32[3] >> 16); - digest[di++] = static_cast<uint8_t>(d32[3] >> 8); - digest[di++] = static_cast<uint8_t>(d32[3] >> 0); - - digest[di++] = static_cast<uint8_t>(d32[4] >> 24); - digest[di++] = static_cast<uint8_t>(d32[4] >> 16); - digest[di++] = static_cast<uint8_t>(d32[4] >> 8); - digest[di++] = static_cast<uint8_t>(d32[4] >> 0); - - return digest; - } - - private: - void process_block() { - uint32_t w[80]; - for (size_t i = 0; i < 16; i++) { - w[i] = static_cast<uint32_t>(m_block[i * 4 + 0] << 24); - w[i] |= static_cast<uint32_t>(m_block[i * 4 + 1] << 16); - w[i] |= static_cast<uint32_t>(m_block[i * 4 + 2] << 8); - w[i] |= static_cast<uint32_t>(m_block[i * 4 + 3]); - } - for (size_t i = 16; i < 80; i++) { - w[i] = left_rotate((w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]), 1); - } - - uint32_t a = m_digest[0]; - uint32_t b = m_digest[1]; - uint32_t c = m_digest[2]; - uint32_t d = m_digest[3]; - uint32_t e = m_digest[4]; - - for (std::size_t i = 0; i < 80; ++i) { - uint32_t f = 0; - uint32_t k = 0; - - if (i < 20) { - f = (b & c) | (~b & d); - k = 0x5A827999; - } else if (i < 40) { - f = b ^ c ^ d; - k = 0x6ED9EBA1; - } else if (i < 60) { - f = (b & c) | (b & d) | (c & d); - k = 0x8F1BBCDC; - } else { - f = b ^ c ^ d; - k = 0xCA62C1D6; - } - uint32_t temp = left_rotate(a, 5) + f + e + k + w[i]; - e = d; - d = c; - c = left_rotate(b, 30); - b = a; - a = temp; - } - - m_digest[0] += a; - m_digest[1] += b; - m_digest[2] += c; - m_digest[3] += d; - m_digest[4] += e; - } - - private: - digest32_t m_digest; - uint8_t m_block[64]; - size_t m_blockByteIndex; - size_t m_byteCount; - }; - - template <typename CharT> - inline constexpr CharT empty_guid[37] = "00000000-0000-0000-0000-000000000000"; - - template <> - inline constexpr wchar_t empty_guid<wchar_t>[37] = L"00000000-0000-0000-0000-000000000000"; - - template <typename CharT> - inline constexpr CharT guid_encoder[17] = "0123456789abcdef"; - - template <> - inline constexpr wchar_t guid_encoder<wchar_t>[17] = L"0123456789abcdef"; -} // namespace Detail - -// -------------------------------------------------------------------------------------------------------------------------- -// UUID format https://tools.ietf.org/html/rfc4122 -// -------------------------------------------------------------------------------------------------------------------------- - -// -------------------------------------------------------------------------------------------------------------------------- -// Field NDR Data Type Octet # Note -// -------------------------------------------------------------------------------------------------------------------------- -// time_low unsigned long 0 - 3 The low field -// of the timestamp. time_mid unsigned short 4 - 5 -// The middle field of the timestamp. time_hi_and_version unsigned -// short 6 - 7 The high field of the timestamp multiplexed -// with the version number. clock_seq_hi_and_reserved unsigned small 8 -// The high field of the clock sequence multiplexed with the variant. -// clock_seq_low unsigned small 9 The low -// field of the clock sequence. node character 10 -// - 15 The spatially unique node identifier. -// -------------------------------------------------------------------------------------------------------------------------- -// 0 1 2 3 -// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | time_low | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | time_mid | time_hi_and_version | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// |clk_seq_hi_res | clk_seq_low | node (0-1) | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | node (2-5) | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - -// -------------------------------------------------------------------------------------------------------------------------- -// enumerations -// -------------------------------------------------------------------------------------------------------------------------- - -// indicated by a bit pattern in octet 8, marked with N in -// xxxxxxxx-xxxx-xxxx-Nxxx-xxxxxxxxxxxx -enum class uuid_variant { - // NCS backward compatibility (with the obsolete Apollo Network Computing - // System 1.5 UUID format) N bit pattern: 0xxx > the first 6 octets of the - // UUID are a 48-bit timestamp (the number of 4 microsecond units of time - // since 1 Jan 1980 UTC); > the next 2 octets are reserved; > the next octet - // is the "address family"; > the final 7 octets are a 56-bit host ID in the - // form specified by the address family - ncs, - - // RFC 4122/DCE 1.1 - // N bit pattern: 10xx - // > big-endian byte order - rfc, - - // Microsoft Corporation backward compatibility - // N bit pattern: 110x - // > little endian byte order - // > formely used in the Component Object Model (COM) library - microsoft, - - // reserved for possible future definition - // N bit pattern: 111x - reserved -}; - -// indicated by a bit pattern in octet 6, marked with M in -// xxxxxxxx-xxxx-Mxxx-xxxx-xxxxxxxxxxxx -enum class uuid_version { - none = 0, // only possible for nil or invalid uuids - time_based = 1, // The time-based version specified in RFC 4122 - dce_security = 2, // DCE Security version, with embedded POSIX UIDs. - name_based_md5 = 3, // The name-based version specified in RFS 4122 with MD5 hashing - random_number_based = 4, // The randomly or pseudo-randomly generated version - // specified in RFS 4122 - name_based_sha1 = 5 // The name-based version specified in RFS 4122 with SHA1 hashing -}; - -// Forward declare uuid & to_string so that we can declare to_string as a friend -// later. -class uuid; -template <class CharT = char, class Traits = std::char_traits<CharT>, - class Allocator = std::allocator<CharT>> -std::basic_string<CharT, Traits, Allocator> to_string(uuid const& id); - -// -------------------------------------------------------------------------------------------------------------------------- -// uuid class -// -------------------------------------------------------------------------------------------------------------------------- -class uuid { - public: - using value_type = uint8_t; - - constexpr uuid() noexcept = default; - - uuid(value_type (&arr)[16]) noexcept { - std::copy(std::cbegin(arr), std::cend(arr), std::begin(data)); - } - - constexpr uuid(std::array<value_type, 16> const& arr) noexcept : data{arr} {} - - explicit uuid(span<value_type, 16> bytes) { - std::copy(std::cbegin(bytes), std::cend(bytes), std::begin(data)); - } - - template <typename ForwardIterator> - explicit uuid(ForwardIterator first, ForwardIterator last) { - if (std::distance(first, last) == 16) std::copy(first, last, std::begin(data)); - } - - [[nodiscard]] constexpr uuid_variant variant() const noexcept { - if ((data[8] & 0x80) == 0x00) - return uuid_variant::ncs; - else if ((data[8] & 0xC0) == 0x80) - return uuid_variant::rfc; - else if ((data[8] & 0xE0) == 0xC0) - return uuid_variant::microsoft; - else - return uuid_variant::reserved; - } - - [[nodiscard]] constexpr uuid_version version() const noexcept { - if ((data[6] & 0xF0) == 0x10) - return uuid_version::time_based; - else if ((data[6] & 0xF0) == 0x20) - return uuid_version::dce_security; - else if ((data[6] & 0xF0) == 0x30) - return uuid_version::name_based_md5; - else if ((data[6] & 0xF0) == 0x40) - return uuid_version::random_number_based; - else if ((data[6] & 0xF0) == 0x50) - return uuid_version::name_based_sha1; - else - return uuid_version::none; - } - - [[nodiscard]] constexpr bool is_nil() const noexcept { - for (size_t i = 0; i < data.size(); ++i) - if (data[i] != 0) return false; - return true; - } - - void swap(uuid& other) noexcept { data.swap(other.data); } - - [[nodiscard]] inline span<std::byte const, 16> as_bytes() const { - return span<std::byte const, 16>(reinterpret_cast<std::byte const*>(data.data()), 16); - } - - template <typename StringType> - [[nodiscard]] constexpr static bool is_valid_uuid(StringType const& in_str) noexcept { - auto str = Detail::to_string_view(in_str); - bool firstDigit = true; - size_t hasBraces = 0; - size_t index = 0; - - if (str.empty()) return false; - - if (str.front() == '{') hasBraces = 1; - if (hasBraces && str.back() != '}') return false; - - for (size_t i = hasBraces; i < str.size() - hasBraces; ++i) { - if (str[i] == '-') continue; - - if (index >= 16 || !std::isxdigit(static_cast<unsigned char>(str[i]))) { - return false; - } - - if (firstDigit) { - firstDigit = false; - } else { - index++; - firstDigit = true; - } - } - - if (index < 16) { - return false; - } - - return true; - } - - template <typename StringType> - [[nodiscard]] constexpr static std::optional<uuid> from_string( - StringType const& in_str) noexcept { - auto str = Detail::to_string_view(in_str); - bool firstDigit = true; - size_t hasBraces = 0; - size_t index = 0; - - std::array<uint8_t, 16> data{{0}}; - - if (str.empty()) return {}; - - if (str.front() == '{') hasBraces = 1; - if (hasBraces && str.back() != '}') return {}; - - for (size_t i = hasBraces; i < str.size() - hasBraces; ++i) { - if (str[i] == '-') continue; - - if (index >= 16 || !std::isxdigit(static_cast<unsigned char>(str[i]))) { - return {}; - } - - if (firstDigit) { - data[index] = static_cast<uint8_t>(Detail::hex2char(str[i]) << 4); - firstDigit = false; - } else { - data[index] = static_cast<uint8_t>(data[index] | Detail::hex2char(str[i])); - index++; - firstDigit = true; - } - } - - if (index < 16) { - return {}; - } - - return uuid{data}; - } - - private: - std::array<value_type, 16> data{{0}}; - - friend bool operator==(uuid const& lhs, uuid const& rhs) noexcept; - friend bool operator<(uuid const& lhs, uuid const& rhs) noexcept; - - template <class Elem, class Traits> - friend std::basic_ostream<Elem, Traits>& operator<<(std::basic_ostream<Elem, Traits>& s, - uuid const& id); - - template <class CharT, class Traits, class Allocator> - friend std::basic_string<CharT, Traits, Allocator> to_string(uuid const& id); - - friend std::hash<uuid>; -}; - -// -------------------------------------------------------------------------------------------------------------------------- -// operators and non-member functions -// -------------------------------------------------------------------------------------------------------------------------- - -[[nodiscard]] inline bool operator==(uuid const& lhs, uuid const& rhs) noexcept { - return lhs.data == rhs.data; -} - -[[nodiscard]] inline bool operator!=(uuid const& lhs, uuid const& rhs) noexcept { - return !(lhs == rhs); -} - -[[nodiscard]] inline bool operator<(uuid const& lhs, uuid const& rhs) noexcept { - return lhs.data < rhs.data; -} - -template <class CharT, class Traits, class Allocator> -[[nodiscard]] inline std::basic_string<CharT, Traits, Allocator> to_string(uuid const& id) { - std::basic_string<CharT, Traits, Allocator> uustr{Detail::empty_guid<CharT>}; - - for (size_t i = 0, index = 0; i < 36; ++i) { - if (i == 8 || i == 13 || i == 18 || i == 23) { - continue; - } - uustr[i] = Detail::guid_encoder<CharT>[id.data[index] >> 4 & 0x0f]; - uustr[++i] = Detail::guid_encoder<CharT>[id.data[index] & 0x0f]; - index++; - } - - return uustr; -} - -template <class Elem, class Traits> -std::basic_ostream<Elem, Traits>& operator<<(std::basic_ostream<Elem, Traits>& s, uuid const& id) { - s << to_string(id); - return s; -} - -inline void swap(uuids::uuid& lhs, uuids::uuid& rhs) noexcept { - lhs.swap(rhs); -} - -// -------------------------------------------------------------------------------------------------------------------------- -// namespace IDs that could be used for generating name-based uuids -// -------------------------------------------------------------------------------------------------------------------------- - -// Name string is a fully-qualified domain name -static uuid uuid_namespace_dns{{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, - 0xc0, 0x4f, 0xd4, 0x30, 0xc8}}; - -// Name string is a URL -static uuid uuid_namespace_url{{0x6b, 0xa7, 0xb8, 0x11, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, - 0xc0, 0x4f, 0xd4, 0x30, 0xc8}}; - -// Name string is an ISO OID (See https://oidref.com/, -// https://en.wikipedia.org/wiki/Object_identifier) -static uuid uuid_namespace_oid{{0x6b, 0xa7, 0xb8, 0x12, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, - 0xc0, 0x4f, 0xd4, 0x30, 0xc8}}; - -// Name string is an X.500 DN, in DER or a text output format (See -// https://en.wikipedia.org/wiki/X.500, -// https://en.wikipedia.org/wiki/Abstract_Syntax_Notation_One) -static uuid uuid_namespace_x500{{0x6b, 0xa7, 0xb8, 0x14, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, - 0xc0, 0x4f, 0xd4, 0x30, 0xc8}}; - -// -------------------------------------------------------------------------------------------------------------------------- -// uuid generators -// -------------------------------------------------------------------------------------------------------------------------- - -#ifdef UUID_SYSTEM_GENERATOR -class uuid_system_generator { - public: - using result_type = uuid; - - uuid operator()() { -#ifdef _WIN32 - GUID newId{}; /// AMLALE: Should be zero-initialized. - HRESULT hr = ::CoCreateGuid(&newId); - - if (FAILED(hr)) { - throw std::system_error(hr, std::system_category(), "CoCreateGuid failed"); - } - - std::array<uint8_t, 16> bytes = {{static_cast<unsigned char>((newId.Data1 >> 24) & 0xFF), - static_cast<unsigned char>((newId.Data1 >> 16) & 0xFF), - static_cast<unsigned char>((newId.Data1 >> 8) & 0xFF), - static_cast<unsigned char>((newId.Data1) & 0xFF), - static_cast<unsigned char>((newId.Data2 >> 8) & 0xFF), - static_cast<unsigned char>((newId.Data2) & 0xFF), - static_cast<unsigned char>((newId.Data3 >> 8) & 0xFF), - static_cast<unsigned char>((newId.Data3) & 0xFF), - newId.Data4[0], newId.Data4[1], newId.Data4[2], - newId.Data4[3], newId.Data4[4], newId.Data4[5], - newId.Data4[6], newId.Data4[7]}}; - - return uuid{std::begin(bytes), std::end(bytes)}; - -#elif defined(__linux__) || defined(__unix__) - - uuid_t id; - uuid_generate(id); - - std::array<uint8_t, 16> bytes = {{id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7], id[8], - id[9], id[10], id[11], id[12], id[13], id[14], id[15]}}; - - return uuid{std::begin(bytes), std::end(bytes)}; - -#elif defined(__APPLE__) - auto newId = CFUUIDCreate(NULL); - auto bytes = CFUUIDGetUUIDBytes(newId); - CFRelease(newId); - - std::array<uint8_t, 16> arrbytes = {{bytes.byte0, bytes.byte1, bytes.byte2, bytes.byte3, - bytes.byte4, bytes.byte5, bytes.byte6, bytes.byte7, - bytes.byte8, bytes.byte9, bytes.byte10, bytes.byte11, - bytes.byte12, bytes.byte13, bytes.byte14, bytes.byte15}}; - return uuid{std::begin(arrbytes), std::end(arrbytes)}; -#else - return uuid{}; -#endif - } -}; -#endif - -template <typename UniformRandomNumberGenerator> -class basic_uuid_random_generator { - public: - using engine_type = UniformRandomNumberGenerator; - - explicit basic_uuid_random_generator(engine_type& gen) : generator(&gen, [](auto) {}) {} - explicit basic_uuid_random_generator(engine_type* gen) : generator(gen, [](auto) {}) {} - - [[nodiscard]] uuid operator()() { - alignas(uint32_t) uint8_t bytes[16]; - for (int i = 0; i < 16; i += 4) - *reinterpret_cast<uint32_t*>(bytes + i) = distribution(*generator); - - // variant must be 10xxxxxx - bytes[8] &= 0xBF; - bytes[8] |= 0x80; - - // version must be 0100xxxx - bytes[6] &= 0x4F; - bytes[6] |= 0x40; - - return uuid{std::begin(bytes), std::end(bytes)}; - } - - private: - std::uniform_int_distribution<uint32_t> distribution; - std::shared_ptr<UniformRandomNumberGenerator> generator; -}; - -using uuid_random_generator = basic_uuid_random_generator<std::mt19937>; - -class uuid_name_generator { - public: - explicit uuid_name_generator(uuid const& namespace_uuid) noexcept : nsuuid(namespace_uuid) {} - - template <typename StringType> - [[nodiscard]] uuid operator()(StringType const& name) { - reset(); - process_characters(Detail::to_string_view(name)); - return make_uuid(); - } - - private: - void reset() { - hasher.reset(); - std::byte bytes[16]; - auto nsbytes = nsuuid.as_bytes(); - std::copy(std::cbegin(nsbytes), std::cend(nsbytes), bytes); - hasher.process_bytes(bytes, 16); - } - - template <typename CharT, typename Traits> - void process_characters(std::basic_string_view<CharT, Traits> const str) { - for (uint32_t c : str) { - hasher.process_byte(static_cast<uint8_t>(c & 0xFF)); - if constexpr (!std::is_same_v<CharT, char>) { - hasher.process_byte(static_cast<uint8_t>((c >> 8) & 0xFF)); - hasher.process_byte(static_cast<uint8_t>((c >> 16) & 0xFF)); - hasher.process_byte(static_cast<uint8_t>((c >> 24) & 0xFF)); - } - } - } - - [[nodiscard]] uuid make_uuid() { - Detail::sha1::digest8_t digest; - hasher.get_digest_bytes(digest); - - // variant must be 0b10xxxxxx - digest[8] &= 0xBF; - digest[8] |= 0x80; - - // version must be 0b0101xxxx - digest[6] &= 0x5F; - digest[6] |= 0x50; - - return uuid{digest, digest + 16}; - } - - private: - uuid nsuuid; - Detail::sha1 hasher; -}; - -#ifdef UUID_TIME_GENERATOR -// !!! DO NOT USE THIS IN PRODUCTION -// this implementation is unreliable for good uuids -class uuid_time_generator { - using mac_address = std::array<unsigned char, 6>; - - std::optional<mac_address> device_address; - - [[nodiscard]] bool get_mac_address() { - if (device_address.has_value()) { - return true; - } - -#ifdef _WIN32 - DWORD len = 0; - auto ret = GetAdaptersInfo(nullptr, &len); - if (ret != ERROR_BUFFER_OVERFLOW) return false; - std::vector<unsigned char> buf(len); - auto pips = reinterpret_cast<PIP_ADAPTER_INFO>(&buf.front()); - ret = GetAdaptersInfo(pips, &len); - if (ret != ERROR_SUCCESS) return false; - mac_address addr; - std::copy(pips->Address, pips->Address + 6, std::begin(addr)); - device_address = addr; -#endif - - return device_address.has_value(); - } - - [[nodiscard]] long long get_time_intervals() { - auto start = std::chrono::system_clock::from_time_t(time_t(-12219292800)); - auto diff = std::chrono::system_clock::now() - start; - auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(diff).count(); - return ns / 100; - } - - [[nodiscard]] static unsigned short get_clock_sequence() { - static std::mt19937 clock_gen(std::random_device{}()); - static std::uniform_int_distribution<unsigned short> clock_dis; - static std::atomic_ushort clock_sequence = clock_dis(clock_gen); - return clock_sequence++; - } - - public: - [[nodiscard]] uuid operator()() { - if (get_mac_address()) { - std::array<uuids::uuid::value_type, 16> data; - - auto tm = get_time_intervals(); - - auto clock_seq = get_clock_sequence(); - - auto ptm = reinterpret_cast<uuids::uuid::value_type*>(&tm); - - memcpy(&data[0], ptm + 4, 4); - memcpy(&data[4], ptm + 2, 2); - memcpy(&data[6], ptm, 2); - - memcpy(&data[8], &clock_seq, 2); - - // variant must be 0b10xxxxxx - data[8] &= 0xBF; - data[8] |= 0x80; - - // version must be 0b0001xxxx - data[6] &= 0x1F; - data[6] |= 0x10; - - memcpy(&data[10], &device_address.value()[0], 6); - - return uuids::uuid{std::cbegin(data), std::cend(data)}; - } - - return {}; - } -}; -#endif -} // namespace uuids - -namespace std { -template <> -struct hash<uuids::uuid> { - using argument_type = uuids::uuid; - using result_type = std::size_t; - - [[nodiscard]] result_type operator()(argument_type const& uuid) const { -#ifdef UUID_HASH_STRING_BASED - std::hash<std::string> hasher; - return static_cast<result_type>(hasher(uuids::to_string(uuid))); -#else - uint64_t l = - static_cast<uint64_t>(uuid.data[0]) << 56 | static_cast<uint64_t>(uuid.data[1]) << 48 | - static_cast<uint64_t>(uuid.data[2]) << 40 | static_cast<uint64_t>(uuid.data[3]) << 32 | - static_cast<uint64_t>(uuid.data[4]) << 24 | static_cast<uint64_t>(uuid.data[5]) << 16 | - static_cast<uint64_t>(uuid.data[6]) << 8 | static_cast<uint64_t>(uuid.data[7]); - uint64_t h = - static_cast<uint64_t>(uuid.data[8]) << 56 | static_cast<uint64_t>(uuid.data[9]) << 48 | - static_cast<uint64_t>(uuid.data[10]) << 40 | static_cast<uint64_t>(uuid.data[11]) << 32 | - static_cast<uint64_t>(uuid.data[12]) << 24 | static_cast<uint64_t>(uuid.data[13]) << 16 | - static_cast<uint64_t>(uuid.data[14]) << 8 | static_cast<uint64_t>(uuid.data[15]); - - if constexpr (sizeof(result_type) > 4) { - return result_type(l ^ h); - } else { - uint64_t hash64 = l ^ h; - return result_type(uint32_t(hash64 >> 32) ^ uint32_t(hash64)); - } -#endif - } -}; -} // namespace std - -#endif /* STDUUID_H */ diff --git a/src/CompilerKit/Utilities/Assembler.h b/src/CompilerKit/Utilities/Assembler.h deleted file mode 100644 index fc965f0..0000000 --- a/src/CompilerKit/Utilities/Assembler.h +++ /dev/null @@ -1,92 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license - -======================================== */ - -#pragma once - -#include <CompilerKit/AST.h> -#include <CompilerKit/CodeGenerator.h> -#include <CompilerKit/Utilities/Compiler.h> - -using namespace CompilerKit; - -/// @brief Get Number from lineBuffer. -/// @param lineBuffer the lineBuffer to fetch from. -/// @param numberKey where to seek that number. -/// @return A numbercast of 32-bit width. -static NumberCast32 GetNumber32(STLString lineBuffer, STLString numberKey) { - auto pos = lineBuffer.find(numberKey) + numberKey.size(); - - while (lineBuffer[pos] == ' ') { - ++pos; - } - - switch (lineBuffer[pos + 1]) { - case 'x': { - if (auto res = strtol(lineBuffer.substr(pos).c_str(), nullptr, 16); !res) { - if (errno != 0) { - CompilerKit::Detail::print_error("invalid hex number: " + lineBuffer, "CompilerKit"); - throw std::runtime_error("invalid_hex"); - } - } - - NumberCast32 numOffset(strtol(lineBuffer.substr(pos).c_str(), nullptr, 16)); - - if (kVerbose) { - kStdOut << "asm: found a base 16 number here: " << lineBuffer.substr(pos) << "\n"; - } - - return numOffset; - } - case 'b': { - if (auto res = strtol(lineBuffer.substr(pos).c_str(), nullptr, 2); !res) { - if (errno != 0) { - CompilerKit::Detail::print_error("invalid binary number:" + lineBuffer, "CompilerKit"); - throw std::runtime_error("invalid_bin"); - } - } - - NumberCast32 numOffset(strtol(lineBuffer.substr(pos).c_str(), nullptr, 2)); - - if (kVerbose) { - kStdOut << "asm: found a base 2 number here:" << lineBuffer.substr(pos) << "\n"; - } - - return numOffset; - } - case 'o': { - if (auto res = strtol(lineBuffer.substr(pos).c_str(), nullptr, 7); !res) { - if (errno != 0) { - CompilerKit::Detail::print_error("invalid octal number: " + lineBuffer, "CompilerKit"); - throw std::runtime_error("invalid_octal"); - } - } - - NumberCast32 numOffset(strtol(lineBuffer.substr(pos).c_str(), nullptr, 7)); - - if (kVerbose) { - kStdOut << "asm: found a base 8 number here:" << lineBuffer.substr(pos) << "\n"; - } - - return numOffset; - } - default: { - if (auto res = strtol(lineBuffer.substr(pos).c_str(), nullptr, 10); !res) { - if (errno != 0) { - CompilerKit::Detail::print_error("invalid hex number: " + lineBuffer, "CompilerKit"); - throw std::runtime_error("invalid_hex"); - } - } - - NumberCast32 numOffset(strtol(lineBuffer.substr(pos).c_str(), nullptr, 10)); - - if (kVerbose) { - kStdOut << "asm: found a base 10 number here:" << lineBuffer.substr(pos) << "\n"; - } - - return numOffset; - } - } -} diff --git a/src/CompilerKit/Utilities/Compiler.h b/src/CompilerKit/Utilities/Compiler.h deleted file mode 100644 index bbca020..0000000 --- a/src/CompilerKit/Utilities/Compiler.h +++ /dev/null @@ -1,123 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license - -======================================== */ - -#pragma once - -#include <CompilerKit/AST.h> -#include <CompilerKit/CodeGenerator.h> -#include <CompilerKit/Detail/Config.h> -#include <CompilerKit/ErrorID.h> -#include <ThirdParty/Dialogs/Dialogs.h> -#include <iostream> - -#define kZero64Section ".zero64" -#define kCode64Section ".code64" -#define kData64Section ".data64" - -#define kZero128Section ".zero128" -#define kCode128Section ".code128" -#define kData128Section ".data128" - -#define kBlank "\e[0;30m" -#define kRed "\e[0;31m" -#define kWhite "\e[0;97m" -#define kYellow "\e[0;33m" - -#define kStdOut (std::cout << kRed << "drv: " << kWhite) -#define kStdErr (std::cerr << kYellow << "drv: " << kWhite) - -#define kPrintF kStdOut -#define kPrintErr kStdErr - -inline static UInt32 kErrorLimit = 10; -inline static UInt32 kAcceptableErrors = 0; -inline static bool kVerbose = false; -inline static bool kOutputAsBinary = false; - -namespace CompilerKit::Detail { -/// @brief Blob structure -struct Blob final { - std::vector<Char> mBlob{}; // PEF code/bss/data blob. - UIntPtr mOffset{0UL}; // the offset of the PEF container header... - - explicit operator bool() { - return mBlob.empty() && mOffset > 0UL; - } -}; - -inline void print_error(STLString reason, STLString file) noexcept { - if (reason[0] == '\n') reason.erase(0, 1); - - kStdErr << reason << kBlank << std::endl; - - if (kAcceptableErrors > kErrorLimit) std::exit(NECTI_EXEC_ERROR); - - ++kAcceptableErrors; -} - -inline void print_warning(STLString reason, STLString file) noexcept { - if (reason[0] == '\n') reason.erase(0, 1); - - kStdOut << kYellow << reason << kBlank << std::endl; -} - -/// @internal -/// @brief Handler for SIGSEGV signal. -inline void drvi_crash_handler(std::int32_t id) { - CompilerKit::STLString verbose_header = "LIBCOMPILER CRASH REPORT - "; - verbose_header += kDistVersion; - verbose_header += " - "; - verbose_header += CompilerKit::current_date(); - - for (auto& ch : verbose_header) { - std::cout << '='; - } - - std::cout << std::endl; - - std::cout << verbose_header << std::endl; - - for (auto& ch : verbose_header) { - std::cout << '='; - } - - std::cout << std::endl; - - kStdOut << "DATE: " << CompilerKit::current_date() << std::endl; - kStdOut << "VERSION: " << kDistVersion << std::endl; - kStdOut << "ERRNO: " << errno << std::endl; - kStdOut << "ERRNO(STRING): " << strerror(errno) << std::endl; - - switch (id) { - case SIGSEGV: { - kStdOut << "SIGNAL: Segmentation Fault." << kBlank << std::endl; - break; - } - case SIGABRT: { - kStdOut << "SIGNAL: Aborted." << kBlank << std::endl; - break; - } - } - - std::cout << kWhite; - - for (auto& ch : verbose_header) { - std::cout << '='; - } - - std::cout << std::endl; - - std::cout << verbose_header << std::endl; - - for (auto& ch : verbose_header) { - std::cout << '='; - } - - std::cout << std::endl; - - std::exit(NECTI_EXEC_ERROR); -} -} // namespace Detail diff --git a/src/CompilerKit/Utilities/DLL.h b/src/CompilerKit/Utilities/DLL.h deleted file mode 100644 index 5bfe032..0000000 --- a/src/CompilerKit/Utilities/DLL.h +++ /dev/null @@ -1,67 +0,0 @@ -/* ======================================== - - Copyright (C) 2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license - -======================================== */ - -#pragma once - -#include <CompilerKit/Detail/Config.h> -#include <dlfcn.h> -#include <mutex> - -struct CompilerKitDylibTraits; - -typedef Int32 (*CompilerKitEntrypoint)(Int32 argc, Char const* argv[]); -typedef VoidPtr CompilerKitDylib; - -struct CompilerKitDylibTraits final { - CompilerKitDylib fDylib{nullptr}; - CompilerKitEntrypoint fEntrypoint{nullptr}; - std::mutex fMutex; - - explicit operator bool() { - return fDylib && fEntrypoint; - } - - CompilerKitDylibTraits& operator()(const Char* path, const Char* fEntrypoint) { - std::lock_guard<std::mutex> lock(this->fMutex); - - if (!path || !fEntrypoint) return *this; - - if (this->fDylib) { - dlclose(this->fDylib); - this->fDylib = nullptr; - } - - this->fDylib = dlopen(path, RTLD_LAZY); - - if (!this->fDylib) { - return *this; - } - - this->fEntrypoint = (CompilerKitEntrypoint) dlsym(this->fDylib, fEntrypoint); - - if (!this->fEntrypoint) { - dlclose(this->fDylib); - this->fDylib = nullptr; - - return *this; - } - - return *this; - } - - NECTI_COPY_DELETE(CompilerKitDylibTraits); - - CompilerKitDylibTraits() = default; - - ~CompilerKitDylibTraits() { - if (this->fDylib) { - dlclose(this->fDylib); - this->fDylib = nullptr; - } - - this->fEntrypoint = nullptr; - } -}; diff --git a/src/CompilerKit/XCOFF.h b/src/CompilerKit/XCOFF.h deleted file mode 100644 index 777f501..0000000 --- a/src/CompilerKit/XCOFF.h +++ /dev/null @@ -1,43 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license - - File: XCOFF.h - Purpose: XCOFF for NeKernel. - - Revision History: - - 04/07/24: Added file (Amlal El Mahrouss) - -======================================== */ - -#ifndef _NECTI_XCOFF_H_ -#define _NECTI_XCOFF_H_ - -#include <CompilerKit/Detail/Config.h> - -#define kXCOFF64Magic 0x01F7 - -#define kXCOFFRelFlg 0x0001 -#define kXCOFFExecutable 0x0002 -#define kXCOFFLnno 0x0004 -#define kXCOFFLSyms 0x0008 - -namespace CompilerKit { -struct XCoffFileHeader; - -/// @brief XCoff file header. -typedef struct XCoffFileHeader { - UInt16 fMagic; - UInt16 fTarget; - UInt16 fNumSecs; - UInt32 fTimeDat; - UIntPtr fSymPtr; - UInt32 fNumSyms; - UInt16 fOptHdr; // ?: Number of bytes in optional header -} XCoffFileHeader; - -typedef struct XCoffFileHeader* XCoffFileHeaderPtr; -} // namespace CompilerKit - -#endif // ifndef _NECTI_XCOFF_H_ diff --git a/src/CompilerKit/ck-osx-san.json b/src/CompilerKit/ck-osx-san.json index df1c36b..c0913aa 100644 --- a/src/CompilerKit/ck-osx-san.json +++ b/src/CompilerKit/ck-osx-san.json @@ -2,11 +2,11 @@ "compiler_path": "clang++", "compiler_std": "c++20", "headers_path": [ - "../CompilerKit", - "../", - "../CompilerKit/src/", - "../CompilerKit/src/impl", - "/opt/homebrew/Cellar/boost/1.87.0/include" + "../../include/CompilerKit", + "../../include/", + "../../include/CompilerKit/src/", + "../../include/CompilerKit/src/impl", + "/opt/homebrew/Cellar/boost/1.89.0/include" ], "sources_path": [ "src/*.cc", diff --git a/src/CompilerKit/ck-osx.json b/src/CompilerKit/ck-osx.json index cab0221..a17d483 100644 --- a/src/CompilerKit/ck-osx.json +++ b/src/CompilerKit/ck-osx.json @@ -2,11 +2,11 @@ "compiler_path": "clang++", "compiler_std": "c++20", "headers_path": [ - "../CompilerKit", - "../", - "../CompilerKit/src/", - "../CompilerKit/src/impl", - "/opt/homebrew/Cellar/boost/1.87.0/include" + "../../include/CompilerKit", + "../../include/", + "../../include/CompilerKit/src/", + "../../include/CompilerKit/src/impl", + "/opt/homebrew/Cellar/boost/1.89.0/include" ], "sources_path": [ "src/*.cc", diff --git a/src/CompilerKit/ck-posix.json b/src/CompilerKit/ck-posix.json index b748f7a..3f6127c 100644 --- a/src/CompilerKit/ck-posix.json +++ b/src/CompilerKit/ck-posix.json @@ -2,10 +2,10 @@ "compiler_path": "clang++", "compiler_std": "c++20", "headers_path": [ - "../CompilerKit", - "../", - "../CompilerKit/src/", - "../CompilerKit/src/impl" + "../../include/CompilerKit", + "../../include/", + "../../include/CompilerKit/src/", + "../../include/CompilerKit/src/impl" ], "sources_path": [ "src/*.cc", diff --git a/src/DebuggerKit/Common.inl b/src/DebuggerKit/Common.inl deleted file mode 100644 index c630041..0000000 --- a/src/DebuggerKit/Common.inl +++ /dev/null @@ -1,23 +0,0 @@ -/* ======================================== - - Copyright (C) 2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license. - -======================================== */ - -#define kBlank "\e[0;30m" -#define kRed "\e[0;31m" -#define kWhite "\e[0;97m" - -#define kStdOut (std::cout << kRed << "dbg: " << kWhite) - -inline bool kKeepRunning = false; - -#ifdef DK_NEKERNEL_DEBUGGER -inline DebuggerKit::NeKernel::NeKernelContract kKernelDebugger; -#else -inline DebuggerKit::POSIX::POSIXMachContract kUserDebugger; -#endif - -static DebuggerKit::ProcessID kPID = 0L; -static DebuggerKit::CAddress kActiveAddress = nullptr; -static CompilerKit::STLString kPath = ""; diff --git a/src/DebuggerKit/DebuggerContract.h b/src/DebuggerKit/DebuggerContract.h deleted file mode 100644 index e205e26..0000000 --- a/src/DebuggerKit/DebuggerContract.h +++ /dev/null @@ -1,43 +0,0 @@ -/* ======================================== - - Copyright (C) 2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <DebuggerKit/Detail/Config.h> -#include <unordered_map> - -#define DK_DEBUGGER_CONTRACT : public ::DebuggerKit::IDebuggerContract - -namespace DebuggerKit { -class IDebuggerContract; - -/// =========================================================== /// -/// \brief Debugger contract class in C++, as per the design states. -/// \author Amlal El Mahrouss -/// =========================================================== /// -class IDebuggerContract { - public: - explicit IDebuggerContract() = default; - virtual ~IDebuggerContract() = default; - - public: - IDebuggerContract& operator=(const IDebuggerContract&) = default; - IDebuggerContract(const IDebuggerContract&) = default; - - public: - virtual bool Attach(std::string path, std::string argv, ProcessID& pid) noexcept = 0; - virtual bool BreakAt(std::string symbol) noexcept = 0; - virtual bool Break() noexcept = 0; - virtual bool Continue() noexcept = 0; - virtual bool Detach() noexcept = 0; - - virtual std::unordered_map<uintptr_t, uintptr_t>& Get() { return m_breakpoints; } - - protected: - ProcessID m_pid{(ProcessID) ~0}; - std::unordered_map<uintptr_t, uintptr_t> m_breakpoints; -}; -} // namespace DebuggerKit diff --git a/src/DebuggerKit/Detail/Config.h b/src/DebuggerKit/Detail/Config.h deleted file mode 100644 index 0ea3ba1..0000000 --- a/src/DebuggerKit/Detail/Config.h +++ /dev/null @@ -1,66 +0,0 @@ -/* ======================================== - - Copyright (C) 2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -/// =========================================================== /// -/// @author Amlal El Mahrouss -/// =========================================================== /// - -#include <CompilerKit/Detail/Config.h> - -#include <arpa/inet.h> -#include <sys/socket.h> -#include <sys/types.h> -#include <sys/un.h> - -#include <sys/ptrace.h> -#include <sys/types.h> -#include <sys/user.h> -#include <sys/wait.h> -#include <unistd.h> - -#include <dlfcn.h> - -#ifdef __APPLE__ -#include <mach-o/dyld.h> -#include <mach/mach.h> -#include <mach/mach_error.h> -#endif - -#ifndef kDistRelease - -#define kDistVersion "v0.0.7-debuggerkit" -#define kDistVersionBCD 0x0001 - -#define ToString(X) Stringify(X) -#define Stringify(X) #X - -#define kDistRelease ToString(kDistReleaseBranch) - -#endif // !kDistRelease - -namespace DebuggerKit { -/// =========================================================== /// -/// \brief Process ID -/// =========================================================== /// -typedef uint64_t ProcessID; - -/// =========================================================== /// -/// \brief Address type, a la BSD. -/// =========================================================== /// -typedef char* CAddress; - -namespace Detail { - constexpr auto kDebugCmdLen = 256U; - constexpr auto kDebugPort = 51820; - constexpr auto kDebugMagic = "NE1.0.0;"; - constexpr uint16_t kDebugVersion = 0x0100; - constexpr auto kDebugDelim = ';'; - constexpr auto kDebugEnd = '\r'; - using dk_socket_type = int64_t; -} // namespace Detail -} // namespace DebuggerKit
\ No newline at end of file diff --git a/src/DebuggerKit/NeKernelContract.h b/src/DebuggerKit/NeKernelContract.h deleted file mode 100644 index fe38a22..0000000 --- a/src/DebuggerKit/NeKernelContract.h +++ /dev/null @@ -1,50 +0,0 @@ -/* ======================================== - - Copyright (C) 2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license. - -======================================== */ - -#ifndef DK_NEKERNEL_CONTRACT_H -#define DK_NEKERNEL_CONTRACT_H - -/// @brief NeKernel Debugging Protocol -/// @author Amlal El Mahrouss - -#ifdef DK_NEKERNEL_DEBUGGER - -#include <CompilerKit/Detail/Config.h> -#include <DebuggerKit/DebuggerContract.h> - -namespace DebuggerKit::NeKernel { -class NeKernelContract; - -/// =========================================================== /// -/// \brief NeKernel Debugger Contract -/// \author Amlal El Mahrouss -/// =========================================================== /// -class NeKernelContract final DK_DEBUGGER_CONTRACT { - public: - NeKernelContract(); - virtual ~NeKernelContract() override; - - public: - NeKernelContract& operator=(const NeKernelContract&) = default; - NeKernelContract(const NeKernelContract&) = default; - - public: - bool Attach(CompilerKit::STLString path, CompilerKit::STLString arg_v, - ProcessID& pid) noexcept override; - bool BreakAt(CompilerKit::STLString symbol) noexcept override; - bool Break() noexcept override; - bool Continue() noexcept override; - bool Detach() noexcept override; - - private: - CompilerKit::STLString m_kernel_path{}; - Detail::dk_socket_type m_socket{0}; -}; -} // namespace DebuggerKit::NeKernel - -#endif // ifdef DK_NEKERNEL_DEBUGGER - -#endif // DK_NEKERNEL_CONTRACT_H diff --git a/src/DebuggerKit/POSIXMachContract.h b/src/DebuggerKit/POSIXMachContract.h deleted file mode 100644 index abf23b5..0000000 --- a/src/DebuggerKit/POSIXMachContract.h +++ /dev/null @@ -1,155 +0,0 @@ -/* ======================================== - - Copyright (C) 2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#ifdef DK_MACH_DEBUGGER - -/// @file POSIXMachContract.h -/// @brief POSIX Mach debugger. - -#include <DebuggerKit/DebuggerContract.h> -#include <filesystem> -#include <vector> - -#ifdef __APPLE__ -CK_IMPORT_C kern_return_t mach_vm_write(vm_map_t target_task, mach_vm_address_t address, - vm_offset_t data, mach_msg_type_number_t dataCnt); - -CK_IMPORT_C kern_return_t mach_vm_protect(vm_map_t target_task, mach_vm_address_t address, - mach_vm_size_t size, boolean_t set_maximum, - vm_prot_t new_protection); -#endif - -#define PTRACE_ATTACH PT_ATTACHEXC -#define PTRACE_DETACH PT_DETACH -#define PTRACE_POKETEXT PT_WRITE_I -#define PTRACE_CONT PT_CONTINUE -#define PTRACE_PEEKTEXT PT_READ_I - -namespace DebuggerKit::POSIX { -/// =========================================================== /// -/// \brief POSIXMachContract engine class in C++ -/// \author Amlal El Mahrouss -/// =========================================================== /// -class POSIXMachContract final DK_DEBUGGER_CONTRACT { - public: - explicit POSIXMachContract() = default; - ~POSIXMachContract() override = default; - - public: - POSIXMachContract& operator=(const POSIXMachContract&) = default; - POSIXMachContract(const POSIXMachContract&) = default; - - public: - bool Attach(CompilerKit::STLString path, CompilerKit::STLString argv, - ProcessID& pid) noexcept override { - pid = fork(); - - if (pid == 0) { - if (argv.empty()) { - ptrace(PT_TRACE_ME, 0, nullptr, 0); - kill(getpid(), SIGSTOP); - } - - std::vector<char*> argv_arr; - - argv_arr.push_back(const_cast<char*>(path.c_str())); - argv_arr.push_back(const_cast<char*>(argv.c_str())); - argv_arr.push_back(nullptr); - - execv(path.c_str(), argv_arr.data()); - - _exit(1); - } - - m_path = path; - m_pid = pid; - - pid = this->m_pid; - - return true; - } - - void SetPath(CompilerKit::STLString path) noexcept { - if (path.empty()) { - return; - } - - m_path = path; - } - - bool BreakAt(CompilerKit::STLString symbol) noexcept override { - if (!m_path.empty() && std::filesystem::exists(m_path) && - std::filesystem::is_regular_file(m_path)) { - auto handle = dlopen(m_path.c_str(), RTLD_LAZY); - - if (handle == nullptr) { - return false; - } - - auto addr = dlsym(handle, symbol.c_str()); - - if (addr == nullptr) { - return false; - } - -#ifdef __APPLE__ - task_read_t task; - task_for_pid(mach_task_self(), m_pid, &task); - - uint32_t brk_inst = 0xD43E0000; - - mach_vm_protect(task, (mach_vm_address_t) addr, sizeof(uint32_t), false, - VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE); - - mach_vm_write(task, (mach_vm_address_t) addr, (vm_offset_t) &brk_inst, sizeof(addr)); -#endif - - return true; - } - - return false; - } - -#ifdef __APPLE__ - bool Break() noexcept override { - task_read_t task; - task_for_pid(mach_task_self(), m_pid, &task); - - kern_return_t ret = task_suspend(task); - - return ret == KERN_SUCCESS; - } - - bool Continue() noexcept override { - task_read_t task; - task_for_pid(mach_task_self(), m_pid, &task); - - kern_return_t ret = task_resume(task); - - return ret == KERN_SUCCESS; - } - - bool Detach() noexcept override { - this->Continue(); - - task_read_t task; - task_for_pid(mach_task_self(), m_pid, &task); - - kern_return_t kr = mach_port_deallocate(mach_task_self(), task); - - return kr = KERN_SUCCESS; - } -#endif - - private: - ProcessID m_pid{0}; - CompilerKit::STLString m_path; -}; -} // namespace DebuggerKit::POSIX - -#endif diff --git a/src/DebuggerKit/dk-nekernel.json b/src/DebuggerKit/dk-nekernel.json index 9c3d311..ad2deb8 100644 --- a/src/DebuggerKit/dk-nekernel.json +++ b/src/DebuggerKit/dk-nekernel.json @@ -2,8 +2,8 @@ "compiler_path": "clang++", "compiler_std": "c++20", "headers_path": [ - "../DebuggerKit", - "../" + "../../include/DebuggerKit", + "../../include" ], "sources_path": ["src/*.cc"], "output_name": "/usr/local/lib/libDebuggerKit.dylib", diff --git a/src/DebuggerKit/dk-osx.json b/src/DebuggerKit/dk-osx.json index c220756..20813aa 100644 --- a/src/DebuggerKit/dk-osx.json +++ b/src/DebuggerKit/dk-osx.json @@ -2,8 +2,8 @@ "compiler_path": "clang++", "compiler_std": "c++20", "headers_path": [ - "../DebuggerKit", - "../" + "../../include/DebuggerKit", + "../../include" ], "sources_path": ["src/*.cc"], "output_name": "/usr/local/lib/libDebuggerKit.dylib", diff --git a/src/LibC++/.gitignore b/src/LibC++/.gitignore deleted file mode 100644 index e3f10ea..0000000 --- a/src/LibC++/.gitignore +++ /dev/null @@ -1 +0,0 @@ -libc++/ diff --git a/src/LibC++/__abi+unreachable.cc b/src/LibC++/__abi+unreachable.cc deleted file mode 100644 index 5628e7d..0000000 --- a/src/LibC++/__abi+unreachable.cc +++ /dev/null @@ -1,16 +0,0 @@ -/* ======================================== - - Copyright (C) 2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license. - -======================================== */ - -#include <LibC++/__abi.h> -#include <LibC++/base_process.h> - -static const int32_t __unreachable_code = 34; - -extern "C" void __compilerkit_unreachable(void) { - std::base_process::signal(__unreachable_code); - - while (1); -}
\ No newline at end of file diff --git a/src/LibC++/__abi.h b/src/LibC++/__abi.h deleted file mode 100644 index 206b5ef..0000000 --- a/src/LibC++/__abi.h +++ /dev/null @@ -1,15 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <LibC++/defines.h> - -__init_decl() - - extern void __compilerkit_unreachable(void); - -__fini_decl()
\ No newline at end of file diff --git a/src/LibC++/__power64.inc b/src/LibC++/__power64.inc deleted file mode 100644 index c06863a..0000000 --- a/src/LibC++/__power64.inc +++ /dev/null @@ -1,39 +0,0 @@ -# Path: LibC++/__power64.inc -# Language: CompilerKit POWER Assembly support for GNU. -# Build Date: 2024-6-4 - -#ifdef __NECTI__ - -#ifdef __ASSEMBLER__ - -#define lda li -#define sta stw -#define ldw li - -#define r0 0 -#define r1 1 -#define r2 2 -#define r3 3 -#define r4 4 -#define r5 5 -#define r6 6 -#define r7 7 -#define r8 8 -#define r9 9 -#define r10 10 -#define r11 11 -#define r12 12 -#define r13 13 -#define r14 14 -#define r15 15 -#define r16 16 -#define r17 17 -#define r18 18 -#define r19 19 -#define r20 20 - -#define nop mr 0, 0 - -#endif - -#endif diff --git a/src/LibC++/base_alloc.h b/src/LibC++/base_alloc.h deleted file mode 100644 index ea5b5b2..0000000 --- a/src/LibC++/base_alloc.h +++ /dev/null @@ -1,43 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <LibC++/defines.h> - -namespace std::base_alloc { -/// @brief allocate a new class. -/// @tparam KindClass the class type to allocate. -template <typename KindClass, typename... Args> -inline KindClass* allocate(Args&&... args) { - return new KindClass(forward(args)...); -} - -/// @brief allocate a new class. -/// @note aborts on error. -/// @tparam KindClass the class type to allocate. -template <typename KindClass, typename... Args> -inline KindClass* allocate_nothrow(Args&&... args) noexcept { - return allocate(forward(args)...); -} - -/// @brief free a class. -/// @tparam KindClass the class type to allocate. -template <typename KindClass> -inline void release(KindClass ptr) { - if (!ptr) return; - - delete ptr; -} - -/// @brief destroy and free a class. -/// @note aborts on error. -/// @tparam KindClass the class type to allocate. -template <typename KindClass> -inline void release_nothrow(KindClass ptr) noexcept { - release(ptr); -} -} // namespace std::base_alloc diff --git a/src/LibC++/base_exception.h b/src/LibC++/base_exception.h deleted file mode 100644 index 8747688..0000000 --- a/src/LibC++/base_exception.h +++ /dev/null @@ -1,37 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <LibC++/__abi.h> -#include <LibC++/base_process.h> -#include <LibC++/defines.h> -#include <iostream> - -/// @author Amlal El Mahrouss (amlal@nekernel.org) - -namespace std::base_exception::abi { -inline constexpr int __terminate_id = 33; - -/// @note This function is internal, don't call it. -extern void __unwind_object_list(); - -inline void __throw_general(const char* what) { - std::cout << "LibC++: Unwinding exception of kind: " << what << ", aborting here..." << std::endl; - __unwind_object_list(); - base_process::exit(__terminate_id); -} - -inline void __throw_domain_error(const char* what) { - __throw_general(what); - __builtin_unreachable(); // prevent from continuing. -} - -inline void __throw_bad_array_new_length(const char* what) { - __throw_general(what); - __builtin_unreachable(); // prevent from continuing. -} -} // namespace std::base_exception::abi diff --git a/src/LibC++/base_math.h b/src/LibC++/base_math.h deleted file mode 100644 index 60b260e..0000000 --- a/src/LibC++/base_math.h +++ /dev/null @@ -1,88 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <LibC++/defines.h> - -#ifndef NAN -#define NAN (__builtin_nanf("")) -#endif // !NAN - -/// @file Math.h -/// @brief Math functions. - -#ifdef __LIBCXX_USE_DOUBLE__ -typedef double real_type; -#else -typedef float real_type; -#endif - -namespace std::base_math { -inline constexpr static auto not_a_number = NAN; - -/// =========================================================== /// -/// @brief Power function, with Repeat argument. -/// =========================================================== /// -template <size_t Exponent> -inline real_type pow(real_type in) { - if (Exponent == 0) return 1; // Any number to the power of 0 is 1. - - if (Exponent == 1) return in; // Any number to the power of 1 is itself. - - size_t cnt = Exponent; - - real_type result = 1; - - for (auto i = 0; i < cnt; ++i) result *= in; - - return result; -} - -/// =========================================================== /// -/// @brief Square root function. -/// =========================================================== /// -inline real_type sqrt(real_type in) { - if (in == 0) return 0; - if (in == not_a_number) return not_a_number; - - auto constexpr const static Base = 2; - - auto x = in / Base; - - for (int i = 0; i < 10; ++i) { - x = (x + in / x) / Base; - } - - return x; -} - -/// =========================================================== /// -/// @brief Square of function, with Base template argument. -/// @param of Base argument to find the square of. -/// =========================================================== /// -template <size_t Base> -inline real_type surd(real_type in) { - if (in == 0) return 0; - if (in == 1) return 1; - - if (Base == 1) return in; - if (Base == 2) return sqrt(in); - - return not_a_number; -} - -/// =========================================================== /// -/// @brief Linear interpolation equation solver. -/// @param from where? -/// @param to to? -/// @param Updated diff value according to difference. -/// =========================================================== /// -inline real_type lerp(real_type to, real_type from, real_type stat) { - real_type diff = (to - from); - return from + (diff * stat); -} -} // namespace std::base_math diff --git a/src/LibC++/base_process.h b/src/LibC++/base_process.h deleted file mode 100644 index cb25aa1..0000000 --- a/src/LibC++/base_process.h +++ /dev/null @@ -1,45 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <LibC++/defines.h> - -__init_decl() - - /// @brief CRT exit, with exit code (!!! exits all threads. !!!) - /// @param code the exit code. - /// @return the return > 0 for non successful. - extern int exit_(int code); - -/// @brief CRT signal handler. -/// @param code the signal code. -extern void signal_(int code); - -extern void (*__atexit_cdecl_ptr)(void); -extern void (**__atexit_lst_ptr)(void); -extern size_t __atexit_lst_cnt; - -__fini_decl() - - /// @brief Standard C++ namespace - namespace std::base_process { - inline int signal(int code) { - signal_(code); - return -1; - } - - inline int32_t exit(const int32_t& code) { - for (auto idx = 0UL; idx < __atexit_lst_cnt; ++idx) { - __atexit_lst_ptr[idx](); - } - - if (__atexit_cdecl_ptr) __atexit_cdecl_ptr(); - - exit_(code); - return -1; - } -} // namespace std::base_process diff --git a/src/LibC++/defines.h b/src/LibC++/defines.h deleted file mode 100644 index 6aac009..0000000 --- a/src/LibC++/defines.h +++ /dev/null @@ -1,81 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license. - -======================================== */ - -#ifndef __NECTI_DEFINES_H__ -#define __NECTI_DEFINES_H__ - -#define __ATTRIBUTE(X) __attribute__((X)) - -typedef __SIZE_TYPE__ size_t; -typedef __INT64_TYPE__ ssize_t; -typedef __INT32_TYPE__ int32_t; - -typedef void* ptr_type; -typedef __SIZE_TYPE__ size_type; - -typedef __INT64_TYPE__ ptrdiff_t; -typedef size_t uintptr_t; -typedef void* voidptr_t; -typedef void* any_t; -typedef char* caddr_t; - -#ifndef NULL -#define NULL ((voidptr_t) 0) -#endif // !null - -#define __alloca(sz) __ck_alloca(sz) - -#define __deref(ptr) (*(ptr)) - -#ifdef __cplusplus -#define __init_decl() extern "C" { -#define __fini_decl() \ - } \ - ; -#else -#define __init_decl() -#define __fini_decl() -#endif - -#if __has_builtin(__builtin_alloca) -#define alloca(sz) __builtin_alloca(sz) -#ifdef __alloca -#undef __alloca -#endif -#define __alloca alloca -#else -#warning !! alloca not detected !! -#endif - -typedef long long off_t; -typedef unsigned long long uoff_t; - -typedef union float_cast { - struct { - unsigned int mantissa : 23; - unsigned int exponent : 8; - unsigned int sign : 1; - }; - - float f; -} __ATTRIBUTE(packed) float_cast_t; - -typedef union double_cast { - struct { - unsigned long long int mantissa : 52; - unsigned int exponent : 11; - unsigned int sign : 1; - }; - - double f; -} __ATTRIBUTE(packed) double_cast_t; - -namespace std { -struct placement_t; -struct nothrow_t; -} // namespace std - -#endif /* __NECTI_DEFINES_H__ */ diff --git a/src/LibC++/filesystem.h b/src/LibC++/filesystem.h deleted file mode 100644 index 4627c50..0000000 --- a/src/LibC++/filesystem.h +++ /dev/null @@ -1,19 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license. - -======================================== */ - -#ifndef __NECTI_FS_H__ -#define __NECTI_FS_H__ - -#include <LibC++/defines.h> - -namespace std { -class path; -class filesystem_error; -class directory_entry; -class directory_iterator; -} // namespace std - -#endif // __NECTI_FS_H__
\ No newline at end of file diff --git a/src/LibC++/make-stdcpp-hdrs.sh b/src/LibC++/make-stdcpp-hdrs.sh deleted file mode 100755 index a3730de..0000000 --- a/src/LibC++/make-stdcpp-hdrs.sh +++ /dev/null @@ -1,13 +0,0 @@ -#! /bin/sh - -outputDir=libc++/ - -mkdir -p $outputDir - -for f in *.h; do - -#This line splits the file name on the delimiter "." -baseName=`echo $f | cut -d "." -f 1` -cp $f $outputDir$baseName - -done diff --git a/src/LibC++/new.cc b/src/LibC++/new.cc deleted file mode 100644 index 85ae82e..0000000 --- a/src/LibC++/new.cc +++ /dev/null @@ -1,7 +0,0 @@ -/* ======================================== - - Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <LibC++/new.h> diff --git a/src/LibC++/new.h b/src/LibC++/new.h deleted file mode 100644 index faa9da4..0000000 --- a/src/LibC++/new.h +++ /dev/null @@ -1,42 +0,0 @@ -/* ======================================== - - Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <LibC++/defines.h> - -namespace std { -struct nothrow_t final { - explicit nothrow_t() = default; - ~nothrow_t() = default; -}; - -struct placement_t final { - explicit placement_t() = default; - ~placement_t() = default; - - void* __base{}; - int32_t __align{}; - size_t __size{}; -}; -} // namespace std - -#ifndef __has_placement -#define placement -#endif - -void* operator new(size_t); -void* operator new[](size_t); - -void* operator new(size_t, const std::nothrow_t&) noexcept; -void* operator new(size_t, void*) noexcept; -void* operator new[](size_t, const std::nothrow_t&) noexcept; -void* operator new[](size_t, void*) noexcept; - -void operator delete(void*) noexcept; -void operator delete(void*, size_t) noexcept; - -void operator delete[](void*) noexcept; diff --git a/src/LibC++/utility.h b/src/LibC++/utility.h deleted file mode 100644 index 62096f5..0000000 --- a/src/LibC++/utility.h +++ /dev/null @@ -1,30 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license. - -======================================== */ - -#ifndef LIBCXX_UTILITY_H -#define LIBCXX_UTILITY_H - -namespace std { -/// @brief Forward object. -/// @tparam Args the object type. -/// @param arg the object. -/// @return object's rvalue -template <typename Args> -inline auto forward(Args& arg) -> Args&& { - return static_cast<const Args&&>(arg); -} - -/// @brief Move object. -/// @tparam Args the object type. -/// @param arg the object. -/// @return object's rvalue -template <typename Args> -inline auto move(Args&& arg) -> Args&& { - return static_cast<Args&&>(arg); -} -} // namespace std - -#endif // LIBCXX_UTILITY_H diff --git a/src/ThirdParty/Dialogs/Dialogs.h b/src/ThirdParty/Dialogs/Dialogs.h deleted file mode 100644 index f632026..0000000 --- a/src/ThirdParty/Dialogs/Dialogs.h +++ /dev/null @@ -1,1738 +0,0 @@ -// -// Portable File Dialogs -// -// Copyright © 2018–2022 Sam Hocevar <sam@hocevar.net> -// -// This library is free software. It comes without any warranty, to -// the extent permitted by applicable law. You can redistribute it -// and/or modify it under the terms of the Do What the Fuck You Want -// to Public License, Version 2, as published by the WTFPL Task Force. -// See http://www.wtfpl.net/ for more details. -// - -#pragma once - -#if _WIN32 -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN 1 -#endif -#include <commdlg.h> -#include <shellapi.h> -#include <shlobj.h> -#include <shobjidl.h> // IFileDialog -#include <strsafe.h> -#include <userenv.h> // GetUserProfileDirectory() -#include <windows.h> -#include <future> // std::async - -#elif __EMSCRIPTEN__ -#include <emscripten.h> - -#else -#ifndef _POSIX_C_SOURCE -#define _POSIX_C_SOURCE 2 // for popen() -#endif -#ifdef __APPLE__ -#ifndef _DARWIN_C_SOURCE -#define _DARWIN_C_SOURCE -#endif -#endif -#include <fcntl.h> // fcntl() -#include <pwd.h> // getpwnam() -#include <sys/stat.h> // stat() -#include <sys/wait.h> // waitpid() -#include <unistd.h> // read(), pipe(), dup2(), getuid() -#include <csignal> // ::kill, std::signal -#include <cstdio> // popen() -#include <cstdlib> // std::getenv() -#endif - -#include <chrono> // std::chrono -#include <iostream> // std::ostream -#include <map> // std::map -#include <memory> // std::shared_ptr -#include <regex> // std::regex -#include <set> // std::set -#include <string> // std::string -#include <thread> // std::mutex, std::this_thread - -// Versions of mingw64 g++ up to 9.3.0 do not have a complete IFileDialog -#ifndef PFD_HAS_IFILEDIALOG -#define PFD_HAS_IFILEDIALOG 1 -#if (defined __MINGW64__ || defined __MINGW32__) && defined __GXX_ABI_VERSION -#if __GXX_ABI_VERSION <= 1013 -#undef PFD_HAS_IFILEDIALOG -#define PFD_HAS_IFILEDIALOG 0 -#endif -#endif -#endif - -namespace pfd { - -enum class button { - cancel = -1, - ok, - yes, - no, - abort, - retry, - ignore, -}; - -enum class choice { - ok = 0, - ok_cancel, - yes_no, - yes_no_cancel, - retry_cancel, - abort_retry_ignore, -}; - -enum class icon { - info = 0, - warning, - error, - question, -}; - -// Additional option flags for various dialog constructors -enum class opt : uint8_t { - none = 0, - // For file open, allow multiselect. - multiselect = 0x1, - // For file save, force overwrite and disable the confirmation dialog. - force_overwrite = 0x2, - // For folder select, force path to be the provided argument instead - // of the last opened directory, which is the Microsoft-recommended, - // user-friendly behaviour. - force_path = 0x4, -}; - -inline opt operator|(opt a, opt b) { - return opt(uint8_t(a) | uint8_t(b)); -} -inline bool operator&(opt a, opt b) { - return bool(uint8_t(a) & uint8_t(b)); -} - -// The settings class, only exposing to the user a way to set verbose mode -// and to force a rescan of installed desktop helpers (zenity, kdialog…). -class settings { - public: - static bool available(); - - static void verbose(bool value); - static void rescan(); - - protected: - explicit settings(bool resync = false); - - bool check_program(std::string const& program); - - inline bool is_osascript() const; - inline bool is_zenity() const; - inline bool is_kdialog() const; - - enum class flag { - is_scanned = 0, - is_verbose, - - has_zenity, - has_matedialog, - has_qarma, - has_kdialog, - is_vista, - - max_flag, - }; - - // Static array of flags for internal state - bool const& flags(flag in_flag) const; - - // Non-const getter for the static array of flags - bool& flags(flag in_flag); -}; - -// Internal classes, not to be used by client applications -namespace internal { - - // Process wait timeout, in milliseconds - static int const default_wait_timeout = 20; - - class executor { - friend class dialog; - - public: - // High level function to get the result of a command - std::string result(int* exit_code = nullptr); - - // High level function to abort - bool kill(); - -#if _WIN32 - void start_func(std::function<std::string(int*)> const& fun); - static BOOL CALLBACK enum_windows_callback(HWND hwnd, LPARAM lParam); -#elif __EMSCRIPTEN__ - void start(int exit_code); -#else - void start_process(std::vector<std::string> const& command); -#endif - - ~executor(); - - protected: - bool ready(int timeout = default_wait_timeout); - void stop(); - - private: - bool m_running = false; - std::string m_stdout; - int m_exit_code = -1; -#if _WIN32 - std::future<std::string> m_future; - std::set<HWND> m_windows; - std::condition_variable m_cond; - std::mutex m_mutex; - DWORD m_tid; -#elif __EMSCRIPTEN__ || __NX__ - // FIXME: do something -#else - pid_t m_pid = 0; - int m_fd = -1; -#endif - }; - - class platform { - protected: -#if _WIN32 - // Helper class around LoadLibraryA() and GetProcAddress() with some safety - class dll { - public: - dll(std::string const& name); - ~dll(); - - template <typename T> - class proc { - public: - proc(dll const& lib, std::string const& sym) - : m_proc(reinterpret_cast<T*>((void*) ::GetProcAddress(lib.handle, sym.c_str()))) {} - - explicit operator bool() const { return m_proc != nullptr; } - operator T*() const { return m_proc; } - - private: - T* m_proc; - }; - - private: - HMODULE handle; - }; - - // Helper class around CoInitialize() and CoUnInitialize() - class ole32_dll : public dll { - public: - ole32_dll(); - ~ole32_dll(); - bool is_initialized(); - - private: - HRESULT m_state; - }; - - // Helper class around CreateActCtx() and ActivateActCtx() - class new_style_context { - public: - new_style_context(); - ~new_style_context(); - - private: - HANDLE create(); - ULONG_PTR m_cookie = 0; - }; -#endif - }; - - class dialog : protected settings, protected platform { - public: - bool ready(int timeout = default_wait_timeout) const; - bool kill() const; - - protected: - explicit dialog(); - - std::vector<std::string> desktop_helper() const; - static std::string buttons_to_name(choice _choice); - static std::string get_icon_name(icon _icon); - - std::string powershell_quote(std::string const& str) const; - std::string osascript_quote(std::string const& str) const; - std::string shell_quote(std::string const& str) const; - - // Keep handle to executing command - std::shared_ptr<executor> m_async; - }; - - class file_dialog : public dialog { - protected: - enum type { - open, - save, - folder, - }; - - file_dialog(type in_type, std::string const& title, std::string const& default_path = "", - std::vector<std::string> const& filters = {}, opt options = opt::none); - - protected: - std::string string_result(); - std::vector<std::string> vector_result(); - -#if _WIN32 - static int CALLBACK bffcallback(HWND hwnd, UINT uMsg, LPARAM, LPARAM pData); -#if PFD_HAS_IFILEDIALOG - std::string select_folder_vista(IFileDialog* ifd, bool force_path); -#endif - - std::wstring m_wtitle; - std::wstring m_wdefault_path; - - std::vector<std::string> m_vector_result; -#endif - }; - -} // namespace internal - -// -// The path class provides some platform-specific path constants -// - -class path : protected internal::platform { - public: - static std::string home(); - static std::string separator(); -}; - -// -// The notify widget -// - -class notify : public internal::dialog { - public: - notify(std::string const& title, std::string const& message, icon _icon = icon::info); -}; - -// -// The message widget -// - -class message : public internal::dialog { - public: - message(std::string const& title, std::string const& text, choice _choice = choice::ok_cancel, - icon _icon = icon::info); - - button result(); - - private: - // Some extra logic to map the exit code to button number - std::map<int, button> m_mappings; -}; - -// -// The open_file, save_file, and open_folder widgets -// - -class open_file : public internal::file_dialog { - public: - open_file(std::string const& title, std::string const& default_path = "", - std::vector<std::string> const& filters = {"All Files", "*"}, opt options = opt::none); - -#if defined(__has_cpp_attribute) -#if __has_cpp_attribute(deprecated) - // Backwards compatibility - [[deprecated("Use pfd::opt::multiselect instead of allow_multiselect")]] -#endif -#endif - open_file(std::string const& title, std::string const& default_path, - std::vector<std::string> const& filters, bool allow_multiselect); - - std::vector<std::string> result(); -}; - -class save_file : public internal::file_dialog { - public: - save_file(std::string const& title, std::string const& default_path = "", - std::vector<std::string> const& filters = {"All Files", "*"}, opt options = opt::none); - -#if defined(__has_cpp_attribute) -#if __has_cpp_attribute(deprecated) - // Backwards compatibility - [[deprecated("Use pfd::opt::force_overwrite instead of confirm_overwrite")]] -#endif -#endif - save_file(std::string const& title, std::string const& default_path, - std::vector<std::string> const& filters, bool confirm_overwrite); - - std::string result(); -}; - -class select_folder : public internal::file_dialog { - public: - select_folder(std::string const& title, std::string const& default_path = "", - opt options = opt::none); - - std::string result(); -}; - -// -// Below this are all the method implementations. You may choose to define the -// macro PFD_SKIP_IMPLEMENTATION everywhere before including this header except -// in one place. This may reduce compilation times. -// - -#if !defined PFD_SKIP_IMPLEMENTATION - -// internal free functions implementations - -namespace internal { - -#if _WIN32 - static inline std::wstring str2wstr(std::string const& str) { - int len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (int) str.size(), nullptr, 0); - std::wstring ret(len, '\0'); - MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (int) str.size(), (LPWSTR) ret.data(), - (int) ret.size()); - return ret; - } - - static inline std::string wstr2str(std::wstring const& str) { - int len = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), (int) str.size(), nullptr, 0, nullptr, - nullptr); - std::string ret(len, '\0'); - WideCharToMultiByte(CP_UTF8, 0, str.c_str(), (int) str.size(), (LPSTR) ret.data(), - (int) ret.size(), nullptr, nullptr); - return ret; - } - - static inline bool is_vista() { - OSVERSIONINFOEXW osvi; - memset(&osvi, 0, sizeof(osvi)); - DWORDLONG const mask = VerSetConditionMask( - VerSetConditionMask(VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL), - VER_MINORVERSION, VER_GREATER_EQUAL), - VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); - osvi.dwOSVersionInfoSize = sizeof(osvi); - osvi.dwMajorVersion = HIBYTE(_WIN32_WINNT_VISTA); - osvi.dwMinorVersion = LOBYTE(_WIN32_WINNT_VISTA); - osvi.wServicePackMajor = 0; - - return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, - mask) != FALSE; - } -#endif - - // This is necessary until C++20 which will have std::string::ends_with() etc. - - static inline bool ends_with(std::string const& str, std::string const& suffix) { - return suffix.size() <= str.size() && - str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0; - } - - static inline bool starts_with(std::string const& str, std::string const& prefix) { - return prefix.size() <= str.size() && str.compare(0, prefix.size(), prefix) == 0; - } - - // This is necessary until C++17 which will have std::filesystem::is_directory - - static inline bool is_directory(std::string const& path) { -#if _WIN32 - auto attr = GetFileAttributesA(path.c_str()); - return attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY); -#elif __EMSCRIPTEN__ - // TODO - return false; -#else - struct stat s; - return stat(path.c_str(), &s) == 0 && S_ISDIR(s.st_mode); -#endif - } - - // This is necessary because getenv is not thread-safe - - static inline std::string getenv(std::string const& str) { -#if _MSC_VER - char* buf = nullptr; - size_t size = 0; - if (_dupenv_s(&buf, &size, str.c_str()) == 0 && buf) { - std::string ret(buf); - free(buf); - return ret; - } - return ""; -#else - auto buf = std::getenv(str.c_str()); - return buf ? buf : ""; -#endif - } - -} // namespace internal - -// settings implementation - -inline settings::settings(bool resync) { - flags(flag::is_scanned) &= !resync; - - if (flags(flag::is_scanned)) return; - - auto pfd_verbose = internal::getenv("PFD_VERBOSE"); - auto match_no = std::regex("(|0|no|false)", std::regex_constants::icase); - if (!std::regex_match(pfd_verbose, match_no)) flags(flag::is_verbose) = true; - -#if _WIN32 - flags(flag::is_vista) = internal::is_vista(); -#elif !__APPLE__ - flags(flag::has_zenity) = check_program("zenity"); - flags(flag::has_matedialog) = check_program("matedialog"); - flags(flag::has_qarma) = check_program("qarma"); - flags(flag::has_kdialog) = check_program("kdialog"); - - // If multiple helpers are available, try to default to the best one - if (flags(flag::has_zenity) && flags(flag::has_kdialog)) { - auto desktop_name = internal::getenv("XDG_SESSION_DESKTOP"); - if (desktop_name == std::string("gnome")) - flags(flag::has_kdialog) = false; - else if (desktop_name == std::string("KDE")) - flags(flag::has_zenity) = false; - } -#endif - - flags(flag::is_scanned) = true; -} - -inline bool settings::available() { -#if _WIN32 - return true; -#elif __APPLE__ - return true; -#elif __EMSCRIPTEN__ - // FIXME: Return true after implementation is complete. - return false; -#else - settings tmp; - return tmp.flags(flag::has_zenity) || tmp.flags(flag::has_matedialog) || - tmp.flags(flag::has_qarma) || tmp.flags(flag::has_kdialog); -#endif -} - -inline void settings::verbose(bool value) { - settings().flags(flag::is_verbose) = value; -} - -inline void settings::rescan() { - settings(/* resync = */ true); -} - -// Check whether a program is present using “which”. -inline bool settings::check_program(std::string const& program) { -#if _WIN32 - (void) program; - return false; -#elif __EMSCRIPTEN__ - (void) program; - return false; -#else - int exit_code = -1; - internal::executor async; - async.start_process({"/bin/sh", "-c", "which " + program}); - async.result(&exit_code); - return exit_code == 0; -#endif -} - -inline bool settings::is_osascript() const { -#if __APPLE__ - return true; -#else - return false; -#endif -} - -inline bool settings::is_zenity() const { - return flags(flag::has_zenity) || flags(flag::has_matedialog) || flags(flag::has_qarma); -} - -inline bool settings::is_kdialog() const { - return flags(flag::has_kdialog); -} - -inline bool const& settings::flags(flag in_flag) const { - static bool flags[size_t(flag::max_flag)]; - return flags[size_t(in_flag)]; -} - -inline bool& settings::flags(flag in_flag) { - return const_cast<bool&>(static_cast<settings const*>(this)->flags(in_flag)); -} - -// path implementation -inline std::string path::home() { -#if _WIN32 - // First try the USERPROFILE environment variable - auto user_profile = internal::getenv("USERPROFILE"); - if (user_profile.size() > 0) return user_profile; - // Otherwise, try GetUserProfileDirectory() - HANDLE token = nullptr; - DWORD len = MAX_PATH; - char buf[MAX_PATH] = {'\0'}; - if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) { - dll userenv("userenv.dll"); - dll::proc<BOOL WINAPI(HANDLE, LPSTR, LPDWORD)> get_user_profile_directory( - userenv, "GetUserProfileDirectoryA"); - get_user_profile_directory(token, buf, &len); - CloseHandle(token); - if (*buf) return buf; - } -#elif __EMSCRIPTEN__ - return "/"; -#else - // First try the HOME environment variable - auto home = internal::getenv("HOME"); - if (home.size() > 0) return home; - // Otherwise, try getpwuid_r() - size_t len = 4096; -#if defined(_SC_GETPW_R_SIZE_MAX) - auto size_max = sysconf(_SC_GETPW_R_SIZE_MAX); - if (size_max != -1) len = size_t(size_max); -#endif - std::vector<char> buf(len); - struct passwd pwd, *result; - if (getpwuid_r(getuid(), &pwd, buf.data(), buf.size(), &result) == 0) return result->pw_dir; -#endif - return "/"; -} - -inline std::string path::separator() { -#if _WIN32 - return "\\"; -#else - return "/"; -#endif -} - -// executor implementation - -inline std::string internal::executor::result(int* exit_code /* = nullptr */) { - stop(); - if (exit_code) *exit_code = m_exit_code; - return m_stdout; -} - -inline bool internal::executor::kill() { -#if _WIN32 - if (m_future.valid()) { - // Close all windows that weren’t open when we started the future - auto previous_windows = m_windows; - EnumWindows(&enum_windows_callback, (LPARAM) this); - for (auto hwnd : m_windows) - if (previous_windows.find(hwnd) == previous_windows.end()) { - SendMessage(hwnd, WM_CLOSE, 0, 0); - // Also send IDNO in case of a Yes/No or Abort/Retry/Ignore messagebox - SendMessage(hwnd, WM_COMMAND, IDNO, 0); - } - } -#elif __EMSCRIPTEN__ || __NX__ - // FIXME: do something - return false; // cannot kill -#else - ::kill(m_pid, SIGKILL); -#endif - stop(); - return true; -} - -#if _WIN32 -inline BOOL CALLBACK internal::executor::enum_windows_callback(HWND hwnd, LPARAM lParam) { - auto that = (executor*) lParam; - - DWORD pid; - auto tid = GetWindowThreadProcessId(hwnd, &pid); - if (tid == that->m_tid) that->m_windows.insert(hwnd); - return TRUE; -} -#endif - -#if _WIN32 -inline void internal::executor::start_func(std::function<std::string(int*)> const& fun) { - stop(); - - auto trampoline = [fun, this]() { - // Save our thread id so that the caller can cancel us - m_tid = GetCurrentThreadId(); - EnumWindows(&enum_windows_callback, (LPARAM) this); - m_cond.notify_all(); - return fun(&m_exit_code); - }; - - std::unique_lock<std::mutex> lock(m_mutex); - m_future = std::async(std::launch::async, trampoline); - m_cond.wait(lock); - m_running = true; -} - -#elif __EMSCRIPTEN__ -inline void internal::executor::start(int exit_code) { - m_exit_code = exit_code; -} - -#else -inline void internal::executor::start_process(std::vector<std::string> const& command) { - stop(); - m_stdout.clear(); - m_exit_code = -1; - - int in[2], out[2]; - if (pipe(in) != 0 || pipe(out) != 0) return; - - m_pid = fork(); - if (m_pid < 0) return; - - close(in[m_pid ? 0 : 1]); - close(out[m_pid ? 1 : 0]); - - if (m_pid == 0) { - dup2(in[0], STDIN_FILENO); - dup2(out[1], STDOUT_FILENO); - - // Ignore stderr so that it doesn’t pollute the console (e.g. GTK+ errors from zenity) - int fd = open("/src/null", O_WRONLY); - dup2(fd, STDERR_FILENO); - close(fd); - - std::vector<char*> args; - std::transform(command.cbegin(), command.cend(), std::back_inserter(args), - [](std::string const& s) { return const_cast<char*>(s.c_str()); }); - args.push_back(nullptr); // null-terminate argv[] - - execvp(args[0], args.data()); - exit(1); - } - - close(in[1]); - m_fd = out[0]; - auto flags = fcntl(m_fd, F_GETFL); - fcntl(m_fd, F_SETFL, flags | O_NONBLOCK); - - m_running = true; -} -#endif - -inline internal::executor::~executor() { - stop(); -} - -inline bool internal::executor::ready(int timeout /* = default_wait_timeout */) { - if (!m_running) return true; - -#if _WIN32 - if (m_future.valid()) { - auto status = m_future.wait_for(std::chrono::milliseconds(timeout)); - if (status != std::future_status::ready) { - // On Windows, we need to run the message pump. If the async - // thread uses a Windows API dialog, it may be attached to the - // main thread and waiting for messages that only we can dispatch. - MSG msg; - while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - return false; - } - - m_stdout = m_future.get(); - } -#elif __EMSCRIPTEN__ || __NX__ - // FIXME: do something - (void) timeout; -#else - char buf[BUFSIZ]; - ssize_t received = read(m_fd, buf, BUFSIZ); // Flawfinder: ignore - if (received > 0) { - m_stdout += std::string(buf, received); - return false; - } - - // Reap child process if it is dead. It is possible that the system has already reaped it - // (this happens when the calling application handles or ignores SIG_CHLD) and results in - // waitpid() failing with ECHILD. Otherwise we assume the child is running and we sleep for - // a little while. - int status; - pid_t child = waitpid(m_pid, &status, WNOHANG); - if (child != m_pid && (child >= 0 || errno != ECHILD)) { - // FIXME: this happens almost always at first iteration - std::this_thread::sleep_for(std::chrono::milliseconds(timeout)); - return false; - } - - close(m_fd); - m_exit_code = WEXITSTATUS(status); -#endif - - m_running = false; - return true; -} - -inline void internal::executor::stop() { - // Loop until the user closes the dialog - while (!ready()); -} - -// dll implementation - -#if _WIN32 -inline internal::platform::dll::dll(std::string const& name) - : handle(::LoadLibraryA(name.c_str())) {} - -inline internal::platform::dll::~dll() { - if (handle) ::FreeLibrary(handle); -} -#endif // _WIN32 - -// ole32_dll implementation - -#if _WIN32 -inline internal::platform::ole32_dll::ole32_dll() : dll("ole32.dll") { - // Use COINIT_MULTITHREADED because COINIT_APARTMENTTHREADED causes crashes. - // See https://github.com/samhocevar/portable-file-dialogs/issues/51 - auto coinit = proc<HRESULT WINAPI(LPVOID, DWORD)>(*this, "CoInitializeEx"); - m_state = coinit(nullptr, COINIT_MULTITHREADED); -} - -inline internal::platform::ole32_dll::~ole32_dll() { - if (is_initialized()) proc<void WINAPI()>(*this, "CoUninitialize")(); -} - -inline bool internal::platform::ole32_dll::is_initialized() { - return m_state == S_OK || m_state == S_FALSE; -} -#endif - -// new_style_context implementation - -#if _WIN32 -inline internal::platform::new_style_context::new_style_context() { - // Only create one activation context for the whole app lifetime. - static HANDLE hctx = create(); - - if (hctx != INVALID_HANDLE_VALUE) ActivateActCtx(hctx, &m_cookie); -} - -inline internal::platform::new_style_context::~new_style_context() { - DeactivateActCtx(0, m_cookie); -} - -inline HANDLE internal::platform::new_style_context::create() { - // This “hack” seems to be necessary for this code to work on windows XP. - // Without it, dialogs do not show and close immediately. GetError() - // returns 0 so I don’t know what causes this. I was not able to reproduce - // this behavior on Windows 7 and 10 but just in case, let it be here for - // those versions too. - // This hack is not required if other dialogs are used (they load comdlg32 - // automatically), only if message boxes are used. - dll comdlg32("comdlg32.dll"); - - // Using approach as shown here: https://stackoverflow.com/a/10444161 - UINT len = ::GetSystemDirectoryA(nullptr, 0); - std::string sys_dir(len, '\0'); - ::GetSystemDirectoryA(&sys_dir[0], len); - - ACTCTXA act_ctx = { - // Do not set flag ACTCTX_FLAG_SET_PROCESS_DEFAULT, since it causes a - // crash with error “default context is already set”. - sizeof(act_ctx), - ACTCTX_FLAG_RESOURCE_NAME_VALID | ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID, - "shell32.dll", - 0, - 0, - sys_dir.c_str(), - (LPCSTR) 124, - nullptr, - 0, - }; - - return ::CreateActCtxA(&act_ctx); -} -#endif // _WIN32 - -// dialog implementation - -inline bool internal::dialog::ready(int timeout /* = default_wait_timeout */) const { - return m_async->ready(timeout); -} - -inline bool internal::dialog::kill() const { - return m_async->kill(); -} - -inline internal::dialog::dialog() : m_async(std::make_shared<executor>()) {} - -inline std::vector<std::string> internal::dialog::desktop_helper() const { -#if __APPLE__ - return {"osascript"}; -#else - return {flags(flag::has_zenity) ? "zenity" - : flags(flag::has_matedialog) ? "matedialog" - : flags(flag::has_qarma) ? "qarma" - : flags(flag::has_kdialog) ? "kdialog" - : "echo"}; -#endif -} - -inline std::string internal::dialog::buttons_to_name(choice _choice) { - switch (_choice) { - case choice::ok_cancel: - return "okcancel"; - case choice::yes_no: - return "yesno"; - case choice::yes_no_cancel: - return "yesnocancel"; - case choice::retry_cancel: - return "retrycancel"; - case choice::abort_retry_ignore: - return "abortretryignore"; - /* case choice::ok: */ default: - return "ok"; - } -} - -inline std::string internal::dialog::get_icon_name(icon _icon) { - switch (_icon) { - case icon::warning: - return "warning"; - case icon::error: - return "error"; - case icon::question: - return "question"; - // Zenity wants "information" but WinForms wants "info" - /* case icon::info: */ default: -#if _WIN32 - return "info"; -#else - return "information"; -#endif - } -} - -// This is only used for debugging purposes -inline std::ostream& operator<<(std::ostream& s, std::vector<std::string> const& v) { - int not_first = 0; - for (auto& e : v) s << (not_first++ ? " " : "") << e; - return s; -} - -// Properly quote a string for Powershell: replace ' or " with '' or "" -// FIXME: we should probably get rid of newlines! -// FIXME: the \" sequence seems unsafe, too! -// XXX: this is no longer used but I would like to keep it around just in case -inline std::string internal::dialog::powershell_quote(std::string const& str) const { - return "'" + std::regex_replace(str, std::regex("['\"]"), "$&$&") + "'"; -} - -// Properly quote a string for osascript: replace \ or " with \\ or \" -// XXX: this also used to replace ' with \' when popen was used, but it would be -// smarter to do shell_quote(osascript_quote(...)) if this is needed again. -inline std::string internal::dialog::osascript_quote(std::string const& str) const { - return "\"" + std::regex_replace(str, std::regex("[\\\\\"]"), "\\$&") + "\""; -} - -// Properly quote a string for the shell: just replace ' with '\'' -// XXX: this is no longer used but I would like to keep it around just in case -inline std::string internal::dialog::shell_quote(std::string const& str) const { - return "'" + std::regex_replace(str, std::regex("'"), "'\\''") + "'"; -} - -// file_dialog implementation - -inline internal::file_dialog::file_dialog(type in_type, std::string const& title, - std::string const& default_path /* = "" */, - std::vector<std::string> const& filters /* = {} */, - opt options /* = opt::none */) { -#if _WIN32 - std::string filter_list; - std::regex whitespace(" *"); - for (size_t i = 0; i + 1 < filters.size(); i += 2) { - filter_list += filters[i] + '\0'; - filter_list += std::regex_replace(filters[i + 1], whitespace, ";") + '\0'; - } - filter_list += '\0'; - - m_async->start_func( - [this, in_type, title, default_path, filter_list, options](int* exit_code) -> std::string { - (void) exit_code; - m_wtitle = internal::str2wstr(title); - m_wdefault_path = internal::str2wstr(default_path); - auto wfilter_list = internal::str2wstr(filter_list); - - // Initialise COM. This is required for the new folder selection window, - // (see https://github.com/samhocevar/portable-file-dialogs/pull/21) - // and to avoid random crashes with GetOpenFileNameW() (see - // https://github.com/samhocevar/portable-file-dialogs/issues/51) - ole32_dll ole32; - - // Folder selection uses a different method - if (in_type == type::folder) { -#if PFD_HAS_IFILEDIALOG - if (flags(flag::is_vista)) { - // On Vista and higher we should be able to use IFileDialog for folder selection - IFileDialog* ifd; - HRESULT hr = dll::proc<HRESULT WINAPI(REFCLSID, LPUNKNOWN, DWORD, REFIID, LPVOID*)>( - ole32, "CoCreateInstance")(CLSID_FileOpenDialog, nullptr, CLSCTX_INPROC_SERVER, - IID_PPV_ARGS(&ifd)); - - // In case CoCreateInstance fails (which it should not), try legacy approach - if (SUCCEEDED(hr)) return select_folder_vista(ifd, options & opt::force_path); - } -#endif - - BROWSEINFOW bi; - memset(&bi, 0, sizeof(bi)); - - bi.lpfn = &bffcallback; - bi.lParam = (LPARAM) this; - - if (flags(flag::is_vista)) { - if (ole32.is_initialized()) bi.ulFlags |= BIF_NEWDIALOGSTYLE; - bi.ulFlags |= BIF_EDITBOX; - bi.ulFlags |= BIF_STATUSTEXT; - } - - auto* list = SHBrowseForFolderW(&bi); - std::string ret; - if (list) { - auto buffer = new wchar_t[MAX_PATH]; - SHGetPathFromIDListW(list, buffer); - dll::proc<void WINAPI(LPVOID)>(ole32, "CoTaskMemFree")(list); - ret = internal::wstr2str(buffer); - delete[] buffer; - } - return ret; - } - - OPENFILENAMEW ofn; - memset(&ofn, 0, sizeof(ofn)); - ofn.lStructSize = sizeof(OPENFILENAMEW); - ofn.hwndOwner = GetActiveWindow(); - - ofn.lpstrFilter = wfilter_list.c_str(); - - auto woutput = std::wstring(MAX_PATH * 256, L'\0'); - ofn.lpstrFile = (LPWSTR) woutput.data(); - ofn.nMaxFile = (DWORD) woutput.size(); - if (!m_wdefault_path.empty()) { - // If a directory was provided, use it as the initial directory. If - // a valid path was provided, use it as the initial file. Otherwise, - // let the Windows API decide. - auto path_attr = GetFileAttributesW(m_wdefault_path.c_str()); - if (path_attr != INVALID_FILE_ATTRIBUTES && (path_attr & FILE_ATTRIBUTE_DIRECTORY)) - ofn.lpstrInitialDir = m_wdefault_path.c_str(); - else if (m_wdefault_path.size() <= woutput.size()) - // second argument is size of buffer, not length of string - StringCchCopyW(ofn.lpstrFile, MAX_PATH * 256 + 1, m_wdefault_path.c_str()); - else { - ofn.lpstrFileTitle = (LPWSTR) m_wdefault_path.data(); - ofn.nMaxFileTitle = (DWORD) m_wdefault_path.size(); - } - } - ofn.lpstrTitle = m_wtitle.c_str(); - ofn.Flags = OFN_NOCHANGEDIR | OFN_EXPLORER; - - dll comdlg32("comdlg32.dll"); - - // Apply new visual style (required for windows XP) - new_style_context ctx; - - if (in_type == type::save) { - if (!(options & opt::force_overwrite)) ofn.Flags |= OFN_OVERWRITEPROMPT; - - dll::proc<BOOL WINAPI(LPOPENFILENAMEW)> get_save_file_name(comdlg32, "GetSaveFileNameW"); - if (get_save_file_name(&ofn) == 0) return ""; - return internal::wstr2str(woutput.c_str()); - } else { - if (options & opt::multiselect) ofn.Flags |= OFN_ALLOWMULTISELECT; - ofn.Flags |= OFN_PATHMUSTEXIST; - - dll::proc<BOOL WINAPI(LPOPENFILENAMEW)> get_open_file_name(comdlg32, "GetOpenFileNameW"); - if (get_open_file_name(&ofn) == 0) return ""; - } - - std::string prefix; - for (wchar_t const* p = woutput.c_str(); *p;) { - auto filename = internal::wstr2str(p); - p += wcslen(p); - // In multiselect mode, we advance p one wchar further and - // check for another filename. If there is one and the - // prefix is empty, it means we just read the prefix. - if ((options & opt::multiselect) && *++p && prefix.empty()) { - prefix = filename + "/"; - continue; - } - - m_vector_result.push_back(prefix + filename); - } - - return ""; - }); -#elif __EMSCRIPTEN__ - // FIXME: do something - (void) in_type; - (void) title; - (void) default_path; - (void) filters; - (void) options; -#else - auto command = desktop_helper(); - - if (is_osascript()) { - std::string script = "set ret to choose"; - switch (in_type) { - case type::save: - script += " file name"; - break; - case type::open: - default: - script += " file"; - if (options & opt::multiselect) script += " with multiple selections allowed"; - break; - case type::folder: - script += " folder"; - break; - } - - if (default_path.size()) { - if (in_type == type::folder || is_directory(default_path)) - script += " default location "; - else - script += " default name "; - script += osascript_quote(default_path); - } - - script += " with prompt " + osascript_quote(title); - - if (in_type == type::open) { - // Concatenate all user-provided filter patterns - std::string patterns; - for (size_t i = 0; i < filters.size() / 2; ++i) patterns += " " + filters[2 * i + 1]; - - // Split the pattern list to check whether "*" is in there; if it - // is, we have to disable filters because there is no mechanism in - // OS X for the user to override the filter. - std::regex sep("\\s+"); - std::string filter_list; - bool has_filter = true; - std::sregex_token_iterator iter(patterns.begin(), patterns.end(), sep, -1); - std::sregex_token_iterator end; - for (; iter != end; ++iter) { - auto pat = iter->str(); - if (pat == "*" || pat == "*.*") - has_filter = false; - else if (internal::starts_with(pat, "*.")) - filter_list += "," + osascript_quote(pat.substr(2, pat.size() - 2)); - } - - if (has_filter && filter_list.size() > 0) { - // There is a weird AppleScript bug where file extensions of length != 3 are - // ignored, e.g. type{"txt"} works, but type{"json"} does not. Fortunately if - // the whole list starts with a 3-character extension, everything works again. - // We use "///" for such an extension because we are sure it cannot appear in - // an actual filename. - script += " of type {\"///\"" + filter_list + "}"; - } - } - - if (in_type == type::open && (options & opt::multiselect)) { - script += "\nset s to \"\""; - script += "\nrepeat with i in ret"; - script += "\n set s to s & (POSIX path of i) & \"\\n\""; - script += "\nend repeat"; - script += "\ncopy s to stdout"; - } else { - script += "\nPOSIX path of ret"; - } - - command.push_back("-e"); - command.push_back(script); - } else if (is_zenity()) { - command.push_back("--file-selection"); - - // If the default path is a directory, make sure it ends with "/" otherwise zenity will - // open the file dialog in the parent directory. - auto filename_arg = "--filename=" + default_path; - if (in_type != type::folder && !ends_with(default_path, "/") && - internal::is_directory(default_path)) - filename_arg += "/"; - command.push_back(filename_arg); - - command.push_back("--title"); - command.push_back(title); - command.push_back("--separator=\n"); - - for (size_t i = 0; i < filters.size() / 2; ++i) { - command.push_back("--file-filter"); - command.push_back(filters[2 * i] + "|" + filters[2 * i + 1]); - } - - if (in_type == type::save) command.push_back("--save"); - if (in_type == type::folder) command.push_back("--directory"); - if (!(options & opt::force_overwrite)) command.push_back("--confirm-overwrite"); - if (options & opt::multiselect) command.push_back("--multiple"); - } else if (is_kdialog()) { - switch (in_type) { - case type::save: - command.push_back("--getsavefilename"); - break; - case type::open: - command.push_back("--getopenfilename"); - break; - case type::folder: - command.push_back("--getexistingdirectory"); - break; - } - if (options & opt::multiselect) { - command.push_back("--multiple"); - command.push_back("--separate-output"); - } - - command.push_back(default_path); - - std::string filter; - for (size_t i = 0; i < filters.size() / 2; ++i) - filter += (i == 0 ? "" : " | ") + filters[2 * i] + "(" + filters[2 * i + 1] + ")"; - command.push_back(filter); - - command.push_back("--title"); - command.push_back(title); - } - - if (flags(flag::is_verbose)) std::cerr << "pfd: " << command << std::endl; - - m_async->start_process(command); -#endif -} - -inline std::string internal::file_dialog::string_result() { -#if _WIN32 - return m_async->result(); -#else - auto ret = m_async->result(); - // Strip potential trailing newline (zenity). Also strip trailing slash - // added by osascript for consistency with other backends. - while (!ret.empty() && (ret.back() == '\n' || ret.back() == '/')) ret.pop_back(); - return ret; -#endif -} - -inline std::vector<std::string> internal::file_dialog::vector_result() { -#if _WIN32 - m_async->result(); - return m_vector_result; -#else - std::vector<std::string> ret; - auto result = m_async->result(); - for (;;) { - // Split result along newline characters - auto i = result.find('\n'); - if (i == 0 || i == std::string::npos) break; - ret.push_back(result.substr(0, i)); - result = result.substr(i + 1, result.size()); - } - return ret; -#endif -} - -#if _WIN32 -// Use a static function to pass as BFFCALLBACK for legacy folder select -inline int CALLBACK internal::file_dialog::bffcallback(HWND hwnd, UINT uMsg, LPARAM, LPARAM pData) { - auto inst = (file_dialog*) pData; - switch (uMsg) { - case BFFM_INITIALIZED: - SendMessage(hwnd, BFFM_SETSELECTIONW, TRUE, (LPARAM) inst->m_wdefault_path.c_str()); - break; - } - return 0; -} - -#if PFD_HAS_IFILEDIALOG -inline std::string internal::file_dialog::select_folder_vista(IFileDialog* ifd, bool force_path) { - std::string result; - - IShellItem* folder; - - // Load library at runtime so app doesn't link it at load time (which will fail on windows XP) - dll shell32("shell32.dll"); - dll::proc<HRESULT WINAPI(PCWSTR, IBindCtx*, REFIID, void**)> create_item( - shell32, "SHCreateItemFromParsingName"); - - if (!create_item) return ""; - - auto hr = create_item(m_wdefault_path.c_str(), nullptr, IID_PPV_ARGS(&folder)); - - // Set default folder if found. This only sets the default folder. If - // Windows has any info about the most recently selected folder, it - // will display it instead. Generally, calling SetFolder() to set the - // current directory “is not a good or expected user experience and - // should therefore be avoided”: - // https://docs.microsoft.com/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifiledialog-setfolder - if (SUCCEEDED(hr)) { - if (force_path) - ifd->SetFolder(folder); - else - ifd->SetDefaultFolder(folder); - folder->Release(); - } - - // Set the dialog title and option to select folders - ifd->SetOptions(FOS_PICKFOLDERS | FOS_FORCEFILESYSTEM); - ifd->SetTitle(m_wtitle.c_str()); - - hr = ifd->Show(GetActiveWindow()); - if (SUCCEEDED(hr)) { - IShellItem* item; - hr = ifd->GetResult(&item); - if (SUCCEEDED(hr)) { - wchar_t* wname = nullptr; - // This is unlikely to fail because we use FOS_FORCEFILESYSTEM, but try - // to output a debug message just in case. - if (SUCCEEDED(item->GetDisplayName(SIGDN_FILESYSPATH, &wname))) { - result = internal::wstr2str(std::wstring(wname)); - dll::proc<void WINAPI(LPVOID)>(ole32_dll(), "CoTaskMemFree")(wname); - } else { - if (SUCCEEDED(item->GetDisplayName(SIGDN_NORMALDISPLAY, &wname))) { - auto name = internal::wstr2str(std::wstring(wname)); - dll::proc<void WINAPI(LPVOID)>(ole32_dll(), "CoTaskMemFree")(wname); - std::cerr << "pfd: failed to get path for " << name << std::endl; - } else - std::cerr << "pfd: item of unknown type selected" << std::endl; - } - - item->Release(); - } - } - - ifd->Release(); - - return result; -} -#endif -#endif - -// notify implementation - -inline notify::notify(std::string const& title, std::string const& message, - icon _icon /* = icon::info */) { - if (_icon == icon::question) // Not supported by notifications - _icon = icon::info; - -#if _WIN32 - // Use a static shared pointer for notify_icon so that we can delete - // it whenever we need to display a new one, and we can also wait - // until the program has finished running. - struct notify_icon_data : public NOTIFYICONDATAW { - ~notify_icon_data() { Shell_NotifyIconW(NIM_DELETE, this); } - }; - - static std::shared_ptr<notify_icon_data> nid; - - // Release the previous notification icon, if any, and allocate a new - // one. Note that std::make_shared() does value initialization, so there - // is no need to memset the structure. - nid = nullptr; - nid = std::make_shared<notify_icon_data>(); - - // For XP support - nid->cbSize = NOTIFYICONDATAW_V2_SIZE; - nid->hWnd = nullptr; - nid->uID = 0; - - // Flag Description: - // - NIF_ICON The hIcon member is valid. - // - NIF_MESSAGE The uCallbackMessage member is valid. - // - NIF_TIP The szTip member is valid. - // - NIF_STATE The dwState and dwStateMask members are valid. - // - NIF_INFO Use a balloon ToolTip instead of a standard ToolTip. The szInfo, uTimeout, - // szInfoTitle, and dwInfoFlags members are valid. - // - NIF_GUID Reserved. - nid->uFlags = NIF_MESSAGE | NIF_ICON | NIF_INFO; - - // Flag Description - // - NIIF_ERROR An error icon. - // - NIIF_INFO An information icon. - // - NIIF_NONE No icon. - // - NIIF_WARNING A warning icon. - // - NIIF_ICON_MASK Version 6.0. Reserved. - // - NIIF_NOSOUND Version 6.0. Do not play the associated sound. Applies only to balloon - // ToolTips - switch (_icon) { - case icon::warning: - nid->dwInfoFlags = NIIF_WARNING; - break; - case icon::error: - nid->dwInfoFlags = NIIF_ERROR; - break; - /* case icon::info: */ default: - nid->dwInfoFlags = NIIF_INFO; - break; - } - - ENUMRESNAMEPROC icon_enum_callback = [](HMODULE, LPCTSTR, LPTSTR lpName, - LONG_PTR lParam) -> BOOL { - ((NOTIFYICONDATAW*) lParam)->hIcon = ::LoadIcon(GetModuleHandle(nullptr), lpName); - return false; - }; - - nid->hIcon = ::LoadIcon(nullptr, IDI_APPLICATION); - ::EnumResourceNames(nullptr, RT_GROUP_ICON, icon_enum_callback, (LONG_PTR) nid.get()); - - nid->uTimeout = 5000; - - StringCchCopyW(nid->szInfoTitle, ARRAYSIZE(nid->szInfoTitle), internal::str2wstr(title).c_str()); - StringCchCopyW(nid->szInfo, ARRAYSIZE(nid->szInfo), internal::str2wstr(message).c_str()); - - // Display the new icon - Shell_NotifyIconW(NIM_ADD, nid.get()); -#elif __EMSCRIPTEN__ - // FIXME: do something - (void) title; - (void) message; -#else - auto command = desktop_helper(); - - if (is_osascript()) { - command.push_back("-e"); - command.push_back("display notification " + osascript_quote(message) + " with title " + - osascript_quote(title)); - } else if (is_zenity()) { - command.push_back("--notification"); - command.push_back("--window-icon"); - command.push_back(get_icon_name(_icon)); - command.push_back("--text"); - command.push_back(title + "\n" + message); - } else if (is_kdialog()) { - command.push_back("--icon"); - command.push_back(get_icon_name(_icon)); - command.push_back("--title"); - command.push_back(title); - command.push_back("--passivepopup"); - command.push_back(message); - command.push_back("5"); - } - - if (flags(flag::is_verbose)) std::cerr << "pfd: " << command << std::endl; - - m_async->start_process(command); -#endif -} - -// message implementation - -inline message::message(std::string const& title, std::string const& text, - choice _choice /* = choice::ok_cancel */, icon _icon /* = icon::info */) { -#if _WIN32 - // Use MB_SYSTEMMODAL rather than MB_TOPMOST to ensure the message window is brought - // to front. See https://github.com/samhocevar/portable-file-dialogs/issues/52 - UINT style = MB_SYSTEMMODAL; - switch (_icon) { - case icon::warning: - style |= MB_ICONWARNING; - break; - case icon::error: - style |= MB_ICONERROR; - break; - case icon::question: - style |= MB_ICONQUESTION; - break; - /* case icon::info: */ default: - style |= MB_ICONINFORMATION; - break; - } - - switch (_choice) { - case choice::ok_cancel: - style |= MB_OKCANCEL; - break; - case choice::yes_no: - style |= MB_YESNO; - break; - case choice::yes_no_cancel: - style |= MB_YESNOCANCEL; - break; - case choice::retry_cancel: - style |= MB_RETRYCANCEL; - break; - case choice::abort_retry_ignore: - style |= MB_ABORTRETRYIGNORE; - break; - /* case choice::ok: */ default: - style |= MB_OK; - break; - } - - m_mappings[IDCANCEL] = button::cancel; - m_mappings[IDOK] = button::ok; - m_mappings[IDYES] = button::yes; - m_mappings[IDNO] = button::no; - m_mappings[IDABORT] = button::abort; - m_mappings[IDRETRY] = button::retry; - m_mappings[IDIGNORE] = button::ignore; - - m_async->start_func([text, title, style](int* exit_code) -> std::string { - auto wtext = internal::str2wstr(text); - auto wtitle = internal::str2wstr(title); - // Apply new visual style (required for all Windows versions) - new_style_context ctx; - *exit_code = MessageBoxW(GetActiveWindow(), wtext.c_str(), wtitle.c_str(), style); - return ""; - }); - -#elif __EMSCRIPTEN__ - std::string full_message; - switch (_icon) { - case icon::warning: - full_message = "⚠️"; - break; - case icon::error: - full_message = "⛔"; - break; - case icon::question: - full_message = "❓"; - break; - /* case icon::info: */ default: - full_message = "ℹ"; - break; - } - - full_message += ' ' + title + "\n\n" + text; - - // This does not really start an async task; it just passes the - // EM_ASM_INT return value to a fake start() function. - m_async->start(EM_ASM_INT( - { - if ($1) return window.confirm(UTF8ToString($0)) ? 0 : -1; - alert(UTF8ToString($0)); - return 0; - }, - full_message.c_str(), _choice == choice::ok_cancel)); -#else - auto command = desktop_helper(); - - if (is_osascript()) { - std::string script = - "display dialog " + osascript_quote(text) + " with title " + osascript_quote(title); - auto if_cancel = button::cancel; - switch (_choice) { - case choice::ok_cancel: - script += - "buttons {\"OK\", \"Cancel\"}" - " default button \"OK\"" - " cancel button \"Cancel\""; - break; - case choice::yes_no: - script += - "buttons {\"Yes\", \"No\"}" - " default button \"Yes\"" - " cancel button \"No\""; - if_cancel = button::no; - break; - case choice::yes_no_cancel: - script += - "buttons {\"Yes\", \"No\", \"Cancel\"}" - " default button \"Yes\"" - " cancel button \"Cancel\""; - break; - case choice::retry_cancel: - script += - "buttons {\"Retry\", \"Cancel\"}" - " default button \"Retry\"" - " cancel button \"Cancel\""; - break; - case choice::abort_retry_ignore: - script += - "buttons {\"Abort\", \"Retry\", \"Ignore\"}" - " default button \"Abort\"" - " cancel button \"Retry\""; - if_cancel = button::retry; - break; - case choice::ok: - default: - script += - "buttons {\"OK\"}" - " default button \"OK\"" - " cancel button \"OK\""; - if_cancel = button::ok; - break; - } - m_mappings[1] = if_cancel; - m_mappings[256] = if_cancel; // XXX: I think this was never correct - script += " with icon "; - switch (_icon) { -#define PFD_OSX_ICON(n) \ - "alias ((path to library folder from system domain) as text " \ - "& \"CoreServices:CoreTypes.bundle:Contents:Resources:" n ".icns\")" - case icon::info: - default: - script += PFD_OSX_ICON("ToolBarInfo"); - break; - case icon::warning: - script += "caution"; - break; - case icon::error: - script += "stop"; - break; - case icon::question: - script += PFD_OSX_ICON("GenericQuestionMarkIcon"); - break; -#undef PFD_OSX_ICON - } - - command.push_back("-e"); - command.push_back(script); - } else if (is_zenity()) { - switch (_choice) { - case choice::ok_cancel: - command.insert(command.end(), {"--question", "--cancel-label=Cancel", "--ok-label=OK"}); - break; - case choice::yes_no: - // Do not use standard --question because it causes “No” to return -1, - // which is inconsistent with the “Yes/No/Cancel” mode below. - command.insert(command.end(), - {"--question", "--switch", "--extra-button=No", "--extra-button=Yes"}); - break; - case choice::yes_no_cancel: - command.insert(command.end(), {"--question", "--switch", "--extra-button=Cancel", - "--extra-button=No", "--extra-button=Yes"}); - break; - case choice::retry_cancel: - command.insert(command.end(), - {"--question", "--switch", "--extra-button=Cancel", "--extra-button=Retry"}); - break; - case choice::abort_retry_ignore: - command.insert(command.end(), {"--question", "--switch", "--extra-button=Ignore", - "--extra-button=Abort", "--extra-button=Retry"}); - break; - case choice::ok: - default: - switch (_icon) { - case icon::error: - command.push_back("--error"); - break; - case icon::warning: - command.push_back("--warning"); - break; - default: - command.push_back("--info"); - break; - } - } - - command.insert(command.end(), - {"--title", title, "--width=300", "--height=0", // sensible defaults - "--no-markup", // do not interpret text as Pango markup - "--text", text, "--icon-name=dialog-" + get_icon_name(_icon)}); - } else if (is_kdialog()) { - if (_choice == choice::ok) { - switch (_icon) { - case icon::error: - command.push_back("--error"); - break; - case icon::warning: - command.push_back("--sorry"); - break; - default: - command.push_back("--msgbox"); - break; - } - } else { - std::string flag = "--"; - if (_icon == icon::warning || _icon == icon::error) flag += "warning"; - flag += "yesno"; - if (_choice == choice::yes_no_cancel) flag += "cancel"; - command.push_back(flag); - if (_choice == choice::yes_no || _choice == choice::yes_no_cancel) { - m_mappings[0] = button::yes; - m_mappings[256] = button::no; - } - } - - command.push_back(text); - command.push_back("--title"); - command.push_back(title); - - // Must be after the above part - if (_choice == choice::ok_cancel) - command.insert(command.end(), {"--yes-label", "OK", "--no-label", "Cancel"}); - } - - if (flags(flag::is_verbose)) std::cerr << "pfd: " << command << std::endl; - - m_async->start_process(command); -#endif -} - -inline button message::result() { - int exit_code; - auto ret = m_async->result(&exit_code); - // osascript will say "button returned:Cancel\n" - // and others will just say "Cancel\n" - if (internal::ends_with(ret, "Cancel\n")) return button::cancel; - if (internal::ends_with(ret, "OK\n")) return button::ok; - if (internal::ends_with(ret, "Yes\n")) return button::yes; - if (internal::ends_with(ret, "No\n")) return button::no; - if (internal::ends_with(ret, "Abort\n")) return button::abort; - if (internal::ends_with(ret, "Retry\n")) return button::retry; - if (internal::ends_with(ret, "Ignore\n")) return button::ignore; - if (m_mappings.count(exit_code) != 0) return m_mappings[exit_code]; - return exit_code == 0 ? button::ok : button::cancel; -} - -// open_file implementation - -inline open_file::open_file(std::string const& title, std::string const& default_path /* = "" */, - std::vector<std::string> const& filters /* = { "All Files", "*" } */, - opt options /* = opt::none */) - : file_dialog(type::open, title, default_path, filters, options) {} - -inline open_file::open_file(std::string const& title, std::string const& default_path, - std::vector<std::string> const& filters, bool allow_multiselect) - : open_file(title, default_path, filters, (allow_multiselect ? opt::multiselect : opt::none)) {} - -inline std::vector<std::string> open_file::result() { - return vector_result(); -} - -// save_file implementation - -inline save_file::save_file(std::string const& title, std::string const& default_path /* = "" */, - std::vector<std::string> const& filters /* = { "All Files", "*" } */, - opt options /* = opt::none */) - : file_dialog(type::save, title, default_path, filters, options) {} - -inline save_file::save_file(std::string const& title, std::string const& default_path, - std::vector<std::string> const& filters, bool confirm_overwrite) - : save_file(title, default_path, filters, - (confirm_overwrite ? opt::none : opt::force_overwrite)) {} - -inline std::string save_file::result() { - return string_result(); -} - -// select_folder implementation - -inline select_folder::select_folder(std::string const& title, - std::string const& default_path /* = "" */, - opt options /* = opt::none */) - : file_dialog(type::folder, title, default_path, {}, options) {} - -inline std::string select_folder::result() { - return string_result(); -} - -#endif // PFD_SKIP_IMPLEMENTATION - -} // namespace pfd |
