summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authoramlal <amlal.elmahrouss@icloud.com>2024-03-19 22:29:33 +0100
committeramlal <amlal.elmahrouss@icloud.com>2024-03-19 22:29:33 +0100
commitd04e7ec0bf1c5ad02b334ba68e992e85eb7b86ac (patch)
tree9d1b18079a5eedcbd337b4366eb9da520aa8d2fc
parentbb46b236ad72934469060706afe7cc3708cc299b (diff)
Secret: :boom: Breaking changes and new instructions add 'hlt'
Signed-off-by: amlal <amlal.elmahrouss@icloud.com>
-rw-r--r--Private/CompilerKit/AsmKit/Arch/amd64.hpp1
-rw-r--r--Private/Toolchain/bin/Source/amd64_to_ae.s20
-rw-r--r--Private/Toolchain/ccplus.cc4
-rw-r--r--Private/Toolchain/i64asm.cc127
4 files changed, 70 insertions, 82 deletions
diff --git a/Private/CompilerKit/AsmKit/Arch/amd64.hpp b/Private/CompilerKit/AsmKit/Arch/amd64.hpp
index 5c40ed0..1d1f9a8 100644
--- a/Private/CompilerKit/AsmKit/Arch/amd64.hpp
+++ b/Private/CompilerKit/AsmKit/Arch/amd64.hpp
@@ -51,6 +51,7 @@ kAsmOpcodeDecl("retn", 0xC3)
kAsmOpcodeDecl("ret", 0xC3)
kAsmOpcodeDecl("sti", 0xfb)
kAsmOpcodeDecl("cli", 0xfa)
+kAsmOpcodeDecl("hlt", 0xf4)
kAsmOpcodeDecl("nop", 0x90)
diff --git a/Private/Toolchain/bin/Source/amd64_to_ae.s b/Private/Toolchain/bin/Source/amd64_to_ae.s
index 040f07b..6b5de94 100644
--- a/Private/Toolchain/bin/Source/amd64_to_ae.s
+++ b/Private/Toolchain/bin/Source/amd64_to_ae.s
@@ -1,14 +1,8 @@
-@bits 64
-@org 0x1000
+#bits 16
+#org 0x7c00
-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
+export .text BIOSStartup
+ mov ax, cx
+ cli
+ hlt
+ jmp 0x7c00 \ No newline at end of file
diff --git a/Private/Toolchain/ccplus.cc b/Private/Toolchain/ccplus.cc
index c52536e..b1333d2 100644
--- a/Private/Toolchain/ccplus.cc
+++ b/Private/Toolchain/ccplus.cc
@@ -274,9 +274,9 @@ class AssemblyMountpointClang final : public CompilerKit::AssemblyMountpoint {
(*kState.fOutputAssembly) << "# Path: " << src_file << "\n";
(*kState.fOutputAssembly)
- << "# Language: AMD64 HCore Assembly (Generated from C++)\n";
+ << "# Language: MultiProcessor Assembly. (Generated from C++)\n";
(*kState.fOutputAssembly) << "# Build Date: " << fmt << "\n\n";
- (*kState.fOutputAssembly) << "@bits 64 "
+ (*kState.fOutputAssembly) << "%bits 64 "
<< "\n\n";
ParserKit::SyntaxLeafList syntax;
diff --git a/Private/Toolchain/i64asm.cc b/Private/Toolchain/i64asm.cc
index b8042fe..2e62fcf 100644
--- a/Private/Toolchain/i64asm.cc
+++ b/Private/Toolchain/i64asm.cc
@@ -24,7 +24,7 @@
#define __ASM_NEED_AMD64__ 1
-#define kAssemblerPragmaSym '@'
+#define kAssemblerPragmaSym '#'
#include <CompilerKit/AsmKit/Arch/amd64.hpp>
#include <CompilerKit/ParserKit.hpp>
@@ -67,7 +67,7 @@ static std::int32_t kRegisterBitWidth = 16U;
static bool kVerbose = false;
-static std::vector<i64_byte_t> kBytes;
+static std::vector<i64_byte_t> kAppBytes;
static CompilerKit::AERecordHeader kCurrentRecord{
.fName = "", .fKind = CompilerKit::kPefCode, .fSize = 0, .fOffset = 0};
@@ -260,7 +260,7 @@ MPCC_MODULE(HCoreAssemblerAMD64) {
return -1;
}
- kRecords[kRecords.size() - 1].fSize = kBytes.size();
+ kRecords[kRecords.size() - 1].fSize = kAppBytes.size();
std::size_t record_count = 0UL;
@@ -303,7 +303,7 @@ MPCC_MODULE(HCoreAssemblerAMD64) {
file_ptr_out.seekp(pos);
hdr.fStartCode = pos_end;
- hdr.fCodeSize = kBytes.size();
+ hdr.fCodeSize = kAppBytes.size();
file_ptr_out << hdr;
@@ -315,7 +315,7 @@ MPCC_MODULE(HCoreAssemblerAMD64) {
}
// byte from byte, we write this.
- for (auto &byte : kBytes) {
+ for (auto &byte : kAppBytes) {
if (byte == 0) continue;
if (byte == 0xFF) {
@@ -391,7 +391,8 @@ static bool asm_read_attributes(std::string &line) {
// now we can tell the code size of the previous kCurrentRecord.
- if (!kRecords.empty()) kRecords[kRecords.size() - 1].fSize = kBytes.size();
+ if (!kRecords.empty())
+ kRecords[kRecords.size() - 1].fSize = kAppBytes.size();
memset(kCurrentRecord.fName, 0, kAESymbolLen);
memcpy(kCurrentRecord.fName, result.c_str(), result.size());
@@ -454,7 +455,8 @@ static bool asm_read_attributes(std::string &line) {
// now we can tell the code size of the previous kCurrentRecord.
- if (!kRecords.empty()) kRecords[kRecords.size() - 1].fSize = kBytes.size();
+ if (!kRecords.empty())
+ kRecords[kRecords.size() - 1].fSize = kAppBytes.size();
memset(kCurrentRecord.fName, 0, kAESymbolLen);
memcpy(kCurrentRecord.fName, name.c_str(), name.size());
@@ -479,7 +481,7 @@ static inline bool is_not_alnum_space(char c) {
return !(isalpha(c) || isdigit(c) || (c == ' ') || (c == '\t') ||
(c == ',') || (c == '(') || (c == ')') || (c == '"') ||
(c == '\'') || (c == '[') || (c == ']') || (c == '+') ||
- (c == '_') || (c == ':') || (c == '@') || (c == '.') || (c == '!'));
+ (c == '_') || (c == ':') || (c == '@') || (c == '.') || (c == '#'));
}
bool is_valid(const std::string &str) {
@@ -500,14 +502,12 @@ std::string CompilerKit::EncoderAMD64::CheckLine(std::string &line,
if (line.empty() || ParserKit::find_word(line, "import") ||
ParserKit::find_word(line, "export") || ParserKit::find_word(line, "#") ||
ParserKit::find_word(line, ";")) {
- if (line.find('#') != std::string::npos) {
- line.erase(line.find('#'));
- } else if (line.find(';') != std::string::npos) {
+ if (line.find(';') != std::string::npos) {
line.erase(line.find(';'));
} else {
// now check the line for validity
if (!detail::algorithm::is_valid(line)) {
- err_str = "Line contains non alphanumeric characters.\nhere -> ";
+ err_str = "Line contains non valid characters.\nhere -> ";
err_str += line;
}
}
@@ -581,7 +581,7 @@ bool CompilerKit::EncoderAMD64::WriteNumber(const std::size_t &pos,
for (char &i : num.number) {
if (i == 0) i = 0xFF;
- kBytes.push_back(i);
+ kAppBytes.push_back(i);
}
if (kVerbose) {
@@ -611,7 +611,7 @@ bool CompilerKit::EncoderAMD64::WriteNumber(const std::size_t &pos,
for (char &i : num.number) {
if (i == 0) i = 0xFF;
- kBytes.push_back(i);
+ kAppBytes.push_back(i);
}
return true;
@@ -636,7 +636,7 @@ bool CompilerKit::EncoderAMD64::WriteNumber(const std::size_t &pos,
for (char &i : num.number) {
if (i == 0) i = 0xFF;
- kBytes.push_back(i);
+ kAppBytes.push_back(i);
}
return true;
@@ -659,7 +659,7 @@ bool CompilerKit::EncoderAMD64::WriteNumber(const std::size_t &pos,
for (char &i : num.number) {
if (i == 0) i = 0xFF;
- kBytes.push_back(i);
+ kAppBytes.push_back(i);
}
if (kVerbose) {
@@ -688,7 +688,7 @@ bool CompilerKit::EncoderAMD64::WriteNumber32(const std::size_t &pos,
for (char &i : num.number) {
if (i == 0) i = 0xFF;
- kBytes.push_back(i);
+ kAppBytes.push_back(i);
}
if (kVerbose) {
@@ -716,7 +716,7 @@ bool CompilerKit::EncoderAMD64::WriteNumber32(const std::size_t &pos,
for (char &i : num.number) {
if (i == 0) i = 0xFF;
- kBytes.push_back(i);
+ kAppBytes.push_back(i);
}
return true;
@@ -739,7 +739,7 @@ bool CompilerKit::EncoderAMD64::WriteNumber32(const std::size_t &pos,
for (char &i : num.number) {
if (i == 0) i = 0xFF;
- kBytes.push_back(i);
+ kAppBytes.push_back(i);
}
return true;
@@ -761,7 +761,7 @@ bool CompilerKit::EncoderAMD64::WriteNumber32(const std::size_t &pos,
for (char &i : num.number) {
if (i == 0) i = 0xFF;
- kBytes.push_back(i);
+ kAppBytes.push_back(i);
}
if (kVerbose) {
@@ -792,7 +792,7 @@ bool CompilerKit::EncoderAMD64::WriteNumber16(const std::size_t &pos,
for (char &i : num.number) {
if (i == 0) i = 0xFF;
- kBytes.push_back(i);
+ kAppBytes.push_back(i);
}
if (kVerbose) {
@@ -822,7 +822,7 @@ bool CompilerKit::EncoderAMD64::WriteNumber16(const std::size_t &pos,
for (char &i : num.number) {
if (i == 0) i = 0xFF;
- kBytes.push_back(i);
+ kAppBytes.push_back(i);
}
return true;
@@ -847,7 +847,7 @@ bool CompilerKit::EncoderAMD64::WriteNumber16(const std::size_t &pos,
for (char &i : num.number) {
if (i == 0) i = 0xFF;
- kBytes.push_back(i);
+ kAppBytes.push_back(i);
}
return true;
@@ -870,7 +870,7 @@ bool CompilerKit::EncoderAMD64::WriteNumber16(const std::size_t &pos,
for (char &i : num.number) {
if (i == 0) i = 0xFF;
- kBytes.push_back(i);
+ kAppBytes.push_back(i);
}
if (kVerbose) {
@@ -898,7 +898,7 @@ bool CompilerKit::EncoderAMD64::WriteNumber8(const std::size_t &pos,
CompilerKit::NumberCast8 num = CompilerKit::NumberCast8(
strtol(jump_label.substr(pos + 2).c_str(), nullptr, 16));
- kBytes.push_back(num.number);
+ kAppBytes.push_back(num.number);
if (kVerbose) {
kStdOut << "i64asm: found a base 16 number here: "
@@ -924,7 +924,7 @@ bool CompilerKit::EncoderAMD64::WriteNumber8(const std::size_t &pos,
<< jump_label.substr(pos) << "\n";
}
- kBytes.push_back(num.number);
+ kAppBytes.push_back(num.number);
return true;
}
@@ -945,7 +945,7 @@ bool CompilerKit::EncoderAMD64::WriteNumber8(const std::size_t &pos,
<< jump_label.substr(pos) << "\n";
}
- kBytes.push_back(num.number);
+ kAppBytes.push_back(num.number);
return true;
}
@@ -964,7 +964,7 @@ bool CompilerKit::EncoderAMD64::WriteNumber8(const std::size_t &pos,
CompilerKit::NumberCast8 num = CompilerKit::NumberCast8(
strtol(jump_label.substr(pos).c_str(), nullptr, 10));
- kBytes.push_back(num.number);
+ kAppBytes.push_back(num.number);
if (kVerbose) {
kStdOut << "i64asm: found a base 10 number here: " << jump_label.substr(pos)
@@ -1017,49 +1017,42 @@ bool CompilerKit::EncoderAMD64::WriteLine(std::string &line,
throw std::runtime_error("comb_op_reg");
}
- bool noRightRegister = false;
+ bool hasRightRegister = false;
std::vector<RegMapAMD64> currentRegList;
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);
+
+ if (bits > 16) registerName.push_back(ext);
+
registerName += reg.fName;
while (line.find(registerName) != std::string::npos) {
- if (ext == 'r')
- bits = 64;
- else if (ext == 'e')
- bits = 32;
-
- if (bits != kRegisterBitWidth) {
- detail::print_error(
- "invalid size for register, current bit width is: " +
- std::to_string(kRegisterBitWidth),
- file);
- throw std::runtime_error("invalid_reg_size");
- }
-
line.erase(line.find(registerName), registerName.size());
+ if (bits == 16) {
+ if (registerName[0] == 'r') {
+ detail::print_error(
+ "invalid size for register, current bit width is: " +
+ std::to_string(kRegisterBitWidth),
+ file);
+ throw std::runtime_error("invalid_reg_size");
+ }
+ }
+
currentRegList.push_back(
{.fName = registerName, .fModRM = reg.fModRM});
}
}
}
- if (currentRegList.size() > 1) noRightRegister = false;
+ if (currentRegList.size() > 1) hasRightRegister = true;
- if (!noRightRegister) {
+ if (hasRightRegister) {
if (bits == 64 || bits == 32) {
bool hasRBasedRegs = false;
@@ -1067,26 +1060,23 @@ bool CompilerKit::EncoderAMD64::WriteLine(std::string &line,
currentRegList[1].fName[0] == 'r') {
if (isdigit(currentRegList[0].fName[1]) &&
isdigit(currentRegList[1].fName[1])) {
- kBytes.emplace_back(0x4d);
+ kAppBytes.emplace_back(0x4d);
+ hasRBasedRegs = true;
+ } else if (isdigit(currentRegList[0].fName[1]) ||
+ isdigit(currentRegList[1].fName[1])) {
+ kAppBytes.emplace_back(0x4c);
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);
+ kAppBytes.emplace_back(opcodeAMD64.fOpcode);
}
- kBytes.emplace_back(0x89);
+ kAppBytes.emplace_back(0x89);
} else if (bits == 16) {
- kBytes.emplace_back(0x66);
- kBytes.emplace_back(0x89);
+ kAppBytes.emplace_back(0x66);
+ kAppBytes.emplace_back(0x89);
// TODO: 16 bit move operation.
} else {
@@ -1094,16 +1084,19 @@ bool CompilerKit::EncoderAMD64::WriteLine(std::string &line,
"Invalid combination of operands and registers.", "i64asm");
throw std::runtime_error("comb_op_reg");
}
+ } else {
+ detail::print_error("Missing right register.", "i64asm");
+ throw std::runtime_error("missing_right_reg");
}
break;
} else if (name == "int" || name == "into" || name == "intd") {
- kBytes.emplace_back(opcodeAMD64.fOpcode);
+ kAppBytes.emplace_back(opcodeAMD64.fOpcode);
this->WriteNumber8(line.find(name) + name.size() + 1, line);
break;
} else if (name == "jmp" || name == "call") {
- kBytes.emplace_back(opcodeAMD64.fOpcode);
+ kAppBytes.emplace_back(opcodeAMD64.fOpcode);
if (!this->WriteNumber32(line.find(name) + name.size() + 1, line)) {
throw std::runtime_error("BUG: WriteNumber32");
@@ -1111,8 +1104,8 @@ bool CompilerKit::EncoderAMD64::WriteLine(std::string &line,
break;
} else {
- kBytes.emplace_back(0);
- kBytes.emplace_back(opcodeAMD64.fOpcode);
+ kAppBytes.emplace_back(0);
+ kAppBytes.emplace_back(opcodeAMD64.fOpcode);
break;
}