summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAmlal El Mahrouss <113760121+Amlal-ElMahrouss@users.noreply.github.com>2024-03-16 21:42:41 +0100
committerAmlal El Mahrouss <113760121+Amlal-ElMahrouss@users.noreply.github.com>2024-03-16 21:43:37 +0100
commite190c1a5f0864606d753bb22bf20c8aa40d99cce (patch)
treea5d82907387195743f6ea32c888a8a2b70107ba1
parent7e784649762d895209ab66bf8a3c7de08da0e12c (diff)
HCR-24: See below.
WiP: - Will rework mod r/m encoding. Features request: - r8 through r15 registers. Signed-off-by: Amlal El Mahrouss <113760121+Amlal-ElMahrouss@users.noreply.github.com>
-rw-r--r--Private/CompilerKit/AsmKit/Arch/amd64.hpp4
-rw-r--r--Private/Toolchain/64asm.cc3
-rw-r--r--Private/Toolchain/bin/README.txt2
-rw-r--r--Private/Toolchain/bin/Source/amd64_to_ae.s14
-rw-r--r--Private/Toolchain/bin/Source/hello_world.s7
-rw-r--r--Private/Toolchain/i64asm.cc73
-rw-r--r--Private/Toolchain/link.cc3
-rw-r--r--Private/Toolchain/makefile2
8 files changed, 64 insertions, 44 deletions
diff --git a/Private/CompilerKit/AsmKit/Arch/amd64.hpp b/Private/CompilerKit/AsmKit/Arch/amd64.hpp
index 971cd24..5c40ed0 100644
--- a/Private/CompilerKit/AsmKit/Arch/amd64.hpp
+++ b/Private/CompilerKit/AsmKit/Arch/amd64.hpp
@@ -48,6 +48,7 @@ kAsmOpcodeDecl("int3", 0xC3)
kAsmOpcodeDecl("iret", 0xCF)
kAsmOpcodeDecl("retf", 0xCB)
kAsmOpcodeDecl("retn", 0xC3)
+kAsmOpcodeDecl("ret", 0xC3)
kAsmOpcodeDecl("sti", 0xfb)
kAsmOpcodeDecl("cli", 0xfa)
@@ -57,8 +58,7 @@ kAsmOpcodeDecl("mov", 0x48)
kAsmOpcodeDecl("jmp", 0xE9)
kAsmOpcodeDecl("call", 0xFF)
-
-kAsmOpcodeDecl("mov", 0x00)};
+};
// \brief 64x0 register prefix
// example: r32, r0
diff --git a/Private/Toolchain/64asm.cc b/Private/Toolchain/64asm.cc
index 04bc63e..71b66ad 100644
--- a/Private/Toolchain/64asm.cc
+++ b/Private/Toolchain/64asm.cc
@@ -28,7 +28,6 @@
#include <iostream>
#include <vector>
#include <memory>
-#include <filesystem>
/////////////////////
@@ -826,7 +825,7 @@ bool CompilerKit::Encoder64x0::WriteLine(std::string &line,
// sta expects this: sta 0x000000, r0
if (name == "sta") {
detail::print_error(
- "invalid combination of opcode and operands.\nhere ->" + line,
+ "invalid combination of opcode and operands.\nHere ->" + line,
file);
throw std::runtime_error("invalid_comb_op_ops");
}
diff --git a/Private/Toolchain/bin/README.txt b/Private/Toolchain/bin/README.txt
index 7530e5e..3b12775 100644
--- a/Private/Toolchain/bin/README.txt
+++ b/Private/Toolchain/bin/README.txt
@@ -1,2 +1,2 @@
The C compilers (ccplus, cc) are work in progress.
-Use it at your own risk. \ No newline at end of file
+ - Amlal \ No newline at end of file
diff --git a/Private/Toolchain/bin/Source/amd64_to_ae.s b/Private/Toolchain/bin/Source/amd64_to_ae.s
new file mode 100644
index 0000000..7e89708
--- /dev/null
+++ b/Private/Toolchain/bin/Source/amd64_to_ae.s
@@ -0,0 +1,14 @@
+!bits 64
+!org 0x1000
+
+export .text main
+ mov rcx, r8
+ mov rax, rcx
+
+ retf
+
+ export .text foo
+ mov rdx, rcx
+ mov rax, rcx
+
+ retf \ No newline at end of file
diff --git a/Private/Toolchain/bin/Source/hello_world.s b/Private/Toolchain/bin/Source/hello_world.s
deleted file mode 100644
index f90edbc..0000000
--- a/Private/Toolchain/bin/Source/hello_world.s
+++ /dev/null
@@ -1,7 +0,0 @@
-!bits 64
-!org 0x1000
-
-export .text main
-mov rcx, rax
-mov rax, rcx
-retf \ No newline at end of file
diff --git a/Private/Toolchain/i64asm.cc b/Private/Toolchain/i64asm.cc
index 9c92dac..5c7e3a1 100644
--- a/Private/Toolchain/i64asm.cc
+++ b/Private/Toolchain/i64asm.cc
@@ -4,13 +4,9 @@
------------------------------------------- */
-/// bugs: 1
-/// mov rcx, rax
-/// mov rax, rcx
-/// prompts the same output.
+/// bugs: 0
-
-/// feature requests: 1
+/// feature request: 1
/// add support for r8, r15 registers, also add support for ret.
/////////////////////////////////////////////////////////////////////////////////////////
@@ -998,6 +994,10 @@ bool CompilerKit::EncoderAMD64::WriteLine(std::string &line,
{.fName = "dx", .fModRM = 0x2}, {.fName = "bx", .fModRM = 0x10},
{.fName = "sp", .fModRM = 0x4}, {.fName = "bp", .fModRM = 0x12},
{.fName = "si", .fModRM = 0x6}, {.fName = "di", .fModRM = 0x14},
+ {.fName = "r8", .fModRM = 0x0}, {.fName = "r13", .fModRM = 0x8},
+ {.fName = "r9", .fModRM = 0x2}, {.fName = "r14", .fModRM = 0x10},
+ {.fName = "r10", .fModRM = 0x4}, {.fName = "r15", .fModRM = 0x12},
+ {.fName = "r11", .fModRM = 0x6},
};
for (auto &opcodeAMD64 : kOpcodesAMD64) {
@@ -1024,6 +1024,12 @@ bool CompilerKit::EncoderAMD64::WriteLine(std::string &line,
for (auto &reg : regs) {
std::vector<char> regExt = {'e', 'r'};
+ if (reg.fName[0] == 'r') {
+ currentRegList.push_back(
+ {.fName = reg.fName, .fModRM = reg.fModRM});
+ break;
+ }
+
for (auto &ext : regExt) {
std::string registerName;
registerName.push_back(ext);
@@ -1036,7 +1042,10 @@ bool CompilerKit::EncoderAMD64::WriteLine(std::string &line,
bits = 32;
if (bits != kRegisterBitWidth) {
- detail::print_error("invalid size for register, current bit width is: " + std::to_string(kRegisterBitWidth), file);
+ detail::print_error(
+ "invalid size for register, current bit width is: " +
+ std::to_string(kRegisterBitWidth),
+ file);
throw std::runtime_error("invalid_reg_size");
}
@@ -1052,30 +1061,30 @@ bool CompilerKit::EncoderAMD64::WriteLine(std::string &line,
if (!noRightRegister) {
if (bits == 64 || bits == 32) {
- if (bits >= 32) kBytes.emplace_back(opcodeAMD64.fOpcode);
+ bool hasRBasedRegs = false;
+
+ if (currentRegList[0].fName[0] == 'r' ||
+ currentRegList[1].fName[0] == 'r') {
+ if (isdigit(currentRegList[0].fName[1]) &&
+ isdigit(currentRegList[1].fName[1])) {
+ kBytes.emplace_back(0x4d);
+ hasRBasedRegs = true;
+ } else if (!isdigit(currentRegList[0].fName[1]) ||
+ !isdigit(currentRegList[1].fName[1])) {
+ if (currentRegList[1].fName[2] == 0 ||
+ currentRegList[0].fName[2] == 0) {
+ kBytes.emplace_back(0x4c);
+ hasRBasedRegs = true;
+ }
+ }
+ }
+
+ if (!hasRBasedRegs &&
+ bits >= 32) {
+ kBytes.emplace_back(opcodeAMD64.fOpcode);
+ }
kBytes.emplace_back(0x89);
-
- if (currentRegList[1].fName.find("sp") != std::string::npos) {
- auto byte = 0xe0;
- byte += currentRegList[0].fModRM;
-
- kBytes.push_back(byte);
- } else if (currentRegList[1].fName.find("dx") !=
- std::string::npos) {
- auto byte = 0xd0;
- byte += currentRegList[0].fModRM;
-
- kBytes.push_back(byte);
- } else if (currentRegList[1].fName.find("ax") !=
- std::string::npos ||
- currentRegList[1].fName.find("cx") !=
- std::string::npos) {
- auto byte = 0xc0;
- byte += (currentRegList[1].fName.find("cx") != std::string::npos) ? currentRegList[1].fModRM : currentRegList[0].fModRM;
-
- kBytes.push_back(byte);
- }
} else if (bits == 16) {
kBytes.emplace_back(0x66);
kBytes.emplace_back(0x89);
@@ -1086,7 +1095,8 @@ bool CompilerKit::EncoderAMD64::WriteLine(std::string &line,
"Invalid combination of operands and registers.", "i64asm");
throw std::runtime_error("comb_op_reg");
}
- } else {
+
+
}
break;
@@ -1117,7 +1127,8 @@ bool CompilerKit::EncoderAMD64::WriteLine(std::string &line,
kRegisterBitWidth = 64U;
} else if (line.find("bits 32") != std::string::npos) {
kRegisterBitWidth = 32U;
- } if (line.find("bits 16") != std::string::npos) {
+ }
+ if (line.find("bits 16") != std::string::npos) {
kRegisterBitWidth = 16U;
}
diff --git a/Private/Toolchain/link.cc b/Private/Toolchain/link.cc
index 58407cf..32733de 100644
--- a/Private/Toolchain/link.cc
+++ b/Private/Toolchain/link.cc
@@ -40,7 +40,7 @@
//! @brief standard PEF entry.
#define kPefStart "__start"
-#define kToolVersion "Mahrouss Visual Linker v2.22, (c) Mahrouss Logic 2024"
+#define kToolVersion "Mahrouss Visual Linker v2.23, (c) Mahrouss Logic 2024"
#define StringCompare(DST, SRC) strcmp(DST, SRC)
@@ -90,6 +90,7 @@ MPCC_MODULE(HCoreLinker) {
kStdOut << "-32x0: Output as 32x0 PEF.\n";
kStdOut << "-64x0: Output as 64x0 PEF.\n";
kStdOut << "-amd64: Output as AMD64 PEF.\n";
+ kStdOut << "-rv64: Output as RISC-V 64 PEF.\n";
kStdOut << "-output-file: Select output file name.\n";
return 0;
diff --git a/Private/Toolchain/makefile b/Private/Toolchain/makefile
index 28f43e2..f74cae4 100644
--- a/Private/Toolchain/makefile
+++ b/Private/Toolchain/makefile
@@ -18,6 +18,7 @@ endif
LINK_SRC=link.cc
LINK_OUTPUT=bin/link.exe
LINK_ALT_OUTPUT=bin/64link.exe
+LINK_ALT_3_OUTPUT=bin/i64link.exe
LINK_ALT_2_OUTPUT=bin/32link.exe
PP_SRC=bpp.cc
@@ -58,6 +59,7 @@ link:
$(LINK_CC) $(COMMON_INC) $(LINK_SRC) -o $(LINK_OUTPUT)
cp $(LINK_OUTPUT) $(LINK_ALT_OUTPUT)
cp $(LINK_OUTPUT) $(LINK_ALT_2_OUTPUT)
+ cp $(LINK_OUTPUT) $(LINK_ALT_3_OUTPUT)
.PHONY: help
help: