summaryrefslogtreecommitdiffhomepage
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
parenta656cb178c384bcb27b22fdc7ce1e10e49e8e5bd (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--.gitignore5
-rw-r--r--Documentation/TODO.txt3
-rw-r--r--Examples/ExampleCDialect.S29
-rw-r--r--Examples/ExampleCDialect.c8
-rw-r--r--Headers/AsmKit/CPU/ppc.hpp1
-rw-r--r--Headers/StdKit/PEF.hpp10
-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
12 files changed, 131 insertions, 57 deletions
diff --git a/.gitignore b/.gitignore
index d56db1e..48a4a74 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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;