summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlalelmahrouss@icloud.com>2024-02-18 08:18:25 +0000
committerAmlal El Mahrouss <amlalelmahrouss@icloud.com>2024-02-18 08:18:25 +0000
commita7686350855be22e3322f0df6ceb22964bf75965 (patch)
tree9bd17adb13d10db83cc87cb1dd5d8274b87abeb0
parent0ab360a35545a0a03c90b97499c85c4381fe7088 (diff)
parent5bceef71ec6e7f8e4e9b7fcb987e44403d6de72c (diff)
Merge branch 'compiler-parser' into 'master'
Linker: custom ABI according to CPU. See merge request mahrouss-logic/mp-cc!3
-rw-r--r--Private/CompilerKit/AsmKit/Arch/amd64.hpp28
-rw-r--r--Private/Toolchain/Compiler/cl-parser.hxx14
-rw-r--r--Private/Toolchain/bin/Source/hello_amd64.masm2
-rw-r--r--Private/Toolchain/ccplus.cc3
-rw-r--r--Private/Toolchain/compile_flags.txt1
-rw-r--r--Private/Toolchain/i64asm.cc90
-rw-r--r--Private/Toolchain/link.cc26
-rw-r--r--Private/Toolchain/makefile2
8 files changed, 97 insertions, 69 deletions
diff --git a/Private/CompilerKit/AsmKit/Arch/amd64.hpp b/Private/CompilerKit/AsmKit/Arch/amd64.hpp
index bb8637f..2438965 100644
--- a/Private/CompilerKit/AsmKit/Arch/amd64.hpp
+++ b/Private/CompilerKit/AsmKit/Arch/amd64.hpp
@@ -40,25 +40,25 @@ struct CpuCodeAMD64 {
#define kJumpLimitStandardLimit 0xEB
inline std::vector<CpuCodeAMD64> kOpcodesAMD64 = {
- kAsmOpcodeDecl("int", 0xCD) kAsmOpcodeDecl("into", 0xCE) kAsmOpcodeDecl(
- "intd", 0xF1) kAsmOpcodeDecl("int3", 0xC3)
+kAsmOpcodeDecl("int", 0xCD)
+kAsmOpcodeDecl("into", 0xCE)
+kAsmOpcodeDecl("intd", 0xF1)
+kAsmOpcodeDecl("int3", 0xC3)
- kAsmOpcodeDecl("iret", 0xCF) kAsmOpcodeDecl("retf", 0xCB)
- kAsmOpcodeDecl("retn", 0xC3) kAsmOpcodeDecl("sti", 0xfb)
- kAsmOpcodeDecl("cli", 0xfa)
+kAsmOpcodeDecl("iret", 0xCF)
+kAsmOpcodeDecl("retf", 0xCB)
+kAsmOpcodeDecl("retn", 0xC3)
+kAsmOpcodeDecl("sti", 0xfb)
+kAsmOpcodeDecl("cli", 0xfa)
- kAsmOpcodeDecl("nop", 0x90)
+kAsmOpcodeDecl("nop", 0x90)
- kAsmOpcodeDecl("mov eax", 0xb8) kAsmOpcodeDecl(
- "mov ecx", 0xb9) kAsmOpcodeDecl("mov edx", 0xba)
- kAsmOpcodeDecl("mov ebx", 0xbb) kAsmOpcodeDecl(
- "mov esp", 0xbc) kAsmOpcodeDecl("mov ebp", 0xbd)
- kAsmOpcodeDecl("mov esi", 0xbe)
+kAsmOpcodeDecl("mov", 0x48)
- kAsmOpcodeDecl("jmp", 0xE9)
- kAsmOpcodeDecl("call", 0xE9)
+kAsmOpcodeDecl("jmp", 0xE9)
+kAsmOpcodeDecl("call", 0xFF)
- kAsmOpcodeDecl("mov", 0x00)};
+kAsmOpcodeDecl("mov", 0x00)};
// \brief 64x0 register prefix
// example: r32, r0
diff --git a/Private/Toolchain/Compiler/cl-parser.hxx b/Private/Toolchain/Compiler/cl-parser.hxx
index d93cdc5..7881127 100644
--- a/Private/Toolchain/Compiler/cl-parser.hxx
+++ b/Private/Toolchain/Compiler/cl-parser.hxx
@@ -18,4 +18,16 @@
#include <CompilerKit/CompilerKit.hpp>
#include <CompilerKit/ParserKit.hpp>
-namespace CompilerKit {} // namespace CompilerKit
+namespace CompilerKit {
+class CLParserExpression {
+ private:
+ StringView mExprView;
+
+ public:
+ CLParserExpression(const char* expr)
+ : mExprView(StringBuilder::Construct(expr)) {}
+ virtual ~CLParserExpression() = default;
+
+ MPCC_COPY_DEFAULT(CLParserExpression);
+};
+} // namespace CompilerKit
diff --git a/Private/Toolchain/bin/Source/hello_amd64.masm b/Private/Toolchain/bin/Source/hello_amd64.masm
index 8ae4f12..2223305 100644
--- a/Private/Toolchain/bin/Source/hello_amd64.masm
+++ b/Private/Toolchain/bin/Source/hello_amd64.masm
@@ -3,7 +3,7 @@ bits 64
export .text MySampleFoo
cli
-mov rsp, rdx
+mov rsp, rsp
int 0x80
jmp 0x100000
sti
diff --git a/Private/Toolchain/ccplus.cc b/Private/Toolchain/ccplus.cc
index e2fe964..77bd22a 100644
--- a/Private/Toolchain/ccplus.cc
+++ b/Private/Toolchain/ccplus.cc
@@ -11,8 +11,9 @@
#include <uuid/uuid.h>
-#include <CompilerKit/AsmKit/Arch/64x0.hpp>
+#include <CompilerKit/AsmKit/Arch/amd64.hpp>
#include <CompilerKit/ParserKit.hpp>
+#include <Compiler/cl-parser.hxx>
#include <cstdio>
#include <fstream>
#include <iostream>
diff --git a/Private/Toolchain/compile_flags.txt b/Private/Toolchain/compile_flags.txt
index 9afc1ed..bf90a5c 100644
--- a/Private/Toolchain/compile_flags.txt
+++ b/Private/Toolchain/compile_flags.txt
@@ -1,3 +1,4 @@
-std=c++20
-I../
-I../CompilerKit
+-I./
diff --git a/Private/Toolchain/i64asm.cc b/Private/Toolchain/i64asm.cc
index b86f88a..55719cf 100644
--- a/Private/Toolchain/i64asm.cc
+++ b/Private/Toolchain/i64asm.cc
@@ -982,6 +982,18 @@ bool CompilerKit::PlatformAssemblerAMD64::WriteLine(std::string &line,
const std::string &file) {
if (ParserKit::find_word(line, "export ")) return true;
+ struct RegMapAMD64 {
+ std::string fName;
+ e64_byte_t fModRM;
+ };
+
+ std::vector<RegMapAMD64> regsPt2{
+ {.fName = "ax", .fModRM = 0b000}, {.fName = "cx", .fModRM = 0b001},
+ {.fName = "dx", .fModRM = 0b010}, {.fName = "bx", .fModRM = 0b011},
+ {.fName = "sp", .fModRM = 0b100}, {.fName = "bp", .fModRM = 0b101},
+ {.fName = "si", .fModRM = 0b110}, {.fName = "di", .fModRM = 0b111},
+ };
+
for (auto &opcodeAMD64 : kOpcodesAMD64) {
// strict check here
if (ParserKit::find_word(line, opcodeAMD64.fName) &&
@@ -989,21 +1001,9 @@ bool CompilerKit::PlatformAssemblerAMD64::WriteLine(std::string &line,
std::string name(opcodeAMD64.fName);
if (name.find("mov") != std::string::npos) {
- struct RegMapAMD64 {
- std::string fName;
- e64_byte_t fModRM;
- };
-
- std::vector<RegMapAMD64> regs{
- {.fName = "ax", .fModRM = 0}, {.fName = "cx", .fModRM = 1},
- {.fName = "dx", .fModRM = 2}, {.fName = "bx", .fModRM = 3},
- {.fName = "sp", .fModRM = 4}, {.fName = "bp", .fModRM = 5},
- {.fName = "si", .fModRM = 6}, {.fName = "di", .fModRM = 7},
- };
-
std::string substr = line.substr(line.find(name) + name.size());
- uint64_t bits = 16;
+ uint64_t bits = 64;
if (substr.find(",") == std::string::npos) {
detail::print_error("Invalid combination of operands and registers.",
@@ -1011,42 +1011,36 @@ bool CompilerKit::PlatformAssemblerAMD64::WriteLine(std::string &line,
throw std::runtime_error("comb_op_reg");
}
- bool found = false;
+ bits = 64;
- for (auto &reg : regs) {
- if (line.find(reg.fName) != std::string::npos) {
- if (!found) {
- if (line.substr(line.find(reg.fName) - 1)[0] == 'r') {
- bits = 64;
+ bool noRightRegister = false;
- kBytes.emplace_back(0x48);
- kBytes.emplace_back(0x89);
- kBytes.emplace_back(0x00);
- } else {
- detail::print_error(
- "Invalid combination of registers, each 64-bit register "
- "must start with 'r'.",
- "i64asm");
- throw std::runtime_error("comb_op_reg");
- }
+ if (!noRightRegister) {
+ if (bits == 64 ||
+ bits == 32)
+ {
+ if (bits != 32)
+ kBytes.emplace_back(opcodeAMD64.fOpcode);
- found = true;
+ kBytes.emplace_back(0x89);
- kBytes.push_back(0xc0 + reg.fModRM);
+ // TODO
- continue;
- }
+ this->WriteNumber32(line.find(name) + name.size() + 2, line);
}
- }
+ else if (bits == 16) {
+ kBytes.emplace_back(0x66);
+ kBytes.emplace_back(0x89);
- if (bits == 64)
- this->WriteNumber32(line.find(name) + name.size() + 2, line);
- else if (bits == 16)
- this->WriteNumber16(line.find(name) + name.size() + 2, line);
- else {
- detail::print_error("Invalid combination of operands and registers.",
- "i64asm");
- throw std::runtime_error("comb_op_reg");
+ // TODO
+
+ this->WriteNumber16(line.find(name) + name.size() + 2, line);
+ }
+ else {
+ detail::print_error("Invalid combination of operands and registers.",
+ "i64asm");
+ throw std::runtime_error("comb_op_reg");
+ }
}
break;
@@ -1057,7 +1051,10 @@ bool CompilerKit::PlatformAssemblerAMD64::WriteLine(std::string &line,
break;
} else if (name == "jmp" || name == "call") {
kBytes.emplace_back(opcodeAMD64.fOpcode);
- this->WriteNumber32(line.find(name) + name.size() + 1, line);
+
+ if (!this->WriteNumber32(line.find(name) + name.size() + 1, line)) {
+ // TODO
+ }
break;
} else {
@@ -1069,10 +1066,9 @@ bool CompilerKit::PlatformAssemblerAMD64::WriteLine(std::string &line,
}
}
- if (line.find("db") != std::string::npos) {
- this->WriteNumber(line.find("db") + strlen("db") + 1, line);
- }
- else if (line.find("org ") != std::string::npos) {
+ if (line.find("db ") != std::string::npos) {
+ this->WriteNumber(line.find("db ") + strlen("db ") + 1, line);
+ } else if (line.find("org ") != std::string::npos) {
size_t base[] = {10, 16, 2, 7};
for (size_t i = 0; i < 4; i++) {
diff --git a/Private/Toolchain/link.cc b/Private/Toolchain/link.cc
index 19ca084..eef72ea 100644
--- a/Private/Toolchain/link.cc
+++ b/Private/Toolchain/link.cc
@@ -46,7 +46,7 @@
#define kPefDeaultOrg (uint64_t)0x10000
#define kPefLinkerNumId 0x5046FF
-#define kPefAbiId "Container:Abi:64x0"
+#define kPefAbiId "Container:Abi:"
enum { kAbiMpUx = 0x5046 /* PF */ };
@@ -279,8 +279,8 @@ MPCC_MODULE(HCoreLinker) {
command_header.Size = ae_records[ae_record_index].fSize;
if (kVerbose)
- kStdOut << "link: object record: " << ae_records[ae_record_index].fName
- << " was marked.\n";
+ kStdOut << "link: object record: "
+ << ae_records[ae_record_index].fName << " was marked.\n";
pef_command_hdrs.emplace_back(command_header);
}
@@ -423,7 +423,25 @@ MPCC_MODULE(HCoreLinker) {
CompilerKit::PEFCommandHeader abi_header{};
- memcpy(abi_header.Name, kPefAbiId, strlen(kPefAbiId));
+ std::string abi = kPefAbiId;
+
+ switch (kArch) {
+ case CompilerKit::kPefArchAMD64: {
+ abi += "MSFT";
+ break;
+ }
+ case CompilerKit::kPefArch32000:
+ case CompilerKit::kPefArch64000: {
+ abi += "MP-UX";
+ break;
+ }
+ default: {
+ abi += "UNIX";
+ break;
+ }
+ }
+
+ memcpy(abi_header.Name, abi.c_str(), abi.size());
abi_header.Size = strlen(kPefAbiId);
abi_header.Offset = output_fc.tellp();
diff --git a/Private/Toolchain/makefile b/Private/Toolchain/makefile
index 92aecea..3e8583f 100644
--- a/Private/Toolchain/makefile
+++ b/Private/Toolchain/makefile
@@ -7,7 +7,7 @@
# ========================================================
#
-COMMON_INC=-I../ -I../CompilerKit
+COMMON_INC=-I../ -I../CompilerKit -I./
LINK_CC=g++ -std=c++20