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 | |
| parent | a656cb178c384bcb27b22fdc7ce1e10e49e8e5bd (diff) | |
Compiler: Improve codegen on PowerPC and fix ppc/x64/64k assemblers.
Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
| -rw-r--r-- | .gitignore | 5 | ||||
| -rw-r--r-- | Documentation/TODO.txt | 3 | ||||
| -rw-r--r-- | Examples/ExampleCDialect.S | 29 | ||||
| -rw-r--r-- | Examples/ExampleCDialect.c | 8 | ||||
| -rw-r--r-- | Headers/AsmKit/CPU/ppc.hpp | 1 | ||||
| -rw-r--r-- | Headers/StdKit/PEF.hpp | 10 | ||||
| -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 |
12 files changed, 131 insertions, 57 deletions
@@ -8,6 +8,9 @@ local.properties .loadpath .recommenders +# NewOS/MP-UX executable +*.exec + docs/ # Compiled class file @@ -220,4 +223,4 @@ _deps # The C/C++ compiler. mcc mpcc -mpc++
\ No newline at end of file +mpc++ diff --git a/Documentation/TODO.txt b/Documentation/TODO.txt index 9c5214e..0e4f807 100644 --- a/Documentation/TODO.txt +++ b/Documentation/TODO.txt @@ -5,6 +5,7 @@ - Add support 'mov' which encodes a,b,c,d,e and 8,15 registers. - C compilers - - Add structs/enums, and a preprocssing program. + - Fix code generation (ppc done) + - Add structs/enums, and a preprocessing program (ppc todo) - Extended Syntax Checker (esc.exe -c-asm foo.s) diff --git a/Examples/ExampleCDialect.S b/Examples/ExampleCDialect.S index d9613ef..2a5203a 100644 --- a/Examples/ExampleCDialect.S +++ b/Examples/ExampleCDialect.S @@ -1,23 +1,28 @@ # Path: Examples/ExampleCDialect.c -# Language: PowerPC Assembly (Generated from ANSI C) -# Build Date: 2024-4-4 +# Language: PowerPC Assembly (Generated from C) +# Build Date: 2024-4-16 -dword export .code64 main - lda r2,0x1000 - lda r12, import __MPCC_IF_PROC_417129812448 - #r12 = Code to jump on, r11 right cond, r10 left cond. - beq r10, r11, r12 -dword export .code64 __MPCC_IF_PROC_417129812448 - ldw r19, import foo - jlr +dword export .code64 __ImageStart - ldw r19, 57 - jlr + li r3,0x1000 + + cmpw r10, r11 + beq import__MPCC_IF_PROC_6168864856 +dword export .code64 __MPCC_IF_PROC_6168864856 + + + + mr r31, r3 + blr + + + mr r31, r0 + blr diff --git a/Examples/ExampleCDialect.c b/Examples/ExampleCDialect.c index 899062c..8c65bf0 100644 --- a/Examples/ExampleCDialect.c +++ b/Examples/ExampleCDialect.c @@ -1,4 +1,10 @@ -int main(int argc, char const* argv[]) { +struct { + int a; + int b; + int c; +}; + +int __ImageStart(int argc, char const* argv[]) { int* foo = 0x1000; if (foo == 57) { diff --git a/Headers/AsmKit/CPU/ppc.hpp b/Headers/AsmKit/CPU/ppc.hpp index 873552d..dea5b00 100644 --- a/Headers/AsmKit/CPU/ppc.hpp +++ b/Headers/AsmKit/CPU/ppc.hpp @@ -15,6 +15,7 @@ #define OPTIONAL 0x4 #define VMX 0x8 #define CPU970 0x10 /* added to OPTIONAL insts that the 970 has */ +#define CPUMAHROUSS 0x12 /* optional mahrouss insts. */ enum optype { NONE, /* no operand */ diff --git a/Headers/StdKit/PEF.hpp b/Headers/StdKit/PEF.hpp index 8d8cc4f..d5379c4 100644 --- a/Headers/StdKit/PEF.hpp +++ b/Headers/StdKit/PEF.hpp @@ -11,23 +11,23 @@ // @file PEF.hpp // @brief Preferred Executable Format -#define kPefMagic "PEF" -#define kPefMagicFat "FEP" +#define kPefMagic "Joy!" +#define kPefMagicFat "yoJ!" -#define kPefExt ".exe" +#define kPefExt ".exec" #define kPefDylibExt ".lib" #define kPefLibExt ".slib" #define kPefObjectExt ".obj" #define kPefDebugExt ".dbg" -#define kPefMagicLen 3 +#define kPefMagicLen 5 #define kPefVersion 2 #define kPefNameLen 64 #define kPefBaseOrigin 0x1000000 -#define kPefStart "__start" +#define kPefStart "__ImageStart" namespace CompilerKit { enum { 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; |
