diff options
| author | Amlal EL Mahrouss <amlalelmahrouss@icloud.com> | 2024-08-08 00:19:14 +0200 |
|---|---|---|
| committer | Amlal EL Mahrouss <amlalelmahrouss@icloud.com> | 2024-08-08 00:19:14 +0200 |
| commit | 5fd78848bc39ae73c85ea29b2fc13ebbf740c223 (patch) | |
| tree | 13aa61d48135fe34a742b6ecbaba099ec905752a | |
| parent | f3b606161a8f667cdfa5a2b11eb949ce2da8231c (diff) | |
[UNSTABLE] [IMP] NDK DLL, needs refactoring though.
Signed-off-by: Amlal EL Mahrouss <amlalelmahrouss@icloud.com>
| -rw-r--r-- | .gitmodules | 3 | ||||
| m--------- | Meta/CSS | 0 | ||||
| -rw-r--r-- | NDKKit/AsmKit/AsmKit.hxx | 4 | ||||
| -rw-r--r-- | NDKKit/Defines.hxx | 4 | ||||
| -rw-r--r-- | NDKKit/NFC/AE.hxx | 28 | ||||
| -rw-r--r-- | NDKKit/NFC/ErrorID.hxx | 2 | ||||
| -rw-r--r-- | NDKKit/NFC/ErrorOr.hxx | 6 | ||||
| -rw-r--r-- | NDKKit/NFC/PEF.hxx | 24 | ||||
| -rw-r--r-- | NDKKit/NFC/Ref.hxx | 6 | ||||
| -rw-r--r-- | NDKKit/NFC/String.hxx | 6 | ||||
| -rw-r--r-- | NDKKit/NFC/XCOFF.hxx | 4 | ||||
| -rw-r--r-- | NDKKit/Output/.gitkeep (renamed from Output/.gitkeep) | 0 | ||||
| -rw-r--r-- | NDKKit/Parser.hxx | 4 | ||||
| -rw-r--r-- | NDKKit/Sources/Assembler32x0.cxx (renamed from NDKKit/Sources/32asm.cxx) | 0 | ||||
| -rw-r--r-- | NDKKit/Sources/Assembler64x0.cxx (renamed from NDKKit/Sources/64asm.cxx) | 126 | ||||
| -rw-r--r-- | NDKKit/Sources/AssemblerAMD64.cxx (renamed from NDKKit/Sources/i64asm.cxx) | 204 | ||||
| -rw-r--r-- | NDKKit/Sources/AssemblerPower.cxx | 1096 | ||||
| -rw-r--r-- | NDKKit/Sources/AssemblyFactory.cxx | 4 | ||||
| -rw-r--r-- | NDKKit/Sources/BasicPreProcessor.cxx (renamed from NDKKit/Sources/bpp.cxx) | 2 | ||||
| -rw-r--r-- | NDKKit/Sources/CCompiler64x0.cxx (renamed from NDKKit/Sources/64x0-cc.cxx) | 92 | ||||
| -rw-r--r-- | NDKKit/Sources/CCompilerPower64.cxx (renamed from NDKKit/Sources/power-cc.cxx) | 90 | ||||
| -rw-r--r-- | NDKKit/Sources/CPlusPlusCompilerAMD64.cxx (renamed from NDKKit/Sources/cplusplus.cxx) | 251 | ||||
| -rw-r--r-- | NDKKit/Sources/Detail/asmutils.hxx | 16 | ||||
| -rw-r--r-- | NDKKit/Sources/Linker.cxx (renamed from NDKKit/Sources/link.cxx) | 54 | ||||
| -rw-r--r-- | NDKKit/Sources/String.cxx | 6 | ||||
| -rw-r--r-- | NDKKit/Sources/coff2ae.cxx | 23 | ||||
| -rw-r--r-- | NDKKit/Sources/elf2ae.cxx | 22 | ||||
| -rw-r--r-- | NDKKit/Sources/power-as.cxx | 976 | ||||
| -rw-r--r-- | makefile | 8 | ||||
| -rw-r--r-- | posix.make | 90 | ||||
| -rw-r--r-- | win64.make | 89 |
31 files changed, 1512 insertions, 1728 deletions
diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 56bc5c6..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "Meta/CSS"] - path = Meta/CSS - url = https://github.com/jothepro/doxygen-awesome-css.git diff --git a/Meta/CSS b/Meta/CSS deleted file mode 160000 -Subproject 9f97817e703aa2c15503067b2a72c97f9d37f46 diff --git a/NDKKit/AsmKit/AsmKit.hxx b/NDKKit/AsmKit/AsmKit.hxx index f6e67f2..c31a52d 100644 --- a/NDKKit/AsmKit/AsmKit.hxx +++ b/NDKKit/AsmKit/AsmKit.hxx @@ -10,7 +10,7 @@ #include <NDKKit/Defines.hxx> #include <NDKKit/NFC/String.hxx> -namespace CompilerKit +namespace NDK { // // @brief Frontend to Assembly mountpoint. @@ -214,4 +214,4 @@ namespace CompilerKit }; #endif // __ASM_NEED_32x0__ -} // namespace CompilerKit +} // namespace NDK diff --git a/NDKKit/Defines.hxx b/NDKKit/Defines.hxx index 31c1998..7bcdc24 100644 --- a/NDKKit/Defines.hxx +++ b/NDKKit/Defines.hxx @@ -82,7 +82,7 @@ #include <string> #include <vector> -namespace CompilerKit +namespace NDK { inline constexpr int BASE_YEAR = 1900; @@ -122,7 +122,7 @@ namespace CompilerKit str[copy_limit] = '\0'; return true; } -} // namespace CompilerKit +} // namespace NDK #define PACKED __attribute__((packed)) diff --git a/NDKKit/NFC/AE.hxx b/NDKKit/NFC/AE.hxx index 22ad05b..ad9b0a2 100644 --- a/NDKKit/NFC/AE.hxx +++ b/NDKKit/NFC/AE.hxx @@ -24,7 +24,7 @@ // You can also relocate at runtime but that's up to the operating system // loader. -namespace CompilerKit +namespace NDK { // @brief Advanced Executable Header // One thing to keep in mind. @@ -60,39 +60,39 @@ namespace CompilerKit kKindRelocationByOffset = 0x23f, kKindRelocationAtRuntime = 0x34f, }; -} // namespace CompilerKit +} // namespace NDK // provide operator<< for AE -std::ofstream& operator<<(std::ofstream& fp, CompilerKit::AEHeader& container) +inline std::ofstream& operator<<(std::ofstream& fp, NDK::AEHeader& container) { - fp.write((char*)&container, sizeof(CompilerKit::AEHeader)); + fp.write((char*)&container, sizeof(NDK::AEHeader)); return fp; } -std::ofstream& operator<<(std::ofstream& fp, - CompilerKit::AERecordHeader& container) +inline std::ofstream& operator<<(std::ofstream& fp, + NDK::AERecordHeader& container) { - fp.write((char*)&container, sizeof(CompilerKit::AERecordHeader)); + fp.write((char*)&container, sizeof(NDK::AERecordHeader)); return fp; } -std::ifstream& operator>>(std::ifstream& fp, CompilerKit::AEHeader& container) +inline std::ifstream& operator>>(std::ifstream& fp, NDK::AEHeader& container) { - fp.read((char*)&container, sizeof(CompilerKit::AEHeader)); + fp.read((char*)&container, sizeof(NDK::AEHeader)); return fp; } -std::ifstream& operator>>(std::ifstream& fp, - CompilerKit::AERecordHeader& container) +inline std::ifstream& operator>>(std::ifstream& fp, + NDK::AERecordHeader& container) { - fp.read((char*)&container, sizeof(CompilerKit::AERecordHeader)); + fp.read((char*)&container, sizeof(NDK::AERecordHeader)); return fp; } -namespace CompilerKit::Utils +namespace NDK::Utils { /** * @brief AE Reader protocol @@ -140,4 +140,4 @@ namespace CompilerKit::Utils return reinterpret_cast<TypeClass*>(raw); } }; -} // namespace CompilerKit::Utils +} // namespace NDK::Utils diff --git a/NDKKit/NFC/ErrorID.hxx b/NDKKit/NFC/ErrorID.hxx index 9845a8b..17183b8 100644 --- a/NDKKit/NFC/ErrorID.hxx +++ b/NDKKit/NFC/ErrorID.hxx @@ -1,7 +1,7 @@ /* * ======================================================== * - * CompilerKit + * NDK * Copyright ZKA Technologies, all rights reserved. * * ======================================================== diff --git a/NDKKit/NFC/ErrorOr.hxx b/NDKKit/NFC/ErrorOr.hxx index 936654a..0e734b6 100644 --- a/NDKKit/NFC/ErrorOr.hxx +++ b/NDKKit/NFC/ErrorOr.hxx @@ -1,7 +1,7 @@ /* * ======================================================== * - * CompilerKit + * NDK * Copyright ZKA Technologies, all rights reserved. * * ======================================================== @@ -12,7 +12,7 @@ #include <NDKKit/Defines.hxx> #include <NDKKit/NFC/Ref.hxx> -namespace CompilerKit +namespace NDK { using ErrorT = UInt32; @@ -58,4 +58,4 @@ namespace CompilerKit using ErrorOrAny = ErrorOr<voidPtr>; -} // namespace CompilerKit +} // namespace NDK diff --git a/NDKKit/NFC/PEF.hxx b/NDKKit/NFC/PEF.hxx index db41630..455a641 100644 --- a/NDKKit/NFC/PEF.hxx +++ b/NDKKit/NFC/PEF.hxx @@ -30,7 +30,7 @@ #define kPefStart "__ImageStart" -namespace CompilerKit +namespace NDK { enum { @@ -104,32 +104,32 @@ namespace CompilerKit kPefCount = 4, kPefInvalid = 0xFF, }; -} // namespace CompilerKit +} // namespace NDK inline std::ofstream& operator<<(std::ofstream& fp, - CompilerKit::PEFContainer& container) + NDK::PEFContainer& container) { - fp.write((char*)&container, sizeof(CompilerKit::PEFContainer)); + fp.write((char*)&container, sizeof(NDK::PEFContainer)); return fp; } inline std::ofstream& operator<<(std::ofstream& fp, - CompilerKit::PEFCommandHeader& container) + NDK::PEFCommandHeader& container) { - fp.write((char*)&container, sizeof(CompilerKit::PEFCommandHeader)); + fp.write((char*)&container, sizeof(NDK::PEFCommandHeader)); return fp; } -std::ifstream& operator>>(std::ifstream& fp, - CompilerKit::PEFContainer& container) +inline std::ifstream& operator>>(std::ifstream& fp, + NDK::PEFContainer& container) { - fp.read((char*)&container, sizeof(CompilerKit::PEFContainer)); + fp.read((char*)&container, sizeof(NDK::PEFContainer)); return fp; } -std::ifstream& operator>>(std::ifstream& fp, - CompilerKit::PEFCommandHeader& container) +inline std::ifstream& operator>>(std::ifstream& fp, + NDK::PEFCommandHeader& container) { - fp.read((char*)&container, sizeof(CompilerKit::PEFCommandHeader)); + fp.read((char*)&container, sizeof(NDK::PEFCommandHeader)); return fp; } diff --git a/NDKKit/NFC/Ref.hxx b/NDKKit/NFC/Ref.hxx index 0f9c0e3..bd1d72f 100644 --- a/NDKKit/NFC/Ref.hxx +++ b/NDKKit/NFC/Ref.hxx @@ -2,7 +2,7 @@ /* * ======================================================== * - * CompilerKit + * NDK * Copyright ZKA Technologies, all rights reserved. * * ======================================================== @@ -10,7 +10,7 @@ #pragma once -namespace CompilerKit +namespace NDK { // @author Amlal // @brief Reference holder class, refers to a pointer of data in static memory. @@ -94,4 +94,4 @@ namespace CompilerKit private: Ref<T> m_Ref{nullptr}; }; -} // namespace CompilerKit +} // namespace NDK diff --git a/NDKKit/NFC/String.hxx b/NDKKit/NFC/String.hxx index 395fe67..2d5497a 100644 --- a/NDKKit/NFC/String.hxx +++ b/NDKKit/NFC/String.hxx @@ -1,7 +1,7 @@ /* * ======================================================== * - * CompilerKit + * NDK * Copyright ZKA Technologies, all rights reserved. * * ======================================================== @@ -12,7 +12,7 @@ #include <NDKKit/Defines.hxx> #include <NDKKit/NFC/ErrorOr.hxx> -namespace CompilerKit +namespace NDK { /** * @brief StringView class, contains a C string and manages it. @@ -87,4 +87,4 @@ namespace CompilerKit static const char* Format(const char* fmt, const char* from); static bool Equals(const char* lhs, const char* rhs); }; -} // namespace CompilerKit +} // namespace NDK diff --git a/NDKKit/NFC/XCOFF.hxx b/NDKKit/NFC/XCOFF.hxx index 97d3ab6..f2da79d 100644 --- a/NDKKit/NFC/XCOFF.hxx +++ b/NDKKit/NFC/XCOFF.hxx @@ -23,7 +23,7 @@ #define kXCOFFLnno 0x0004 #define kXCOFFLSyms 0x0008 -namespace CompilerKit +namespace NDK { /// @brief XCoff identification header. typedef struct XCoffFileHeader @@ -36,6 +36,6 @@ namespace CompilerKit UInt32 fNumSyms; UInt16 fOptHdr; // ?: Number of bytes in optional header } XCoffFileHeader; -} // namespace CompilerKit +} // namespace NDK #endif // ifndef __XCOFF__ diff --git a/Output/.gitkeep b/NDKKit/Output/.gitkeep index e69de29..e69de29 100644 --- a/Output/.gitkeep +++ b/NDKKit/Output/.gitkeep diff --git a/NDKKit/Parser.hxx b/NDKKit/Parser.hxx index 43ecc4a..51b0154 100644 --- a/NDKKit/Parser.hxx +++ b/NDKKit/Parser.hxx @@ -9,7 +9,7 @@ #include <NDKKit/AsmKit/AsmKit.hxx> #include <vector> -namespace CompilerKit +namespace NDK { inline auto cInvalidLang = "?"; @@ -175,4 +175,4 @@ namespace CompilerKit return false; } -} // namespace CompilerKit +} // namespace NDK diff --git a/NDKKit/Sources/32asm.cxx b/NDKKit/Sources/Assembler32x0.cxx index 4425e08..4425e08 100644 --- a/NDKKit/Sources/32asm.cxx +++ b/NDKKit/Sources/Assembler32x0.cxx diff --git a/NDKKit/Sources/64asm.cxx b/NDKKit/Sources/Assembler64x0.cxx index 4e084e7..2df6339 100644 --- a/NDKKit/Sources/64asm.cxx +++ b/NDKKit/Sources/Assembler64x0.cxx @@ -44,7 +44,7 @@ #define kStdOut (std::cout << kWhite) #define kStdErr (std::cout << kRed) -static char kOutputArch = CompilerKit::kPefArch64000; +static char kOutputArch = NDK::kPefArch64000; static Boolean kOutputAsBinary = false; static UInt32 kErrorLimit = 10; @@ -61,10 +61,10 @@ static bool kVerbose = false; static std::vector<e64k_num_t> kBytes; -static CompilerKit::AERecordHeader kCurrentRecord{ - .fName = "", .fKind = CompilerKit::kPefCode, .fSize = 0, .fOffset = 0}; +static NDK::AERecordHeader kCurrentRecord{ + .fName = "", .fKind = NDK::kPefCode, .fSize = 0, .fOffset = 0}; -static std::vector<CompilerKit::AERecordHeader> kRecords; +static std::vector<NDK::AERecordHeader> kRecords; static std::vector<std::string> kUndefinedSymbols; static const std::string kUndefinedSymbol = ":UndefinedSymbol:"; @@ -74,21 +74,21 @@ static const std::string kRelocSymbol = ":RuntimeSymbol:"; static bool asm_read_attributes(std::string &line); namespace detail { -void print_error(std::string reason, const std::string &file) noexcept { +void print_error_asm(std::string reason, std::string file) noexcept { if (reason[0] == '\n') reason.erase(0, 1); - kStdErr << kRed << "[ 64asm ] " << kWhite - << ((file == "64asm") ? "internal assembler error " + kStdErr << kRed << "[ ndk ] " << kWhite + << ((file == "ndk") ? "internal error " : ("in file, " + file)) << kBlank << std::endl; - kStdErr << kRed << "[ 64asm ] " << kWhite << reason << kBlank << std::endl; + kStdErr << kRed << "[ ndk ] " << kWhite << reason << kBlank << std::endl; if (kAcceptableErrors > kErrorLimit) std::exit(3); ++kAcceptableErrors; } -void print_warning(std::string reason, const std::string &file) noexcept { +void print_warning_asm(std::string reason, std::string file) noexcept { if (reason[0] == '\n') reason.erase(0, 1); if (!file.empty()) { @@ -159,13 +159,13 @@ NDK_MODULE(NewOSAssembler64000) { std::string line; - CompilerKit::AEHeader hdr{0}; + NDK::AEHeader hdr{0}; memset(hdr.fPad, kAEInvalidOpcode, kAEPad); hdr.fMagic[0] = kAEMag0; hdr.fMagic[1] = kAEMag1; - hdr.fSize = sizeof(CompilerKit::AEHeader); + hdr.fSize = sizeof(NDK::AEHeader); hdr.fArch = kOutputArch; ///////////////////////////////////////////////////////////////////////////////////////// @@ -174,11 +174,11 @@ NDK_MODULE(NewOSAssembler64000) { ///////////////////////////////////////////////////////////////////////////////////////// - CompilerKit::Encoder64x0 asm64; + NDK::Encoder64x0 asm64; while (std::getline(file_ptr, line)) { if (auto ln = asm64.CheckLine(line, argv[i]); !ln.empty()) { - detail::print_error(ln, argv[i]); + detail::print_error_asm(ln, argv[i]); continue; } @@ -188,7 +188,7 @@ NDK_MODULE(NewOSAssembler64000) { } catch (const std::exception &e) { if (kVerbose) { std::string what = e.what(); - detail::print_warning("exit because of: " + what, "64asm"); + detail::print_warning_asm("exit because of: " + what, "64asm"); } std::filesystem::remove(object_output); @@ -225,7 +225,7 @@ NDK_MODULE(NewOSAssembler64000) { if (kVerbose) kStdOut << "64asm: Wrote record " << rec.fName << " to file...\n"; - rec.fFlags |= CompilerKit::kKindRelocationAtRuntime; + rec.fFlags |= NDK::kKindRelocationAtRuntime; rec.fOffset = record_count; ++record_count; @@ -236,7 +236,7 @@ NDK_MODULE(NewOSAssembler64000) { ++record_count; for (auto &sym : kUndefinedSymbols) { - CompilerKit::AERecordHeader _record_hdr{0}; + NDK::AERecordHeader _record_hdr{0}; if (kVerbose) kStdOut << "64asm: Wrote symbol " << sym << " to file...\n"; @@ -303,9 +303,9 @@ asm_fail_exit: static bool asm_read_attributes(std::string &line) { // import is the opposite of export, it signals to the ld // that we need this symbol. - if (CompilerKit::find_word(line, "import")) { + if (NDK::find_word(line, "import")) { if (kOutputAsBinary) { - detail::print_error("Invalid import directive in flat binary mode.", + detail::print_error_asm("Invalid import directive in flat binary mode.", "64asm"); throw std::runtime_error("invalid_import_bin"); } @@ -314,7 +314,7 @@ static bool asm_read_attributes(std::string &line) { /// sanity check to avoid stupid linker errors. if (name.size() == 0) { - detail::print_error("Invalid import", "power-as"); + detail::print_error_asm("Invalid import", "power-as"); throw std::runtime_error("invalid_import"); } @@ -330,20 +330,20 @@ static bool asm_read_attributes(std::string &line) { if (name.find(".code64") != std::string::npos) { // data is treated as code. - kCurrentRecord.fKind = CompilerKit::kPefCode; + kCurrentRecord.fKind = NDK::kPefCode; } else if (name.find(".data64") != std::string::npos) { // no code will be executed from here. - kCurrentRecord.fKind = CompilerKit::kPefData; + kCurrentRecord.fKind = NDK::kPefData; } else if (name.find(".zero64") != std::string::npos) { // this is a bss section. - kCurrentRecord.fKind = CompilerKit::kPefZero; + kCurrentRecord.fKind = NDK::kPefZero; } // this is a special case for the start stub. // we want this so that ld can find it. if (name == kPefStart) { - kCurrentRecord.fKind = CompilerKit::kPefCode; + kCurrentRecord.fKind = NDK::kPefCode; } // now we can tell the code size of the previous kCurrentRecord. @@ -364,9 +364,9 @@ static bool asm_read_attributes(std::string &line) { // export is a special keyword used by 64asm to tell the AE output stage to // mark this section as a header. it currently supports .code64, .data64., // .zero64 - else if (CompilerKit::find_word(line, "export")) { + else if (NDK::find_word(line, "export")) { if (kOutputAsBinary) { - detail::print_error("Invalid export directive in flat binary mode.", + detail::print_error_asm("Invalid export directive in flat binary mode.", "64asm"); throw std::runtime_error("invalid_export_bin"); } @@ -383,24 +383,24 @@ static bool asm_read_attributes(std::string &line) { // data is treated as code. name_copy.erase(name_copy.find(".code64"), strlen(".code64")); - kCurrentRecord.fKind = CompilerKit::kPefCode; + kCurrentRecord.fKind = NDK::kPefCode; } else if (name.find(".data64") != std::string::npos) { // no code will be executed from here. name_copy.erase(name_copy.find(".data64"), strlen(".data64")); - kCurrentRecord.fKind = CompilerKit::kPefData; + kCurrentRecord.fKind = NDK::kPefData; } else if (name.find(".zero64") != std::string::npos) { // this is a bss section. name_copy.erase(name_copy.find(".zero64"), strlen(".zero64")); - kCurrentRecord.fKind = CompilerKit::kPefZero; + kCurrentRecord.fKind = NDK::kPefZero; } // this is a special case for the start stub. // we want this so that ld can find it. if (name == kPefStart) { - kCurrentRecord.fKind = CompilerKit::kPefCode; + kCurrentRecord.fKind = NDK::kPefCode; } while (name_copy.find(" ") != std::string::npos) @@ -439,7 +439,7 @@ static inline bool is_not_alnum_space(char c) { (c == '_') || (c == ':') || (c == '@') || (c == '.')); } -bool is_valid(const std::string &str) { +bool is_valid_64x0(const std::string &str) { return std::find_if(str.begin(), str.end(), is_not_alnum_space) == str.end(); } } // namespace detail::algorithm @@ -450,20 +450,20 @@ bool is_valid(const std::string &str) { ///////////////////////////////////////////////////////////////////////////////////////// -std::string CompilerKit::Encoder64x0::CheckLine(std::string &line, +std::string NDK::Encoder64x0::CheckLine(std::string &line, const std::string &file) { std::string err_str; - if (line.empty() || CompilerKit::find_word(line, "import") || - CompilerKit::find_word(line, "export") || - line.find('#') != std::string::npos || CompilerKit::find_word(line, ";")) { + if (line.empty() || NDK::find_word(line, "import") || + NDK::find_word(line, "export") || + line.find('#') != std::string::npos || NDK::find_word(line, ";")) { if (line.find('#') != std::string::npos) { line.erase(line.find('#')); } else if (line.find(';') != std::string::npos) { line.erase(line.find(';')); } else { // now check the line for validity - if (!detail::algorithm::is_valid(line)) { + if (!detail::algorithm::is_valid_64x0(line)) { err_str = "Line contains non alphanumeric characters.\nhere -> "; err_str += line; } @@ -472,7 +472,7 @@ std::string CompilerKit::Encoder64x0::CheckLine(std::string &line, return err_str; } - if (!detail::algorithm::is_valid(line)) { + if (!detail::algorithm::is_valid_64x0(line)) { err_str = "Line contains non alphanumeric characters.\nhere -> "; err_str += line; @@ -539,7 +539,7 @@ std::string CompilerKit::Encoder64x0::CheckLine(std::string &line, if (auto it = std::find(filter_inst.begin(), filter_inst.end(), opcode64x0.fName); it == filter_inst.cend()) { - if (CompilerKit::find_word(line, opcode64x0.fName)) { + if (NDK::find_word(line, opcode64x0.fName)) { if (!isspace(line[line.find(opcode64x0.fName) + strlen(opcode64x0.fName)])) { err_str += "\nMissing space between "; @@ -559,7 +559,7 @@ std::string CompilerKit::Encoder64x0::CheckLine(std::string &line, return err_str; } -bool CompilerKit::Encoder64x0::WriteNumber(const std::size_t &pos, +bool NDK::Encoder64x0::WriteNumber(const std::size_t &pos, std::string &jump_label) { if (!isdigit(jump_label[pos])) return false; @@ -568,12 +568,12 @@ bool CompilerKit::Encoder64x0::WriteNumber(const std::size_t &pos, if (auto res = strtol(jump_label.substr(pos + 2).c_str(), nullptr, 16); !res) { if (errno != 0) { - detail::print_error("invalid hex number: " + jump_label, "64asm"); + detail::print_error_asm("invalid hex number: " + jump_label, "64asm"); throw std::runtime_error("invalid_hex_number"); } } - CompilerKit::NumberCast64 num( + NDK::NumberCast64 num( strtol(jump_label.substr(pos + 2).c_str(), nullptr, 16)); for (char &i : num.number) { @@ -591,12 +591,12 @@ bool CompilerKit::Encoder64x0::WriteNumber(const std::size_t &pos, if (auto res = strtol(jump_label.substr(pos + 2).c_str(), nullptr, 2); !res) { if (errno != 0) { - detail::print_error("invalid binary number: " + jump_label, "64asm"); + detail::print_error_asm("invalid binary number: " + jump_label, "64asm"); throw std::runtime_error("invalid_bin"); } } - CompilerKit::NumberCast64 num( + NDK::NumberCast64 num( strtol(jump_label.substr(pos + 2).c_str(), nullptr, 2)); if (kVerbose) { @@ -614,12 +614,12 @@ bool CompilerKit::Encoder64x0::WriteNumber(const std::size_t &pos, if (auto res = strtol(jump_label.substr(pos + 2).c_str(), nullptr, 7); !res) { if (errno != 0) { - detail::print_error("invalid octal number: " + jump_label, "64asm"); + detail::print_error_asm("invalid octal number: " + jump_label, "64asm"); throw std::runtime_error("invalid_octal"); } } - CompilerKit::NumberCast64 num( + NDK::NumberCast64 num( strtol(jump_label.substr(pos + 2).c_str(), nullptr, 7)); if (kVerbose) { @@ -645,7 +645,7 @@ bool CompilerKit::Encoder64x0::WriteNumber(const std::size_t &pos, } } - CompilerKit::NumberCast64 num( + NDK::NumberCast64 num( strtol(jump_label.substr(pos).c_str(), nullptr, 10)); for (char &i : num.number) { @@ -666,14 +666,14 @@ bool CompilerKit::Encoder64x0::WriteNumber(const std::size_t &pos, ///////////////////////////////////////////////////////////////////////////////////////// -bool CompilerKit::Encoder64x0::WriteLine(std::string &line, +bool NDK::Encoder64x0::WriteLine(std::string &line, const std::string &file) { - if (CompilerKit::find_word(line, "export ")) return true; + if (NDK::find_word(line, "export ")) return true; for (auto &opcode64x0 : kOpcodes64x0) { // strict check here - if (CompilerKit::find_word(line, opcode64x0.fName) && - detail::algorithm::is_valid(line)) { + if (NDK::find_word(line, opcode64x0.fName) && + detail::algorithm::is_valid_64x0(line)) { std::string name(opcode64x0.fName); std::string jump_label, cpy_jump_label; @@ -707,11 +707,11 @@ bool CompilerKit::Encoder64x0::WriteLine(std::string &line, // it ranges from r0 to r19 // something like r190 doesn't exist in the instruction set. - if (kOutputArch == CompilerKit::kPefArch64000) { + if (kOutputArch == NDK::kPefArch64000) { if (isdigit(line[line_index + 3]) && isdigit(line[line_index + 2])) { reg_str += line[line_index + 3]; - detail::print_error( + detail::print_error_asm( "invalid register index, r" + reg_str + "\nnote: The 64x0 accepts registers from r0 to r20.", file); @@ -723,7 +723,7 @@ bool CompilerKit::Encoder64x0::WriteLine(std::string &line, std::size_t reg_index = strtol(reg_str.c_str(), nullptr, 10); if (reg_index > kAsmRegisterLimit) { - detail::print_error("invalid register index, r" + reg_str, + detail::print_error_asm("invalid register index, r" + reg_str, file); throw std::runtime_error("invalid_register_index"); } @@ -743,7 +743,7 @@ bool CompilerKit::Encoder64x0::WriteLine(std::string &line, if (opcode64x0.fFunct7 != kAsmImmediate) { // remember! register to register! if (found_some == 1) { - detail::print_error( + detail::print_error_asm( "Too few registers.\ntip: each 64asm register " "starts with 'r'.\nline: " + line, @@ -754,24 +754,24 @@ bool CompilerKit::Encoder64x0::WriteLine(std::string &line, if (found_some < 1 && name != "ldw" && name != "lda" && name != "stw") { - detail::print_error( + detail::print_error_asm( "invalid combination of opcode and registers.\nline: " + line, file); throw std::runtime_error("invalid_comb_op_reg"); } else if (found_some == 1 && name == "add") { - detail::print_error( + detail::print_error_asm( "invalid combination of opcode and registers.\nline: " + line, file); throw std::runtime_error("invalid_comb_op_reg"); } else if (found_some == 1 && name == "sub") { - detail::print_error( + detail::print_error_asm( "invalid combination of opcode and registers.\nline: " + line, file); throw std::runtime_error("invalid_comb_op_reg"); } if (found_some > 0 && name == "pop") { - detail::print_error( + detail::print_error_asm( "invalid combination for opcode 'pop'.\ntip: it expects " "nothing.\nline: " + line, @@ -807,7 +807,7 @@ bool CompilerKit::Encoder64x0::WriteLine(std::string &line, if (jump_label[0] != kAsmRegisterPrefix[0] && !isdigit(jump_label[1])) { if (found_sym) { - detail::print_error( + detail::print_error_asm( "invalid combination of opcode and operands.\nhere -> " + jump_label, file); @@ -833,7 +833,7 @@ bool CompilerKit::Encoder64x0::WriteLine(std::string &line, if (!this->WriteNumber(0, jump_label)) { // sta expects this: sta 0x000000, r0 if (name == "sta") { - detail::print_error( + detail::print_error_asm( "invalid combination of opcode and operands.\nHere ->" + line, file); throw std::runtime_error("invalid_comb_op_ops"); @@ -841,7 +841,7 @@ bool CompilerKit::Encoder64x0::WriteLine(std::string &line, } else { if (name == "sta" && cpy_jump_label.find("import ") != std::string::npos) { - detail::print_error("invalid usage import on 'sta', here: " + line, + detail::print_error_asm("invalid usage import on 'sta', here: " + line, file); throw std::runtime_error("invalid_sta_usage"); } @@ -860,7 +860,7 @@ bool CompilerKit::Encoder64x0::WriteLine(std::string &line, cpy_jump_label.erase(cpy_jump_label.find("import"), strlen("import")); if (name == "sta") { - detail::print_error("import is not allowed on a sta operation.", + detail::print_error_asm("import is not allowed on a sta operation.", file); throw std::runtime_error("import_sta_op"); } else { @@ -876,7 +876,7 @@ bool CompilerKit::Encoder64x0::WriteLine(std::string &line, << " to address: " << label.second << std::endl; } - CompilerKit::NumberCast64 num(label.second); + NDK::NumberCast64 num(label.second); for (auto &num : num.number) { kBytes.push_back(num); @@ -908,7 +908,7 @@ bool CompilerKit::Encoder64x0::WriteLine(std::string &line, } if (cpy_jump_label.size() < 1) { - detail::print_error("label is empty, can't jump on it.", file); + detail::print_error_asm("label is empty, can't jump on it.", file); throw std::runtime_error("label_empty"); } diff --git a/NDKKit/Sources/i64asm.cxx b/NDKKit/Sources/AssemblerAMD64.cxx index c2ce4ac..b20eaaf 100644 --- a/NDKKit/Sources/i64asm.cxx +++ b/NDKKit/Sources/AssemblerAMD64.cxx @@ -53,7 +53,7 @@ #define kStdOut (std::cout << kWhite) #define kStdErr (std::cout << kRed) -static char kOutputArch = CompilerKit::kPefArchAMD64; +static char kOutputArch = NDK::kPefArchAMD64; static Boolean kOutputAsBinary = false; static UInt32 kErrorLimit = 10; @@ -73,12 +73,12 @@ static bool kVerbose = false; static std::vector<i64_byte_t> kAppBytes; -static CompilerKit::AERecordHeader kCurrentRecord{ - .fName = "", .fKind = CompilerKit::kPefCode, .fSize = 0, .fOffset = 0}; +static NDK::AERecordHeader kCurrentRecord{ + .fName = "", .fKind = NDK::kPefCode, .fSize = 0, .fOffset = 0}; -static std::vector<CompilerKit::AERecordHeader> kRecords; -static std::vector<std::string> kDefinedSymbols; -static std::vector<std::string> kUndefinedSymbols; +static std::vector<NDK::AERecordHeader> kRecords; +static std::vector<std::string> kDefinedSymbols; +static std::vector<std::string> kUndefinedSymbols; static const std::string kUndefinedSymbol = ":UndefinedSymbol:"; static const std::string kRelocSymbol = ":RuntimeSymbol:"; @@ -86,40 +86,6 @@ static const std::string kRelocSymbol = ":RuntimeSymbol:"; // \brief forward decl. static bool asm_read_attributes(std::string& line); -namespace detail -{ - void print_error(std::string reason, const std::string& file) noexcept - { - if (reason[0] == '\n') - reason.erase(0, 1); - - kStdErr << kRed << "[ i64asm ] " << kWhite - << ((file == "i64asm") ? "internal assembler error " - : ("in file, " + file)) - << kBlank << std::endl; - kStdErr << kRed << "[ i64asm ] " << kWhite << reason << kBlank << std::endl; - - if (kAcceptableErrors > kErrorLimit) - std::exit(3); - - ++kAcceptableErrors; - } - - void print_warning(std::string reason, const std::string& file) noexcept - { - if (reason[0] == '\n') - reason.erase(0, 1); - - if (!file.empty()) - { - kStdOut << kYellow << "[ file ] " << kWhite << file << kBlank << std::endl; - } - - kStdOut << kYellow << "[ i64asm ] " << kWhite << reason << kBlank - << std::endl; - } -} // namespace detail - #include <asmutils.hxx> ///////////////////////////////////////////////////////////////////////////////////////// @@ -234,13 +200,13 @@ NDK_MODULE(NewOSAssemblerAMD64) std::string line; - CompilerKit::AEHeader hdr{0}; + NDK::AEHeader hdr{0}; memset(hdr.fPad, kAEInvalidOpcode, kAEPad); hdr.fMagic[0] = kAEMag0; hdr.fMagic[1] = kAEMag1; - hdr.fSize = sizeof(CompilerKit::AEHeader); + hdr.fSize = sizeof(NDK::AEHeader); hdr.fArch = kOutputArch; ///////////////////////////////////////////////////////////////////////////////////////// @@ -249,13 +215,13 @@ NDK_MODULE(NewOSAssemblerAMD64) ///////////////////////////////////////////////////////////////////////////////////////// - CompilerKit::EncoderAMD64 asm64; + NDK::EncoderAMD64 asm64; while (std::getline(file_ptr, line)) { if (auto ln = asm64.CheckLine(line, argv[i]); !ln.empty()) { - detail::print_error(ln, argv[i]); + detail::print_error_asm(ln, argv[i]); continue; } @@ -269,7 +235,7 @@ NDK_MODULE(NewOSAssemblerAMD64) if (kVerbose) { std::string what = e.what(); - detail::print_warning("exit because of: " + what, "i64asm"); + detail::print_warning_asm("exit because of: " + what, "i64asm"); } try @@ -317,7 +283,7 @@ NDK_MODULE(NewOSAssemblerAMD64) if (kVerbose) kStdOut << "i64asm: Wrote record " << rec.fName << " to file...\n"; - rec.fFlags |= CompilerKit::kKindRelocationAtRuntime; + rec.fFlags |= NDK::kKindRelocationAtRuntime; rec.fOffset = record_count; ++record_count; @@ -329,7 +295,7 @@ NDK_MODULE(NewOSAssemblerAMD64) for (auto& sym : kUndefinedSymbols) { - CompilerKit::AERecordHeader _record_hdr{0}; + NDK::AERecordHeader _record_hdr{0}; if (kVerbose) kStdOut << "i64asm: Wrote symbol " << sym << " to file...\n"; @@ -412,11 +378,11 @@ static bool asm_read_attributes(std::string& line) { // import is the opposite of export, it signals to the ld // that we need this symbol. - if (CompilerKit::find_word(line, "import")) + if (NDK::find_word(line, "import")) { if (kOutputAsBinary) { - detail::print_error("Invalid directive in flat binary mode.", "i64asm"); + detail::print_error_asm("Invalid directive in flat binary mode.", "i64asm"); throw std::runtime_error("invalid_import_bin"); } @@ -424,7 +390,7 @@ static bool asm_read_attributes(std::string& line) if (name.size() == 0) { - detail::print_error("Invalid import", "power-as"); + detail::print_error_asm("Invalid import", "power-as"); throw std::runtime_error("invalid_import"); } @@ -443,17 +409,17 @@ static bool asm_read_attributes(std::string& line) if (name.find(".code64") != std::string::npos) { // data is treated as code. - kCurrentRecord.fKind = CompilerKit::kPefCode; + kCurrentRecord.fKind = NDK::kPefCode; } else if (name.find(".data64") != std::string::npos) { // no code will be executed from here. - kCurrentRecord.fKind = CompilerKit::kPefData; + kCurrentRecord.fKind = NDK::kPefData; } else if (name.find(".zero64") != std::string::npos) { // this is a bss section. - kCurrentRecord.fKind = CompilerKit::kPefZero; + kCurrentRecord.fKind = NDK::kPefZero; } // this is a special case for the start stub. @@ -461,7 +427,7 @@ static bool asm_read_attributes(std::string& line) if (name == kPefStart) { - kCurrentRecord.fKind = CompilerKit::kPefCode; + kCurrentRecord.fKind = NDK::kPefCode; } // now we can tell the code size of the previous kCurrentRecord. @@ -483,11 +449,11 @@ static bool asm_read_attributes(std::string& line) // export is a special keyword used by i64asm to tell the AE output stage to // mark this section as a header. it currently supports .code64, .data64 and // .zero64. - else if (CompilerKit::find_word(line, "export")) + else if (NDK::find_word(line, "export")) { if (kOutputAsBinary) { - detail::print_error("Invalid directive in flat binary mode.", "i64asm"); + detail::print_error_asm("Invalid directive in flat binary mode.", "i64asm"); throw std::runtime_error("invalid_export_bin"); } @@ -504,7 +470,7 @@ static bool asm_read_attributes(std::string& line) if (std::find(kDefinedSymbols.begin(), kDefinedSymbols.end(), name) != kDefinedSymbols.end()) { - detail::print_error("Symbol already defined.", "i64asm"); + detail::print_error_asm("Symbol already defined.", "i64asm"); throw std::runtime_error("invalid_export_bin"); } @@ -515,21 +481,21 @@ static bool asm_read_attributes(std::string& line) // data is treated as code. name_copy.erase(name_copy.find(".code64"), strlen(".code64")); - kCurrentRecord.fKind = CompilerKit::kPefCode; + kCurrentRecord.fKind = NDK::kPefCode; } else if (name.find(".data64") != std::string::npos) { // no code will be executed from here. name_copy.erase(name_copy.find(".data64"), strlen(".data64")); - kCurrentRecord.fKind = CompilerKit::kPefData; + kCurrentRecord.fKind = NDK::kPefData; } else if (name.find(".zero64") != std::string::npos) { // this is a bss section. name_copy.erase(name_copy.find(".zero64"), strlen(".zero64")); - kCurrentRecord.fKind = CompilerKit::kPefZero; + kCurrentRecord.fKind = NDK::kPefZero; } // this is a special case for the start stub. @@ -537,7 +503,7 @@ static bool asm_read_attributes(std::string& line) if (name == kPefStart) { - kCurrentRecord.fKind = CompilerKit::kPefCode; + kCurrentRecord.fKind = NDK::kPefCode; } while (name_copy.find(" ") != std::string::npos) @@ -579,7 +545,7 @@ namespace detail::algorithm (c == '_') || (c == ':') || (c == '@') || (c == '.') || (c == '#')); } - bool is_valid(const std::string& str) + bool is_valid_amd64(const std::string& str) { return std::find_if(str.begin(), str.end(), is_not_alnum_space) == str.end(); } @@ -591,15 +557,15 @@ namespace detail::algorithm ///////////////////////////////////////////////////////////////////////////////////////// -std::string CompilerKit::EncoderAMD64::CheckLine(std::string& line, - const std::string& file) +std::string NDK::EncoderAMD64::CheckLine(std::string& line, + const std::string& file) { std::string err_str; - if (line.empty() || CompilerKit::find_word(line, "import") || - CompilerKit::find_word(line, "export") || - CompilerKit::find_word(line, kAssemblerPragmaSymStr) || - CompilerKit::find_word(line, ";") || line[0] == kAssemblerPragmaSym) + if (line.empty() || NDK::find_word(line, "import") || + NDK::find_word(line, "export") || + NDK::find_word(line, kAssemblerPragmaSymStr) || + NDK::find_word(line, ";") || line[0] == kAssemblerPragmaSym) { if (line.find(';') != std::string::npos) { @@ -608,7 +574,7 @@ std::string CompilerKit::EncoderAMD64::CheckLine(std::string& line, else { // now check the line for validity - if (!detail::algorithm::is_valid(line)) + if (!detail::algorithm::is_valid_amd64(line)) { err_str = "Line contains non valid characters.\nhere -> "; err_str += line; @@ -618,7 +584,7 @@ std::string CompilerKit::EncoderAMD64::CheckLine(std::string& line, return err_str; } - if (!detail::algorithm::is_valid(line)) + if (!detail::algorithm::is_valid_amd64(line)) { err_str = "Line contains non alphanumeric characters.\nHere -> "; err_str += line; @@ -671,7 +637,7 @@ std::string CompilerKit::EncoderAMD64::CheckLine(std::string& line, } for (auto& opcodeAMD64 : kOpcodesAMD64) { - if (CompilerKit::find_word(line, opcodeAMD64.fName)) + if (NDK::find_word(line, opcodeAMD64.fName)) { return err_str; } @@ -682,8 +648,8 @@ std::string CompilerKit::EncoderAMD64::CheckLine(std::string& line, return err_str; } -bool CompilerKit::EncoderAMD64::WriteNumber(const std::size_t& pos, - std::string& jump_label) +bool NDK::EncoderAMD64::WriteNumber(const std::size_t& pos, + std::string& jump_label) { if (!isdigit(jump_label[pos])) return false; @@ -696,12 +662,12 @@ bool CompilerKit::EncoderAMD64::WriteNumber(const std::size_t& pos, { if (errno != 0) { - detail::print_error("invalid hex number: " + jump_label, "i64asm"); + detail::print_error_asm("invalid hex number: " + jump_label, "i64asm"); throw std::runtime_error("invalid_hex"); } } - CompilerKit::NumberCast64 num = CompilerKit::NumberCast64( + NDK::NumberCast64 num = NDK::NumberCast64( strtol(jump_label.substr(pos + 2).c_str(), nullptr, 16)); for (char& i : num.number) @@ -726,12 +692,12 @@ bool CompilerKit::EncoderAMD64::WriteNumber(const std::size_t& pos, { if (errno != 0) { - detail::print_error("invalid binary number: " + jump_label, "i64asm"); + detail::print_error_asm("invalid binary number: " + jump_label, "i64asm"); throw std::runtime_error("invalid_bin"); } } - CompilerKit::NumberCast64 num = CompilerKit::NumberCast64( + NDK::NumberCast64 num = NDK::NumberCast64( strtol(jump_label.substr(pos + 2).c_str(), nullptr, 2)); if (kVerbose) @@ -756,12 +722,12 @@ bool CompilerKit::EncoderAMD64::WriteNumber(const std::size_t& pos, { if (errno != 0) { - detail::print_error("invalid octal number: " + jump_label, "i64asm"); + detail::print_error_asm("invalid octal number: " + jump_label, "i64asm"); throw std::runtime_error("invalid_octal"); } } - CompilerKit::NumberCast64 num = CompilerKit::NumberCast64( + NDK::NumberCast64 num = NDK::NumberCast64( strtol(jump_label.substr(pos + 2).c_str(), nullptr, 7)); if (kVerbose) @@ -794,7 +760,7 @@ bool CompilerKit::EncoderAMD64::WriteNumber(const std::size_t& pos, } } - CompilerKit::NumberCast64 num = CompilerKit::NumberCast64( + NDK::NumberCast64 num = NDK::NumberCast64( strtol(jump_label.substr(pos).c_str(), nullptr, 10)); for (char& i : num.number) @@ -814,8 +780,8 @@ bool CompilerKit::EncoderAMD64::WriteNumber(const std::size_t& pos, return true; } -bool CompilerKit::EncoderAMD64::WriteNumber32(const std::size_t& pos, - std::string& jump_label) +bool NDK::EncoderAMD64::WriteNumber32(const std::size_t& pos, + std::string& jump_label) { if (!isdigit(jump_label[pos])) return false; @@ -831,7 +797,7 @@ bool CompilerKit::EncoderAMD64::WriteNumber32(const std::size_t& pos, return false; } - CompilerKit::NumberCast32 num = CompilerKit::NumberCast32(res); + NDK::NumberCast32 num = NDK::NumberCast32(res); for (char& i : num.number) { @@ -858,7 +824,7 @@ bool CompilerKit::EncoderAMD64::WriteNumber32(const std::size_t& pos, return false; } - CompilerKit::NumberCast32 num = CompilerKit::NumberCast32(res); + NDK::NumberCast32 num = NDK::NumberCast32(res); if (kVerbose) { @@ -885,7 +851,7 @@ bool CompilerKit::EncoderAMD64::WriteNumber32(const std::size_t& pos, return false; } - CompilerKit::NumberCast32 num = CompilerKit::NumberCast32(res); + NDK::NumberCast32 num = NDK::NumberCast32(res); if (kVerbose) { @@ -916,7 +882,7 @@ bool CompilerKit::EncoderAMD64::WriteNumber32(const std::size_t& pos, return false; } - CompilerKit::NumberCast32 num = CompilerKit::NumberCast32(res); + NDK::NumberCast32 num = NDK::NumberCast32(res); for (char& i : num.number) { @@ -935,8 +901,8 @@ bool CompilerKit::EncoderAMD64::WriteNumber32(const std::size_t& pos, return true; } -bool CompilerKit::EncoderAMD64::WriteNumber16(const std::size_t& pos, - std::string& jump_label) +bool NDK::EncoderAMD64::WriteNumber16(const std::size_t& pos, + std::string& jump_label) { if (!isdigit(jump_label[pos])) return false; @@ -949,12 +915,12 @@ bool CompilerKit::EncoderAMD64::WriteNumber16(const std::size_t& pos, { if (errno != 0) { - detail::print_error("invalid hex number: " + jump_label, "i64asm"); + detail::print_error_asm("invalid hex number: " + jump_label, "i64asm"); throw std::runtime_error("invalid_hex"); } } - CompilerKit::NumberCast16 num = CompilerKit::NumberCast16( + NDK::NumberCast16 num = NDK::NumberCast16( strtol(jump_label.substr(pos + 2).c_str(), nullptr, 16)); for (char& i : num.number) @@ -979,12 +945,12 @@ bool CompilerKit::EncoderAMD64::WriteNumber16(const std::size_t& pos, { if (errno != 0) { - detail::print_error("invalid binary number: " + jump_label, "i64asm"); + detail::print_error_asm("invalid binary number: " + jump_label, "i64asm"); throw std::runtime_error("invalid_bin"); } } - CompilerKit::NumberCast16 num = CompilerKit::NumberCast16( + NDK::NumberCast16 num = NDK::NumberCast16( strtol(jump_label.substr(pos + 2).c_str(), nullptr, 2)); if (kVerbose) @@ -1009,12 +975,12 @@ bool CompilerKit::EncoderAMD64::WriteNumber16(const std::size_t& pos, { if (errno != 0) { - detail::print_error("invalid octal number: " + jump_label, "i64asm"); + detail::print_error_asm("invalid octal number: " + jump_label, "i64asm"); throw std::runtime_error("invalid_octal"); } } - CompilerKit::NumberCast16 num = CompilerKit::NumberCast16( + NDK::NumberCast16 num = NDK::NumberCast16( strtol(jump_label.substr(pos + 2).c_str(), nullptr, 7)); if (kVerbose) @@ -1047,7 +1013,7 @@ bool CompilerKit::EncoderAMD64::WriteNumber16(const std::size_t& pos, } } - CompilerKit::NumberCast16 num = CompilerKit::NumberCast16( + NDK::NumberCast16 num = NDK::NumberCast16( strtol(jump_label.substr(pos).c_str(), nullptr, 10)); for (char& i : num.number) @@ -1067,8 +1033,8 @@ bool CompilerKit::EncoderAMD64::WriteNumber16(const std::size_t& pos, return true; } -bool CompilerKit::EncoderAMD64::WriteNumber8(const std::size_t& pos, - std::string& jump_label) +bool NDK::EncoderAMD64::WriteNumber8(const std::size_t& pos, + std::string& jump_label) { if (!isdigit(jump_label[pos])) return false; @@ -1081,12 +1047,12 @@ bool CompilerKit::EncoderAMD64::WriteNumber8(const std::size_t& pos, { if (errno != 0) { - detail::print_error("invalid hex number: " + jump_label, "i64asm"); + detail::print_error_asm("invalid hex number: " + jump_label, "i64asm"); throw std::runtime_error("invalid_hex"); } } - CompilerKit::NumberCast8 num = CompilerKit::NumberCast8( + NDK::NumberCast8 num = NDK::NumberCast8( strtol(jump_label.substr(pos + 2).c_str(), nullptr, 16)); kAppBytes.push_back(num.number); @@ -1105,12 +1071,12 @@ bool CompilerKit::EncoderAMD64::WriteNumber8(const std::size_t& pos, { if (errno != 0) { - detail::print_error("invalid binary number: " + jump_label, "i64asm"); + detail::print_error_asm("invalid binary number: " + jump_label, "i64asm"); throw std::runtime_error("invalid_bin"); } } - CompilerKit::NumberCast8 num = CompilerKit::NumberCast8( + NDK::NumberCast8 num = NDK::NumberCast8( strtol(jump_label.substr(pos + 2).c_str(), nullptr, 2)); if (kVerbose) @@ -1129,12 +1095,12 @@ bool CompilerKit::EncoderAMD64::WriteNumber8(const std::size_t& pos, { if (errno != 0) { - detail::print_error("invalid octal number: " + jump_label, "i64asm"); + detail::print_error_asm("invalid octal number: " + jump_label, "i64asm"); throw std::runtime_error("invalid_octal"); } } - CompilerKit::NumberCast8 num = CompilerKit::NumberCast8( + NDK::NumberCast8 num = NDK::NumberCast8( strtol(jump_label.substr(pos + 2).c_str(), nullptr, 7)); if (kVerbose) @@ -1161,7 +1127,7 @@ bool CompilerKit::EncoderAMD64::WriteNumber8(const std::size_t& pos, } } - CompilerKit::NumberCast8 num = CompilerKit::NumberCast8( + NDK::NumberCast8 num = NDK::NumberCast8( strtol(jump_label.substr(pos).c_str(), nullptr, 10)); kAppBytes.push_back(num.number); @@ -1181,10 +1147,10 @@ bool CompilerKit::EncoderAMD64::WriteNumber8(const std::size_t& pos, ///////////////////////////////////////////////////////////////////////////////////////// -bool CompilerKit::EncoderAMD64::WriteLine(std::string& line, - const std::string& file) +bool NDK::EncoderAMD64::WriteLine(std::string& line, + const std::string& file) { - if (CompilerKit::find_word(line, "export ")) + if (NDK::find_word(line, "export ")) return true; struct RegMapAMD64 @@ -1216,8 +1182,8 @@ bool CompilerKit::EncoderAMD64::WriteLine(std::string& line, for (auto& opcodeAMD64 : kOpcodesAMD64) { // strict check here - if (CompilerKit::find_word(line, opcodeAMD64.fName) && - detail::algorithm::is_valid(line)) + if (NDK::find_word(line, opcodeAMD64.fName) && + detail::algorithm::is_valid_amd64(line)) { foundInstruction = true; std::string name(opcodeAMD64.fName); @@ -1231,7 +1197,7 @@ bool CompilerKit::EncoderAMD64::WriteLine(std::string& line, if (substr.find(",") == std::string::npos) { - detail::print_error("Syntax error.", "i64asm"); + detail::print_error_asm("Syntax error.", "i64asm"); throw std::runtime_error("syntax_err"); } @@ -1260,7 +1226,7 @@ bool CompilerKit::EncoderAMD64::WriteLine(std::string& line, { if (registerName[0] == 'r') { - detail::print_error( + detail::print_error_asm( "invalid size for register, current bit width is: " + std::to_string(kRegisterBitWidth), file); @@ -1314,7 +1280,7 @@ bool CompilerKit::EncoderAMD64::WriteLine(std::string& line, { if (hasRBasedRegs) { - detail::print_error( + detail::print_error_asm( "Invalid combination of operands and registers.", "i64asm"); throw std::runtime_error("comb_op_reg"); } @@ -1326,7 +1292,7 @@ bool CompilerKit::EncoderAMD64::WriteLine(std::string& line, if (currentRegList[1].fName[0] == 'r' && currentRegList[0].fName[0] == 'e') { - detail::print_error("Invalid combination of operands and registers.", + detail::print_error_asm("Invalid combination of operands and registers.", "i64asm"); throw std::runtime_error("comb_op_reg"); } @@ -1334,7 +1300,7 @@ bool CompilerKit::EncoderAMD64::WriteLine(std::string& line, if (currentRegList[0].fName[0] == 'r' && currentRegList[1].fName[0] == 'e') { - detail::print_error("Invalid combination of operands and registers.", + detail::print_error_asm("Invalid combination of operands and registers.", "i64asm"); throw std::runtime_error("comb_op_reg"); } @@ -1344,7 +1310,7 @@ bool CompilerKit::EncoderAMD64::WriteLine(std::string& line, if (currentRegList[0].fName[0] == 'r' || currentRegList[0].fName[0] == 'e') { - detail::print_error("Invalid combination of operands and registers.", + detail::print_error_asm("Invalid combination of operands and registers.", "i64asm"); throw std::runtime_error("comb_op_reg"); } @@ -1352,7 +1318,7 @@ bool CompilerKit::EncoderAMD64::WriteLine(std::string& line, if (currentRegList[1].fName[0] == 'r' || currentRegList[1].fName[0] == 'e') { - detail::print_error("Invalid combination of operands and registers.", + detail::print_error_asm("Invalid combination of operands and registers.", "i64asm"); throw std::runtime_error("comb_op_reg"); } @@ -1362,7 +1328,7 @@ bool CompilerKit::EncoderAMD64::WriteLine(std::string& line, if (currentRegList[0].fName[0] != 'r' || currentRegList[0].fName[0] == 'e') { - detail::print_error("Invalid combination of operands and registers.", + detail::print_error_asm("Invalid combination of operands and registers.", "i64asm"); throw std::runtime_error("comb_op_reg"); } @@ -1370,7 +1336,7 @@ bool CompilerKit::EncoderAMD64::WriteLine(std::string& line, if (currentRegList[1].fName[0] != 'r' || currentRegList[1].fName[0] == 'e') { - detail::print_error("Invalid combination of operands and registers.", + detail::print_error_asm("Invalid combination of operands and registers.", "i64asm"); throw std::runtime_error("comb_op_reg"); } @@ -1416,7 +1382,7 @@ bool CompilerKit::EncoderAMD64::WriteLine(std::string& line, { if (foundInstruction) { - detail::print_error("Syntax error: " + line, "i64asm"); + detail::print_error_asm("Syntax error: " + line, "i64asm"); throw std::runtime_error("syntax_err"); } diff --git a/NDKKit/Sources/AssemblerPower.cxx b/NDKKit/Sources/AssemblerPower.cxx new file mode 100644 index 0000000..f118fc3 --- /dev/null +++ b/NDKKit/Sources/AssemblerPower.cxx @@ -0,0 +1,1096 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies + +------------------------------------------- */ + +///////////////////////////////////////////////////////////////////////////////////////// + +/// @file power-as.cxx +/// @author Amlal EL Mahrouss +/// @brief POWER Assembler. + +/// REMINDER: when dealing with an undefined symbol use (string +/// size):LinkerFindSymbol:(string) so that li will look for it. + +///////////////////////////////////////////////////////////////////////////////////////// + +#define __ASM_NEED_PPC__ 1 + +#include <NDKKit/NFC/ErrorID.hxx> +#include <NDKKit/AsmKit/CPU/ppc.hxx> +#include <NDKKit/NFC/PEF.hxx> +#include <NDKKit/Parser.hxx> +#include <NDKKit/NFC/AE.hxx> +#include <NDKKit/Version.hxx> +#include <filesystem> +#include <algorithm> +#include <iostream> +#include <fstream> +#include <vector> + +///////////////////// + +// ANSI ESCAPE CODES + +///////////////////// + +#define kBlank "\e[0;30m" +#define kRed "\e[0;31m" +#define kWhite "\e[0;97m" +#define kYellow "\e[0;33m" + +#define kStdOut (std::cout << kWhite) +#define kStdErr (std::cout << kRed) + +constexpr auto cPowerIPAlignment = 0x4U; + +static CharType kOutputArch = NDK::kPefArchPowerPC; +static Boolean kOutputAsBinary = false; + +static UInt32 kErrorLimit = 10; +static UInt32 kAcceptableErrors = 0; + +static std::size_t kCounter = 1UL; + +static std::uintptr_t kOrigin = kPefBaseOrigin; +static std::vector<std::pair<std::string, std::uintptr_t>> kOriginLabel; + +static bool kVerbose = false; + +static std::vector<uint8_t> kBytes; + +static NDK::AERecordHeader kCurrentRecord{ + .fName = "", .fKind = NDK::kPefCode, .fSize = 0, .fOffset = 0}; + +static std::vector<NDK::AERecordHeader> kRecords; +static std::vector<std::string> kUndefinedSymbols; + +static const std::string kUndefinedSymbol = ":UndefinedSymbol:"; +static const std::string kRelocSymbol = ":RuntimeSymbol:"; + +// \brief forward decl. +static bool asm_read_attributes(std::string& line); + +/// Do not move it on top! it uses the assembler detail namespace! +#include <asmutils.hxx> + +///////////////////////////////////////////////////////////////////////////////////////// + +/// @brief POWER assembler entrypoint, the program/module starts here. + +///////////////////////////////////////////////////////////////////////////////////////// + +NDK_MODULE(NewOSAssemblerPowerPC) +{ + for (size_t i = 1; i < argc; ++i) + { + if (argv[i][0] == '/') + { + if (strcmp(argv[i], "/version") == 0 || strcmp(argv[i], "/v") == 0) + { + kStdOut << "power-as: POWER64 Assembler Driver.\npower-as: " << kDistVersion << "\npower-as: " + "Copyright (c) " + "ZKA Technologies.\n"; + return 0; + } + else if (strcmp(argv[i], "/h") == 0) + { + kStdOut << "power-as: POWER64 Assembler Driver.\npower-as: Copyright (c) 2024 " + "ZKA Technologies.\n"; + kStdOut << "/version,/v: print program version.\n"; + kStdOut << "/verbose: print verbose output.\n"; + kStdOut << "/binary: output as flat binary.\n"; + + return 0; + } + else if (strcmp(argv[i], "/binary") == 0) + { + kOutputAsBinary = true; + continue; + } + else if (strcmp(argv[i], "/verbose") == 0) + { + kVerbose = true; + continue; + } + + kStdOut << "power-as: ignore " << argv[i] << "\n"; + continue; + } + + if (!std::filesystem::exists(argv[i])) + { + kStdOut << "power-as: can't open: " << argv[i] << std::endl; + goto asm_fail_exit; + } + + std::string object_output(argv[i]); + + for (auto& ext : kAsmFileExts) + { + if (object_output.find(ext) != std::string::npos) + { + object_output.erase(object_output.find(ext), std::strlen(ext)); + } + } + + object_output += kOutputAsBinary ? kBinaryFileExt : kObjectFileExt; + + std::ifstream file_ptr(argv[i]); + std::ofstream file_ptr_out(object_output, std::ofstream::binary); + + if (file_ptr_out.bad()) + { + if (kVerbose) + { + kStdOut << "power-as: error: " << strerror(errno) << "\n"; + } + } + + std::string line; + + NDK::AEHeader hdr{0}; + + memset(hdr.fPad, kAEInvalidOpcode, kAEPad); + + hdr.fMagic[0] = kAEMag0; + hdr.fMagic[1] = kAEMag1; + hdr.fSize = sizeof(NDK::AEHeader); + hdr.fArch = kOutputArch; + + ///////////////////////////////////////////////////////////////////////////////////////// + + // COMPILATION LOOP + + ///////////////////////////////////////////////////////////////////////////////////////// + + NDK::EncoderPowerPC asm64; + + while (std::getline(file_ptr, line)) + { + if (auto ln = asm64.CheckLine(line, argv[i]); !ln.empty()) + { + detail::print_error_asm(ln, argv[i]); + continue; + } + + try + { + asm_read_attributes(line); + asm64.WriteLine(line, argv[i]); + } + catch (const std::exception& e) + { + if (kVerbose) + { + std::string what = e.what(); + detail::print_warning_asm("exit because of: " + what, "power-as"); + } + + std::filesystem::remove(object_output); + goto asm_fail_exit; + } + } + + if (!kOutputAsBinary) + { + if (kVerbose) + { + kStdOut << "power-as: Writing object file...\n"; + } + + // this is the final step, write everything to the file. + + auto pos = file_ptr_out.tellp(); + + hdr.fCount = kRecords.size() + kUndefinedSymbols.size(); + + file_ptr_out << hdr; + + if (kRecords.empty()) + { + kStdErr << "power-as: At least one record is needed to write an object " + "file.\npower-as: Make one using `export .code64 foo_bar`.\n"; + + std::filesystem::remove(object_output); + return -1; + } + + kRecords[kRecords.size() - 1].fSize = kBytes.size(); + + std::size_t record_count = 0UL; + + for (auto& record_hdr : kRecords) + { + record_hdr.fFlags |= NDK::kKindRelocationAtRuntime; + record_hdr.fOffset = record_count; + ++record_count; + + file_ptr_out << record_hdr; + + if (kVerbose) + kStdOut << "power-as: Wrote record " << record_hdr.fName << "...\n"; + } + + // increment once again, so that we won't lie about the kUndefinedSymbols. + ++record_count; + + for (auto& sym : kUndefinedSymbols) + { + NDK::AERecordHeader undefined_sym{0}; + + if (kVerbose) + kStdOut << "power-as: Wrote symbol " << sym << " to file...\n"; + + undefined_sym.fKind = kAEInvalidOpcode; + undefined_sym.fSize = sym.size(); + undefined_sym.fOffset = record_count; + + ++record_count; + + memset(undefined_sym.fPad, kAEInvalidOpcode, kAEPad); + memcpy(undefined_sym.fName, sym.c_str(), sym.size()); + + file_ptr_out << undefined_sym; + + ++kCounter; + } + + auto pos_end = file_ptr_out.tellp(); + + file_ptr_out.seekp(pos); + + hdr.fStartCode = pos_end; + hdr.fCodeSize = kBytes.size(); + + file_ptr_out << hdr; + + file_ptr_out.seekp(pos_end); + } + else + { + if (kVerbose) + { + kStdOut << "power-as: Write raw binary...\n"; + } + } + + // byte from byte, we write this. + for (auto& byte : kBytes) + { + file_ptr_out.write(reinterpret_cast<const char*>(&byte), sizeof(byte)); + } + + if (kVerbose) + kStdOut << "power-as: Wrote file with program in it.\n"; + + file_ptr_out.flush(); + file_ptr_out.close(); + + if (kVerbose) + kStdOut << "power-as: Exit succeeded.\n"; + + return 0; + } + +asm_fail_exit: + + if (kVerbose) + kStdOut << "power-as: Exit failed.\n"; + + return MPCC_EXEC_ERROR; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +// @brief Check for attributes +// returns true if any was found. + +///////////////////////////////////////////////////////////////////////////////////////// + +static bool asm_read_attributes(std::string& line) +{ + // import is the opposite of export, it signals to the li + // that we need this symbol. + if (NDK::find_word(line, "import")) + { + if (kOutputAsBinary) + { + detail::print_error_asm("Invalid import directive in flat binary mode.", + "power-as"); + throw std::runtime_error("invalid_import_bin"); + } + + auto name = line.substr(line.find("import") + strlen("import") + 1); + + if (name.size() == 0) + { + detail::print_error_asm("Invalid import", "power-as"); + throw std::runtime_error("invalid_import"); + } + + std::string result = std::to_string(name.size()); + result += kUndefinedSymbol; + + // mangle this + for (char& j : name) + { + if (j == ' ' || j == ',') + j = '$'; + } + + result += name; + + if (name.find(".code64") != std::string::npos) + { + // data is treated as code. + kCurrentRecord.fKind = NDK::kPefCode; + } + else if (name.find(".data64") != std::string::npos) + { + // no code will be executed from here. + kCurrentRecord.fKind = NDK::kPefData; + } + else if (name.find(".zero64") != std::string::npos) + { + // this is a bss section. + kCurrentRecord.fKind = NDK::kPefZero; + } + + // this is a special case for the start stub. + // we want this so that li can find it. + + if (name == kPefStart) + { + kCurrentRecord.fKind = NDK::kPefCode; + } + + // now we can tell the code size of the previous kCurrentRecord. + + if (!kRecords.empty()) + kRecords[kRecords.size() - 1].fSize = kBytes.size(); + + memset(kCurrentRecord.fName, 0, kAESymbolLen); + memcpy(kCurrentRecord.fName, result.c_str(), result.size()); + + ++kCounter; + + memset(kCurrentRecord.fPad, kAEInvalidOpcode, kAEPad); + + kRecords.emplace_back(kCurrentRecord); + + return true; + } + // export is a special keyword used by power-as to tell the AE output stage to + // mark this section as a header. it currently supports .code64, .data64., + // .zero64 + else if (NDK::find_word(line, "export")) + { + if (kOutputAsBinary) + { + detail::print_error_asm("Invalid export directive in flat binary mode.", + "power-as"); + throw std::runtime_error("invalid_export_bin"); + } + + auto name = line.substr(line.find("export") + strlen("export")); + + std::string name_copy = name; + + for (char& j : name) + { + if (j == ' ') + j = '$'; + } + + if (name.find(".code64") != std::string::npos) + { + // data is treated as code. + + name_copy.erase(name_copy.find(".code64"), strlen(".code64")); + kCurrentRecord.fKind = NDK::kPefCode; + } + else if (name.find(".data64") != std::string::npos) + { + // no code will be executed from here. + + name_copy.erase(name_copy.find(".data64"), strlen(".data64")); + kCurrentRecord.fKind = NDK::kPefData; + } + else if (name.find(".zero64") != std::string::npos) + { + // this is a bss section. + + name_copy.erase(name_copy.find(".zero64"), strlen(".zero64")); + kCurrentRecord.fKind = NDK::kPefZero; + } + + // this is a special case for the start stub. + // we want this so that li can find it. + + if (name == kPefStart) + { + kCurrentRecord.fKind = NDK::kPefCode; + } + + while (name_copy.find(" ") != std::string::npos) + name_copy.erase(name_copy.find(" "), 1); + + kOriginLabel.push_back(std::make_pair(name_copy, kOrigin)); + ++kOrigin; + + // now we can tell the code size of the previous kCurrentRecord. + + if (!kRecords.empty()) + kRecords[kRecords.size() - 1].fSize = kBytes.size(); + + memset(kCurrentRecord.fName, 0, kAESymbolLen); + memcpy(kCurrentRecord.fName, name.c_str(), name.size()); + + ++kCounter; + + memset(kCurrentRecord.fPad, kAEInvalidOpcode, kAEPad); + + kRecords.emplace_back(kCurrentRecord); + + return true; + } + + return false; +} + +// \brief algorithms and helpers. + +namespace detail::algorithm +{ + // \brief authorize a brief set of characters. + static inline bool is_not_alnum_space(char c) + { + return !(isalpha(c) || isdigit(c) || (c == ' ') || (c == '\t') || + (c == ',') || (c == '(') || (c == ')') || (c == '"') || + (c == '\'') || (c == '[') || (c == ']') || (c == '+') || + (c == '_') || (c == ':') || (c == '@') || (c == '.')); + } + + bool is_valid_power64(const std::string& str) + { + return std::find_if(str.begin(), str.end(), is_not_alnum_space) == str.end(); + } +} // namespace detail::algorithm + +///////////////////////////////////////////////////////////////////////////////////////// + +// @brief Check for line (syntax check) + +///////////////////////////////////////////////////////////////////////////////////////// + +std::string NDK::EncoderPowerPC::CheckLine(std::string& line, + const std::string& file) +{ + std::string err_str; + + if (line.empty() || NDK::find_word(line, "import") || + NDK::find_word(line, "export") || + line.find('#') != std::string::npos || NDK::find_word(line, ";")) + { + if (line.find('#') != std::string::npos) + { + line.erase(line.find('#')); + } + else if (line.find(';') != std::string::npos) + { + line.erase(line.find(';')); + } + else + { + /// does the line contains valid input? + if (!detail::algorithm::is_valid_power64(line)) + { + err_str = "Line contains non alphanumeric characters.\nhere -> "; + err_str += line; + } + } + + return err_str; + } + + if (!detail::algorithm::is_valid_power64(line)) + { + err_str = "Line contains non alphanumeric characters.\nhere -> "; + err_str += line; + + return err_str; + } + + // check for a valid instruction format. + + if (line.find(',') != std::string::npos) + { + if (line.find(',') + 1 == line.size()) + { + err_str += "\nInstruction lacks right register, here -> "; + err_str += line.substr(line.find(',')); + + return err_str; + } + else + { + bool nothing_on_right = true; + + if (line.find(',') + 1 > line.size()) + { + err_str += "\nInstruction not complete, here -> "; + err_str += line; + + return err_str; + } + + auto substr = line.substr(line.find(',') + 1); + + for (auto& ch : substr) + { + if (ch != ' ' && ch != '\t') + { + nothing_on_right = false; + } + } + + // this means we found nothing after that ',' . + if (nothing_on_right) + { + err_str += "\nInstruction not complete, here -> "; + err_str += line; + + return err_str; + } + } + } + + // these do take an argument. + std::vector<std::string> operands_inst = {"stw", "li"}; + + // these don't. + std::vector<std::string> filter_inst = {"blr", "bl", "sc"}; + + for (auto& opcodePPC : kOpcodesPowerPC) + { + if (NDK::find_word(line, opcodePPC.name)) + { + for (auto& op : operands_inst) + { + // if only the instruction was found. + if (line == op) + { + err_str += "\nMalformed "; + err_str += op; + err_str += " instruction, here -> "; + err_str += line; + } + } + + // if it is like that -> addr1, 0x0 + if (auto it = + std::find(filter_inst.begin(), filter_inst.end(), opcodePPC.name); + it == filter_inst.cend()) + { + if (NDK::find_word(line, opcodePPC.name)) + { + if (!isspace( + line[line.find(opcodePPC.name) + strlen(opcodePPC.name)])) + { + err_str += "\nMissing space between "; + err_str += opcodePPC.name; + err_str += " and operands.\nhere -> "; + err_str += line; + } + } + } + + return err_str; + } + } + + err_str += "Unrecognized instruction: " + line; + + return err_str; +} + +bool NDK::EncoderPowerPC::WriteNumber(const std::size_t& pos, + std::string& jump_label) +{ + if (!isdigit(jump_label[pos])) + return false; + + switch (jump_label[pos + 1]) + { + case 'x': { + if (auto res = strtol(jump_label.substr(pos + 2).c_str(), nullptr, 16); + !res) + { + if (errno != 0) + { + detail::print_error_asm("invalid hex number: " + jump_label, "power-as"); + throw std::runtime_error("invalid_hex"); + } + } + + NDK::NumberCast64 num( + strtol(jump_label.substr(pos + 2).c_str(), nullptr, 16)); + + for (char& i : num.number) + { + kBytes.push_back(i); + } + + if (kVerbose) + { + kStdOut << "power-as: found a base 16 number here: " + << jump_label.substr(pos) << "\n"; + } + + return true; + } + case 'b': { + if (auto res = strtol(jump_label.substr(pos + 2).c_str(), nullptr, 2); + !res) + { + if (errno != 0) + { + detail::print_error_asm("invalid binary number: " + jump_label, "power-as"); + throw std::runtime_error("invalid_bin"); + } + } + + NDK::NumberCast64 num( + strtol(jump_label.substr(pos + 2).c_str(), nullptr, 2)); + + if (kVerbose) + { + kStdOut << "power-as: found a base 2 number here: " + << jump_label.substr(pos) << "\n"; + } + + for (char& i : num.number) + { + kBytes.push_back(i); + } + + return true; + } + case 'o': { + if (auto res = strtol(jump_label.substr(pos + 2).c_str(), nullptr, 7); + !res) + { + if (errno != 0) + { + detail::print_error_asm("invalid octal number: " + jump_label, "power-as"); + throw std::runtime_error("invalid_octal"); + } + } + + NDK::NumberCast64 num( + strtol(jump_label.substr(pos + 2).c_str(), nullptr, 7)); + + if (kVerbose) + { + kStdOut << "power-as: found a base 8 number here: " + << jump_label.substr(pos) << "\n"; + } + + for (char& i : num.number) + { + kBytes.push_back(i); + } + + return true; + } + default: { + break; + } + } + + /* check for errno and stuff like that */ + if (auto res = strtol(jump_label.substr(pos).c_str(), nullptr, 10); !res) + { + if (errno != 0) + { + return false; + } + } + + NDK::NumberCast64 num( + strtol(jump_label.substr(pos).c_str(), nullptr, 10)); + + for (char& i : num.number) + { + kBytes.push_back(i); + } + + if (kVerbose) + { + kStdOut << "power-as: found a base 10 number here: " << jump_label.substr(pos) + << "\n"; + } + + return true; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +/// @brief Read and write an instruction to the output array. + +///////////////////////////////////////////////////////////////////////////////////////// + +bool NDK::EncoderPowerPC::WriteLine(std::string& line, + const std::string& file) +{ + if (NDK::find_word(line, "export")) + return true; + if (!detail::algorithm::is_valid_power64(line)) + return true; + + for (auto& opcodePPC : kOpcodesPowerPC) + { + // strict check here + if (NDK::find_word(line, opcodePPC.name)) + { + std::string name(opcodePPC.name); + std::string jump_label, cpy_jump_label; + std::vector<size_t> found_registers_index; + + // check funct7 type. + switch (opcodePPC.ops->type) + { + default: { + NumberCast32 num(opcodePPC.opcode); + + for (auto ch : num.number) + { + kBytes.emplace_back(ch); + } + break; + } + case BADDR: + case PCREL: { + auto num = GetNumber32(line, name); + + kBytes.emplace_back(num.number[0]); + kBytes.emplace_back(num.number[1]); + kBytes.emplace_back(num.number[2]); + kBytes.emplace_back(0x48); + + break; + } + /// General purpose, float, vector operations. Everything that involve + /// registers. + case G0REG: + case FREG: + case VREG: + case GREG: { + // \brief how many registers we found. + std::size_t found_some_count = 0UL; + std::size_t register_count = 0UL; + std::string opcodeName = opcodePPC.name; + std::size_t register_sum = 0; + + NumberCast64 num(opcodePPC.opcode); + + for (size_t line_index = 0UL; line_index < line.size(); + line_index++) + { + if (line[line_index] == kAsmRegisterPrefix[0] && + isdigit(line[line_index + 1])) + { + std::string register_syntax = kAsmRegisterPrefix; + register_syntax += line[line_index + 1]; + + if (isdigit(line[line_index + 2])) + register_syntax += line[line_index + 2]; + + std::string reg_str; + reg_str += line[line_index + 1]; + + if (isdigit(line[line_index + 2])) + reg_str += line[line_index + 2]; + + // it ranges from r0 to r19 + // something like r190 doesn't exist in the instruction set. + if (isdigit(line[line_index + 3]) && + isdigit(line[line_index + 2])) + { + reg_str += line[line_index + 3]; + detail::print_error_asm( + "invalid register index, r" + reg_str + + "\nnote: The POWER accepts registers from r0 to r32.", + file); + throw std::runtime_error("invalid_register_index"); + } + + // finally cast to a size_t + std::size_t reg_index = strtol(reg_str.c_str(), nullptr, 10); + + if (reg_index > kAsmRegisterLimit) + { + detail::print_error_asm("invalid register index, r" + reg_str, + file); + throw std::runtime_error("invalid_register_index"); + } + + if (opcodeName == "li") + { + char numIndex = 0; + + for (size_t i = 0; i != reg_index; i++) + { + numIndex += 0x20; + } + + auto num = GetNumber32(line, reg_str); + + kBytes.push_back(num.number[0]); + kBytes.push_back(num.number[1]); + kBytes.push_back(numIndex); + kBytes.push_back(0x38); + + // check if bigger than two. + for (size_t i = 2; i < 4; i++) + { + if (num.number[i] > 0) + { + detail::print_warning_asm("number overflow on li operation.", + file); + break; + } + } + + break; + } + + if ((opcodeName[0] == 's' && opcodeName[1] == 't')) + { + if (register_sum == 0) + { + for (size_t indexReg = 0UL; indexReg < reg_index; + ++indexReg) + { + register_sum += 0x20; + } + } + else + { + register_sum += reg_index; + } + } + + if (opcodeName == "mr") + { + switch (register_count) + { + case 0: { + kBytes.push_back(0x78); + + char numIndex = 0x3; + + for (size_t i = 0; i != reg_index; i++) + { + numIndex += 0x8; + } + + kBytes.push_back(numIndex); + + break; + } + case 1: { + char numIndex = 0x1; + + for (size_t i = 0; i != reg_index; i++) + { + numIndex += 0x20; + } + + for (size_t i = 0; i != reg_index; i++) + { + kBytes[kBytes.size() - 1] += 0x8; + } + + kBytes[kBytes.size() - 1] -= 0x8; + + kBytes.push_back(numIndex); + + if (reg_index >= 10 && reg_index < 20) + kBytes.push_back(0x7d); + else if (reg_index >= 20 && reg_index < 30) + kBytes.push_back(0x7e); + else if (reg_index >= 30) + kBytes.push_back(0x7f); + else + kBytes.push_back(0x7c); + + break; + } + default: + break; + } + + ++register_count; + ++found_some_count; + } + + if (opcodeName == "addi") + { + if (found_some_count == 2 || found_some_count == 0) + kBytes.emplace_back(reg_index); + else if (found_some_count == 1) + kBytes.emplace_back(0x00); + + ++found_some_count; + + if (found_some_count > 3) + { + detail::print_error_asm("Too much registers. -> " + line, file); + throw std::runtime_error("too_much_regs"); + } + } + + if (opcodeName.find("cmp") != std::string::npos) + { + ++found_some_count; + + if (found_some_count > 3) + { + detail::print_error_asm("Too much registers. -> " + line, file); + throw std::runtime_error("too_much_regs"); + } + } + + if (opcodeName.find("mf") != std::string::npos || + opcodeName.find("mt") != std::string::npos) + { + char numIndex = 0; + + for (size_t i = 0; i != reg_index; i++) + { + numIndex += 0x20; + } + + num.number[2] += numIndex; + + ++found_some_count; + + if (found_some_count > 1) + { + detail::print_error_asm("Too much registers. -> " + line, file); + throw std::runtime_error("too_much_regs"); + } + + if (kVerbose) + { + kStdOut << "power-as: Found register: " << register_syntax + << "\n"; + kStdOut << "power-as: Amount of registers in instruction: " + << found_some_count << "\n"; + } + + if (reg_index >= 10 && reg_index < 20) + num.number[3] = 0x7d; + else if (reg_index >= 20 && reg_index < 30) + num.number[3] = 0x7e; + else if (reg_index >= 30) + num.number[3] = 0x7f; + else + num.number[3] = 0x7c; + + for (auto ch : num.number) + { + kBytes.emplace_back(ch); + } + } + + found_registers_index.push_back(reg_index); + } + } + + if (opcodeName == "addi") + { + kBytes.emplace_back(0x38); + } + + if (opcodeName.find("cmp") != std::string::npos) + { + char rightReg = 0x0; + + for (size_t i = 0; i != found_registers_index[1]; i++) + { + rightReg += 0x08; + } + + kBytes.emplace_back(0x00); + kBytes.emplace_back(rightReg); + kBytes.emplace_back(found_registers_index[0]); + kBytes.emplace_back(0x7c); + } + + if ((opcodeName[0] == 's' && opcodeName[1] == 't')) + { + size_t offset = 0UL; + + if (line.find('+') != std::string::npos) + { + auto number = GetNumber32(line.substr(line.find("+")), "+"); + offset = number.raw; + } + + kBytes.push_back(offset); + kBytes.push_back(0x00); + kBytes.push_back(register_sum); + + kBytes.emplace_back(0x90); + } + + if (opcodeName == "mr") + { + if (register_count == 1) + { + detail::print_error_asm("Too few registers. -> " + line, file); + throw std::runtime_error("too_few_registers"); + } + } + + // we're not in immediate addressing, reg to reg. + if (opcodePPC.ops->type != GREG) + { + // remember! register to register! + if (found_some_count == 1) + { + detail::print_error_asm( + "Unrecognized register found.\ntip: each power-as register " + "starts with 'r'.\nline: " + + line, + file); + + throw std::runtime_error("not_a_register"); + } + } + + if (found_some_count < 1 && name[0] != 'l' && name[0] != 's') + { + detail::print_error_asm( + "invalid combination of opcode and registers.\nline: " + line, + file); + throw std::runtime_error("invalid_comb_op_reg"); + } + + break; + } + } + + kOrigin += cPowerIPAlignment; + break; + } + } + + return true; +} + +// Last rev 13-1-24 diff --git a/NDKKit/Sources/AssemblyFactory.cxx b/NDKKit/Sources/AssemblyFactory.cxx index a04f4fc..961ca01 100644 --- a/NDKKit/Sources/AssemblyFactory.cxx +++ b/NDKKit/Sources/AssemblyFactory.cxx @@ -23,7 +23,7 @@ //! @file AsmKit.cpp //! @brief AssemblyKit source implementation. -namespace CompilerKit +namespace NDK { ///! @brief Compile for specific format (ELF, PEF, ZBIN) Int32 AssemblyFactory::Compile(std::string& sourceFile, @@ -56,4 +56,4 @@ namespace CompilerKit return mount_prev; } -} // namespace CompilerKit +} // namespace NDK diff --git a/NDKKit/Sources/bpp.cxx b/NDKKit/Sources/BasicPreProcessor.cxx index 6c8ab95..e707387 100644 --- a/NDKKit/Sources/bpp.cxx +++ b/NDKKit/Sources/BasicPreProcessor.cxx @@ -279,7 +279,7 @@ void bpp_parse_file(std::ifstream &hdr_file, std::ofstream &pp_out) { } for (auto macro : kMacros) { - if (CompilerKit::find_word(hdr_line, macro.fName) && + if (NDK::find_word(hdr_line, macro.fName) && hdr_line.find("%def") == std::string::npos) { auto value = macro.fValue; diff --git a/NDKKit/Sources/64x0-cc.cxx b/NDKKit/Sources/CCompiler64x0.cxx index f38bb28..40fae77 100644 --- a/NDKKit/Sources/64x0-cc.cxx +++ b/NDKKit/Sources/CCompiler64x0.cxx @@ -79,10 +79,10 @@ namespace detail struct CompilerState final { - std::vector<CompilerKit::SyntaxLeafList> fSyntaxTreeList; + std::vector<NDK::SyntaxLeafList> fSyntaxTreeList; std::vector<CompilerRegisterMap> kStackFrame; std::vector<CompilerStructMap> kStructMap; - CompilerKit::SyntaxLeafList* fSyntaxTree{nullptr}; + NDK::SyntaxLeafList* fSyntaxTree{nullptr}; std::unique_ptr<std::ofstream> fOutputAssembly; std::string fLastFile; std::string fLastError; @@ -100,37 +100,7 @@ namespace detail /// @brief prints an error into stdout. /// @param reason the reason of the error. /// @param file where does it originate from? - void print_error(std::string reason, std::string file) noexcept - { - if (reason[0] == '\n') - reason.erase(0, 1); - - if (file.find(".pp") != std::string::npos) - { - file.erase(file.find(".pp"), 3); - } - - if (kState.fLastFile != file) - { - std::cout << kRed << "[ cc ] " << kWhite - << ((file == "cc") ? "internal compiler error " - : ("in file, " + file)) - << kBlank << std::endl; - std::cout << kRed << "[ cc ] " << kWhite << reason << kBlank << std::endl; - - kState.fLastFile = file; - } - else - { - std::cout << kRed << "[ cc ] [ " << kState.fLastFile << " ] " << kWhite - << reason << kBlank << std::endl; - } - - if (kAcceptableErrors > kErrorLimit) - std::exit(3); - - ++kAcceptableErrors; - } + void print_error_asm(std::string reason, std::string file) noexcept; struct CompilerType final { @@ -163,7 +133,7 @@ static std::string kRegisterPrefix = kAsmRegisterPrefix; ///////////////////////////////////////// static std::vector<std::string> kFileList; -static CompilerKit::AssemblyFactory kFactory; +static NDK::AssemblyFactory kFactory; static bool kInStruct = false; static bool kOnWhileLoop = false; static bool kOnForLoop = false; @@ -172,13 +142,13 @@ static bool kIfFound = false; static size_t kBracesCount = 0UL; /* @brief C compiler backend for C */ -class CompilerBackendCLang final : public CompilerKit::CompilerBackend +class CompilerBackend64x0 final : public NDK::CompilerBackend { public: - explicit CompilerBackendCLang() = default; - ~CompilerBackendCLang() override = default; + explicit CompilerBackend64x0() = default; + ~CompilerBackend64x0() override = default; - MPCC_COPY_DEFAULT(CompilerBackendCLang); + MPCC_COPY_DEFAULT(CompilerBackend64x0); std::string Check(const char* text, const char* file); bool Compile(const std::string& text, const char* file) override; @@ -189,7 +159,7 @@ public: } }; -static CompilerBackendCLang* kCompilerBackend = nullptr; +static CompilerBackend64x0* kCompilerBackend = nullptr; static std::vector<detail::CompilerType> kCompilerVariables; static std::vector<std::string> kCompilerFunctions; static std::vector<detail::CompilerType> kCompilerTypes; @@ -231,7 +201,7 @@ namespace detail ///////////////////////////////////////////////////////////////////////////////////////// -bool CompilerBackendCLang::Compile(const std::string& text, const char* file) +bool CompilerBackend64x0::Compile(const std::string& text, const char* file) { std::string textBuffer = text; @@ -249,7 +219,7 @@ bool CompilerBackendCLang::Compile(const std::string& text, const char* file) // start parsing for (size_t text_index = 0; text_index < textBuffer.size(); ++text_index) { - auto syntaxLeaf = CompilerKit::SyntaxLeafList::SyntaxLeaf(); + auto syntaxLeaf = NDK::SyntaxLeafList::SyntaxLeaf(); auto gen = uuids::uuid_random_generator{generator}; uuids::uuid out = gen(); @@ -433,7 +403,7 @@ bool CompilerBackendCLang::Compile(const std::string& text, const char* file) if (textBuffer[text_index] == '=' && kInStruct) { - detail::print_error("assignement of value in struct " + textBuffer, + detail::print_error_asm("assignement of value in struct " + textBuffer, file); continue; } @@ -767,7 +737,7 @@ bool CompilerBackendCLang::Compile(const std::string& text, const char* file) syntaxLeaf.fUserValue.clear(); } - auto syntaxLeaf = CompilerKit::SyntaxLeafList::SyntaxLeaf(); + auto syntaxLeaf = NDK::SyntaxLeafList::SyntaxLeaf(); syntaxLeaf.fUserValue = "\n"; kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf); @@ -777,7 +747,7 @@ bool CompilerBackendCLang::Compile(const std::string& text, const char* file) static bool kShouldHaveBraces = false; static std::string kFnName; -std::string CompilerBackendCLang::Check(const char* text, const char* file) +std::string CompilerBackend64x0::Check(const char* text, const char* file) { std::string err_str; std::string ln = text; @@ -1035,7 +1005,7 @@ cc_next: // extern does not declare anything, it imports a variable. // so that's why it's not declare upper. - if (CompilerKit::find_word(ln, "extern")) + if (NDK::find_word(ln, "extern")) { auto substr = ln.substr(ln.find("extern") + strlen("extern")); kCompilerVariables.push_back({.fValue = substr}); @@ -1106,7 +1076,7 @@ skip_braces_check: for (auto& key : kCompilerTypes) { - if (CompilerKit::find_word(ln, key.fName)) + if (NDK::find_word(ln, key.fName)) { if (isdigit(ln[ln.find(key.fName) + key.fName.size() + 1])) { @@ -1207,9 +1177,9 @@ skip_braces_check: if (ln.find('(') != std::string::npos) { - if (ln.find(';') == std::string::npos && !CompilerKit::find_word(ln, "|") && - !CompilerKit::find_word(ln, "||") && !CompilerKit::find_word(ln, "&") && - !CompilerKit::find_word(ln, "&&") && !CompilerKit::find_word(ln, "~")) + if (ln.find(';') == std::string::npos && !NDK::find_word(ln, "|") && + !NDK::find_word(ln, "||") && !NDK::find_word(ln, "&") && + !NDK::find_word(ln, "&&") && !NDK::find_word(ln, "~")) { bool found_func = false; size_t i = ln.find('('); @@ -1325,7 +1295,7 @@ skip_braces_check: ///////////////////////////////////////////////////////////////////////////////////////// -class AssemblyCCInterface final : public CompilerKit::AssemblyInterface +class AssemblyCCInterface final : public NDK::AssemblyInterface { public: explicit AssemblyCCInterface() = default; @@ -1335,7 +1305,7 @@ public: [[maybe_unused]] static Int32 Arch() noexcept { - return CompilerKit::AssemblyFactory::kArch64x0; + return NDK::AssemblyFactory::kArch64x0; } Int32 CompileToFormat(std::string& src, Int32 arch) override @@ -1367,14 +1337,14 @@ public: kState.fOutputAssembly = std::make_unique<std::ofstream>(dest); - auto fmt = CompilerKit::current_date(); + auto fmt = NDK::current_date(); (*kState.fOutputAssembly) << "# Path: " << src_file << "\n"; (*kState.fOutputAssembly) << "# Language: 64x0 Assembly (Generated from ANSI C)\n"; (*kState.fOutputAssembly) << "# Date: " << fmt << "\n\n"; - CompilerKit::SyntaxLeafList syntax; + NDK::SyntaxLeafList syntax; kState.fSyntaxTreeList.push_back(syntax); kState.fSyntaxTree = @@ -1391,7 +1361,7 @@ public: } else { - detail::print_error(err, src.data()); + detail::print_error_asm(err, src.data()); } } @@ -1411,7 +1381,7 @@ public: for (auto& access_ident : access_keywords) { - if (CompilerKit::find_word(leaf.fUserValue, access_ident)) + if (NDK::find_word(leaf.fUserValue, access_ident)) { for (auto& struc : kState.kStructMap) { @@ -1422,7 +1392,7 @@ public: for (auto& keyword : keywords) { - if (CompilerKit::find_word(leaf.fUserValue, keyword)) + if (NDK::find_word(leaf.fUserValue, keyword)) { std::size_t cnt = 0UL; @@ -1453,7 +1423,7 @@ public: } } - if (CompilerKit::find_word(leaf.fUserValue, needle)) + if (NDK::find_word(leaf.fUserValue, needle)) { if (leaf.fUserValue.find("import " + needle) != std::string::npos) @@ -1536,8 +1506,8 @@ NDK_MODULE(NewOSCompilerCLang64x0) bool skip = false; kFactory.Mount(new AssemblyCCInterface()); - kMachine = CompilerKit::AssemblyFactory::kArch64x0; - kCompilerBackend = new CompilerBackendCLang(); + kMachine = NDK::AssemblyFactory::kArch64x0; + kCompilerBackend = new CompilerBackend64x0(); for (auto index = 1UL; index < argc; ++index) { @@ -1598,7 +1568,7 @@ NDK_MODULE(NewOSCompilerCLang64x0) std::string err = "Unknown command: "; err += argv[index]; - detail::print_error(err, "cc"); + detail::print_error_asm(err, "cc"); continue; } @@ -1611,7 +1581,7 @@ NDK_MODULE(NewOSCompilerCLang64x0) { if (kState.fVerbose) { - detail::print_error(srcFile + " is not a valid C source.\n", "cc"); + detail::print_error_asm(srcFile + " is not a valid C source.\n", "cc"); } return 1; diff --git a/NDKKit/Sources/power-cc.cxx b/NDKKit/Sources/CCompilerPower64.cxx index deddcfd..45bdeaa 100644 --- a/NDKKit/Sources/power-cc.cxx +++ b/NDKKit/Sources/CCompilerPower64.cxx @@ -70,10 +70,10 @@ namespace detail struct CompilerState final { - std::vector<CompilerKit::SyntaxLeafList> fSyntaxTreeList; + std::vector<NDK::SyntaxLeafList> fSyntaxTreeList; std::vector<CompilerRegisterMap> kStackFrame; std::vector<CompilerStructMap> kStructMap; - CompilerKit::SyntaxLeafList* fSyntaxTree{nullptr}; + NDK::SyntaxLeafList* fSyntaxTree{nullptr}; std::unique_ptr<std::ofstream> fOutputAssembly; std::string fLastFile; std::string fLastError; @@ -91,35 +91,7 @@ namespace detail /// @brief prints an error into stdout. /// @param reason the reason of the error. /// @param file where does it originate from? - void print_error(std::string reason, std::string file) noexcept - { - if (reason[0] == '\n') - reason.erase(0, 1); - - if (file.find(".pp") != std::string::npos) - file.erase(file.find(".pp"), 3); - - if (kState.fLastFile != file) - { - std::cout << kRed << "[ cc ] " << kWhite - << ((file == "cc") ? "internal compiler error " - : ("in file, " + file)) - << kBlank << std::endl; - std::cout << kRed << "[ cc ] " << kWhite << reason << kBlank << std::endl; - - kState.fLastFile = file; - } - else - { - std::cout << kRed << "[ cc ] [ " << kState.fLastFile << " ] " << kWhite - << reason << kBlank << std::endl; - } - - if (kAcceptableErrors > kErrorLimit) - std::exit(3); - - ++kAcceptableErrors; - } + void print_error_asm(std::string reason, std::string file) noexcept; struct CompilerType final { @@ -152,7 +124,7 @@ static std::string kRegisterPrefix = kAsmRegisterPrefix; ///////////////////////////////////////// static std::vector<std::string> kFileList; -static CompilerKit::AssemblyFactory kFactory; +static NDK::AssemblyFactory kFactory; static bool kInStruct = false; static bool kOnWhileLoop = false; static bool kOnForLoop = false; @@ -161,13 +133,13 @@ static bool kIfFound = false; static size_t kBracesCount = 0UL; /* @brief C compiler backend for C */ -class CompilerBackendCLang final : public CompilerKit::CompilerBackend +class CompilerBackendPower64 final : public NDK::CompilerBackend { public: - explicit CompilerBackendCLang() = default; - ~CompilerBackendCLang() override = default; + explicit CompilerBackendPower64() = default; + ~CompilerBackendPower64() override = default; - MPCC_COPY_DEFAULT(CompilerBackendCLang); + MPCC_COPY_DEFAULT(CompilerBackendPower64); std::string Check(const char* text, const char* file); bool Compile(const std::string& text, const char* file) override; @@ -178,7 +150,7 @@ public: } }; -static CompilerBackendCLang* kCompilerBackend = nullptr; +static CompilerBackendPower64* kCompilerBackend = nullptr; static std::vector<detail::CompilerType> kCompilerVariables; static std::vector<std::string> kCompilerFunctions; static std::vector<detail::CompilerType> kCompilerTypes; @@ -220,7 +192,7 @@ namespace detail ///////////////////////////////////////////////////////////////////////////////////////// -bool CompilerBackendCLang::Compile(const std::string& text, const char* file) +bool CompilerBackendPower64::Compile(const std::string& text, const char* file) { std::string textBuffer = text; @@ -238,7 +210,7 @@ bool CompilerBackendCLang::Compile(const std::string& text, const char* file) // start parsing for (size_t text_index = 0; text_index < textBuffer.size(); ++text_index) { - auto syntaxLeaf = CompilerKit::SyntaxLeafList::SyntaxLeaf(); + auto syntaxLeaf = NDK::SyntaxLeafList::SyntaxLeaf(); auto gen = uuids::uuid_random_generator{generator}; uuids::uuid out = gen(); @@ -442,7 +414,7 @@ bool CompilerBackendCLang::Compile(const std::string& text, const char* file) if (textBuffer[text_index] == '=' && kInStruct) { - detail::print_error( + detail::print_error_asm( "assignement of value inside a struct " + textBuffer, file); continue; } @@ -788,7 +760,7 @@ bool CompilerBackendCLang::Compile(const std::string& text, const char* file) syntaxLeaf.fUserValue.clear(); } - auto syntaxLeaf = CompilerKit::SyntaxLeafList::SyntaxLeaf(); + auto syntaxLeaf = NDK::SyntaxLeafList::SyntaxLeaf(); syntaxLeaf.fUserValue = "\n"; kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf); @@ -798,7 +770,7 @@ bool CompilerBackendCLang::Compile(const std::string& text, const char* file) static bool kShouldHaveBraces = false; static std::string kFnName; -std::string CompilerBackendCLang::Check(const char* text, const char* file) +std::string CompilerBackendPower64::Check(const char* text, const char* file) { std::string err_str; std::string ln = text; @@ -1056,7 +1028,7 @@ cc_next: // extern does not declare anything, it imports a variable. // so that's why it's not declare upper. - if (CompilerKit::find_word(ln, "extern")) + if (NDK::find_word(ln, "extern")) { auto substr = ln.substr(ln.find("extern") + strlen("extern")); kCompilerVariables.push_back({.fValue = substr}); @@ -1127,7 +1099,7 @@ skip_braces_check: for (auto& key : kCompilerTypes) { - if (CompilerKit::find_word(ln, key.fName)) + if (NDK::find_word(ln, key.fName)) { if (isdigit(ln[ln.find(key.fName) + key.fName.size() + 1])) { @@ -1228,9 +1200,9 @@ skip_braces_check: if (ln.find('(') != std::string::npos) { - if (ln.find(';') == std::string::npos && !CompilerKit::find_word(ln, "|") && - !CompilerKit::find_word(ln, "||") && !CompilerKit::find_word(ln, "&") && - !CompilerKit::find_word(ln, "&&") && !CompilerKit::find_word(ln, "~")) + if (ln.find(';') == std::string::npos && !NDK::find_word(ln, "|") && + !NDK::find_word(ln, "||") && !NDK::find_word(ln, "&") && + !NDK::find_word(ln, "&&") && !NDK::find_word(ln, "~")) { bool found_func = false; size_t i = ln.find('('); @@ -1346,7 +1318,7 @@ skip_braces_check: ///////////////////////////////////////////////////////////////////////////////////////// -class AssemblyMountpointCLang final : public CompilerKit::AssemblyInterface +class AssemblyMountpointCLang final : public NDK::AssemblyInterface { public: explicit AssemblyMountpointCLang() = default; @@ -1356,7 +1328,7 @@ public: [[maybe_unused]] static Int32 Arch() noexcept { - return CompilerKit::AssemblyFactory::kArchPowerPC; + return NDK::AssemblyFactory::kArchPowerPC; } Int32 CompileToFormat(std::string& src, Int32 arch) override @@ -1388,14 +1360,14 @@ public: kState.fOutputAssembly = std::make_unique<std::ofstream>(dest); - auto fmt = CompilerKit::current_date(); + auto fmt = NDK::current_date(); (*kState.fOutputAssembly) << "# Path: " << src_file << "\n"; (*kState.fOutputAssembly) << "# Language: POWER Assembly (Generated from C)\n"; (*kState.fOutputAssembly) << "# Date: " << fmt << "\n\n"; - CompilerKit::SyntaxLeafList syntax; + NDK::SyntaxLeafList syntax; kState.fSyntaxTreeList.push_back(syntax); kState.fSyntaxTree = @@ -1412,7 +1384,7 @@ public: } else { - detail::print_error(err, src.data()); + detail::print_error_asm(err, src.data()); } } @@ -1431,7 +1403,7 @@ public: for (auto& access_ident : access_keywords) { - if (CompilerKit::find_word(leaf.fUserValue, access_ident)) + if (NDK::find_word(leaf.fUserValue, access_ident)) { for (auto& struc : kState.kStructMap) { @@ -1442,7 +1414,7 @@ public: for (auto& keyword : keywords) { - if (CompilerKit::find_word(leaf.fUserValue, keyword)) + if (NDK::find_word(leaf.fUserValue, keyword)) { std::size_t cnt = 0UL; @@ -1473,7 +1445,7 @@ public: } } - if (CompilerKit::find_word(leaf.fUserValue, needle)) + if (NDK::find_word(leaf.fUserValue, needle)) { if (leaf.fUserValue.find("import ") != std::string::npos) { @@ -1554,8 +1526,8 @@ NDK_MODULE(NewOSCompilerCLangPowerPC) bool skip = false; kFactory.Mount(new AssemblyMountpointCLang()); - kMachine = CompilerKit::AssemblyFactory::kArchPowerPC; - kCompilerBackend = new CompilerBackendCLang(); + kMachine = NDK::AssemblyFactory::kArchPowerPC; + kCompilerBackend = new CompilerBackendPower64(); for (auto index = 1UL; index < argc; ++index) { @@ -1616,7 +1588,7 @@ NDK_MODULE(NewOSCompilerCLangPowerPC) std::string err = "Unknown command: "; err += argv[index]; - detail::print_error(err, "cc"); + detail::print_error_asm(err, "cc"); continue; } @@ -1629,7 +1601,7 @@ NDK_MODULE(NewOSCompilerCLangPowerPC) { if (kState.fVerbose) { - detail::print_error(srcFile + " is not a valid C source.\n", "cc"); + detail::print_error_asm(srcFile + " is not a valid C source.\n", "cc"); } return 1; diff --git a/NDKKit/Sources/cplusplus.cxx b/NDKKit/Sources/CPlusPlusCompilerAMD64.cxx index 6bb59f5..5036297 100644 --- a/NDKKit/Sources/cplusplus.cxx +++ b/NDKKit/Sources/CPlusPlusCompilerAMD64.cxx @@ -83,10 +83,10 @@ namespace detail struct CompilerState final { - std::vector<CompilerKit::SyntaxLeafList> fSyntaxTreeList; + std::vector<NDK::SyntaxLeafList> fSyntaxTreeList; std::vector<CompilerRegisterMap> kStackFrame; std::vector<CompilerStructMap> kStructMap; - CompilerKit::SyntaxLeafList* fSyntaxTree{nullptr}; + NDK::SyntaxLeafList* fSyntaxTree{nullptr}; std::unique_ptr<std::ofstream> fOutputAssembly; std::string fLastFile; std::string fLastError; @@ -104,39 +104,8 @@ namespace detail /// @brief prints an error into stdout. /// @param reason the reason of the error. /// @param file where does it originate from? - void print_error(std::string reason, std::string file) noexcept - { - if (reason[0] == '\n') - reason.erase(0, 1); - - if (file.find(".pp") != std::string::npos) - { - file.erase(file.find(".pp"), 3); - } - - if (kState.fLastFile != file) - { - std::cout << kRed << "[ cplusplus ] " << kWhite - << ((file == "cplusplus") ? "internal compiler error " - : ("in file, " + file)) - << kBlank << std::endl; - std::cout << kRed << "[ cplusplus ] " << kWhite << reason << kBlank - << std::endl; - - kState.fLastFile = file; - } - else - { - std::cout << kRed << "[ cplusplus ] [ " << kState.fLastFile << " ] " << kWhite - << reason << kBlank << std::endl; - } - - if (kAcceptableErrors > kErrorLimit) - std::exit(3); - - ++kAcceptableErrors; - } - + void print_error_asm(std::string reason, std::string file) noexcept; + struct CompilerType { std::string fName; @@ -147,7 +116,7 @@ namespace detail ///////////////////////////////////////////////////////////////////////////////////////// // Target architecture. -static int kMachine = CompilerKit::AssemblyFactory::kArchAMD64; +static int kMachine = NDK::AssemblyFactory::kArchAMD64; ///////////////////////////////////////// @@ -159,7 +128,7 @@ static size_t kRegisterCnt = kAsmRegisterLimit; static size_t kStartUsable = 8; static size_t kUsableLimit = 15; static size_t kRegisterCounter = kStartUsable; -static std::vector<CompilerKit::CompilerKeyword> kKeywords; +static std::vector<NDK::CompilerKeyword> kKeywords; ///////////////////////////////////////// @@ -168,7 +137,7 @@ static std::vector<CompilerKit::CompilerKeyword> kKeywords; ///////////////////////////////////////// static std::vector<std::string> kFileList; -static CompilerKit::AssemblyFactory kFactory; +static NDK::AssemblyFactory kFactory; static bool kInStruct = false; static bool kOnWhileLoop = false; static bool kOnForLoop = false; @@ -176,7 +145,7 @@ static bool kInBraces = false; static size_t kBracesCount = 0UL; /* @brief C++ compiler backend for the ZKA C++ driver */ -class CompilerBackendCPlusPlus final : public CompilerKit::CompilerBackend +class CompilerBackendCPlusPlus final : public NDK::CompilerBackend { public: explicit CompilerBackendCPlusPlus() = default; @@ -252,7 +221,7 @@ bool CompilerBackendCPlusPlus::Compile(const std::string& text, // expr; std::size_t index = 0UL; - std::vector<std::pair<CompilerKit::CompilerKeyword, std::size_t>> keywords_list; + std::vector<std::pair<NDK::CompilerKeyword, std::size_t>> keywords_list; bool found = false; static bool commentBlock = false; @@ -263,15 +232,15 @@ bool CompilerBackendCPlusPlus::Compile(const std::string& text, { switch (keyword.keyword_kind) { - case CompilerKit::eKeywordKindCommentMultiLineStart: { + case NDK::eKeywordKindCommentMultiLineStart: { commentBlock = true; return true; } - case CompilerKit::eKeywordKindCommentMultiLineEnd: { + case NDK::eKeywordKindCommentMultiLineEnd: { commentBlock = false; break; } - case CompilerKit::eKeywordKindCommentInline: { + case NDK::eKeywordKindCommentInline: { break; } default: @@ -279,15 +248,15 @@ bool CompilerBackendCPlusPlus::Compile(const std::string& text, } if (text[text.find(keyword.keyword_name) - 1] == '+' && - keyword.keyword_kind == CompilerKit::KeywordKind::eKeywordKindVariableAssign) + keyword.keyword_kind == NDK::KeywordKind::eKeywordKindVariableAssign) continue; if (text[text.find(keyword.keyword_name) - 1] == '-' && - keyword.keyword_kind == CompilerKit::KeywordKind::eKeywordKindVariableAssign) + keyword.keyword_kind == NDK::KeywordKind::eKeywordKindVariableAssign) continue; if (text[text.find(keyword.keyword_name) + 1] == '=' && - keyword.keyword_kind == CompilerKit::KeywordKind::eKeywordKindVariableAssign) + keyword.keyword_kind == NDK::KeywordKind::eKeywordKindVariableAssign) continue; keywords_list.emplace_back(std::make_pair(keyword, index)); @@ -303,7 +272,7 @@ bool CompilerBackendCPlusPlus::Compile(const std::string& text, { if (isalnum(text[i])) { - detail::print_error("syntax error: " + text, file); + detail::print_error_asm("syntax error: " + text, file); return false; } } @@ -311,11 +280,11 @@ bool CompilerBackendCPlusPlus::Compile(const std::string& text, for (auto& keyword : keywords_list) { - auto syntax_tree = CompilerKit::SyntaxLeafList::SyntaxLeaf(); + auto syntax_tree = NDK::SyntaxLeafList::SyntaxLeaf(); switch (keyword.first.keyword_kind) { - case CompilerKit::KeywordKind::eKeywordKindIf: { + case NDK::KeywordKind::eKeywordKindIf: { auto expr = text.substr(text.find(keyword.first.keyword_name) + keyword.first.keyword_name.size() + 1, text.find(")") - 1); if (expr.find(">=") != std::string::npos) @@ -407,7 +376,7 @@ bool CompilerBackendCPlusPlus::Compile(const std::string& text, break; } - case CompilerKit::KeywordKind::eKeywordKindFunctionStart: { + case NDK::KeywordKind::eKeywordKindFunctionStart: { if (text.ends_with(";")) { break; @@ -439,7 +408,7 @@ bool CompilerBackendCPlusPlus::Compile(const std::string& text, ++kLevelFunction; } - case CompilerKit::KeywordKind::eKeywordKindFunctionEnd: { + case NDK::KeywordKind::eKeywordKindFunctionEnd: { if (text.ends_with(";")) break; @@ -454,50 +423,50 @@ bool CompilerBackendCPlusPlus::Compile(const std::string& text, kRegisterMap.clear(); break; } - case CompilerKit::KeywordKind::eKeywordKindEndInstr: - case CompilerKit::KeywordKind::eKeywordKindVariableInc: - case CompilerKit::KeywordKind::eKeywordKindVariableDec: - case CompilerKit::KeywordKind::eKeywordKindVariableAssign: { + case NDK::KeywordKind::eKeywordKindEndInstr: + case NDK::KeywordKind::eKeywordKindVariableInc: + case NDK::KeywordKind::eKeywordKindVariableDec: + case NDK::KeywordKind::eKeywordKindVariableAssign: { std::string valueOfVar = ""; - if (keyword.first.keyword_kind == CompilerKit::KeywordKind::eKeywordKindVariableInc) + if (keyword.first.keyword_kind == NDK::KeywordKind::eKeywordKindVariableInc) { valueOfVar = text.substr(text.find("+=") + 2); } - else if (keyword.first.keyword_kind == CompilerKit::KeywordKind::eKeywordKindVariableDec) + else if (keyword.first.keyword_kind == NDK::KeywordKind::eKeywordKindVariableDec) { valueOfVar = text.substr(text.find("-=") + 2); } - else if (keyword.first.keyword_kind == CompilerKit::KeywordKind::eKeywordKindVariableAssign) + else if (keyword.first.keyword_kind == NDK::KeywordKind::eKeywordKindVariableAssign) { valueOfVar = text.substr(text.find("=") + 1); } - else if (keyword.first.keyword_kind == CompilerKit::KeywordKind::eKeywordKindEndInstr) + else if (keyword.first.keyword_kind == NDK::KeywordKind::eKeywordKindEndInstr) { break; } while (valueOfVar.find(";") != std::string::npos && - keyword.first.keyword_kind != CompilerKit::KeywordKind::eKeywordKindEndInstr) + keyword.first.keyword_kind != NDK::KeywordKind::eKeywordKindEndInstr) { valueOfVar.erase(valueOfVar.find(";")); } std::string varName = text; - if (keyword.first.keyword_kind == CompilerKit::KeywordKind::eKeywordKindVariableInc) + if (keyword.first.keyword_kind == NDK::KeywordKind::eKeywordKindVariableInc) { varName.erase(varName.find("+=")); } - else if (keyword.first.keyword_kind == CompilerKit::KeywordKind::eKeywordKindVariableDec) + else if (keyword.first.keyword_kind == NDK::KeywordKind::eKeywordKindVariableDec) { varName.erase(varName.find("-=")); } - else if (keyword.first.keyword_kind == CompilerKit::KeywordKind::eKeywordKindVariableAssign) + else if (keyword.first.keyword_kind == NDK::KeywordKind::eKeywordKindVariableAssign) { varName.erase(varName.find("=")); } - else if (keyword.first.keyword_kind == CompilerKit::KeywordKind::eKeywordKindEndInstr) + else if (keyword.first.keyword_kind == NDK::KeywordKind::eKeywordKindEndInstr) { varName.erase(varName.find(";")); } @@ -506,7 +475,7 @@ bool CompilerBackendCPlusPlus::Compile(const std::string& text, for (auto& keyword : kKeywords) { - if (keyword.keyword_kind == CompilerKit::eKeywordKindType) + if (keyword.keyword_kind == NDK::eKeywordKindType) { if (text.find(keyword.keyword_name) != std::string::npos) { @@ -525,13 +494,13 @@ bool CompilerBackendCPlusPlus::Compile(const std::string& text, if (typeFound) { - if (keyword.first.keyword_kind == CompilerKit::KeywordKind::eKeywordKindVariableInc) + if (keyword.first.keyword_kind == NDK::KeywordKind::eKeywordKindVariableInc) { - detail::print_error("Can't increment variable when it's being created.", file); + detail::print_error_asm("Can't increment variable when it's being created.", file); } - else if (keyword.first.keyword_kind == CompilerKit::KeywordKind::eKeywordKindVariableDec) + else if (keyword.first.keyword_kind == NDK::KeywordKind::eKeywordKindVariableDec) { - detail::print_error("Can't decrement variable when it's being created.", file); + detail::print_error_asm("Can't decrement variable when it's being created.", file); } if (kRegisterMap.size() > cRegisters.size()) @@ -595,24 +564,24 @@ bool CompilerBackendCPlusPlus::Compile(const std::string& text, } else { - if (kKeywords[keyword.second - 1].keyword_kind == CompilerKit::eKeywordKindType || - kKeywords[keyword.second - 1].keyword_kind == CompilerKit::eKeywordKindTypePtr) + if (kKeywords[keyword.second - 1].keyword_kind == NDK::eKeywordKindType || + kKeywords[keyword.second - 1].keyword_kind == NDK::eKeywordKindTypePtr) { syntax_tree.fUserValue = "\n"; continue; } - if (keyword.first.keyword_kind == CompilerKit::KeywordKind::eKeywordKindEndInstr) + if (keyword.first.keyword_kind == NDK::KeywordKind::eKeywordKindEndInstr) { syntax_tree.fUserValue = "\n"; continue; } - if (keyword.first.keyword_kind == CompilerKit::KeywordKind::eKeywordKindVariableInc) + if (keyword.first.keyword_kind == NDK::KeywordKind::eKeywordKindVariableInc) { instr = "add "; } - else if (keyword.first.keyword_kind == CompilerKit::KeywordKind::eKeywordKindVariableDec) + else if (keyword.first.keyword_kind == NDK::KeywordKind::eKeywordKindVariableDec) { instr = "sub "; } @@ -691,13 +660,13 @@ bool CompilerBackendCPlusPlus::Compile(const std::string& text, if (syntax_tree.fUserValue.empty()) { - detail::print_error("Variable not declared: " + varErrCpy, file); + detail::print_error_asm("Variable not declared: " + varErrCpy, file); } } break; } - case CompilerKit::KeywordKind::eKeywordKindReturn: { + case NDK::KeywordKind::eKeywordKindReturn: { auto pos = text.find("return") + strlen("return") + 1; std::string subText = text.substr(pos); subText = subText.erase(subText.find(";")); @@ -721,7 +690,7 @@ bool CompilerBackendCPlusPlus::Compile(const std::string& text, if (syntax_tree.fUserValue.empty()) { - detail::print_error("Variable not declared: " + subText, file); + detail::print_error_asm("Variable not declared: " + subText, file); } } else @@ -757,7 +726,7 @@ _MpccOkay: ///////////////////////////////////////////////////////////////////////////////////////// -class AssemblyCPlusPlusInterface final : public CompilerKit::AssemblyInterface +class AssemblyCPlusPlusInterface final : public NDK::AssemblyInterface { public: explicit AssemblyCPlusPlusInterface() = default; @@ -768,7 +737,7 @@ public: [[maybe_unused]] static Int32 Arch() noexcept { - return CompilerKit::AssemblyFactory::kArchAMD64; + return NDK::AssemblyFactory::kArchAMD64; } Int32 CompileToFormat(std::string& src, Int32 arch) override @@ -808,7 +777,7 @@ public: kState.fOutputAssembly = std::make_unique<std::ofstream>(dest); - auto fmt = CompilerKit::current_date(); + auto fmt = NDK::current_date(); (*kState.fOutputAssembly) << "; Path: " << src_file << "\n"; (*kState.fOutputAssembly) @@ -817,7 +786,7 @@ public: (*kState.fOutputAssembly) << "#bits 64\n#org 0x1000000" << "\n"; - CompilerKit::SyntaxLeafList syntax; + NDK::SyntaxLeafList syntax; kState.fSyntaxTreeList.emplace_back(syntax); kState.fSyntaxTree = @@ -859,67 +828,67 @@ static void cxx_print_help() ".cpp", ".cxx", ".cc", ".c++", ".cp" \ } -NDK_MODULE(CompilerCPlusPlus) +NDK_MODULE(CompilerCPlusPlusX8664) { bool skip = false; - kKeywords.push_back({.keyword_name = "if", .keyword_kind = CompilerKit::eKeywordKindIf}); - kKeywords.push_back({.keyword_name = "else", .keyword_kind = CompilerKit::eKeywordKindElse}); - kKeywords.push_back({.keyword_name = "else if", .keyword_kind = CompilerKit::eKeywordKindElseIf}); - - kKeywords.push_back({.keyword_name = "class", .keyword_kind = CompilerKit::eKeywordKindClass}); - kKeywords.push_back({.keyword_name = "struct", .keyword_kind = CompilerKit::eKeywordKindClass}); - kKeywords.push_back({.keyword_name = "namespace", .keyword_kind = CompilerKit::eKeywordKindNamespace}); - kKeywords.push_back({.keyword_name = "typedef", .keyword_kind = CompilerKit::eKeywordKindTypedef}); - kKeywords.push_back({.keyword_name = "using", .keyword_kind = CompilerKit::eKeywordKindTypedef}); - kKeywords.push_back({.keyword_name = "{", .keyword_kind = CompilerKit::eKeywordKindBodyStart}); - kKeywords.push_back({.keyword_name = "}", .keyword_kind = CompilerKit::eKeywordKindBodyEnd}); - kKeywords.push_back({.keyword_name = "auto", .keyword_kind = CompilerKit::eKeywordKindVariable}); - kKeywords.push_back({.keyword_name = "int", .keyword_kind = CompilerKit::eKeywordKindType}); - kKeywords.push_back({.keyword_name = "bool", .keyword_kind = CompilerKit::eKeywordKindType}); - kKeywords.push_back({.keyword_name = "unsigned", .keyword_kind = CompilerKit::eKeywordKindType}); - kKeywords.push_back({.keyword_name = "short", .keyword_kind = CompilerKit::eKeywordKindType}); - kKeywords.push_back({.keyword_name = "char", .keyword_kind = CompilerKit::eKeywordKindType}); - kKeywords.push_back({.keyword_name = "long", .keyword_kind = CompilerKit::eKeywordKindType}); - kKeywords.push_back({.keyword_name = "float", .keyword_kind = CompilerKit::eKeywordKindType}); - kKeywords.push_back({.keyword_name = "double", .keyword_kind = CompilerKit::eKeywordKindType}); - kKeywords.push_back({.keyword_name = "void", .keyword_kind = CompilerKit::eKeywordKindType}); - - kKeywords.push_back({.keyword_name = "auto*", .keyword_kind = CompilerKit::eKeywordKindVariablePtr}); - kKeywords.push_back({.keyword_name = "int*", .keyword_kind = CompilerKit::eKeywordKindTypePtr}); - kKeywords.push_back({.keyword_name = "bool*", .keyword_kind = CompilerKit::eKeywordKindTypePtr}); - kKeywords.push_back({.keyword_name = "unsigned*", .keyword_kind = CompilerKit::eKeywordKindTypePtr}); - kKeywords.push_back({.keyword_name = "short*", .keyword_kind = CompilerKit::eKeywordKindTypePtr}); - kKeywords.push_back({.keyword_name = "char*", .keyword_kind = CompilerKit::eKeywordKindTypePtr}); - kKeywords.push_back({.keyword_name = "long*", .keyword_kind = CompilerKit::eKeywordKindTypePtr}); - kKeywords.push_back({.keyword_name = "float*", .keyword_kind = CompilerKit::eKeywordKindTypePtr}); - kKeywords.push_back({.keyword_name = "double*", .keyword_kind = CompilerKit::eKeywordKindTypePtr}); - kKeywords.push_back({.keyword_name = "void*", .keyword_kind = CompilerKit::eKeywordKindTypePtr}); - - kKeywords.push_back({.keyword_name = "(", .keyword_kind = CompilerKit::eKeywordKindFunctionStart}); - kKeywords.push_back({.keyword_name = ")", .keyword_kind = CompilerKit::eKeywordKindFunctionEnd}); - kKeywords.push_back({.keyword_name = "=", .keyword_kind = CompilerKit::eKeywordKindVariableAssign}); - kKeywords.push_back({.keyword_name = "+=", .keyword_kind = CompilerKit::eKeywordKindVariableInc}); - kKeywords.push_back({.keyword_name = "-=", .keyword_kind = CompilerKit::eKeywordKindVariableDec}); - kKeywords.push_back({.keyword_name = "const", .keyword_kind = CompilerKit::eKeywordKindConstant}); - kKeywords.push_back({.keyword_name = "*", .keyword_kind = CompilerKit::eKeywordKindPtr}); - kKeywords.push_back({.keyword_name = "->", .keyword_kind = CompilerKit::eKeywordKindPtrAccess}); - kKeywords.push_back({.keyword_name = ".", .keyword_kind = CompilerKit::eKeywordKindAccess}); - kKeywords.push_back({.keyword_name = ",", .keyword_kind = CompilerKit::eKeywordKindArgSeparator}); - kKeywords.push_back({.keyword_name = ";", .keyword_kind = CompilerKit::eKeywordKindEndInstr}); - kKeywords.push_back({.keyword_name = ":", .keyword_kind = CompilerKit::eKeywordKindSpecifier}); - kKeywords.push_back({.keyword_name = "public:", .keyword_kind = CompilerKit::eKeywordKindSpecifier}); - kKeywords.push_back({.keyword_name = "private:", .keyword_kind = CompilerKit::eKeywordKindSpecifier}); - kKeywords.push_back({.keyword_name = "protected:", .keyword_kind = CompilerKit::eKeywordKindSpecifier}); - kKeywords.push_back({.keyword_name = "final", .keyword_kind = CompilerKit::eKeywordKindSpecifier}); - kKeywords.push_back({.keyword_name = "return", .keyword_kind = CompilerKit::eKeywordKindReturn}); - kKeywords.push_back({.keyword_name = "/*", .keyword_kind = CompilerKit::eKeywordKindCommentMultiLineStart}); - kKeywords.push_back({.keyword_name = "*/", .keyword_kind = CompilerKit::eKeywordKindCommentMultiLineStart}); - kKeywords.push_back({.keyword_name = "//", .keyword_kind = CompilerKit::eKeywordKindCommentInline}); - kKeywords.push_back({.keyword_name = "==", .keyword_kind = CompilerKit::eKeywordKindEq}); - kKeywords.push_back({.keyword_name = "!=", .keyword_kind = CompilerKit::eKeywordKindNotEq}); - kKeywords.push_back({.keyword_name = ">=", .keyword_kind = CompilerKit::eKeywordKindGreaterEq}); - kKeywords.push_back({.keyword_name = "<=", .keyword_kind = CompilerKit::eKeywordKindLessEq}); + kKeywords.push_back({.keyword_name = "if", .keyword_kind = NDK::eKeywordKindIf}); + kKeywords.push_back({.keyword_name = "else", .keyword_kind = NDK::eKeywordKindElse}); + kKeywords.push_back({.keyword_name = "else if", .keyword_kind = NDK::eKeywordKindElseIf}); + + kKeywords.push_back({.keyword_name = "class", .keyword_kind = NDK::eKeywordKindClass}); + kKeywords.push_back({.keyword_name = "struct", .keyword_kind = NDK::eKeywordKindClass}); + kKeywords.push_back({.keyword_name = "namespace", .keyword_kind = NDK::eKeywordKindNamespace}); + kKeywords.push_back({.keyword_name = "typedef", .keyword_kind = NDK::eKeywordKindTypedef}); + kKeywords.push_back({.keyword_name = "using", .keyword_kind = NDK::eKeywordKindTypedef}); + kKeywords.push_back({.keyword_name = "{", .keyword_kind = NDK::eKeywordKindBodyStart}); + kKeywords.push_back({.keyword_name = "}", .keyword_kind = NDK::eKeywordKindBodyEnd}); + kKeywords.push_back({.keyword_name = "auto", .keyword_kind = NDK::eKeywordKindVariable}); + kKeywords.push_back({.keyword_name = "int", .keyword_kind = NDK::eKeywordKindType}); + kKeywords.push_back({.keyword_name = "bool", .keyword_kind = NDK::eKeywordKindType}); + kKeywords.push_back({.keyword_name = "unsigned", .keyword_kind = NDK::eKeywordKindType}); + kKeywords.push_back({.keyword_name = "short", .keyword_kind = NDK::eKeywordKindType}); + kKeywords.push_back({.keyword_name = "char", .keyword_kind = NDK::eKeywordKindType}); + kKeywords.push_back({.keyword_name = "long", .keyword_kind = NDK::eKeywordKindType}); + kKeywords.push_back({.keyword_name = "float", .keyword_kind = NDK::eKeywordKindType}); + kKeywords.push_back({.keyword_name = "double", .keyword_kind = NDK::eKeywordKindType}); + kKeywords.push_back({.keyword_name = "void", .keyword_kind = NDK::eKeywordKindType}); + + kKeywords.push_back({.keyword_name = "auto*", .keyword_kind = NDK::eKeywordKindVariablePtr}); + kKeywords.push_back({.keyword_name = "int*", .keyword_kind = NDK::eKeywordKindTypePtr}); + kKeywords.push_back({.keyword_name = "bool*", .keyword_kind = NDK::eKeywordKindTypePtr}); + kKeywords.push_back({.keyword_name = "unsigned*", .keyword_kind = NDK::eKeywordKindTypePtr}); + kKeywords.push_back({.keyword_name = "short*", .keyword_kind = NDK::eKeywordKindTypePtr}); + kKeywords.push_back({.keyword_name = "char*", .keyword_kind = NDK::eKeywordKindTypePtr}); + kKeywords.push_back({.keyword_name = "long*", .keyword_kind = NDK::eKeywordKindTypePtr}); + kKeywords.push_back({.keyword_name = "float*", .keyword_kind = NDK::eKeywordKindTypePtr}); + kKeywords.push_back({.keyword_name = "double*", .keyword_kind = NDK::eKeywordKindTypePtr}); + kKeywords.push_back({.keyword_name = "void*", .keyword_kind = NDK::eKeywordKindTypePtr}); + + kKeywords.push_back({.keyword_name = "(", .keyword_kind = NDK::eKeywordKindFunctionStart}); + kKeywords.push_back({.keyword_name = ")", .keyword_kind = NDK::eKeywordKindFunctionEnd}); + kKeywords.push_back({.keyword_name = "=", .keyword_kind = NDK::eKeywordKindVariableAssign}); + kKeywords.push_back({.keyword_name = "+=", .keyword_kind = NDK::eKeywordKindVariableInc}); + kKeywords.push_back({.keyword_name = "-=", .keyword_kind = NDK::eKeywordKindVariableDec}); + kKeywords.push_back({.keyword_name = "const", .keyword_kind = NDK::eKeywordKindConstant}); + kKeywords.push_back({.keyword_name = "*", .keyword_kind = NDK::eKeywordKindPtr}); + kKeywords.push_back({.keyword_name = "->", .keyword_kind = NDK::eKeywordKindPtrAccess}); + kKeywords.push_back({.keyword_name = ".", .keyword_kind = NDK::eKeywordKindAccess}); + kKeywords.push_back({.keyword_name = ",", .keyword_kind = NDK::eKeywordKindArgSeparator}); + kKeywords.push_back({.keyword_name = ";", .keyword_kind = NDK::eKeywordKindEndInstr}); + kKeywords.push_back({.keyword_name = ":", .keyword_kind = NDK::eKeywordKindSpecifier}); + kKeywords.push_back({.keyword_name = "public:", .keyword_kind = NDK::eKeywordKindSpecifier}); + kKeywords.push_back({.keyword_name = "private:", .keyword_kind = NDK::eKeywordKindSpecifier}); + kKeywords.push_back({.keyword_name = "protected:", .keyword_kind = NDK::eKeywordKindSpecifier}); + kKeywords.push_back({.keyword_name = "final", .keyword_kind = NDK::eKeywordKindSpecifier}); + kKeywords.push_back({.keyword_name = "return", .keyword_kind = NDK::eKeywordKindReturn}); + kKeywords.push_back({.keyword_name = "/*", .keyword_kind = NDK::eKeywordKindCommentMultiLineStart}); + kKeywords.push_back({.keyword_name = "*/", .keyword_kind = NDK::eKeywordKindCommentMultiLineStart}); + kKeywords.push_back({.keyword_name = "//", .keyword_kind = NDK::eKeywordKindCommentInline}); + kKeywords.push_back({.keyword_name = "==", .keyword_kind = NDK::eKeywordKindEq}); + kKeywords.push_back({.keyword_name = "!=", .keyword_kind = NDK::eKeywordKindNotEq}); + kKeywords.push_back({.keyword_name = ">=", .keyword_kind = NDK::eKeywordKindGreaterEq}); + kKeywords.push_back({.keyword_name = "<=", .keyword_kind = NDK::eKeywordKindLessEq}); kFactory.Mount(new AssemblyCPlusPlusInterface()); kCompilerBackend = new CompilerBackendCPlusPlus(); @@ -983,7 +952,7 @@ NDK_MODULE(CompilerCPlusPlus) std::string err = "Unknown option: "; err += argv[index]; - detail::print_error(err, "cplusplus"); + detail::print_error_asm(err, "cplusplus"); continue; } @@ -1008,7 +977,7 @@ NDK_MODULE(CompilerCPlusPlus) { if (kState.fVerbose) { - detail::print_error(argv_i + " is not a valid C++ source.\n", "cplusplus"); + detail::print_error_asm(argv_i + " is not a valid C++ source.\n", "cplusplus"); } return 1; diff --git a/NDKKit/Sources/Detail/asmutils.hxx b/NDKKit/Sources/Detail/asmutils.hxx index d65c991..d0a5221 100644 --- a/NDKKit/Sources/Detail/asmutils.hxx +++ b/NDKKit/Sources/Detail/asmutils.hxx @@ -9,7 +9,13 @@ #include <NDKKit/AsmKit/AsmKit.hxx> #include <NDKKit/Parser.hxx> -using namespace CompilerKit; +using namespace NDK; + +namespace detail +{ + extern void print_error_asm(std::string reason, std::string file) noexcept; + extern void print_warning_asm(std::string reason, std::string file) noexcept; +} // namespace detail /// @brief Get Number from lineBuffer. /// @param lineBuffer the lineBuffer to fetch from. @@ -32,7 +38,7 @@ static NumberCast32 GetNumber32(std::string lineBuffer, std::string numberKey) { if (errno != 0) { - detail::print_error("invalid hex number: " + lineBuffer, "asm"); + detail::print_error_asm("invalid hex number: " + lineBuffer, "asm"); throw std::runtime_error("invalid_hex"); } } @@ -52,7 +58,7 @@ static NumberCast32 GetNumber32(std::string lineBuffer, std::string numberKey) { if (errno != 0) { - detail::print_error("invalid binary number:" + lineBuffer, "asm"); + detail::print_error_asm("invalid binary number:" + lineBuffer, "asm"); throw std::runtime_error("invalid_bin"); } } @@ -72,7 +78,7 @@ static NumberCast32 GetNumber32(std::string lineBuffer, std::string numberKey) { if (errno != 0) { - detail::print_error("invalid octal number: " + lineBuffer, "asm"); + detail::print_error_asm("invalid octal number: " + lineBuffer, "asm"); throw std::runtime_error("invalid_octal"); } } @@ -92,7 +98,7 @@ static NumberCast32 GetNumber32(std::string lineBuffer, std::string numberKey) { if (errno != 0) { - detail::print_error("invalid hex number: " + lineBuffer, "asm"); + detail::print_error_asm("invalid hex number: " + lineBuffer, "asm"); throw std::runtime_error("invalid_hex"); } } diff --git a/NDKKit/Sources/link.cxx b/NDKKit/Sources/Linker.cxx index db28a32..579672c 100644 --- a/NDKKit/Sources/link.cxx +++ b/NDKKit/Sources/Linker.cxx @@ -60,7 +60,7 @@ enum static std::string kOutput = ""; static Int32 kAbi = eABINewOS; static Int32 kSubArch = kPefNoSubCpu; -static Int32 kArch = CompilerKit::kPefArchInvalid; +static Int32 kArch = NDK::kPefArchInvalid; static Bool kFatBinaryEnable = false; static Bool kStartFound = false; static Bool kDuplicateSymbols = false; @@ -118,31 +118,31 @@ NDK_MODULE(NewOSLinker) } else if (StringCompare(argv[i], "/64x0") == 0) { - kArch = CompilerKit::kPefArch64000; + kArch = NDK::kPefArch64000; continue; } else if (StringCompare(argv[i], "/amd64") == 0) { - kArch = CompilerKit::kPefArchAMD64; + kArch = NDK::kPefArchAMD64; continue; } else if (StringCompare(argv[i], "/32x0") == 0) { - kArch = CompilerKit::kPefArch32000; + kArch = NDK::kPefArch32000; continue; } else if (StringCompare(argv[i], "/power64") == 0) { - kArch = CompilerKit::kPefArchPowerPC; + kArch = NDK::kPefArchPowerPC; continue; } else if (StringCompare(argv[i], "/arm64") == 0) { - kArch = CompilerKit::kPefArchARM64; + kArch = NDK::kPefArchARM64; continue; } @@ -225,12 +225,12 @@ NDK_MODULE(NewOSLinker) return MPCC_EXEC_ERROR; } - CompilerKit::PEFContainer pef_container{}; + NDK::PEFContainer pef_container{}; int32_t archs = kArch; pef_container.Count = 0UL; - pef_container.Kind = CompilerKit::kPefKindExec; + pef_container.Kind = NDK::kPefKindExec; pef_container.SubCpu = kSubArch; pef_container.Linker = kLinkerId; // ZKA Technologies Linker pef_container.Abi = kAbi; // Multi-Processor UX ABI @@ -242,7 +242,7 @@ NDK_MODULE(NewOSLinker) // specify the start address, can be 0x10000 pef_container.Start = kLinkerDefaultOrigin; - pef_container.HdrSz = sizeof(CompilerKit::PEFContainer); + pef_container.HdrSz = sizeof(NDK::PEFContainer); std::ofstream outputFc(kOutput, std::ofstream::binary); @@ -258,15 +258,15 @@ NDK_MODULE(NewOSLinker) //! Read AE to convert as PEF. - std::vector<CompilerKit::PEFCommandHeader> commandHdrsList; - CompilerKit::Utils::AEReadableProtocol readProto{}; + std::vector<NDK::PEFCommandHeader> commandHdrsList; + NDK::Utils::AEReadableProtocol readProto{}; for (const auto& i : kObjectList) { if (!std::filesystem::exists(i)) continue; - CompilerKit::AEHeader hdr{}; + NDK::AEHeader hdr{}; readProto.FP = std::ifstream(i, std::ifstream::binary); readProto.FP >> hdr; @@ -274,7 +274,7 @@ NDK_MODULE(NewOSLinker) auto ae_header = hdr; if (ae_header.fMagic[0] == kAEMag0 && ae_header.fMagic[1] == kAEMag1 && - ae_header.fSize == sizeof(CompilerKit::AEHeader)) + ae_header.fSize == sizeof(NDK::AEHeader)) { if (ae_header.fArch != kArch) { @@ -313,14 +313,14 @@ NDK_MODULE(NewOSLinker) pef_container.Count = cnt; char_type* raw_ae_records = - new char_type[cnt * sizeof(CompilerKit::AERecordHeader)]; - memset(raw_ae_records, 0, cnt * sizeof(CompilerKit::AERecordHeader)); + new char_type[cnt * sizeof(NDK::AERecordHeader)]; + memset(raw_ae_records, 0, cnt * sizeof(NDK::AERecordHeader)); auto* ae_records = readProto.Read(raw_ae_records, cnt); for (size_t ae_record_index = 0; ae_record_index < cnt; ++ae_record_index) { - CompilerKit::PEFCommandHeader command_header{0}; + NDK::PEFCommandHeader command_header{0}; size_t offsetOfData = ae_records[ae_record_index].fOffset + ae_header.fSize; memcpy(command_header.Name, ae_records[ae_record_index].fName, @@ -508,7 +508,7 @@ NDK_MODULE(NewOSLinker) // step 4: write all PEF commands. - CompilerKit::PEFCommandHeader dateHeader{}; + NDK::PEFCommandHeader dateHeader{}; time_t timestamp = time(nullptr); @@ -518,28 +518,28 @@ NDK_MODULE(NewOSLinker) strncpy(dateHeader.Name, timeStampStr.c_str(), timeStampStr.size()); dateHeader.Flags = 0; - dateHeader.Kind = CompilerKit::kPefZero; + dateHeader.Kind = NDK::kPefZero; dateHeader.Offset = outputFc.tellp(); dateHeader.Size = timeStampStr.size(); commandHdrsList.push_back(dateHeader); - CompilerKit::PEFCommandHeader abiHeader{}; + NDK::PEFCommandHeader abiHeader{}; std::string abi = kLinkerAbiContainer; switch (kArch) { - case CompilerKit::kPefArchAMD64: { + case NDK::kPefArchAMD64: { abi += "MSFT"; break; } - case CompilerKit::kPefArchPowerPC: { + case NDK::kPefArchPowerPC: { abi += "SYSV"; break; } - case CompilerKit::kPefArch32000: - case CompilerKit::kPefArch64000: { + case NDK::kPefArch32000: + case NDK::kPefArch64000: { abi += "MHRA"; break; } @@ -554,11 +554,11 @@ NDK_MODULE(NewOSLinker) abiHeader.Size = abi.size(); abiHeader.Offset = outputFc.tellp(); abiHeader.Flags = 0; - abiHeader.Kind = CompilerKit::kPefLinkerID; + abiHeader.Kind = NDK::kPefLinkerID; commandHdrsList.push_back(abiHeader); - CompilerKit::PEFCommandHeader uuidHeader{}; + NDK::PEFCommandHeader uuidHeader{}; std::random_device rd; @@ -578,7 +578,7 @@ NDK_MODULE(NewOSLinker) uuidHeader.Size = 16; uuidHeader.Offset = outputFc.tellp(); uuidHeader.Flags = 0; - uuidHeader.Kind = CompilerKit::kPefZero; + uuidHeader.Kind = NDK::kPefZero; commandHdrsList.push_back(uuidHeader); @@ -589,7 +589,7 @@ NDK_MODULE(NewOSLinker) constexpr Int32 cPaddingOffset = 16; - size_t previousOffset = (commandHdrsList.size() * sizeof(CompilerKit::PEFCommandHeader)) + cPaddingOffset; + size_t previousOffset = (commandHdrsList.size() * sizeof(NDK::PEFCommandHeader)) + cPaddingOffset; // Finally write down the command headers. // And check for any duplications diff --git a/NDKKit/Sources/String.cxx b/NDKKit/Sources/String.cxx index 87f4721..5153487 100644 --- a/NDKKit/Sources/String.cxx +++ b/NDKKit/Sources/String.cxx @@ -1,7 +1,7 @@ /* * ======================================================== * - * CompilerKit + * NDK * Copyright ZKA Technologies, all rights reserved. * * ======================================================== @@ -20,7 +20,7 @@ #include <NDKKit/NFC/String.hxx> -namespace CompilerKit { +namespace NDK { CharType *StringView::Data() { return m_Data; } const CharType *StringView::CData() const { return m_Data; } @@ -197,4 +197,4 @@ StringView &StringView::operator+=(const StringView &rhs) { return *this; } -} // namespace CompilerKit +} // namespace NDK diff --git a/NDKKit/Sources/coff2ae.cxx b/NDKKit/Sources/coff2ae.cxx deleted file mode 100644 index eb2e133..0000000 --- a/NDKKit/Sources/coff2ae.cxx +++ /dev/null @@ -1,23 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Technologies - -------------------------------------------- */ - -#include <NDKKit/Parser.hxx> -#include <NDKKit/NFC/AE.hxx> -#include <NDKKit/NFC/PEF.hxx> -#include <filesystem> -#include <fstream> -#include <iostream> -#include <memory> -#include <vector> - -///////////////////////////////////////////////////////////////////////////////////////// - -/// @file coff2ae.cxx -/// @brief COFF To AE, the program/module starts here. - -///////////////////////////////////////////////////////////////////////////////////////// - -NDK_MODULE(NewOSCOFFToAE) { return 0; } diff --git a/NDKKit/Sources/elf2ae.cxx b/NDKKit/Sources/elf2ae.cxx deleted file mode 100644 index eb5169e..0000000 --- a/NDKKit/Sources/elf2ae.cxx +++ /dev/null @@ -1,22 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Technologies - -------------------------------------------- */ - -#include <NDKKit/Parser.hxx> -#include <NDKKit/NFC/AE.hxx> -#include <NDKKit/NFC/PEF.hxx> -#include <filesystem> -#include <fstream> -#include <iostream> -#include <memory> -#include <vector> - -///////////////////////////////////////////////////////////////////////////////////////// - -/// @brief COFF 2 AE entrypoint, the program/module starts here. - -///////////////////////////////////////////////////////////////////////////////////////// - -NDK_MODULE(NewOSELFToAE) { return 0; } diff --git a/NDKKit/Sources/power-as.cxx b/NDKKit/Sources/power-as.cxx deleted file mode 100644 index 81cfc15..0000000 --- a/NDKKit/Sources/power-as.cxx +++ /dev/null @@ -1,976 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Technologies - -------------------------------------------- */ - -///////////////////////////////////////////////////////////////////////////////////////// - -/// @file power-as.cxx -/// @author Amlal EL Mahrouss -/// @brief POWER Assembler. - -/// REMINDER: when dealing with an undefined symbol use (string -/// size):LinkerFindSymbol:(string) so that li will look for it. - -///////////////////////////////////////////////////////////////////////////////////////// - -#define __ASM_NEED_PPC__ 1 - -#include <NDKKit/NFC/ErrorID.hxx> -#include <NDKKit/AsmKit/CPU/ppc.hxx> -#include <NDKKit/NFC/PEF.hxx> -#include <NDKKit/Parser.hxx> -#include <NDKKit/NFC/AE.hxx> -#include <NDKKit/Version.hxx> -#include <filesystem> -#include <algorithm> -#include <iostream> -#include <fstream> -#include <vector> - -///////////////////// - -// ANSI ESCAPE CODES - -///////////////////// - -#define kBlank "\e[0;30m" -#define kRed "\e[0;31m" -#define kWhite "\e[0;97m" -#define kYellow "\e[0;33m" - -#define kStdOut (std::cout << kWhite) -#define kStdErr (std::cout << kRed) - -constexpr auto cPowerIPAlignment = 0x4U; - -static CharType kOutputArch = CompilerKit::kPefArchPowerPC; -static Boolean kOutputAsBinary = false; - -static UInt32 kErrorLimit = 10; -static UInt32 kAcceptableErrors = 0; - -static std::size_t kCounter = 1UL; - -static std::uintptr_t kOrigin = kPefBaseOrigin; -static std::vector<std::pair<std::string, std::uintptr_t>> kOriginLabel; - -static bool kVerbose = false; - -static std::vector<uint8_t> kBytes; - -static CompilerKit::AERecordHeader kCurrentRecord{ - .fName = "", .fKind = CompilerKit::kPefCode, .fSize = 0, .fOffset = 0}; - -static std::vector<CompilerKit::AERecordHeader> kRecords; -static std::vector<std::string> kUndefinedSymbols; - -static const std::string kUndefinedSymbol = ":UndefinedSymbol:"; -static const std::string kRelocSymbol = ":RuntimeSymbol:"; - -// \brief forward decl. -static bool asm_read_attributes(std::string &line); - -namespace detail { -void print_error(std::string reason, const std::string &file) noexcept { - if (reason[0] == '\n') reason.erase(0, 1); - - kStdErr << kRed << "[ power-as ] " << kWhite - << ((file == "power-as") ? "internal assembler error " - : ("in file, " + file)) - << kBlank << std::endl; - kStdErr << kRed << "[ power-as ] " << kWhite << reason << kBlank << std::endl; - - if (kAcceptableErrors > kErrorLimit) std::exit(3); - - ++kAcceptableErrors; -} - -void print_warning(std::string reason, const std::string &file) noexcept { - if (reason[0] == '\n') reason.erase(0, 1); - - if (!file.empty()) { - kStdOut << kYellow << "[ file ] " << kWhite << file << kBlank << std::endl; - } - - kStdOut << kYellow << "[ power-as ] " << kWhite << reason << kBlank - << std::endl; -} -} // namespace detail - -/// Do not move it on top! it uses the assembler detail namespace! -#include <asmutils.hxx> - -///////////////////////////////////////////////////////////////////////////////////////// - -/// @brief POWER assembler entrypoint, the program/module starts here. - -///////////////////////////////////////////////////////////////////////////////////////// - -NDK_MODULE(NewOSAssemblerPowerPC) { - for (size_t i = 1; i < argc; ++i) { - if (argv[i][0] == '/') { - if (strcmp(argv[i], "/version") == 0 || strcmp(argv[i], "/v") == 0) { - kStdOut << "power-as: POWER64 Assembler Driver.\npower-as: " << kDistVersion << "\npower-as: " - "Copyright (c) " - "ZKA Technologies.\n"; - return 0; - } else if (strcmp(argv[i], "/h") == 0) { - kStdOut << "power-as: POWER64 Assembler Driver.\npower-as: Copyright (c) 2024 " - "ZKA Technologies.\n"; - kStdOut << "/version,/v: print program version.\n"; - kStdOut << "/verbose: print verbose output.\n"; - kStdOut << "/binary: output as flat binary.\n"; - - return 0; - } else if (strcmp(argv[i], "/binary") == 0) { - kOutputAsBinary = true; - continue; - } else if (strcmp(argv[i], "/verbose") == 0) { - kVerbose = true; - continue; - } - - kStdOut << "power-as: ignore " << argv[i] << "\n"; - continue; - } - - if (!std::filesystem::exists(argv[i])) { - kStdOut << "power-as: can't open: " << argv[i] << std::endl; - goto asm_fail_exit; - } - - std::string object_output(argv[i]); - - for (auto &ext : kAsmFileExts) { - if (object_output.find(ext) != std::string::npos) { - object_output.erase(object_output.find(ext), std::strlen(ext)); - } - } - - object_output += kOutputAsBinary ? kBinaryFileExt : kObjectFileExt; - - std::ifstream file_ptr(argv[i]); - std::ofstream file_ptr_out(object_output, std::ofstream::binary); - - if (file_ptr_out.bad()) { - if (kVerbose) { - kStdOut << "power-as: error: " << strerror(errno) << "\n"; - } - } - - std::string line; - - CompilerKit::AEHeader hdr{0}; - - memset(hdr.fPad, kAEInvalidOpcode, kAEPad); - - hdr.fMagic[0] = kAEMag0; - hdr.fMagic[1] = kAEMag1; - hdr.fSize = sizeof(CompilerKit::AEHeader); - hdr.fArch = kOutputArch; - - ///////////////////////////////////////////////////////////////////////////////////////// - - // COMPILATION LOOP - - ///////////////////////////////////////////////////////////////////////////////////////// - - CompilerKit::EncoderPowerPC asm64; - - while (std::getline(file_ptr, line)) { - if (auto ln = asm64.CheckLine(line, argv[i]); !ln.empty()) { - detail::print_error(ln, argv[i]); - continue; - } - - try { - asm_read_attributes(line); - asm64.WriteLine(line, argv[i]); - } catch (const std::exception &e) { - if (kVerbose) { - std::string what = e.what(); - detail::print_warning("exit because of: " + what, "power-as"); - } - - std::filesystem::remove(object_output); - goto asm_fail_exit; - } - } - - if (!kOutputAsBinary) { - if (kVerbose) { - kStdOut << "power-as: Writing object file...\n"; - } - - // this is the final step, write everything to the file. - - auto pos = file_ptr_out.tellp(); - - hdr.fCount = kRecords.size() + kUndefinedSymbols.size(); - - file_ptr_out << hdr; - - if (kRecords.empty()) { - kStdErr << "power-as: At least one record is needed to write an object " - "file.\npower-as: Make one using `export .code64 foo_bar`.\n"; - - std::filesystem::remove(object_output); - return -1; - } - - kRecords[kRecords.size() - 1].fSize = kBytes.size(); - - std::size_t record_count = 0UL; - - for (auto &record_hdr : kRecords) { - record_hdr.fFlags |= CompilerKit::kKindRelocationAtRuntime; - record_hdr.fOffset = record_count; - ++record_count; - - file_ptr_out << record_hdr; - - if (kVerbose) - kStdOut << "power-as: Wrote record " << record_hdr.fName << "...\n"; - } - - // increment once again, so that we won't lie about the kUndefinedSymbols. - ++record_count; - - for (auto &sym : kUndefinedSymbols) { - CompilerKit::AERecordHeader undefined_sym{0}; - - if (kVerbose) - kStdOut << "power-as: Wrote symbol " << sym << " to file...\n"; - - undefined_sym.fKind = kAEInvalidOpcode; - undefined_sym.fSize = sym.size(); - undefined_sym.fOffset = record_count; - - ++record_count; - - memset(undefined_sym.fPad, kAEInvalidOpcode, kAEPad); - memcpy(undefined_sym.fName, sym.c_str(), sym.size()); - - file_ptr_out << undefined_sym; - - ++kCounter; - } - - auto pos_end = file_ptr_out.tellp(); - - file_ptr_out.seekp(pos); - - hdr.fStartCode = pos_end; - hdr.fCodeSize = kBytes.size(); - - file_ptr_out << hdr; - - file_ptr_out.seekp(pos_end); - } else { - if (kVerbose) { - kStdOut << "power-as: Write raw binary...\n"; - } - } - - // byte from byte, we write this. - for (auto &byte : kBytes) { - file_ptr_out.write(reinterpret_cast<const char *>(&byte), sizeof(byte)); - } - - if (kVerbose) kStdOut << "power-as: Wrote file with program in it.\n"; - - file_ptr_out.flush(); - file_ptr_out.close(); - - if (kVerbose) kStdOut << "power-as: Exit succeeded.\n"; - - return 0; - } - -asm_fail_exit: - - if (kVerbose) kStdOut << "power-as: Exit failed.\n"; - - return MPCC_EXEC_ERROR; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -// @brief Check for attributes -// returns true if any was found. - -///////////////////////////////////////////////////////////////////////////////////////// - -static bool asm_read_attributes(std::string &line) { - // import is the opposite of export, it signals to the li - // that we need this symbol. - if (CompilerKit::find_word(line, "import")) { - if (kOutputAsBinary) { - detail::print_error("Invalid import directive in flat binary mode.", - "power-as"); - throw std::runtime_error("invalid_import_bin"); - } - - auto name = line.substr(line.find("import") + strlen("import") + 1); - - if (name.size() == 0) { - detail::print_error("Invalid import", "power-as"); - throw std::runtime_error("invalid_import"); - } - - std::string result = std::to_string(name.size()); - result += kUndefinedSymbol; - - // mangle this - for (char &j : name) { - if (j == ' ' || j == ',') j = '$'; - } - - result += name; - - if (name.find(".code64") != std::string::npos) { - // data is treated as code. - kCurrentRecord.fKind = CompilerKit::kPefCode; - } else if (name.find(".data64") != std::string::npos) { - // no code will be executed from here. - kCurrentRecord.fKind = CompilerKit::kPefData; - } else if (name.find(".zero64") != std::string::npos) { - // this is a bss section. - kCurrentRecord.fKind = CompilerKit::kPefZero; - } - - // this is a special case for the start stub. - // we want this so that li can find it. - - if (name == kPefStart) { - kCurrentRecord.fKind = CompilerKit::kPefCode; - } - - // now we can tell the code size of the previous kCurrentRecord. - - if (!kRecords.empty()) kRecords[kRecords.size() - 1].fSize = kBytes.size(); - - memset(kCurrentRecord.fName, 0, kAESymbolLen); - memcpy(kCurrentRecord.fName, result.c_str(), result.size()); - - ++kCounter; - - memset(kCurrentRecord.fPad, kAEInvalidOpcode, kAEPad); - - kRecords.emplace_back(kCurrentRecord); - - return true; - } - // export is a special keyword used by power-as to tell the AE output stage to - // mark this section as a header. it currently supports .code64, .data64., - // .zero64 - else if (CompilerKit::find_word(line, "export")) { - if (kOutputAsBinary) { - detail::print_error("Invalid export directive in flat binary mode.", - "power-as"); - throw std::runtime_error("invalid_export_bin"); - } - - auto name = line.substr(line.find("export") + strlen("export")); - - std::string name_copy = name; - - for (char &j : name) { - if (j == ' ') j = '$'; - } - - if (name.find(".code64") != std::string::npos) { - // data is treated as code. - - name_copy.erase(name_copy.find(".code64"), strlen(".code64")); - kCurrentRecord.fKind = CompilerKit::kPefCode; - } else if (name.find(".data64") != std::string::npos) { - // no code will be executed from here. - - name_copy.erase(name_copy.find(".data64"), strlen(".data64")); - kCurrentRecord.fKind = CompilerKit::kPefData; - } else if (name.find(".zero64") != std::string::npos) { - // this is a bss section. - - name_copy.erase(name_copy.find(".zero64"), strlen(".zero64")); - kCurrentRecord.fKind = CompilerKit::kPefZero; - } - - // this is a special case for the start stub. - // we want this so that li can find it. - - if (name == kPefStart) { - kCurrentRecord.fKind = CompilerKit::kPefCode; - } - - while (name_copy.find(" ") != std::string::npos) - name_copy.erase(name_copy.find(" "), 1); - - kOriginLabel.push_back(std::make_pair(name_copy, kOrigin)); - ++kOrigin; - - // now we can tell the code size of the previous kCurrentRecord. - - if (!kRecords.empty()) kRecords[kRecords.size() - 1].fSize = kBytes.size(); - - memset(kCurrentRecord.fName, 0, kAESymbolLen); - memcpy(kCurrentRecord.fName, name.c_str(), name.size()); - - ++kCounter; - - memset(kCurrentRecord.fPad, kAEInvalidOpcode, kAEPad); - - kRecords.emplace_back(kCurrentRecord); - - return true; - } - - return false; -} - -// \brief algorithms and helpers. - -namespace detail::algorithm { -// \brief authorize a brief set of characters. -static inline bool is_not_alnum_space(char c) { - return !(isalpha(c) || isdigit(c) || (c == ' ') || (c == '\t') || - (c == ',') || (c == '(') || (c == ')') || (c == '"') || - (c == '\'') || (c == '[') || (c == ']') || (c == '+') || - (c == '_') || (c == ':') || (c == '@') || (c == '.')); -} - -bool is_valid(const std::string &str) { - return std::find_if(str.begin(), str.end(), is_not_alnum_space) == str.end(); -} -} // namespace detail::algorithm - -///////////////////////////////////////////////////////////////////////////////////////// - -// @brief Check for line (syntax check) - -///////////////////////////////////////////////////////////////////////////////////////// - -std::string CompilerKit::EncoderPowerPC::CheckLine(std::string &line, - const std::string &file) { - std::string err_str; - - if (line.empty() || CompilerKit::find_word(line, "import") || - CompilerKit::find_word(line, "export") || - line.find('#') != std::string::npos || CompilerKit::find_word(line, ";")) { - if (line.find('#') != std::string::npos) { - line.erase(line.find('#')); - } else if (line.find(';') != std::string::npos) { - line.erase(line.find(';')); - } else { - /// does the line contains valid input? - if (!detail::algorithm::is_valid(line)) { - err_str = "Line contains non alphanumeric characters.\nhere -> "; - err_str += line; - } - } - - return err_str; - } - - if (!detail::algorithm::is_valid(line)) { - err_str = "Line contains non alphanumeric characters.\nhere -> "; - err_str += line; - - return err_str; - } - - // check for a valid instruction format. - - if (line.find(',') != std::string::npos) { - if (line.find(',') + 1 == line.size()) { - err_str += "\nInstruction lacks right register, here -> "; - err_str += line.substr(line.find(',')); - - return err_str; - } else { - bool nothing_on_right = true; - - if (line.find(',') + 1 > line.size()) { - err_str += "\nInstruction not complete, here -> "; - err_str += line; - - return err_str; - } - - auto substr = line.substr(line.find(',') + 1); - - for (auto &ch : substr) { - if (ch != ' ' && ch != '\t') { - nothing_on_right = false; - } - } - - // this means we found nothing after that ',' . - if (nothing_on_right) { - err_str += "\nInstruction not complete, here -> "; - err_str += line; - - return err_str; - } - } - } - - // these do take an argument. - std::vector<std::string> operands_inst = {"stw", "li"}; - - // these don't. - std::vector<std::string> filter_inst = {"blr", "bl", "sc"}; - - for (auto &opcodePPC : kOpcodesPowerPC) { - if (CompilerKit::find_word(line, opcodePPC.name)) { - for (auto &op : operands_inst) { - // if only the instruction was found. - if (line == op) { - err_str += "\nMalformed "; - err_str += op; - err_str += " instruction, here -> "; - err_str += line; - } - } - - // if it is like that -> addr1, 0x0 - if (auto it = - std::find(filter_inst.begin(), filter_inst.end(), opcodePPC.name); - it == filter_inst.cend()) { - if (CompilerKit::find_word(line, opcodePPC.name)) { - if (!isspace( - line[line.find(opcodePPC.name) + strlen(opcodePPC.name)])) { - err_str += "\nMissing space between "; - err_str += opcodePPC.name; - err_str += " and operands.\nhere -> "; - err_str += line; - } - } - } - - return err_str; - } - } - - err_str += "Unrecognized instruction: " + line; - - return err_str; -} - -bool CompilerKit::EncoderPowerPC::WriteNumber(const std::size_t &pos, - std::string &jump_label) { - if (!isdigit(jump_label[pos])) return false; - - switch (jump_label[pos + 1]) { - case 'x': { - if (auto res = strtol(jump_label.substr(pos + 2).c_str(), nullptr, 16); - !res) { - if (errno != 0) { - detail::print_error("invalid hex number: " + jump_label, "power-as"); - throw std::runtime_error("invalid_hex"); - } - } - - CompilerKit::NumberCast64 num( - strtol(jump_label.substr(pos + 2).c_str(), nullptr, 16)); - - for (char &i : num.number) { - kBytes.push_back(i); - } - - if (kVerbose) { - kStdOut << "power-as: found a base 16 number here: " - << jump_label.substr(pos) << "\n"; - } - - return true; - } - case 'b': { - if (auto res = strtol(jump_label.substr(pos + 2).c_str(), nullptr, 2); - !res) { - if (errno != 0) { - detail::print_error("invalid binary number: " + jump_label, "power-as"); - throw std::runtime_error("invalid_bin"); - } - } - - CompilerKit::NumberCast64 num( - strtol(jump_label.substr(pos + 2).c_str(), nullptr, 2)); - - if (kVerbose) { - kStdOut << "power-as: found a base 2 number here: " - << jump_label.substr(pos) << "\n"; - } - - for (char &i : num.number) { - kBytes.push_back(i); - } - - return true; - } - case 'o': { - if (auto res = strtol(jump_label.substr(pos + 2).c_str(), nullptr, 7); - !res) { - if (errno != 0) { - detail::print_error("invalid octal number: " + jump_label, "power-as"); - throw std::runtime_error("invalid_octal"); - } - } - - CompilerKit::NumberCast64 num( - strtol(jump_label.substr(pos + 2).c_str(), nullptr, 7)); - - if (kVerbose) { - kStdOut << "power-as: found a base 8 number here: " - << jump_label.substr(pos) << "\n"; - } - - for (char &i : num.number) { - kBytes.push_back(i); - } - - return true; - } - default: { - break; - } - } - - /* check for errno and stuff like that */ - if (auto res = strtol(jump_label.substr(pos).c_str(), nullptr, 10); !res) { - if (errno != 0) { - return false; - } - } - - CompilerKit::NumberCast64 num( - strtol(jump_label.substr(pos).c_str(), nullptr, 10)); - - for (char &i : num.number) { - kBytes.push_back(i); - } - - if (kVerbose) { - kStdOut << "power-as: found a base 10 number here: " << jump_label.substr(pos) - << "\n"; - } - - return true; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -/// @brief Read and write an instruction to the output array. - -///////////////////////////////////////////////////////////////////////////////////////// - -bool CompilerKit::EncoderPowerPC::WriteLine(std::string &line, - const std::string &file) { - if (CompilerKit::find_word(line, "export")) return true; - if (!detail::algorithm::is_valid(line)) return true; - - for (auto &opcodePPC : kOpcodesPowerPC) { - // strict check here - if (CompilerKit::find_word(line, opcodePPC.name)) { - std::string name(opcodePPC.name); - std::string jump_label, cpy_jump_label; - std::vector<size_t> found_registers_index; - - // check funct7 type. - switch (opcodePPC.ops->type) { - default: { - NumberCast32 num(opcodePPC.opcode); - - for (auto ch : num.number) { - kBytes.emplace_back(ch); - } - break; - } - case BADDR: - case PCREL: { - auto num = GetNumber32(line, name); - - kBytes.emplace_back(num.number[0]); - kBytes.emplace_back(num.number[1]); - kBytes.emplace_back(num.number[2]); - kBytes.emplace_back(0x48); - - break; - } - /// General purpose, float, vector operations. Everything that involve - /// registers. - case G0REG: - case FREG: - case VREG: - case GREG: { - // \brief how many registers we found. - std::size_t found_some_count = 0UL; - std::size_t register_count = 0UL; - std::string opcodeName = opcodePPC.name; - std::size_t register_sum = 0; - - NumberCast64 num(opcodePPC.opcode); - - for (size_t line_index = 0UL; line_index < line.size(); - line_index++) { - if (line[line_index] == kAsmRegisterPrefix[0] && - isdigit(line[line_index + 1])) { - std::string register_syntax = kAsmRegisterPrefix; - register_syntax += line[line_index + 1]; - - if (isdigit(line[line_index + 2])) - register_syntax += line[line_index + 2]; - - std::string reg_str; - reg_str += line[line_index + 1]; - - if (isdigit(line[line_index + 2])) - reg_str += line[line_index + 2]; - - // it ranges from r0 to r19 - // something like r190 doesn't exist in the instruction set. - if (isdigit(line[line_index + 3]) && - isdigit(line[line_index + 2])) { - reg_str += line[line_index + 3]; - detail::print_error( - "invalid register index, r" + reg_str + - "\nnote: The POWER accepts registers from r0 to r32.", - file); - throw std::runtime_error("invalid_register_index"); - } - - // finally cast to a size_t - std::size_t reg_index = strtol(reg_str.c_str(), nullptr, 10); - - if (reg_index > kAsmRegisterLimit) { - detail::print_error("invalid register index, r" + reg_str, - file); - throw std::runtime_error("invalid_register_index"); - } - - if (opcodeName == "li") { - char numIndex = 0; - - for (size_t i = 0; i != reg_index; i++) { - numIndex += 0x20; - } - - auto num = GetNumber32(line, reg_str); - - kBytes.push_back(num.number[0]); - kBytes.push_back(num.number[1]); - kBytes.push_back(numIndex); - kBytes.push_back(0x38); - - // check if bigger than two. - for (size_t i = 2; i < 4; i++) { - if (num.number[i] > 0) { - detail::print_warning("number overflow on li operation.", - file); - break; - } - } - - break; - } - - if ((opcodeName[0] == 's' && opcodeName[1] == 't')) { - if (register_sum == 0) { - for (size_t indexReg = 0UL; indexReg < reg_index; - ++indexReg) { - register_sum += 0x20; - } - } else { - register_sum += reg_index; - } - } - - if (opcodeName == "mr") { - switch (register_count) { - case 0: { - kBytes.push_back(0x78); - - char numIndex = 0x3; - - for (size_t i = 0; i != reg_index; i++) { - numIndex += 0x8; - } - - kBytes.push_back(numIndex); - - break; - } - case 1: { - char numIndex = 0x1; - - for (size_t i = 0; i != reg_index; i++) { - numIndex += 0x20; - } - - for (size_t i = 0; i != reg_index; i++) { - kBytes[kBytes.size() - 1] += 0x8; - } - - kBytes[kBytes.size() - 1] -= 0x8; - - kBytes.push_back(numIndex); - - if (reg_index >= 10 && reg_index < 20) - kBytes.push_back(0x7d); - else if (reg_index >= 20 && reg_index < 30) - kBytes.push_back(0x7e); - else if (reg_index >= 30) - kBytes.push_back(0x7f); - else - kBytes.push_back(0x7c); - - break; - } - default: - break; - } - - ++register_count; - ++found_some_count; - } - - if (opcodeName == "addi") { - if (found_some_count == 2 || found_some_count == 0) - kBytes.emplace_back(reg_index); - else if (found_some_count == 1) - kBytes.emplace_back(0x00); - - ++found_some_count; - - if (found_some_count > 3) { - detail::print_error("Too much registers. -> " + line, file); - throw std::runtime_error("too_much_regs"); - } - } - - if (opcodeName.find("cmp") != std::string::npos) { - ++found_some_count; - - if (found_some_count > 3) { - detail::print_error("Too much registers. -> " + line, file); - throw std::runtime_error("too_much_regs"); - } - } - - if (opcodeName.find("mf") != std::string::npos || - opcodeName.find("mt") != std::string::npos) { - char numIndex = 0; - - for (size_t i = 0; i != reg_index; i++) { - numIndex += 0x20; - } - - num.number[2] += numIndex; - - ++found_some_count; - - if (found_some_count > 1) { - detail::print_error("Too much registers. -> " + line, file); - throw std::runtime_error("too_much_regs"); - } - - if (kVerbose) { - kStdOut << "power-as: Found register: " << register_syntax - << "\n"; - kStdOut << "power-as: Amount of registers in instruction: " - << found_some_count << "\n"; - } - - if (reg_index >= 10 && reg_index < 20) - num.number[3] = 0x7d; - else if (reg_index >= 20 && reg_index < 30) - num.number[3] = 0x7e; - else if (reg_index >= 30) - num.number[3] = 0x7f; - else - num.number[3] = 0x7c; - - for (auto ch : num.number) { - kBytes.emplace_back(ch); - } - } - - found_registers_index.push_back(reg_index); - } - } - - if (opcodeName == "addi") { - kBytes.emplace_back(0x38); - } - - if (opcodeName.find("cmp") != std::string::npos) { - char rightReg = 0x0; - - for (size_t i = 0; i != found_registers_index[1]; i++) { - rightReg += 0x08; - } - - kBytes.emplace_back(0x00); - kBytes.emplace_back(rightReg); - kBytes.emplace_back(found_registers_index[0]); - kBytes.emplace_back(0x7c); - } - - if ((opcodeName[0] == 's' && opcodeName[1] == 't')) { - size_t offset = 0UL; - - if (line.find('+') != std::string::npos) { - auto number = GetNumber32(line.substr(line.find("+")), "+"); - offset = number.raw; - } - - kBytes.push_back(offset); - kBytes.push_back(0x00); - kBytes.push_back(register_sum); - - kBytes.emplace_back(0x90); - } - - if (opcodeName == "mr") { - if (register_count == 1) { - detail::print_error("Too few registers. -> " + line, file); - throw std::runtime_error("too_few_registers"); - } - } - - // we're not in immediate addressing, reg to reg. - if (opcodePPC.ops->type != GREG) { - // remember! register to register! - if (found_some_count == 1) { - detail::print_error( - "Unrecognized register found.\ntip: each power-as register " - "starts with 'r'.\nline: " + - line, - file); - - throw std::runtime_error("not_a_register"); - } - } - - if (found_some_count < 1 && name[0] != 'l' && name[0] != 's') { - detail::print_error( - "invalid combination of opcode and registers.\nline: " + line, - file); - throw std::runtime_error("invalid_comb_op_reg"); - } - - break; - } - } - - kOrigin += cPowerIPAlignment; - break; - } - } - - return true; -} - -// Last rev 13-1-24 diff --git a/makefile b/makefile new file mode 100644 index 0000000..5dae246 --- /dev/null +++ b/makefile @@ -0,0 +1,8 @@ +FLAGS=-I./NDKKit -I./ -D__NDK_MODULE__ -I./NDKKit/Sources/Detail -fPIC -I./Private -shared -std=c++20 +CC=x86_64-w64-mingw32-g++.exe +OUT=libNDK.dll + +.PHONY: build-lib +build-lib: + $(CC) $(FLAGS) $(wildcard NDKKit/Sources/*.cxx) -o $(OUT) + @echo "=> OK." diff --git a/posix.make b/posix.make deleted file mode 100644 index 832eb70..0000000 --- a/posix.make +++ /dev/null @@ -1,90 +0,0 @@ - # - # ======================================================== - # - # NDK - # Copyright ZKA Technologies, all rights reserved. - # - # ======================================================== - # - -COMMON_INC=-I./NDKKit -I./ -I./NDKKit/Sources/Detail -LINK_CC=clang++ -std=c++20 -LINK_SRC=NDKKit/Sources/link.cxx -LINK_OUTPUT=Output/link -LINK_ALT_OUTPUT=Output/64link -LINK_ALT_3_OUTPUT=Output/i64link -LINK_ALT_2_OUTPUT=Output/32link -LINK_ALT_4_OUTPUT=Output/ppclink - -PP_SRC=NDKKit/Sources/bpp.cxx -PP_OUTPUT=Output/bpp - -SRC_COMMON=NDKKit/Sources/String.cxx NDKKit/Sources/AssemblyFactory.cxx - -# C++ Compiler (AMD64) -AMD64_CXX_SRC=NDKKit/Sources/cplusplus.cxx $(SRC_COMMON) -AMD64_CXX_OUTPUT=Output/cplusplus - -# C Compiler (POWER) -64X0_CC_SRC=NDKKit/Sources/64x0-cc.cxx $(SRC_COMMON) -64X0_CC_OUTPUT=Output/64x0-cc - -# C Compiler (Our own RISC) -PPC_CC_SRC=NDKKit/Sources/power-cc.cxx $(SRC_COMMON) -PPC_CC_OUTPUT=Output/power-cc - -# 64x0 Assembler (Our Own RISC) -ASM_SRC=NDKKit/Sources/64asm.cxx $(SRC_COMMON) -ASM_OUTPUT=Output/64asm - -# AMD64 Assembler (Intel CISC) -IASM_SRC=NDKKit/Sources/i64asm.cxx $(SRC_COMMON) -IASM_OUTPUT=Output/i64asm - -# Power4 Assembler (IBM RISC) -PPCASM_SRC=NDKKit/Sources/power-as.cxx $(SRC_COMMON) -PPCASM_OUTPUT=Output/power-as - -.PHONY: all -all: pre-processor compiler linker - @echo "make: done." - -.PHONY: pre-processor -pre-processor: - $(LINK_CC) $(COMMON_INC) $(PP_SRC) -o $(PP_OUTPUT) - -.PHONY: compiler -compiler: - $(LINK_CC) $(COMMON_INC) $(64X0_CC_SRC) -o $(64X0_CC_OUTPUT) - $(LINK_CC) $(COMMON_INC) $(AMD64_CXX_SRC) -o $(AMD64_CXX_OUTPUT) - $(LINK_CC) $(COMMON_INC) $(PPC_CC_SRC) -o $(PPC_CC_OUTPUT) - $(LINK_CC) $(COMMON_INC) $(IASM_SRC) -o $(IASM_OUTPUT) - $(LINK_CC) $(COMMON_INC) $(ASM_SRC) -o $(ASM_OUTPUT) - $(LINK_CC) $(COMMON_INC) $(PPCASM_SRC) -o $(PPCASM_OUTPUT) - -.PHONY: linker -linker: - $(LINK_CC) $(COMMON_INC) $(LINK_SRC) -o $(LINK_OUTPUT) - cp $(LINK_OUTPUT) $(LINK_ALT_OUTPUT) - cp $(LINK_OUTPUT) $(LINK_ALT_2_OUTPUT) - cp $(LINK_OUTPUT) $(LINK_ALT_3_OUTPUT) - cp $(LINK_OUTPUT) $(LINK_ALT_4_OUTPUT) - -.PHONY: help -help: - @echo "compiler - ZKA Technologies Compiler Suite." - @echo "pre-processor - ZKA Technologies Preprocessor Suite." - @echo "linker - ZKA Technologies Linkers." - @echo "clean - Clean objects and executables." - -.PHONY: clean -clean: - rm -f $(64X0_CC_OUTPUT) - rm -f $(PPC_CC_OUTPUT) - rm -f $(PP_OUTPUT) - rm -f $(ASM_OUTPUT) - rm -f $(IASM_OUTPUT) - rm -f $(LINK_OUTPUT) - rm -rf *.obj - -# Last rev 8-1-24 diff --git a/win64.make b/win64.make deleted file mode 100644 index 7fca096..0000000 --- a/win64.make +++ /dev/null @@ -1,89 +0,0 @@ - # - # ======================================================== - # - # NDK - # Copyright ZKA Technologies, all rights reserved. - # - # ======================================================== - # - -COMMON_INC=-I./NDKKit -I./ -I./NDKKit/Sources/Detail -LINK_CC=clang++ -std=c++20 -Xlinker -s -LINK_SRC=NDKKit/Sources/link.cxx -LINK_OUTPUT=Output/link.exe -LINK_ALT_OUTPUT=Output/64link.exe -LINK_ALT_3_OUTPUT=Output/i64link.exe -LINK_ALT_2_OUTPUT=Output/32link.exe - -PP_SRC=NDKKit/Sources/bpp.cxx -PP_OUTPUT=Output/bpp.exe - -SRC_COMMON=NDKKit/Sources/String.cxx NDKKit/Sources/AssemblyFactory.cxx - -# C++ Compiler (AMD64) -AMD64_CXX_SRC=NDKKit/Sources/cplusplus.cxx $(SRC_COMMON) -AMD64_CXX_OUTPUT=Output/cplusplus.exe - -# C Compiler (POWER) -64X0_CC_SRC=NDKKit/Sources/64x0-cc.cxx $(SRC_COMMON) -64X0_CC_OUTPUT=Output/64x0-cc.exe - -# C Compiler -PPC_CC_SRC=NDKKit/Sources/power-cc.cxx $(SRC_COMMON) -PPC_CC_OUTPUT=Output/power-cc.exe - -# 64x0 Assembler -ASM_SRC=NDKKit/Sources/64asm.cxx $(SRC_COMMON) -ASM_OUTPUT=Output/64asm.exe - -# AMD64 Assembler -IASM_SRC=NDKKit/Sources/i64asm.cxx $(SRC_COMMON) -IASM_OUTPUT=Output/i64asm.exe - -# POWER Assembler -PPCASM_SRC=NDKKit/Sources/power-as.cxx $(SRC_COMMON) -PPCASM_OUTPUT=Output/power-as.exe - -.PHONY: all -all: pre-processor compiler linker - @echo "make: done." - -.PHONY: pre-processor -pre-processor: - $(LINK_CC) $(COMMON_INC) $(PP_SRC) -o $(PP_OUTPUT) - -.PHONY: compiler -compiler: - $(LINK_CC) $(COMMON_INC) $(64X0_CC_SRC) -o $(64X0_CC_OUTPUT) - $(LINK_CC) $(COMMON_INC) $(AMD64_CXX_SRC) -o $(AMD64_CXX_OUTPUT) - $(LINK_CC) $(COMMON_INC) $(PPC_CC_SRC) -o $(PPC_CC_OUTPUT) - $(LINK_CC) $(COMMON_INC) $(IASM_SRC) -o $(IASM_OUTPUT) - $(LINK_CC) $(COMMON_INC) $(ASM_SRC) -o $(ASM_OUTPUT) - $(LINK_CC) $(COMMON_INC) $(PPCASM_SRC) -o $(PPCASM_OUTPUT) - -.PHONY: linker -linker: - $(LINK_CC) $(COMMON_INC) $(LINK_SRC) -o $(LINK_OUTPUT) - cp $(LINK_OUTPUT) $(LINK_ALT_OUTPUT) - cp $(LINK_OUTPUT) $(LINK_ALT_2_OUTPUT) - cp $(LINK_OUTPUT) $(LINK_ALT_3_OUTPUT) - -.PHONY: help -help: - @echo "compiler - ZKA Compiler Suite." - @echo "pre-processor - ZKA Preprocessor Suite." - @echo "linker - ZKA Linkers." - @echo "clean - Clean objects and executables." - -.PHONY: clean -clean: - rm -f $(64X0_CC_OUTPUT) - rm -f $(PPC_CC_OUTPUT) - rm -f $(PP_OUTPUT) - rm -f $(ASM_OUTPUT) - rm -f $(IASM_OUTPUT) - rm -f $(LINK_OUTPUT) - rm -rf *.obj - rm -rf *.exec - -# Last rev 8-1-24 |
