summaryrefslogtreecommitdiffhomepage
path: root/Sources
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2024-04-16 15:58:46 +0200
committerAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2024-04-16 15:58:46 +0200
commit56fd0994ae3a2f1b327ebac45f5927f7656d68a4 (patch)
tree69583e054edf12092a604104282f00e988109bfa /Sources
parenta656cb178c384bcb27b22fdc7ce1e10e49e8e5bd (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.cc8
-rw-r--r--Sources/ccplus.cc21
-rw-r--r--Sources/i64asm.cc7
-rw-r--r--Sources/link.cc1
-rw-r--r--Sources/ppc-cc.cc88
-rw-r--r--Sources/ppcasm.cc7
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;