diff options
| author | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-04-16 15:58:46 +0200 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-04-16 15:58:46 +0200 |
| commit | 56fd0994ae3a2f1b327ebac45f5927f7656d68a4 (patch) | |
| tree | 69583e054edf12092a604104282f00e988109bfa /Sources | |
| parent | a656cb178c384bcb27b22fdc7ce1e10e49e8e5bd (diff) | |
Compiler: Improve codegen on PowerPC and fix ppc/x64/64k assemblers.
Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
Diffstat (limited to 'Sources')
| -rw-r--r-- | Sources/64asm.cc | 8 | ||||
| -rw-r--r-- | Sources/ccplus.cc | 21 | ||||
| -rw-r--r-- | Sources/i64asm.cc | 7 | ||||
| -rw-r--r-- | Sources/link.cc | 1 | ||||
| -rw-r--r-- | Sources/ppc-cc.cc | 88 | ||||
| -rw-r--r-- | Sources/ppcasm.cc | 7 |
6 files changed, 95 insertions, 37 deletions
diff --git a/Sources/64asm.cc b/Sources/64asm.cc index b955ad6..1d6404e 100644 --- a/Sources/64asm.cc +++ b/Sources/64asm.cc @@ -310,6 +310,14 @@ static bool asm_read_attributes(std::string &line) { auto name = line.substr(line.find("import") + strlen("import")); + /// sanity check to avoid stupid linker errors. + if (name.size() == 0) + { + detail::print_error("Invalid import", + "ppcasm"); + throw std::runtime_error("invalid_import"); + } + std::string result = std::to_string(name.size()); result += kUndefinedSymbol; diff --git a/Sources/ccplus.cc b/Sources/ccplus.cc index ee73093..7e15afc 100644 --- a/Sources/ccplus.cc +++ b/Sources/ccplus.cc @@ -151,22 +151,23 @@ static bool kOnForLoop = false; static bool kInBraces = false; static size_t kBracesCount = 0UL; -/* @brief C compiler backend for Mahrouss Logic C */ -class CompilerBackendClang final : public ParserKit::CompilerBackend { +/* @brief C++ compiler backend for Mahrouss Logic C++ */ +class CompilerBackendCPlusPlus final : public ParserKit::CompilerBackend { public: - explicit CompilerBackendClang() = default; - ~CompilerBackendClang() override = default; + explicit CompilerBackendCPlusPlus() = default; + ~CompilerBackendCPlusPlus() override = default; - MPCC_COPY_DEFAULT(CompilerBackendClang); + MPCC_COPY_DEFAULT(CompilerBackendCPlusPlus); bool Compile(const std::string& text, const char* file) override; - const char* Language() override { return "C++20 based dialect for NewOS."; } + const char* Language() override; + }; /// compiler variables -static CompilerBackendClang* kCompilerBackend = nullptr; +static CompilerBackendCPlusPlus* kCompilerBackend = nullptr; static std::vector<detail::CompilerType> kCompilerVariables; static std::vector<std::string> kCompilerFunctions; @@ -181,6 +182,8 @@ union number_cast final { }; } // namespace detail +const char* CompilerBackendCPlusPlus::Language() override { return "C++"; } + ///////////////////////////////////////////////////////////////////////////////////////// // @name Compile @@ -188,7 +191,7 @@ union number_cast final { ///////////////////////////////////////////////////////////////////////////////////////// -bool CompilerBackendClang::Compile(const std::string& text, const char* file) { +bool CompilerBackendCPlusPlus::Compile(const std::string& text, const char* file) { if (text.empty()) return false; // if (expr) @@ -370,7 +373,7 @@ MPCC_MODULE(CompilerCPlusPlus) { bool skip = false; kFactory.Mount(new AssemblyMountpointClang()); - kCompilerBackend = new CompilerBackendClang(); + kCompilerBackend = new CompilerBackendCPlusPlus(); for (auto index = 1UL; index < argc; ++index) { if (argv[index][0] == '-') { diff --git a/Sources/i64asm.cc b/Sources/i64asm.cc index f7fa5e5..d19c515 100644 --- a/Sources/i64asm.cc +++ b/Sources/i64asm.cc @@ -367,6 +367,13 @@ static bool asm_read_attributes(std::string &line) { auto name = line.substr(line.find("import") + strlen("import") + 1); + if (name.size() == 0) + { + detail::print_error("Invalid import", + "ppcasm"); + throw std::runtime_error("invalid_import"); + } + std::string result = std::to_string(name.size()); result += kUndefinedSymbol; diff --git a/Sources/link.cc b/Sources/link.cc index 8c88411..7a58083 100644 --- a/Sources/link.cc +++ b/Sources/link.cc @@ -193,6 +193,7 @@ MPCC_MODULE(NewOSLinker) { pef_container.Magic[0] = kPefMagic[kFatBinaryEnable ? 2 : 0]; pef_container.Magic[1] = kPefMagic[1]; pef_container.Magic[2] = kPefMagic[kFatBinaryEnable ? 0 : 2]; + pef_container.Magic[3] = kPefMagic[3]; pef_container.Version = kPefVersion; // specify the start address, can be 0x10000 diff --git a/Sources/ppc-cc.cc b/Sources/ppc-cc.cc index 4e2f162..bb38439 100644 --- a/Sources/ppc-cc.cc +++ b/Sources/ppc-cc.cc @@ -320,16 +320,35 @@ bool CompilerBackendCLang::Compile(const std::string &text, const char *file) { value += tmp; } - syntaxLeaf.fUserValue = "\tldw r19, "; + syntaxLeaf.fUserValue = "\tmr r31, "; // make it pretty. - if (value.find('\t') != std::string::npos) + while (value.find('\t') != std::string::npos) value.erase(value.find('\t'), 1); - syntaxLeaf.fUserValue += value + "\n"; + while (value.find(' ') != std::string::npos) + value.erase(value.find(' '), 1); + + while (value.find("import") != std::string::npos) + value.erase(value.find("import"), strlen("import")); + + bool found = false; + + for (auto& reg : kState.kStackFrame) + { + if (value.find(reg.fName) != std::string::npos) + { + found = true; + syntaxLeaf.fUserValue += reg.fReg; + break; + } + } + + if (!found) + syntaxLeaf.fUserValue += "r0"; } - syntaxLeaf.fUserValue += "\tjlr"; + syntaxLeaf.fUserValue += "\n\tblr"; kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf); @@ -352,12 +371,13 @@ bool CompilerBackendCLang::Compile(const std::string &text, const char *file) { kIfFunction = "__MPCC_IF_PROC_"; kIfFunction += std::to_string(time_off._Raw); - syntaxLeaf.fUserValue = "\tlda r12, import "; - syntaxLeaf.fUserValue += - kIfFunction + - "\n\t#r12 = Code to jump on, r11 right cond, r10 left cond.\n\tbeq " - "r10, r11, r12\ndword export .code64 " + - kIfFunction + "\n"; + syntaxLeaf.fUserValue = + "\tcmpw " + "r10, r11"; + + syntaxLeaf.fUserValue += "\n\tbeq import" + kIfFunction + " \ndword export .code64 " + + kIfFunction + "\n"; + kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf); kIfFound = true; @@ -421,11 +441,11 @@ bool CompilerBackendCLang::Compile(const std::string &text, const char *file) { if (textBuffer.find('=') != std::string::npos && kInBraces && !kIfFound) { if (textBuffer.find("*") != std::string::npos) { if (textBuffer.find("=") > textBuffer.find("*")) - substr += "\tlda "; + substr += "\tli "; else - substr += "\tldw "; + substr += "\tli "; } else { - substr += "\tldw "; + substr += "\tli "; } } else if (textBuffer.find('=') != std::string::npos && !kInBraces) { substr += "stw export .data64 "; @@ -512,22 +532,33 @@ bool CompilerBackendCLang::Compile(const std::string &text, const char *file) { return type.fName.find(substr) != std::string::npos; }); - if (kRegisterCounter == 5 || kRegisterCounter == 6) ++kRegisterCounter; + kCompilerVariables.push_back({.fName = substr}); + + if (textBuffer[text_index] == ';') break; std::string reg = kAsmRegisterPrefix; + + ++kRegisterCounter; reg += std::to_string(kRegisterCounter); - if (var_to_find == kCompilerVariables.cend()) { - ++kRegisterCounter; + auto newSubstr = substr.substr(substr.find(" ")); + + std::string symbol; + + for (size_t start = 0; start < newSubstr.size(); ++start) { + if (newSubstr[start] == ',') + break; + + if (newSubstr[start] == ' ') + continue; - kState.kStackFrame.push_back({.fName = substr, .fReg = reg}); - kCompilerVariables.push_back({.fName = substr}); + symbol += (newSubstr[start]); } - syntaxLeaf.fUserValue += substr; - kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf); + kState.kStackFrame.push_back({.fName = symbol, .fReg = reg}); - if (textBuffer[text_index] == '=') break; + syntaxLeaf.fUserValue += "\n\tli " + reg + substr.substr(substr.find(',')); + kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf); } // function handler. @@ -576,7 +607,7 @@ bool CompilerBackendCLang::Compile(const std::string &text, const char *file) { } args += args_buffer; - args += "\n\tlda r19, "; + args += "\n\tli r19, "; } } @@ -598,7 +629,8 @@ bool CompilerBackendCLang::Compile(const std::string &text, const char *file) { if (kInBraces) { syntaxLeaf.fUserValue = args; syntaxLeaf.fUserValue += substr; - syntaxLeaf.fUserValue += "\n\tjrl\n"; + + syntaxLeaf.fUserValue += "\n\tblr\n"; kState.fSyntaxTree->fLeafList.push_back(syntaxLeaf); @@ -1139,7 +1171,7 @@ class AssemblyMountpointCLang final : public CompilerKit::AssemblyInterface { (*kState.fOutputAssembly) << "# Path: " << src_file << "\n"; (*kState.fOutputAssembly) - << "# Language: PowerPC Assembly (Generated from ANSI C)\n"; + << "# Language: PowerPC Assembly (Generated from C)\n"; (*kState.fOutputAssembly) << "# Build Date: " << fmt << "\n\n"; ParserKit::SyntaxLeafList syntax; @@ -1204,12 +1236,12 @@ class AssemblyMountpointCLang final : public CompilerKit::AssemblyInterface { } if (ParserKit::find_word(leaf.fUserValue, needle)) { - if (leaf.fUserValue.find("import " + needle) != + if (leaf.fUserValue.find("import ") != std::string::npos) { - std::string range = "import " + needle; + std::string range = "import "; leaf.fUserValue.replace( - leaf.fUserValue.find("import " + needle), range.size(), - needle); + leaf.fUserValue.find(range), range.size(), + ""); } if (leaf.fUserValue.find("ldw r6") != std::string::npos) { diff --git a/Sources/ppcasm.cc b/Sources/ppcasm.cc index eadedec..4bab2c4 100644 --- a/Sources/ppcasm.cc +++ b/Sources/ppcasm.cc @@ -315,6 +315,13 @@ static bool asm_read_attributes(std::string &line) { auto name = line.substr(line.find("import") + strlen("import") + 1); + if (name.size() == 0) + { + detail::print_error("Invalid import", + "ppcasm"); + throw std::runtime_error("invalid_import"); + } + std::string result = std::to_string(name.size()); result += kUndefinedSymbol; |
